Compare commits

..

2 Commits

Author SHA1 Message Date
nntrivi2001 43f29ee904 fix(ccam-open): always rebuild the dashboard bundle
/ccam-open built only when client/dist was missing, so a stale bundle
silently outlived code fixes (seen 2026-08-13: fix b0bfc66 wasn't served
until a --force rebuild). Pass --force unconditionally.
2026-08-13 15:38:50 +07:00
nntrivi2001 18a42873b2 fix(mcp): fall back to lane cwd when source_repo is null
Adopted lanes have source_repo = null; lane-mcp.js passed it raw to
readSourceMcpServers and threw ENOMCPCONFIG. Match the existing fallback
pattern in lane-env.js/lane-profile.js.
2026-08-13 15:36:36 +07:00
3 changed files with 21 additions and 14 deletions
+10 -11
View File
@@ -1,19 +1,19 @@
---
description: Build the dashboard UI if needed and print its URL
description: Rebuild the dashboard UI and print its URL
---
Build the dashboard bundle if it is not there yet, then print the URL. The
bootstrap already builds it on session start, so this is usually a no-op — use
it to force a rebuild, or to finish the build if the bootstrap's own attempt
failed (check `~/.claude/agent-dashboard/runtime/client-build.log`).
Rebuild the dashboard bundle, then print the URL. Always forces a rebuild so a
stale bundle (e.g. after a fix commit landed but the bootstrap's build predates
it) never serves silently. Also finishes the build if the bootstrap's own
attempt failed (check `~/.claude/agent-dashboard/runtime/client-build.log`).
```bash
node "${CLAUDE_PLUGIN_ROOT}/scripts/plugin-open.js"
node "${CLAUDE_PLUGIN_ROOT}/scripts/plugin-open.js" --force
```
The first run installs the client toolchain and takes a few minutes; later runs
print the URL immediately. No server restart is needed — the server already
serves from that directory.
Install + build takes a few minutes if the client toolchain isn't already
installed; otherwise the rebuild itself takes ~10-15s. No server restart is
needed — the server already serves from that directory.
Then help the user open it:
@@ -25,5 +25,4 @@ uname -s
- `Linux``xdg-open <url>`
- otherwise → tell them to open the URL in a browser.
Keep the output to a few lines. Pass `--force` to the script only if the user
asks for a rebuild.
Keep the output to a few lines.
+7
View File
@@ -79,6 +79,13 @@ describe("syncMcp — reading and relocating", () => {
`${lane.cwd}/.playwright-mcp/profiles/default`
);
});
it("falls back to the lane's own cwd when source_repo is null (adopted lane)", async () => {
const lane = makeLane(null);
writeClaudeJson({ [lane.cwd]: { mcpServers: { playwright: { command: "npx", args: [] } } } });
const result = await laneMcp.syncMcp(lane);
assert.deepEqual(result.servers, ["playwright"]);
});
});
describe("syncMcp — Playwright output-dir pinning", () => {
+4 -3
View File
@@ -120,8 +120,9 @@ function excludeFromGit(laneDir, line) {
* @returns {{servers: string[], profilesSeeded: string[]}}
*/
async function syncMcp(lane) {
const sourceServers = readSourceMcpServers(lane.source_repo);
const relocated = relocate(sourceServers, lane.source_repo, lane.cwd);
const sourceRepo = lane.source_repo || lane.cwd;
const sourceServers = readSourceMcpServers(sourceRepo);
const relocated = relocate(sourceServers, sourceRepo, lane.cwd);
pinPlaywrightOutputDir(relocated, lane.cwd);
fs.writeFileSync(
@@ -130,7 +131,7 @@ async function syncMcp(lane) {
);
excludeFromGit(lane.cwd, ".mcp.json");
const profilesSeeded = seedProfiles(lane.source_repo, lane.cwd);
const profilesSeeded = seedProfiles(sourceRepo, lane.cwd);
return { servers: Object.keys(relocated), profilesSeeded };
}