@timekast/factory 1.17.5 → 1.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -123,38 +123,39 @@ export const INVITE_ADMIN_SCRIPT_CMD = 'npx @timekast/factory invite-admin';
123
123
  export const INVITE_ADMIN_SCRIPT_FILE = 'scripts/tools/invite-admin.ts';
124
124
  /**
125
125
  * Kit-local reference generators — autogen of `project/reference/*` (INVENTORY,
126
- * CODEBASE, HOOKS, SCHEMA, API). Each shells a `scripts/tools/generate-*.mjs`
127
- * that ships with the FULL brain, so the installer ensures each alias ONLY when
128
- * its backing file exists (file-gated, insert-if-missing — same contract as
129
- * `preflight`). A derivative bootstrapped before a generator existed self-heals
130
- * the alias on the next `update`/`beta` (the script file arrives via `scripts/**`
131
- * in the tracked set, then the alias appears). Never overwrites a dev's own value.
126
+ * CODEBASE, HOOKS, SCHEMA, API). Each shells a `scripts/tools/generate-*.ts`
127
+ * (run via `tsx`, same as the other TS tools) that ships with the FULL brain, so
128
+ * the installer ensures each alias ONLY when its backing file exists (file-gated,
129
+ * insert-if-missing — same contract as `preflight`). A derivative bootstrapped
130
+ * before a generator existed self-heals the alias on the next `update`/`beta`
131
+ * (the script file arrives via `scripts/**` in the tracked set, then the alias
132
+ * appears). Never overwrites a dev's own value.
132
133
  */
133
134
  export const GENERATOR_SCRIPTS = [
134
135
  {
135
136
  name: 'generate:inventory',
136
- cmd: 'node scripts/tools/generate-inventory.mjs',
137
- file: 'scripts/tools/generate-inventory.mjs',
137
+ cmd: 'tsx scripts/tools/generate-inventory.ts',
138
+ file: 'scripts/tools/generate-inventory.ts',
138
139
  },
139
140
  {
140
141
  name: 'generate:codebase',
141
- cmd: 'node scripts/tools/generate-codebase.mjs',
142
- file: 'scripts/tools/generate-codebase.mjs',
142
+ cmd: 'tsx scripts/tools/generate-codebase.ts',
143
+ file: 'scripts/tools/generate-codebase.ts',
143
144
  },
144
145
  {
145
146
  name: 'generate:hooks',
146
- cmd: 'node scripts/tools/generate-hooks.mjs',
147
- file: 'scripts/tools/generate-hooks.mjs',
147
+ cmd: 'tsx scripts/tools/generate-hooks.ts',
148
+ file: 'scripts/tools/generate-hooks.ts',
148
149
  },
149
150
  {
150
151
  name: 'generate:schema',
151
- cmd: 'node scripts/tools/generate-schema.mjs',
152
- file: 'scripts/tools/generate-schema.mjs',
152
+ cmd: 'tsx scripts/tools/generate-schema.ts',
153
+ file: 'scripts/tools/generate-schema.ts',
153
154
  },
154
155
  {
155
156
  name: 'generate:api',
156
- cmd: 'node scripts/tools/generate-api.mjs',
157
- file: 'scripts/tools/generate-api.mjs',
157
+ cmd: 'tsx scripts/tools/generate-api.ts',
158
+ file: 'scripts/tools/generate-api.ts',
158
159
  },
159
160
  ];
160
161
  /**
@@ -165,5 +166,21 @@ export const GENERATOR_SCRIPTS = [
165
166
  * generator set shipped" (they ship together in the FULL brain).
166
167
  */
167
168
  export const GENERATE_REFERENCE_NAME = 'generate:reference';
