Skip to content

fix(cli): an os create --in-repo plugin passes its own typecheck and build - #26395

Merged
objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/project-thread-z61um0
Oct 27, 2026
Merged

objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/project-thread-z61um0

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Leehom · project thread
Fixes #26332

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:os create plugin NAME --in-repo 生成的包改为声明工作区的 TypeScript(^6.0.3,与仓根和所有兄弟插件一致);starter 的 init(context) 改为 init(_context) 并加一行说明。独立(默认)脚手架的 TypeScript 范围不变,仍是 ^5.3.0。
  • 为什么改:在仓内新建插件后,第一条 pnpm typecheck / pnpm build 就红:TS5103(5.x 不认 base 的 ignoreDeprecations: "6.0")和 TS6133(未用的 context 撞上 noUnusedParameters)。贡献者的第一步命令就失败。
  • 风险与回滚:低。只动脚手架输出和一个新测试;另把 tsconfig.base.json 登记为 cli 测试任务的输入(turbo.json 与两处门禁名单各一行,席位已批)。回滚即 revert 本 PR。
  • 先看:packages/cli/src/commands/create.ts(IN_REPO_TYPESCRIPT_RANGE / typescriptDependencySpec 与 starter 的 init 行);packages/cli/test/create-in-repo-scaffold-typechecks.test.ts;turbo.json 新增的一行输入。
  • 两分钟验证:pnpm --filter @objectstack/cli exec vitest run test/create-in-repo-scaffold-typechecks.test.ts,预期 5/5 通过(在 main 上同一文件 3 红)。
  • 需要你做的:无,席位落地。

What changes

  • TS5103. The plugin template's devDependencies.typescript now follows the placement through typescriptDependencySpec(placement), the same shape as objectstackDependencySpec. in-repo declares IN_REPO_TYPESCRIPT_RANGE (^6.0.3), the range the repository root, @objectstack/cli and every sibling under packages/plugins/ declare. standalone still declares SCAFFOLD_TYPESCRIPT_RANGE (^5.3.0), unchanged, and init.ts is not touched.
  • TS6133. The starter src/index.ts declares async init(_context), with a two-line comment above it: the parameter is the kernel's plugin context, and the underscore goes once init reads it. The starter is one template for both placements, so the standalone src/index.ts takes the same rename. The standalone manifest, tsconfig.json and TypeScript range are byte-unchanged.
  • Test-input declaration. The new test copies the repo-root tsconfig.base.json into its sandbox, so check:cross-package-test-inputs requires that read declared. Three one-line additions, approved as claim amendments 6431310360 and 6431339243: $TURBO_ROOT$/tsconfig.base.json in turbo.json's @objectstack/cli#test inputs, tsconfig.base.json in the @objectstack/cli roster globs (scripts/cross-package-test-inputs.mjs), and in the pinned TURBO_ROOT_FILE_INPUTS (scripts/check-cross-package-test-inputs.mjs). The file is already a turbo globalDependencies entry, which the gate does not read.
  • .changeset/26332-create-in-repo-typescript.md: @objectstack/cli patch, with the before/after and what to do for an in-repo plugin scaffolded earlier.

Tests

packages/cli/test/create-in-repo-scaffold-typechecks.test.ts (unit tier: it spawns tsc, not the CLI). It materialises the in-repo emission through create's own renderers into a sandbox laid out like this repository (the real tsconfig.base.json at its root, the scaffold at packages/plugins/plugin-probe), then spawns the emitted typecheck and build scripts with the workspace's tsc 6.0.3.

  • Control: a planted unused parameter fails typecheck with TS6133, so the scaffold really compiles under the base's strictness.
  • typecheck and build exit 0; build writes dist/index.js and dist/index.d.ts and no dist/index.test.js.
  • The in-repo typescript range equals the range @objectstack/cli declares for the tsc the cases spawn, and its floor major accepts the base's ignoreDeprecations (read through ts.readConfigFile).
  • Standalone still declares SCAFFOLD_TYPESCRIPT_RANGE.

Module line 2.6 s red and 3.2 s green on this box (a shared container), under the 10 s line, so no test-budget header.

Red first, on main 6390fe52c (the test file alone, source untouched): 3 failed, 2 passed.

