You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-up to #10359 · Blocked-by: #10359 (its PR removes the agent generator and makes os g agent point here in prose; this card adds the scaffolder that prose says does not exist yet).
The maintainer's ruling on #10359 was Option A — retire the agent generator and add a skill generator, with explicit latitude: "The implementer is permitted to split the skill-generator half into its own card if that scopes better; the retirement half proceeds either way." This is that split. The retirement half is PR #11028; this is the second half, filed rather than dropped.
Placeholder spelling. GitHub's body sanitizer strips short angle-bracket fragments, including inside code fences and inline code — measured on the first revision of this very issue, where three of them vanished silently. Placeholders below are therefore spelled in CAPS (NAME, TYPE).
Why it was split off rather than done in the same PR
Adding a seventh GENERATORS entry looks mechanical and is not. Four things have to be decided first, and each of them is a decision rather than a template:
1. The generated filename does not match the loader's filePatterns
DEFAULT_METADATA_TYPE_REGISTRY (packages/spec/src/kernel/metadata-plugin.zod.ts) gives every metadata type a filePatterns shaped **/*.TYPE.ts, and skill is no exception:
But runMetadataGeneration in packages/cli/src/commands/generate.ts writes ${toSnakeCase(name)}.ts — no type infix. So os g skill lead-qualification would produce src/skills/lead_qualification.ts, which matches noskill file pattern, while real projects name theirs NAME.skill.ts (examples/app-crm/src/objects/account.object.ts, …/views/lead.view.ts, and so on for every type).
That is not a cosmetic mismatch on this type: skill is allowRuntimeCreate: true and is discovered from the filesystem, so a scaffold the pattern misses would validate, publish and never load — the exact silent-strip failure #10359 exists to close, re-entering through the fix for it. Getting it right means deciding one of:
give the harness a per-generator filename hook and use it for skill only (a divergence that needs a reason), or
change the harness convention to NAME.TYPE.ts for all seven types — which is arguably what the registry has said all along, and which changes every existing generator's output plus the docs and examples that show it.
The second option is a real repo-wide question and should not ride in on a skill template.
2. tools is required, with no default
SkillSchema declares tools: z.array(…) with no.optional() and no .default(), so a template must emit something. [] is the obvious placeholder and is not obviously right: ADR-0064 is entirely about tool scoping to an agent, and it records actions_executor's empty tools: [] plus a resolver fall-through as "the hole". That fall-through has since been closed (SkillSchema's own docblock now says an agent's tool set is the union of its surface-compatible skills' tools, with no global fall-through), but which default a scaffolder should teach — [], a commented example, or a wildcard family like action_* — is an authoring-guidance decision, not a fill-in-the-blank.
3. surface has to be chosen, and it is lint-checked
surface: 'ask' | 'build' | 'both' defaults to 'ask' in the schema, and ADR-0063 §3 binds a skill to an agent whose surface it matches, enforced at load. A scaffold either emits the key (teaching the author it exists, and picking for them) or omits it (silently taking 'ask'). Both are defensible; the choice belongs in this card.
4. The obvious copy source for the template is itself wrong
The @example blocks on SkillSchema and defineSkill (packages/spec/src/ai/skill.zod.ts) both pass triggerPhrases, which is a retiredKey() tombstone that rejects on parse. Verified at origin/main @ f334d662e:
packages/cli/README.md — the "Available generate types" roster and the same sentence.
packages/cli/src/commands/generate.ts's RETIRED_GENERATORS.agent.detail — the refusal tells the author os g skill does not exist; that line has to move with this card.
Tests + a changeset.
⛔ Repo-root skills/** is a governed surface and is not in scope — that directory is the published authoring-skill catalog (SKILL.md files for coding agents), a different thing from defineSkill agent skills. See content/docs/ai/skills.mdx for the two-meanings note.
Premise re-check commands
git grep -n "defaultDir" origin/main -- packages/cli/src/commands/generate.ts
git grep -n "type: 'skill'" origin/main -- packages/spec/src/kernel/metadata-plugin.zod.ts
ls examples/app-crm/src/objects # the naming convention real projects use
Follow-up to #10359 · Blocked-by: #10359 (its PR removes the
agentgenerator and makesos g agentpoint here in prose; this card adds the scaffolder that prose says does not exist yet).The maintainer's ruling on #10359 was Option A — retire the
agentgenerator and add askillgenerator, with explicit latitude: "The implementer is permitted to split the skill-generator half into its own card if that scopes better; the retirement half proceeds either way." This is that split. The retirement half is PR #11028; this is the second half, filed rather than dropped.Why it was split off rather than done in the same PR
Adding a seventh
GENERATORSentry looks mechanical and is not. Four things have to be decided first, and each of them is a decision rather than a template:1. The generated filename does not match the loader's
filePatternsDEFAULT_METADATA_TYPE_REGISTRY(packages/spec/src/kernel/metadata-plugin.zod.ts) gives every metadata type afilePatternsshaped**/*.TYPE.ts, andskillis no exception:But
runMetadataGenerationinpackages/cli/src/commands/generate.tswrites${toSnakeCase(name)}.ts— no type infix. Soos g skill lead-qualificationwould producesrc/skills/lead_qualification.ts, which matches noskillfile pattern, while real projects name theirsNAME.skill.ts(examples/app-crm/src/objects/account.object.ts,…/views/lead.view.ts, and so on for every type).That is not a cosmetic mismatch on this type:
skillisallowRuntimeCreate: trueand is discovered from the filesystem, so a scaffold the pattern misses would validate, publish and never load — the exact silent-strip failure #10359 exists to close, re-entering through the fix for it. Getting it right means deciding one of:skillonly (a divergence that needs a reason), orNAME.TYPE.tsfor all seven types — which is arguably what the registry has said all along, and which changes every existing generator's output plus the docs and examples that show it.The second option is a real repo-wide question and should not ride in on a skill template.
2.
toolsis required, with no defaultSkillSchemadeclarestools: z.array(…)with no.optional()and no.default(), so a template must emit something.[]is the obvious placeholder and is not obviously right: ADR-0064 is entirely about tool scoping to an agent, and it recordsactions_executor's emptytools: []plus a resolver fall-through as "the hole". That fall-through has since been closed (SkillSchema's own docblock now says an agent's tool set is the union of its surface-compatible skills' tools, with no global fall-through), but which default a scaffolder should teach —[], a commented example, or a wildcard family likeaction_*— is an authoring-guidance decision, not a fill-in-the-blank.3.
surfacehas to be chosen, and it is lint-checkedsurface: 'ask' | 'build' | 'both'defaults to'ask'in the schema, and ADR-0063 §3 binds a skill to an agent whose surface it matches, enforced at load. A scaffold either emits the key (teaching the author it exists, and picking for them) or omits it (silently taking'ask'). Both are defensible; the choice belongs in this card.4. The obvious copy source for the template is itself wrong
The
@exampleblocks onSkillSchemaanddefineSkill(packages/spec/src/ai/skill.zod.ts) both passtriggerPhrases, which is aretiredKey()tombstone that rejects on parse. Verified atorigin/main@f334d662e:Filed separately as #11026 — but whoever writes the template must not copy from there.
Scope
packages/cli/src/commands/generate.ts— askillentry (or whatever Add metamodel interfaces for ObjectQL/ObjectUI contract #1 decides), plus the filename question.content/docs/deployment/cli.mdx— the Available-types table, theos g …example block, and the retirement Callout PR fix(cli): retire theagentgenerator —os g agentnow names ADR-0063 and points at skills #11028 added, whose last sentence ("There is noos g skillscaffolder yet, so write that file by hand for now") becomes false the moment this lands.packages/cli/README.md— the "Available generate types" roster and the same sentence.packages/cli/src/commands/generate.ts'sRETIRED_GENERATORS.agent.detail— the refusal tells the authoros g skilldoes not exist; that line has to move with this card.⛔ Repo-root
skills/**is a governed surface and is not in scope — that directory is the published authoring-skill catalog (SKILL.mdfiles for coding agents), a different thing fromdefineSkillagent skills. Seecontent/docs/ai/skills.mdxfor the two-meanings note.Premise re-check commands
Generated by Claude Code