Repository navigation
feat(cli,create-objectstack): the starter wires src/security and src/datasets, os g permission/dataset, AGENTS.md names the package manager - #30258
Conversation
… permission/dataset, AGENTS.md names the package manager Claude-Session: https://claude.ai/code/session_01Utp6CaSDwi65gmZEL5wiWy Co-authored-by: Claude <noreply@anthropic.com>
… package manager Claude-Session: https://claude.ai/code/session_01Utp6CaSDwi65gmZEL5wiWy Co-authored-by: Claude <noreply@anthropic.com>
…folds Claude-Session: https://claude.ai/code/session_01Utp6CaSDwi65gmZEL5wiWy Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Utp6CaSDwi65gmZEL5wiWy Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Utp6CaSDwi65gmZEL5wiWy Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 3 package(s): 4 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 3 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 41 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 3907b0e9174260c67802a48ac891c51ab07baf63 && git checkout 3907b0e9174260c67802a48ac891c51ab07baf63
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 771b2db20ac08d78b7fec5c2bd1ee30de9aa26dc c45f7cb00c3c468531fc9d6248eb8297a2eb2c25 && git checkout -B drift-repro 771b2db20ac08d78b7fec5c2bd1ee30de9aa26dc && git merge --no-ff c45f7cb00c3c468531fc9d6248eb8297a2eb2c25
node scripts/docs-audit/affected-docs.mjs --json 771b2db20ac08d78b7fec5c2bd1ee30de9aa26dc
|
|
domain:server#4 · os-bill · session_01Utp6CZMkHvuDeVYgTD73qF 席位意见:ACCEPT。空模板一出生就有权限集和数据集的位置, 席位核对Head-sha:
|
Requested by Bill · project thread
domain:server#4 · os-bill · session_01Utp6CZMkHvuDeVYgTD73qF
维护者速读
npm create objectstack)自带已接线的空目录src/security(权限集)和src/datasets(分析数据集);os g permission/os g dataset两个新类型往这两处写文件;生成的 AGENTS.md 按建项目时实际用的包管理器写pnpm run …或npm run …。os g也生成不了,只能手工接线;pnpm 项目的 AGENTS.md 还一直写npm run。packages/cli/src/commands/generate.ts(permission / dataset 两个生成器,权限集默认授予读/建/改、readScope: 'own')、packages/create-objectstack/src/templates/blank/objectstack.config.ts(新增两条接线)、packages/create-objectstack/src/index.ts(AGENTS.md 填入包管理器)。pnpm --filter @objectstack/cli exec vitest run --project unit test/generate-scaffold-validates.test.ts src/commands/generate-permission-dataset.pin.test.ts,预期全部通过,其中os g 'permission'、os g 'dataset'两条在 validate/build/lint 下零发现。Fixes #30123
Clause-②: yes (widening) —
os generateaccepts two new type values,permissionanddataset; no flag or export is removed or narrowed.Metadata-protocol: none
What changes
Blank starter (
create-objectstack).src/security/index.tsandsrc/datasets/index.tsship as empty barrels, andobjectstack.config.tshands them to the stack's existingpermissionsanddatasetskeys through the sameexportsOf()helper as the eight directories it already wired. Both keys exist onObjectStackDefinitionSchematoday (permissions: z.array(PermissionSetSchema),datasets: z.array(DatasetSchema)), so no spec change. The generated AGENTS.md "Project Structure" block names both directories, and the two READMEs list them.os generate permission NAME [--object OBJECT]writessrc/security/NAME.permission.ts. The type key is the registry's own (permission, file pattern*.permission.ts), and the stack key issingularToPlural('permission')=permissions, so the generator rides the existing roster machinery:os initwires it,os greports reach, and every derived pin measures it. The scaffold is adefinePermissionSetgranting the bound object (from--object, or the stack's only object) read, create and edit without delete, withreadScope: 'own'written. Without a depth, a read grant on a private object is reported bysecurity-private-no-readscope(info), which the zero-findings pin refused;'own'states the same reach the object's sharing model gives instead of widening it, and the emitted comment names'org'.isDefaultis not written, and the comment says what it would do.os generate dataset NAME [--object OBJECT]writessrc/datasets/NAME.dataset.ts: adefineDatasetover the bound object with arecord_countcount measure, grouped by the record's title field when the object has one (no dimension otherwise).defineDatasettypes the literal as aDataset, so it needs noas const(the card's last measured point).Generated AGENTS.md names the package manager. The template's eight
npm runoccurrences are{{PM}} run, andwriteAgentGuidesfills{{PM}}with the managerdetectPackageManager()chose for the same run, the one the install line and "Next steps" already name. Both written copies (AGENTS.md,.github/copilot-instructions.md) carry it.Docs.
content/docs/deployment/cli.mdx(examples, types table,--object, "What it does") andpackages/cli/README.mdlist the two types.Deviation from the dispatch's suggested route: the types are
permissionanddataset, notpermission-set. The generator key is the registry type key, which names both the file infix (metadataFileName) and the stack key (singularToPlural);permission-sethas no registry entry and would map to no stack key.Tests
packages/cli/src/commands/generate-permission-dataset.pin.test.ts(new, unit): roster facts (directory, stack key, binds, file name), each scaffold loaded throughbundle-requireasos validateloads it parses underPermissionSetSchema/DatasetSchemawith the nameos greports, grants or covers only the bound object, and the no-title-field dataset case.generate-scaffold-validates(zero findings at any severity across validate/build/lint),scaffold-emission-typechecks,create-objectstack-wiring-parity(blank config and barrels byte-equal to whatos initrenders),generate-file-name-registry-parity,generate-scaffold-wiring, and the nightlygenerate-scaffolds-reach-stack.e2e/generate-scaffold-gates.e2e(run locally underOS_TEST_TIERS=nightly).packages/create-objectstack/src/scaffold-next-steps-pm.test.ts: a new describe scaffolds through the real CLI under a stub-pnpm PATH and a pnpm-less PATH and reads both written guides back:pnpm runand no barenpm run; controlnpm runand nopnpm; no unfilled placeholder either way.Acceptance notes
os init'srenderEmptyWiredBarrelfrom the type key and must stay byte-equal to it (wiring-parity pin), so the starter's copy says "permission", not "permission set".src/securityholds permission sets only, because its barrel feeds thepermissionskey. Positions, sharing rules and other security metadata still need their own barrel and key.Verification
Local runs, on ce2e6f6 (before the one merge of origin/main) unless a line names c45f7cb
pnpm --filter create-objectstack exec vitest run: Test Files 23 passed (23), Tests 362 passed (362), on ce2e6f6 and again on c45f7cb..replace(/\{\{PM\}\}/g, pm)removed fromindex.tsthroughscripts/ablation-replace.mjs⇒ both new AGENTS.md cases red (2 failed); restored, blob equal to HEAD,git diff HEADempty.pnpm --filter @objectstack/cli exec vitest run --project unit: 384 files, 5394 passed, 29 skipped; the 2 published-subpath files first refused becausepackages/cliwas not built, and passed (29/29) afterpnpm --filter @objectstack/cli build.--project integrationtest/create-objectstack-stack-reach.test.ts(and the picklist pin): 9 passed.OS_TEST_TIERS=nightlygenerate-scaffolds-reach-stack.e2e+generate-scaffold-gates.e2e: 58 passed.pnpm --filter @objectstack/cli --filter create-objectstack run typecheck: exit 0.pnpm lint: exit 0.dispatch-gates --commands(93 families),--ran: 89 run green, 4 NOT MEASURED (recorded exit 3, prerequisite not met in this shallow worktree:check-plugin-teardown-shape --self-testneeds an unshallow fetch,check:skill-examplesneeds client builds,check:dual-build-cjs-loadsandcheck:i18n-coverageneed packages outside this build closure). CI runs all four.🤖 Generated with Claude Code
https://claude.ai/code/session_01Utp6CaSDwi65gmZEL5wiWy
Generated by Claude Code