Skip to content

Commit 250ccd2

Browse files
os-salesclaude
andcommitted
feat(cli)!: retire os create example; the refusal names os init (#16483)
The `example` template emitted a subset of what `os init` writes plus one README, the only template-level duplication #15531 found between the two scaffolder families. Removed under the #15531 ruling (batch #66, option B) with no alias and no deprecation window. The template is not merely deleted: `os create example` still answers, exits 1 and names `os init`, rather than falling through to `Unknown type:` and printing only the surviving roster. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YFY46JydE1gMxQG1TqBcMZ
1 parent 4fe00b8 commit 250ccd2

11 files changed

Lines changed: 573 additions & 164 deletions
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
---
2+
"@objectstack/cli": minor
3+
---
4+
5+
feat(cli)!: retire `os create example` — it was a weaker `os init` plus a README, and the refusal now names `os init` (#16483, #15531)
6+
7+
**BREAKING** — a published CLI surface is removed. `os create example <name>` is a
8+
command a user can run today and cannot run after this release. Graded `minor`
9+
rather than `major` under this repo's lockstep launch-window convention (no
10+
package here has ever shipped a `major` changeset); the break is stated here
11+
instead of in the number.
12+
13+
<!-- adr-0087: not-required (no-migration-prescription) the retired surface is a CLI subcommand, not authored metadata: no Zod schema, no `packages/spec` declaration, no authorable key and no stored `sys_metadata` shape changes, so `objectstack migrate meta` has nothing to rewrite and the ledger has no step to carry. The channel that reaches every affected caller is the command itself, which now exits non-zero naming `os init`. -->
14+
15+
**No alias and no deprecation window.** `os create example` will not come back,
16+
so change the command rather than pinning an older CLI.
17+
18+
#15531 rendered the real emission of both scaffolder families and hashed it file
19+
by file. The only template-level duplication left between them was this one
20+
template: `os create example` wrote a **subset** of what `os init` writes, plus
21+
one README. The two families' emission policy is already unified through four
22+
shared exports, so the remaining duplicate was the template itself — and the
23+
ruling (decision batch #66, option B) is that it goes, not that the two command
24+
families merge. They emit two different artifacts: a kernel code `Plugin` is not
25+
a declarative app, and collapsing them would make that collision structural.
26+
27+
**What to run instead**
28+
29+
```bash
30+
os init <name> # a full application project
31+
os init <name> -t empty # objectstack.config.ts only
32+
```
33+
34+
`os init` writes the same `objectstack.config.ts` and `tsconfig.json` the retired
35+
template did, and adds `src/objects`, a `.gitignore` and the dependency install
36+
it never had.
37+
38+
**`os create plugin` is unaffected.** It scaffolds the kernel code `Plugin`
39+
contract — `src/index.ts` exporting a `Plugin` with `init` / `destroy`, built by
40+
`tsc`, publishable as `@objectstack/plugin-<name>` — which `os init` does not
41+
emit. `os create`'s flags, its `--in-repo` placement and its standalone
42+
emission policy are unchanged.
43+
44+
**The removal is a signpost, not a deletion.** `os create example` still answers:
45+
it exits **1** and names `os init`, rather than falling through to the generic
46+
`Unknown type:` roster. A reader arriving from an older tutorial or a CI script
47+
that still calls it learns what replaced it instead of learning only that their
48+
spelling is off the list. Pinned end-to-end by driving the real CLI in
49+
`packages/cli/test/create-example-retired.e2e.test.ts`, which asserts both halves
50+
— the non-zero exit **and** the message naming `os init` — and holds the four
51+
public doc pages to the same promise.

content/docs/deployment/cli.mdx

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,7 +1241,7 @@ only.
12411241
| Command | Alias | Description |
12421242
|---------|-------|-------------|
12431243
| `os generate <type> <name>` | `os g` | Generate metadata files |
1244-
| `os create <type> [name]` | | Scaffold a standalone plugin or example project |
1244+
| `os create <type> [name]` | | Scaffold a standalone **kernel code** plugin project |
12451245

12461246
#### `os generate` (alias: `os g`)
12471247

@@ -1314,19 +1314,31 @@ third-party extension primitive, authored as `src/skills/<name>.skill.ts` with
13141314

13151315
#### `os create`
13161316

1317-
Scaffolds a **standalone** project — a **kernel code** plugin (the `Plugin` contract,
1317+
Scaffolds a **standalone** **kernel code** plugin project (the `Plugin` contract,
13181318
built by `tsc`, publishable; *not* the metadata plugin `os init -t plugin` emits — see
1319-
[Which scaffolder?](#os-init)), or an example application — into the current directory:
1319+
[Which scaffolder?](#os-init)) into the current directory:
13201320

13211321
```bash
13221322
os create plugin analytics # Create ./plugin-analytics
1323-
os create example my-app # Create ./my-app
13241323

13251324
cd plugin-analytics
13261325
pnpm install
13271326
pnpm build
13281327
```
13291328

1329+
<Callout type="warn" title="`os create example` is retired">
1330+
Use [`os init`](#os-init) to scaffold an application. `os create example` emitted a
1331+
subset of what `os init` writes plus one README, so it was withdrawn in
1332+
[#16483](https://github.com/objectstack-ai/objectstack/issues/16483) rather than kept as
1333+
a second, weaker way to do the same thing — with **no alias and no deprecation window**.
1334+
Running it now exits non-zero and names `os init`.
1335+
1336+
```bash
1337+
os init my-app # a full application project
1338+
os init my-app -t empty # objectstack.config.ts only
1339+
```
1340+
</Callout>
1341+
13301342
The emitted `package.json` declares its `@objectstack/*` dependencies as
13311343
published semver ranges pinned to the version of the CLI that generated it, and
13321344
the emitted `tsconfig.json` is self-contained, so the project installs and
@@ -1335,9 +1347,8 @@ builds anywhere — a workspace around it is neither needed nor assumed.
13351347
**Options:**
13361348
- `-d, --dir <directory>` — Write the project here instead of `./<name>`
13371349
- `--in-repo` — Scaffold **inside an ObjectStack monorepo checkout** instead
1338-
(`packages/plugins/<name>` for a plugin, `examples/<name>` for an example),
1339-
with `workspace:*` dependencies and a `tsconfig.json` that extends the
1340-
repository root config. For ObjectStack platform work only: the project it
1350+
(`packages/plugins/plugin-<name>`), with `workspace:*` dependencies and a
1351+
`tsconfig.json` that extends the repository root config. For ObjectStack platform work only: the project it
13411352
writes installs nowhere else, and the command refuses the flag when the
13421353
current directory is not a pnpm workspace root.
13431354

0 commit comments

Comments
 (0)