Skip to content

fix(create-objectstack): 远程模板的对象名改写被静默跳过 —— 5/6 已发布模板对新用户不可用 (#4926) - #4927

Merged
os-zhuang merged 2 commits into
mainfrom
claude/ci-errors-i1t8fi
Aug 4, 2026
Merged

fix(create-objectstack): 远程模板的对象名改写被静默跳过 —— 5/6 已发布模板对新用户不可用 (#4926)#4927
os-zhuang merged 2 commits into
mainfrom
claude/ci-errors-i1t8fi

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Closes#4926

npx create-objectstack@latest my-app -t todo(以及 compliance / content / contracts / procurement)产出的工程objectstack build 都过不去。6 个模板里 5 个如此,只有本仓库自带的 blank 是好的。夜间金丝雀 —— 那个存在意义就是当新用户探针的 workflow —— 连续 20 次定时运行全红(≥2026-07-27),因为它 if: github.event_name == 'schedule',PR 永远不跑,夜里没人看。

根因:同名文件、两套 schema

rewriteProjectIdentity 只从 objectstack.manifest.json 读模板原始 namespace。而这个文件名对应两种完全不同的文档:

自带 blank远程模板
schemaapp 形态$schema: …/template-manifest.json(注册表文档)
namespace没有
真实 namespacemanifest + config只在 objectstack.config.ts

于是远程模板一律读到 undefined,&& templateNamespace 守卫落空,对象名改写整段跳过;而 config 的 namespace:无条件改写的。结果 namespace: 'my_app'name: 'todo_task' 并存,违反 ${namespace}_${shortName}

代码注释本身留了线索 ——「Used to swap the bundled template's literal blank_ prefix」:这段逻辑从设计起就只考虑自带模板。

改动

抽出 src/rewrite-identity.ts(index.ts 在 import 时 program.parse(),里面的东西测不了 —— pkg-utils.ts 当初就是为此而拆):

  1. objectstack.config.ts 成为 namespace 的权威来源,manifest 降为回退。config 里的 namespace: 正是脚手架自己要改写的那个字面量,两者不可能不一致。
  2. 改写完成后自我校验。「静默什么都没做」和「本来就不需要做」在外部同形 —— 这个歧义正是本缺陷得以出厂的原因。残留任何旧前缀就抛错,指名文件与行号,把失败拉回脚手架现场,而不是留给用户的第一条 objectstack build

验证

objectstack-ai/templates@960f24d真实模板对新旧逻辑各跑一遍:

模板旧逻辑 namespace新逻辑应改写旧逻辑实改新逻辑残留
todoundefinedtodo700
complianceundefinedcompliance1700
contentundefinedcontent2200
contractsundefinedcontracts1200
procurementundefinedprocurement1600

生产上共 74 处对象名从未被改写。

其余闸门:

  • 10 个新单测,覆盖两种 manifest 形态、回退路径、两者皆无、以及 manifest 不可解析;
  • 自带 blank 无回归:实跑脚手架产出 namespace: 'regr_app' + name: 'regr_app_note';
  • 包内测试 28/28,tsc --noEmiteslint 均为 0 退出码。

未在本 PR 处理

金丝雀「只在夜里跑且无人看」这个结构性问题本身没修 —— 本 PR 只让它接下来会变绿。要不要给它加通知/让 PR 也跑,由维护者定。

🤖 Generated with Claude Code

https://claude.ai/code/session_01BbNVKv6KgPzuQ5p76nMgnf


Generated by Claude Code

…te for every remote template (#4926)
`npx create-objectstack@latest my-app -t <template>` produced a project that
could not build for 5 of the 6 offered templates. Only the bundled `blank`
worked. The nightly registry canary — the workflow whose entire purpose is to
be the new-user canary — had been red on all five for at least a week (20/20
scheduled runs since 2026-07-27), unseen because it runs only on `schedule`.
`rewriteProjectIdentity` read the template's original namespace from
`objectstack.manifest.json` alone, and that filename means two different
documents. The bundled template's is app-shaped and carries `namespace`; a
remote template's is the template-REGISTRY document
(`$schema: .../template-manifest.json`) and carries none — its namespace lives
only in `objectstack.config.ts`. So `templateNamespace` came back undefined for
every remote template, the `&& templateNamespace` guard fell through, and the
object-name rewrite was skipped entirely — while the config's `namespace:` was
rewritten unconditionally. That leaves `namespace: 'my_app'` beside
`name: 'todo_task'`, which the ${namespace}_${shortName} rule rejects.
Measured against the real templates at objectstack-ai/templates@960f24d, the old
code resolved `undefined` for all five and rewrote 0 of the 74 object names that
needed it: todo 7, compliance 17, content 22, contracts 12, procurement 16.
Two changes, in a new module because index.ts calls program.parse() on import
and nothing there is testable (the reason pkg-utils.ts already exists):
- `objectstack.config.ts` is now the AUTHORITY for the template namespace, with
the manifest as fallback. The config holds the very literal the scaffolder
overwrites, so the two cannot disagree.
- The rewrite VERIFIES ITSELF. A prefix rewrite that quietly does nothing is
indistinguishable from one that was not needed, and that ambiguity is what let
this ship. Any surviving stale prefix now throws, naming the files and lines,
at the scaffold — not in the user's first `objectstack build`.
Verified: 10 new unit tests covering both manifest shapes, the fallback, the
absent case and an unparseable manifest; all five real templates now resolve
their namespace and rewrite every literal with zero stale left; the bundled
blank template still scaffolds to `namespace: 'regr_app'` / `name:
'regr_app_note'`; package suite 28/28, tsc --noEmit and eslint clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BbNVKv6KgPzuQ5p76nMgnf
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BbNVKv6KgPzuQ5p76nMgnf
@vercel

vercelBot commented Aug 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
ProjectDeploymentActionsUpdated (UTC)
objectstackIgnoredIgnoredAug 3, 2026 4:32pm

Request Review

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation tests tooling labels Aug 3, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): create-objectstack.

8 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/skills-reference.mdx(via create-objectstack)
  • content/docs/ai/skills.mdx(via create-objectstack)
  • content/docs/deployment/self-hosting.mdx(via create-objectstack)
  • content/docs/getting-started/index.mdx(via create-objectstack)
  • content/docs/getting-started/your-first-project.mdx(via create-objectstack)
  • content/docs/plugins/packages.mdx(via create-objectstack)
  • content/docs/releases/v15.mdx(via create-objectstack)
  • content/docs/releases/v9.mdx(via create-objectstack)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@os-zhuang
os-zhuang marked this pull request as ready for review August 4, 2026 00:05
@os-zhuang
os-zhuang added this pull request to the merge queueAug 4, 2026
Merged via the queue into main with commit 8d41998Aug 4, 2026
25 checks passed
@os-zhuang
os-zhuang deleted the claude/ci-errors-i1t8fi branch August 4, 2026 00:13
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/mteststooling

Projects

None yet

2 participants

@os-zhuang@claude