devflow-kit 3.0.1 → 3.2.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.
- package/CHANGELOG.md +49 -0
- package/README.md +1 -1
- package/dist/agents/git.md +2 -2
- package/dist/cli/agents-view/index.js +1 -1
- package/dist/cli/agents-view/render.js +71 -17
- package/dist/cli/agents-view/state.js +42 -16
- package/dist/cli/agents-view/terminal.js +5 -5
- package/dist/cli/commands/agents.js +142 -51
- package/dist/cli/commands/ambient.js +1 -1
- package/dist/cli/commands/attribution-prompts.js +8 -8
- package/dist/cli/commands/capture.js +1 -1
- package/dist/cli/commands/compliance-prompts.js +8 -8
- package/dist/cli/commands/compliance.js +8 -7
- package/dist/cli/commands/flags.js +33 -31
- package/dist/cli/commands/hud.js +1 -1
- package/dist/cli/commands/init-seed.js +9 -9
- package/dist/cli/commands/init.js +162 -85
- package/dist/cli/commands/install-report.js +10 -10
- package/dist/cli/commands/learning.js +302 -136
- package/dist/cli/commands/memory.js +36 -15
- package/dist/cli/commands/proxy.js +23 -23
- package/dist/cli/commands/rules.js +6 -5
- package/dist/cli/commands/tracker-prompts.js +6 -6
- package/dist/cli/commands/tracker.js +9 -9
- package/dist/cli/commands/uninstall.js +183 -59
- package/dist/cli/flags-view/render.js +5 -5
- package/dist/cli/flags-view/state.js +9 -9
- package/dist/cli/flags-view/terminal.js +4 -4
- package/dist/cli/tui/cells.js +1 -1
- package/dist/cli/tui/terminal.js +6 -6
- package/dist/commands/code-review.md +0 -2
- package/dist/commands/debug.md +14 -11
- package/dist/commands/dynamic-build.md +51 -47
- package/dist/commands/dynamic-plan.md +27 -7
- package/dist/commands/dynamic-profile.md +17 -3
- package/dist/commands/dynamic-tickets.md +18 -4
- package/dist/commands/explore.md +9 -3
- package/dist/commands/implement.md +20 -16
- package/dist/commands/plan.md +13 -9
- package/dist/commands/release.md +23 -3
- package/dist/commands/research.md +9 -3
- package/dist/commands/resolve.md +9 -12
- package/dist/commands/self-review.md +0 -2
- package/dist/core/agent-frontmatter.js +28 -3
- package/dist/core/agent-models.js +204 -42
- package/dist/core/agent-state.js +28 -6
- package/dist/core/ansi.js +2 -2
- package/dist/core/assets.js +1 -1
- package/dist/core/cache.js +7 -8
- package/dist/core/codex-auth-inspect.js +4 -4
- package/dist/core/compliance-compose.js +3 -3
- package/dist/core/compliance.js +3 -4
- package/dist/core/evidence-policy.js +14 -13
- package/dist/core/external-models.js +1 -1
- package/dist/core/feature-config.js +71 -13
- package/dist/core/feature-switch.js +3 -3
- package/dist/core/flags.js +49 -25
- package/dist/core/fs-atomic.js +6 -7
- package/dist/core/learning-queue-cleanup.js +16 -81
- package/dist/core/learning-store.js +61 -0
- package/dist/core/linked-path.js +46 -0
- package/dist/core/manifest.js +5 -5
- package/dist/core/mds-variants.js +13 -13
- package/dist/core/model-discovery.js +8 -8
- package/dist/core/observations.js +17 -101
- package/dist/core/orphan-sweep.js +4 -4
- package/dist/core/plugins.js +13 -8
- package/dist/core/project-paths.js +9 -13
- package/dist/core/proxy-log.js +8 -8
- package/dist/core/proxy-state.js +3 -3
- package/dist/core/queue-drain.js +31 -0
- package/dist/core/reference-sweep.js +6 -6
- package/dist/core/teammate-mode-cleanup.js +1 -1
- package/dist/core/tracker.js +14 -14
- package/dist/hud/colors.js +2 -2
- package/dist/hud/components/learning-counts.js +54 -22
- package/dist/hud/components/version-badge.js +1 -1
- package/dist/skills/git/references/pr/resolve-review-threads.md +2 -2
- package/dist/skills/git/references/tracker/github/create-release.md +2 -2
- package/dist/skills/git/references/tracker/jira/create-release.md +2 -2
- package/dist/skills/git/references/tracker/linear/create-release.md +2 -2
- package/dist/targets/claude-code/compliance-install.js +17 -15
- package/dist/targets/claude-code/hooks.js +2 -2
- package/dist/targets/claude-code/installer.js +59 -32
- package/dist/targets/claude-code/legacy.js +1 -1
- package/dist/targets/claude-code/post-install.js +135 -45
- package/dist/targets/claude-code/tracker-install.js +2 -2
- package/package.json +1 -1
- package/src/assets/agents/code.md +15 -21
- package/src/assets/agents/design.md +4 -2
- package/src/assets/agents/diagnose.md +3 -1
- package/src/assets/agents/evaluate.md +4 -0
- package/src/assets/agents/git.mds +2 -2
- package/src/assets/agents/knowledge.md +5 -3
- package/src/assets/agents/learning.md +281 -196
- package/src/assets/agents/research.md +3 -1
- package/src/assets/agents/review.md +5 -3
- package/src/assets/agents/scrutinize.md +5 -1
- package/src/assets/agents/simplify.md +4 -0
- package/src/assets/agents/skim.md +4 -2
- package/src/assets/agents/synthesize.md +6 -0
- package/src/assets/agents/test.md +18 -10
- package/src/assets/agents/triage.md +11 -9
- package/src/assets/agents/validate.md +14 -10
- package/src/assets/commands/_partials/_decisions.mds +8 -3
- package/src/assets/commands/_partials/_docs_root.mds +3 -3
- package/src/assets/commands/_partials/_engine.mds +16 -32
- package/src/assets/commands/_partials/_knowledge.mds +0 -2
- package/src/assets/commands/_partials/_preamble.mds +6 -2
- package/src/assets/commands/_partials/_settings.mds +2 -2
- package/src/assets/commands/_partials/_tracker.mds +1 -1
- package/src/assets/commands/code-review.mds +0 -2
- package/src/assets/commands/debug.mds +13 -8
- package/src/assets/commands/dynamic-build.mds +18 -12
- package/src/assets/commands/dynamic-plan.mds +10 -4
- package/src/assets/commands/dynamic-profile.mds +1 -1
- package/src/assets/commands/dynamic-tickets.mds +2 -2
- package/src/assets/commands/explore.mds +9 -1
- package/src/assets/commands/implement.mds +19 -13
- package/src/assets/commands/plan.mds +12 -8
- package/src/assets/commands/release.md +23 -3
- package/src/assets/commands/research.mds +9 -3
- package/src/assets/commands/resolve.mds +9 -10
- package/src/assets/mds/git/_pr.mds +3 -3
- package/src/assets/mds/tracker/_common.mds +1 -1
- package/src/assets/mds/tracker/_github.mds +3 -3
- package/src/assets/mds/tracker/_jira.mds +3 -3
- package/src/assets/mds/tracker/_linear.mds +3 -3
- package/src/assets/mds/tracker/_mcp.mds +6 -5
- package/src/assets/scripts/hooks/assets/orchestrator-charter.md +4 -2
- package/src/assets/scripts/hooks/background-memory-update +97 -33
- package/src/assets/scripts/hooks/capture-prompt +4 -3
- package/src/assets/scripts/hooks/capture-question +4 -3
- package/src/assets/scripts/hooks/capture-turn +5 -20
- package/src/assets/scripts/hooks/ensure-devflow-init +14 -2
- package/src/assets/scripts/hooks/ensure-proxy +5 -6
- package/src/assets/scripts/hooks/ensure-root-gitignore +123 -11
- package/src/assets/scripts/hooks/git-marker +71 -0
- package/src/assets/scripts/hooks/is-hex-sha +1 -1
- package/src/assets/scripts/hooks/json-helper.cjs +345 -944
- package/src/assets/scripts/hooks/json-parse +25 -129
- package/src/assets/scripts/hooks/lib/decisions-format.cjs +205 -156
- package/src/assets/scripts/hooks/lib/learning-store.cjs +3207 -0
- package/src/assets/scripts/hooks/lib/mkdir-lock.cjs +7 -5
- package/src/assets/scripts/hooks/lib/project-paths.cjs +13 -19
- package/src/assets/scripts/hooks/lib/render-decisions.cjs +253 -226
- package/src/assets/scripts/hooks/memory-worker +10 -0
- package/src/assets/scripts/hooks/pre-compact-memory +66 -14
- package/src/assets/scripts/hooks/preamble +9 -1
- package/src/assets/scripts/hooks/queue-append +55 -23
- package/src/assets/scripts/hooks/resolve-project-root +3 -4
- package/src/assets/scripts/hooks/session-start-context +146 -45
- package/src/assets/scripts/hooks/session-start-memory +33 -11
- package/src/assets/scripts/lib/project-config.cjs +2 -2
- package/src/assets/scripts/pr-evidence.cjs +3 -3
- package/src/assets/scripts/redact-secrets.cjs +20 -20
- package/src/assets/scripts/release-trace.cjs +1 -1
- package/src/assets/scripts/resolve-evidence-policy.cjs +3 -3
- package/src/assets/scripts/resolve-settings.cjs +3 -3
- package/src/assets/scripts/verify-evidence.cjs +2 -2
- package/src/assets/skills/apply-decisions/SKILL.md +37 -17
- package/src/assets/skills/docs-framework/SKILL.md +2 -2
- package/src/assets/skills/feature-knowledge/SKILL.md +6 -5
- package/src/assets/skills/test-driven-development/SKILL.md +6 -4
- package/dist/core/observation-io.js +0 -50
- package/src/assets/scripts/hooks/decisions-usage-scan.cjs +0 -131
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
* - createFlagsCommand() factory — fresh Commander instance per call;
|
|
6
6
|
* used by tests; src/cli.ts consumes the flagsCommand singleton export.
|
|
7
7
|
* - Persist pipeline: convergeFlagsIntoSettings (fold-before-strip) — the
|
|
8
|
-
* single pipeline entry point shared with init.ts (ARCH-H1
|
|
9
|
-
* -
|
|
8
|
+
* single pipeline entry point shared with init.ts (ARCH-H1).
|
|
9
|
+
* - process.exit swallows async work: all error paths set
|
|
10
10
|
* process.exitCode = 1 and return; never call process.exit().
|
|
11
|
-
* -
|
|
11
|
+
* - Multi-artifact fan-out: compute record first; settings write
|
|
12
12
|
* and manifest write handled independently with their own error paths.
|
|
13
|
-
* -
|
|
13
|
+
* - Applies-on-restart: bare non-TTY invocation prints status table
|
|
14
14
|
* with a note that changes apply on restart.
|
|
15
|
-
* -
|
|
15
|
+
* - Validate at the sink: parseFlagValueInput → coerceFlagValue
|
|
16
16
|
* runs inside the core helpers before any write.
|
|
17
17
|
*/
|
|
18
18
|
import { Command } from 'commander';
|
|
@@ -25,7 +25,7 @@ import { FLAG_REGISTRY, findFlag, convergeFlagsIntoSettings, parseFlagValueInput
|
|
|
25
25
|
import { readManifest, writeManifest } from '../../core/manifest.js';
|
|
26
26
|
import { writeSettingsFileAtomic } from '../../core/fs-atomic.js';
|
|
27
27
|
import { sanitizeCell } from '../tui/cells.js';
|
|
28
|
-
// Static imports for pure view-state helpers — no TTY machinery
|
|
28
|
+
// Static imports for pure view-state helpers — no TTY machinery.
|
|
29
29
|
// runFlagsTui stays lazily imported in handleBare to keep TTY module out of
|
|
30
30
|
// --list/--status code paths; buildFlagRows and collectFlagRecord are pure.
|
|
31
31
|
import { buildFlagRows, collectFlagRecord } from '../flags-view/state.js';
|
|
@@ -36,7 +36,7 @@ import { buildFlagRows, collectFlagRecord } from '../flags-view/state.js';
|
|
|
36
36
|
* Malformed JSON → returns `{ ok: false, reason: string }`.
|
|
37
37
|
*
|
|
38
38
|
* NEVER silently falls back to '{}' on malformed JSON — that would clobber the
|
|
39
|
-
* user's settings. The caller must abort with exit code 1 on !ok
|
|
39
|
+
* user's settings. The caller must abort with exit code 1 on !ok.
|
|
40
40
|
*/
|
|
41
41
|
async function readSettingsSafe(settingsPath) {
|
|
42
42
|
let raw;
|
|
@@ -51,7 +51,7 @@ async function readSettingsSafe(settingsPath) {
|
|
|
51
51
|
}
|
|
52
52
|
// REL-M2 + PERF-L4: single parse — validate root shape and return raw string.
|
|
53
53
|
// The plain-object guard catches null/array roots before they reach applyFlags/stripFlags
|
|
54
|
-
// (
|
|
54
|
+
// (validate at the sink; early rejection gives actionable error messages).
|
|
55
55
|
let parsed;
|
|
56
56
|
try {
|
|
57
57
|
parsed = JSON.parse(raw);
|
|
@@ -69,18 +69,19 @@ async function readSettingsSafe(settingsPath) {
|
|
|
69
69
|
*
|
|
70
70
|
* Uses `convergeFlagsIntoSettings` (ARCH-H1: fold-before-strip pipeline) so the
|
|
71
71
|
* invariant lives in the pipeline, not at call sites. This ensures that:
|
|
72
|
-
* - An externally-set /focus survives unless viewModeExplicit is true
|
|
72
|
+
* - An externally-set /focus survives unless viewModeExplicit is true.
|
|
73
73
|
* - Valued flags not yet claimed by devflow (absent from the manifest record)
|
|
74
74
|
* have their existing settings values preserved rather than stripped (REG-H1,
|
|
75
|
-
* SEC-M3
|
|
75
|
+
* SEC-M3).
|
|
76
76
|
*
|
|
77
|
-
*
|
|
77
|
+
* Settings write and manifest write are evaluated independently.
|
|
78
78
|
* Each failure is reported with its own message and exit code 1.
|
|
79
79
|
* The second write is never skipped due to the first succeeding or failing.
|
|
80
80
|
*
|
|
81
81
|
* Returns a discriminated PersistResult (never a boolean — avoids the two-state
|
|
82
82
|
* lie that cannot express the third "manifest absent" outcome). Success is tracked
|
|
83
|
-
* in LOCALS, never read back off `process.exitCode
|
|
83
|
+
* in LOCALS, never read back off `process.exitCode`, which is process-wide and
|
|
84
|
+
* may already have been set by an earlier, unrelated failure.
|
|
84
85
|
*/
|
|
85
86
|
async function persistFlagConfig(claudeDir, devflowDir, settingsContent, newRecord,
|
|
86
87
|
// ARCH-M2 + PERF-L1: caller passes the already-read manifest so this function
|
|
@@ -88,14 +89,14 @@ async function persistFlagConfig(claudeDir, devflowDir, settingsContent, newReco
|
|
|
88
89
|
// = extra write). null → {ok:false,reason:'no-manifest'} (C2 discriminant intact).
|
|
89
90
|
manifest, opts = { viewModeExplicit: false }) {
|
|
90
91
|
// D15: convergeFlagsIntoSettings is the fold-before-strip pipeline entry point
|
|
91
|
-
// (
|
|
92
|
+
// (REG-H1, ARCH-H1). ownedRecord is omitted so the
|
|
92
93
|
// `newRecord` (the manifest record) serves as the owned set — a key present in
|
|
93
94
|
// the manifest means devflow previously claimed it; absent = never written by
|
|
94
95
|
// devflow, so the existing settings value is adopted.
|
|
95
96
|
const { settings: updatedSettings, record: foldedRecord } = convergeFlagsIntoSettings(settingsContent, newRecord, opts);
|
|
96
|
-
//
|
|
97
|
+
// Accumulate each artifact's failure independently; combine at the end.
|
|
97
98
|
const failed = [];
|
|
98
|
-
// Settings write — independent error path
|
|
99
|
+
// Settings write — independent error path.
|
|
99
100
|
const settingsPath = path.join(claudeDir, 'settings.json');
|
|
100
101
|
try {
|
|
101
102
|
await writeSettingsFileAtomic(settingsPath, updatedSettings);
|
|
@@ -104,9 +105,9 @@ manifest, opts = { viewModeExplicit: false }) {
|
|
|
104
105
|
p.log.error(`Failed to write settings.json: ${err instanceof Error ? err.message : String(err)}`);
|
|
105
106
|
failed.push('settings');
|
|
106
107
|
process.exitCode = 1;
|
|
107
|
-
//
|
|
108
|
+
// Still attempt the manifest write — evaluate each artifact independently.
|
|
108
109
|
}
|
|
109
|
-
// Manifest write — independent error path
|
|
110
|
+
// Manifest write — independent error path.
|
|
110
111
|
// Uses foldedRecord (not newRecord) so adopted values are persisted to the
|
|
111
112
|
// manifest, keeping manifest ↔ settings.json in sync.
|
|
112
113
|
//
|
|
@@ -129,17 +130,17 @@ manifest, opts = { viewModeExplicit: false }) {
|
|
|
129
130
|
failed.push('manifest');
|
|
130
131
|
process.exitCode = 1;
|
|
131
132
|
}
|
|
132
|
-
//
|
|
133
|
+
// OR the locals afterwards — never compose required side effects with ||/&&.
|
|
133
134
|
return failed.length > 0 ? { ok: false, failed } : { ok: true };
|
|
134
135
|
}
|
|
135
136
|
/**
|
|
136
137
|
* Load manifest and settings.json for the mutating CLI branches.
|
|
137
138
|
*
|
|
138
139
|
* Returns a discriminated result — never exits itself. The dispatcher or handler
|
|
139
|
-
* reports the reason and sets process.exitCode = 1 on failure
|
|
140
|
-
* One shared load path means a fix lands once, not four times (
|
|
141
|
-
*
|
|
142
|
-
*
|
|
140
|
+
* reports the reason and sets process.exitCode = 1 on failure.
|
|
141
|
+
* One shared load path means a fix lands once, not four times (the four copies
|
|
142
|
+
* of the same preamble are exactly the "fix on one site, miss the other three"
|
|
143
|
+
* shape).
|
|
143
144
|
*/
|
|
144
145
|
async function loadFlagContext(claudeDir, devflowDir) {
|
|
145
146
|
const manifest = await readManifest(devflowDir);
|
|
@@ -225,7 +226,7 @@ async function handleStatus(devflowDir) {
|
|
|
225
226
|
* Collapsed from two identical 50-line branches into one handler parameterized by
|
|
226
227
|
* `value: boolean` — the only deltas were the record assignment (true vs false)
|
|
227
228
|
* and one error-message string (--set vs --unset as the suggested alternative)
|
|
228
|
-
* (CPLX-H2
|
|
229
|
+
* (CPLX-H2: one fix lands once, not twice).
|
|
229
230
|
*/
|
|
230
231
|
async function handleSetBooleans(claudeDir, devflowDir, ids, value) {
|
|
231
232
|
// Validate: must be known boolean flags only.
|
|
@@ -255,7 +256,7 @@ async function handleSetBooleans(claudeDir, devflowDir, ids, value) {
|
|
|
255
256
|
process.exitCode = 1;
|
|
256
257
|
return;
|
|
257
258
|
}
|
|
258
|
-
//
|
|
259
|
+
// Compute new record before any write
|
|
259
260
|
const newRecord = { ...ctx.value.manifest.features.flags };
|
|
260
261
|
for (const flag of flagDefs) {
|
|
261
262
|
newRecord[flag.id] = value;
|
|
@@ -283,7 +284,7 @@ async function handleSet(claudeDir, devflowDir, setValues) {
|
|
|
283
284
|
}
|
|
284
285
|
const id = assignment.slice(0, eqIdx);
|
|
285
286
|
const text = assignment.slice(eqIdx + 1);
|
|
286
|
-
// Prototype pollution guard
|
|
287
|
+
// Prototype pollution guard
|
|
287
288
|
if (id === '__proto__' || id === 'constructor' || id === 'prototype') {
|
|
288
289
|
p.log.error(`Unknown flag: ${color.bold(id)}`);
|
|
289
290
|
process.exitCode = 1;
|
|
@@ -314,7 +315,7 @@ async function handleSet(claudeDir, devflowDir, setValues) {
|
|
|
314
315
|
process.exitCode = 1;
|
|
315
316
|
return;
|
|
316
317
|
}
|
|
317
|
-
//
|
|
318
|
+
// Compute final record before any write
|
|
318
319
|
const newRecord = { ...ctx.value.manifest.features.flags };
|
|
319
320
|
for (const { id, flag, value } of assignments) {
|
|
320
321
|
// null from parseFlagValueInput for literal 'unset' → use neutral value
|
|
@@ -355,7 +356,7 @@ async function handleUnset(claudeDir, devflowDir, ids) {
|
|
|
355
356
|
process.exitCode = 1;
|
|
356
357
|
return;
|
|
357
358
|
}
|
|
358
|
-
//
|
|
359
|
+
// Compute new record before any write
|
|
359
360
|
const newRecord = { ...ctx.value.manifest.features.flags };
|
|
360
361
|
for (const flag of flagDefs) {
|
|
361
362
|
newRecord[flag.id] = neutralValueOf(flag);
|
|
@@ -373,9 +374,9 @@ async function handleUnset(claudeDir, devflowDir, ids) {
|
|
|
373
374
|
* Apply a TUI result to disk — the save/persist seam extracted from handleBare.
|
|
374
375
|
*
|
|
375
376
|
* Enables seam testing of the TUI→persist wiring without a real TTY (closes
|
|
376
|
-
* the interactive-surface coverage gap
|
|
377
|
+
* the interactive-surface coverage gap). The test drives
|
|
377
378
|
* runFlagsTui with PassThrough streams, feeds its result here, and asserts
|
|
378
|
-
* the whole post-state of both artifacts (manifest + settings.json)
|
|
379
|
+
* the whole post-state of both artifacts (manifest + settings.json).
|
|
379
380
|
*
|
|
380
381
|
* @param result TUI result from runFlagsTui — action 'save', 'cancel', or 'abort'.
|
|
381
382
|
* @param freshSettingsContent Settings.json content re-read AFTER the TUI closed
|
|
@@ -441,7 +442,8 @@ async function handleBare(claudeDir, devflowDir) {
|
|
|
441
442
|
// ── Launch TUI ────────────────────────────────────────────────────
|
|
442
443
|
const { runFlagsTui } = await import('../flags-view/index.js');
|
|
443
444
|
// Wrap: runTui rejects on initial-render failure or handler throw.
|
|
444
|
-
// On rejection: log and bail — no settings write
|
|
445
|
+
// On rejection: log and bail — no settings write; set process.exitCode
|
|
446
|
+
// rather than calling process.exit(), which would skip pending cleanup.
|
|
445
447
|
let result;
|
|
446
448
|
try {
|
|
447
449
|
result = await runFlagsTui(initialRows);
|
|
@@ -458,7 +460,7 @@ async function handleBare(claudeDir, devflowDir) {
|
|
|
458
460
|
// Code /config) that ran during the session would be silently overwritten by
|
|
459
461
|
// the atomic rename in writeSettingsFileAtomic. Re-reading rebases the flag
|
|
460
462
|
// write onto current content and ensures convergeFlagsIntoSettings sees the
|
|
461
|
-
// fresh viewMode (
|
|
463
|
+
// fresh viewMode (file state, not config state, is reality).
|
|
462
464
|
const freshSettings = await readSettingsSafe(path.join(claudeDir, 'settings.json'));
|
|
463
465
|
if (!freshSettings.ok) {
|
|
464
466
|
p.log.error(freshSettings.reason);
|
package/dist/cli/commands/hud.js
CHANGED
|
@@ -71,7 +71,7 @@ const DEVFLOW_STATUSLINE_SUFFIXES = [
|
|
|
71
71
|
* any parent directory — so installs from the custom-directory and local-scope era
|
|
72
72
|
* are still recognised. A bare `statusline.sh` (the Claude Code docs' own example,
|
|
73
73
|
* `~/.claude/statusline.sh`) or a path that merely contains a `devflow` segment is
|
|
74
|
-
* the user's (
|
|
74
|
+
* the user's (remove or replace only what devflow provably wrote).
|
|
75
75
|
* Backslashes are read as slashes so a Windows install is matched the same way. A
|
|
76
76
|
* hand-edited command that is not a string is the user's, as in `endsWithAny`.
|
|
77
77
|
*
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* All exported functions are pure — no I/O, no side effects.
|
|
10
10
|
*
|
|
11
|
-
*
|
|
11
|
+
* Seeding helpers are CLI-init-specific logic, so they live
|
|
12
12
|
* beside init.ts in src/cli/commands/ rather than in src/core/ (which holds
|
|
13
13
|
* agent-neutral, target-agnostic utilities).
|
|
14
14
|
*/
|
|
@@ -36,8 +36,8 @@ export const FEATURE_DEFAULTS = {
|
|
|
36
36
|
* memory, learning and knowledge are recorded in the manifest alone (a repository
|
|
37
37
|
* only narrows them at read time), so the seed takes no per-repo input at all. Seeding from whatever repo init happens to run in
|
|
38
38
|
* would flip the switch for EVERY repo as a side effect — a stale per-repo
|
|
39
|
-
* `true` would silently re-enable a feature the user turned off.
|
|
40
|
-
*
|
|
39
|
+
* `true` would silently re-enable a feature the user turned off. State-aware
|
|
40
|
+
* re-init preserves the prior machine-wide choice, the manifest's.
|
|
41
41
|
*/
|
|
42
42
|
export function resolveSeedFeatures(manifest) {
|
|
43
43
|
const ambient = manifest?.features.ambient ?? FEATURE_DEFAULTS.ambient;
|
|
@@ -63,7 +63,7 @@ export function resolveSeedFeatures(manifest) {
|
|
|
63
63
|
* Resolve the flag record for the init seed.
|
|
64
64
|
*
|
|
65
65
|
* Returns a FlagsRecord containing ALL registry flags at their resolved values.
|
|
66
|
-
* FlagsRecord key-presence encodes the "known" concept
|
|
66
|
+
* FlagsRecord key-presence encodes the "known" concept: present key =
|
|
67
67
|
* known at last install, absent key = new to this install → adopt default on seed.
|
|
68
68
|
*
|
|
69
69
|
* @param manifestFlags - FlagsRecord from the manifest, or null for fresh install.
|
|
@@ -72,11 +72,11 @@ export function resolveSeedFeatures(manifest) {
|
|
|
72
72
|
* Rules:
|
|
73
73
|
* - null manifestFlags (fresh install) → all flags at registry defaults
|
|
74
74
|
* - Entry present → keep (coerceFlagValue is applied at read
|
|
75
|
-
* time via sanitizeFlagsRecord
|
|
76
|
-
* - Entry absent → adopt registry default
|
|
75
|
+
* time via sanitizeFlagsRecord)
|
|
76
|
+
* - Entry absent → adopt registry default
|
|
77
77
|
* - Unknown IDs from old manifest → pass through unchanged (forward-compat)
|
|
78
78
|
*
|
|
79
|
-
*
|
|
79
|
+
* Absent key = unknown to this install → adopt default.
|
|
80
80
|
* view-mode is not set here; resolveInitSeed sets flags['view-mode'] after composing.
|
|
81
81
|
*/
|
|
82
82
|
export function resolveSeedFlags(manifestFlags, registry = FLAG_REGISTRY) {
|
|
@@ -222,7 +222,7 @@ export function resolveExistingAttributionSuppression(settingsJson) {
|
|
|
222
222
|
* view-mode priority: existing settings.json (non-default) → manifest → 'default'.
|
|
223
223
|
* suppress-attribution priority: settings.json exact devflow shape → manifest → false.
|
|
224
224
|
* All flag overrides are encoded into flags so all flag state lives in one FlagsRecord
|
|
225
|
-
* (
|
|
225
|
+
* (fold before strip — the fold happens here).
|
|
226
226
|
*
|
|
227
227
|
* This is the single composition point; callers (init.ts hoist block) call this
|
|
228
228
|
* once and pass `seed` down to prompt wiring.
|
|
@@ -236,7 +236,7 @@ export function resolveInitSeed(seedManifest, settingsSnapshot, plugins) {
|
|
|
236
236
|
const flags = resolveSeedFlags(manifestFlags);
|
|
237
237
|
const manifestPlugins = seedManifest !== null ? seedManifest.plugins : null;
|
|
238
238
|
const { workflowPlugins, languagePlugins } = resolveSeedPlugins(manifestPlugins, seedManifest?.knownPlugins, plugins);
|
|
239
|
-
// Encode the resolved view mode into flags['view-mode'] (
|
|
239
|
+
// Encode the resolved view mode into flags['view-mode'] (all flag state in FlagsRecord).
|
|
240
240
|
// Priority: existing settings.json (non-default) → flags['view-mode'] from manifest → 'default'.
|
|
241
241
|
// resolveExistingViewMode returns undefined when absent or 'default' — treated as no-opinion.
|
|
242
242
|
const existingViewMode = resolveExistingViewMode(settingsSnapshot);
|