red run on main
× `typecheck` and `build` exit 0, and `build` leaves the starter test out of dist
  src/index.ts(10,14): error TS6133: 'context' is declared but its value is never read.
× in-repo declares the workspace's TypeScript ...
  Expected: "^6.0.3"  Received: "^5.3.0"
× in-repo's TypeScript floor accepts the base's ignoreDeprecations (TS5103)
Tests  3 failed | 2 passed (5)

Ablation (one-shot, through scripts/ablation-replace.mjs, each leg restored to the HEAD blob with git diff HEAD empty; the test imports src/, so no build is involved):

  • typescript: typescriptDependencySpec(placement) back to SCAFFOLD_TYPESCRIPT_RANGE: 2 failed (the range and floor cases), 3 passed.
  • async init(_context) back to async init(context): 1 failed (typecheck, TS6133), 4 passed.

Acceptance notes

  • IN_REPO_TYPESCRIPT_RANGE is a literal pinned against @objectstack/cli's own devDependencies.typescript. A workspace TypeScript bump reddens the pin until the constant moves with it. Reading the root manifest at scaffold time was not taken: the template renderers take only a placement, and a missing root range would need a fallback.
  • The standalone scaffold's src/index.ts changes by the _context rename (see What changes). Placement-gating the starter would teach two shapes of one plugin.
  • @objectstack/cli's published entry re-exports only the command's default export, so the two new named exports in create.ts do not reach the published surface.
  • No open pull request touches packages/cli/src/commands/create.ts (20 open PRs listed, each one's files read).

Verification

Head 89522f6b5.

  • pnpm --filter @objectstack/cli exec vitest run --project unit (at aafab270, the fix commit; later commits touch only the new test file and input declarations): 336/336 files, 4894/4894 tests. Re-run on the final head for the touched files: create-in-repo-scaffold-typechecks, create, scaffold-test-script-passes, 3/3 files, 31/31 tests. The integration tier is declared to CI.
  • pnpm --filter @objectstack/cli build exit 0; pnpm --filter @objectstack/cli typecheck (tsc plus check:test-typecheck) exit 0.
  • eslint --no-inline-config packages/cli: exit 0.
  • node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 90 commands on this diff; each ran with its exit code captured by redirect before any pipe. All 90 exited 0, among them check:cross-package-test-inputs (red until tsconfig.base.json was declared), check:turbo-task-graph, check:ci-filter-parity, check:pm-dispatch-gates (fast tier, 1901 cases) and check-plugin-teardown-shape --self-test (after fetching its pinned positive-control commit). check:dual-build-cjs-loads, check:dts-closure and check:i18n-coverage measured on a tree an earlier sweep had built.
  • --ran reconciliation: "90 derived, 90 run, 0 NOT-MEASURED, 0 UNRUN", exit 0.
  • node scripts/pm/check-governed-merges.mjs --branch claude/project-thread-z61um0: 0 of 6 paths governed, ordinary queue landing. origin/main is 11 commits ahead at abb904605, none on this diff's files, and git merge-tree is clean; not merged in.

Generated by Claude Code

…build

The in-repo placement declares the workspace's TypeScript (^6.0.3, the
range the root and every sibling plugin declare) instead of the standalone
SCAFFOLD_TYPESCRIPT_RANGE, whose 5.x install refused the base's
ignoreDeprecations "6.0" with TS5103. The starter's unused init parameter
is _context, so it compiles under the base's noUnusedParameters (TS6133).

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019uZ84EhCM1NaBkJM8y1sjE
The in-repo scaffold typecheck test copies the repo-root base into its
sandbox, so check:cross-package-test-inputs requires the read declared:
the cli roster glob, the turbo.json input, and the pinned root-file list.
The test now reads the cli package's own typescript range instead of the
root manifest and the sibling plugins.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019uZ84EhCM1NaBkJM8y1sjE
@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tests tooling labels Oct 27, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/cli, touching 3 documentable anchor(s).

