Repository navigation
fix(cli): os create plugin ships a starter test, so a fresh scaffold's npm test passes - #25236
Conversation
…s npm test passes Clause-②: no Metadata-protocol: none Claude-Session: https://claude.ai/code/session_01QkpbEcZUG5GHxLNpzuuR5y Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 1 package(s): 10 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 2 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 30 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 9d763a7352bbb2c9da45d932f4d64a618b019745 && git checkout 9d763a7352bbb2c9da45d932f4d64a618b019745
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 03de83bfe145eea8f495bcbc9886105715721b3f 2aed9ddea3b47346abc41f4fb08711e44fca7150 && git checkout -B drift-repro 03de83bfe145eea8f495bcbc9886105715721b3f && git merge --no-ff 2aed9ddea3b47346abc41f4fb08711e44fca7150
node scripts/docs-audit/affected-docs.mjs --json 03de83bfe145eea8f495bcbc9886105715721b3f
|
席位核对ACCEPT ·
Generated by Claude Code |
Requested by Sales · project thread
Fixes #25175
Clause-②: no
Metadata-protocol: none
This is the
os create pluginhalf of #25175, the half left after #25196 landed theos init -t pluginhalf (9c431bad3). With it, both plugin scaffolds pass their ownnpm testout of the box.What changes
A project made by
os create plugin NAMEdeclared"test": "vitest"and contained no test file, so its firstnpm testexited 1 withNo test files found, exiting with code 1. Theplugintemplate inpackages/cli/src/commands/create.ts(both placements) now:src/index.test.ts, a starter test that runs the checks the kernel runs on a plugin when it loads one, before any of its code: aname, aninitfunction (the loader'svalidatePluginStructure), and the protocol'sPluginSchema(assertPluginContract), through@objectstack/spec/kernel, which the manifest already declares. Its header links the@objectstack/verifyharness ("A runtime plugin" onprotocol/kernel/plugin-spec) for tests that need a booted kernel;tsconfig.build.json:extends: './tsconfig.json',exclude: ['dist', 'node_modules', 'src/**/*.test.ts'];build: 'tsc -p tsconfig.build.json',dev: 'tsc -p tsconfig.build.json --watch'andtest: 'vitest run'(one pass that exits, asos initemits).typecheckstaystsc --noEmit, ontsconfig.json.The three public pages whose printed file tree
create-plugin-docs-parity.test.tsholds equal to the emitted file set gain one line per new file:content/docs/plugins/index.mdx,content/docs/protocol/kernel/index.mdxandcontent/docs/protocol/kernel/plugin-spec.mdx(its CLI transcript, in emission order).Changeset:
.changeset/25175-create-plugin-scaffold-test.md(@objectstack/clipatch), with the one-line fix for a project scaffolded by an earlier release.The route, and why it is honest
The card allows a starter test or a script that does not fail on an empty suite. This takes the starter test. The previous dev's four measured placements (report on #25175) were re-measured on this branch:
npm testnpm run buildtypecheckcovers the testsrc/index.test.ts, build staystscdist/index.test.js+.d.tsemitted, the package ships its tests, and vitest collects the compiled copy toosrc/index.test.ts+tsconfig.build.jsondist/=index.js,index.d.ts; still 1 filetypechecktest/outsiderootDir: 'src'vitest run --passWithNoTestsS2 is the only row that keeps
dist/clean without hiding the test from the type checker. The pin below holds each of those properties, and the ablation shows each one can go red.The test is not a placeholder: emitted with
initrenamed tostart, it failsexpected 'undefined' to be 'function'; emitted withversion: 'v0.1.0',PluginSchemarefuses it (ablation legs E and F).Measured end to end (npm 10.9.4, registry
@objectstack/spec18.0.0, vitest 4.1.12, typescript 5.9.3)os create plugin e2e-pkgfrom this branch's built CLI, outside the repository, thennpx -y npm@10 install:npm testTest Files 1 passed (1),Tests 1 passed (1)npm run builddist/=index.d.ts,index.jsnpm testafter the buildTest Files 1 passed (1)npm run typechecknpm testwithsrc/index.test.tsremovedNo test files found, exiting with code 1main'sos create plugin,npm testNo test files found, exiting with code 1The pin, and its ablation
packages/cli/test/scaffold-test-script-passes.test.ts(unittier) gains anos createblock beside theos initone, sharing its sandbox (OS temp dir, no ancestor runner config, one symlink per declared dependency). Roster derived fromcreate'stemplates(default placement) whose manifest declarestest:testscript exits 0 and the files that ran are exactly the shipped test files;buildscript,dist/holdsindex.jsand no*.test.*, andteststill runs exactly the shipped files;typecheckpasses, and fails once a type error is planted in the starter test;test.Ablation through
scripts/ablation-replace.mjsoncreate.ts(imported by relative source specifier, nodist/on the path), each leg restored withblob == HEADandgit diff HEADempty:build: 'tsc'(S1)the build compiled the starter test into dist/: expected [ 'index.test.d.ts', 'index.test.js' ] to deeply equal []tsconfig.build.jsonwithout the test excludetypecheck: 'tsc -p tsconfig.build.json --noEmit'(test outside the checked program)a type error in the starter test passed typechecksrc/index.spec-off.tsvitest runfinds none)initrenamed tostartexpected 'undefined' to be 'function'v0.1.0PluginSchemaissue list not emptyVerification (head
2aed9ddea, after mergingorigin/main03de83bf; the two incoming commits touch none of these files)create-plugin-docs-parity+create:Test Files 3 passed (3),Tests 32 passed (32).@objectstack/cliunittier, full (vitest run --project unit --maxWorkers=2):Test Files 324 passed (324),Tests 4784 passed (4784). Theintegrationtier is declared to CI: the diff touches no spawn entry and no integration-tier file.pnpm --filter @objectstack/cli typecheck: exit 0,check:test-typecheckOK (no new signature). ESLint on the two changed TS files: clean.dispatch-gates.mjs --commands, pluscheck:template-version-syncandcheck:scaffold-emission-policy, exit 0. Four first exited 3 on prerequisites outside this diff (check-plugin-teardown-shape --self-testneeds a pinned commit a shallow clone lacks;check:skill-examples,check:dual-build-cjs-loadsandcheck:i18n-coveragereaddist/of packages outside the CLI closure) and exit 0 aftergit fetchof that commit and a fullpnpm build.Acceptance notes
--in-repoplacement gets the same three changes; its sandbox run is not pinned, because itstsconfig.jsonextends this monorepo's root config and means nothing outside it. Its emission is covered bycreate.test.tsand the docs-parity pin reads the default placement only, as before.os createstill saypnpm install/pnpm build; it does not mentionpnpm test. Unchanged here, to keep the plugin-spec transcript the only docs edit beyond the listings.claude/project-thread-4oxk47, notclaude/issue-25175-*; the claim on cli:os init -t pluginandos create pluginemit a test script but no test file, so the fresh scaffold'snpm testexits 1 with "No test files found" #25175 records that.Generated by Claude Code