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.
- package/dist/core/FrameworkSessionStore.d.ts +43 -0
- package/dist/core/FrameworkSessionStore.d.ts.map +1 -0
- package/dist/core/FrameworkSessionStore.js +90 -0
- package/dist/core/FrameworkSessionStore.js.map +1 -0
- package/dist/core/PostUpdateMigrator.d.ts +16 -0
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +44 -9
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/PreCompactionFlush.d.ts +9 -0
- package/dist/core/PreCompactionFlush.d.ts.map +1 -1
- package/dist/core/PreCompactionFlush.js +10 -4
- package/dist/core/PreCompactionFlush.js.map +1 -1
- package/dist/core/ResumeValidator.d.ts +6 -0
- package/dist/core/ResumeValidator.d.ts.map +1 -1
- package/dist/core/ResumeValidator.js +10 -5
- package/dist/core/ResumeValidator.js.map +1 -1
- package/dist/core/types.d.ts +13 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +17 -17
- package/upgrades/1.0.11.md +61 -0
- package/upgrades/1.0.12.md +64 -0
- package/upgrades/side-effects/feat-portability-framework-gate.md +62 -0
- package/upgrades/side-effects/feat-portability-session-store.md +62 -0
|
@@ -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":"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;;;;;;;;;;;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;
|
|
1
|
+
{"version":3,"file":"PostUpdateMigrator.d.ts","sourceRoot":"","sources":["../../src/core/PostUpdateMigrator.ts"],"names":[],"mappings":"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"}
|
|
@@ -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
|
-
//
|
|
241
|
-
|
|
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)');
|