168
- export const GENERATE_REFERENCE_CMD = 'node scripts/tools/generate-inventory.mjs && node scripts/tools/generate-codebase.mjs && node scripts/tools/generate-hooks.mjs && node scripts/tools/generate-schema.mjs && node scripts/tools/generate-api.mjs';
169
- export const GENERATE_REFERENCE_GATE_FILE = 'scripts/tools/generate-schema.mjs';
169
+ export const GENERATE_REFERENCE_CMD = 'tsx scripts/tools/generate-inventory.ts && tsx scripts/tools/generate-codebase.ts && tsx scripts/tools/generate-hooks.ts && tsx scripts/tools/generate-schema.ts && tsx scripts/tools/generate-api.ts';
170
+ export const GENERATE_REFERENCE_GATE_FILE = 'scripts/tools/generate-schema.ts';
171
+ /**
172
+ * Update-time healing registry: for each kit-owned script, the prior command(s)
173
+ * the kit used to ship. When the kit changes HOW a script is invoked (e.g. the
174
+ * `node`/`.mjs` → `tsx`/`.ts` migration of the reference generators), an existing
175
+ * derivative carries the OLD command in its `package.json`; `factory update`
176
+ * overwrites that stale kit-owned alias with the current command — but NEVER a
177
+ * value the dev diverged on their own (see `ensureFactoryScripts`). Add an entry
178
+ * whenever a kit-owned script's invocation changes, so existing derivatives
179
+ * self-heal on their next update instead of pointing at a deleted file.
180
+ */
181
+ export const OBSOLETE_SCRIPT_CMDS = {
182
+ ...Object.fromEntries(GENERATOR_SCRIPTS.map((g) => [g.name, [`node ${g.file.replace(/\.ts$/, '.mjs')}`]])),
183
+ [GENERATE_REFERENCE_NAME]: [
184
+ GENERATOR_SCRIPTS.map((g) => `node ${g.file.replace(/\.ts$/, '.mjs')}`).join(' && '),
185
+ ],
186
+ };
@@ -8,7 +8,7 @@
8
8
  import { existsSync, readFileSync, writeFileSync } from 'node:fs';
9
9
  import path from 'node:path';
10
10
  import { CLIError } from './cli-error.js';
11
- import { FACTORY_SCRIPTS, GENERATE_REFERENCE_CMD, GENERATE_REFERENCE_GATE_FILE, GENERATE_REFERENCE_NAME, GENERATOR_SCRIPTS, INVITE_ADMIN_SCRIPT_CMD, INVITE_ADMIN_SCRIPT_FILE, INVITE_ADMIN_SCRIPT_NAME, PREFLIGHT_SCRIPT_CMD, PREFLIGHT_SCRIPT_FILE, PREFLIGHT_SCRIPT_NAME, PROFILES, UPDATE_SCRIPT_NAME, } from './constants.js';
11
+ import { FACTORY_SCRIPTS, GENERATE_REFERENCE_CMD, GENERATE_REFERENCE_GATE_FILE, GENERATE_REFERENCE_NAME, GENERATOR_SCRIPTS, INVITE_ADMIN_SCRIPT_CMD, INVITE_ADMIN_SCRIPT_FILE, INVITE_ADMIN_SCRIPT_NAME, OBSOLETE_SCRIPT_CMDS, PREFLIGHT_SCRIPT_CMD, PREFLIGHT_SCRIPT_FILE, PREFLIGHT_SCRIPT_NAME, PROFILES, UPDATE_SCRIPT_NAME, } from './constants.js';
12
12
  /**
13
13
  * Auto-detect the profile to install into an existing repo from its
14
14
  * `package.json`: a `factoryVersion` field means the repo was born from the
@@ -82,6 +82,14 @@ function ensureFactoryScripts(pkg, extraScripts = {}) {
82
82
  else if (existing === cmd) {
83
83
  result = { action: 'already-correct' };
84
84
  }
85
+ else if ((OBSOLETE_SCRIPT_CMDS[name] ?? []).includes(existing)) {
86
+ // The value is a KNOWN-OBSOLETE kit command (e.g. the old `node …mjs` that
87
+ // the .ts migration retired) — heal it to the current command. A genuinely
88
+ // dev-divergent value falls through to `conflict` and is left intact.
89
+ scripts[name] = cmd;
90
+ changed = true;
91
+ result = { action: 'healed' };
92
+ }
85
93
  else {
86
94
  result = { action: 'conflict', existingValue: existing };
87
95
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timekast/factory",
3
- "version": "1.17.5",
3
+ "version": "1.18.0",
4
4
  "description": "Public, thin CLI to bootstrap and maintain TimeKast Factory derived projects.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",