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
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
*/
|
|
38
38
|
export declare const AUTO_COMPACT_HOOK_MATCHER = "Bash|Task";
|
|
39
39
|
/**
|
|
40
|
-
* Stable command the hook fires. Wraps `peaks
|
|
40
|
+
* Stable command the hook fires. Wraps `peaks code auto-compact` so the
|
|
41
41
|
* heavy lifting (ratio probe + in-band `claude --compact` spawn)
|
|
42
42
|
* lives in the CLI surface, not inlined into the hook.
|
|
43
43
|
*
|
|
@@ -46,7 +46,7 @@ export declare const AUTO_COMPACT_HOOK_MATCHER = "Bash|Task";
|
|
|
46
46
|
* so the unqualified command works in the same shell the runner
|
|
47
47
|
* is using.
|
|
48
48
|
*/
|
|
49
|
-
export declare const AUTO_COMPACT_HOOK_COMMAND = "peaks
|
|
49
|
+
export declare const AUTO_COMPACT_HOOK_COMMAND = "peaks code auto-compact";
|
|
50
50
|
/**
|
|
51
51
|
* Magic comment marker that fences the auto-compatchook block.
|
|
52
52
|
* Both install (writes the marker) and remove (matches on it) use
|
|
@@ -39,7 +39,7 @@ import { dirname, join } from 'node:path';
|
|
|
39
39
|
*/
|
|
40
40
|
export const AUTO_COMPACT_HOOK_MATCHER = 'Bash|Task';
|
|
41
41
|
/**
|
|
42
|
-
* Stable command the hook fires. Wraps `peaks
|
|
42
|
+
* Stable command the hook fires. Wraps `peaks code auto-compact` so the
|
|
43
43
|
* heavy lifting (ratio probe + in-band `claude --compact` spawn)
|
|
44
44
|
* lives in the CLI surface, not inlined into the hook.
|
|
45
45
|
*
|
|
@@ -48,7 +48,7 @@ export const AUTO_COMPACT_HOOK_MATCHER = 'Bash|Task';
|
|
|
48
48
|
* so the unqualified command works in the same shell the runner
|
|
49
49
|
* is using.
|
|
50
50
|
*/
|
|
51
|
-
export const AUTO_COMPACT_HOOK_COMMAND = 'peaks
|
|
51
|
+
export const AUTO_COMPACT_HOOK_COMMAND = 'peaks code auto-compact';
|
|
52
52
|
/**
|
|
53
53
|
* Magic comment marker that fences the auto-compatchook block.
|
|
54
54
|
* Both install (writes the marker) and remove (matches on it) use
|
|
@@ -20,6 +20,57 @@ export declare function resolveClaudeModelFromEnv(env: NodeJS.ProcessEnv | undef
|
|
|
20
20
|
* Callers MAY additionally infer ≥1M from the observed token count: if
|
|
21
21
|
* `contextTokens > DEFAULT_CONTEXT_WINDOW_TOKENS`, the model cannot be a
|
|
22
22
|
* 200K model and must be ≥1M (see `readClaudeTranscriptEstimate`).
|
|
23
|
+
*
|
|
24
|
+
* This is the HEURISTIC layer only. Explicit user overrides sit ABOVE it —
|
|
25
|
+
* see `resolveContextWindow`, which is what the probe actually calls.
|
|
23
26
|
*/
|
|
24
27
|
export declare function modelContextWindowTokens(model: string): number;
|
|
28
|
+
/**
|
|
29
|
+
* Slice 2026-09-09-context-window-override: vendor-neutral escape hatch for
|
|
30
|
+
* the context-window size in tokens. Third-party / proxied models whose id
|
|
31
|
+
* carries no `[1M]` suffix (and is absent from the hardcoded allowlist) are
|
|
32
|
+
* otherwise stuck at the 200K default, which inflates `ratio` up to 5×.
|
|
33
|
+
* Same spirit as `PEAKS_CALLER_ID`: an env var the user can export, plus a
|
|
34
|
+
* machine-wide `peaks config set --key context.windowTokens` twin.
|
|
35
|
+
*/
|
|
36
|
+
export declare const CONTEXT_WINDOW_TOKENS_ENV_VAR = "PEAKS_CONTEXT_WINDOW_TOKENS";
|
|
37
|
+
/**
|
|
38
|
+
* Which layer produced a resolved context window:
|
|
39
|
+
* - `env-override` — `PEAKS_CONTEXT_WINDOW_TOKENS`
|
|
40
|
+
* - `config` — `context.windowTokens` (`peaks config set`)
|
|
41
|
+
* - `model-heuristic` — `[1M]` suffix / `ONE_MILLION_CONTEXT_MODELS`
|
|
42
|
+
* - `default` — 200K safe default
|
|
43
|
+
*/
|
|
44
|
+
export type ContextWindowSource = 'env-override' | 'config' | 'model-heuristic' | 'default';
|
|
45
|
+
export interface ContextWindowResolution {
|
|
46
|
+
readonly tokens: number;
|
|
47
|
+
readonly source: ContextWindowSource;
|
|
48
|
+
}
|
|
49
|
+
/** Explicit override inputs (both optional; env wins over config). */
|
|
50
|
+
export interface ContextWindowOverrides {
|
|
51
|
+
readonly env?: NodeJS.ProcessEnv | undefined;
|
|
52
|
+
/** Raw `context.windowTokens` value (unvalidated — validated here). */
|
|
53
|
+
readonly configWindowTokens?: unknown;
|
|
54
|
+
/** Warning sink for an invalid override (defaults to `console.warn`). */
|
|
55
|
+
readonly onInvalidOverride?: ((message: string) => void) | undefined;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Parse an explicit context-window override. Accepts a positive finite
|
|
59
|
+
* integer only (number, or a numeric string so an env var works); anything
|
|
60
|
+
* else — `0`, negative, `NaN`, `Infinity`, `1.5`, `'abc'`, `''` — returns
|
|
61
|
+
* null so the caller can ignore it and fall through to the next layer.
|
|
62
|
+
*/
|
|
63
|
+
export declare function parseContextWindowOverride(raw: unknown): number | null;
|
|
64
|
+
/**
|
|
65
|
+
* Resolve the context window in tokens AND report which layer won
|
|
66
|
+
* (first hit wins):
|
|
67
|
+
* 1. env `PEAKS_CONTEXT_WINDOW_TOKENS`
|
|
68
|
+
* 2. config `context.windowTokens`
|
|
69
|
+
* 3. model-name heuristic (`modelContextWindowTokens`)
|
|
70
|
+
* 4. `DEFAULT_CONTEXT_WINDOW_TOKENS` (200_000)
|
|
71
|
+
*
|
|
72
|
+
* An invalid explicit override is ignored with a warning and falls through
|
|
73
|
+
* to the next layer — a typo must never crash or silently win the probe.
|
|
74
|
+
*/
|
|
75
|
+
export declare function resolveContextWindow(model: string, overrides?: ContextWindowOverrides): ContextWindowResolution;
|
|
25
76
|
export declare const CLAUDE_CODE_ADAPTER: IdeAdapter;
|
|
@@ -161,6 +161,9 @@ export function resolveClaudeModelFromEnv(env) {
|
|
|
161
161
|
* Callers MAY additionally infer ≥1M from the observed token count: if
|
|
162
162
|
* `contextTokens > DEFAULT_CONTEXT_WINDOW_TOKENS`, the model cannot be a
|
|
163
163
|
* 200K model and must be ≥1M (see `readClaudeTranscriptEstimate`).
|
|
164
|
+
*
|
|
165
|
+
* This is the HEURISTIC layer only. Explicit user overrides sit ABOVE it —
|
|
166
|
+
* see `resolveContextWindow`, which is what the probe actually calls.
|
|
164
167
|
*/
|
|
165
168
|
export function modelContextWindowTokens(model) {
|
|
166
169
|
const m = model.trim().toLowerCase();
|
|
@@ -174,6 +177,60 @@ export function modelContextWindowTokens(model) {
|
|
|
174
177
|
}
|
|
175
178
|
return DEFAULT_CONTEXT_WINDOW_TOKENS;
|
|
176
179
|
}
|
|
180
|
+
/**
|
|
181
|
+
* Slice 2026-09-09-context-window-override: vendor-neutral escape hatch for
|
|
182
|
+
* the context-window size in tokens. Third-party / proxied models whose id
|
|
183
|
+
* carries no `[1M]` suffix (and is absent from the hardcoded allowlist) are
|
|
184
|
+
* otherwise stuck at the 200K default, which inflates `ratio` up to 5×.
|
|
185
|
+
* Same spirit as `PEAKS_CALLER_ID`: an env var the user can export, plus a
|
|
186
|
+
* machine-wide `peaks config set --key context.windowTokens` twin.
|
|
187
|
+
*/
|
|
188
|
+
export const CONTEXT_WINDOW_TOKENS_ENV_VAR = 'PEAKS_CONTEXT_WINDOW_TOKENS';
|
|
189
|
+
/**
|
|
190
|
+
* Parse an explicit context-window override. Accepts a positive finite
|
|
191
|
+
* integer only (number, or a numeric string so an env var works); anything
|
|
192
|
+
* else — `0`, negative, `NaN`, `Infinity`, `1.5`, `'abc'`, `''` — returns
|
|
193
|
+
* null so the caller can ignore it and fall through to the next layer.
|
|
194
|
+
*/
|
|
195
|
+
export function parseContextWindowOverride(raw) {
|
|
196
|
+
if (typeof raw !== 'number' && typeof raw !== 'string')
|
|
197
|
+
return null;
|
|
198
|
+
if (typeof raw === 'string' && raw.trim().length === 0)
|
|
199
|
+
return null;
|
|
200
|
+
const parsed = typeof raw === 'number' ? raw : Number(raw.trim());
|
|
201
|
+
return Number.isFinite(parsed) && Number.isInteger(parsed) && parsed > 0 ? parsed : null;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Resolve the context window in tokens AND report which layer won
|
|
205
|
+
* (first hit wins):
|
|
206
|
+
* 1. env `PEAKS_CONTEXT_WINDOW_TOKENS`
|
|
207
|
+
* 2. config `context.windowTokens`
|
|
208
|
+
* 3. model-name heuristic (`modelContextWindowTokens`)
|
|
209
|
+
* 4. `DEFAULT_CONTEXT_WINDOW_TOKENS` (200_000)
|
|
210
|
+
*
|
|
211
|
+
* An invalid explicit override is ignored with a warning and falls through
|
|
212
|
+
* to the next layer — a typo must never crash or silently win the probe.
|
|
213
|
+
*/
|
|
214
|
+
export function resolveContextWindow(model, overrides = {}) {
|
|
215
|
+
const warn = overrides.onInvalidOverride ?? ((message) => console.warn(message));
|
|
216
|
+
const envRaw = overrides.env?.[CONTEXT_WINDOW_TOKENS_ENV_VAR];
|
|
217
|
+
if (envRaw !== undefined) {
|
|
218
|
+
const parsed = parseContextWindowOverride(envRaw);
|
|
219
|
+
if (parsed !== null)
|
|
220
|
+
return { tokens: parsed, source: 'env-override' };
|
|
221
|
+
warn(`[peaks] ${CONTEXT_WINDOW_TOKENS_ENV_VAR}="${String(envRaw)}" is not a positive integer — ignoring the override`);
|
|
222
|
+
}
|
|
223
|
+
if (overrides.configWindowTokens !== undefined) {
|
|
224
|
+
const parsed = parseContextWindowOverride(overrides.configWindowTokens);
|
|
225
|
+
if (parsed !== null)
|
|
226
|
+
return { tokens: parsed, source: 'config' };
|
|
227
|
+
warn(`[peaks] config context.windowTokens=${JSON.stringify(overrides.configWindowTokens)} is not a positive integer — ignoring the override`);
|
|
228
|
+
}
|
|
229
|
+
const heuristic = modelContextWindowTokens(model);
|
|
230
|
+
return heuristic === DEFAULT_CONTEXT_WINDOW_TOKENS
|
|
231
|
+
? { tokens: heuristic, source: 'default' }
|
|
232
|
+
: { tokens: heuristic, source: 'model-heuristic' };
|
|
233
|
+
}
|
|
177
234
|
/** A non-negative finite number, or null when the value is not numeric. */
|
|
178
235
|
function numericTokenCount(value) {
|
|
179
236
|
if (typeof value === 'number' && Number.isFinite(value) && value >= 0)
|
|
@@ -277,14 +334,20 @@ function findLatestTranscriptUsage(filePath) {
|
|
|
277
334
|
}
|
|
278
335
|
}
|
|
279
336
|
/**
|
|
280
|
-
* Resolve the context window for a transcript usage entry.
|
|
281
|
-
*
|
|
282
|
-
*
|
|
283
|
-
*
|
|
337
|
+
* Resolve the context window for a transcript usage entry. Explicit user
|
|
338
|
+
* overrides (`resolveContextWindow`) win outright — the user pinned the
|
|
339
|
+
* number, so nothing else may contradict it. Without an explicit override,
|
|
340
|
+
* when the observed token count contradicts the heuristic window (tokens
|
|
341
|
+
* exceed it), the model must be ≥1M, so bump to the 1M window (the late
|
|
342
|
+
* rescue; it keeps the heuristic source tag, only the tokens change).
|
|
284
343
|
*/
|
|
285
|
-
function resolveContextWindowTokens(model, contextTokens) {
|
|
286
|
-
const
|
|
287
|
-
|
|
344
|
+
function resolveContextWindowTokens(model, contextTokens, overrides = {}) {
|
|
345
|
+
const resolved = resolveContextWindow(model, overrides);
|
|
346
|
+
if (resolved.source === 'env-override' || resolved.source === 'config')
|
|
347
|
+
return resolved;
|
|
348
|
+
return contextTokens > resolved.tokens
|
|
349
|
+
? { tokens: ONE_MILLION_CONTEXT_TOKENS, source: resolved.source }
|
|
350
|
+
: resolved;
|
|
288
351
|
}
|
|
289
352
|
/**
|
|
290
353
|
* Conservative transcript-estimate fallback. Recursively searches
|
|
@@ -298,9 +361,11 @@ function resolveContextWindowTokens(model, contextTokens) {
|
|
|
298
361
|
*
|
|
299
362
|
* Window model resolution is env-first: when `envModel` is present, its id
|
|
300
363
|
* (which Claude Code stamps with the `[1M]` / `[200K]` suffix) drives the
|
|
301
|
-
* window; otherwise the transcript `message.model` is used.
|
|
364
|
+
* window; otherwise the transcript `message.model` is used. Explicit
|
|
365
|
+
* overrides (env `PEAKS_CONTEXT_WINDOW_TOKENS` / config `context.windowTokens`)
|
|
366
|
+
* sit above both and are reported via `capacitySource`.
|
|
302
367
|
*/
|
|
303
|
-
function readClaudeTranscriptEstimate(outerSessionId, envModel) {
|
|
368
|
+
function readClaudeTranscriptEstimate(outerSessionId, envModel, overrides = {}) {
|
|
304
369
|
const projectsDir = join(homedir(), '.claude', 'projects');
|
|
305
370
|
const path = findTranscriptJsonl(projectsDir, outerSessionId);
|
|
306
371
|
if (path === null)
|
|
@@ -309,9 +374,10 @@ function readClaudeTranscriptEstimate(outerSessionId, envModel) {
|
|
|
309
374
|
if (latest === null)
|
|
310
375
|
return null;
|
|
311
376
|
const model = envModel !== undefined && envModel.trim().length > 0 ? envModel : latest.model;
|
|
312
|
-
const
|
|
377
|
+
const resolved = resolveContextWindowTokens(model, latest.contextTokens, overrides);
|
|
378
|
+
const contextWindowTokens = resolved.tokens;
|
|
313
379
|
const ratio = Math.min(1, latest.contextTokens / contextWindowTokens);
|
|
314
|
-
return { ratio, contextTokens: latest.contextTokens, contextWindowTokens };
|
|
380
|
+
return { ratio, contextTokens: latest.contextTokens, contextWindowTokens, capacitySource: resolved.source };
|
|
315
381
|
}
|
|
316
382
|
/**
|
|
317
383
|
* Claude Code's vendor-specific context-percent fallback, exposed as
|
|
@@ -344,13 +410,17 @@ function readContextPercentFallback(input) {
|
|
|
344
410
|
}
|
|
345
411
|
if (typeof input.outerSessionId === 'string' && input.outerSessionId.length > 0) {
|
|
346
412
|
const envModel = resolveClaudeModelFromEnv(input.env);
|
|
347
|
-
const estimate = readClaudeTranscriptEstimate(input.outerSessionId, envModel
|
|
413
|
+
const estimate = readClaudeTranscriptEstimate(input.outerSessionId, envModel, {
|
|
414
|
+
env: input.env,
|
|
415
|
+
configWindowTokens: input.configWindowTokens
|
|
416
|
+
});
|
|
348
417
|
if (estimate !== null) {
|
|
349
418
|
return {
|
|
350
419
|
ratio: estimate.ratio,
|
|
351
420
|
source: 'transcript-estimate',
|
|
352
421
|
rawTokens: estimate.contextTokens,
|
|
353
422
|
capacityTokens: estimate.contextWindowTokens,
|
|
423
|
+
capacitySource: estimate.capacitySource,
|
|
354
424
|
ide,
|
|
355
425
|
capturedAt
|
|
356
426
|
};
|
|
@@ -401,7 +471,7 @@ export const CLAUDE_CODE_ADAPTER = {
|
|
|
401
471
|
// Pathway = 'ide-native' (not 'shell-exec') so the dispatcher
|
|
402
472
|
// routes main-session compacts through the PreToolUse hook in
|
|
403
473
|
// `.claude/settings.local.json`. The hook fires
|
|
404
|
-
// `peaks
|
|
474
|
+
// `peaks code auto-compact` on the NEXT Bash/Task tool
|
|
405
475
|
// call from the runner, which in-band spawns `claude --compact`
|
|
406
476
|
// against the CURRENT runner — not a child process (the
|
|
407
477
|
// shell-exec spawn-new-claude bug documented in
|
|
@@ -412,7 +482,7 @@ export const CLAUDE_CODE_ADAPTER = {
|
|
|
412
482
|
envVarForContextPercent: 'CLAUDE_CONTEXT_USAGE_PERCENT',
|
|
413
483
|
compactCommand: 'claude --compact',
|
|
414
484
|
compactPathway: 'ide-native',
|
|
415
|
-
postCompactDetectCommand: 'peaks
|
|
485
|
+
postCompactDetectCommand: 'peaks code auto-compact --json',
|
|
416
486
|
readContextPercentFallback
|
|
417
487
|
},
|
|
418
488
|
// Slice #011: standards profile. Claude Code reads its constitution at
|
|
@@ -197,7 +197,7 @@ export interface IdeCompactProfile {
|
|
|
197
197
|
readonly compactPathway: 'shell-exec' | 'ide-native' | 'llm-self-compress' | 'noop';
|
|
198
198
|
/**
|
|
199
199
|
* Optional command the runner invokes post-compact to confirm
|
|
200
|
-
* ratio dropped (e.g. `peaks
|
|
200
|
+
* ratio dropped (e.g. `peaks code auto-compact --json`). When omitted,
|
|
201
201
|
* the orchestrator polls `envVarForContextPercent` directly.
|
|
202
202
|
*/
|
|
203
203
|
readonly postCompactDetectCommand?: string;
|
|
@@ -239,6 +239,15 @@ export interface ContextPercentFallbackInput {
|
|
|
239
239
|
readonly outerSessionId?: string | undefined;
|
|
240
240
|
/** Injectable env (defaults to process.env in the reader). */
|
|
241
241
|
readonly env?: NodeJS.ProcessEnv | undefined;
|
|
242
|
+
/**
|
|
243
|
+
* Raw `context.windowTokens` value from the merged config (project layer
|
|
244
|
+
* over user layer), read by the generic reader so the adapter stays free
|
|
245
|
+
* of config-path knowledge. UNVALIDATED — the adapter validates it via
|
|
246
|
+
* `parseContextWindowOverride` and warns on a bad value.
|
|
247
|
+
*
|
|
248
|
+
* Slice 2026-09-09-context-window-override.
|
|
249
|
+
*/
|
|
250
|
+
readonly configWindowTokens?: unknown;
|
|
242
251
|
}
|
|
243
252
|
/**
|
|
244
253
|
* Per-IDE standards-file location + format profile. Used by the
|
|
@@ -8,7 +8,10 @@ export type ConfirmationOptions = {
|
|
|
8
8
|
forceConfirm?: boolean | undefined;
|
|
9
9
|
};
|
|
10
10
|
export declare class ConfirmationRequiredError extends Error {
|
|
11
|
-
|
|
11
|
+
readonly transitionKey: TransitionKey;
|
|
12
|
+
readonly mode: SkillPresenceMode;
|
|
13
|
+
readonly nextActions: readonly string[];
|
|
14
|
+
constructor(transitionKey: TransitionKey, mode: SkillPresenceMode);
|
|
12
15
|
}
|
|
13
16
|
export declare function requireUserConfirmation(options: ConfirmationOptions): Promise<void>;
|
|
14
17
|
export {};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import * as readline from 'node:readline';
|
|
2
1
|
import { getSkillPresence } from '../skills/skill-presence-service.js';
|
|
3
2
|
const ASSISTED_CONFIRM_TRANSITIONS = new Set([
|
|
4
3
|
'prd:confirmed-by-user',
|
|
@@ -6,7 +5,9 @@ const ASSISTED_CONFIRM_TRANSITIONS = new Set([
|
|
|
6
5
|
'qa:verdict-issued'
|
|
7
6
|
]);
|
|
8
7
|
export function requiresConfirmation(mode, transitionKey) {
|
|
9
|
-
|
|
8
|
+
// Slice 2026-09-09-mode-consolidation: `swarm` removed as a mode; the
|
|
9
|
+
// two auto-proceed peers are `full-auto` and `24h`.
|
|
10
|
+
if (mode === 'full-auto' || mode === '24h') {
|
|
10
11
|
return false;
|
|
11
12
|
}
|
|
12
13
|
if (mode === 'strict') {
|
|
@@ -22,12 +23,23 @@ function describeTransition(transitionKey) {
|
|
|
22
23
|
return `Transition ${role.toUpperCase()} → ${state}`;
|
|
23
24
|
}
|
|
24
25
|
export class ConfirmationRequiredError extends Error {
|
|
25
|
-
|
|
26
|
+
transitionKey;
|
|
27
|
+
mode;
|
|
28
|
+
nextActions;
|
|
29
|
+
constructor(transitionKey, mode) {
|
|
26
30
|
const description = describeTransition(transitionKey);
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
'
|
|
31
|
+
const nextActions = [
|
|
32
|
+
`Ask the user via AskUserQuestion whether to proceed with ${description} in ${mode} mode.`,
|
|
33
|
+
'If the user approves, re-run the same command with --confirm.'
|
|
34
|
+
];
|
|
35
|
+
super(`Confirmation required for: ${description} (mode: ${mode})\n` +
|
|
36
|
+
`${nextActions[0]}\n` +
|
|
37
|
+
`${nextActions[1]}\n` +
|
|
38
|
+
'No terminal prompt is available: this gate never reads stdin.');
|
|
30
39
|
this.name = 'ConfirmationRequiredError';
|
|
40
|
+
this.transitionKey = transitionKey;
|
|
41
|
+
this.mode = mode;
|
|
42
|
+
this.nextActions = nextActions;
|
|
31
43
|
}
|
|
32
44
|
}
|
|
33
45
|
export async function requireUserConfirmation(options) {
|
|
@@ -40,11 +52,11 @@ export async function requireUserConfirmation(options) {
|
|
|
40
52
|
if (!requiresConfirmation(mode, options.transitionKey)) {
|
|
41
53
|
return;
|
|
42
54
|
}
|
|
43
|
-
// --confirm flag bypasses
|
|
55
|
+
// --confirm flag bypasses the gate
|
|
44
56
|
if (options.confirmed) {
|
|
45
57
|
return;
|
|
46
58
|
}
|
|
47
|
-
// PEAKS_AUTO_CONFIRM=1 only works for full-auto/
|
|
59
|
+
// PEAKS_AUTO_CONFIRM=1 only works for full-auto/24h (already returned above)
|
|
48
60
|
// For assisted/strict, env var is ignored unless --force-confirm is also set
|
|
49
61
|
if (process.env.PEAKS_AUTO_CONFIRM === '1') {
|
|
50
62
|
if (options.forceConfirm) {
|
|
@@ -53,7 +65,7 @@ export async function requireUserConfirmation(options) {
|
|
|
53
65
|
'This bypasses user confirmation. Use with caution.');
|
|
54
66
|
return;
|
|
55
67
|
}
|
|
56
|
-
throw new ConfirmationRequiredError(options.transitionKey);
|
|
68
|
+
throw new ConfirmationRequiredError(options.transitionKey, mode);
|
|
57
69
|
}
|
|
58
70
|
// --force-confirm without env var
|
|
59
71
|
if (options.forceConfirm) {
|
|
@@ -62,23 +74,9 @@ export async function requireUserConfirmation(options) {
|
|
|
62
74
|
'This bypasses user confirmation. Use with caution.');
|
|
63
75
|
return;
|
|
64
76
|
}
|
|
65
|
-
//
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
return new Promise((resolve, reject) => {
|
|
71
|
-
const description = describeTransition(options.transitionKey);
|
|
72
|
-
const prompt = `\n[CONFIRM] ${description}\nProceed? (y/N) `;
|
|
73
|
-
rl.question(prompt, (answer) => {
|
|
74
|
-
rl.close();
|
|
75
|
-
const normalized = answer.trim().toLowerCase();
|
|
76
|
-
if (normalized === 'y' || normalized === 'yes') {
|
|
77
|
-
resolve();
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
reject(new ConfirmationRequiredError(options.transitionKey));
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
});
|
|
77
|
+
// No bypass flag: refuse immediately. Never read stdin — in an LLM-driven
|
|
78
|
+
// session there is no TTY, so a prompt would hang forever, and a `y/N`
|
|
79
|
+
// terminal prompt would also violate the Human-NL-Choice-Only rule (the
|
|
80
|
+
// user answers via AskUserQuestion, never by typing into a shell).
|
|
81
|
+
throw new ConfirmationRequiredError(options.transitionKey, mode);
|
|
84
82
|
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slice 2026-09-09-mode-consolidation (Slice D): one read for the whole
|
|
3
|
+
* stacked mode picture.
|
|
4
|
+
*
|
|
5
|
+
* The autonomy model has two layers that used to be read by nothing in
|
|
6
|
+
* common:
|
|
7
|
+
*
|
|
8
|
+
* - MODE — `SkillPresenceMode` on the presence lease: the autonomy
|
|
9
|
+
* level (`full-auto | assisted | strict | 24h`).
|
|
10
|
+
* - STATE — `.peaks/_runtime/<sid>/24h-state.json`, the 6-state
|
|
11
|
+
* machine (`IDLE / BRAINSTORM / USER_CONFIRM / 24H_ACTIVE /
|
|
12
|
+
* WAITING_USER / HANDOFF`): the long-run PHASE *inside* the `24h`
|
|
13
|
+
* mode.
|
|
14
|
+
*
|
|
15
|
+
* This module is the single place that reads both, plus the Job-mode
|
|
16
|
+
* decision and the resolved auto-compact profile, so `peaks code mode
|
|
17
|
+
* status` (and any future consumer) does not re-derive the stack.
|
|
18
|
+
*
|
|
19
|
+
* Read-only + fail-soft: every sub-read is wrapped so a missing or
|
|
20
|
+
* malformed artifact degrades to `null` / `false` rather than throwing.
|
|
21
|
+
*/
|
|
22
|
+
import { type SkillPresenceMode } from '../skills/skill-presence-service.js';
|
|
23
|
+
import type { State24hSnapshot } from '../24h-mode/state.js';
|
|
24
|
+
import { type AutoCompactMode } from '../code/auto-compact-modes.js';
|
|
25
|
+
export interface ResolvedPresenceMode {
|
|
26
|
+
readonly mode: SkillPresenceMode | null;
|
|
27
|
+
readonly skill: string | null;
|
|
28
|
+
readonly source: 'canonical' | 'file' | 'env' | 'none';
|
|
29
|
+
}
|
|
30
|
+
export interface ModeStatus {
|
|
31
|
+
/** Autonomy level from the presence lease; `null` when no lease / no mode recorded. */
|
|
32
|
+
readonly mode: SkillPresenceMode | null;
|
|
33
|
+
/** Active skill name from the same lease read (display aid). */
|
|
34
|
+
readonly skill: string | null;
|
|
35
|
+
/** Where the mode came from. */
|
|
36
|
+
readonly modeSource: 'canonical' | 'file' | 'env' | 'none';
|
|
37
|
+
/** `true` when the resolved mode is `24h`. */
|
|
38
|
+
readonly is24h: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* The 24h internal state machine snapshot. Populated only when
|
|
41
|
+
* `is24h` is true (the phase is meaningless outside the 24h mode);
|
|
42
|
+
* `null` when the mode is not `24h` or the snapshot is unreadable.
|
|
43
|
+
*/
|
|
44
|
+
readonly h24State: State24hSnapshot | null;
|
|
45
|
+
/** Job-mode flag from `job-shape.json` (`false` when undecided / unreadable). */
|
|
46
|
+
readonly jobMode: boolean;
|
|
47
|
+
/** Resolved auto-compact profile: `partial` iff the mode is `24h`. */
|
|
48
|
+
readonly autoCompactProfile: AutoCompactMode;
|
|
49
|
+
/** Thresholds backing `autoCompactProfile` (display aid). */
|
|
50
|
+
readonly autoCompactThresholds: {
|
|
51
|
+
readonly autoFire: number;
|
|
52
|
+
readonly preCompact: number;
|
|
53
|
+
readonly redLine: number;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Read the active presence mode via the canonical lease projection.
|
|
58
|
+
* Never throws.
|
|
59
|
+
*/
|
|
60
|
+
export declare function resolvePresenceMode(projectRoot: string): ResolvedPresenceMode;
|
|
61
|
+
/**
|
|
62
|
+
* Resolve the auto-compact profile from the MODE, not from the 24h
|
|
63
|
+
* state machine. `24h` mode → `partial` (earlier thresholds for
|
|
64
|
+
* long-run sessions); every other mode → `standard`.
|
|
65
|
+
*
|
|
66
|
+
* Slice 2026-09-09-mode-consolidation: this replaced the previous
|
|
67
|
+
* `24h-state.state === '24H_ACTIVE'` mapping. The state machine is the
|
|
68
|
+
* long-run *phase*; the mode is the autonomy level the user (or the
|
|
69
|
+
* T3/T4 auto-engage) selected. Keying off the mode means a `24h`
|
|
70
|
+
* session keeps the partial profile even while it is in
|
|
71
|
+
* `WAITING_USER`, which is the correct long-run behaviour.
|
|
72
|
+
*/
|
|
73
|
+
export declare function resolveAutoCompactProfile(projectRoot: string): AutoCompactMode;
|
|
74
|
+
/**
|
|
75
|
+
* Assemble the full stacked status. `sessionId` defaults to the
|
|
76
|
+
* canonical binding when omitted.
|
|
77
|
+
*/
|
|
78
|
+
export declare function resolveModeStatus(input: {
|
|
79
|
+
projectRoot: string;
|
|
80
|
+
sessionId?: string | null | undefined;
|
|
81
|
+
}): ModeStatus;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slice 2026-09-09-mode-consolidation (Slice D): one read for the whole
|
|
3
|
+
* stacked mode picture.
|
|
4
|
+
*
|
|
5
|
+
* The autonomy model has two layers that used to be read by nothing in
|
|
6
|
+
* common:
|
|
7
|
+
*
|
|
8
|
+
* - MODE — `SkillPresenceMode` on the presence lease: the autonomy
|
|
9
|
+
* level (`full-auto | assisted | strict | 24h`).
|
|
10
|
+
* - STATE — `.peaks/_runtime/<sid>/24h-state.json`, the 6-state
|
|
11
|
+
* machine (`IDLE / BRAINSTORM / USER_CONFIRM / 24H_ACTIVE /
|
|
12
|
+
* WAITING_USER / HANDOFF`): the long-run PHASE *inside* the `24h`
|
|
13
|
+
* mode.
|
|
14
|
+
*
|
|
15
|
+
* This module is the single place that reads both, plus the Job-mode
|
|
16
|
+
* decision and the resolved auto-compact profile, so `peaks code mode
|
|
17
|
+
* status` (and any future consumer) does not re-derive the stack.
|
|
18
|
+
*
|
|
19
|
+
* Read-only + fail-soft: every sub-read is wrapped so a missing or
|
|
20
|
+
* malformed artifact degrades to `null` / `false` rather than throwing.
|
|
21
|
+
*/
|
|
22
|
+
import { resolveActiveSkillForCaller } from '../audit/enforcers/active-skill-resolver.js';
|
|
23
|
+
import { getCurrentSessionId } from '../skills/skill-presence-service.js';
|
|
24
|
+
// Import the 24h store directly (NOT the `24h-mode/index.js` barrel) —
|
|
25
|
+
// the barrel re-exports `decider.ts`, which imports this module, and
|
|
26
|
+
// that would form an import cycle.
|
|
27
|
+
import { read24hState } from '../24h-mode/store.js';
|
|
28
|
+
import { readJobShapeDecision } from '../code/job-shape-decision.js';
|
|
29
|
+
import { AUTO_COMPACT_THRESHOLDS } from '../code/auto-compact-modes.js';
|
|
30
|
+
/**
|
|
31
|
+
* Read the active presence mode via the canonical lease projection.
|
|
32
|
+
* Never throws.
|
|
33
|
+
*/
|
|
34
|
+
export function resolvePresenceMode(projectRoot) {
|
|
35
|
+
try {
|
|
36
|
+
const resolved = resolveActiveSkillForCaller(projectRoot);
|
|
37
|
+
const mode = resolved.mode;
|
|
38
|
+
return {
|
|
39
|
+
mode: mode === null ? null : mode,
|
|
40
|
+
skill: resolved.skill,
|
|
41
|
+
source: resolved.source
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return { mode: null, skill: null, source: 'none' };
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Resolve the auto-compact profile from the MODE, not from the 24h
|
|
50
|
+
* state machine. `24h` mode → `partial` (earlier thresholds for
|
|
51
|
+
* long-run sessions); every other mode → `standard`.
|
|
52
|
+
*
|
|
53
|
+
* Slice 2026-09-09-mode-consolidation: this replaced the previous
|
|
54
|
+
* `24h-state.state === '24H_ACTIVE'` mapping. The state machine is the
|
|
55
|
+
* long-run *phase*; the mode is the autonomy level the user (or the
|
|
56
|
+
* T3/T4 auto-engage) selected. Keying off the mode means a `24h`
|
|
57
|
+
* session keeps the partial profile even while it is in
|
|
58
|
+
* `WAITING_USER`, which is the correct long-run behaviour.
|
|
59
|
+
*/
|
|
60
|
+
export function resolveAutoCompactProfile(projectRoot) {
|
|
61
|
+
return resolvePresenceMode(projectRoot).mode === '24h' ? 'partial' : 'standard';
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Assemble the full stacked status. `sessionId` defaults to the
|
|
65
|
+
* canonical binding when omitted.
|
|
66
|
+
*/
|
|
67
|
+
export function resolveModeStatus(input) {
|
|
68
|
+
const { projectRoot } = input;
|
|
69
|
+
const presence = resolvePresenceMode(projectRoot);
|
|
70
|
+
const is24h = presence.mode === '24h';
|
|
71
|
+
let sessionId = input.sessionId ?? null;
|
|
72
|
+
if (sessionId === null) {
|
|
73
|
+
try {
|
|
74
|
+
sessionId = getCurrentSessionId(projectRoot);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
sessionId = null;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
let h24State = null;
|
|
81
|
+
if (is24h && sessionId !== null) {
|
|
82
|
+
try {
|
|
83
|
+
h24State = read24hState(projectRoot, sessionId);
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
h24State = null;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
let jobMode = false;
|
|
90
|
+
if (sessionId !== null) {
|
|
91
|
+
try {
|
|
92
|
+
jobMode = readJobShapeDecision(projectRoot, sessionId).decision.isJob;
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
jobMode = false;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
mode: presence.mode,
|
|
100
|
+
skill: presence.skill,
|
|
101
|
+
modeSource: presence.source,
|
|
102
|
+
is24h,
|
|
103
|
+
h24State,
|
|
104
|
+
jobMode,
|
|
105
|
+
autoCompactProfile: is24h ? 'partial' : 'standard',
|
|
106
|
+
autoCompactThresholds: AUTO_COMPACT_THRESHOLDS[is24h ? 'partial' : 'standard']
|
|
107
|
+
};
|
|
108
|
+
}
|
|
@@ -76,7 +76,16 @@ export interface ProjectPreferences {
|
|
|
76
76
|
* dispatch *shape* (worker graph vs flat dispatch).
|
|
77
77
|
*/
|
|
78
78
|
readonly swarmMode: boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Legacy UA opt-in prompt decision. The UA knowledge-graph surface was
|
|
81
|
+
* removed in 2026-09-09 (project analysis is codegraph-first); the field
|
|
82
|
+
* is retained only so legacy `.peaks/preferences.json` files keep parsing.
|
|
83
|
+
*/
|
|
79
84
|
readonly uaPrompt: UaPromptDecision;
|
|
85
|
+
/**
|
|
86
|
+
* Legacy AgentShield opt-in prompt decision. The ECC AgentShield
|
|
87
|
+
* subprocess was removed in 4.0.0-beta.11; retained for legacy parse.
|
|
88
|
+
*/
|
|
80
89
|
readonly agentShieldPrompt: UaPromptDecision;
|
|
81
90
|
readonly classifyConservatism: ClassifyConservatism;
|
|
82
91
|
readonly classifyRules: ClassifyRuleOverrides;
|
|
@@ -84,15 +93,15 @@ export interface ProjectPreferences {
|
|
|
84
93
|
/** Loop Autonomous (L4 14.5) toggle. Default: false — never auto-enable. */
|
|
85
94
|
readonly loopAutonomousEnabled: boolean;
|
|
86
95
|
/**
|
|
87
|
-
* L2.3 P2-a: ECC AgentShield subprocess toggle
|
|
96
|
+
* L2.3 P2-a: ECC AgentShield subprocess toggle — **frozen, no-op**.
|
|
88
97
|
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
98
|
+
* Slice 3 of 4.0.0-beta.11 removed the ECC AgentShield subprocess
|
|
99
|
+
* entirely (upstream ships no `ecc-agentshield` binary). The field is
|
|
100
|
+
* retained only so legacy `.peaks/preferences.json` files still parse
|
|
101
|
+
* (`static-service.ts` calls `loadPreferences` for back-compat and
|
|
102
|
+
* ignores the value). Setting it to `true` has no effect.
|
|
92
103
|
*
|
|
93
|
-
*
|
|
94
|
-
* `agentShieldEnabled: true` with ECC missing surfaces a soft
|
|
95
|
-
* "ECC not installed" warning and the audit still completes.
|
|
104
|
+
* Default: false.
|
|
96
105
|
*/
|
|
97
106
|
readonly agentShieldEnabled: boolean;
|
|
98
107
|
/**
|
|
@@ -98,7 +98,6 @@ export const seedCapabilityItems = [
|
|
|
98
98
|
capability('gitnexus.repo-intelligence', 'gitnexus', 'GitNexus Repository Intelligence', 'cli', 'repo-intelligence', ['engineer'], 'medium', 'local-repo-scan', 'Use local project scanning through Peaks RD.', 'Repository Intelligence', '仓库智能分析', 'Repository intelligence should be proxied through Peaks before use.', '仓库智能分析应先通过 Peaks 代理边界再使用。'),
|
|
99
99
|
capability('claude-code-best-practice.workflow-guidance', 'claude-code-best-practice', 'Claude Code Best Practice', 'doc', 'workflow-guidance', ['engineer'], 'low', 'peaks-built-in-rules', 'Use Peaks built-in workflow and review rules.', 'Claude Code Best Practice', 'Claude Code 最佳实践', 'Guidance for Claude Code engineering workflows.', 'Claude Code 工程工作流指导。'),
|
|
100
100
|
capability('superpowers.workflow-methodology', 'superpowers', 'Superpowers Methodology', 'workflow', 'workflow-methodology', ['product', 'engineer'], 'low', 'peaks-workflow-route', 'Use Peaks route/autonomous plans.', 'Superpowers Methodology', 'Superpowers 方法论', 'Workflow and artifact methodology reference.', '工作流与 artifact 方法论参考。'),
|
|
101
|
-
capability('understand-anything.knowledge-graph', 'understand-anything', 'Understand Anything Knowledge Graph', 'skill', 'project-analysis', ['engineer', 'product', 'qa'], 'low', 'peaks-codegraph-or-rd-scan', 'Use peaks codegraph or peaks RD project scan when Understand Anything is not installed. Optionally suggest installing it via Claude Code: /plugin marketplace add Lum1104/Understand-Anything then /plugin install understand-anything.', 'Understand Anything Knowledge Graph', 'Understand Anything 知识图谱', 'Multi-agent project knowledge graph that Peaks reads from .understand-anything/knowledge-graph.json when it has been generated by the Understand Anything plugin in Claude Code.', '通过 Claude Code 的 Understand Anything 插件生成的多 agent 知识图谱,Peaks 在 .understand-anything/knowledge-graph.json 存在时读取它作为项目分析证据。'),
|
|
102
101
|
capability('penpot.design-source', 'penpot', 'Penpot Design Source', 'doc', 'design-source', ['designer', 'engineer'], 'medium', 'manual-design-input', 'Ask for exported design notes or screenshots.', 'Penpot Design Source', 'Penpot 设计来源', 'Design-source reference for UI planning.', '用于 UI 规划的设计来源参考。'),
|
|
103
102
|
capability('gstack.product-stack-guidance', 'gstack', 'Product Stack Guidance', 'doc', 'product-guidance', ['product'], 'low', 'peaks-prd', 'Use peaks-prd for product goals and non-goals.', 'Product Stack Guidance', '产品栈指导', 'Product and startup stack guidance reference.', '产品与创业栈指导参考。'),
|
|
104
103
|
capability('awesome-design-md.design-reference', 'awesome-design-md', 'Design Markdown Reference', 'doc', 'design-reference', ['designer', 'engineer'], 'low', 'peaks-ui-visual-direction', 'Use peaks-ui to define visual direction and interaction constraints.', 'Design Reference', '设计参考', 'Design markdown examples and inspiration.', '设计 markdown 示例与灵感。'),
|