Skip to content

Commit cfcd8ff

Browse files
A.R.claude
andcommitted
fix(ci): commit missing post-build-shebang.mjs + re-arm watcher on profile switch
- .gitignore: add packages/mcp-server/scripts/ to allowlist (blanket * rule was excluding the scripts dir, so post-build-shebang.mjs was never tracked) - post-build-shebang.mjs: add the missing script that CI was failing on (Cannot find module: post-build-shebang.mjs across all 8 matrix jobs) - DashboardProvider: track daemonStatusWatchedProfile so ensureDaemonStatusWatch() re-arms when the active profile changes (addresses P2 review comment) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent a196df7 commit cfcd8ff

3 files changed

Lines changed: 41 additions & 3 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@
5656
!packages/mcp-server/
5757
!packages/mcp-server/src/
5858
!packages/mcp-server/src/**
59+
!packages/mcp-server/scripts/
60+
!packages/mcp-server/scripts/**
5961
!packages/mcp-server/test/
6062
!packages/mcp-server/test/**
6163
!packages/mcp-server/package.json

packages/extension/src/webview/DashboardProvider.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ export class DashboardProvider implements vscode.WebviewViewProvider {
122122
private onMcpServerDefinitionsChanged?: () => void;
123123
private daemonEventsAbort: AbortController | null = null;
124124
private daemonStatusWatcher: fs.FSWatcher | null = null;
125+
private daemonStatusWatchedProfile: string | null = null;
125126
// v0.8.5: deps factory injected from extension.ts so the auto-regen hook
126127
// on `postStaleness` can reuse the live ApplyIdeConfigDeps without pulling
127128
// the daemon runtime singletons into the webview module.
@@ -2094,17 +2095,20 @@ export class DashboardProvider implements vscode.WebviewViewProvider {
20942095
// File may not exist yet (daemon not started). Re-arm on next refresh.
20952096
this.stopDaemonStatusWatch();
20962097
});
2098+
this.daemonStatusWatchedProfile = profile;
20972099
} catch {
20982100
// daemon-status.json doesn't exist yet — watcher will be re-armed
20992101
// the next time refresh() is called (startDaemonStatusWatch is called
21002102
// from refresh() → ensureWatcher() path below).
21012103
this.daemonStatusWatcher = null;
2104+
this.daemonStatusWatchedProfile = null;
21022105
}
21032106
}
21042107

21052108
private stopDaemonStatusWatch(): void {
21062109
this.daemonStatusWatcher?.close();
21072110
this.daemonStatusWatcher = null;
2111+
this.daemonStatusWatchedProfile = null;
21082112
}
21092113

21102114
/**
@@ -2115,9 +2119,9 @@ export class DashboardProvider implements vscode.WebviewViewProvider {
21152119
private ensureDaemonStatusWatch(): void {
21162120
const profile = getActiveName() ?? "default";
21172121
const statusFile = getProfilePaths(profile).daemonStatus;
2118-
// Re-arm if watcher is null (never started, file missing at last attempt,
2119-
// or profile changed). A live watcher needs no action.
2120-
if (!this.daemonStatusWatcher) {
2122+
// Re-arm when: watcher never started, file was missing last time, or
2123+
// the active profile has changed since the watcher was last started.
2124+
if (!this.daemonStatusWatcher || this.daemonStatusWatchedProfile !== profile) {
21212125
if (fs.existsSync(statusFile)) {
21222126
this.startDaemonStatusWatch();
21232127
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/usr/bin/env node
2+
/**
3+
* Post-build shebang injection for dist/cli.mjs.
4+
*
5+
* tsup intentionally omits shebang from bundled output because a shebang in
6+
* source files trips vitest/esbuild during test imports. However, the npm
7+
* package.json `bin` field points directly at `dist/cli.mjs`; on POSIX npm
8+
* creates a symlink (not a wrapper script), so the kernel needs the shebang
9+
* to exec the file directly.
10+
*
11+
* This script prepends `#!/usr/bin/env node` and ensures the file is
12+
* executable (0o755). It is a no-op on Windows where the kernel ignores
13+
* shebangs and npm uses `.cmd` wrappers anyway.
14+
*/
15+
import { readFileSync, writeFileSync, chmodSync, existsSync } from "node:fs";
16+
import { join } from "node:path";
17+
18+
const file = join(import.meta.dirname, "..", "dist", "cli.mjs");
19+
if (!existsSync(file)) {
20+
console.error("post-build-shebang: dist/cli.mjs not found");
21+
process.exit(1);
22+
}
23+
24+
const content = readFileSync(file, "utf8");
25+
if (content.startsWith("#!/usr/bin/env node")) {
26+
console.log("post-build-shebang: already present, skipping");
27+
process.exit(0);
28+
}
29+
30+
writeFileSync(file, "#!/usr/bin/env node\n" + content);
31+
chmodSync(file, 0o755);
32+
console.log("post-build-shebang: injected shebang + chmod 755");

0 commit comments

Comments
 (0)