instar 1.0.10 → 1.0.12

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.
@@ -0,0 +1,43 @@
1
+ /**
2
+ * FrameworkSessionStore — resolve a session's transcript file path for the
3
+ * runtime that produced it.
4
+ *
5
+ * Portability audit Gap 3. PreCompactionFlush and ResumeValidator hardcoded
6
+ * Claude Code's transcript convention (`~/.claude/projects/<encoded-cwd>/
7
+ * <sessionId>.jsonl`). A Codex session is never found there, so compaction
8
+ * flush and resume validation silently no-op for Codex agents.
9
+ *
10
+ * Codex's layout was determined empirically from a live ~/.codex/ (Codex CLI
11
+ * 0.78.0), NOT guessed:
12
+ * ~/.codex/sessions/YYYY/MM/DD/rollout-<ISO8601-dashes>-<uuid>.jsonl
13
+ * where the trailing <uuid> equals the session id (and the first JSONL line
14
+ * is a `session_meta` record whose payload.id is that same uuid). Sessions
15
+ * are date-partitioned, NOT cwd-keyed, so a Codex lookup globs by id across
16
+ * the date tree rather than building a deterministic path.
17
+ *
18
+ * Pure path resolution + filesystem lookup. No mutation, no network.
19
+ */
20
+ export type SessionFramework = 'claude-code' | 'codex-cli';
21
+ export interface ResolveTranscriptOptions {
22
+ framework: SessionFramework;
23
+ sessionId: string;
24
+ /** Project working directory (used by the Claude Code cwd-encoded path). */
25
+ projectDir: string;
26
+ /** Home dir override (testing). Defaults to os.homedir(). */
27
+ homeDir?: string;
28
+ /**
29
+ * Root override (testing). For claude-code this replaces
30
+ * `<home>/.claude/projects`; for codex-cli it replaces
31
+ * `<home>/.codex/sessions`.
32
+ */
33
+ rootOverride?: string;
34
+ }
35
+ /**
36
+ * Resolve the transcript path for a session under the given framework.
37
+ * Returns '' when it cannot be resolved (no session id, or — for Codex —
38
+ * no matching file on disk yet). Callers already treat '' / missing-file
39
+ * as "nothing to flush/validate", so the failure mode is a safe no-op,
40
+ * identical to the pre-Gap-3 Claude behavior.
41
+ */
42
+ export declare function resolveFrameworkTranscriptPath(opts: ResolveTranscriptOptions): string;
43
+ //# sourceMappingURL=FrameworkSessionStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FrameworkSessionStore.d.ts","sourceRoot":"","sources":["../../src/core/FrameworkSessionStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAMH,MAAM,MAAM,gBAAgB,GAAG,aAAa,GAAG,WAAW,CAAC;AAE3D,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,gBAAgB,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,UAAU,EAAE,MAAM,CAAC;IACnB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAoDD;;;;;;GAMG;AACH,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,wBAAwB,GAAG,MAAM,CASrF"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * FrameworkSessionStore — resolve a session's transcript file path for the
3
+ * runtime that produced it.
4
+ *
5
+ * Portability audit Gap 3. PreCompactionFlush and ResumeValidator hardcoded
6
+ * Claude Code's transcript convention (`~/.claude/projects/<encoded-cwd>/
7
+ * <sessionId>.jsonl`). A Codex session is never found there, so compaction
8
+ * flush and resume validation silently no-op for Codex agents.
9
+ *
10
+ * Codex's layout was determined empirically from a live ~/.codex/ (Codex CLI
11
+ * 0.78.0), NOT guessed:
12
+ * ~/.codex/sessions/YYYY/MM/DD/rollout-<ISO8601-dashes>-<uuid>.jsonl
13
+ * where the trailing <uuid> equals the session id (and the first JSONL line
14
+ * is a `session_meta` record whose payload.id is that same uuid). Sessions
15
+ * are date-partitioned, NOT cwd-keyed, so a Codex lookup globs by id across
16
+ * the date tree rather than building a deterministic path.
17
+ *
18
+ * Pure path resolution + filesystem lookup. No mutation, no network.
19
+ */
20
+ import * as fs from 'node:fs';
21
+ import * as os from 'node:os';
22
+ import * as path from 'node:path';
23
+ /**
24
+ * Claude Code: deterministic path
25
+ * `<home>/.claude/projects/<cwd with [/.] → ->/<sessionId>.jsonl`.
26
+ * This mirrors the exact pre-Gap-3 logic in PreCompactionFlush so the
27
+ * Claude path is byte-for-byte unchanged.
28
+ */
29
+ function claudeTranscriptPath(opts) {
30
+ const home = opts.homeDir ?? os.homedir();
31
+ const root = opts.rootOverride ?? path.join(home, '.claude', 'projects');
32
+ const encoded = opts.projectDir.replace(/[\/.]/g, '-');
33
+ return path.join(root, encoded, `${opts.sessionId}.jsonl`);
34
+ }
35
+ /**
36
+ * Codex CLI: glob `<home>/.codex/sessions/YYYY/MM/DD/rollout-*-<id>.jsonl`.
37
+ * Empirically the filename ends with `-<sessionId>.jsonl`. Returns the
38
+ * first match (a session id is unique), or '' when not found.
39
+ */
40
+ function codexTranscriptPath(opts) {
41
+ const home = opts.homeDir ?? os.homedir();
42
+ const root = opts.rootOverride ?? path.join(home, '.codex', 'sessions');
43
+ if (!fs.existsSync(root))
44
+ return '';
45
+ const suffix = `-${opts.sessionId}.jsonl`;
46
+ // sessions/YYYY/MM/DD/<file>. Walk at most 3 levels deep.
47
+ const years = safeReaddir(root);
48
+ for (const y of years) {
49
+ const yDir = path.join(root, y);
50
+ for (const m of safeReaddir(yDir)) {
51
+ const mDir = path.join(yDir, m);
52
+ for (const d of safeReaddir(mDir)) {
53
+ const dDir = path.join(mDir, d);
54
+ for (const f of safeReaddir(dDir)) {
55
+ if (f.startsWith('rollout-') && f.endsWith(suffix)) {
56
+ return path.join(dDir, f);
57
+ }
58
+ }
59
+ }
60
+ }
61
+ }
62
+ return '';
63
+ }
64
+ function safeReaddir(dir) {
65
+ try {
66
+ return fs.readdirSync(dir);
67
+ }
68
+ catch {
69
+ return [];
70
+ }
71
+ }
72
+ /**
73
+ * Resolve the transcript path for a session under the given framework.
74
+ * Returns '' when it cannot be resolved (no session id, or — for Codex —
75
+ * no matching file on disk yet). Callers already treat '' / missing-file
76
+ * as "nothing to flush/validate", so the failure mode is a safe no-op,
77
+ * identical to the pre-Gap-3 Claude behavior.
78
+ */
79
+ export function resolveFrameworkTranscriptPath(opts) {
80
+ if (!opts.sessionId)
81
+ return '';
82
+ switch (opts.framework) {
83
+ case 'codex-cli':
84
+ return codexTranscriptPath(opts);
85
+ case 'claude-code':
86
+ default:
87
+ return claudeTranscriptPath(opts);
88
+ }
89
+ }
90
+ //# sourceMappingURL=FrameworkSessionStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FrameworkSessionStore.js","sourceRoot":"","sources":["../../src/core/FrameworkSessionStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAmBlC;;;;;GAKG;AACH,SAAS,oBAAoB,CAAC,IAA8B;IAC1D,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;IAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IACzE,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IACvD,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,SAAS,QAAQ,CAAC,CAAC;AAC7D,CAAC;AAED;;;;GAIG;AACH,SAAS,mBAAmB,CAAC,IAA8B;IACzD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;IAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;IACxE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACpC,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,SAAS,QAAQ,CAAC;IAC1C,0DAA0D;IAC1D,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAChC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAChC,KAAK,MAAM,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;YAClC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YAChC,KAAK,MAAM,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;gBAClC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;gBAChC,KAAK,MAAM,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;oBAClC,IAAI,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;wBACnD,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;oBAC5B,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,WAAW,CAAC,GAAW;IAC9B,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,8BAA8B,CAAC,IAA8B;IAC3E,IAAI,CAAC,IAAI,CAAC,SAAS;QAAE,OAAO,EAAE,CAAC;IAC/B,QAAQ,IAAI,CAAC,SAAS,EAAE,CAAC;QACvB,KAAK,WAAW;YACd,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAC;QACnC,KAAK,aAAa,CAAC;QACnB;YACE,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC;AACH,CAAC"}
@@ -45,6 +45,22 @@ export declare class PostUpdateMigrator {
45
45
  */
46
46
  private stepEngine;
47
47
  constructor(config: MigratorConfig);
48
+ /**
49
+ * Resolve the set of frameworks this install actively uses, read from
50
+ * the persisted `.instar/config.json` `enabledFrameworks` field.
51
+ *
52
+ * Default (unset / empty / unreadable): `['claude-code']` — the
53
+ * historical behavior, so existing and dual-framework installs are
54
+ * unaffected. A Codex-only install sets `enabledFrameworks:
55
+ * ['codex-cli']`, which makes framework-specific migration steps that
56
+ * scaffold `.claude/`-only artifacts skip cleanly instead of writing
57
+ * files that runtime will never read.
58
+ *
59
+ * Single source of truth for the migrator's framework gating — both
60
+ * the parity-renderings backfill and the legacy `.claude/`-specific
61
+ * steps consult this.
62
+ */
63
+ private getEnabledFrameworks;
48
64
  /**
49
65
  * F-7 atomic-step primitive: register a step that will run once on
50
66
  * the release boundary where `step.version <= toVersion`. Idempotent
@@ -1 +1 @@
1
- {"version":3,"file":"PostUpdateMigrator.d.ts","sourceRoot":"","sources":["../../src/core/PostUpdateMigrator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PostUpdateMigrator.d.ts","sourceRoot":"","sources":["../../src/core/PostUpdateMigrator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AA8BH,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAC3B,MAAM,yBAAyB,CAAC;AAIjC,MAAM,WAAW,eAAe;IAC9B,wBAAwB;IACxB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,kCAAkC;IAClC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,2CAA2C;IAC3C,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAAiB;IAC/B;;;;;;OAMG;IACH,OAAO,CAAC,UAAU,CAAiC;gBAEvC,MAAM,EAAE,cAAc;IAIlC;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,oBAAoB;IAoB5B;;;;;;;;;;;OAWG;IACH,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI;IAItC;;;;;;OAMG;IACG,eAAe,CACnB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,qBAAqB,CAAC;IAIjC,OAAO,CAAC,aAAa;IAOrB;;;OAGG;IACH,OAAO,IAAI,eAAe;IA+C1B,OAAO,CAAC,4CAA4C;IA4CpD;;;;;;;;;;OAUG;IACG,YAAY,IAAI,OAAO,CAAC,eAAe,CAAC;YA4BhC,uBAAuB;IAkGrC,OAAO,CAAC,0BAA0B;IAkGlC,OAAO,CAAC,0BAA0B;IAkElC,OAAO,CAAC,oBAAoB;IAqH5B,OAAO,CAAC,8BAA8B;IA2EtC;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAaxB;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,0BAA0B;IA8BlC;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAW5B;;;;;;;;;OASG;IACH,OAAO,CAAC,kBAAkB;IA2B1B;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,OAAO,CAAC,yBAAyB;IA4HjC;6EACyE;IACzE,OAAO,CAAC,wBAAwB;IAShC;sDACkD;IAClD,OAAO,CAAC,wBAAwB;IAQhC;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAiKpB;;;;;;;;OAQG;IACH,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI;IA6CvE;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IA+DzB;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAkChC;;;;;;;;;OASG;IACH,OAAO,CAAC,wBAAwB;IAoEhC;;;;;;OAMG;IACH,OAAO,CAAC,oBAAoB;IAiE5B;;;;;OAKG;IACH,OAAO,CAAC,2BAA2B;IA8BnC;;;;OAIG;IACH,OAAO,CAAC,wBAAwB;IAwGhC;;;;;;OAMG;IACH,OAAO,CAAC,8BAA8B;IAwDtC,OAAO,CAAC,0BAA0B;IA8DlC;;;OAGG;IACH,OAAO,CAAC,eAAe;IAgXvB;;;OAGG;IACH,OAAO,CAAC,cAAc;IAwHtB;;;OAGG;IACH,OAAO,CAAC,eAAe;IAqOvB;;;OAGG;IACH,OAAO,CAAC,aAAa;IAqFrB;;;OAGG;IACH;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAqChC,OAAO,CAAC,gBAAgB;IAiBxB;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,OAAO,CAAC,qBAAqB;IAkE7B;;;;;;;;;;;;;;;;;;;OAmBG;IACH,OAAO,CAAC,0BAA0B;IAgDlC;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IAkC5B;;;;;;;;;;OAUG;IACH,OAAO,CAAC,kBAAkB;IA2C1B;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;IA+BzB,OAAO,CAAC,oBAAoB;IAgC5B;;;OAGG;IACH,OAAO,CAAC,aAAa;IAyBrB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAqC9B;;;OAGG;IACH,cAAc,CAAC,IAAI,EAAE,eAAe,GAAG,qBAAqB,GAAG,yBAAyB,GAAG,mBAAmB,GAAG,wBAAwB,GAAG,8BAA8B,GAAG,2BAA2B,GAAG,4BAA4B,GAAG,iBAAiB,GAAG,0BAA0B,GAAG,wBAAwB,GAAG,iBAAiB,GAAG,0BAA0B,GAAG,uBAAuB,GAAG,iBAAiB,GAAG,MAAM;IAoB3Z,oFAAoF;IACpF,iCAAiC,IAAI,MAAM;IAI3C,6EAA6E;IAC7E,yBAAyB,IAAI,MAAM;IAInC,OAAO,CAAC,mBAAmB;IA0V3B,OAAO,CAAC,wBAAwB;IAmEhC,OAAO,CAAC,2BAA2B;IA0DnC,OAAO,CAAC,yBAAyB;IAuGjC,OAAO,CAAC,2BAA2B;IAsHnC,OAAO,CAAC,qBAAqB;IAqP7B,OAAO,CAAC,uBAAuB;IA6H/B,OAAO,CAAC,2BAA2B;IA8GnC,OAAO,CAAC,iCAAiC;IA6DzC,OAAO,CAAC,4BAA4B;IA4LpC;;;;;;;;;;OAUG;IACH;;;;;;;;;;;OAWG;IAEH,gBAAuB,iCAAiC,EAAE,WAAW,CAAC,MAAM,CAAC,CA4B1E;IAEH;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,8BAA8B;IAiHtC,OAAO,CAAC,uBAAuB;IA4B/B;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAczB,OAAO,CAAC,sBAAsB;IAwC9B,OAAO,CAAC,iBAAiB;IAwBzB,OAAO,CAAC,mBAAmB;IAoB3B,OAAO,CAAC,8BAA8B;IAoHtC,OAAO,CAAC,+BAA+B;IAmJvC,OAAO,CAAC,oBAAoB;IAO5B,OAAO,CAAC,qBAAqB;IA4N7B,OAAO,CAAC,qBAAqB;IA4H7B,OAAO,CAAC,6BAA6B;IAyKrC,OAAO,CAAC,0BAA0B;IAgClC,OAAO,CAAC,gBAAgB;IAqFxB,OAAO,CAAC,6BAA6B;CAoCtC"}
@@ -52,6 +52,37 @@ export class PostUpdateMigrator {
52
52
  constructor(config) {
53
53
  this.config = config;
54
54
  }
55
+ /**
56
+ * Resolve the set of frameworks this install actively uses, read from
57
+ * the persisted `.instar/config.json` `enabledFrameworks` field.
58
+ *
59
+ * Default (unset / empty / unreadable): `['claude-code']` — the
60
+ * historical behavior, so existing and dual-framework installs are
61
+ * unaffected. A Codex-only install sets `enabledFrameworks:
62
+ * ['codex-cli']`, which makes framework-specific migration steps that
63
+ * scaffold `.claude/`-only artifacts skip cleanly instead of writing
64
+ * files that runtime will never read.
65
+ *
66
+ * Single source of truth for the migrator's framework gating — both
67
+ * the parity-renderings backfill and the legacy `.claude/`-specific
68
+ * steps consult this.
69
+ */
70
+ getEnabledFrameworks() {
71
+ try {
72
+ const configPath = path.join(this.config.stateDir, 'config.json');
73
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
74
+ const enabled = config.enabledFrameworks;
75
+ if (Array.isArray(enabled) && enabled.length > 0) {
76
+ const filtered = enabled.filter((f) => f === 'claude-code' || f === 'codex-cli');
77
+ if (filtered.length > 0)
78
+ return filtered;
79
+ }
80
+ }
81
+ catch {
82
+ // fall through to default
83
+ }
84
+ return ['claude-code'];
85
+ }
55
86
  /**
56
87
  * F-7 atomic-step primitive: register a step that will run once on
57
88
  * the release boundary where `step.version <= toVersion`. Idempotent
@@ -237,15 +268,8 @@ export class PostUpdateMigrator {
237
268
  // Lazy-import registry so PostUpdateMigrator doesn't pull the entire
238
269
  // parity graph at startup for agents that never invoke migrate().
239
270
  const { listParityRules } = await import('../providers/parity/registry.js');
240
- // Determine enabled frameworks from config — default to claude-code+codex-cli
241
- // for portable agents, claude-code-only as a safe fallback.
242
- const frameworks = (() => {
243
- const enabled = config.enabledFrameworks;
244
- if (Array.isArray(enabled) && enabled.length > 0) {
245
- return enabled.filter(f => f === 'claude-code' || f === 'codex-cli');
246
- }
247
- return ['claude-code'];
248
- })();
271
+ // Single source of truth for framework gating (see getEnabledFrameworks).
272
+ const frameworks = this.getEnabledFrameworks();
249
273
  const rules = listParityRules();
250
274
  let renderedCount = 0;
251
275
  let skippedCount = 0;
@@ -2126,6 +2150,17 @@ The user has been talking to you (possibly for days). A generic greeting like "H
2126
2150
  * Migrates legacy PostToolUse/Notification hooks to proper SessionStart type.
2127
2151
  */
2128
2152
  migrateSettings(result) {
2153
+ // Framework gate (portability audit Gap 5). `.claude/settings.json` is
2154
+ // Claude Code's hook/MCP configuration — it has zero meaning for a
2155
+ // Codex-only runtime. Skip the entire step when claude-code is not in
2156
+ // the enabled set so a Codex-only install is not scaffolded with
2157
+ // `.claude/` artifacts it will never read. Default (unset config) is
2158
+ // ['claude-code'], so existing and dual-framework installs are
2159
+ // unaffected.
2160
+ if (!this.getEnabledFrameworks().includes('claude-code')) {
2161
+ result.skipped.push('.claude/settings.json (skipped — claude-code not in enabledFrameworks)');
2162
+ return;
2163
+ }
2129
2164
  const settingsPath = path.join(this.config.projectDir, '.claude', 'settings.json');
2130
2165
  if (!fs.existsSync(settingsPath)) {
2131
2166
  result.skipped.push('.claude/settings.json (not found — will be created on next init)');