peaks-loop 4.0.51 → 4.0.52
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 +20 -0
- package/README-en.md +1 -1
- package/README.md +1 -1
- package/dist/cli/commands/baseline-commands.js +11 -1
- package/dist/cli/commands/codegraph-command-runtime.d.ts +28 -0
- package/dist/cli/commands/codegraph-command-runtime.js +72 -0
- package/dist/cli/commands/codegraph-commands.d.ts +2 -11
- package/dist/cli/commands/codegraph-commands.js +173 -228
- package/dist/cli/commands/codegraph-status-command.d.ts +22 -0
- package/dist/cli/commands/codegraph-status-command.js +299 -0
- package/dist/cli/commands/core/memory-command.js +6 -2
- package/dist/cli/commands/job-commands.js +121 -30
- package/dist/cli/commands/project-commands.js +13 -3
- package/dist/cli/commands/request-commands.js +19 -8
- package/dist/cli/commands/slice-commands.js +2 -2
- package/dist/services/artifacts/artifact-prerequisites.js +23 -1
- package/dist/services/codegraph/codegraph-autorefresh.d.ts +16 -0
- package/dist/services/codegraph/codegraph-autorefresh.js +51 -5
- package/dist/services/codegraph/codegraph-config-repair-writer.d.ts +88 -0
- package/dist/services/codegraph/codegraph-config-repair-writer.js +322 -0
- package/dist/services/codegraph/codegraph-exclude-integrity.d.ts +20 -2
- package/dist/services/codegraph/codegraph-exclude-integrity.js +24 -3
- package/dist/services/codegraph/codegraph-exclude-reconciler.d.ts +23 -2
- package/dist/services/codegraph/codegraph-exclude-reconciler.js +123 -12
- package/dist/services/codegraph/codegraph-exclude-repair.d.ts +109 -55
- package/dist/services/codegraph/codegraph-exclude-repair.js +249 -195
- package/dist/services/codegraph/codegraph-include-reconciler.d.ts +10 -0
- package/dist/services/codegraph/codegraph-include-reconciler.js +160 -0
- package/dist/services/codegraph/codegraph-index-integrity.d.ts +268 -0
- package/dist/services/codegraph/codegraph-index-integrity.js +471 -0
- package/dist/services/codegraph/codegraph-service.d.ts +54 -0
- package/dist/services/codegraph/codegraph-service.js +84 -1
- package/dist/services/doctor/doctor-service/checks/codegraph-exclude-integrity.js +19 -4
- package/dist/services/doctor/doctor-service/checks/codegraph-index-integrity.d.ts +54 -0
- package/dist/services/doctor/doctor-service/checks/codegraph-index-integrity.js +151 -0
- package/dist/services/doctor/doctor-service/checks/l3-orphan-sessions.js +10 -10
- package/dist/services/doctor/doctor-service/plugin-registry.js +2 -0
- package/dist/services/doctor/doctor-service/types.d.ts +25 -0
- package/dist/services/memory/project-memory-service/index/kind-dispatch.js +48 -13
- package/dist/services/memory/project-memory-service/index.d.ts +5 -3
- package/dist/services/memory/project-memory-service/index.js +2 -2
- package/dist/services/memory/project-memory-service/parsers/frontmatter.d.ts +15 -1
- package/dist/services/memory/project-memory-service/parsers/frontmatter.js +34 -6
- package/dist/services/memory/project-memory-service/parsers/markdown-pure.d.ts +27 -1
- package/dist/services/memory/project-memory-service/parsers/markdown-pure.js +92 -7
- package/dist/services/memory/project-memory-service/types.d.ts +86 -0
- package/dist/services/slice/slice-check-types.d.ts +1 -1
- package/dist/services/workspace/runtime-layout.d.ts +91 -0
- package/dist/services/workspace/runtime-layout.js +148 -0
- package/dist/services/workspace/workspace-claude-settings-materializer.js +14 -0
- package/package.json +6 -6
- package/scripts/clean-dist.mjs +15 -3
- package/scripts/sync-version.mjs +26 -4
- package/skills/bee/peaks-prd/SKILL.md +1 -1
- package/skills/bee/peaks-qa/references/qa-skill-presence.md +1 -1
- package/skills/bee/peaks-rd/references/skill-presence-and-title.md +1 -1
- package/skills/bee/peaks-sc/SKILL.md +1 -1
- package/skills/bee/peaks-txt/SKILL.md +3 -3
- package/skills/peaks-code/SKILL.md +1 -1
- package/skills/peaks-code/references/project-memory-loading.md +19 -1
- package/skills/peaks-code/references/step-11-memory-sediment.md +1 -1
|
@@ -1,11 +1,27 @@
|
|
|
1
|
+
// src/cli/commands/codegraph-commands.ts
|
|
2
|
+
//
|
|
3
|
+
// The codegraph verbs that MUTATE or PROXY: `repair-exclude`, `repair-index`,
|
|
4
|
+
// `init`, `affected`, plus the commander registration for every codegraph
|
|
5
|
+
// subcommand.
|
|
6
|
+
//
|
|
7
|
+
// D1 (rid 2026-09-17-oversize-and-scale, the 800-line file-size cap) moved
|
|
8
|
+
// the shared invocation runtime to `codegraph-command-runtime.ts` and the
|
|
9
|
+
// `status` integrity gate to `codegraph-status-command.ts`, both verbatim.
|
|
10
|
+
// This path keeps its public surface: `registerCodegraphCommands` is defined
|
|
11
|
+
// here and `rewriteBareCodegraphHints` / `attributeUpstreamUpToDateLine` are
|
|
12
|
+
// re-exported below, so every existing importer still resolves.
|
|
1
13
|
import { InvalidArgumentError } from 'commander';
|
|
2
14
|
import { statSync } from 'node:fs';
|
|
3
15
|
import { resolve } from 'node:path';
|
|
4
|
-
import { createCodegraphInvocation, executeCodegraphInvocation, defaultCodegraphInitGuard, writeCodegraphMarker, writeCodegraphAffectedContext, CodegraphInitConflictError } from '../../services/codegraph/codegraph-service.js';
|
|
5
|
-
import { CODEGRAPH_INTEGRITY_EXIT_CODE, inspectCodegraphExcludeIntegrity, isCodegraphExcludeConfigPresent, renderCodegraphExcludeIntegrityLines } from '../../services/codegraph/codegraph-exclude-integrity.js';
|
|
16
|
+
import { createCodegraphInvocation, executeCodegraphInvocation, defaultCodegraphInitGuard, resolveProjectRoot, writeCodegraphMarker, writeCodegraphAffectedContext, CodegraphInitConflictError } from '../../services/codegraph/codegraph-service.js';
|
|
6
17
|
import { repairCodegraphExcludeFromProject } from '../../services/codegraph/codegraph-exclude-repair.js';
|
|
7
18
|
import { fail, ok } from 'peaks-loop-shared/result';
|
|
8
|
-
import {
|
|
19
|
+
import { printResult, redactSensitiveErrorMessage } from '../cli-helpers.js';
|
|
20
|
+
import { printCodegraphFailure, runCodegraphCommand } from './codegraph-command-runtime.js';
|
|
21
|
+
import { runCodegraphStatusCommand } from './codegraph-status-command.js';
|
|
22
|
+
// Re-exported so the D1 split is invisible to importers of THIS path.
|
|
23
|
+
export { rewriteBareCodegraphHints } from './codegraph-command-runtime.js';
|
|
24
|
+
export { attributeUpstreamUpToDateLine } from './codegraph-status-command.js';
|
|
9
25
|
function addPeaksJsonOption(command) {
|
|
10
26
|
return command.option('--peaks-json', 'print Peaks error envelope as machine-readable JSON');
|
|
11
27
|
}
|
|
@@ -22,219 +38,118 @@ function parsePositiveInteger(value) {
|
|
|
22
38
|
}
|
|
23
39
|
return parsed;
|
|
24
40
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
* `[OK] Index is up to date` printed above our `[FAIL] ...` reads as
|
|
48
|
-
* "nothing to see here" — and the OK is the line the eye lands on first.
|
|
49
|
-
* The exit code and the JSON envelope are already right; only this line
|
|
50
|
-
* lies by juxtaposition.
|
|
51
|
-
*
|
|
52
|
-
* So: keep upstream's wording — the line stays recognizable, and the
|
|
53
|
-
* Files/Nodes counts around it are untouched — but drop the bare OK
|
|
54
|
-
* marker and name the only question it answers. Clean runs never reach
|
|
55
|
-
* this, so their output stays byte-identical.
|
|
56
|
-
*
|
|
57
|
-
* The match is anchored to THAT line. An earlier version keyed on
|
|
58
|
-
* `includes('up to date')`, which is content-blind: upstream prints other
|
|
59
|
-
* `[OK] ... are up to date` lines (a language-server or watcher line is the
|
|
60
|
-
* observed one), and each of those was rewritten into a claim about the
|
|
61
|
-
* INDEX — a misattribution introduced by a change whose entire purpose was
|
|
62
|
-
* to stop misleading output. Anything that is not the index line is passed
|
|
63
|
-
* through byte-for-byte, tail note and all.
|
|
64
|
-
*/
|
|
65
|
-
const INDEX_UP_TO_DATE_RE = /^\[OK\]\s+Index is up to date\b/i;
|
|
66
|
-
export function attributeUpstreamUpToDateLine(stdout) {
|
|
67
|
-
return stdout
|
|
68
|
-
.split('\n')
|
|
69
|
-
.map((line) => {
|
|
70
|
-
const visible = line.replace(ANSI_SGR_PATTERN, '').trim();
|
|
71
|
-
if (!INDEX_UP_TO_DATE_RE.test(visible)) {
|
|
72
|
-
return line;
|
|
73
|
-
}
|
|
74
|
-
// Only the OK marker is downgraded and the attribution appended: the
|
|
75
|
-
// rest of the line — including whatever upstream wrote after it — is
|
|
76
|
-
// preserved, so nothing upstream actually said is replaced.
|
|
77
|
-
const withoutOk = visible.replace(/^\[OK\]\s*/, '');
|
|
78
|
-
return `[i] ${withoutOk} (upstream: matches the last scan only; repository coverage is answered below)`;
|
|
79
|
-
})
|
|
80
|
-
.join('\n');
|
|
81
|
-
}
|
|
82
|
-
async function runCodegraphCommand(io, command, options, asJson, attributeStdout) {
|
|
83
|
-
try {
|
|
84
|
-
const invocation = createCodegraphInvocation(options);
|
|
85
|
-
const result = await executeCodegraphInvocation(invocation);
|
|
86
|
-
if (result.exitCode !== null && result.exitCode !== 0 && asJson === true) {
|
|
87
|
-
printCodegraphFailure(io, command, new Error(result.stderr || result.stdout || `codegraph exited with code ${result.exitCode}`), true, result.exitCode);
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
const didFail = result.exitCode !== null && result.exitCode !== 0;
|
|
91
|
-
const rewritten = rewriteBareCodegraphHints(result.stdout);
|
|
92
|
-
const stdout = attributeStdout === undefined ? rewritten : attributeStdout(rewritten);
|
|
93
|
-
const stderr = rewriteBareCodegraphHints(result.stderr);
|
|
94
|
-
if (stdout.length > 0) {
|
|
95
|
-
io.stdout((didFail ? redactSensitiveErrorMessage(stdout) : stdout).trimEnd());
|
|
96
|
-
}
|
|
97
|
-
if (stderr.length > 0) {
|
|
98
|
-
io.stderr((didFail ? redactSensitiveErrorMessage(stderr) : stderr).trimEnd());
|
|
99
|
-
}
|
|
100
|
-
if (didFail) {
|
|
101
|
-
process.exitCode = result.exitCode;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
catch (error) {
|
|
105
|
-
printCodegraphFailure(io, command, error, asJson);
|
|
41
|
+
// " Include now admits 7 of 9 extractor-supported tracked file(s)." — printed
|
|
42
|
+
// only when the ratio reports a SHORTFALL, i.e. when the repair has left
|
|
43
|
+
// files the extractor supports unadmitted. That is the one reading of this
|
|
44
|
+
// sentence an operator can act on.
|
|
45
|
+
//
|
|
46
|
+
// What this used to say, and why it was wrong: the denominator was fed from
|
|
47
|
+
// the reconciler's admitted count — the NUMERATOR's own expression — so the
|
|
48
|
+
// clause could only ever print "N of N", and it was gated on
|
|
49
|
+
// `after > before` with a "(was N)" trailer computed by a second full glob
|
|
50
|
+
// pass. A repo with 10 supported tracked files of which 5 were admitted was
|
|
51
|
+
// told "5 of 5", asserting total coverage that nothing had measured. The
|
|
52
|
+
// denominator is now an independent measurement (see the report field), and
|
|
53
|
+
// the trailer — whose only consumer was this sentence — is gone with the
|
|
54
|
+
// pass that produced it (perf: 11.73 ms of the repair entry's +14.13 ms, on
|
|
55
|
+
// every automatic seam including no-ops).
|
|
56
|
+
//
|
|
57
|
+
// Silence when the ratio is complete is deliberate: "2 of 2" is true but
|
|
58
|
+
// says nothing, and the patterns that changed are already named by the
|
|
59
|
+
// caller's own sentence.
|
|
60
|
+
function admittingClause(report) {
|
|
61
|
+
if (report.trackedSourceCount === 0 || report.includeAdmittedAfter >= report.trackedSourceCount) {
|
|
62
|
+
return '';
|
|
106
63
|
}
|
|
64
|
+
return ` Include now admits ${report.includeAdmittedAfter} of ${report.trackedSourceCount} extractor-supported tracked file(s).`;
|
|
107
65
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
printCodegraphFailure(io, 'codegraph.status', error, true);
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
const upstream = {
|
|
124
|
-
exitCode: result.exitCode,
|
|
125
|
-
stdout: rewriteBareCodegraphHints(result.stdout).trimEnd(),
|
|
126
|
-
stderr: redactSensitiveErrorMessage(rewriteBareCodegraphHints(result.stderr)).trimEnd()
|
|
127
|
-
};
|
|
128
|
-
const upstreamFailed = result.exitCode !== null && result.exitCode !== 0;
|
|
129
|
-
if (integrity?.gap === true) {
|
|
130
|
-
printResult(io, fail('codegraph.status', 'CODEGRAPH_INDEX_INCOMPLETE', `codegraph index is incomplete: ${integrity.excludedTrackedCount} of ${integrity.trackedSourceCount} tracked source files are excluded by ${integrity.rulesToRemove.length} rule(s).`, { upstream, integrity, integrityWarning }, ['Run `peaks codegraph repair-exclude --project <root>` to drop the offending rules and rebuild the index.']), true);
|
|
131
|
-
}
|
|
132
|
-
else if (upstreamFailed) {
|
|
133
|
-
printResult(io, fail('codegraph.status', 'CODEGRAPH_COMMAND_FAILED', redactSensitiveErrorMessage(upstream.stderr || upstream.stdout || `codegraph exited with code ${String(result.exitCode)}`), { upstream, integrity, integrityWarning }, ['Check the codegraph project path before retrying']), true);
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
printResult(io, ok('codegraph.status', { upstream, integrity, integrityWarning }), true);
|
|
137
|
-
}
|
|
138
|
-
if (upstreamFailed) {
|
|
139
|
-
process.exitCode = result.exitCode ?? 1;
|
|
66
|
+
const REPAIR_MODES = {
|
|
67
|
+
exclude: {
|
|
68
|
+
commandId: 'codegraph.repair-exclude',
|
|
69
|
+
reindex: true,
|
|
70
|
+
noopNote: 'Nothing to repair in the codegraph config; nothing was written.'
|
|
71
|
+
},
|
|
72
|
+
index: {
|
|
73
|
+
commandId: 'codegraph.repair-index',
|
|
74
|
+
// 'force' is upstream's `clear()` + full re-index — the only documented
|
|
75
|
+
// way to drop rows for files deleted in an earlier commit.
|
|
76
|
+
reindex: 'force',
|
|
77
|
+
noopNote: 'The codegraph config already admits every supported tracked file and blocks none; the index was still rebuilt from scratch.'
|
|
140
78
|
}
|
|
79
|
+
};
|
|
80
|
+
// One sentence, the same shape in both modes, because both modes run the
|
|
81
|
+
// same two-axis repair — only the rebuild differs.
|
|
82
|
+
//
|
|
83
|
+
// A1 (`2026-09-17-codegraph-msg-and-refresh`): EACH COUNT NAMES ITS OWN AXIS.
|
|
84
|
+
// The previous wording ended one sentence about both axes with a single
|
|
85
|
+
// "recovering N tracked source file(s)", fed by `filesRecovered` — the
|
|
86
|
+
// EXCLUDE axis' counter. On this repo it printed "Added 5 include pattern(s)
|
|
87
|
+
// and removed 0 exclude rule(s), recovering 0 tracked source file(s)." while
|
|
88
|
+
// those 5 patterns had just admitted 31 tracked source files (30 `.mjs` + 1
|
|
89
|
+
// `.cjs`): a true statement about the axis that did not move, read as a
|
|
90
|
+
// verdict on the one that did. The `admittingClause` could not correct it
|
|
91
|
+
// either — it is silent when the coverage ratio is complete, which is
|
|
92
|
+
// exactly the state a fresh include repair produces.
|
|
93
|
+
//
|
|
94
|
+
// So: the include clause carries the include axis' own file delta and the
|
|
95
|
+
// exclude clause carries the exclude axis' own count, and a reader cannot
|
|
96
|
+
// attribute either number to the other clause. No combined total is printed,
|
|
97
|
+
// because there is no honest single number here — the two axes recover
|
|
98
|
+
// disjoint sets (one widens admission, the other unblocks admitted files)
|
|
99
|
+
// and only the first of them is cheap enough to measure on every repair.
|
|
100
|
+
function appliedRepairNote(report) {
|
|
101
|
+
return (`Added ${report.includePatternsAdded.length} include pattern(s), newly admitting ${report.includeFilesRecovered} tracked source file(s), and removed ${report.rulesRemoved.length} exclude rule(s), recovering ${report.filesRecovered} tracked source file(s) that a rule had been hiding.` +
|
|
102
|
+
admittingClause(report) +
|
|
103
|
+
` Config backed up to ${report.backupPath ?? ''}.`);
|
|
141
104
|
}
|
|
142
105
|
/**
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
* The upstream status is still proxied verbatim (that is what the
|
|
146
|
-
* command has always done), but a clean upstream "index is up to date"
|
|
147
|
-
* is no longer sufficient: when git-tracked source files are being
|
|
148
|
-
* excluded by the config, the command says so, names the rules and
|
|
149
|
-
* files, and exits non-zero.
|
|
150
|
-
*
|
|
151
|
-
* Read-only by construction — it imports the integrity inspector, never
|
|
152
|
-
* the repair writer. Fixing the config is `peaks codegraph init`
|
|
153
|
-
* (fresh) or `peaks codegraph repair-exclude` (explicit).
|
|
154
|
-
*/
|
|
155
|
-
async function runCodegraphStatusCommand(io, options, asJson) {
|
|
156
|
-
let integrity = null;
|
|
157
|
-
let integrityWarning = null;
|
|
158
|
-
const projectRoot = resolve(options.project);
|
|
159
|
-
try {
|
|
160
|
-
// Never initialized here → no exclude list is in play, so there is
|
|
161
|
-
// nothing to report. Staying silent keeps `status` honest and
|
|
162
|
-
// unchanged for projects that do not use codegraph at all.
|
|
163
|
-
integrity = isCodegraphExcludeConfigPresent(projectRoot)
|
|
164
|
-
? inspectCodegraphExcludeIntegrity(projectRoot)
|
|
165
|
-
: null;
|
|
166
|
-
}
|
|
167
|
-
catch (error) {
|
|
168
|
-
// Not a git work tree, no config yet, malformed config — the
|
|
169
|
-
// upstream status is still worth printing, so degrade to a warning
|
|
170
|
-
// instead of failing the whole command.
|
|
171
|
-
integrityWarning = getErrorMessage(error);
|
|
172
|
-
}
|
|
173
|
-
if (asJson === true) {
|
|
174
|
-
await runCodegraphStatusJson(io, options, integrity, integrityWarning);
|
|
175
|
-
}
|
|
176
|
-
else {
|
|
177
|
-
// Only when the gate found a gap: upstream's `[OK] Index is up to
|
|
178
|
-
// date` answers "consistent with the last scan", and printing it
|
|
179
|
-
// unqualified right above our `[FAIL]` tells the reader two opposite
|
|
180
|
-
// things at once. Clean runs get no transform and stay byte-identical.
|
|
181
|
-
await runCodegraphCommand(io, 'codegraph.status', { subcommand: 'status', project: options.project }, false, integrity?.gap === true ? attributeUpstreamUpToDateLine : undefined);
|
|
182
|
-
if (integrityWarning !== null) {
|
|
183
|
-
io.stdout(`[WARN] codegraph exclude integrity not evaluated: ${integrityWarning}`);
|
|
184
|
-
}
|
|
185
|
-
else if (integrity !== null) {
|
|
186
|
-
for (const line of renderCodegraphExcludeIntegrityLines(integrity)) {
|
|
187
|
-
io.stdout(line);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
if (integrity?.gap === true) {
|
|
192
|
-
process.exitCode = CODEGRAPH_INTEGRITY_EXIT_CODE;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* Explicit repair path: reconcile → drop offending rules → back up the
|
|
197
|
-
* config → rebuild the index. Mirrors the automatic step `init` runs
|
|
106
|
+
* Explicit repair path: reconcile both config axes → back up the config →
|
|
107
|
+
* rewrite it → rebuild the index. Mirrors the automatic step `init` runs
|
|
198
108
|
* after a fresh upstream init, for workspaces that were already
|
|
199
109
|
* initialized before the integrity gate existed.
|
|
200
110
|
*/
|
|
201
|
-
async function
|
|
111
|
+
async function runCodegraphRepairCommand(io, options, asJson, mode) {
|
|
112
|
+
const spec = REPAIR_MODES[mode];
|
|
202
113
|
let projectRoot;
|
|
203
114
|
try {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
115
|
+
// `resolveProjectRoot`, not a hand-rolled `resolve` + `statSync`: it is
|
|
116
|
+
// the canonicalizer every codegraph invocation already goes through
|
|
117
|
+
// (`createCodegraphInvocation`), so the config path this verb reports
|
|
118
|
+
// and writes names the SAME directory the spawn and the other verbs use
|
|
119
|
+
// even when `--project` is a symlink, a short name or a differently
|
|
120
|
+
// cased alias. The error path is unchanged.
|
|
121
|
+
projectRoot = resolveProjectRoot(options.project);
|
|
209
122
|
}
|
|
210
123
|
catch (error) {
|
|
211
|
-
printCodegraphFailure(io,
|
|
124
|
+
printCodegraphFailure(io, spec.commandId, error, asJson);
|
|
212
125
|
return;
|
|
213
126
|
}
|
|
214
|
-
const report = await repairCodegraphExcludeFromProject(projectRoot
|
|
127
|
+
const report = await repairCodegraphExcludeFromProject(projectRoot, undefined, {
|
|
128
|
+
reindex: spec.reindex
|
|
129
|
+
});
|
|
215
130
|
// Where the notes go matters: `printResult` renders every `warnings`
|
|
216
131
|
// entry to stderr with a `warning: ` prefix, so a confirmation parked
|
|
217
132
|
// in the third slot reads as a problem — and a real warning parked
|
|
218
133
|
// there double-prefixes. Confirmations go to `nextActions`; only a
|
|
219
134
|
// genuine `report.warning` reaches `warnings`, verbatim.
|
|
220
|
-
const confirmations = [
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
else {
|
|
225
|
-
confirmations.push('No tracked source file is excluded by the codegraph config; nothing to repair.');
|
|
226
|
-
}
|
|
227
|
-
if (report.applied) {
|
|
135
|
+
const confirmations = [
|
|
136
|
+
report.applied ? appliedRepairNote(report) : spec.noopNote
|
|
137
|
+
];
|
|
138
|
+
if (report.applied || mode === 'index') {
|
|
228
139
|
confirmations.push('Re-run `peaks codegraph status --project <root>` to confirm the gap is closed.');
|
|
229
140
|
}
|
|
230
|
-
printResult(io, ok(
|
|
141
|
+
printResult(io, ok(spec.commandId, {
|
|
231
142
|
applied: report.applied,
|
|
232
143
|
rulesRemoved: report.rulesRemoved,
|
|
144
|
+
includePatternsAdded: report.includePatternsAdded,
|
|
233
145
|
filesRecovered: report.filesRecovered,
|
|
146
|
+
includeFilesRecovered: report.includeFilesRecovered,
|
|
147
|
+
includeAdmittedAfter: report.includeAdmittedAfter,
|
|
234
148
|
trackedSourceCount: report.trackedSourceCount,
|
|
235
149
|
configPath: report.configPath,
|
|
236
150
|
backupPath: report.backupPath,
|
|
237
151
|
reindexed: report.reindexed,
|
|
152
|
+
forcedRebuild: report.forcedRebuild,
|
|
238
153
|
warning: report.warning
|
|
239
154
|
}, report.warning === null ? [] : [report.warning], confirmations), asJson);
|
|
240
155
|
// A repair that could not run to completion (or could not reindex)
|
|
@@ -325,18 +240,20 @@ async function runCodegraphInitCommand(io, options, asJson) {
|
|
|
325
240
|
catch {
|
|
326
241
|
// intentionally swallowed — surface as warning below
|
|
327
242
|
}
|
|
328
|
-
// Upstream `init` writes
|
|
329
|
-
// some
|
|
330
|
-
// project
|
|
331
|
-
//
|
|
332
|
-
//
|
|
333
|
-
//
|
|
334
|
-
//
|
|
335
|
-
// is
|
|
243
|
+
// Upstream `init` writes BOTH default templates: a 99-rule `exclude`
|
|
244
|
+
// list (some rules collide with real source directories in this
|
|
245
|
+
// project) and a 32-entry `include` list (which omits five extensions
|
|
246
|
+
// upstream's own extractor supports). Left alone, a fresh clone / new
|
|
247
|
+
// machine gets an index that silently omits tracked source files while
|
|
248
|
+
// `status` says it is up to date. Reconcile now, append the missing
|
|
249
|
+
// include patterns, drop the offending rules, and rebuild the index — a
|
|
250
|
+
// fresh init is the one moment this is both safe (nothing has been
|
|
251
|
+
// indexed yet) and necessary (`.codegraph/` is gitignored, so every
|
|
252
|
+
// clone starts from the default templates).
|
|
336
253
|
//
|
|
337
254
|
// Never throws: a failure here is reported as a warning, not a
|
|
338
255
|
// failed init (the init itself already succeeded).
|
|
339
|
-
const
|
|
256
|
+
const configRepair = await repairCodegraphExcludeFromProject(projectRoot);
|
|
340
257
|
// These are confirmations, not warnings: `printResult` renders every
|
|
341
258
|
// `warnings` entry to stderr behind a `warning: ` prefix, so a fully
|
|
342
259
|
// successful init used to print a wall of `warning:` lines for what
|
|
@@ -344,9 +261,19 @@ async function runCodegraphInitCommand(io, options, asJson) {
|
|
|
344
261
|
const initNotes = [
|
|
345
262
|
`Stamped peaks-loop marker at ${guardOutcome.codegraphDir}/.peaks-loop-marker`
|
|
346
263
|
];
|
|
347
|
-
if (
|
|
348
|
-
|
|
349
|
-
|
|
264
|
+
if (configRepair.applied) {
|
|
265
|
+
if (configRepair.includePatternsAdded.length > 0) {
|
|
266
|
+
// A1 (2026-09-17): the include axis names its OWN file delta here too.
|
|
267
|
+
// Naming the patterns alone left the same gap the repair note had —
|
|
268
|
+
// a reader learned which extensions were appended but not how many
|
|
269
|
+
// tracked files that admitted, and this note is the ONLY place a
|
|
270
|
+
// fresh `init` reports the include repair.
|
|
271
|
+
initNotes.push(`Added ${configRepair.includePatternsAdded.length} include pattern(s) upstream's extractor supports but its default template omits, newly admitting ${configRepair.includeFilesRecovered} tracked source file(s) (${configRepair.includePatternsAdded.join(', ')}).${admittingClause(configRepair)}`);
|
|
272
|
+
}
|
|
273
|
+
if (configRepair.rulesRemoved.length > 0) {
|
|
274
|
+
initNotes.push(`Removed ${configRepair.rulesRemoved.length} exclude rule(s) that blocked tracked source files, recovering ${configRepair.filesRecovered} file(s); config backed up to ${configRepair.backupPath ?? ''}.`);
|
|
275
|
+
}
|
|
276
|
+
if (configRepair.reindexed) {
|
|
350
277
|
initNotes.push('Rebuilt the codegraph index over the recovered files.');
|
|
351
278
|
}
|
|
352
279
|
}
|
|
@@ -355,17 +282,21 @@ async function runCodegraphInitCommand(io, options, asJson) {
|
|
|
355
282
|
codegraphDir: guardOutcome.codegraphDir,
|
|
356
283
|
markerWritten: true,
|
|
357
284
|
excludeRepair: {
|
|
358
|
-
applied:
|
|
359
|
-
rulesRemoved:
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
285
|
+
applied: configRepair.applied,
|
|
286
|
+
rulesRemoved: configRepair.rulesRemoved,
|
|
287
|
+
includePatternsAdded: configRepair.includePatternsAdded,
|
|
288
|
+
filesRecovered: configRepair.filesRecovered,
|
|
289
|
+
includeFilesRecovered: configRepair.includeFilesRecovered,
|
|
290
|
+
includeAdmittedAfter: configRepair.includeAdmittedAfter,
|
|
291
|
+
trackedSourceCount: configRepair.trackedSourceCount,
|
|
292
|
+
reindexed: configRepair.reindexed,
|
|
293
|
+
backupPath: configRepair.backupPath,
|
|
294
|
+
warning: configRepair.warning
|
|
364
295
|
}
|
|
365
296
|
},
|
|
366
297
|
// Verbatim: `printResult` supplies the `warning: ` prefix, so a
|
|
367
298
|
// prefix added here would render as `warning: warning: ...`.
|
|
368
|
-
|
|
299
|
+
configRepair.warning === null ? [] : [configRepair.warning], initNotes), asJson);
|
|
369
300
|
}
|
|
370
301
|
catch (error) {
|
|
371
302
|
printCodegraphFailure(io, 'codegraph.init', error, asJson);
|
|
@@ -442,41 +373,55 @@ export function registerCodegraphCommands(program, io) {
|
|
|
442
373
|
addProjectOption(codegraph.command('status').description('Show codegraph status, including the exclude integrity gate')).action((options) => runCodegraphStatusCommand(io, options, options.peaksJson));
|
|
443
374
|
addProjectOption(codegraph
|
|
444
375
|
.command('repair-exclude')
|
|
445
|
-
.description('
|
|
376
|
+
.description('Normalize the codegraph include list, drop exclude rules that block tracked source files, then rebuild the index')).action((options) => runCodegraphRepairCommand(io, options, options.peaksJson, 'exclude'));
|
|
377
|
+
addProjectOption(codegraph
|
|
378
|
+
.command('repair-index')
|
|
379
|
+
.description('Repair both codegraph config axes, then rebuild the index from scratch (drops rows for deleted files)')).action((options) => runCodegraphRepairCommand(io, options, options.peaksJson, 'index'));
|
|
446
380
|
addProjectOption(codegraph.command('init').description('Initialize codegraph for a project')).action((options) => runCodegraphInitCommand(io, options, options.peaksJson));
|
|
447
381
|
addProjectOption(codegraph
|
|
448
382
|
.command('index')
|
|
449
383
|
.description('Index a project with codegraph')
|
|
450
384
|
.option('--force', 'force reindexing')
|
|
451
|
-
.option('--quiet', 'reduce upstream output')).action((options) =>
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
385
|
+
.option('--quiet', 'reduce upstream output')).action(async (options) => {
|
|
386
|
+
// `runCodegraphCommand` returns "upstream failed" for the one caller
|
|
387
|
+
// that ranks exit-code precedence (`status`); every other command just
|
|
388
|
+
// awaits it, so it is discarded here rather than leaked to commander.
|
|
389
|
+
await runCodegraphCommand(io, 'codegraph.index', {
|
|
390
|
+
subcommand: 'index',
|
|
391
|
+
project: options.project,
|
|
392
|
+
...(options.force === true ? { force: true } : {}),
|
|
393
|
+
...(options.quiet === true ? { quiet: true } : {})
|
|
394
|
+
}, options.peaksJson);
|
|
395
|
+
});
|
|
457
396
|
addProjectOption(codegraph
|
|
458
397
|
.command('query')
|
|
459
398
|
.description('Query codegraph')
|
|
460
399
|
.argument('<search>', 'search text')
|
|
461
400
|
.option('--json', 'forward JSON output flag to upstream codegraph')
|
|
462
|
-
.option('--limit <n>', 'maximum result count', parsePositiveInteger)).action((search, options) =>
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
401
|
+
.option('--limit <n>', 'maximum result count', parsePositiveInteger)).action(async (search, options) => {
|
|
402
|
+
await runCodegraphCommand(io, 'codegraph.query', {
|
|
403
|
+
subcommand: 'query',
|
|
404
|
+
project: options.project,
|
|
405
|
+
search,
|
|
406
|
+
...(options.json === true ? { json: true } : {}),
|
|
407
|
+
...(options.limit !== undefined ? { limit: options.limit } : {})
|
|
408
|
+
}, options.peaksJson);
|
|
409
|
+
});
|
|
469
410
|
addProjectOption(codegraph
|
|
470
411
|
.command('files')
|
|
471
412
|
.description('List codegraph files')
|
|
472
413
|
.option('--json', 'forward JSON output flag to upstream codegraph')
|
|
473
|
-
.option('--max-depth <n>', 'maximum traversal depth', parsePositiveInteger)).action((options) =>
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
414
|
+
.option('--max-depth <n>', 'maximum traversal depth', parsePositiveInteger)).action(async (options) => {
|
|
415
|
+
await runCodegraphCommand(io, 'codegraph.files', {
|
|
416
|
+
subcommand: 'files',
|
|
417
|
+
project: options.project,
|
|
418
|
+
...(options.json === true ? { json: true } : {}),
|
|
419
|
+
...(options.maxDepth !== undefined ? { maxDepth: options.maxDepth } : {})
|
|
420
|
+
}, options.peaksJson);
|
|
421
|
+
});
|
|
422
|
+
addProjectOption(codegraph.command('context').description('Build task context with codegraph').argument('<task>', 'task text')).action(async (task, options) => {
|
|
423
|
+
await runCodegraphCommand(io, 'codegraph.context', { subcommand: 'context', project: options.project, task }, options.peaksJson);
|
|
424
|
+
});
|
|
480
425
|
addProjectOption(codegraph
|
|
481
426
|
.command('affected')
|
|
482
427
|
.description('Find code affected by files')
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type ProgramIO } from '../cli-helpers.js';
|
|
2
|
+
import { type CommonCodegraphOptions } from './codegraph-command-runtime.js';
|
|
3
|
+
export declare function attributeUpstreamUpToDateLine(stdout: string): string;
|
|
4
|
+
/**
|
|
5
|
+
* `peaks codegraph status` with an integrity gate.
|
|
6
|
+
*
|
|
7
|
+
* The upstream status is still proxied verbatim (that is what the
|
|
8
|
+
* command has always done), but a clean upstream "index is up to date"
|
|
9
|
+
* is no longer sufficient: when git-tracked source files are being
|
|
10
|
+
* excluded by the config, or the index itself does not cover the
|
|
11
|
+
* repository, the command says so and names the rules and files.
|
|
12
|
+
*
|
|
13
|
+
* SEVERITY (user decision, option C): the exclude gate keeps its shipped
|
|
14
|
+
* blocking behaviour (exit 74); the index gate is ADVISORY by default and
|
|
15
|
+
* blocking only when `PEAKS_CODEGRAPH_INDEX_STRICT` is set. A detected
|
|
16
|
+
* gap is the finding either way — only the tag and the exit code move.
|
|
17
|
+
*
|
|
18
|
+
* Read-only by construction — it imports the integrity inspectors, never
|
|
19
|
+
* the repair writer. Fixing the config is `peaks codegraph init`
|
|
20
|
+
* (fresh) or `peaks codegraph repair-exclude` (explicit).
|
|
21
|
+
*/
|
|
22
|
+
export declare function runCodegraphStatusCommand(io: ProgramIO, options: CommonCodegraphOptions, asJson?: boolean): Promise<void>;
|