peaks-loop 4.0.32 → 4.0.34
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 +39 -0
- package/README-en.md +3 -4
- package/README.md +20 -28
- package/dist/cli/commands/_register.js +4 -3
- package/dist/cli/commands/audit-commands.js +12 -39
- package/dist/cli/commands/capability-commands.d.ts +6 -0
- package/dist/cli/commands/capability-commands.js +20 -2
- package/dist/cli/commands/code-commands.js +2 -0
- package/dist/cli/commands/code-mode-gate-commands.js +3 -3
- package/dist/cli/commands/code-mode-status-command.d.ts +17 -0
- package/dist/cli/commands/code-mode-status-command.js +51 -0
- package/dist/cli/commands/code-run-command.js +8 -1
- package/dist/cli/commands/code-runtime-commands.js +13 -5
- package/dist/cli/commands/core/skill-command.js +1 -1
- package/dist/cli/commands/ecc-commands.js +3 -2
- package/dist/cli/commands/project-commands.js +1 -1
- package/dist/cli/commands/request-commands.js +3 -7
- package/dist/cli/commands/session-24h-mode.js +9 -1
- package/dist/cli/commands/shadcn-commands.d.ts +32 -0
- package/dist/cli/commands/shadcn-commands.js +120 -0
- package/dist/cli/commands/slice-commands.js +1 -4
- package/dist/services/24h-mode/auto-engage.d.ts +39 -0
- package/dist/services/24h-mode/auto-engage.js +46 -0
- package/dist/services/24h-mode/decider.d.ts +11 -5
- package/dist/services/24h-mode/decider.js +13 -13
- package/dist/services/audit/enforcers/active-skill-resolver.d.ts +3 -1
- package/dist/services/audit/enforcers/active-skill-resolver.js +3 -5
- package/dist/services/audit/static-service.d.ts +1 -1
- package/dist/services/audit/static-service.js +1 -1
- package/dist/services/code/auto-compact-lifecycle.d.ts +1 -1
- package/dist/services/code/auto-compact-lifecycle.js +1 -1
- package/dist/services/code/auto-compact-modes.d.ts +1 -1
- package/dist/services/code/auto-compact-modes.js +1 -1
- package/dist/services/code/auto-compact-orchestrator.js +18 -22
- package/dist/services/code/mode-gate.d.ts +6 -2
- package/dist/services/code/mode-gate.js +9 -5
- package/dist/services/code/orchestrator-can-do.js +2 -2
- package/dist/services/code-review/ecc-bridge.d.ts +94 -15
- package/dist/services/code-review/ecc-bridge.js +133 -13
- package/dist/services/config/config-service.d.ts +17 -0
- package/dist/services/config/config-service.js +34 -0
- package/dist/services/context/auto-compact-dispatcher.d.ts +2 -2
- package/dist/services/context/auto-compact-dispatcher.js +4 -4
- package/dist/services/context/auto-compact-reader.js +8 -1
- package/dist/services/context/auto-compact-types.d.ts +13 -1
- package/dist/services/context/build-dispatch-system-prompt.js +2 -2
- package/dist/services/context/context-schema.d.ts +1 -1
- package/dist/services/dashboard/project-dashboard-service.d.ts +0 -7
- package/dist/services/dashboard/project-dashboard-service.js +1 -9
- package/dist/services/hooks/auto-compact-hook-install.d.ts +2 -2
- package/dist/services/hooks/auto-compact-hook-install.js +2 -2
- package/dist/services/ide/adapters/claude-code-adapter.d.ts +51 -0
- package/dist/services/ide/adapters/claude-code-adapter.js +84 -14
- package/dist/services/ide/ide-types.d.ts +10 -1
- package/dist/services/mode/mode-enforcement.d.ts +4 -1
- package/dist/services/mode/mode-enforcement.js +26 -28
- package/dist/services/mode/mode-status-service.d.ts +81 -0
- package/dist/services/mode/mode-status-service.js +108 -0
- package/dist/services/preferences/preferences-types.d.ts +16 -7
- package/dist/services/recommendations/capability-seed-items.js +0 -1
- package/dist/services/recommendations/installed-capability-detector.d.ts +33 -0
- package/dist/services/recommendations/installed-capability-detector.js +76 -0
- package/dist/services/scan/orphan-service.js +1 -1
- package/dist/services/skills/presence-lease-service.d.ts +21 -0
- package/dist/services/skills/presence-lease-service.js +26 -0
- package/dist/services/skills/skill-presence-service.d.ts +10 -1
- package/dist/services/skills/skill-presence-service.js +32 -4
- package/dist/services/skills/skill-statusline-service.js +6 -3
- package/dist/services/slice/multi-pass-orchestrator.js +0 -13
- package/dist/services/slice/slice-decompose-import-edges.d.ts +2 -2
- package/dist/services/slice/slice-decompose-import-edges.js +1 -29
- package/dist/services/slice/slice-decompose-runners.d.ts +2 -4
- package/dist/services/slice/slice-decompose-runners.js +1 -23
- package/dist/services/slice/slice-decompose-service.d.ts +3 -4
- package/dist/services/slice/slice-decompose-service.js +10 -29
- package/dist/services/slice/slice-decompose-types.d.ts +6 -47
- package/dist/services/slice/slice-decompose-types.js +3 -2
- package/dist/services/slice/slice-topology-types.d.ts +2 -3
- package/package.json +5 -5
- package/schemas/decomposition-v1.json +0 -12
- package/schemas/decomposition-v2.json +1 -15
- package/skills/bee/peaks-prd/SKILL.md +0 -1
- package/skills/bee/peaks-rd/SKILL.md +1 -1
- package/skills/bee/peaks-rd/references/external-references.md +1 -3
- package/skills/bee/peaks-rd/references/parallel-review-fanout.md +7 -2
- package/skills/bee/peaks-rd/references/rd-fanout-contracts.md +22 -8
- package/skills/bee/peaks-rd/references/rd-runbook.md +0 -2
- package/skills/bee/peaks-txt/SKILL.md +0 -12
- package/skills/peaks-code/SKILL.md +9 -9
- package/skills/peaks-code/references/mode-selection.md +7 -3
- package/skills/peaks-code/references/periodic-checkpoint.md +4 -4
- package/skills/peaks-code/references/runbook.md +10 -5
- package/skills/peaks-code/references/session-overload-signal-index.md +2 -2
- package/skills/peaks-code/references/standards-preflight.md +1 -1
- package/skills/peaks-code/references/startup-sequence.md +1 -1
- package/skills/peaks-code/references/step-0-8-gate.md +1 -1
- package/skills/peaks-code/references/swarm-dispatch-contract.md +2 -2
- package/skills/peaks-code/references/workflow-gates-and-types.md +1 -1
- package/skills/peaks-doctor/SKILL.md +1 -1
- package/skills/peaks-slice-decompose/SKILL.md +0 -1
- package/skills/peaks-slice-decompose/references/v2-schema.md +1 -12
- package/dist/cli/commands/understand-commands.d.ts +0 -3
- package/dist/cli/commands/understand-commands.js +0 -148
- package/dist/services/understand/hybrid-types.d.ts +0 -32
- package/dist/services/understand/hybrid-types.js +0 -1
- package/dist/services/understand/understand-hybrid-service.d.ts +0 -10
- package/dist/services/understand/understand-hybrid-service.js +0 -100
- package/dist/services/understand/understand-scan-service.d.ts +0 -28
- package/dist/services/understand/understand-scan-service.js +0 -170
- package/dist/services/understand/understand-types.d.ts +0 -50
- package/dist/services/understand/understand-types.js +0 -1
|
@@ -185,11 +185,11 @@ export function buildOrchestratorCanDoResult(input, signals) {
|
|
|
185
185
|
// Q4 — context ratio gate. ≥0.95 → red-line; ≥0.85 → pre-compact.
|
|
186
186
|
if (signals.q4ContextRatio >= ORCHESTRATOR_REDLINE_RATIO) {
|
|
187
187
|
blockers.push(`context red-line (ratio=${signals.q4ContextRatio.toFixed(2)} ≥ ${ORCHESTRATOR_REDLINE_RATIO}); auto-compact now or push to next session`);
|
|
188
|
-
suggestions.push('peaks
|
|
188
|
+
suggestions.push('peaks code auto-compact');
|
|
189
189
|
}
|
|
190
190
|
else if (signals.q4ContextRatio >= ORCHESTRATOR_PRECOMPACT_RATIO) {
|
|
191
191
|
blockers.push(`context near limit (ratio=${signals.q4ContextRatio.toFixed(2)} ≥ ${ORCHESTRATOR_PRECOMPACT_RATIO}); auto-compact or push to next session`);
|
|
192
|
-
suggestions.push('peaks
|
|
192
|
+
suggestions.push('peaks code auto-compact');
|
|
193
193
|
}
|
|
194
194
|
// Q3 — user-decision keywords → soft warning, NOT a blocker. The
|
|
195
195
|
// LLM should AskUserQuestion, which is cheap.
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
* === Source: peaks-rd/references/parallel-review-fanout.md ===
|
|
32
32
|
*
|
|
33
33
|
* Sub-agent 1 contract (Tier 7 v2.11.0): the parent RD loop calls
|
|
34
|
-
* `Agent({ subagent_type: '
|
|
34
|
+
* `Agent({ subagent_type: 'ecc:code-reviewer', ... })`
|
|
35
35
|
* with the diff + handoff in scope, receives the structured envelope,
|
|
36
36
|
* then runs `adaptEccEnvelopeToRdCodeReview(env, { rid, generatedAt })`
|
|
37
37
|
* and writes the resulting body to
|
|
@@ -51,18 +51,43 @@ export interface EccEnvelope {
|
|
|
51
51
|
readonly gateAction: EccGateAction;
|
|
52
52
|
}
|
|
53
53
|
/**
|
|
54
|
-
*
|
|
54
|
+
* The real upstream ECC agent name for the code-review role:
|
|
55
|
+
* `~/.peaks/agents/ecc/code-reviewer.md`. Upstream ships `<lang>-reviewer`
|
|
56
|
+
* agents and has NO `code-review.md`, so this is the default the
|
|
57
|
+
* `ready-via-cache` nextActions name when the caller does not pass the
|
|
58
|
+
* output of `resolveMaterializedAgentName(['code-reviewer', 'code-review'])`.
|
|
59
|
+
*/
|
|
60
|
+
export declare const DEFAULT_CACHE_ECC_AGENT_NAME = "code-reviewer";
|
|
61
|
+
/**
|
|
62
|
+
* The native (plugin) ECC agent id dispatched through the Agent tool.
|
|
63
|
+
* Verified upstream: the plugin is named `ecc` (`.claude-plugin/plugin.json`,
|
|
64
|
+
* `marketplace.json`) and the agent's frontmatter `name` is `code-reviewer`
|
|
65
|
+
* (`~/.peaks/agents/ecc/code-reviewer.md`), so the composed id is
|
|
66
|
+
* `ecc:code-reviewer`. The previous id composed the OLD repo name
|
|
67
|
+
* (`everything-claude-code`) with a non-existent `code-review` agent, so it
|
|
68
|
+
* matched no registry entry and the native path silently fell through to
|
|
69
|
+
* inline review.
|
|
70
|
+
*/
|
|
71
|
+
export declare const DEFAULT_NATIVE_ECC_AGENT_ID = "ecc:code-reviewer";
|
|
72
|
+
/**
|
|
73
|
+
* 6-state ECC detection result:
|
|
55
74
|
* - `ready` — ECC plugin is installed and reachable
|
|
56
|
-
* - `
|
|
57
|
-
*
|
|
75
|
+
* - `ready-via-cache` — plugin/agent absent, but the materialized ECC
|
|
76
|
+
* review agent (real name `code-reviewer`, NOT
|
|
77
|
+
* `code-review`) exists under `~/.peaks/agents/ecc/`;
|
|
78
|
+
* dispatch a GENERIC sub-agent with that body
|
|
79
|
+
* - `plugin-missing` — `everything-claude-code` not in skill list and no materialized cache
|
|
80
|
+
* - `agent-missing` — plugin present but `code-review` agent absent and no materialized cache
|
|
58
81
|
* - `dispatch-failed` — Agent tool call threw before returning envelope
|
|
59
82
|
* - `envelope-malformed` — returned value failed `isEccEnvelope` validation
|
|
60
83
|
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
* the
|
|
84
|
+
* Fallback order (RD fan-out, 2026-09-09-ecc-dynamic): native plugin →
|
|
85
|
+
* cache-backed generic agent → inline. The caller (peaks-rd's sub-agent 1
|
|
86
|
+
* contract) inspects `state` and either proceeds with the envelope or records
|
|
87
|
+
* a degradation note in the request artifact body
|
|
88
|
+
* (`code-review-ecc-degraded-to-inline`).
|
|
64
89
|
*/
|
|
65
|
-
export type EccDetectState = 'ready' | 'plugin-missing' | 'agent-missing' | 'dispatch-failed' | 'envelope-malformed';
|
|
90
|
+
export type EccDetectState = 'ready' | 'ready-via-cache' | 'plugin-missing' | 'agent-missing' | 'dispatch-failed' | 'envelope-malformed';
|
|
66
91
|
export interface EccDetectResult {
|
|
67
92
|
readonly state: EccDetectState;
|
|
68
93
|
readonly pluginInstalled: boolean;
|
|
@@ -105,39 +130,93 @@ export declare function adaptEccEnvelopeToRdCodeReview(env: EccEnvelope, opts: {
|
|
|
105
130
|
generatedAt: string;
|
|
106
131
|
}): RdCodeReviewDoc;
|
|
107
132
|
/**
|
|
108
|
-
*
|
|
133
|
+
* 6-state detector — mirrors `detectOcr`'s shape (state enum + warnings
|
|
109
134
|
* + nextActions). The caller passes in the result of its own probe:
|
|
110
135
|
*
|
|
111
136
|
* - `pluginInstalled`: did the skill list scan find `everything-claude-code`?
|
|
112
137
|
* - `agentAvailable`: did the Agent tool say `code-review` is registered?
|
|
138
|
+
* - `cacheAgentAvailable`: does the resolved materialized agent exist
|
|
139
|
+
* (`~/.peaks/agents/ecc/<cacheAgentName>.md`, default `code-reviewer`)?
|
|
113
140
|
* - `dispatchError`: optional — the Agent tool threw before returning.
|
|
114
141
|
* - `envelope`: optional — what came back (if anything).
|
|
115
142
|
*
|
|
116
|
-
* The detector never blocks: when state
|
|
117
|
-
*
|
|
118
|
-
*
|
|
143
|
+
* The detector never blocks: when the state is not dispatchable
|
|
144
|
+
* (`ready` / `ready-via-cache`), the parent RD loop records a
|
|
145
|
+
* `code-review-ecc-degraded-to-inline` note and falls back to inline
|
|
146
|
+
* review. This matches `detectOcr`'s soft-fail policy.
|
|
147
|
+
*
|
|
148
|
+
* Backward compat: the native id is `DEFAULT_NATIVE_ECC_AGENT_ID`
|
|
149
|
+
* (`ecc:code-reviewer` — plugin `ecc`, agent `code-reviewer`). A registry
|
|
150
|
+
* that still exposes the OLD `everything-claude-code` plugin id will not
|
|
151
|
+
* match it, so the operator should pin the id explicitly. peaks-loop
|
|
152
|
+
* cannot enumerate the user's plugin registry: detection stays
|
|
153
|
+
* caller-supplied (`pluginInstalled` / `agentAvailable`), never probed here.
|
|
119
154
|
*/
|
|
120
155
|
export declare function detectEcc(input: {
|
|
121
156
|
readonly pluginInstalled: boolean;
|
|
122
157
|
readonly agentAvailable: boolean;
|
|
158
|
+
/**
|
|
159
|
+
* Did the caller find the materialized review agent (written by
|
|
160
|
+
* `peaks ecc install` / `materializeEccAgents`) under `~/.peaks/agents/ecc/`?
|
|
161
|
+
* When true and the native plugin path is unavailable, `state` becomes
|
|
162
|
+
* `ready-via-cache` so the RD loop can dispatch a generic sub-agent with
|
|
163
|
+
* the materialized body.
|
|
164
|
+
*/
|
|
165
|
+
readonly cacheAgentAvailable?: boolean;
|
|
166
|
+
/**
|
|
167
|
+
* Resolved materialized agent name — pass
|
|
168
|
+
* `resolveMaterializedAgentName(['code-reviewer', 'code-review'])` from
|
|
169
|
+
* `peaks-loop-mut`. Defaults to `code-reviewer` (the real upstream name);
|
|
170
|
+
* upstream has no `code-review.md`.
|
|
171
|
+
*/
|
|
172
|
+
readonly cacheAgentName?: string;
|
|
123
173
|
readonly dispatchError?: unknown;
|
|
124
174
|
readonly envelope?: unknown;
|
|
125
175
|
}): EccDetectResult;
|
|
126
176
|
/**
|
|
127
177
|
* Convenience: run `detectEcc` and `adaptEccEnvelopeToRdCodeReview`
|
|
128
178
|
* in one call. The parent RD loop calls this after the Agent tool
|
|
129
|
-
* returns. When `detectEcc` returns
|
|
130
|
-
*
|
|
131
|
-
*
|
|
179
|
+
* returns. When `detectEcc` returns a non-dispatchable state
|
|
180
|
+
* (`plugin-missing` / `agent-missing` / `dispatch-failed` /
|
|
181
|
+
* `envelope-malformed`), the caller should NOT call
|
|
182
|
+
* `adaptEccEnvelopeToRdCodeReview` — fall back to inline review instead.
|
|
183
|
+
*
|
|
184
|
+
* Both `ready` (native plugin) and `ready-via-cache` (materialized generic
|
|
185
|
+
* agent) adapt the envelope through the SAME bridge.
|
|
132
186
|
*/
|
|
133
187
|
export declare function runEccCodeReview(input: {
|
|
134
188
|
readonly rid: string;
|
|
135
189
|
readonly generatedAt: string;
|
|
136
190
|
readonly pluginInstalled: boolean;
|
|
137
191
|
readonly agentAvailable: boolean;
|
|
192
|
+
readonly cacheAgentAvailable?: boolean;
|
|
193
|
+
/** Resolved materialized agent name (see `detectEcc`); defaults to `code-reviewer`. */
|
|
194
|
+
readonly cacheAgentName?: string;
|
|
138
195
|
readonly dispatchError?: unknown;
|
|
139
196
|
readonly envelope?: unknown;
|
|
140
197
|
}): {
|
|
141
198
|
detect: EccDetectResult;
|
|
142
199
|
doc: RdCodeReviewDoc | null;
|
|
143
200
|
};
|
|
201
|
+
/**
|
|
202
|
+
* The exact JSON shape the generic (cache-backed) sub-agent MUST return.
|
|
203
|
+
* Kept as a const so the RD reference docs and the prompt builder cannot
|
|
204
|
+
* drift: `isEccEnvelope` is the authoritative validator.
|
|
205
|
+
*/
|
|
206
|
+
export declare const ECC_OUTPUT_CONTRACT: string;
|
|
207
|
+
/**
|
|
208
|
+
* Compose the plugin-free dispatch prompt for sub-agent 1.
|
|
209
|
+
*
|
|
210
|
+
* `instructions` is the body of the materialized review agent
|
|
211
|
+
* (`~/.peaks/agents/ecc/code-reviewer.md` — resolve the real name with
|
|
212
|
+
* `resolveMaterializedAgentName`, never hardcode `code-review.md`);
|
|
213
|
+
* `diff` is the slice diff. The
|
|
214
|
+
* composed prompt is handed to a GENERIC sub-agent (no ECC plugin needed)
|
|
215
|
+
* and its reply is validated with `isEccEnvelope`, then rendered by
|
|
216
|
+
* `adaptEccEnvelopeToRdCodeReview` — the same bridge the native path uses.
|
|
217
|
+
*/
|
|
218
|
+
export declare function buildCacheBackedEccPrompt(input: {
|
|
219
|
+
readonly rid: string;
|
|
220
|
+
readonly instructions: string;
|
|
221
|
+
readonly diff: string;
|
|
222
|
+
}): string;
|
|
@@ -1,3 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The real upstream ECC agent name for the code-review role:
|
|
3
|
+
* `~/.peaks/agents/ecc/code-reviewer.md`. Upstream ships `<lang>-reviewer`
|
|
4
|
+
* agents and has NO `code-review.md`, so this is the default the
|
|
5
|
+
* `ready-via-cache` nextActions name when the caller does not pass the
|
|
6
|
+
* output of `resolveMaterializedAgentName(['code-reviewer', 'code-review'])`.
|
|
7
|
+
*/
|
|
8
|
+
export const DEFAULT_CACHE_ECC_AGENT_NAME = 'code-reviewer';
|
|
9
|
+
/**
|
|
10
|
+
* The native (plugin) ECC agent id dispatched through the Agent tool.
|
|
11
|
+
* Verified upstream: the plugin is named `ecc` (`.claude-plugin/plugin.json`,
|
|
12
|
+
* `marketplace.json`) and the agent's frontmatter `name` is `code-reviewer`
|
|
13
|
+
* (`~/.peaks/agents/ecc/code-reviewer.md`), so the composed id is
|
|
14
|
+
* `ecc:code-reviewer`. The previous id composed the OLD repo name
|
|
15
|
+
* (`everything-claude-code`) with a non-existent `code-review` agent, so it
|
|
16
|
+
* matched no registry entry and the native path silently fell through to
|
|
17
|
+
* inline review.
|
|
18
|
+
*/
|
|
19
|
+
export const DEFAULT_NATIVE_ECC_AGENT_ID = 'ecc:code-reviewer';
|
|
20
|
+
/** Materialized path hint for the cache-backed agent, e.g. `~/.peaks/agents/ecc/code-reviewer.md`. */
|
|
21
|
+
function materializedAgentPath(name) {
|
|
22
|
+
const resolved = name !== undefined && name.length > 0 ? name : DEFAULT_CACHE_ECC_AGENT_NAME;
|
|
23
|
+
return `~/.peaks/agents/ecc/${resolved}.md`;
|
|
24
|
+
}
|
|
1
25
|
/**
|
|
2
26
|
* Validate a raw value as an EccEnvelope. Accepts the strict shape
|
|
3
27
|
* only — extra fields are tolerated (forward-compat for ECC adding
|
|
@@ -82,7 +106,7 @@ export function adaptEccEnvelopeToRdCodeReview(env, opts) {
|
|
|
82
106
|
`## Summary`,
|
|
83
107
|
'',
|
|
84
108
|
`- generatedAt: ${opts.generatedAt}`,
|
|
85
|
-
`- source:
|
|
109
|
+
`- source: ${DEFAULT_NATIVE_ECC_AGENT_ID} (Tier 7 bridge)`,
|
|
86
110
|
`- gateAction: ${env.gateAction}`,
|
|
87
111
|
`- passed: ${env.passed}`,
|
|
88
112
|
`- violations: ${env.violations.length}`,
|
|
@@ -146,43 +170,87 @@ function renderFindings(violations) {
|
|
|
146
170
|
return ['## Findings', '', ...bullets, ''].join('\n');
|
|
147
171
|
}
|
|
148
172
|
/**
|
|
149
|
-
*
|
|
173
|
+
* 6-state detector — mirrors `detectOcr`'s shape (state enum + warnings
|
|
150
174
|
* + nextActions). The caller passes in the result of its own probe:
|
|
151
175
|
*
|
|
152
176
|
* - `pluginInstalled`: did the skill list scan find `everything-claude-code`?
|
|
153
177
|
* - `agentAvailable`: did the Agent tool say `code-review` is registered?
|
|
178
|
+
* - `cacheAgentAvailable`: does the resolved materialized agent exist
|
|
179
|
+
* (`~/.peaks/agents/ecc/<cacheAgentName>.md`, default `code-reviewer`)?
|
|
154
180
|
* - `dispatchError`: optional — the Agent tool threw before returning.
|
|
155
181
|
* - `envelope`: optional — what came back (if anything).
|
|
156
182
|
*
|
|
157
|
-
* The detector never blocks: when state
|
|
158
|
-
*
|
|
159
|
-
*
|
|
183
|
+
* The detector never blocks: when the state is not dispatchable
|
|
184
|
+
* (`ready` / `ready-via-cache`), the parent RD loop records a
|
|
185
|
+
* `code-review-ecc-degraded-to-inline` note and falls back to inline
|
|
186
|
+
* review. This matches `detectOcr`'s soft-fail policy.
|
|
187
|
+
*
|
|
188
|
+
* Backward compat: the native id is `DEFAULT_NATIVE_ECC_AGENT_ID`
|
|
189
|
+
* (`ecc:code-reviewer` — plugin `ecc`, agent `code-reviewer`). A registry
|
|
190
|
+
* that still exposes the OLD `everything-claude-code` plugin id will not
|
|
191
|
+
* match it, so the operator should pin the id explicitly. peaks-loop
|
|
192
|
+
* cannot enumerate the user's plugin registry: detection stays
|
|
193
|
+
* caller-supplied (`pluginInstalled` / `agentAvailable`), never probed here.
|
|
160
194
|
*/
|
|
161
195
|
export function detectEcc(input) {
|
|
162
196
|
const warnings = [];
|
|
163
197
|
const nextActions = [];
|
|
198
|
+
const cacheAgentAvailable = input.cacheAgentAvailable === true;
|
|
199
|
+
const cacheAgentPath = materializedAgentPath(input.cacheAgentName);
|
|
164
200
|
if (!input.pluginInstalled) {
|
|
201
|
+
if (cacheAgentAvailable) {
|
|
202
|
+
return {
|
|
203
|
+
state: 'ready-via-cache',
|
|
204
|
+
pluginInstalled: false,
|
|
205
|
+
agentAvailable: false,
|
|
206
|
+
warnings: [
|
|
207
|
+
'ECC Claude Code plugin is not installed; using the cache-backed generic agent instead.'
|
|
208
|
+
],
|
|
209
|
+
nextActions: [
|
|
210
|
+
`Dispatch a generic sub-agent with the body of \`${cacheAgentPath}\` (see \`buildCacheBackedEccPrompt\`).`,
|
|
211
|
+
'Refresh the materialized copy with `peaks ecc install`.',
|
|
212
|
+
'Install the `ecc` plugin for the native path (optional; native plugin → cache-backed → inline).'
|
|
213
|
+
]
|
|
214
|
+
};
|
|
215
|
+
}
|
|
165
216
|
return {
|
|
166
217
|
state: 'plugin-missing',
|
|
167
218
|
pluginInstalled: false,
|
|
168
219
|
agentAvailable: false,
|
|
169
220
|
warnings,
|
|
170
221
|
nextActions: [
|
|
171
|
-
'Install the `
|
|
172
|
-
'
|
|
222
|
+
'Install the `ecc` plugin (Claude Code marketplace).',
|
|
223
|
+
'Or run `peaks ecc install` to populate the cache-backed generic agent path.',
|
|
224
|
+
'Until one of the two is available, peaks-rd falls back to inline code review (degradation note: code-review-ecc-degraded-to-inline).'
|
|
173
225
|
]
|
|
174
226
|
};
|
|
175
227
|
}
|
|
176
228
|
if (!input.agentAvailable) {
|
|
229
|
+
if (cacheAgentAvailable) {
|
|
230
|
+
return {
|
|
231
|
+
state: 'ready-via-cache',
|
|
232
|
+
pluginInstalled: true,
|
|
233
|
+
agentAvailable: false,
|
|
234
|
+
warnings: [
|
|
235
|
+
'`ecc` is installed but its `code-reviewer` agent is not registered; using the cache-backed generic agent instead.'
|
|
236
|
+
],
|
|
237
|
+
nextActions: [
|
|
238
|
+
`Dispatch a generic sub-agent with the body of \`${cacheAgentPath}\` (see \`buildCacheBackedEccPrompt\`).`,
|
|
239
|
+
'Verify the plugin is enabled in your Claude Code settings (MCP servers / agent registry) to restore the native path.'
|
|
240
|
+
]
|
|
241
|
+
};
|
|
242
|
+
}
|
|
177
243
|
return {
|
|
178
244
|
state: 'agent-missing',
|
|
179
245
|
pluginInstalled: true,
|
|
180
246
|
agentAvailable: false,
|
|
181
247
|
warnings: [
|
|
182
|
-
'`
|
|
248
|
+
'`ecc` is installed but its `code-reviewer` agent is not registered.'
|
|
183
249
|
],
|
|
184
250
|
nextActions: [
|
|
185
251
|
'Verify the plugin is enabled in your Claude Code settings (MCP servers / agent registry).',
|
|
252
|
+
`If your registry still exposes the old \`everything-claude-code\` plugin id, pin the native agent id explicitly (\`${DEFAULT_NATIVE_ECC_AGENT_ID}\`) instead of relying on detection.`,
|
|
253
|
+
'Or run `peaks ecc install` to populate the cache-backed generic agent path.',
|
|
186
254
|
'Until resolved, peaks-rd falls back to inline code review.'
|
|
187
255
|
]
|
|
188
256
|
};
|
|
@@ -226,17 +294,69 @@ export function detectEcc(input) {
|
|
|
226
294
|
/**
|
|
227
295
|
* Convenience: run `detectEcc` and `adaptEccEnvelopeToRdCodeReview`
|
|
228
296
|
* in one call. The parent RD loop calls this after the Agent tool
|
|
229
|
-
* returns. When `detectEcc` returns
|
|
230
|
-
*
|
|
231
|
-
*
|
|
297
|
+
* returns. When `detectEcc` returns a non-dispatchable state
|
|
298
|
+
* (`plugin-missing` / `agent-missing` / `dispatch-failed` /
|
|
299
|
+
* `envelope-malformed`), the caller should NOT call
|
|
300
|
+
* `adaptEccEnvelopeToRdCodeReview` — fall back to inline review instead.
|
|
301
|
+
*
|
|
302
|
+
* Both `ready` (native plugin) and `ready-via-cache` (materialized generic
|
|
303
|
+
* agent) adapt the envelope through the SAME bridge.
|
|
232
304
|
*/
|
|
233
305
|
export function runEccCodeReview(input) {
|
|
234
306
|
const detect = detectEcc(input);
|
|
235
|
-
|
|
307
|
+
const dispatchable = detect.state === 'ready' || detect.state === 'ready-via-cache';
|
|
308
|
+
if (!dispatchable || input.envelope === undefined) {
|
|
236
309
|
return { detect, doc: null };
|
|
237
310
|
}
|
|
238
|
-
//
|
|
311
|
+
// A dispatchable state implies input.envelope passed isEccEnvelope; the runtime
|
|
239
312
|
// type is therefore EccEnvelope, not `unknown`. Cast is justified by detect's contract.
|
|
240
313
|
const env = input.envelope;
|
|
241
314
|
return { detect, doc: adaptEccEnvelopeToRdCodeReview(env, { rid: input.rid, generatedAt: input.generatedAt }) };
|
|
242
315
|
}
|
|
316
|
+
/**
|
|
317
|
+
* The exact JSON shape the generic (cache-backed) sub-agent MUST return.
|
|
318
|
+
* Kept as a const so the RD reference docs and the prompt builder cannot
|
|
319
|
+
* drift: `isEccEnvelope` is the authoritative validator.
|
|
320
|
+
*/
|
|
321
|
+
export const ECC_OUTPUT_CONTRACT = [
|
|
322
|
+
'Return ONLY a single JSON object (no prose, no markdown fence) with this exact shape:',
|
|
323
|
+
'{',
|
|
324
|
+
' "passed": boolean,',
|
|
325
|
+
' "violations": [{ "kind": string, "line": number, "snippet": string, "hint": string }],',
|
|
326
|
+
' "gateAction": "pass" | "warn" | "block"',
|
|
327
|
+
'}',
|
|
328
|
+
'`kind` is one of: correctness, type-safety, error-handling, mutation, file-size, naming, dead-code, regression, contract-drift, other.',
|
|
329
|
+
'`gateAction: "block"` requires at least one violation; `pass` requires an empty violations array.'
|
|
330
|
+
].join('\n');
|
|
331
|
+
/**
|
|
332
|
+
* Compose the plugin-free dispatch prompt for sub-agent 1.
|
|
333
|
+
*
|
|
334
|
+
* `instructions` is the body of the materialized review agent
|
|
335
|
+
* (`~/.peaks/agents/ecc/code-reviewer.md` — resolve the real name with
|
|
336
|
+
* `resolveMaterializedAgentName`, never hardcode `code-review.md`);
|
|
337
|
+
* `diff` is the slice diff. The
|
|
338
|
+
* composed prompt is handed to a GENERIC sub-agent (no ECC plugin needed)
|
|
339
|
+
* and its reply is validated with `isEccEnvelope`, then rendered by
|
|
340
|
+
* `adaptEccEnvelopeToRdCodeReview` — the same bridge the native path uses.
|
|
341
|
+
*/
|
|
342
|
+
export function buildCacheBackedEccPrompt(input) {
|
|
343
|
+
return [
|
|
344
|
+
'# Code review (ECC cache-backed generic agent)',
|
|
345
|
+
'',
|
|
346
|
+
`Request: ${input.rid}`,
|
|
347
|
+
'',
|
|
348
|
+
`## Agent instructions (materialized from ${DEFAULT_NATIVE_ECC_AGENT_ID})`,
|
|
349
|
+
'',
|
|
350
|
+
input.instructions.trim(),
|
|
351
|
+
'',
|
|
352
|
+
'## Diff under review',
|
|
353
|
+
'',
|
|
354
|
+
'```diff',
|
|
355
|
+
input.diff.trim(),
|
|
356
|
+
'```',
|
|
357
|
+
'',
|
|
358
|
+
'## Required output',
|
|
359
|
+
'',
|
|
360
|
+
ECC_OUTPUT_CONTRACT
|
|
361
|
+
].join('\n');
|
|
362
|
+
}
|
|
@@ -15,6 +15,23 @@ export { resolveProjectRootForConfig, resolveCanonicalProjectRoot } from './conf
|
|
|
15
15
|
*/
|
|
16
16
|
export declare function loadGlobalConfig(): ConfigV2 | null;
|
|
17
17
|
export declare function isConfigLayer(value: string): value is ConfigLayer;
|
|
18
|
+
/**
|
|
19
|
+
* Machine-scoped context-window override key, the config twin of the
|
|
20
|
+
* `PEAKS_CONTEXT_WINDOW_TOKENS` env var (slice
|
|
21
|
+
* 2026-09-09-context-window-override). Written with
|
|
22
|
+
* `peaks config set --key context.windowTokens --value <positive-int>`
|
|
23
|
+
* (user layer) so the user pins it once instead of exporting an env var
|
|
24
|
+
* in every shell.
|
|
25
|
+
*/
|
|
26
|
+
export declare const CONTEXT_WINDOW_TOKENS_CONFIG_KEY = "context.windowTokens";
|
|
27
|
+
/**
|
|
28
|
+
* Read the raw `context.windowTokens` value from the merged config, project
|
|
29
|
+
* layer over user layer (most specific wins). Returns the RAW value —
|
|
30
|
+
* validation lives in the context-window resolver so exactly one warning is
|
|
31
|
+
* emitted per bad value. Returns `undefined` when absent or unreadable;
|
|
32
|
+
* never throws (a corrupt config must not crash a context probe).
|
|
33
|
+
*/
|
|
34
|
+
export declare function readContextWindowTokensOverride(projectRoot?: string | null): unknown;
|
|
18
35
|
export declare function isSensitiveConfigPath(path: string): boolean;
|
|
19
36
|
export declare function isLegacyConfigKey(path: string): boolean;
|
|
20
37
|
export declare function containsSensitiveConfigValue(value: unknown): boolean;
|
|
@@ -176,6 +176,40 @@ function removeProjectSensitiveConfig(config) {
|
|
|
176
176
|
export function isConfigLayer(value) {
|
|
177
177
|
return value === 'user' || value === 'project';
|
|
178
178
|
}
|
|
179
|
+
/**
|
|
180
|
+
* Machine-scoped context-window override key, the config twin of the
|
|
181
|
+
* `PEAKS_CONTEXT_WINDOW_TOKENS` env var (slice
|
|
182
|
+
* 2026-09-09-context-window-override). Written with
|
|
183
|
+
* `peaks config set --key context.windowTokens --value <positive-int>`
|
|
184
|
+
* (user layer) so the user pins it once instead of exporting an env var
|
|
185
|
+
* in every shell.
|
|
186
|
+
*/
|
|
187
|
+
export const CONTEXT_WINDOW_TOKENS_CONFIG_KEY = 'context.windowTokens';
|
|
188
|
+
/**
|
|
189
|
+
* Read the raw `context.windowTokens` value from the merged config, project
|
|
190
|
+
* layer over user layer (most specific wins). Returns the RAW value —
|
|
191
|
+
* validation lives in the context-window resolver so exactly one warning is
|
|
192
|
+
* emitted per bad value. Returns `undefined` when absent or unreadable;
|
|
193
|
+
* never throws (a corrupt config must not crash a context probe).
|
|
194
|
+
*/
|
|
195
|
+
export function readContextWindowTokensOverride(projectRoot) {
|
|
196
|
+
try {
|
|
197
|
+
const projectRaw = readProjectJsonFile(projectRoot ?? null);
|
|
198
|
+
if (isRecord(projectRaw)) {
|
|
199
|
+
const fromProject = getNestedValue(projectRaw, CONTEXT_WINDOW_TOKENS_CONFIG_KEY);
|
|
200
|
+
if (fromProject !== undefined)
|
|
201
|
+
return fromProject;
|
|
202
|
+
}
|
|
203
|
+
const userRaw = readUserJsonFile();
|
|
204
|
+
if (isRecord(userRaw)) {
|
|
205
|
+
return getNestedValue(userRaw, CONTEXT_WINDOW_TOKENS_CONFIG_KEY);
|
|
206
|
+
}
|
|
207
|
+
return undefined;
|
|
208
|
+
}
|
|
209
|
+
catch { // TODO(g2): legacy silent catch — never let config IO break a probe (grace: 1 minor release, v2.14.0)
|
|
210
|
+
return undefined;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
179
213
|
export function isSensitiveConfigPath(path) {
|
|
180
214
|
const normalized = path.toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
181
215
|
return normalized.includes('apikey') || normalized.includes('accesskey') || normalized.includes('privatekey') || normalized.includes('token') || normalized.includes('secret') || normalized.includes('password') || normalized.includes('bearer') || normalized.includes('credential') || normalized.includes('auth');
|
|
@@ -45,7 +45,7 @@ export interface DispatchIdeCompactInput {
|
|
|
45
45
|
* the compact should target. Default `'main'` — the orchestrator
|
|
46
46
|
* (peaks-code body) runs in the main-session Claude Code window and
|
|
47
47
|
* wants to compress *its* context, not a sub-agent's. Sub-agent
|
|
48
|
-
* shells that spawn their own `peaks
|
|
48
|
+
* shells that spawn their own `peaks code auto-compact` flow pass
|
|
49
49
|
* `'sub-agent'` to preserve the legacy shell-spawn behaviour.
|
|
50
50
|
*
|
|
51
51
|
* Behaviour matrix (claude-code MVP):
|
|
@@ -66,7 +66,7 @@ export interface DispatchIdeCompactInput {
|
|
|
66
66
|
* when the dispatch path completed without error — for
|
|
67
67
|
* `llm-self-compress` the LLM still has to do the actual summary,
|
|
68
68
|
* so the orchestrator MUST NOT treat `ok: true` as proof that the
|
|
69
|
-
* context actually shrunk; the next `peaks
|
|
69
|
+
* context actually shrunk; the next `peaks code auto-compact` probe
|
|
70
70
|
* confirms.
|
|
71
71
|
*/
|
|
72
72
|
export declare function dispatchIdeCompact(input: DispatchIdeCompactInput): Promise<CompactDispatchResult>;
|
|
@@ -7,7 +7,7 @@ import { getAdapter } from '../ide/ide-registry.js';
|
|
|
7
7
|
* when the dispatch path completed without error — for
|
|
8
8
|
* `llm-self-compress` the LLM still has to do the actual summary,
|
|
9
9
|
* so the orchestrator MUST NOT treat `ok: true` as proof that the
|
|
10
|
-
* context actually shrunk; the next `peaks
|
|
10
|
+
* context actually shrunk; the next `peaks code auto-compact` probe
|
|
11
11
|
* confirms.
|
|
12
12
|
*/
|
|
13
13
|
export async function dispatchIdeCompact(input) {
|
|
@@ -77,7 +77,7 @@ export async function dispatchIdeCompact(input) {
|
|
|
77
77
|
case 'ide-native':
|
|
78
78
|
// Slice 2026-07-02-auto-compact-zero-pause: write the auto-compact
|
|
79
79
|
// PreToolUse hook into `.claude/settings.local.json`. The hook
|
|
80
|
-
// command (`peaks
|
|
80
|
+
// command (`peaks code auto-compact`) reads
|
|
81
81
|
// `CLAUDE_CONTEXT_USAGE_PERCENT` on every subsequent Bash/Task
|
|
82
82
|
// tool call from the runner and, at ratio ≥ 0.95, in-band spawns
|
|
83
83
|
// `claude --compact` against the CURRENT runner (not a child
|
|
@@ -106,7 +106,7 @@ export async function dispatchIdeCompact(input) {
|
|
|
106
106
|
};
|
|
107
107
|
}
|
|
108
108
|
// Lazy install: we only get here when the caller explicitly
|
|
109
|
-
// invokes `peaks
|
|
109
|
+
// invokes `peaks code auto-compact`, so the user has
|
|
110
110
|
// already opted in. No zero-touch surprise on workspace init.
|
|
111
111
|
return await dispatchIdeNativeHook({
|
|
112
112
|
projectRoot: input.projectRoot,
|
|
@@ -144,7 +144,7 @@ export async function dispatchIdeCompact(input) {
|
|
|
144
144
|
* into `.claude/settings.local.json` (idempotent; the install
|
|
145
145
|
* service is a no-op if the hook is already present). On the next
|
|
146
146
|
* Bash/Task tool call from the runner, the hook fires
|
|
147
|
-
* `peaks
|
|
147
|
+
* `peaks code auto-compact` which in-band spawns
|
|
148
148
|
* `claude --compact` against the CURRENT runner session.
|
|
149
149
|
*
|
|
150
150
|
* Returns `ok: true, pathway: 'ide-native'` regardless of install
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { detectIdeFromEnv } from './ide-detect.js';
|
|
2
2
|
import { getAdapter } from '../ide/ide-registry.js';
|
|
3
|
+
import { readContextWindowTokensOverride } from '../config/config-service.js';
|
|
3
4
|
/**
|
|
4
5
|
* Read env-var-based context percentage. Returns `null` when the env
|
|
5
6
|
* is absent or unparseable. Adapter-driven: the caller passes the
|
|
@@ -74,11 +75,17 @@ export function readContextPercent(input) {
|
|
|
74
75
|
// Fallback: the adapter owns any vendor-specific statusline /
|
|
75
76
|
// transcript probe. When it returns a probe, honor it; otherwise
|
|
76
77
|
// fall through to conservative-fallback.
|
|
78
|
+
//
|
|
79
|
+
// Slice 2026-09-09-context-window-override: the generic reader also
|
|
80
|
+
// hands the adapter the raw `context.windowTokens` config override, so
|
|
81
|
+
// the adapter's window resolver can prefer an explicit user value over
|
|
82
|
+
// its model-name heuristics (the env override arrives via `env`).
|
|
77
83
|
const fallback = adapter.compact.readContextPercentFallback?.({
|
|
78
84
|
projectRoot: input.projectRoot,
|
|
79
85
|
sessionId: input.sessionId,
|
|
80
86
|
outerSessionId: input.outerSessionId,
|
|
81
|
-
env
|
|
87
|
+
env,
|
|
88
|
+
configWindowTokens: readContextWindowTokensOverride(input.projectRoot)
|
|
82
89
|
});
|
|
83
90
|
if (fallback)
|
|
84
91
|
return fallback;
|
|
@@ -45,7 +45,7 @@ export type CompactTrigger = {
|
|
|
45
45
|
}
|
|
46
46
|
/**
|
|
47
47
|
* Part 22: auto-fire zone (0.80 ≤ ratio < 0.85). peaks-loop
|
|
48
|
-
* preempts and runs `peaks
|
|
48
|
+
* preempts and runs `peaks code auto-compact` itself
|
|
49
49
|
* without LLM involvement. The LLM is not asked to "decide";
|
|
50
50
|
* the toolkit is applied synchronously.
|
|
51
51
|
*/
|
|
@@ -186,6 +186,18 @@ export interface ContextPercentProbe {
|
|
|
186
186
|
* percent sources.
|
|
187
187
|
*/
|
|
188
188
|
readonly capacityTokens?: number;
|
|
189
|
+
/**
|
|
190
|
+
* Which layer produced `capacityTokens` (token-based sources only):
|
|
191
|
+
* - `env-override` — `PEAKS_CONTEXT_WINDOW_TOKENS`
|
|
192
|
+
* - `config` — `context.windowTokens` (`peaks config set`)
|
|
193
|
+
* - `model-heuristic` — `[1M]` suffix / known-1M model allowlist
|
|
194
|
+
* - `default` — 200K safe default
|
|
195
|
+
* Undefined for byte / percent sources (`user-overridden`, `${ideId}-env`,
|
|
196
|
+
* `statusline-poll`), which have no token window. Slice
|
|
197
|
+
* 2026-09-09-context-window-override: lets a wrong window be diagnosed in
|
|
198
|
+
* one read instead of guessing which heuristic fired.
|
|
199
|
+
*/
|
|
200
|
+
readonly capacitySource?: string;
|
|
189
201
|
readonly ide: string;
|
|
190
202
|
readonly capturedAt: string;
|
|
191
203
|
}
|
|
@@ -191,9 +191,9 @@ function renderContextBlock(probe) {
|
|
|
191
191
|
const usedPct = (probe.ratio * 100).toFixed(1);
|
|
192
192
|
const freePct = ((1 - probe.ratio) * 100).toFixed(1);
|
|
193
193
|
const action = probe.ratio >= 0.95
|
|
194
|
-
? 'RED-LINE — call `peaks
|
|
194
|
+
? 'RED-LINE — call `peaks code auto-compact` immediately.'
|
|
195
195
|
: probe.ratio >= 0.85
|
|
196
|
-
? 'pre-compact zone — consider running `peaks
|
|
196
|
+
? 'pre-compact zone — consider running `peaks code auto-compact` proactively.'
|
|
197
197
|
: probe.ratio >= 0.5
|
|
198
198
|
? 'soft-warn zone — continue working; the next dispatch will re-check.'
|
|
199
199
|
: 'plenty of room — continue without compacting.';
|
|
@@ -12,12 +12,6 @@ export type ProjectDashboardOpenSpec = {
|
|
|
12
12
|
count: number;
|
|
13
13
|
changes: OpenSpecChangeSummary[];
|
|
14
14
|
};
|
|
15
|
-
export type ProjectDashboardUnderstand = {
|
|
16
|
-
exists: boolean;
|
|
17
|
-
graphExists: boolean;
|
|
18
|
-
graphPath: string;
|
|
19
|
-
parseError?: string;
|
|
20
|
-
};
|
|
21
15
|
export type ProjectDashboardDoctor = {
|
|
22
16
|
ok: boolean;
|
|
23
17
|
passed: number;
|
|
@@ -69,7 +63,6 @@ export type ProjectDashboard = {
|
|
|
69
63
|
okPolicy: DashboardOkPolicy;
|
|
70
64
|
requests: ProjectDashboardRequests;
|
|
71
65
|
openspec: ProjectDashboardOpenSpec;
|
|
72
|
-
understand: ProjectDashboardUnderstand;
|
|
73
66
|
doctor: ProjectDashboardDoctor;
|
|
74
67
|
runbookHealth: ProjectDashboardRunbookHealth;
|
|
75
68
|
capabilities: ProjectDashboardCapabilities;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { listRequestArtifacts } from '../artifacts/request-artifact-service.js';
|
|
2
2
|
import { scanOpenSpec } from '../openspec/openspec-scan-service.js';
|
|
3
|
-
import { scanUnderstandAnything } from '../understand/understand-scan-service.js';
|
|
4
3
|
import { seedCapabilityItems } from '../recommendations/capability-seed-items.js';
|
|
5
4
|
import { requiredSkillNames } from 'peaks-loop-shared/paths';
|
|
6
5
|
import { getSkillPresence } from '../skills/skill-presence-service.js';
|
|
@@ -107,10 +106,9 @@ export async function loadProjectDashboard(options) {
|
|
|
107
106
|
const clock = options.clock ?? defaultClock;
|
|
108
107
|
const sampleSize = options.sampleCapabilities ?? 8;
|
|
109
108
|
const okPolicy = options.okPolicy ?? 'workspace-only';
|
|
110
|
-
const [items, openspecReport,
|
|
109
|
+
const [items, openspecReport, doctorAndRunbook] = await Promise.all([
|
|
111
110
|
listRequestArtifacts({ projectRoot: options.projectRoot }),
|
|
112
111
|
scanOpenSpec({ openspecRoot: `${options.projectRoot}/openspec` }),
|
|
113
|
-
scanUnderstandAnything({ projectRoot: options.projectRoot }),
|
|
114
112
|
loadDoctorAndRunbookHealth(options.doctorReport, options.runbookHealth)
|
|
115
113
|
]);
|
|
116
114
|
const okVerdict = resolveDashboardOk({
|
|
@@ -133,12 +131,6 @@ export async function loadProjectDashboard(options) {
|
|
|
133
131
|
count: openspecReport.changes.length,
|
|
134
132
|
changes: openspecReport.changes
|
|
135
133
|
},
|
|
136
|
-
understand: {
|
|
137
|
-
exists: understandReport.exists,
|
|
138
|
-
graphExists: understandReport.graph.exists,
|
|
139
|
-
graphPath: understandReport.graph.path,
|
|
140
|
-
...(understandReport.graph.parseError !== undefined ? { parseError: understandReport.graph.parseError } : {})
|
|
141
|
-
},
|
|
142
134
|
doctor: doctorAndRunbook.doctor,
|
|
143
135
|
runbookHealth: doctorAndRunbook.runbookHealth,
|
|
144
136
|
capabilities: buildCapabilitiesSummary(sampleSize),
|