Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .changeset/scaffold-tsx-range-retired.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
'@objectstack/cli': patch
---

chore(cli): retire `SCAFFOLD_TSX_RANGE`, a conditional statement nothing satisfies

`SCAFFOLD_TSX_RANGE` and its docblock are removed from `src/commands/init.ts`. The
`os create example` template was the only emission that ever declared a `tsx` range,
and its retirement left the constant reaching no scaffold at all.

**The docblock is the reason, and it is not a false statement.** It read *"The `tsx`
range a scaffolded project declares **when its scripts need it**"* — a conditional
whose antecedent no longer holds anywhere on the tree. Vacuously true, so no review
looking for false statements catches it; what it misleads is a reader's default
assumption that some scaffold satisfies the antecedent.

**No surviving scaffold should declare `tsx`, measured rather than assumed.** All four
surviving emissions (`os init -t app` / `-t plugin` / `-t empty`, `os create plugin`)
plus the bundled `create-objectstack` blank template run every script they emit through
`objectstack`, `tsc` or `vitest`; none executes a `.ts` entrypoint directly, which is
the only thing `tsx` is for. The capability is not missing either: `@objectstack/cli`
— which every one of those emissions declares — carries `tsx` as its own dependency.
Declaring it a second time in a scaffold would have announced a lower floor
(`^4.21.0`) for a tool the project never names.

**Nothing importable is withdrawn.** This package's `exports` map is `.` / `./console`
/ `./hook-body` / `./package.json`, with no subpath pattern, and `src/index.ts`
re-exports only the oclif command classes — so no consumer could ever import this
symbol. It is a `patch` and not a breaking change for that reason, but it is not
`skip-changeset` either: the CLI builds with plain `tsc`, so the constant really did
ship. Measured across a before/after build of `packages/cli`, four files inside the
published `files[]` move — `dist/commands/init.js`, `dist/commands/init.d.ts` and both
`.map` siblings — and the other 496 are byte-identical.

No assertion is added for the retired range. `test/scaffold-emission-policy.e2e.test.ts`
already records why: a row in that table is owed by a range some emission really
declares, and by nothing else. Its comment is updated to describe the retirement rather
than the intermediate state it used to describe.
3 changes: 0 additions & 3 deletions packages/cli/src/commands/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,9 +317,6 @@ export const SCAFFOLD_VITEST_RANGE = '^4.0.0';
/** The `@types/node` range a scaffolded project declares. */
export const SCAFFOLD_TYPES_NODE_RANGE = '^22.0.0';

/** The `tsx` range a scaffolded project declares when its scripts need it. */
export const SCAFFOLD_TSX_RANGE = '^4.21.0';

/** The zod range a scaffolded project declares when it authors schemas. */
export const SCAFFOLD_ZOD_RANGE = '^4.3.6';

Expand Down
12 changes: 8 additions & 4 deletions packages/cli/test/scaffold-emission-policy.e2e.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,10 +204,14 @@ describe('scaffold emission policy — one definition, four emissions', () => {
it('emits the exported constant rather than a literal, for every policy range', () => {
const ranges = declaredRanges();
// ⚠️ `tsx` left this table with #16483: the retired `os create example`
// template was the only emission that declared it, so `SCAFFOLD_TSX_RANGE`
// now reaches no scaffold at all. Asserting it here anyway would compare an
// empty harvest against the constant and go red on a correct tree; a row is
// owed by a range some emission really declares, and by nothing else.
// template was the only emission that declared it. `SCAFFOLD_TSX_RANGE`
// has now been retired with it — every surviving emission runs its scripts
// through `objectstack`, `tsc` or `vitest`, none of which is invoked as
// `tsx`, so no emission declares that range. Asserting it here anyway
// would compare an empty harvest against a constant and go red on a
// correct tree; a row is owed by a range some emission really declares,
// and by nothing else — so this table grows a `tsx` row only after some
// emission declares one, never to keep a constant company.
const expected: Array<[string, string]> = [
['typescript', SCAFFOLD_TYPESCRIPT_RANGE],
['vitest', SCAFFOLD_VITEST_RANGE],
Expand Down
Loading