peaks-loop 4.0.50 → 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 +34 -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/share-commands.js +85 -18
- 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/dispatch/sub-agent-dispatcher.d.ts +11 -30
- package/dist/services/dispatch/sub-agent-dispatcher.js +5 -48
- 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/ide/adapters/claude-code-adapter.js +0 -1
- package/dist/services/ide/adapters/codex-adapter.js +1 -2
- package/dist/services/ide/adapters/cursor-adapter.js +1 -2
- package/dist/services/ide/adapters/hermes-adapter.js +1 -2
- package/dist/services/ide/adapters/openclaw-adapter.js +1 -2
- package/dist/services/ide/adapters/qoder-adapter.js +1 -2
- package/dist/services/ide/adapters/tongyi-lingma-adapter.js +1 -2
- package/dist/services/ide/adapters/trae-adapter.js +1 -2
- package/dist/services/ide/adapters/zcode-adapter.js +0 -1
- package/dist/services/ide/ide-types.d.ts +0 -2
- 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-perf-audit/SKILL.md +2 -2
- package/skills/bee/peaks-perf-audit/references/audit-protocol.md +1 -1
- package/skills/bee/peaks-prd/SKILL.md +4 -4
- package/skills/bee/peaks-prd/references/prd-for-multi-pass.md +1 -1
- package/skills/bee/peaks-prd/references/workflow.md +1 -1
- package/skills/bee/peaks-qa/SKILL.md +6 -6
- package/skills/bee/peaks-qa/references/external-capability-guidance.md +1 -1
- package/skills/bee/peaks-qa/references/qa-fanout-contract.md +1 -1
- package/skills/bee/peaks-qa/references/qa-skill-presence.md +1 -1
- package/skills/bee/peaks-qa/references/reading-handoff-frontmatter.md +2 -2
- package/skills/bee/peaks-rd/SKILL.md +2 -2
- package/skills/bee/peaks-rd/references/code-reviewer-4dim-hint.md +1 -1
- package/skills/bee/peaks-rd/references/external-references.md +1 -1
- package/skills/bee/peaks-rd/references/mandatory-perf-baseline.md +1 -1
- package/skills/bee/peaks-rd/references/ocr-multilang-1.8.md +2 -2
- package/skills/bee/peaks-rd/references/parallel-review-fanout.md +2 -2
- package/skills/bee/peaks-rd/references/rd-fanout-contracts.md +11 -8
- package/skills/bee/peaks-rd/references/rd-runbook.md +1 -1
- package/skills/bee/peaks-rd/references/rd-sub-agent-dispatch.md +7 -7
- package/skills/bee/peaks-rd/references/rd-transition-gates.md +1 -1
- package/skills/bee/peaks-rd/references/reading-v2-slice-results.md +1 -1
- package/skills/bee/peaks-rd/references/skill-presence-and-title.md +1 -1
- package/skills/bee/peaks-rd/references/v2-12-fanout-collapse.md +7 -5
- package/skills/bee/peaks-rd/references/writing-handoff-frontmatter.md +3 -3
- package/skills/bee/peaks-reviewer/SKILL.md +1 -1
- package/skills/bee/peaks-sc/SKILL.md +1 -1
- package/skills/bee/peaks-security-audit/SKILL.md +3 -3
- package/skills/bee/peaks-security-audit/references/audit-protocol.md +1 -1
- package/skills/bee/peaks-txt/SKILL.md +3 -3
- package/skills/bee/peaks-txt/references/context-capsule.md +1 -1
- package/skills/bee/peaks-ui/SKILL.md +1 -1
- package/skills/peaks-audit/SKILL.md +1 -1
- package/skills/peaks-code/SKILL.md +9 -9
- package/skills/peaks-code/references/context-governance.md +1 -1
- package/skills/peaks-code/references/dag-orchestrator.md +3 -4
- package/skills/peaks-code/references/external-references.md +1 -1
- package/skills/peaks-code/references/external-skill-invocation.md +2 -2
- package/skills/peaks-code/references/fanout-mandatory.md +3 -3
- package/skills/peaks-code/references/frontend-only-mode.md +2 -2
- package/skills/peaks-code/references/gstack-integration.md +1 -1
- package/skills/peaks-code/references/micro-cycle.md +1 -1
- package/skills/peaks-code/references/periodic-checkpoint.md +2 -2
- package/skills/peaks-code/references/project-memory-loading.md +19 -1
- package/skills/peaks-code/references/project-scan-checklist.md +1 -1
- package/skills/peaks-code/references/resume-detection.md +1 -1
- package/skills/peaks-code/references/runbook.md +3 -3
- package/skills/peaks-code/references/session-overload-signal-index.md +2 -2
- package/skills/peaks-code/references/startup-sequence.md +16 -16
- package/skills/peaks-code/references/step-11-memory-sediment.md +3 -3
- package/skills/peaks-code/references/sub-agent-dispatch.md +7 -6
- package/skills/peaks-code/references/swarm-dispatch-contract.md +1 -1
- package/skills/peaks-code/references/workflow-gates-and-types.md +3 -3
- package/skills/peaks-code/references/worktree-governance.md +1 -1
- package/skills/peaks-final-review/SKILL.md +3 -3
- package/skills/peaks-ide/references/audit-log-helper.md +5 -4
- package/skills/peaks-resume/SKILL.md +1 -1
- package/skills/peaks-slice-decompose/SKILL.md +4 -4
- package/skills/peaks-slice-decompose/references/cross-pass-edge-interpretation.md +1 -1
- package/skills/peaks-slice-decompose/references/granularity-decision.md +1 -1
- package/skills/peaks-slice-decompose/references/v2-schema.md +2 -2
- package/skills/peaks-solo/SKILL.md +1 -2
|
@@ -139,22 +139,13 @@ export declare const claudeCodeSubAgentDispatcher: SubAgentDispatcher;
|
|
|
139
139
|
* stays the same; only the per-IDE wiring breaks (intentionally).
|
|
140
140
|
*/
|
|
141
141
|
export declare const traeSubAgentDispatcher: SubAgentDispatcher;
|
|
142
|
-
/**
|
|
143
|
-
* Trae-CN dispatcher. Mirrors Trae's shape with a separate label so
|
|
144
|
-
* the CLI's IDE detection can distinguish a Trae install region
|
|
145
|
-
* (Trae-CN differs in skill install path / log location only;
|
|
146
|
-
* dispatch surface is identical per slice #011 framework rule).
|
|
147
|
-
*
|
|
148
|
-
* Slice 1.3: real `awaitBatch` — same polling core as Trae.
|
|
149
|
-
*/
|
|
150
|
-
export declare const traeCnSubAgentDispatcher: SubAgentDispatcher;
|
|
151
142
|
/**
|
|
152
143
|
* Codex (OpenAI CLI IDE) dispatcher.
|
|
153
144
|
*
|
|
154
145
|
* Slice #13 noted Codex's sub-agent tool name is TBD; per slice #009
|
|
155
146
|
* rationale, the dispatcher mirrors Claude Code's shape so the
|
|
156
|
-
* adapter contract stays uniform. Slice 1.3 promotes Codex from
|
|
157
|
-
*
|
|
147
|
+
* adapter contract stays uniform. Slice 1.3 promotes Codex from the
|
|
148
|
+
* 1.2 marker to a real `awaitBatch` (file-based polling,
|
|
158
149
|
* Codex default 45s — Codex's documented heartbeat is slightly
|
|
159
150
|
* slower per slice #13 R-3).
|
|
160
151
|
*/
|
|
@@ -201,36 +192,26 @@ export declare class SubAgentNotSupportedError extends Error {
|
|
|
201
192
|
*/
|
|
202
193
|
export declare function awaitClaudeCodeBatch(input: SubAgentAwaitBatchInput): Promise<readonly SubAgentBatchResult[]>;
|
|
203
194
|
/**
|
|
204
|
-
* Slice 1.3 — shared per-IDE polling core for trae /
|
|
205
|
-
*
|
|
206
|
-
*
|
|
207
|
-
* (a) `defaultTimeoutMs` (Trae /
|
|
208
|
-
*
|
|
209
|
-
*
|
|
210
|
-
* IDE).
|
|
195
|
+
* Slice 1.3 — shared per-IDE polling core for trae / codex / cursor.
|
|
196
|
+
* Same polling loop shape as `awaitClaudeCodeBatch`, with per-IDE
|
|
197
|
+
* default timeout + note prefix. The 3 IDEs differ only in
|
|
198
|
+
* (a) `defaultTimeoutMs` (Trae / Cursor = 30s, Codex = 45s per slice
|
|
199
|
+
* #13 R-3) and (b) the `note` label surfaced when an IDE times out
|
|
200
|
+
* (so 1.4 dogfood can attribute a timeout to the right IDE).
|
|
211
201
|
*
|
|
212
|
-
* MVP rationale (per Karpathy §2 Simplicity First): the
|
|
202
|
+
* MVP rationale (per Karpathy §2 Simplicity First): the 3 IDEs
|
|
213
203
|
* currently share the same file-based polling transport. The only
|
|
214
204
|
* per-IDE distinction is the timeout + label. Future per-IDE
|
|
215
205
|
* divergence (real IPC / shell hooks) is a 1.4 dogfood concern —
|
|
216
206
|
* here we keep the dispatcher interface uniform while each IDE's
|
|
217
|
-
* `awaitBatch` is
|
|
218
|
-
* `awaitByLlmFallback` marker.
|
|
207
|
+
* `awaitBatch` is a real implementation.
|
|
219
208
|
*/
|
|
220
209
|
export interface PollDispatchRecordsOptions {
|
|
221
|
-
readonly ide: 'trae' | '
|
|
210
|
+
readonly ide: 'trae' | 'codex' | 'cursor';
|
|
222
211
|
readonly defaultTimeoutMs: number;
|
|
223
212
|
readonly notePrefix: string;
|
|
224
213
|
}
|
|
225
214
|
export declare function pollDispatchRecords(input: SubAgentAwaitBatchInput, opts: PollDispatchRecordsOptions): Promise<readonly SubAgentBatchResult[]>;
|
|
226
|
-
/**
|
|
227
|
-
* 1.2 fallback for trae / trae-cn / codex / cursor. Deprecated by
|
|
228
|
-
* slice 1.3 — kept exported for legacy callers + back-compat tests
|
|
229
|
-
* (the 1.2 marker is still a valid envelope shape; the 1.4 dogfood
|
|
230
|
-
* tests can compare the marker note vs the 1.3 real note to verify
|
|
231
|
-
* per-IDE attribution).
|
|
232
|
-
*/
|
|
233
|
-
export declare function awaitByLlmFallback(input: SubAgentAwaitBatchInput, ide: string): Promise<readonly SubAgentBatchResult[]>;
|
|
234
215
|
/**
|
|
235
216
|
* In-process awaiter registration hook (used by `peaks sub-agent dispatch`
|
|
236
217
|
* to attach a resolver; not part of the dispatcher public surface).
|
|
@@ -106,38 +106,13 @@ export const traeSubAgentDispatcher = {
|
|
|
106
106
|
notePrefix: 'trae 1.3 real awaitBatch'
|
|
107
107
|
})
|
|
108
108
|
};
|
|
109
|
-
/**
|
|
110
|
-
* Trae-CN dispatcher. Mirrors Trae's shape with a separate label so
|
|
111
|
-
* the CLI's IDE detection can distinguish a Trae install region
|
|
112
|
-
* (Trae-CN differs in skill install path / log location only;
|
|
113
|
-
* dispatch surface is identical per slice #011 framework rule).
|
|
114
|
-
*
|
|
115
|
-
* Slice 1.3: real `awaitBatch` — same polling core as Trae.
|
|
116
|
-
*/
|
|
117
|
-
export const traeCnSubAgentDispatcher = {
|
|
118
|
-
label: 'trae-cn',
|
|
119
|
-
supportsRole: (role) => role.length > 0,
|
|
120
|
-
buildToolCall: ({ role, prompt, requestId }) => ({
|
|
121
|
-
name: 'Task',
|
|
122
|
-
args: {
|
|
123
|
-
subagent_type: 'general-purpose',
|
|
124
|
-
description: `${role} for rid=${requestId}`,
|
|
125
|
-
prompt,
|
|
126
|
-
},
|
|
127
|
-
}),
|
|
128
|
-
awaitBatch: async (input) => pollDispatchRecords(input, {
|
|
129
|
-
ide: 'trae-cn',
|
|
130
|
-
defaultTimeoutMs: 30_000,
|
|
131
|
-
notePrefix: 'trae-cn 1.3 real awaitBatch'
|
|
132
|
-
})
|
|
133
|
-
};
|
|
134
109
|
/**
|
|
135
110
|
* Codex (OpenAI CLI IDE) dispatcher.
|
|
136
111
|
*
|
|
137
112
|
* Slice #13 noted Codex's sub-agent tool name is TBD; per slice #009
|
|
138
113
|
* rationale, the dispatcher mirrors Claude Code's shape so the
|
|
139
|
-
* adapter contract stays uniform. Slice 1.3 promotes Codex from
|
|
140
|
-
*
|
|
114
|
+
* adapter contract stays uniform. Slice 1.3 promotes Codex from the
|
|
115
|
+
* 1.2 marker to a real `awaitBatch` (file-based polling,
|
|
141
116
|
* Codex default 45s — Codex's documented heartbeat is slightly
|
|
142
117
|
* slower per slice #13 R-3).
|
|
143
118
|
*/
|
|
@@ -245,14 +220,14 @@ export async function awaitClaudeCodeBatch(input) {
|
|
|
245
220
|
// service. The back-compat envelope shape is preserved (one
|
|
246
221
|
// `SubAgentBatchResult` per record path) so the S3 characterization
|
|
247
222
|
// test stays green; the underlying loop is identical to the trae /
|
|
248
|
-
//
|
|
223
|
+
// codex / cursor wrappers below. The new typed outcome
|
|
249
224
|
// lives on the unified service; the S4 fail-fast test pins it.
|
|
250
225
|
//
|
|
251
226
|
// Slice 2026-07-30-nightshift: claude-code does NOT use a
|
|
252
227
|
// per-IDE note prefix. The 1.4 dogfood contract says the done
|
|
253
228
|
// note is `null` (raw outcome) and the failed note is the raw
|
|
254
|
-
// `outcome` string with no prefix. The
|
|
255
|
-
// (trae /
|
|
229
|
+
// `outcome` string with no prefix. The 3 non-Claude IDEs
|
|
230
|
+
// (trae / codex / cursor) prefix the note with their
|
|
256
231
|
// per-IDE label so cross-IDE attribution is visible to the LLM.
|
|
257
232
|
// Passing no `notePrefix` here keeps the legacy contract.
|
|
258
233
|
const unified = await awaitBatchUnified(input.dispatchCount, input.recordPaths, input.timeoutMs, { defaultTimeoutMs: 60_000 });
|
|
@@ -299,24 +274,6 @@ export async function pollDispatchRecords(input, opts) {
|
|
|
299
274
|
});
|
|
300
275
|
return unified.results;
|
|
301
276
|
}
|
|
302
|
-
/**
|
|
303
|
-
* 1.2 fallback for trae / trae-cn / codex / cursor. Deprecated by
|
|
304
|
-
* slice 1.3 — kept exported for legacy callers + back-compat tests
|
|
305
|
-
* (the 1.2 marker is still a valid envelope shape; the 1.4 dogfood
|
|
306
|
-
* tests can compare the marker note vs the 1.3 real note to verify
|
|
307
|
-
* per-IDE attribution).
|
|
308
|
-
*/
|
|
309
|
-
export async function awaitByLlmFallback(input, ide) {
|
|
310
|
-
const startedAt = Date.now();
|
|
311
|
-
return input.recordPaths.map((p, i) => ({
|
|
312
|
-
dispatchIndex: i,
|
|
313
|
-
recordPath: p,
|
|
314
|
-
status: 'timeout',
|
|
315
|
-
durationMs: 0,
|
|
316
|
-
note: `awaitByLlm: ${ide} 1.2 fallback (real impl in 1.3)`
|
|
317
|
-
}));
|
|
318
|
-
void startedAt;
|
|
319
|
-
}
|
|
320
277
|
/**
|
|
321
278
|
* In-process awaiter registration hook (used by `peaks sub-agent dispatch`
|
|
322
279
|
* to attach a resolver; not part of the dispatcher public surface).
|
|
@@ -30,8 +30,23 @@ import { inspectCodegraphExcludeIntegrity, isCodegraphExcludeConfigPresent } fro
|
|
|
30
30
|
const CHECK_ID = 'capability:codegraph-exclude-integrity';
|
|
31
31
|
/** How many rules / offending files the message names before eliding. */
|
|
32
32
|
const MAX_NAMED = 5;
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
/**
|
|
34
|
+
* 2026-09-17 — `projectRoot` is the doctor's resolved L3 root, NOT
|
|
35
|
+
* `process.cwd()`. Same defect as the sibling `codegraph-index-integrity`
|
|
36
|
+
* probe (see its note): with `projectRootResolver` injected, every other
|
|
37
|
+
* check inspected the caller's root while this one inspected the operator's
|
|
38
|
+
* checkout, so its verdict depended on which repository you ran the doctor
|
|
39
|
+
* in. This one is read-only — it reads `.codegraph/config.json` and
|
|
40
|
+
* `git ls-files`, never the sqlite index — so unlike its sibling it did not
|
|
41
|
+
* also materialise `-shm`/`-wal` sidecars; the wrong-root defect was the
|
|
42
|
+
* same either way.
|
|
43
|
+
*/
|
|
44
|
+
function defaultProbe(projectRoot) {
|
|
45
|
+
// An unresolved root is not a project — see the sibling probe's note: a
|
|
46
|
+
// relative lookup here would resolve against `cwd` and inspect the
|
|
47
|
+
// operator's checkout.
|
|
48
|
+
if (projectRoot.length === 0)
|
|
49
|
+
return null;
|
|
35
50
|
// No config → codegraph was never initialized here, so no exclude
|
|
36
51
|
// list is in play and there is nothing to report.
|
|
37
52
|
return isCodegraphExcludeConfigPresent(projectRoot)
|
|
@@ -48,8 +63,8 @@ function renderGapMessage(excludedTrackedCount, trackedSourceCount, rulesToRemov
|
|
|
48
63
|
const elidedFiles = violations.length > MAX_NAMED ? `; … (+${violations.length - MAX_NAMED})` : '';
|
|
49
64
|
return `codegraph index is incomplete: ${excludedTrackedCount} of ${trackedSourceCount} tracked source files are blocked by ${rulesToRemove.length} exclude rule(s) [${namedRules}${elidedRules}]. Blocked: ${namedFiles}${elidedFiles}. Run \`peaks codegraph repair-exclude --project <root>\` to drop them and rebuild the index.`;
|
|
50
65
|
}
|
|
51
|
-
function run({ options }) {
|
|
52
|
-
const probe = options.codegraphIntegrityProbe ?? defaultProbe;
|
|
66
|
+
function run({ options, resolvedL3Root }) {
|
|
67
|
+
const probe = options.codegraphIntegrityProbe ?? (() => defaultProbe(resolvedL3Root));
|
|
53
68
|
let report;
|
|
54
69
|
try {
|
|
55
70
|
report = probe();
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check: codegraph index integrity (`capability:codegraph-index-integrity`).
|
|
3
|
+
*
|
|
4
|
+
* The third codegraph check, and the one that stops `[OK]` from being a
|
|
5
|
+
* self-consistency assertion:
|
|
6
|
+
* - `capability:codegraph` answers "is upstream resolvable";
|
|
7
|
+
* - `capability:codegraph-exclude-integrity` answers "do the `exclude`
|
|
8
|
+
* rules drop tracked files";
|
|
9
|
+
* - this one answers "does the INDEX ITSELF cover the repository" —
|
|
10
|
+
* files the extractor supports that `include` never admitted, and rows
|
|
11
|
+
* the index still holds for paths that are gone.
|
|
12
|
+
*
|
|
13
|
+
* Why the exclude gate structurally cannot answer it: that gate runs the
|
|
14
|
+
* `include` filter FIRST and reconciles `exclude` against the survivors, so
|
|
15
|
+
* a file dropped by `include` is not "a tracked source file" as far as it is
|
|
16
|
+
* concerned; and it never reads the index at all, so dead rows are invisible
|
|
17
|
+
* to it. Both defects were present while `peaks codegraph status` printed
|
|
18
|
+
* `[OK] Index is up to date`.
|
|
19
|
+
*
|
|
20
|
+
* Read-only by construction — it consumes the same read-only inspector
|
|
21
|
+
* `peaks codegraph status` gates on. It never writes `.codegraph/config.json`
|
|
22
|
+
* and never invokes the upstream binary.
|
|
23
|
+
*
|
|
24
|
+
* Failure posture:
|
|
25
|
+
* - codegraph not initialized in the inspected root (no
|
|
26
|
+
* `.codegraph/codegraph.db`) → `ok: true`; there is no index to be
|
|
27
|
+
* incomplete or stale, and a fresh clone must not fail the doctor.
|
|
28
|
+
* - a confirmed gap on either axis → `ok: false`. ADVISORY by default
|
|
29
|
+
* (`severity: 'warning'`, the doctor exit code is left alone), and
|
|
30
|
+
* blocking (no severity tag) when the project opts in with
|
|
31
|
+
* `PEAKS_CODEGRAPH_INDEX_STRICT=1` — the user's option C decision.
|
|
32
|
+
* The finding is `ok: false` either way; only its severity moves.
|
|
33
|
+
* - could not evaluate (not a git work tree, missing/malformed config,
|
|
34
|
+
* unreadable index) → `ok: false, severity: 'warning'` so the doctor
|
|
35
|
+
* reports the blind spot without flipping the exit code on an
|
|
36
|
+
* unrelated failure. Kept non-blocking in BOTH modes: "could not
|
|
37
|
+
* evaluate" is not a finding about the project, and it is
|
|
38
|
+
* distinguishable from the `ok: true` "covers the repository"
|
|
39
|
+
* verdict by its `ok` value.
|
|
40
|
+
*
|
|
41
|
+
* R12-2 — the partial collapse that remains, stated rather than implied:
|
|
42
|
+
* this branch and the advisory `gap` branch below BOTH emit `ok: false`
|
|
43
|
+
* with `severity: 'warning'`, and `DoctorCheck` has no third field, so in
|
|
44
|
+
* the doctor envelope they are separated by message text alone. Not fixed,
|
|
45
|
+
* deliberately: the shape is legacy (`runDoctor` compatibility is a
|
|
46
|
+
* stated constraint), neither state is `ok: true` — so the invariant that
|
|
47
|
+
* a non-measurement may never read as "verified clean" holds — and in the
|
|
48
|
+
* mode where they are collapsed neither state moves the exit code.
|
|
49
|
+
* Under `PEAKS_CODEGRAPH_INDEX_STRICT=1` they ARE separated in the
|
|
50
|
+
* machine fields: the advisory `gap` branch drops its tag, this one keeps
|
|
51
|
+
* it. Pinned by the "(severity policy)" and "(unevaluable)" tests.
|
|
52
|
+
*/
|
|
53
|
+
import type { DoctorCheckPlugin } from '../types.js';
|
|
54
|
+
export declare const check: DoctorCheckPlugin;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check: codegraph index integrity (`capability:codegraph-index-integrity`).
|
|
3
|
+
*
|
|
4
|
+
* The third codegraph check, and the one that stops `[OK]` from being a
|
|
5
|
+
* self-consistency assertion:
|
|
6
|
+
* - `capability:codegraph` answers "is upstream resolvable";
|
|
7
|
+
* - `capability:codegraph-exclude-integrity` answers "do the `exclude`
|
|
8
|
+
* rules drop tracked files";
|
|
9
|
+
* - this one answers "does the INDEX ITSELF cover the repository" —
|
|
10
|
+
* files the extractor supports that `include` never admitted, and rows
|
|
11
|
+
* the index still holds for paths that are gone.
|
|
12
|
+
*
|
|
13
|
+
* Why the exclude gate structurally cannot answer it: that gate runs the
|
|
14
|
+
* `include` filter FIRST and reconciles `exclude` against the survivors, so
|
|
15
|
+
* a file dropped by `include` is not "a tracked source file" as far as it is
|
|
16
|
+
* concerned; and it never reads the index at all, so dead rows are invisible
|
|
17
|
+
* to it. Both defects were present while `peaks codegraph status` printed
|
|
18
|
+
* `[OK] Index is up to date`.
|
|
19
|
+
*
|
|
20
|
+
* Read-only by construction — it consumes the same read-only inspector
|
|
21
|
+
* `peaks codegraph status` gates on. It never writes `.codegraph/config.json`
|
|
22
|
+
* and never invokes the upstream binary.
|
|
23
|
+
*
|
|
24
|
+
* Failure posture:
|
|
25
|
+
* - codegraph not initialized in the inspected root (no
|
|
26
|
+
* `.codegraph/codegraph.db`) → `ok: true`; there is no index to be
|
|
27
|
+
* incomplete or stale, and a fresh clone must not fail the doctor.
|
|
28
|
+
* - a confirmed gap on either axis → `ok: false`. ADVISORY by default
|
|
29
|
+
* (`severity: 'warning'`, the doctor exit code is left alone), and
|
|
30
|
+
* blocking (no severity tag) when the project opts in with
|
|
31
|
+
* `PEAKS_CODEGRAPH_INDEX_STRICT=1` — the user's option C decision.
|
|
32
|
+
* The finding is `ok: false` either way; only its severity moves.
|
|
33
|
+
* - could not evaluate (not a git work tree, missing/malformed config,
|
|
34
|
+
* unreadable index) → `ok: false, severity: 'warning'` so the doctor
|
|
35
|
+
* reports the blind spot without flipping the exit code on an
|
|
36
|
+
* unrelated failure. Kept non-blocking in BOTH modes: "could not
|
|
37
|
+
* evaluate" is not a finding about the project, and it is
|
|
38
|
+
* distinguishable from the `ok: true` "covers the repository"
|
|
39
|
+
* verdict by its `ok` value.
|
|
40
|
+
*
|
|
41
|
+
* R12-2 — the partial collapse that remains, stated rather than implied:
|
|
42
|
+
* this branch and the advisory `gap` branch below BOTH emit `ok: false`
|
|
43
|
+
* with `severity: 'warning'`, and `DoctorCheck` has no third field, so in
|
|
44
|
+
* the doctor envelope they are separated by message text alone. Not fixed,
|
|
45
|
+
* deliberately: the shape is legacy (`runDoctor` compatibility is a
|
|
46
|
+
* stated constraint), neither state is `ok: true` — so the invariant that
|
|
47
|
+
* a non-measurement may never read as "verified clean" holds — and in the
|
|
48
|
+
* mode where they are collapsed neither state moves the exit code.
|
|
49
|
+
* Under `PEAKS_CODEGRAPH_INDEX_STRICT=1` they ARE separated in the
|
|
50
|
+
* machine fields: the advisory `gap` branch drops its tag, this one keeps
|
|
51
|
+
* it. Pinned by the "(severity policy)" and "(unevaluable)" tests.
|
|
52
|
+
*/
|
|
53
|
+
import { getErrorMessage } from 'peaks-loop-shared/result';
|
|
54
|
+
import { isCodegraphInitialized } from '../../../codegraph/codegraph-service.js';
|
|
55
|
+
import { CODEGRAPH_INDEX_STRICT_ENV_VAR, CODEGRAPH_REPAIR_INDEX_COMMAND, inspectCodegraphIndexIntegrity, isCodegraphIndexStrictMode } from '../../../codegraph/codegraph-index-integrity.js';
|
|
56
|
+
const CHECK_ID = 'capability:codegraph-index-integrity';
|
|
57
|
+
/** How many offending paths the message names per axis before eliding. */
|
|
58
|
+
const MAX_NAMED = 5;
|
|
59
|
+
function elide(paths) {
|
|
60
|
+
const named = paths.slice(0, MAX_NAMED).join(', ');
|
|
61
|
+
return paths.length > MAX_NAMED ? `${named}, … (+${paths.length - MAX_NAMED})` : named;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* 2026-09-17 — `projectRoot` is the doctor's resolved L3 root, NOT
|
|
65
|
+
* `process.cwd()`. It used to read `process.cwd()`, which is a different
|
|
66
|
+
* thing from the root the rest of the doctor was pointed at: a caller that
|
|
67
|
+
* injects `projectRootResolver` (e.g.
|
|
68
|
+
* `tests/unit/doctor/doctor-exit-code-warn-only.test.ts`) got every other
|
|
69
|
+
* check aimed at its temp root while THIS one opened the operator's real
|
|
70
|
+
* `.codegraph/codegraph.db`. Opening that database materialises its
|
|
71
|
+
* `-shm`/`-wal` sidecars, so a unit run mutated the operator's checkout and
|
|
72
|
+
* the check's result depended on which repository you happened to run it
|
|
73
|
+
* in. Every other L3 check reads `resolvedL3Root` from `DoctorContext`;
|
|
74
|
+
* this one now does too.
|
|
75
|
+
*/
|
|
76
|
+
function defaultProbe(projectRoot) {
|
|
77
|
+
// An unresolved root is not a project. It must NOT fall through to a
|
|
78
|
+
// relative lookup (`join('', '.codegraph', …)` resolves against `cwd`),
|
|
79
|
+
// because that fallback IS the defect this signature was changed to close:
|
|
80
|
+
// a caller that never resolved a root would silently inspect the operator's
|
|
81
|
+
// checkout. `runDoctor` always resolves one; only a hand-built test context
|
|
82
|
+
// can pass ''.
|
|
83
|
+
if (projectRoot.length === 0)
|
|
84
|
+
return null;
|
|
85
|
+
// No index → nothing to be incomplete or stale.
|
|
86
|
+
return isCodegraphInitialized(projectRoot) ? inspectCodegraphIndexIntegrity(projectRoot) : null;
|
|
87
|
+
}
|
|
88
|
+
function renderGapMessage(includeGap, admittedTrackedCount, trackedSourceCount, deadRows, indexedFileCount) {
|
|
89
|
+
const parts = [];
|
|
90
|
+
if (includeGap.length > 0) {
|
|
91
|
+
parts.push(`${includeGap.length} of ${trackedSourceCount} extractor-supported tracked file(s) are not admitted by the config's include globs (admitted: ${admittedTrackedCount}) [${elide(includeGap)}]`);
|
|
92
|
+
}
|
|
93
|
+
if (deadRows.length > 0) {
|
|
94
|
+
parts.push(`${deadRows.length} of ${indexedFileCount} indexed file(s) are gone from disk [${elide(deadRows)}]`);
|
|
95
|
+
}
|
|
96
|
+
return `codegraph index does not cover the repository: ${parts.join('; ')}.`;
|
|
97
|
+
}
|
|
98
|
+
// The remediation clause, in both modes. Naming the command is the
|
|
99
|
+
// slice-002 half of slice-001's design decision 4 (which deliberately named
|
|
100
|
+
// none while none existed); the command name is a shared constant, so this
|
|
101
|
+
// message cannot drift from the CLI surface it points at.
|
|
102
|
+
function remediation() {
|
|
103
|
+
return `Run \`${CODEGRAPH_REPAIR_INDEX_COMMAND}\` to add the missing include pattern(s) and rebuild the index without the stale rows.`;
|
|
104
|
+
}
|
|
105
|
+
function run({ options, resolvedL3Root }) {
|
|
106
|
+
const probe = options.codegraphIndexIntegrityProbe ?? (() => defaultProbe(resolvedL3Root));
|
|
107
|
+
const strict = isCodegraphIndexStrictMode();
|
|
108
|
+
let report;
|
|
109
|
+
try {
|
|
110
|
+
report = probe();
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
return [{
|
|
114
|
+
id: CHECK_ID,
|
|
115
|
+
ok: false,
|
|
116
|
+
severity: 'warning',
|
|
117
|
+
message: `codegraph index integrity could not be evaluated: ${getErrorMessage(error)}`
|
|
118
|
+
}];
|
|
119
|
+
}
|
|
120
|
+
if (report === null) {
|
|
121
|
+
return [{
|
|
122
|
+
id: CHECK_ID,
|
|
123
|
+
ok: true,
|
|
124
|
+
message: 'codegraph is not initialized in this project (no .codegraph/codegraph.db); there is no index to be incomplete or stale'
|
|
125
|
+
}];
|
|
126
|
+
}
|
|
127
|
+
if (!report.gap) {
|
|
128
|
+
return [{
|
|
129
|
+
id: CHECK_ID,
|
|
130
|
+
ok: true,
|
|
131
|
+
message: `codegraph index covers the repository (${report.admittedTrackedCount} extractor-supported tracked file(s) admitted, ${report.indexedFileCount} indexed row(s), none stale)`
|
|
132
|
+
}];
|
|
133
|
+
}
|
|
134
|
+
const gapMessage = renderGapMessage(report.includeGap, report.admittedTrackedCount, report.trackedSourceCount, report.deadRows, report.indexedFileCount);
|
|
135
|
+
// Option C: advisory by default, blocking on opt-in. `ok: false` in both
|
|
136
|
+
// modes — the finding is reported either way; only `severity` (and with
|
|
137
|
+
// it the doctor exit code) moves. The advisory suffix is the discovery
|
|
138
|
+
// path for the switch, so an operator who wants blocking is told how.
|
|
139
|
+
return strict
|
|
140
|
+
? [{ id: CHECK_ID, ok: false, message: `${gapMessage} ${remediation()}` }]
|
|
141
|
+
: [{
|
|
142
|
+
id: CHECK_ID,
|
|
143
|
+
ok: false,
|
|
144
|
+
severity: 'warning',
|
|
145
|
+
message: `${gapMessage} ${remediation()} Advisory: set ${CODEGRAPH_INDEX_STRICT_ENV_VAR}=1 to make this blocking.`
|
|
146
|
+
}];
|
|
147
|
+
}
|
|
148
|
+
export const check = {
|
|
149
|
+
name: 'codegraph-index-integrity',
|
|
150
|
+
run
|
|
151
|
+
};
|
|
@@ -18,16 +18,16 @@
|
|
|
18
18
|
import { existsSync, readdirSync } from 'node:fs';
|
|
19
19
|
import { join } from 'node:path';
|
|
20
20
|
import { getErrorMessage } from 'peaks-loop-shared/result';
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
21
|
+
import { RUNTIME_SYSTEM_SUBDIRS } from '../../../workspace/runtime-layout.js';
|
|
22
|
+
// The exclude-list moved to `src/services/workspace/runtime-layout.ts`.
|
|
23
|
+
// It is imported above, not re-declared here: the local literal
|
|
24
|
+
// (`new Set(['change'])`) had already drifted — `callers/` is a designed
|
|
25
|
+
// location written by `caller-binding-service.ts` and was never added, so
|
|
26
|
+
// this check reported `4 orphan session(s) …: callers, cli, unknown-sid, x`
|
|
27
|
+
// and `peaks doctor` exited 1 on a clean workspace, permanently.
|
|
28
|
+
// `tests/unit/workspace/runtime-layout-drift-guard.test.ts` now fails when
|
|
29
|
+
// the code writes a `.peaks/_runtime/` child the registry does not know, so
|
|
30
|
+
// the set can no longer drift silently.
|
|
31
31
|
function run({ resolvedL3Root, isValidSessionId }) {
|
|
32
32
|
try {
|
|
33
33
|
const runtimeDir = join(resolvedL3Root, '.peaks/_runtime');
|
|
@@ -43,6 +43,7 @@ import { check as statuslineInstall } from './checks/statusline-install.js';
|
|
|
43
43
|
import { check as statuslineRuntime } from './checks/statusline-runtime.js';
|
|
44
44
|
import { check as codegraphCapability } from './checks/codegraph-capability.js';
|
|
45
45
|
import { check as codegraphExcludeIntegrity } from './checks/codegraph-exclude-integrity.js';
|
|
46
|
+
import { check as codegraphIndexIntegrity } from './checks/codegraph-index-integrity.js';
|
|
46
47
|
import { check as distSourceVersion } from './checks/dist-source-version.js';
|
|
47
48
|
import { check as multiBinaryDrift } from './checks/multi-binary-drift.js';
|
|
48
49
|
import { check as workspaceLayout } from './checks/workspace-layout.js';
|
|
@@ -72,6 +73,7 @@ export const PLUGINS = [
|
|
|
72
73
|
statuslineRuntime, // id "statusline:runtime"
|
|
73
74
|
codegraphCapability, // id "capability:codegraph"
|
|
74
75
|
codegraphExcludeIntegrity, // id "capability:codegraph-exclude-integrity"
|
|
76
|
+
codegraphIndexIntegrity, // id "capability:codegraph-index-integrity"
|
|
75
77
|
distSourceVersion, // id "build:dist-version-matches-source"
|
|
76
78
|
multiBinaryDrift, // id "build:multi-binary-drift"
|
|
77
79
|
workspaceLayout, // id "build:workspace-layout-canonical"
|
|
@@ -94,6 +94,23 @@ export type CodegraphExcludeIntegrityProbe = {
|
|
|
94
94
|
readonly matchedRule: string;
|
|
95
95
|
}[];
|
|
96
96
|
};
|
|
97
|
+
/**
|
|
98
|
+
* Structural shape of the codegraph index-integrity report the
|
|
99
|
+
* `capability:codegraph-index-integrity` check gates on. Declared
|
|
100
|
+
* structurally (rather than imported from the codegraph service) to
|
|
101
|
+
* keep this type module dependency-free — the default probe returns a
|
|
102
|
+
* `CodegraphIndexIntegrityReport`, which is assignable here.
|
|
103
|
+
*/
|
|
104
|
+
export type CodegraphIndexIntegrityProbe = {
|
|
105
|
+
readonly gap: boolean;
|
|
106
|
+
readonly trackedSourceCount: number;
|
|
107
|
+
readonly admittedTrackedCount: number;
|
|
108
|
+
/** Class ① — extractor-supported tracked files `include` does not admit. */
|
|
109
|
+
readonly includeGap: readonly string[];
|
|
110
|
+
readonly indexedFileCount: number;
|
|
111
|
+
/** Class ② — index rows whose path is gone from disk. */
|
|
112
|
+
readonly deadRows: readonly string[];
|
|
113
|
+
};
|
|
97
114
|
export type DistVersionComparison = {
|
|
98
115
|
dist: string | null;
|
|
99
116
|
source: string;
|
|
@@ -256,6 +273,14 @@ export type DoctorOptions = {
|
|
|
256
273
|
* and reported as a non-blocking warning.
|
|
257
274
|
*/
|
|
258
275
|
codegraphIntegrityProbe?: () => CodegraphExcludeIntegrityProbe | null;
|
|
276
|
+
/**
|
|
277
|
+
* Optional override for the `capability:codegraph-index-integrity`
|
|
278
|
+
* check. Returns the report, or `null` when codegraph is not
|
|
279
|
+
* initialized in the inspected root (no index to inspect). When
|
|
280
|
+
* omitted, the check inspects `process.cwd()`. Throwing is allowed
|
|
281
|
+
* and reported as a non-blocking warning.
|
|
282
|
+
*/
|
|
283
|
+
codegraphIndexIntegrityProbe?: () => CodegraphIndexIntegrityProbe | null;
|
|
259
284
|
skillPresenceProbe?: () => DoctorSkillPresence | null;
|
|
260
285
|
skillPresenceFreshnessThresholdMs?: number;
|
|
261
286
|
statusLineInstalledProbe?: () => boolean;
|
|
@@ -591,7 +591,6 @@ export const CLAUDE_CODE_ADAPTER = {
|
|
|
591
591
|
const root = scope === 'global' ? homedir() : resolve(projectRoot ?? homedir());
|
|
592
592
|
return join(root, '.claude', 'settings.json');
|
|
593
593
|
},
|
|
594
|
-
supportsScope: () => true,
|
|
595
594
|
},
|
|
596
595
|
envVar: 'CLAUDE_PROJECT_DIR',
|
|
597
596
|
hookEvent: 'PreToolUse',
|
|
@@ -54,8 +54,7 @@ export const CODEX_ADAPTER = {
|
|
|
54
54
|
resolveSettingsFile: (scope, projectRoot) => {
|
|
55
55
|
const root = scope === 'global' ? homedir() : resolve(projectRoot ?? homedir());
|
|
56
56
|
return join(root, '.codex', 'settings.json');
|
|
57
|
-
}
|
|
58
|
-
supportsScope: (scope) => scope === 'project' || scope === 'global'
|
|
57
|
+
}
|
|
59
58
|
},
|
|
60
59
|
envVar: 'CODEX_PROJECT_DIR', // UNVERIFIED — see slice #13 PRD R-3; fallback path still works
|
|
61
60
|
hookEvent: 'pre_tool_use', // UNVERIFIED — Codex lowercase snake_case pattern; re-verify against Codex docs
|
|
@@ -44,8 +44,7 @@ export const CURSOR_ADAPTER = {
|
|
|
44
44
|
resolveSettingsFile: (scope, projectRoot) => {
|
|
45
45
|
const root = scope === 'global' ? homedir() : resolve(projectRoot ?? homedir());
|
|
46
46
|
return join(root, '.cursor', 'settings.json');
|
|
47
|
-
}
|
|
48
|
-
supportsScope: (scope) => scope === 'project' || scope === 'global'
|
|
47
|
+
}
|
|
49
48
|
},
|
|
50
49
|
envVar: 'CURSOR_PROJECT_DIR', // UNVERIFIED — see slice #12 PRD R-2; fallback path still works
|
|
51
50
|
hookEvent: 'beforeShellExecution', // UNVERIFIED — see slice #12 PRD R-1; re-verify against Cursor's published hook schema
|
|
@@ -29,8 +29,7 @@ export const HERMES_ADAPTER = {
|
|
|
29
29
|
resolveSettingsFile: (scope, projectRoot) => {
|
|
30
30
|
const root = scope === 'global' ? homedir() : resolve(projectRoot ?? homedir());
|
|
31
31
|
return join(root, '.hermes', 'settings.json');
|
|
32
|
-
}
|
|
33
|
-
supportsScope: (scope) => scope === 'project' || scope === 'global'
|
|
32
|
+
}
|
|
34
33
|
},
|
|
35
34
|
envVar: 'HERMES_PROJECT_DIR', // UNVERIFIED
|
|
36
35
|
hookEvent: 'PreToolUse', // UNVERIFIED
|
|
@@ -22,8 +22,7 @@ export const OPENCLAW_ADAPTER = {
|
|
|
22
22
|
resolveSettingsFile: (scope, projectRoot) => {
|
|
23
23
|
const root = scope === 'global' ? homedir() : resolve(projectRoot ?? homedir());
|
|
24
24
|
return join(root, '.openclaw', 'settings.json');
|
|
25
|
-
}
|
|
26
|
-
supportsScope: (scope) => scope === 'project' || scope === 'global'
|
|
25
|
+
}
|
|
27
26
|
},
|
|
28
27
|
envVar: 'OPENCLAW_PROJECT_DIR', // UNVERIFIED
|
|
29
28
|
hookEvent: 'PreToolUse', // UNVERIFIED
|
|
@@ -33,8 +33,7 @@ export const QODER_ADAPTER = {
|
|
|
33
33
|
resolveSettingsFile: (scope, projectRoot) => {
|
|
34
34
|
const root = scope === 'global' ? homedir() : resolve(projectRoot ?? homedir());
|
|
35
35
|
return join(root, '.qoder', 'settings.json');
|
|
36
|
-
}
|
|
37
|
-
supportsScope: (scope) => scope === 'project' || scope === 'global'
|
|
36
|
+
}
|
|
38
37
|
},
|
|
39
38
|
envVar: 'QODER_PROJECT_DIR', // UNVERIFIED
|
|
40
39
|
hookEvent: 'PreToolUse', // UNVERIFIED
|
|
@@ -24,8 +24,7 @@ export const TONGYI_LINGMA_ADAPTER = {
|
|
|
24
24
|
resolveSettingsFile: (scope, projectRoot) => {
|
|
25
25
|
const root = scope === 'global' ? homedir() : resolve(projectRoot ?? homedir());
|
|
26
26
|
return join(root, '.lingma', 'settings.json');
|
|
27
|
-
}
|
|
28
|
-
supportsScope: (scope) => scope === 'project' || scope === 'global'
|
|
27
|
+
}
|
|
29
28
|
},
|
|
30
29
|
envVar: 'TONGYI_LINGMA_PROJECT_DIR', // UNVERIFIED
|
|
31
30
|
hookEvent: 'PreToolUse', // UNVERIFIED
|
|
@@ -50,8 +50,7 @@ export const TRAE_ADAPTER = {
|
|
|
50
50
|
resolveSettingsFile: (scope, projectRoot) => {
|
|
51
51
|
const root = scope === 'global' ? homedir() : resolve(projectRoot ?? homedir());
|
|
52
52
|
return join(root, '.trae', 'settings.json');
|
|
53
|
-
}
|
|
54
|
-
supportsScope: (scope) => scope === 'project' || scope === 'global'
|
|
53
|
+
}
|
|
55
54
|
},
|
|
56
55
|
envVar: 'TRAE_PROJECT_DIR',
|
|
57
56
|
hookEvent: 'beforeToolCall', // VERIFIED against Trae 1.x fixture — slice 009-009-2026-06-07-trae-dogfood (2026-06-07); fixture at tests/fixtures/trae/trae-1x-payload.json
|
|
@@ -159,7 +159,6 @@ export const ZCODE_ADAPTER = {
|
|
|
159
159
|
const root = scope === 'global' ? homedir() : resolve(projectRoot ?? homedir());
|
|
160
160
|
return join(root, '.zcode', 'settings.json');
|
|
161
161
|
},
|
|
162
|
-
supportsScope: (scope) => scope === 'project' || scope === 'global',
|
|
163
162
|
},
|
|
164
163
|
// UNVERIFIED — z-code 桌面应用未公开 `ZCODE_PROJECT_DIR` env var,这里
|
|
165
164
|
// 用占位符,RD 阶段假设 z-code 借用了 Anthropic-compatible 协议并可能
|
|
@@ -41,8 +41,6 @@ export interface IdeSettingsLocation {
|
|
|
41
41
|
readonly localSettingsFileName?: string;
|
|
42
42
|
/** 解析出 settings.json 绝对路径 */
|
|
43
43
|
resolveSettingsFile(scope: 'project' | 'global', projectRoot: string | undefined): string;
|
|
44
|
-
/** 该 IDE 是否支持此 scope(用于清晰报错) */
|
|
45
|
-
supportsScope(scope: 'project' | 'global'): boolean;
|
|
46
44
|
}
|
|
47
45
|
/**
|
|
48
46
|
* Slim IDE adapter 描述。每 IDE 一个静态常量(无需 DI)。
|