6 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/deployment/cli.mdx (via os create (command, read off packages/cli/src/commands/create.ts))
  • content/docs/deployment/troubleshooting.mdx (via os create (command, read off packages/cli/src/commands/create.ts))
  • content/docs/getting-started/your-first-project.mdx (via os create (command, read off packages/cli/src/commands/create.ts))
  • content/docs/plugins/index.mdx (via os create (command, read off packages/cli/src/commands/create.ts))
  • content/docs/protocol/kernel/index.mdx (via os create (command, read off packages/cli/src/commands/create.ts))
  • content/docs/protocol/kernel/plugin-spec.mdx (via os create (command, read off packages/cli/src/commands/create.ts))

⛔ 2 release-owned page(s) also name something this change touched. These are read-only:

  • content/docs/releases/v17/17-4.mdx (via os create (command, read off packages/cli/src/commands/create.ts))
  • content/docs/releases/v18/18-1.mdx (via os create (command, read off packages/cli/src/commands/create.ts))

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

What this run could not see
  • 1 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 55 of 207 client-bound route-ledger rows — the other 152 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 152: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 55 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 97 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

Coarse fallback — 31 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json abb9046057b6713b78712dfe53a329deefa534ba → packageMentionDocs.

Which tree this was computed on

This run read content/docs from 708b1bd33b3b2967e571f1a2955841be7ebb8dde — the merge of head 89522f6b56da1a49da6881f728ccdaea7ec7fee1 into base abb9046057b6713b78712dfe53a329deefa534ba, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 708b1bd33b3b2967e571f1a2955841be7ebb8dde && git checkout 708b1bd33b3b2967e571f1a2955841be7ebb8dde
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin abb9046057b6713b78712dfe53a329deefa534ba 89522f6b56da1a49da6881f728ccdaea7ec7fee1 && git checkout -B drift-repro abb9046057b6713b78712dfe53a329deefa534ba && git merge --no-ff 89522f6b56da1a49da6881f728ccdaea7ec7fee1

node scripts/docs-audit/affected-docs.mjs --json abb9046057b6713b78712dfe53a329deefa534ba

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs abb9046057b6713b78712dfe53a329deefa534ba → pass the list as
args.docs, on the commit named under Which tree this was computed on.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对 · ACCEPT · domain:server seat 1 · os-project-manager · session_01R1q2xdtYgU6FKrZ7LgjPCC · 2026-10-27T02:12Z

Head 89522f6b56, report 6431771888 (on #26332), claim 6430900105 with amendments 6431310360 and 6431339243. Clause-②: no, not governed, no packages/spec/**: no contract review is owed.

item reading
Shape Draft, base main, Fixes #26332, patch changeset for @objectstack/cli. Not governed (0 of 6 paths), 215 changed lines.
Fix Triage 6428264123. TS5103: typescriptDependencySpec(placement) gives the in-repo placement IN_REPO_TYPESCRIPT_RANGE (^6.0.3, the workspace's range), and standalone keeps SCAFFOLD_TYPESCRIPT_RANGE. TS6133: the starter's init(_context), with a comment on what the parameter is for. The starter is shared, so the standalone src/index.ts takes the same rename; its manifest, tsconfig and range are unchanged. The seat accepts that.
Evidence 56 check runs succeeded and 6 were expected skips on this head, 0 failed; mergeable clean. create-in-repo-scaffold-typechecks.test.ts copies the real tsconfig.base.json into a sandbox and spawns the emitted typecheck and build (a TS6133 control included). It also pins the in-repo range to the package's own and standalone to SCAFFOLD_TYPESCRIPT_RANGE. Red on main 3 of 5, green 5 of 5, and the two-leg ablation is red. Test budget: three tsc spawns and no CLI spawn; module line 2.6–3.2 s, under 10 s, so no header. Derived gates: 90 of 90 exit 0.
Carried The tsconfig.base.json test input is declared in turbo.json, TURBO_ROOT_FILE_INPUTS and the cli roster (amendments above). check:cross-package-test-inputs exits 0.
Landing 「按照 pm-dispatch 规则复核过的都授权」 (Leehom, 2026-10-25T11:35Z): ready and auto-merge through the relay, once every check on this head is green or an expected skip.

Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 27, 2026 02:13
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 27, 2026 02:13
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 27, 2026
Merged via the queue into main with commit 13e5c0e Oct 27, 2026
63 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-z61um0 branch October 27, 2026 02:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

2 participants