diff --git a/.agents/PROJECT.md b/.agents/PROJECT.md index 94bbed88..9f7057c2 100644 --- a/.agents/PROJECT.md +++ b/.agents/PROJECT.md @@ -214,6 +214,7 @@ The package README documents the `kb.yaml` configuration schema and merge semant **Root-level development (via `@williamthorsen/nmr`):** - `pnpm install` - Install all dependencies +- `pnpm run bootstrap` - Build every package; required after install before the MCP server or CLI bins will run - `nmr check` - Run typecheck, format check, lint check, and tests - `nmr check:strict` - Strict checks including coverage and audit - `nmr ci` - Full CI pipeline (strict checks + build) diff --git a/.config/wt.toml b/.config/wt.toml index 916fc033..1b4a2750 100644 --- a/.config/wt.toml +++ b/.config/wt.toml @@ -3,4 +3,4 @@ [post-create] direnv = "direnv allow" deps = "pnpm install" -build = "nmr build" +bootstrap = "pnpm run bootstrap" diff --git a/.github/workflows/code-quality.yaml b/.github/workflows/code-quality.yaml index e5bf20ea..2a964469 100644 --- a/.github/workflows/code-quality.yaml +++ b/.github/workflows/code-quality.yaml @@ -25,4 +25,4 @@ jobs: code-quality: uses: williamthorsen/.github/.github/workflows/code-quality-pnpm-workflow.yaml@v7 with: - check-command: pnpm exec nmr build && pnpm exec nmr check:strict + check-command: pnpm exec nmr check:strict diff --git a/README.md b/README.md index 6b49658a..5c4aa6a5 100644 --- a/README.md +++ b/README.md @@ -10,5 +10,6 @@ See [`.agents/PROJECT.md`](.agents/PROJECT.md) for project structure, commands, ```bash pnpm install -nmr check # Run all checks (typecheck, format, lint, test) +pnpm run bootstrap # Build every package; required before running the MCP server or CLI bins +pnpm exec nmr check # Run all checks (typecheck, format, lint, test) ``` diff --git a/package.json b/package.json index 01613896..683ae4a3 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "scripts": { "agents:install": "tsx packages/agents/src/cli.ts install", "agents:install-launchers": "bash packages/agents/scripts/install-launchers.sh", + "bootstrap": "nmr build", "ci:post": "pnpm --filter agents run test:sh", "prepare": "lefthook install" }, diff --git a/packages/agents/bin/codeassembly-agents.js b/packages/agents/bin/codeassembly-agents.js index 02293471..92ea0c71 100755 --- a/packages/agents/bin/codeassembly-agents.js +++ b/packages/agents/bin/codeassembly-agents.js @@ -11,7 +11,7 @@ const entryPoint = new URL('../dist/esm/cli.js', import.meta.url); // module in the graph, so keying the build-first message off the error code would also // fire when the build is present and one of its imports is missing. if (!existsSync(entryPoint)) { - process.stderr.write('codeassembly-agents: build output not found — run `pnpm run build` first\n'); + process.stderr.write('codeassembly-agents: build output not found — run `pnpm run bootstrap` first\n'); process.exit(1); } diff --git a/packages/kb/bin/kb.js b/packages/kb/bin/kb.js index 2824bd3d..a9b49a07 100755 --- a/packages/kb/bin/kb.js +++ b/packages/kb/bin/kb.js @@ -11,7 +11,7 @@ const entryPoint = new URL('../dist/esm/cli/index.js', import.meta.url); // module in the graph, so keying the build-first message off the error code would also // fire when the build is present and one of its imports is missing. if (!existsSync(entryPoint)) { - process.stderr.write('kb: build output not found — run `pnpm run build` first\n'); + process.stderr.write('kb: build output not found — run `pnpm run bootstrap` first\n'); process.exit(1); } diff --git a/packages/kb/package.json b/packages/kb/package.json index 79454d5c..a65b64c8 100644 --- a/packages/kb/package.json +++ b/packages/kb/package.json @@ -76,8 +76,7 @@ "!dist/esm/test-utils" ], "scripts": { - "build": "nmr compile", - "prepare": "nmr compile" + "build": "nmr compile" }, "dependencies": { "picomatch": "4.0.5", diff --git a/packages/lifecycle/package.json b/packages/lifecycle/package.json index fa25b811..f259134d 100644 --- a/packages/lifecycle/package.json +++ b/packages/lifecycle/package.json @@ -16,8 +16,7 @@ "dist" ], "scripts": { - "build": "nmr compile", - "prepare": "nmr compile" + "build": "nmr compile" }, "devDependencies": { "esbuild": "0.28.1" diff --git a/packages/mcp/bin/codeassembly-mcp.js b/packages/mcp/bin/codeassembly-mcp.js index fd7e0a62..8abe44a0 100755 --- a/packages/mcp/bin/codeassembly-mcp.js +++ b/packages/mcp/bin/codeassembly-mcp.js @@ -11,7 +11,7 @@ const entryPoint = new URL('../dist/esm/cli.js', import.meta.url); // module in the graph, so keying the build-first message off the error code would also // fire when the build is present and one of its imports is missing. if (!existsSync(entryPoint)) { - process.stderr.write('codeassembly-mcp: build output not found — run `pnpm run build` first\n'); + process.stderr.write('codeassembly-mcp: build output not found — run `pnpm run bootstrap` first\n'); process.exit(1); } diff --git a/packages/mcp/package.json b/packages/mcp/package.json index bb8b5b31..0a5b8093 100644 --- a/packages/mcp/package.json +++ b/packages/mcp/package.json @@ -12,8 +12,7 @@ "dist" ], "scripts": { - "build": "nmr compile", - "prepare": "nmr compile" + "build": "nmr compile" }, "dependencies": { "@codeassembly/run-core": "workspace:*", diff --git a/packages/mcp/src/__tests__/protocol-stdio.test.ts b/packages/mcp/src/__tests__/protocol-stdio.test.ts index abf3219b..9740085c 100644 --- a/packages/mcp/src/__tests__/protocol-stdio.test.ts +++ b/packages/mcp/src/__tests__/protocol-stdio.test.ts @@ -4,7 +4,7 @@ import { dirname, join, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; import { Client } from '@modelcontextprotocol/sdk/client'; -import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio'; +import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'; import { describe, expect, it } from 'vitest'; import { isErrorResult, parseAndGetString } from './helpers.ts'; diff --git a/packages/mcp/src/__tests__/protocol.test.ts b/packages/mcp/src/__tests__/protocol.test.ts index 72119c11..3e703c9b 100644 --- a/packages/mcp/src/__tests__/protocol.test.ts +++ b/packages/mcp/src/__tests__/protocol.test.ts @@ -4,7 +4,7 @@ import { join } from 'node:path'; import { v3RunIndexSchema } from '@codeassembly/run-core'; import { Client } from '@modelcontextprotocol/sdk/client'; -import { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory'; +import { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js'; import { afterEach, describe, expect, it } from 'vitest'; import { createServer } from '../server.ts'; diff --git a/packages/mcp/src/__tests__/staleness.test.ts b/packages/mcp/src/__tests__/staleness.test.ts index f0a97e33..b3defe0f 100644 --- a/packages/mcp/src/__tests__/staleness.test.ts +++ b/packages/mcp/src/__tests__/staleness.test.ts @@ -4,7 +4,7 @@ import { join } from 'node:path'; import { pathToFileURL } from 'node:url'; import { Client } from '@modelcontextprotocol/sdk/client'; -import { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory'; +import { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { isBuildStale } from '../staleness.ts'; diff --git a/packages/mcp/src/cli.ts b/packages/mcp/src/cli.ts index d24a41e9..bde01877 100644 --- a/packages/mcp/src/cli.ts +++ b/packages/mcp/src/cli.ts @@ -1,6 +1,6 @@ import process from 'node:process'; -import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio'; +import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { createServer } from './server.ts'; diff --git a/packages/mcp/src/server.ts b/packages/mcp/src/server.ts index 8d1ab5ff..dd2377a9 100644 --- a/packages/mcp/src/server.ts +++ b/packages/mcp/src/server.ts @@ -1,4 +1,4 @@ -import { McpServer } from '@modelcontextprotocol/sdk/server/mcp'; +import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { z } from 'zod'; import { isBuildStale } from './staleness.ts'; diff --git a/packages/run-core/README.md b/packages/run-core/README.md index a5a53950..cafa0a8c 100644 --- a/packages/run-core/README.md +++ b/packages/run-core/README.md @@ -29,8 +29,6 @@ codeassembly-runs --path # override the base projects directory ### Bin wrapper pattern -The `bin` field in `package.json` points to `bin/codeassembly-runs.js`, a committed wrapper script that dynamically imports the build output at runtime. Do not point `bin` entries directly into `dist/` — pnpm creates bin symlinks during install, before lifecycle scripts like `prepare` run, so the target won't exist in a fresh worktree and `pnpm install` will emit confusing "Failed to create bin" warnings. - -If invoked before building, the wrapper finds the entry file absent and tells the user to run `pnpm run build`. It checks for the file directly rather than keying off `ERR_MODULE_NOT_FOUND`, which Node raises for any unresolved module in the graph — including a missing dependency of a build output that is present, where advising a rebuild would be wrong. Any other load failure is reported verbatim. +The `bin` field in `package.json` points to `bin/codeassembly-runs.js`, a committed wrapper script that dynamically imports the build output at runtime. Do not point `bin` entries directly into `dist/` — pnpm creates bin symlinks during install, and nothing compiles until `pnpm run bootstrap` runs afterward, so the target won't exist in a fresh worktree and `pnpm install` will emit confusing "Failed to create bin" warnings. Any new `bin` entry in this monorepo should follow the same pattern. See `bin/codeassembly-runs.js` for the template, and the `@williamthorsen/node-monorepo-tools` packages for the original rationale. diff --git a/packages/run-core/bin/codeassembly-runs.js b/packages/run-core/bin/codeassembly-runs.js index 6bb21c80..115b2222 100755 --- a/packages/run-core/bin/codeassembly-runs.js +++ b/packages/run-core/bin/codeassembly-runs.js @@ -11,7 +11,7 @@ const entryPoint = new URL('../dist/esm/cli.js', import.meta.url); // module in the graph, so keying the build-first message off the error code would also // fire when the build is present and one of its imports is missing. if (!existsSync(entryPoint)) { - process.stderr.write('codeassembly-runs: build output not found — run `pnpm run build` first\n'); + process.stderr.write('codeassembly-runs: build output not found — run `pnpm run bootstrap` first\n'); process.exit(1); } diff --git a/packages/run-core/package.json b/packages/run-core/package.json index 113699fc..8d0731de 100644 --- a/packages/run-core/package.json +++ b/packages/run-core/package.json @@ -35,8 +35,7 @@ "dist" ], "scripts": { - "build": "nmr compile", - "prepare": "nmr compile" + "build": "nmr compile" }, "dependencies": { "yaml": "2.9.0",