devflow-kit 3.0.0 → 3.1.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 +22 -0
- package/dist/agents/git.md +2 -2
- package/dist/cli/agents-view/index.js +1 -1
- package/dist/cli/agents-view/render.js +2 -2
- package/dist/cli/agents-view/state.js +2 -2
- package/dist/cli/agents-view/terminal.js +5 -5
- package/dist/cli/commands/agents.js +7 -6
- 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 +34 -32
- package/dist/cli/commands/install-report.js +10 -10
- package/dist/cli/commands/learning.js +267 -129
- package/dist/cli/commands/memory.js +1 -1
- 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 +20 -20
- 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/dynamic-build.md +18 -4
- package/dist/commands/dynamic-plan.md +19 -5
- package/dist/commands/dynamic-profile.md +17 -3
- package/dist/commands/dynamic-tickets.md +18 -4
- package/dist/commands/release.md +15 -1
- package/dist/commands/research.md +1 -1
- package/dist/commands/resolve.md +8 -9
- package/dist/core/agent-frontmatter.js +3 -3
- package/dist/core/agent-models.js +6 -6
- package/dist/core/agent-state.js +2 -2
- package/dist/core/ansi.js +2 -2
- 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 +3 -3
- package/dist/core/feature-switch.js +3 -3
- package/dist/core/flags.js +25 -25
- package/dist/core/fs-atomic.js +6 -7
- package/dist/core/learning-queue-cleanup.js +16 -80
- package/dist/core/learning-store.js +61 -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 +4 -5
- 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/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 +2 -16
- package/dist/hud/components/version-badge.js +1 -1
- package/dist/skills/git/references/pr/resolve-review-threads.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 +24 -24
- package/dist/targets/claude-code/legacy.js +1 -1
- package/dist/targets/claude-code/post-install.js +25 -11
- package/dist/targets/claude-code/tracker-install.js +2 -2
- package/package.json +1 -1
- package/src/assets/agents/code.md +1 -4
- package/src/assets/agents/design.md +2 -2
- package/src/assets/agents/diagnose.md +1 -1
- package/src/assets/agents/git.mds +2 -2
- package/src/assets/agents/knowledge.md +3 -3
- package/src/assets/agents/learning.md +281 -196
- package/src/assets/agents/research.md +1 -1
- package/src/assets/agents/review.md +3 -3
- package/src/assets/agents/scrutinize.md +1 -1
- package/src/assets/agents/skim.md +1 -1
- package/src/assets/agents/triage.md +9 -9
- 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 +1 -1
- package/src/assets/commands/_partials/_preamble.mds +6 -2
- package/src/assets/commands/_partials/_settings.mds +2 -2
- package/src/assets/commands/dynamic-build.mds +1 -1
- package/src/assets/commands/dynamic-plan.mds +3 -3
- package/src/assets/commands/dynamic-profile.mds +1 -1
- package/src/assets/commands/dynamic-tickets.mds +2 -2
- package/src/assets/commands/release.md +15 -1
- package/src/assets/commands/research.mds +1 -1
- package/src/assets/commands/resolve.mds +8 -9
- 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 +1 -1
- package/src/assets/mds/tracker/_jira.mds +1 -1
- package/src/assets/mds/tracker/_linear.mds +1 -1
- package/src/assets/mds/tracker/_mcp.mds +6 -5
- package/src/assets/scripts/hooks/assets/orchestrator-charter.md +1 -0
- package/src/assets/scripts/hooks/background-memory-update +28 -22
- package/src/assets/scripts/hooks/capture-turn +1 -17
- package/src/assets/scripts/hooks/ensure-devflow-init +1 -1
- package/src/assets/scripts/hooks/ensure-proxy +5 -6
- package/src/assets/scripts/hooks/ensure-root-gitignore +1 -1
- package/src/assets/scripts/hooks/is-hex-sha +1 -1
- package/src/assets/scripts/hooks/json-helper.cjs +348 -814
- package/src/assets/scripts/hooks/json-parse +3 -2
- package/src/assets/scripts/hooks/lib/decisions-format.cjs +205 -156
- package/src/assets/scripts/hooks/lib/learning-store.cjs +3102 -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/queue-append +2 -2
- package/src/assets/scripts/hooks/resolve-project-root +3 -4
- package/src/assets/scripts/hooks/session-start-context +40 -18
- 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/targets/claude-code/templates/managed-settings.json +3 -3
- package/dist/core/observation-io.js +0 -50
- package/src/assets/scripts/hooks/decisions-usage-scan.cjs +0 -131
|
@@ -84,7 +84,7 @@ export async function runMigrationsWithFallback(discoveredProjects, gitRoot, dev
|
|
|
84
84
|
* or command still loading in Claude Code with no diagnostic at all. Both outcomes
|
|
85
85
|
* have to reach the summary.
|
|
86
86
|
*
|
|
87
|
-
* Pure function — returns lines, logs nothing
|
|
87
|
+
* Pure function — returns lines, logs nothing.
|
|
88
88
|
*/
|
|
89
89
|
export function formatSweepSummary(report) {
|
|
90
90
|
const lines = [];
|
|
@@ -194,7 +194,8 @@ export function resolveComplianceInitState(complianceOption, seedFrameworks) {
|
|
|
194
194
|
return undefined;
|
|
195
195
|
}
|
|
196
196
|
// Re-export formatComplianceSummary from compliance-prompts.ts so existing test imports
|
|
197
|
-
// (tests/init-logic.test.ts
|
|
197
|
+
// (the 'formatComplianceSummary' suite in tests/init-logic.test.ts imports it from
|
|
198
|
+
// '../src/cli/commands/init.js') keep resolving.
|
|
198
199
|
export { formatComplianceSummary } from './compliance-prompts.js';
|
|
199
200
|
/**
|
|
200
201
|
* Parse the --tracker CLI option into a tracker override.
|
|
@@ -222,7 +223,7 @@ export function resolveTrackerInitState(trackerOption) {
|
|
|
222
223
|
/**
|
|
223
224
|
* The outcome line for a provider that arrived as `--tracker <id>`.
|
|
224
225
|
*
|
|
225
|
-
* D-TRACKER-CLI-SURFACE
|
|
226
|
+
* D-TRACKER-CLI-SURFACE: the Advanced path prints no end-of-wizard
|
|
226
227
|
* summary, and `--tracker` suppresses the wizard step that would otherwise
|
|
227
228
|
* print one, so the CLI-override arm is the only place the selection can
|
|
228
229
|
* surface there. Without this line `devflow init --advanced --tracker jira`
|
|
@@ -255,7 +256,7 @@ export function buildTrackerLifecycleIO() {
|
|
|
255
256
|
*
|
|
256
257
|
* D-TRACKER-CONVERGE: the manifest write and the tracker file-lifecycle owners
|
|
257
258
|
* are ONE unit because their relative order is the invariant, not an
|
|
258
|
-
* implementation detail
|
|
259
|
+
* implementation detail. The manifest write is explicitly failable —
|
|
259
260
|
* init must not abort on it — so converging the sentinel ahead of it leaves the
|
|
260
261
|
* two disagreeing in both directions: github→jira writes a sentinel naming a
|
|
261
262
|
* provider the manifest never records, and jira→github removes the sentinel while
|
|
@@ -268,7 +269,7 @@ export function buildTrackerLifecycleIO() {
|
|
|
268
269
|
* taken as a separate argument, so there is exactly one binding and the sentinel
|
|
269
270
|
* cannot name a value other than the one on disk.
|
|
270
271
|
*
|
|
271
|
-
* Every step reports rather than aborts
|
|
272
|
+
* Every step reports rather than aborts: a
|
|
272
273
|
* feature-state change must never fail `devflow init`.
|
|
273
274
|
*/
|
|
274
275
|
export async function persistManifestThenConvergeTracker(opts) {
|
|
@@ -302,7 +303,7 @@ export async function persistManifestThenConvergeTracker(opts) {
|
|
|
302
303
|
messages.push({ level: 'warn', text });
|
|
303
304
|
// D-TRACKER-PARALLEL: the two owners touch disjoint files — the attempt
|
|
304
305
|
// counters and the sentinel — depend on nothing the other writes, and both
|
|
305
|
-
// report through TrackerResult instead of throwing
|
|
306
|
+
// report through TrackerResult instead of throwing, so they run
|
|
306
307
|
// concurrently and their warnings are pushed in a fixed order regardless of
|
|
307
308
|
// which settles first.
|
|
308
309
|
const [rearm, sentinel] = await Promise.all([
|
|
@@ -361,7 +362,7 @@ export async function drainDisabledFeatureQueues(opts, io = { drainMemoryQueue,
|
|
|
361
362
|
* earlier shape rewrote the whole record as a HUD-only fresh install (ambient,
|
|
362
363
|
* memory, learning, knowledge, rules and proxy all `false`, plugins `[]`) while
|
|
363
364
|
* leaving those features' artifacts on disk: the record stopped describing the
|
|
364
|
-
* machine, the next re-init seeded every feature off
|
|
365
|
+
* machine, the next re-init seeded every feature off, and with
|
|
365
366
|
* memory/learning/knowledge switched by the manifest alone
|
|
366
367
|
* (D-FEATURES-NARROW-ONLY) a HUD install would have really disabled them
|
|
367
368
|
* everywhere. `version` is kept too: --hud-only reinstalls no plugin, and a
|
|
@@ -759,7 +760,7 @@ export const initCommand = new Command('init')
|
|
|
759
760
|
// modePromptShown: true only when the Setup-mode p.select actually ran (i.e. the user
|
|
760
761
|
// was shown a live interactive prompt and made an active choice). Used by
|
|
761
762
|
// shouldRunComplianceStep to preserve the promptless contracts of --recommended and !isTTY
|
|
762
|
-
// without re-checking the mode name
|
|
763
|
+
// without re-checking the mode name.
|
|
763
764
|
let modePromptShown = false;
|
|
764
765
|
let useRecommended;
|
|
765
766
|
if (options.recommended) {
|
|
@@ -877,7 +878,7 @@ export const initCommand = new Command('init')
|
|
|
877
878
|
// ── Recommended path ──
|
|
878
879
|
// B4: compliance wizard step — runs only when the Setup-mode prompt actually ran
|
|
879
880
|
// (modePromptShown=true), preserving the promptless contracts of --recommended and !isTTY.
|
|
880
|
-
// shouldRunComplianceStep gates on modePromptShown rather than the mode name
|
|
881
|
+
// shouldRunComplianceStep gates on modePromptShown rather than the mode name.
|
|
881
882
|
// Re-init never routes here (seedManifest !== null → banner path → Advanced), so this path
|
|
882
883
|
// always sees fresh-install defaults.
|
|
883
884
|
let wizardCompliance;
|
|
@@ -1131,9 +1132,9 @@ export const initCommand = new Command('init')
|
|
|
1131
1132
|
isTTY: process.stdin.isTTY,
|
|
1132
1133
|
hasCliOverride: cliComplianceOverride !== undefined,
|
|
1133
1134
|
})) {
|
|
1134
|
-
// runComplianceStep: note with "Current setting:" header (legible on re-init
|
|
1135
|
+
// runComplianceStep: note with "Current setting:" header (legible on re-init),
|
|
1135
1136
|
// labeled Yes/No select (immune to Enter-through muscle memory), and framework multiselect.
|
|
1136
|
-
// Returns {kind:'cancelled'} on Escape — caller owns the cancel idiom
|
|
1137
|
+
// Returns {kind:'cancelled'} on Escape — caller owns the cancel idiom.
|
|
1137
1138
|
const complianceStep = await runComplianceStep({
|
|
1138
1139
|
seed: { enabled: complianceEnabled, frameworks: complianceFrameworks },
|
|
1139
1140
|
prompts: buildClackCompliancePrompts(),
|
|
@@ -1187,19 +1188,19 @@ export const initCommand = new Command('init')
|
|
|
1187
1188
|
// silently carries the seeded value. The gate stays an explicit predicate call so the
|
|
1188
1189
|
// documented gate table in attribution-prompts.ts remains the single authority.
|
|
1189
1190
|
// isTTY is guaranteed true here (the non-TTY guard above exit-1'd); passing it keeps
|
|
1190
|
-
// the promptless contract enforced at the predicate rather than by position
|
|
1191
|
+
// the promptless contract enforced at the predicate rather than by position.
|
|
1191
1192
|
if (shouldRunAttributionStep({
|
|
1192
1193
|
// D27-GATE: bind to the resolved mode so all four documented gate-table rows
|
|
1193
1194
|
// are reachable and the predicate — not lexical placement — enforces Advanced-only.
|
|
1194
1195
|
// Using useRecommended ? 'recommended' : 'advanced' makes the gate testable from
|
|
1195
1196
|
// both sides and prevents the Recommended path from accidentally running the step
|
|
1196
|
-
// if this block is ever repositioned
|
|
1197
|
+
// if this block is ever repositioned.
|
|
1197
1198
|
mode: useRecommended ? 'recommended' : 'advanced',
|
|
1198
1199
|
isTTY: process.stdin.isTTY,
|
|
1199
1200
|
})) {
|
|
1200
1201
|
const attributionStep = await runAttributionStep({
|
|
1201
1202
|
// attributionSeedFrom keeps the seed a real boolean regardless of the stored
|
|
1202
|
-
// FlagsRecord value type — undefined/null/false all map to false
|
|
1203
|
+
// FlagsRecord value type — undefined/null/false all map to false.
|
|
1203
1204
|
seed: attributionSeedFrom(enabledFlags),
|
|
1204
1205
|
prompts: buildClackAttributionPrompts(),
|
|
1205
1206
|
});
|
|
@@ -1220,7 +1221,7 @@ export const initCommand = new Command('init')
|
|
|
1220
1221
|
/**
|
|
1221
1222
|
* D40: init applies seeded flag defaults non-interactively. Flags are customized
|
|
1222
1223
|
* exclusively via `devflow flags`; re-init preserves existing values and adopts
|
|
1223
|
-
* registry defaults only for absent flags
|
|
1224
|
+
* registry defaults only for absent flags. No TUI is opened during init.
|
|
1224
1225
|
*/
|
|
1225
1226
|
{
|
|
1226
1227
|
const activeCount = countActiveFlags(enabledFlags);
|
|
@@ -1474,10 +1475,10 @@ export const initCommand = new Command('init')
|
|
|
1474
1475
|
p.log.error(`${error}`);
|
|
1475
1476
|
process.exit(1);
|
|
1476
1477
|
}
|
|
1477
|
-
// Converge compliance artifacts (
|
|
1478
|
+
// Converge compliance artifacts (always converge, never short-circuit).
|
|
1478
1479
|
// Called unconditionally so that enabling/disabling compliance during init
|
|
1479
1480
|
// is reflected in the installed artifacts without a separate devflow compliance run.
|
|
1480
|
-
// Wrapped in its own try/catch (
|
|
1481
|
+
// Wrapped in its own try/catch (warn-not-abort).
|
|
1481
1482
|
let convergeResult = null;
|
|
1482
1483
|
try {
|
|
1483
1484
|
convergeResult = await convergeFromManifest({
|
|
@@ -1525,7 +1526,7 @@ export const initCommand = new Command('init')
|
|
|
1525
1526
|
}
|
|
1526
1527
|
// Sweep orphaned *-teams.md workflow command variants left by the Agent Teams
|
|
1527
1528
|
// refactor. None are ever re-installed, so a blanket sweep is safe on any
|
|
1528
|
-
// install type (the full-install dir wipe only covers full installs).
|
|
1529
|
+
// install type (the full-install dir wipe only covers full installs).
|
|
1529
1530
|
try {
|
|
1530
1531
|
for (const f of await fs.readdir(commandsDir)) {
|
|
1531
1532
|
if (f.endsWith('-teams.md')) {
|
|
@@ -1598,6 +1599,7 @@ export const initCommand = new Command('init')
|
|
|
1598
1599
|
'dream-procedure.md',
|
|
1599
1600
|
'lib/staleness.cjs',
|
|
1600
1601
|
'dream-lock',
|
|
1602
|
+
'decisions-usage-scan.cjs',
|
|
1601
1603
|
];
|
|
1602
1604
|
const hooksDir = path.join(devflowDir, 'scripts', 'hooks');
|
|
1603
1605
|
for (const legacy of LEGACY_HOOK_FILES) {
|
|
@@ -1613,7 +1615,7 @@ export const initCommand = new Command('init')
|
|
|
1613
1615
|
const settingsPath = path.join(claudeDir, 'settings.json');
|
|
1614
1616
|
// === Proxy preflight (when enabled) ===
|
|
1615
1617
|
// Runs before the settings mutation pass so that proxyEnabled reflects reality
|
|
1616
|
-
// (preflight failure forces it off without aborting init
|
|
1618
|
+
// (preflight failure forces it off without aborting init).
|
|
1617
1619
|
//
|
|
1618
1620
|
// Read existing proxy state once to recover the remembered port.
|
|
1619
1621
|
// Init has no --port option; the remembered port from proxy.json always
|
|
@@ -1660,7 +1662,7 @@ export const initCommand = new Command('init')
|
|
|
1660
1662
|
'Routing disabled for this init — run `devflow proxy --enable` after signing in.');
|
|
1661
1663
|
proxyEnabled = false;
|
|
1662
1664
|
// Write proxy.json disabled so runtime authority converges with the
|
|
1663
|
-
// failed preflight outcome
|
|
1665
|
+
// failed preflight outcome. Without this write,
|
|
1664
1666
|
// proxy.json stays enabled:true from the prior run, causing
|
|
1665
1667
|
// reapplyAgentMapping to write GPT model IDs into agent frontmatter
|
|
1666
1668
|
// with no relay — a dormancy inversion.
|
|
@@ -1695,7 +1697,7 @@ export const initCommand = new Command('init')
|
|
|
1695
1697
|
}
|
|
1696
1698
|
else {
|
|
1697
1699
|
// Proxy disabled at entry: if proxy.json exists and is enabled, mark it disabled.
|
|
1698
|
-
//
|
|
1700
|
+
// Runtime authority (proxy.json) must converge with proxyEnabled=false.
|
|
1699
1701
|
// Check the Result — write errors are surfaced rather than silently ignored
|
|
1700
1702
|
// (consistent with the enable branch above).
|
|
1701
1703
|
if (priorProxyStateResult.ok && priorProxyStateResult.value.enabled) {
|
|
@@ -1716,7 +1718,7 @@ export const initCommand = new Command('init')
|
|
|
1716
1718
|
// MUST run AFTER the proxy preflight block above: preflight can force proxyEnabled=false
|
|
1717
1719
|
// on failure, and reapply's dormancy (GPT models materialize only while proxy enabled)
|
|
1718
1720
|
// depends on the FINAL proxyEnabled value — running earlier would leave GPT model lines
|
|
1719
|
-
// in agent frontmatter after a preflight failure. Per-item failures are non-fatal
|
|
1721
|
+
// in agent frontmatter after a preflight failure. Per-item failures are non-fatal.
|
|
1720
1722
|
//
|
|
1721
1723
|
// Init-only optimization: skip reapply when mapping is empty AND proxy is off.
|
|
1722
1724
|
// An empty mapping means every agent uses its shipped default; the file copy already
|
|
@@ -1776,7 +1778,7 @@ export const initCommand = new Command('init')
|
|
|
1776
1778
|
// Strip Devflow-managed teammateMode ("auto"). User-set values (e.g. "tmux") are preserved.
|
|
1777
1779
|
content = stripDevflowTeammateModeFromJson(content);
|
|
1778
1780
|
// Claude Code flags — convergeFlagsIntoSettings is the single pipeline entry point
|
|
1779
|
-
// (ARCH-H1
|
|
1781
|
+
// (ARCH-H1): fold valued flags and view-mode from
|
|
1780
1782
|
// existing settings before strip, then strip all managed keys and apply the folded
|
|
1781
1783
|
// record. ownedRecord=existingManifest?.features.flags??null distinguishes keys
|
|
1782
1784
|
// devflow previously wrote (must not be overridden by fold) from keys newly adopted
|
|
@@ -1806,7 +1808,7 @@ export const initCommand = new Command('init')
|
|
|
1806
1808
|
// would silently delete both their URL and the window-enforcement var.
|
|
1807
1809
|
// Invariant: proxy.json always reflects the final settled state after the
|
|
1808
1810
|
// preflight block above — all paths that force proxyEnabled=false also write
|
|
1809
|
-
// proxy.json enabled:false
|
|
1811
|
+
// proxy.json enabled:false, so managedPort == effectivePort.
|
|
1810
1812
|
if (await proxyJsonExists(devflowDir)) {
|
|
1811
1813
|
const proxyStateForStrip = await readProxyState(devflowDir);
|
|
1812
1814
|
const managedPort = proxyStateForStrip.ok ? proxyStateForStrip.value.port : DEFAULT_PROXY_PORT;
|
|
@@ -1838,14 +1840,14 @@ export const initCommand = new Command('init')
|
|
|
1838
1840
|
// read-modify-write, not a whole-file write: init owns only reviewPublication,
|
|
1839
1841
|
// and every other key in the file — the hand-written per-repo `tracker`
|
|
1840
1842
|
// override first among them — is carried from disk, under --reset too
|
|
1841
|
-
// (D-CONFIG-PRESERVE-UNMANAGED in feature-config.ts
|
|
1843
|
+
// (D-CONFIG-PRESERVE-UNMANAGED in feature-config.ts).
|
|
1842
1844
|
// A malformed or unreadable file is left untouched and named (D-CONFIG-NO-REPAIR).
|
|
1843
1845
|
if (gitRoot) {
|
|
1844
1846
|
const configWrite = await writeManagedConfig(gitRoot, {
|
|
1845
1847
|
// reviewPublication has no prompt, so it is carried over from the
|
|
1846
1848
|
// reset-gated snapshot rather than re-read from disk: seedConfig is null
|
|
1847
1849
|
// under --reset, which is what collapses the field back to 'auto' with
|
|
1848
|
-
// every other feature (
|
|
1850
|
+
// every other feature (read the post-gate binding, not the file).
|
|
1849
1851
|
reviewPublication: seedConfig?.reviewPublication ?? DEFAULT_CONFIG.reviewPublication,
|
|
1850
1852
|
});
|
|
1851
1853
|
if (!configWrite.ok)
|
|
@@ -1873,7 +1875,7 @@ export const initCommand = new Command('init')
|
|
|
1873
1875
|
// Deterministically ensure .devflow/ is gitignored at the repo root — independent
|
|
1874
1876
|
// of every feature toggle. The always-on ensure-root-gitignore
|
|
1875
1877
|
// hook covers projects that never re-run init; this covers the init-time path so a
|
|
1876
|
-
// fresh install never tracks .devflow/. Decoupled from memory
|
|
1878
|
+
// fresh install never tracks .devflow/. Decoupled from memory.
|
|
1877
1879
|
if (gitRoot) {
|
|
1878
1880
|
await ensureDevflowGitignore(gitRoot, verbose);
|
|
1879
1881
|
}
|
|
@@ -1932,7 +1934,7 @@ export const initCommand = new Command('init')
|
|
|
1932
1934
|
s.start('Finalizing installation...');
|
|
1933
1935
|
}
|
|
1934
1936
|
else {
|
|
1935
|
-
//
|
|
1937
|
+
// User declined sudo and chose the settings.json fallback.
|
|
1936
1938
|
// securityMode is 'managed' (from resolveSecurityAction or interactive choice) but
|
|
1937
1939
|
// managedSettingsConfirmed is false — honor the "fall back to settings.json" label
|
|
1938
1940
|
// by writing to user settings. Manifest will record 'user' to match reality.
|
|
@@ -1987,7 +1989,7 @@ export const initCommand = new Command('init')
|
|
|
1987
1989
|
}
|
|
1988
1990
|
else {
|
|
1989
1991
|
// Exhaustive guard — if TypeScript reaches here, a new SecurityMode variant was added
|
|
1990
|
-
// without a matching branch
|
|
1992
|
+
// without a matching branch — guards against stale references after rename/refactor.
|
|
1991
1993
|
const _exhaustive = securityMode;
|
|
1992
1994
|
void _exhaustive;
|
|
1993
1995
|
}
|
|
@@ -2038,7 +2040,7 @@ export const initCommand = new Command('init')
|
|
|
2038
2040
|
// devflow:compliance is never swept here — no suppression predicate is needed.
|
|
2039
2041
|
logSummaryLines(formatSweepSummary(installReport));
|
|
2040
2042
|
// Reference-overlay reporting: the overlay rewrites files inside an installed skill
|
|
2041
|
-
// the user may have shadowed, and reports any unit it had to leave alone
|
|
2043
|
+
// the user may have shadowed, and reports any unit it had to leave alone.
|
|
2042
2044
|
logSummaryLines(formatOverlaySummary(installReport));
|
|
2043
2045
|
// Skill-scoping reporting: a deselected skill is deleted and a dormant shadow
|
|
2044
2046
|
// is inert, and neither is distinguishable from "never installed" on disk.
|
|
@@ -2120,7 +2122,7 @@ export const initCommand = new Command('init')
|
|
|
2120
2122
|
knowledge: knowledgeEnabled,
|
|
2121
2123
|
learning: learningEnabled,
|
|
2122
2124
|
rules: rulesEnabled,
|
|
2123
|
-
// FlagsRecord written directly — key-presence encodes "known"
|
|
2125
|
+
// FlagsRecord written directly — key-presence encodes "known".
|
|
2124
2126
|
// view-mode is encoded as flags['view-mode'] (the resolved final value).
|
|
2125
2127
|
flags: enabledFlags,
|
|
2126
2128
|
security: securityMode,
|
|
@@ -2141,7 +2143,7 @@ export const initCommand = new Command('init')
|
|
|
2141
2143
|
// ── Manifest write + tracker selection lifecycle (the ONE call site) ──────
|
|
2142
2144
|
// persistManifestThenConvergeTracker owns the ordering invariant: the
|
|
2143
2145
|
// tracker file-lifecycle owners in src/core/tracker.ts converge only against
|
|
2144
|
-
// a provider the manifest actually persisted (D-TRACKER-CONVERGE
|
|
2146
|
+
// a provider the manifest actually persisted (D-TRACKER-CONVERGE).
|
|
2145
2147
|
const trackerLifecycle = await persistManifestThenConvergeTracker({
|
|
2146
2148
|
devflowDir,
|
|
2147
2149
|
claudeDir,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Rendering for the post-install summary — pure functions that turn an
|
|
3
|
-
* {@link InstallReport} into lines, logging nothing
|
|
3
|
+
* {@link InstallReport} into lines, logging nothing.
|
|
4
4
|
*
|
|
5
5
|
* Its own module rather than a section of init.ts because `devflow tracker --set`
|
|
6
6
|
* renders the same overlay outcomes from a different command. A CLI command
|
|
@@ -18,18 +18,18 @@ import { prefixSkillName } from '../../core/plugins.js';
|
|
|
18
18
|
* shadowed, and a unit it could not refresh is left in one of the states
|
|
19
19
|
* {@link OverlayFailureState} enumerates — running on the previous install, half
|
|
20
20
|
* replaced, absent, or recoverable only from a backup path. None of that is visible from
|
|
21
|
-
* the filesystem at a glance, so all of it reaches the summary —
|
|
21
|
+
* the filesystem at a glance, so all of it reaches the summary — a report field
|
|
22
22
|
* with no render site is not a report, and a render site that flattens four states into
|
|
23
23
|
* one sentence is the same defect one layer up.
|
|
24
24
|
*
|
|
25
|
-
* Pure function — returns lines, logs nothing
|
|
25
|
+
* Pure function — returns lines, logs nothing.
|
|
26
26
|
*
|
|
27
27
|
* @param skillName - Bare name of the skill hosting the generated references,
|
|
28
28
|
* rendered `devflow:`-prefixed. Defaults to the core constant the build path and
|
|
29
29
|
* the installer's overlay trigger both read, so the renderer is never a third
|
|
30
|
-
* independent statement of which skill owns them —
|
|
31
|
-
*
|
|
32
|
-
*
|
|
30
|
+
* independent statement of which skill owns them — a divergence where changing
|
|
31
|
+
* the answer means finding every retyped spelling and nothing fails if one is
|
|
32
|
+
* missed.
|
|
33
33
|
*/
|
|
34
34
|
export function formatOverlaySummary(report, skillName = SKILL_REFS_SKILL_NAME) {
|
|
35
35
|
const lines = [];
|
|
@@ -59,7 +59,7 @@ export function formatOverlaySummary(report, skillName = SKILL_REFS_SKILL_NAME)
|
|
|
59
59
|
* be told about.
|
|
60
60
|
*
|
|
61
61
|
* Exported because `devflow tracker --set` renders the same states when it aborts
|
|
62
|
-
* on an overlay failure (
|
|
62
|
+
* on an overlay failure (one sentence per state, in one place,
|
|
63
63
|
* rather than a second wording that drifts).
|
|
64
64
|
*
|
|
65
65
|
* Exhaustive over {@link OverlayFailureState} — a new state added to the union without a
|
|
@@ -103,7 +103,7 @@ export function describeOverlayFailureState(state) {
|
|
|
103
103
|
* The delta line is emitted only when something moved: on a steady-state re-init
|
|
104
104
|
* the counts are noise.
|
|
105
105
|
*
|
|
106
|
-
* Pure function — returns lines, logs nothing
|
|
106
|
+
* Pure function — returns lines, logs nothing.
|
|
107
107
|
*
|
|
108
108
|
* @param previous - The provider recorded by the PRIOR manifest, or undefined on
|
|
109
109
|
* a first install. Rendered only when it differs from `provider`.
|
|
@@ -144,7 +144,7 @@ export function formatTrackerAssetSummary(input) {
|
|
|
144
144
|
* how the selection was assembled, and a duplicate name in either list is a
|
|
145
145
|
* manifest detail rather than a different selection.
|
|
146
146
|
*
|
|
147
|
-
* Pure function
|
|
147
|
+
* Pure function.
|
|
148
148
|
*
|
|
149
149
|
* @param previousPlugins - `manifest.plugins` as it stands before this run, or
|
|
150
150
|
* `null` when there is no prior manifest.
|
|
@@ -176,7 +176,7 @@ export function isPluginListUnchanged(previousPlugins, effectivePluginNames) {
|
|
|
176
176
|
* it is FALSE when there is no prior manifest: a first install removed nothing a
|
|
177
177
|
* user had, so there is no upgrade to explain (design review L2).
|
|
178
178
|
*
|
|
179
|
-
* Pure function — returns lines, logs nothing
|
|
179
|
+
* Pure function — returns lines, logs nothing.
|
|
180
180
|
*/
|
|
181
181
|
export function formatSkillScopeSummary(report, pluginListUnchanged) {
|
|
182
182
|
const lines = [];
|