peaks-loop 3.0.0 → 3.0.1
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/.claude-plugin/marketplace.json +3 -3
- package/CHANGELOG.md +57 -57
- package/README-en.md +2 -2
- package/README.md +2 -2
- package/agents/karpathy-reviewer.md +2 -2
- package/dist/src/cli/commands/agent-commands.js +3 -3
- package/dist/src/cli/commands/audit-commands.d.ts +1 -1
- package/dist/src/cli/commands/audit-commands.js +6 -6
- package/dist/src/cli/commands/classify-classify-commands.js +1 -1
- package/dist/src/cli/commands/code-review-commands.d.ts +3 -3
- package/dist/src/cli/commands/code-review-commands.js +5 -5
- package/dist/src/cli/commands/compact-command.d.ts +21 -0
- package/dist/src/cli/commands/compact-command.js +252 -0
- package/dist/src/cli/commands/context-commands.d.ts +1 -1
- package/dist/src/cli/commands/context-commands.js +1 -1
- package/dist/src/cli/commands/contract-commands.d.ts +1 -1
- package/dist/src/cli/commands/core/session-command.js +17 -7
- package/dist/src/cli/commands/core/skill-command.js +1 -1
- package/dist/src/cli/commands/feedback-commands.js +1 -1
- package/dist/src/cli/commands/hook-handle.d.ts +1 -1
- package/dist/src/cli/commands/hook-handle.js +1 -1
- package/dist/src/cli/commands/legacy-commands.d.ts +1 -1
- package/dist/src/cli/commands/legacy-commands.js +2 -2
- package/dist/src/cli/commands/log-commands.js +2 -2
- package/dist/src/cli/commands/loop-commands.d.ts +1 -1
- package/dist/src/cli/commands/loop-commands.js +1 -1
- package/dist/src/cli/commands/loop-eval-commands.d.ts +1 -1
- package/dist/src/cli/commands/loop-eval-commands.js +1 -1
- package/dist/src/cli/commands/playwright-commands.d.ts +1 -1
- package/dist/src/cli/commands/playwright-commands.js +2 -2
- package/dist/src/cli/commands/request-commands.js +40 -1
- package/dist/src/cli/commands/role-commands.js +1 -1
- package/dist/src/cli/commands/slice-commands.js +5 -5
- package/dist/src/cli/commands/upgrade-commands.d.ts +1 -1
- package/dist/src/cli/commands/upgrade-commands.js +6 -6
- package/dist/src/cli/commands/workspace/init-command.js +2 -2
- package/dist/src/cli/program.js +10 -1
- package/dist/src/services/agent/ecc-agent-service.js +5 -5
- package/dist/src/services/audit/artifact-writer.d.ts +1 -1
- package/dist/src/services/audit/artifact-writer.js +1 -1
- package/dist/src/services/audit/decision-writer.d.ts +1 -1
- package/dist/src/services/audit/decision-writer.js +1 -1
- package/dist/src/services/audit/enforcers/lint-output-style.js +5 -5
- package/dist/src/services/audit/enforcers/mock-placement.d.ts +1 -1
- package/dist/src/services/audit/enforcers/mock-placement.js +1 -1
- package/dist/src/services/audit/enforcers/no-root-pollution.js +1 -1
- package/dist/src/services/audit/red-line-catalog-p2-a.js +2 -2
- package/dist/src/services/audit/red-line-catalog-p2-b.js +2 -2
- package/dist/src/services/audit/static-service.d.ts +1 -1
- package/dist/src/services/audit/static-service.js +5 -5
- package/dist/src/services/audit/types.d.ts +1 -1
- package/dist/src/services/audit/types.js +1 -1
- package/dist/src/services/audit-independent/perf-audit-service.js +1 -1
- package/dist/src/services/audit-independent/security-audit-service.js +1 -1
- package/dist/src/services/classify/classify-service.d.ts +1 -1
- package/dist/src/services/classify/classify-service.js +1 -1
- package/dist/src/services/classify/classify-types.d.ts +1 -1
- package/dist/src/services/classify/classify-types.js +1 -1
- package/dist/src/services/code-review/ecc-bridge.d.ts +2 -2
- package/dist/src/services/code-review/ecc-bridge.js +2 -2
- package/dist/src/services/code-review/ocr-service.d.ts +9 -9
- package/dist/src/services/code-review/ocr-service.js +16 -16
- package/dist/src/services/compact/decision-tables.d.ts +66 -0
- package/dist/src/services/compact/decision-tables.js +127 -0
- package/dist/src/services/compact/request-transition-hook.d.ts +20 -0
- package/dist/src/services/compact/request-transition-hook.js +110 -0
- package/dist/src/services/compact/suggest-service.d.ts +74 -0
- package/dist/src/services/compact/suggest-service.js +203 -0
- package/dist/src/services/config/config-migration.js +1 -1
- package/dist/src/services/config/config-safety.d.ts +1 -1
- package/dist/src/services/config/config-safety.js +1 -1
- package/dist/src/services/config/config-service.d.ts +1 -1
- package/dist/src/services/config/config-service.js +1 -1
- package/dist/src/services/context/auto-compact-dispatcher.js +4 -4
- package/dist/src/services/context/auto-compact-types.d.ts +6 -6
- package/dist/src/services/context/auto-compact-types.js +5 -5
- package/dist/src/services/dispatch/sub-agent-dispatcher.js +1 -1
- package/dist/src/services/dispatch/test-tool-detection.d.ts +1 -1
- package/dist/src/services/dispatch/test-tool-detection.js +1 -1
- package/dist/src/services/doctor/doctor-service.d.ts +1 -1
- package/dist/src/services/doctor/doctor-service.js +5 -5
- package/dist/src/services/hooks/presence-marker-detector.js +5 -5
- package/dist/src/services/ide/adapters/claude-code-adapter.d.ts +1 -1
- package/dist/src/services/ide/adapters/claude-code-adapter.js +2 -2
- package/dist/src/services/ide/adapters/codex-adapter.d.ts +2 -2
- package/dist/src/services/ide/adapters/codex-adapter.js +2 -2
- package/dist/src/services/ide/adapters/cursor-adapter.d.ts +2 -2
- package/dist/src/services/ide/adapters/cursor-adapter.js +2 -2
- package/dist/src/services/ide/adapters/hermes-adapter.d.ts +1 -1
- package/dist/src/services/ide/adapters/hermes-adapter.js +1 -1
- package/dist/src/services/ide/adapters/openclaw-adapter.d.ts +1 -1
- package/dist/src/services/ide/adapters/openclaw-adapter.js +1 -1
- package/dist/src/services/ide/adapters/trae-adapter.d.ts +1 -1
- package/dist/src/services/ide/adapters/trae-adapter.js +1 -1
- package/dist/src/services/ide/ide-types.d.ts +9 -9
- package/dist/src/services/legacy/legacy-detector.d.ts +1 -1
- package/dist/src/services/legacy/legacy-detector.js +1 -1
- package/dist/src/services/log/log-commands-service.d.ts +1 -1
- package/dist/src/services/log/log-commands-service.js +1 -1
- package/dist/src/services/log/logger.d.ts +3 -3
- package/dist/src/services/log/logger.js +3 -3
- package/dist/src/services/log/redact.d.ts +1 -1
- package/dist/src/services/log/redact.js +1 -1
- package/dist/src/services/loop/evaluator-dispatcher.d.ts +1 -1
- package/dist/src/services/loop/evaluator-dispatcher.js +16 -15
- package/dist/src/services/loop/monotonic-guard.js +35 -18
- package/dist/src/services/loop/monotonic-runner.d.ts +3 -0
- package/dist/src/services/loop/monotonic-runner.js +62 -28
- package/dist/src/services/loop/run-driver.js +45 -24
- package/dist/src/services/memory/llm-reranker.d.ts +1 -1
- package/dist/src/services/memory/llm-reranker.js +1 -1
- package/dist/src/services/mut/production-stryker.d.ts +0 -5
- package/dist/src/services/mut/production-stryker.js +19 -10
- package/dist/src/services/openspec/openspec-propose-from-doctor-service.d.ts +1 -1
- package/dist/src/services/openspec/openspec-propose-from-doctor-service.js +1 -1
- package/dist/src/services/perf/perf-baseline-service.d.ts +2 -2
- package/dist/src/services/perf/perf-baseline-service.js +2 -2
- package/dist/src/services/prd/handoff-auto-regen.js +1 -1
- package/dist/src/services/prd/project-scan-sediment.js +3 -3
- package/dist/src/services/prd/project-scan-types.d.ts +1 -1
- package/dist/src/services/preferences/preferences-types.d.ts +3 -3
- package/dist/src/services/preferences/preferences-types.js +2 -2
- package/dist/src/services/role/role-registry.d.ts +1 -1
- package/dist/src/services/role/role-registry.js +1 -1
- package/dist/src/services/sc/sc-service.js +3 -3
- package/dist/src/services/skill/resume-detector.js +2 -2
- package/dist/src/services/skills/sync-service.d.ts +3 -3
- package/dist/src/services/skills/sync-service.js +9 -9
- package/dist/src/services/slice/calibration-store.d.ts +1 -1
- package/dist/src/services/slice/calibration-store.js +1 -1
- package/dist/src/services/solo/auto-compact-orchestrator.d.ts +1 -1
- package/dist/src/services/solo/auto-compact-orchestrator.js +7 -7
- package/dist/src/services/solo/dag-orchestrator.js +1 -1
- package/dist/src/services/solo/mode-gate.d.ts +1 -1
- package/dist/src/services/solo/mode-gate.js +4 -4
- package/dist/src/services/solo/user-touchpoint-classifier.js +1 -1
- package/dist/src/services/standards/migrate-claude-rules-service.js +5 -5
- package/dist/src/services/standards/migrate-service.d.ts +3 -3
- package/dist/src/services/standards/migrate-service.js +5 -5
- package/dist/src/services/standards/project-standards-service.js +1 -1
- package/dist/src/services/upgrade/gitignore-migrate-service.d.ts +3 -3
- package/dist/src/services/upgrade/gitignore-migrate-service.js +4 -4
- package/dist/src/services/upgrade/upgrade-service.d.ts +1 -1
- package/dist/src/services/upgrade/upgrade-service.js +5 -5
- package/dist/src/services/verdict/envelopes.d.ts +1 -1
- package/dist/src/services/verdict/envelopes.js +1 -1
- package/dist/src/services/workflow/workflow-loader.js +1 -1
- package/dist/src/services/workspace/migrate-1-4-1-service.d.ts +1 -1
- package/dist/src/services/workspace/migrate-1-4-1-service.js +1 -1
- package/dist/src/services/workspace/migrate-types.d.ts +1 -1
- package/dist/src/services/workspace/migrate-types.js +1 -1
- package/dist/src/services/workspace/workspace-claude-settings-materializer.d.ts +2 -2
- package/dist/src/services/workspace/workspace-claude-settings-materializer.js +9 -9
- package/dist/src/services/workspace/workspace-service.d.ts +1 -1
- package/dist/src/services/workspace/workspace-service.js +1 -1
- package/dist/src/shared/path-safety.d.ts +1 -1
- package/dist/src/shared/path-safety.js +1 -1
- package/dist/src/shared/version.d.ts +1 -1
- package/dist/src/shared/version.js +1 -1
- package/output-styles/peaks-skill-swarm.md +33 -33
- package/package.json +5 -4
- package/schemas/decomposition-v1.json +1 -1
- package/schemas/decomposition-v2.json +1 -1
- package/schemas/replay-fixture.schema.json +1 -1
- package/schemas/reviewer-envelope.schema.json +1 -1
- package/scripts/install-skills.mjs +11 -11
- package/skills/peaks-audit/SKILL.md +2 -2
- package/skills/peaks-doctor/SKILL.md +4 -4
- package/skills/peaks-final-review/SKILL.md +2 -2
- package/skills/peaks-ide/SKILL.md +3 -3
- package/skills/peaks-perf-audit/SKILL.md +1 -1
- package/skills/peaks-prd/SKILL.md +14 -14
- package/skills/peaks-prd/references/workflow.md +1 -1
- package/skills/peaks-qa/SKILL.md +17 -17
- package/skills/peaks-qa/references/artifact-per-request.md +1 -1
- package/skills/peaks-qa/references/browser-validation-contracts.md +2 -2
- package/skills/peaks-qa/references/codegraph-regression-focus.md +1 -1
- package/skills/peaks-qa/references/external-capability-guidance.md +2 -2
- package/skills/peaks-qa/references/qa-fanout-contract.md +1 -1
- package/skills/peaks-qa/references/qa-gstack-integration.md +3 -3
- package/skills/peaks-qa/references/qa-local-artifacts.md +1 -1
- package/skills/peaks-qa/references/qa-matt-pocock-integration.md +1 -1
- package/skills/peaks-qa/references/qa-runbook.md +3 -3
- package/skills/peaks-qa/references/qa-skill-presence.md +1 -1
- package/skills/peaks-qa/references/qa-standards-preflight.md +2 -2
- package/skills/peaks-qa/references/qa-transition-gates.md +9 -9
- package/skills/peaks-qa/references/regression-gates.md +1 -1
- package/skills/peaks-rd/SKILL.md +13 -13
- package/skills/peaks-rd/references/artifact-and-standards-output.md +1 -1
- package/skills/peaks-rd/references/codegraph-project-analysis.md +1 -1
- package/skills/peaks-rd/references/external-references.md +3 -3
- package/skills/peaks-rd/references/karpathy-reviewer-prompt.md +1 -1
- package/skills/peaks-rd/references/mandatory-perf-baseline.md +1 -1
- package/skills/peaks-rd/references/matt-pocock-integration.md +2 -2
- package/skills/peaks-rd/references/ocr-integration.md +19 -19
- package/skills/peaks-rd/references/openspec-cli.md +2 -2
- package/skills/peaks-rd/references/rd-gstack-integration.md +5 -5
- package/skills/peaks-rd/references/rd-runbook.md +9 -9
- package/skills/peaks-rd/references/rd-standards-preflight.md +1 -1
- package/skills/peaks-rd/references/rd-transition-gates.md +13 -13
- package/skills/peaks-rd/references/skill-presence-and-title.md +1 -1
- package/skills/peaks-reviewer/SKILL.md +2 -2
- package/skills/peaks-sc/SKILL.md +9 -9
- package/skills/peaks-security-audit/SKILL.md +1 -1
- package/skills/peaks-slice-decompose/SKILL.md +2 -2
- package/skills/peaks-solo/SKILL.md +49 -49
- package/skills/peaks-solo/references/a2a-artifact-mapping.md +8 -8
- package/skills/peaks-solo/references/anchoring-and-session-info.md +3 -3
- package/skills/peaks-solo/references/boundaries.md +4 -4
- package/skills/peaks-solo/references/browser-workflow.md +2 -2
- package/skills/peaks-solo/references/codegraph-orchestration.md +1 -1
- package/skills/peaks-solo/references/completion-handoff.md +2 -2
- package/skills/peaks-solo/references/external-references.md +3 -3
- package/skills/peaks-solo/references/external-skill-invocation.md +2 -2
- package/skills/peaks-solo/references/frontend-only-mode.md +1 -1
- package/skills/peaks-solo/references/gstack-integration.md +4 -4
- package/skills/peaks-solo/references/local-artifact-workspace.md +2 -2
- package/skills/peaks-solo/references/micro-cycle.md +4 -4
- package/skills/peaks-solo/references/mode-selection.md +5 -5
- package/skills/peaks-solo/references/openspec-workflow.md +2 -2
- package/skills/peaks-solo/references/playwright-mcp-multi-terminal.md +1 -1
- package/skills/peaks-solo/references/project-memory-loading.md +1 -1
- package/skills/peaks-solo/references/project-scan-checklist.md +1 -1
- package/skills/peaks-solo/references/quality-gate-cheatsheet.md +1 -1
- package/skills/peaks-solo/references/resume-detection.md +1 -1
- package/skills/peaks-solo/references/runbook.md +20 -20
- package/skills/peaks-solo/references/skill-presence-and-title.md +2 -2
- package/skills/peaks-solo/references/standards-preflight.md +2 -2
- package/skills/peaks-solo/references/step-0-55-1x-detection.md +3 -3
- package/skills/peaks-solo/references/sub-agent-dispatch.md +3 -3
- package/skills/peaks-solo/references/swarm-dispatch-contract.md +3 -3
- package/skills/peaks-solo/references/workflow-gates-and-types.md +34 -34
- package/skills/peaks-solo-resume/SKILL.md +2 -2
- package/skills/peaks-solo-status/SKILL.md +4 -4
- package/skills/peaks-solo-test/SKILL.md +4 -4
- package/skills/peaks-sop/SKILL.md +5 -5
- package/skills/peaks-txt/SKILL.md +17 -17
- package/skills/peaks-ui/SKILL.md +17 -17
- package/skills/peaks-ui/references/workflow.md +1 -1
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `peaks compact suggest` — strategic-compact service layer.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the ECC `suggest-compact.js` PreToolUse hook's two-signal
|
|
5
|
+
* suggestion logic but as a deterministic, machine-enforced CLI
|
|
6
|
+
* primitive. Two signals:
|
|
7
|
+
*
|
|
8
|
+
* 1. Context size (primary) — read latest usage row from
|
|
9
|
+
* `.peaks/_runtime/<sid>/usage.jsonl`. Suggest at
|
|
10
|
+
* COMPACT_CONTEXT_THRESHOLD (default 160k on 200k window, 250k
|
|
11
|
+
* on 1M window) and re-remind every COMPACT_CONTEXT_INTERVAL
|
|
12
|
+
* tokens (default 60k). A 1M window is detected when observed
|
|
13
|
+
* tokens exceed 200k AND the `modelKind: '1m'` marker is on
|
|
14
|
+
* the latest usage row, or when PEAKS_MODEL_KIND=1m is set.
|
|
15
|
+
*
|
|
16
|
+
* 2. Tool-call count (secondary) — read latest tool-call counter
|
|
17
|
+
* from the same usage.jsonl. Suggest at COMPACT_THRESHOLD
|
|
18
|
+
* (default 50) and re-remind every 25 calls.
|
|
19
|
+
*
|
|
20
|
+
* If usage.jsonl is absent (no peaks-loop session yet), fall back to
|
|
21
|
+
* PEAKS_CONTEXT_TOKENS / PEAKS_TOOL_CALLS env vars. If neither signal
|
|
22
|
+
* is available, the primitive returns `shouldSuggest: false` and a
|
|
23
|
+
* `dataUnavailable: true` flag — never throws.
|
|
24
|
+
*/
|
|
25
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
26
|
+
import { join } from 'node:path';
|
|
27
|
+
import { lookupPhaseTransition, buildSuggestedCompactMessage, SURVIVAL_TABLE } from './decision-tables.js';
|
|
28
|
+
/** Snapshot of the survival table for the dry-run envelope. */
|
|
29
|
+
const SURVIVAL_TABLE_PERSISTS = SURVIVAL_TABLE.persists;
|
|
30
|
+
const SURVIVAL_TABLE_LOST = SURVIVAL_TABLE.lost;
|
|
31
|
+
/** Default tool-call threshold before first suggestion. */
|
|
32
|
+
export const DEFAULT_TOOL_CALL_THRESHOLD = 50;
|
|
33
|
+
/** Default additional tool calls before the suggestion repeats. */
|
|
34
|
+
export const TOOL_CALL_REMIND_STEP = 25;
|
|
35
|
+
/** Default context-size threshold on a 200k window. */
|
|
36
|
+
export const DEFAULT_CONTEXT_THRESHOLD_200K = 160_000;
|
|
37
|
+
/** Default context-size threshold on a 1M window. */
|
|
38
|
+
export const DEFAULT_CONTEXT_THRESHOLD_1M = 250_000;
|
|
39
|
+
/** Default re-remind interval for context size. */
|
|
40
|
+
export const DEFAULT_CONTEXT_INTERVAL = 60_000;
|
|
41
|
+
function readLatestUsageRow(projectRoot, sessionId) {
|
|
42
|
+
const path = join(projectRoot, '.peaks', '_runtime', sessionId, 'usage.jsonl');
|
|
43
|
+
if (!existsSync(path))
|
|
44
|
+
return null;
|
|
45
|
+
try {
|
|
46
|
+
const raw = readFileSync(path, 'utf8');
|
|
47
|
+
const lines = raw.split(/\r?\n/).filter((l) => l.length > 0);
|
|
48
|
+
if (lines.length === 0)
|
|
49
|
+
return null;
|
|
50
|
+
const last = lines[lines.length - 1];
|
|
51
|
+
if (last === undefined)
|
|
52
|
+
return null;
|
|
53
|
+
return JSON.parse(last);
|
|
54
|
+
}
|
|
55
|
+
catch { // TODO(g2): legacy silent catch — grace: 1 minor release (v2.14.0)
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function parseIntEnv(env, key, fallback) {
|
|
60
|
+
const raw = env[key];
|
|
61
|
+
if (typeof raw !== 'string' || raw.length === 0)
|
|
62
|
+
return fallback;
|
|
63
|
+
const parsed = Number.parseInt(raw, 10);
|
|
64
|
+
return Number.isFinite(parsed) ? parsed : fallback;
|
|
65
|
+
}
|
|
66
|
+
function detectWindowKind(env, observedTokens, rowModelKind) {
|
|
67
|
+
if (rowModelKind === '1m')
|
|
68
|
+
return '1m';
|
|
69
|
+
if (env['PEAKS_MODEL_KIND'] === '1m')
|
|
70
|
+
return '1m';
|
|
71
|
+
// Heuristic from SKILL.md: a `[1m]` model marker OR observed tokens
|
|
72
|
+
// already exceed the 200k window. We use observed as the second
|
|
73
|
+
// signal only.
|
|
74
|
+
if (observedTokens > DEFAULT_CONTEXT_THRESHOLD_200K)
|
|
75
|
+
return '1m';
|
|
76
|
+
return '200k';
|
|
77
|
+
}
|
|
78
|
+
export function suggestCompact(options) {
|
|
79
|
+
const env = options.env ?? process.env;
|
|
80
|
+
const contextThreshold = parseIntEnv(env, 'COMPACT_CONTEXT_THRESHOLD', 0);
|
|
81
|
+
const contextInterval = parseIntEnv(env, 'COMPACT_CONTEXT_INTERVAL', DEFAULT_CONTEXT_INTERVAL);
|
|
82
|
+
const toolCallThreshold = parseIntEnv(env, 'COMPACT_THRESHOLD', DEFAULT_TOOL_CALL_THRESHOLD);
|
|
83
|
+
let tokensUsed = 0;
|
|
84
|
+
let toolCalls = 0;
|
|
85
|
+
let modelKind;
|
|
86
|
+
let source = 'none';
|
|
87
|
+
if (options.sessionId !== null) {
|
|
88
|
+
const row = readLatestUsageRow(options.projectRoot, options.sessionId);
|
|
89
|
+
if (row !== null) {
|
|
90
|
+
if (typeof row.tokens === 'number' && Number.isFinite(row.tokens))
|
|
91
|
+
tokensUsed = row.tokens;
|
|
92
|
+
if (typeof row.toolCalls === 'number' && Number.isFinite(row.toolCalls))
|
|
93
|
+
toolCalls = row.toolCalls;
|
|
94
|
+
if (typeof row.modelKind === 'string')
|
|
95
|
+
modelKind = row.modelKind;
|
|
96
|
+
source = 'usage-jsonl';
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (source === 'none') {
|
|
100
|
+
const envTokens = env['PEAKS_CONTEXT_TOKENS'];
|
|
101
|
+
if (typeof envTokens === 'string' && envTokens.length > 0) {
|
|
102
|
+
const parsed = Number.parseInt(envTokens, 10);
|
|
103
|
+
if (Number.isFinite(parsed) && parsed >= 0) {
|
|
104
|
+
tokensUsed = parsed;
|
|
105
|
+
source = 'env-vars';
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const envCalls = env['PEAKS_TOOL_CALLS'];
|
|
109
|
+
if (typeof envCalls === 'string' && envCalls.length > 0) {
|
|
110
|
+
const parsed = Number.parseInt(envCalls, 10);
|
|
111
|
+
if (Number.isFinite(parsed) && parsed >= 0) {
|
|
112
|
+
toolCalls = parsed;
|
|
113
|
+
source = 'env-vars';
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
const windowKind = detectWindowKind(env, tokensUsed, modelKind);
|
|
118
|
+
const windowCapacity = windowKind === '1m' ? 1_000_000 : 200_000;
|
|
119
|
+
const effectiveContextThreshold = contextThreshold > 0
|
|
120
|
+
? contextThreshold
|
|
121
|
+
: (windowKind === '1m' ? DEFAULT_CONTEXT_THRESHOLD_1M : DEFAULT_CONTEXT_THRESHOLD_200K);
|
|
122
|
+
const ratio = windowCapacity > 0 ? tokensUsed / windowCapacity : 0;
|
|
123
|
+
const dataUnavailable = tokensUsed === 0 && toolCalls === 0;
|
|
124
|
+
// Two-signal suggestion. The context signal is primary: the LLM
|
|
125
|
+
// gets a real "/compact" recommendation only when context-size OR
|
|
126
|
+
// tool-count crosses the threshold AND we have non-zero data.
|
|
127
|
+
let shouldSuggest = false;
|
|
128
|
+
let reason = 'below-threshold';
|
|
129
|
+
if (!dataUnavailable) {
|
|
130
|
+
if (contextThreshold !== 0 && tokensUsed >= effectiveContextThreshold) {
|
|
131
|
+
shouldSuggest = true;
|
|
132
|
+
const overBy = tokensUsed - effectiveContextThreshold;
|
|
133
|
+
reason = `context >= ${effectiveContextThreshold} on ${windowKind} window (over by ${overBy} tokens)`;
|
|
134
|
+
}
|
|
135
|
+
else if (toolCalls >= toolCallThreshold) {
|
|
136
|
+
shouldSuggest = true;
|
|
137
|
+
reason = `tool-calls >= ${toolCallThreshold} (count=${toolCalls})`;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return {
|
|
141
|
+
shouldSuggest,
|
|
142
|
+
reason,
|
|
143
|
+
ratio,
|
|
144
|
+
windowKind,
|
|
145
|
+
tokensUsed,
|
|
146
|
+
toolCalls,
|
|
147
|
+
thresholds: {
|
|
148
|
+
contextTokens: effectiveContextThreshold,
|
|
149
|
+
contextInterval,
|
|
150
|
+
toolCalls: toolCallThreshold
|
|
151
|
+
},
|
|
152
|
+
dataUnavailable,
|
|
153
|
+
source
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
export function dryRunCompact(options) {
|
|
157
|
+
const suggest = suggestCompact({
|
|
158
|
+
projectRoot: options.projectRoot,
|
|
159
|
+
sessionId: options.sessionId,
|
|
160
|
+
...(options.env !== undefined ? { env: options.env } : {})
|
|
161
|
+
});
|
|
162
|
+
const hasPhase = options.from !== undefined && options.to !== undefined;
|
|
163
|
+
const recommend = hasPhase
|
|
164
|
+
? buildRecommendEnvelope(options.from, options.to)
|
|
165
|
+
: {
|
|
166
|
+
from: null,
|
|
167
|
+
to: null,
|
|
168
|
+
shouldCompact: false,
|
|
169
|
+
severity: null,
|
|
170
|
+
rationale: null,
|
|
171
|
+
suggestedMessage: null
|
|
172
|
+
};
|
|
173
|
+
// Action threshold: either suggest-signal OR recommend=yes. The LLM
|
|
174
|
+
// is the final arbiter; the primitive just surfaces the composite
|
|
175
|
+
// signal.
|
|
176
|
+
const action = suggest.shouldSuggest || recommend.shouldCompact ? 'compact' : 'skip';
|
|
177
|
+
return {
|
|
178
|
+
action,
|
|
179
|
+
suggest,
|
|
180
|
+
recommend,
|
|
181
|
+
survival: { persists: SURVIVAL_TABLE_PERSISTS, lost: SURVIVAL_TABLE_LOST }
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
function buildRecommendEnvelope(from, to) {
|
|
185
|
+
const lookup = lookupPhaseTransition(from, to);
|
|
186
|
+
const shouldCompact = lookup.severity === 'yes' || lookup.severity === 'maybe';
|
|
187
|
+
return {
|
|
188
|
+
from,
|
|
189
|
+
to,
|
|
190
|
+
shouldCompact,
|
|
191
|
+
severity: lookup.severity,
|
|
192
|
+
rationale: lookup.rationale,
|
|
193
|
+
suggestedMessage: buildSuggestedCompactMessage(from, to, lookup.severity)
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
export function buildRecommendEnvelopePure(from, to) {
|
|
197
|
+
return buildRecommendEnvelope(from, to);
|
|
198
|
+
}
|
|
199
|
+
// Re-export phase primitives for callers that don't want to traverse
|
|
200
|
+
// decision-tables. The CLI command file imports `isPhase` from here
|
|
201
|
+
// to keep the validation path co-located with the recommend envelope
|
|
202
|
+
// builder.
|
|
203
|
+
export { PHASE_TRANSITIONS, lookupPhaseTransition, buildSuggestedCompactMessage, PHASES, isPhase, SURVIVAL_TABLE } from './decision-tables.js';
|
|
@@ -132,7 +132,7 @@ export function executeMigration(opts) {
|
|
|
132
132
|
// Per the 2.0.1 slim spec, the on-disk `~/.peaks/config.json` is
|
|
133
133
|
// `{ "version": "2.0.1", "ocr": { "llm": { ... } } }`. Legacy fields
|
|
134
134
|
// (language, model, economyMode, swarmMode, tokens, providers,
|
|
135
|
-
// proxy) live in <project>/.peaks/preferences.json. peaks-
|
|
135
|
+
// proxy) live in <project>/.peaks/preferences.json. peaks-loop writes
|
|
136
136
|
// the `ocr.llm.*` placeholders so the user has a discoverable spot
|
|
137
137
|
// to paste their endpoint; the placeholders are empty strings, not
|
|
138
138
|
// auto-configured values, so the post-migration file MUST contain
|
|
@@ -5,7 +5,7 @@ export declare function resolveProjectRootForConfig(startPath: string): string;
|
|
|
5
5
|
/**
|
|
6
6
|
* Canonicalise a user-supplied project root path against git's view of the
|
|
7
7
|
* repository root. This is the fix for the nested-directory regression
|
|
8
|
-
* where peaks-
|
|
8
|
+
* where peaks-loop would write `.peaks/` under a nested sub-folder
|
|
9
9
|
* (e.g. `prompt-project/prompt-project/.peaks/`) because the LLM passed
|
|
10
10
|
* `$(pwd)` from inside a sub-directory of a real git repo. Without
|
|
11
11
|
* canonicalisation, peaks accepted the cwd as-is, built the .peaks/
|
|
@@ -93,7 +93,7 @@ export function resolveProjectRootForConfig(startPath) {
|
|
|
93
93
|
/**
|
|
94
94
|
* Canonicalise a user-supplied project root path against git's view of the
|
|
95
95
|
* repository root. This is the fix for the nested-directory regression
|
|
96
|
-
* where peaks-
|
|
96
|
+
* where peaks-loop would write `.peaks/` under a nested sub-folder
|
|
97
97
|
* (e.g. `prompt-project/prompt-project/.peaks/`) because the LLM passed
|
|
98
98
|
* `$(pwd)` from inside a sub-directory of a real git repo. Without
|
|
99
99
|
* canonicalisation, peaks accepted the cwd as-is, built the .peaks/
|
|
@@ -38,7 +38,7 @@ export declare function setMiniMaxProviderConfig(input: MiniMaxProviderConfig):
|
|
|
38
38
|
* `~/.peaks/config.json`. The user populates this themselves by
|
|
39
39
|
* pasting the `peaks code-review config-template` output (or by
|
|
40
40
|
* running `peaks config set --key ocr.llm.url --value '...'`).
|
|
41
|
-
* peaks-
|
|
41
|
+
* peaks-loop never auto-writes these values.
|
|
42
42
|
*/
|
|
43
43
|
export declare function getOcrConfig(): OcrConfig;
|
|
44
44
|
/**
|
|
@@ -512,7 +512,7 @@ function toOcrConfig(value) {
|
|
|
512
512
|
* `~/.peaks/config.json`. The user populates this themselves by
|
|
513
513
|
* pasting the `peaks code-review config-template` output (or by
|
|
514
514
|
* running `peaks config set --key ocr.llm.url --value '...'`).
|
|
515
|
-
* peaks-
|
|
515
|
+
* peaks-loop never auto-writes these values.
|
|
516
516
|
*/
|
|
517
517
|
export function getOcrConfig() {
|
|
518
518
|
const userConfig = readUserJsonFile() ?? {};
|
|
@@ -9,22 +9,22 @@
|
|
|
9
9
|
*
|
|
10
10
|
* Pathway dispatch:
|
|
11
11
|
*
|
|
12
|
-
* - `shell-exec` — peaks-
|
|
12
|
+
* - `shell-exec` — peaks-loop spawns the adapter's
|
|
13
13
|
* `compactCommand` via `child_process.spawn`.
|
|
14
14
|
* Works for any IDE that accepts a slash
|
|
15
15
|
* command via a shell-spawnable entry point
|
|
16
16
|
* (Claude Code MVP: `/compact`).
|
|
17
|
-
* - `ide-native` — peaks-
|
|
17
|
+
* - `ide-native` — peaks-loop writes the compact intent to
|
|
18
18
|
* the IDE's hook file (per
|
|
19
19
|
* `IdeSettingsLocation`). Used when the IDE
|
|
20
20
|
* requires a registered hook rather than a
|
|
21
21
|
* runtime command.
|
|
22
|
-
* - `llm-self-compress` — peaks-
|
|
22
|
+
* - `llm-self-compress` — peaks-loop records the intent and
|
|
23
23
|
* returns `ok: true` with `pathway` echoed.
|
|
24
24
|
* The LLM does its own context summarization
|
|
25
25
|
* on the next turn. Always available; least
|
|
26
26
|
* precise fallback.
|
|
27
|
-
* - `noop` — adapter explicitly opted out. peaks-
|
|
27
|
+
* - `noop` — adapter explicitly opted out. peaks-loop
|
|
28
28
|
* returns `ok: false` with `message: 'noop'`.
|
|
29
29
|
* Used by legacy / unverified adapters.
|
|
30
30
|
*/
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-compact shared types (v2.13.0 AC-1..AC-4).
|
|
3
3
|
*
|
|
4
|
-
* Two-tier threshold model — peaks-
|
|
4
|
+
* Two-tier threshold model — peaks-loop is project-aware and the LLM
|
|
5
5
|
* is the decision-maker:
|
|
6
6
|
*
|
|
7
7
|
* - 50% soft warn — log a one-line info row; continue.
|
|
8
|
-
* - 85% pre-compact zone — peaks-
|
|
8
|
+
* - 85% pre-compact zone — peaks-loop prepares the convergence
|
|
9
9
|
* toolkit (checkpoint + convergence
|
|
10
10
|
* plan + auto-decisions log +
|
|
11
11
|
* IDE-compact dispatcher). The LLM
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* toolkit is "ready to use" so the
|
|
15
15
|
* LLM doesn't lose context to a
|
|
16
16
|
* last-second `/compact` panic.
|
|
17
|
-
* - 95% RED LINE — peaks-
|
|
17
|
+
* - 95% RED LINE — peaks-loop refuses to dispatch any
|
|
18
18
|
* further sub-agent and synchronously
|
|
19
19
|
* triggers IDE-side compact. At 95%+
|
|
20
20
|
* the context window is too tight to
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
*
|
|
26
26
|
* Why 0.85 / 0.95 split: the LLM uses the 0.85–0.95 zone to do
|
|
27
27
|
* intelligent convergence — wait for in-flight sub-agents, finish
|
|
28
|
-
* the current todo row, persist a checkpoint, then compact. peaks-
|
|
28
|
+
* the current todo row, persist a checkpoint, then compact. peaks-loop
|
|
29
29
|
* provides the toolkit; the LLM picks the moment. At 0.95 the window
|
|
30
|
-
* is gone and peaks-
|
|
30
|
+
* is gone and peaks-loop takes over synchronously to keep the runner
|
|
31
31
|
* alive.
|
|
32
32
|
*/
|
|
33
33
|
export declare const AUTO_COMPACT_SOFT_WARN_RATIO = 0.5;
|
|
@@ -49,7 +49,7 @@ export type CompactTrigger = {
|
|
|
49
49
|
message: string;
|
|
50
50
|
toolkitReady: true;
|
|
51
51
|
}
|
|
52
|
-
/** Red line (ratio ≥ 0.95): peaks-
|
|
52
|
+
/** Red line (ratio ≥ 0.95): peaks-loop forces synchronous compact; LLM cannot opt out. */
|
|
53
53
|
| {
|
|
54
54
|
kind: 'red-line';
|
|
55
55
|
ratio: number;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-compact shared types (v2.13.0 AC-1..AC-4).
|
|
3
3
|
*
|
|
4
|
-
* Two-tier threshold model — peaks-
|
|
4
|
+
* Two-tier threshold model — peaks-loop is project-aware and the LLM
|
|
5
5
|
* is the decision-maker:
|
|
6
6
|
*
|
|
7
7
|
* - 50% soft warn — log a one-line info row; continue.
|
|
8
|
-
* - 85% pre-compact zone — peaks-
|
|
8
|
+
* - 85% pre-compact zone — peaks-loop prepares the convergence
|
|
9
9
|
* toolkit (checkpoint + convergence
|
|
10
10
|
* plan + auto-decisions log +
|
|
11
11
|
* IDE-compact dispatcher). The LLM
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* toolkit is "ready to use" so the
|
|
15
15
|
* LLM doesn't lose context to a
|
|
16
16
|
* last-second `/compact` panic.
|
|
17
|
-
* - 95% RED LINE — peaks-
|
|
17
|
+
* - 95% RED LINE — peaks-loop refuses to dispatch any
|
|
18
18
|
* further sub-agent and synchronously
|
|
19
19
|
* triggers IDE-side compact. At 95%+
|
|
20
20
|
* the context window is too tight to
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
*
|
|
26
26
|
* Why 0.85 / 0.95 split: the LLM uses the 0.85–0.95 zone to do
|
|
27
27
|
* intelligent convergence — wait for in-flight sub-agents, finish
|
|
28
|
-
* the current todo row, persist a checkpoint, then compact. peaks-
|
|
28
|
+
* the current todo row, persist a checkpoint, then compact. peaks-loop
|
|
29
29
|
* provides the toolkit; the LLM picks the moment. At 0.95 the window
|
|
30
|
-
* is gone and peaks-
|
|
30
|
+
* is gone and peaks-loop takes over synchronously to keep the runner
|
|
31
31
|
* alive.
|
|
32
32
|
*/
|
|
33
33
|
export const AUTO_COMPACT_SOFT_WARN_RATIO = 0.5;
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*
|
|
16
16
|
* Why this exists:
|
|
17
17
|
* - Prior SKILL.md hardcoded `Task(subagent_type="general-purpose", ...)`
|
|
18
|
-
* which made peaks-
|
|
18
|
+
* which made peaks-loop depend on Claude Code's specific sub-agent
|
|
19
19
|
* tool name. Adding a new IDE (Trae, future Cursor, etc.) required
|
|
20
20
|
* editing every SKILL.md that mentioned sub-agent dispatch.
|
|
21
21
|
* - This file (plus the per-IDE adapter wiring) collapses all
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Slice 2026-06-24-test-tool-detection-injection.
|
|
3
3
|
*
|
|
4
4
|
* The Test Tool Detection block is prepended to every sub-agent prompt
|
|
5
|
-
* dispatched by peaks-
|
|
5
|
+
* dispatched by peaks-loop (both the single-dispatch chokepoint in
|
|
6
6
|
* `src/cli/commands/dispatch-commands.ts` and the DAG-dispatch chokepoint
|
|
7
7
|
* in `src/services/solo/dag-orchestrator.ts`). It tells the sub-agent
|
|
8
8
|
* to read `package.json#scripts.test` first and use the project-local
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Slice 2026-06-24-test-tool-detection-injection.
|
|
3
3
|
*
|
|
4
4
|
* The Test Tool Detection block is prepended to every sub-agent prompt
|
|
5
|
-
* dispatched by peaks-
|
|
5
|
+
* dispatched by peaks-loop (both the single-dispatch chokepoint in
|
|
6
6
|
* `src/cli/commands/dispatch-commands.ts` and the DAG-dispatch chokepoint
|
|
7
7
|
* in `src/services/solo/dag-orchestrator.ts`). It tells the sub-agent
|
|
8
8
|
* to read `package.json#scripts.test` first and use the project-local
|
|
@@ -46,7 +46,7 @@ export type WorkspaceLayoutInspection = {
|
|
|
46
46
|
export type WorkspaceLayoutProbe = () => WorkspaceLayoutInspection;
|
|
47
47
|
/**
|
|
48
48
|
* 2026-06-10 — `gateguard-fact-force` (a third-party PreToolUse hook,
|
|
49
|
-
* NOT peaks-
|
|
49
|
+
* NOT peaks-loop) fires on Edit / Write and demands a 4-fact questionnaire
|
|
50
50
|
* before allowing the edit. When the LLM is in a peaks-qa flow and tries
|
|
51
51
|
* to update `.peaks/_runtime/<sid>/qa/requests/*.md` via the Edit/Write
|
|
52
52
|
* tool, the hook demands facts that are inapplicable to QA envelope
|
|
@@ -272,11 +272,11 @@ function findDestructiveApplyLines(section) {
|
|
|
272
272
|
return lines.filter((line) => DESTRUCTIVE_APPLY_PATTERNS.some((pattern) => pattern.test(line)));
|
|
273
273
|
}
|
|
274
274
|
// ---------------------------------------------------------------------------
|
|
275
|
-
// 2026-06-10 — gateguard-fact-force integration check (NOT a peaks-
|
|
275
|
+
// 2026-06-10 — gateguard-fact-force integration check (NOT a peaks-loop hook).
|
|
276
276
|
//
|
|
277
277
|
// The `gateguard-fact-force` hook is a third-party PreToolUse hook that
|
|
278
278
|
// fires on Edit / Write / MultiEdit and demands a 4-fact questionnaire
|
|
279
|
-
// before allowing the edit. It is unrelated to peaks-
|
|
279
|
+
// before allowing the edit. It is unrelated to peaks-loop, but when the
|
|
280
280
|
// LLM is in a peaks-qa flow and edits `.peaks/_runtime/<sid>/qa/requests/
|
|
281
281
|
// *.md`, the questionnaire demands facts that do not apply (no
|
|
282
282
|
// importers, no public API, no data files, user instruction already
|
|
@@ -293,7 +293,7 @@ const GATEGUARD_HOOK_NEEDLES = ['gateguard', 'fact-force', 'fact_force'];
|
|
|
293
293
|
/** Token the gateguard hook exposes for "skip these paths" — the check
|
|
294
294
|
* treats any match against `.peaks` (path or globs) as a routed
|
|
295
295
|
* configuration. We accept a few common spellings because the third-
|
|
296
|
-
* party hook's CLI surface is not part of peaks-
|
|
296
|
+
* party hook's CLI surface is not part of peaks-loop's contract. */
|
|
297
297
|
const GATEGUARD_PEAKS_SKIP_NEEDLES = [
|
|
298
298
|
'.peaks',
|
|
299
299
|
'peaks-skip',
|
|
@@ -603,7 +603,7 @@ export async function runDoctor(options = {}) {
|
|
|
603
603
|
checks.push({
|
|
604
604
|
id: 'statusline:runtime',
|
|
605
605
|
ok: true,
|
|
606
|
-
message: `peaks ${CLI_VERSION} (win32): if the statusLine shows nothing in git bash, verify \`peaks\` resolves on PATH in the shell Claude Code uses (run \`peaks -v\` there), reinstall globally with \`npm i -g peaks-
|
|
606
|
+
message: `peaks ${CLI_VERSION} (win32): if the statusLine shows nothing in git bash, verify \`peaks\` resolves on PATH in the shell Claude Code uses (run \`peaks -v\` there), reinstall globally with \`npm i -g peaks-loop@latest\` if the version is older than ${CLI_VERSION}, then re-run \`peaks statusline install\` and reload Claude Code`
|
|
607
607
|
});
|
|
608
608
|
}
|
|
609
609
|
else {
|
|
@@ -768,7 +768,7 @@ export async function runDoctor(options = {}) {
|
|
|
768
768
|
checks.push({
|
|
769
769
|
id: 'integration:gateguard-peaks-conflict',
|
|
770
770
|
ok: false,
|
|
771
|
-
message: `gateguard-fact-force PreToolUse hook is installed (${sources}, matcher: ${matchers}) with no .peaks/** skip pattern; every Edit/Write of a peaks-qa envelope (.peaks/_runtime/<sid>/qa/requests/*.md) will be intercepted and demand a 4-fact questionnaire that does not apply to QA templates. Workaround: set \`ECC_DISABLED_HOOKS=pre:edit-write:gateguard-fact-force\` for the session, OR add a paired PreToolUse entry whose matcher restricts the hook to non-.peaks paths. peaks-
|
|
771
|
+
message: `gateguard-fact-force PreToolUse hook is installed (${sources}, matcher: ${matchers}) with no .peaks/** skip pattern; every Edit/Write of a peaks-qa envelope (.peaks/_runtime/<sid>/qa/requests/*.md) will be intercepted and demand a 4-fact questionnaire that does not apply to QA templates. Workaround: set \`ECC_DISABLED_HOOKS=pre:edit-write:gateguard-fact-force\` for the session, OR add a paired PreToolUse entry whose matcher restricts the hook to non-.peaks paths. peaks-loop is NOT the source of this hook.`
|
|
772
772
|
});
|
|
773
773
|
}
|
|
774
774
|
}
|
|
@@ -6,7 +6,7 @@ import { resolve } from 'node:path';
|
|
|
6
6
|
* Background: the consumer-facing CLAUDE.md template (rendered by
|
|
7
7
|
* `peaks standards init` / `peaks standards update`) instructs the LLM
|
|
8
8
|
* to display a compact status header
|
|
9
|
-
* `Peaks-
|
|
9
|
+
* `Peaks-Loop Skill: <skill> | Peaks-Loop Gate: <gate> | Next: <one short action>`
|
|
10
10
|
* on every turn while a peaks skill is active. If the LLM forgets (e.g.
|
|
11
11
|
* because of context compaction or a fresh session), the user is left
|
|
12
12
|
* without an at-a-glance signal that peaks is orchestrating the work.
|
|
@@ -20,21 +20,21 @@ import { resolve } from 'node:path';
|
|
|
20
20
|
* - `active`: whether an active-skill marker was found on disk.
|
|
21
21
|
* - `skill?`: the active skill name, if any.
|
|
22
22
|
* - `markerFound`: whether the latest assistant message carries the
|
|
23
|
-
* expected `Peaks-
|
|
23
|
+
* expected `Peaks-Loop Skill:` / `Peaks-Loop Gate:`
|
|
24
24
|
* marker. Always `false` when `active` is `false`.
|
|
25
25
|
* - `warning?`: a human-readable warning emitted when the marker
|
|
26
26
|
* is missing while the presence is active.
|
|
27
27
|
*
|
|
28
28
|
* The function is pure: it does not write to disk, does not clear the
|
|
29
29
|
* presence file, and does not depend on `process.cwd()`. The caller is
|
|
30
|
-
* expected to provide the absolute project root (peaks-
|
|
30
|
+
* expected to provide the absolute project root (peaks-loop convention
|
|
31
31
|
* from the standards-commands family — see dev-preference rule
|
|
32
32
|
* `project-option-is-canonical-project-root-source`).
|
|
33
33
|
*/
|
|
34
34
|
const PRESENCE_CANONICAL_PATH = '.peaks/_runtime/active-skill.json';
|
|
35
35
|
const PRESENCE_LEGACY_PATH = '.peaks/.active-skill.json';
|
|
36
|
-
const MARKER_PRIMARY = 'Peaks-
|
|
37
|
-
const MARKER_SECONDARY = 'Peaks-
|
|
36
|
+
const MARKER_PRIMARY = 'Peaks-Loop Skill:';
|
|
37
|
+
const MARKER_SECONDARY = 'Peaks-Loop Gate:';
|
|
38
38
|
const SKILL_NAME_RE = /"skill"\s*:\s*"([^"\\]*(?:\\.[^"\\]*)*)"/;
|
|
39
39
|
export const PRESENCE_MARKER_WARNING = [
|
|
40
40
|
'Peaks skill context may have been lost from this conversation; please re-invoke /peaks-<skill>.'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { IdeAdapter } from '../ide-types.js';
|
|
2
2
|
/**
|
|
3
|
-
* Claude Code adapter —— peaks-
|
|
3
|
+
* Claude Code adapter —— peaks-loop 的"起源 IDE"。
|
|
4
4
|
*
|
|
5
5
|
* 该 adapter 从原 `src/services/skills/hooks-settings-service.ts` 提取,保持
|
|
6
6
|
* 字节级兼容:用户在 Claude Code 环境下跑 `peaks hooks install` 产出的
|
|
@@ -2,7 +2,7 @@ import { homedir } from 'node:os';
|
|
|
2
2
|
import { join, resolve } from 'node:path';
|
|
3
3
|
import { claudeCodeSubAgentDispatcher } from '../../dispatch/sub-agent-dispatcher.js';
|
|
4
4
|
/**
|
|
5
|
-
* Claude Code adapter —— peaks-
|
|
5
|
+
* Claude Code adapter —— peaks-loop 的"起源 IDE"。
|
|
6
6
|
*
|
|
7
7
|
* 该 adapter 从原 `src/services/skills/hooks-settings-service.ts` 提取,保持
|
|
8
8
|
* 字节级兼容:用户在 Claude Code 环境下跑 `peaks hooks install` 产出的
|
|
@@ -50,7 +50,7 @@ export const CLAUDE_CODE_ADAPTER = {
|
|
|
50
50
|
// v2.13.0 AC-1 + AC-3 MVP: Claude Code is the first IDE to fill
|
|
51
51
|
// the `compact` profile. Future adapters (trae / codex / cursor /
|
|
52
52
|
// qoder / tongyi-lingma / hermes / openclaw) follow the same
|
|
53
|
-
// shape — peaks-
|
|
53
|
+
// shape — peaks-loop reads the env-var and dispatches the
|
|
54
54
|
// command via `IdeAdapter.compact`, with zero hard-coded IDE
|
|
55
55
|
// names anywhere in the orchestrator. If your IDE exposes a
|
|
56
56
|
// context-percent env-var and a slash-style compact command,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { IdeAdapter } from '../ide-types.js';
|
|
2
2
|
/**
|
|
3
|
-
* Codex (OpenAI CLI IDE) adapter —— peaks-
|
|
3
|
+
* Codex (OpenAI CLI IDE) adapter —— peaks-loop 的第四个内置 IDE 适配器(slice #13, 2.4.0)。
|
|
4
4
|
*
|
|
5
5
|
* 不可消除的 per-IDE 字段(slice #1 锁定,same shape as trae-adapter.ts / cursor-adapter.ts):
|
|
6
6
|
* - settings.dirName = '.codex' : Codex 项目根下的配置目录
|
|
@@ -10,7 +10,7 @@ import type { IdeAdapter } from '../ide-types.js';
|
|
|
10
10
|
* - toolMatcher = 'shell' : Codex 的 shell command matcher
|
|
11
11
|
*
|
|
12
12
|
* Slice #13 status (2026-06-17, 2.4.0):
|
|
13
|
-
* - Adapter is the fourth built-in IDE in peaks-
|
|
13
|
+
* - Adapter is the fourth built-in IDE in peaks-loop after Claude Code (#1),
|
|
14
14
|
* Trae (#2), and Cursor (#12). It further confirms the slice #1 + slice #2
|
|
15
15
|
* architecture scales linearly: registering a new IDE is a one-entry fill
|
|
16
16
|
* of the slim `IdeAdapter` shape with no dispatch-chokepoint changes.
|
|
@@ -2,7 +2,7 @@ import { homedir } from 'node:os';
|
|
|
2
2
|
import { join, resolve } from 'node:path';
|
|
3
3
|
import { codexSubAgentDispatcher } from '../../dispatch/sub-agent-dispatcher.js';
|
|
4
4
|
/**
|
|
5
|
-
* Codex (OpenAI CLI IDE) adapter —— peaks-
|
|
5
|
+
* Codex (OpenAI CLI IDE) adapter —— peaks-loop 的第四个内置 IDE 适配器(slice #13, 2.4.0)。
|
|
6
6
|
*
|
|
7
7
|
* 不可消除的 per-IDE 字段(slice #1 锁定,same shape as trae-adapter.ts / cursor-adapter.ts):
|
|
8
8
|
* - settings.dirName = '.codex' : Codex 项目根下的配置目录
|
|
@@ -12,7 +12,7 @@ import { codexSubAgentDispatcher } from '../../dispatch/sub-agent-dispatcher.js'
|
|
|
12
12
|
* - toolMatcher = 'shell' : Codex 的 shell command matcher
|
|
13
13
|
*
|
|
14
14
|
* Slice #13 status (2026-06-17, 2.4.0):
|
|
15
|
-
* - Adapter is the fourth built-in IDE in peaks-
|
|
15
|
+
* - Adapter is the fourth built-in IDE in peaks-loop after Claude Code (#1),
|
|
16
16
|
* Trae (#2), and Cursor (#12). It further confirms the slice #1 + slice #2
|
|
17
17
|
* architecture scales linearly: registering a new IDE is a one-entry fill
|
|
18
18
|
* of the slim `IdeAdapter` shape with no dispatch-chokepoint changes.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { IdeAdapter } from '../ide-types.js';
|
|
2
2
|
/**
|
|
3
|
-
* Cursor IDE adapter —— peaks-
|
|
3
|
+
* Cursor IDE adapter —— peaks-loop 的第三个内置 IDE 适配器(slice #12, 2.4.0)。
|
|
4
4
|
*
|
|
5
5
|
* 不可消除的 per-IDE 字段(slice #1 锁定,same shape as trae-adapter.ts):
|
|
6
6
|
* - settings.dirName = '.cursor' : Cursor 项目根下的配置目录
|
|
@@ -10,7 +10,7 @@ import type { IdeAdapter } from '../ide-types.js';
|
|
|
10
10
|
* - toolMatcher = 'Bash' : Cursor 的 shell execution tool matcher
|
|
11
11
|
*
|
|
12
12
|
* Slice #12 status (2026-06-17, 2.4.0):
|
|
13
|
-
* - Adapter is the third built-in IDE in peaks-
|
|
13
|
+
* - Adapter is the third built-in IDE in peaks-loop after Claude Code (#1) and Trae (#2).
|
|
14
14
|
* - Confirms the slice #1 + slice #2 architecture scales linearly: registering
|
|
15
15
|
* a new IDE is genuinely a one-entry fill of the slim `IdeAdapter` shape.
|
|
16
16
|
* - 2 UNVERIFIED fields: `envVar` (Cursor's `CURSOR_PROJECT_DIR` is the
|
|
@@ -2,7 +2,7 @@ import { homedir } from 'node:os';
|
|
|
2
2
|
import { join, resolve } from 'node:path';
|
|
3
3
|
import { cursorSubAgentDispatcher } from '../../dispatch/sub-agent-dispatcher.js';
|
|
4
4
|
/**
|
|
5
|
-
* Cursor IDE adapter —— peaks-
|
|
5
|
+
* Cursor IDE adapter —— peaks-loop 的第三个内置 IDE 适配器(slice #12, 2.4.0)。
|
|
6
6
|
*
|
|
7
7
|
* 不可消除的 per-IDE 字段(slice #1 锁定,same shape as trae-adapter.ts):
|
|
8
8
|
* - settings.dirName = '.cursor' : Cursor 项目根下的配置目录
|
|
@@ -12,7 +12,7 @@ import { cursorSubAgentDispatcher } from '../../dispatch/sub-agent-dispatcher.js
|
|
|
12
12
|
* - toolMatcher = 'Bash' : Cursor 的 shell execution tool matcher
|
|
13
13
|
*
|
|
14
14
|
* Slice #12 status (2026-06-17, 2.4.0):
|
|
15
|
-
* - Adapter is the third built-in IDE in peaks-
|
|
15
|
+
* - Adapter is the third built-in IDE in peaks-loop after Claude Code (#1) and Trae (#2).
|
|
16
16
|
* - Confirms the slice #1 + slice #2 architecture scales linearly: registering
|
|
17
17
|
* a new IDE is genuinely a one-entry fill of the slim `IdeAdapter` shape.
|
|
18
18
|
* - 2 UNVERIFIED fields: `envVar` (Cursor's `CURSOR_PROJECT_DIR` is the
|
|
@@ -2,7 +2,7 @@ import { homedir } from 'node:os';
|
|
|
2
2
|
import { join, resolve } from 'node:path';
|
|
3
3
|
import { traeSubAgentDispatcher } from '../../dispatch/sub-agent-dispatcher.js';
|
|
4
4
|
/**
|
|
5
|
-
* Trae IDE adapter —— peaks-
|
|
5
|
+
* Trae IDE adapter —— peaks-loop 的第二个内置 IDE 适配器。
|
|
6
6
|
*
|
|
7
7
|
* 不可消除的 per-IDE 字段(slice #1 锁定):
|
|
8
8
|
* - settings.dirName = '.trae' : Trae 项目根下的配置目录
|