peaks-loop 4.1.2 → 4.1.3
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 +136 -47
- package/CHANGELOG.md +56 -0
- package/README-en.md +1 -1
- package/README.md +1 -1
- package/contracts/readonly-argv-whitelist.json +211 -0
- package/dist/cli/commands/audit-artifact-runners.d.ts +16 -0
- package/dist/cli/commands/audit-artifact-runners.js +170 -0
- package/dist/cli/commands/audit-command-shared.d.ts +97 -0
- package/dist/cli/commands/audit-command-shared.js +60 -0
- package/dist/cli/commands/audit-commands.d.ts +7 -31
- package/dist/cli/commands/audit-commands.js +64 -473
- package/dist/cli/commands/audit-goal-runners.d.ts +17 -0
- package/dist/cli/commands/audit-goal-runners.js +114 -0
- package/dist/cli/commands/audit-red-lines-runners.d.ts +11 -0
- package/dist/cli/commands/audit-red-lines-runners.js +43 -0
- package/dist/cli/commands/audit-refusal-data.d.ts +23 -0
- package/dist/cli/commands/audit-refusal-data.js +69 -0
- package/dist/cli/commands/audit-static-runners.d.ts +13 -0
- package/dist/cli/commands/audit-static-runners.js +139 -0
- package/dist/cli/commands/await-runners.d.ts +11 -0
- package/dist/cli/commands/await-runners.js +148 -0
- package/dist/cli/commands/code-auto-compact-command.d.ts +3 -0
- package/dist/cli/commands/code-auto-compact-command.js +124 -0
- package/dist/cli/commands/code-auto-compact-envelope.d.ts +22 -0
- package/dist/cli/commands/code-auto-compact-envelope.js +39 -0
- package/dist/cli/commands/code-context-audit-command.d.ts +3 -0
- package/dist/cli/commands/code-context-audit-command.js +68 -0
- package/dist/cli/commands/code-context-now-command.d.ts +3 -0
- package/dist/cli/commands/code-context-now-command.js +124 -0
- package/dist/cli/commands/code-context-now-envelope.d.ts +66 -0
- package/dist/cli/commands/code-context-now-envelope.js +136 -0
- package/dist/cli/commands/code-context-now-mapping.d.ts +27 -0
- package/dist/cli/commands/code-context-now-mapping.js +43 -0
- package/dist/cli/commands/code-emit-handoff-command.d.ts +3 -0
- package/dist/cli/commands/code-emit-handoff-command.js +99 -0
- package/dist/cli/commands/code-gate-step-08-command.d.ts +3 -0
- package/dist/cli/commands/code-gate-step-08-command.js +139 -0
- package/dist/cli/commands/code-post-compact-detect-command.d.ts +3 -0
- package/dist/cli/commands/code-post-compact-detect-command.js +50 -0
- package/dist/cli/commands/code-runtime-commands.d.ts +9 -43
- package/dist/cli/commands/code-runtime-commands.js +20 -672
- package/dist/cli/commands/code-runtime-session.d.ts +1 -0
- package/dist/cli/commands/code-runtime-session.js +15 -0
- package/dist/cli/commands/compact-command.d.ts +6 -2
- package/dist/cli/commands/compact-command.js +12 -559
- package/dist/cli/commands/compact-dry-run-command.d.ts +3 -0
- package/dist/cli/commands/compact-dry-run-command.js +87 -0
- package/dist/cli/commands/compact-force-command.d.ts +3 -0
- package/dist/cli/commands/compact-force-command.js +98 -0
- package/dist/cli/commands/compact-harness-window-command.d.ts +3 -0
- package/dist/cli/commands/compact-harness-window-command.js +174 -0
- package/dist/cli/commands/compact-history-command.d.ts +3 -0
- package/dist/cli/commands/compact-history-command.js +89 -0
- package/dist/cli/commands/compact-read-commands.d.ts +3 -0
- package/dist/cli/commands/compact-read-commands.js +123 -0
- package/dist/cli/commands/compact-settle-command.d.ts +3 -0
- package/dist/cli/commands/compact-settle-command.js +130 -0
- package/dist/cli/commands/compact-shared.d.ts +9 -0
- package/dist/cli/commands/compact-shared.js +26 -0
- package/dist/cli/commands/core/skill-command.d.ts +1 -44
- package/dist/cli/commands/core/skill-command.js +13 -541
- package/dist/cli/commands/core/skill-context-verdict.d.ts +38 -0
- package/dist/cli/commands/core/skill-context-verdict.js +63 -0
- package/dist/cli/commands/core/skill-generated-config-notice.d.ts +41 -0
- package/dist/cli/commands/core/skill-generated-config-notice.js +75 -0
- package/dist/cli/commands/core/skill-heartbeat-commands.d.ts +3 -0
- package/dist/cli/commands/core/skill-heartbeat-commands.js +50 -0
- package/dist/cli/commands/core/skill-presence-commands.d.ts +3 -0
- package/dist/cli/commands/core/skill-presence-commands.js +123 -0
- package/dist/cli/commands/core/skill-presence-housekeeping-commands.d.ts +3 -0
- package/dist/cli/commands/core/skill-presence-housekeeping-commands.js +165 -0
- package/dist/cli/commands/core/skill-registry-commands.d.ts +3 -0
- package/dist/cli/commands/core/skill-registry-commands.js +117 -0
- package/dist/cli/commands/core/skill-runbook-command.d.ts +3 -0
- package/dist/cli/commands/core/skill-runbook-command.js +29 -0
- package/dist/cli/commands/dispatch-command-spec.d.ts +2 -0
- package/dist/cli/commands/dispatch-command-spec.js +62 -0
- package/dist/cli/commands/dispatch-commands.js +159 -775
- package/dist/cli/commands/dispatch-detached-branch.d.ts +3 -0
- package/dist/cli/commands/dispatch-detached-branch.js +58 -0
- package/dist/cli/commands/dispatch-envelope.d.ts +36 -0
- package/dist/cli/commands/dispatch-envelope.js +104 -0
- package/dist/cli/commands/dispatch-isolation-lease.d.ts +17 -0
- package/dist/cli/commands/dispatch-isolation-lease.js +149 -0
- package/dist/cli/commands/dispatch-preflight.d.ts +7 -0
- package/dist/cli/commands/dispatch-preflight.js +105 -0
- package/dist/cli/commands/dispatch-prompt-blocks.d.ts +10 -0
- package/dist/cli/commands/dispatch-prompt-blocks.js +56 -0
- package/dist/cli/commands/dispatch-prompt-composition.d.ts +30 -0
- package/dist/cli/commands/dispatch-prompt-composition.js +171 -0
- package/dist/cli/commands/dispatch-record-write.d.ts +24 -0
- package/dist/cli/commands/dispatch-record-write.js +96 -0
- package/dist/cli/commands/dispatch-tool-call.d.ts +15 -0
- package/dist/cli/commands/dispatch-tool-call.js +128 -0
- package/dist/cli/commands/evolution-command-shared.d.ts +78 -0
- package/dist/cli/commands/evolution-command-shared.js +107 -0
- package/dist/cli/commands/evolution-commands.d.ts +11 -1
- package/dist/cli/commands/evolution-commands.js +19 -350
- package/dist/cli/commands/evolution-evaluate-command.d.ts +24 -0
- package/dist/cli/commands/evolution-evaluate-command.js +138 -0
- package/dist/cli/commands/evolution-propose-command.d.ts +23 -0
- package/dist/cli/commands/evolution-propose-command.js +145 -0
- package/dist/cli/commands/evolution-status-command.d.ts +17 -0
- package/dist/cli/commands/evolution-status-command.js +41 -0
- package/dist/cli/commands/evolution-verdict-commands.d.ts +30 -0
- package/dist/cli/commands/evolution-verdict-commands.js +100 -0
- package/dist/cli/commands/finalize-accumulator.d.ts +44 -0
- package/dist/cli/commands/finalize-accumulator.js +55 -0
- package/dist/cli/commands/finalize-branches.d.ts +34 -0
- package/dist/cli/commands/finalize-branches.js +119 -0
- package/dist/cli/commands/finalize-runners.d.ts +3 -0
- package/dist/cli/commands/finalize-runners.js +92 -0
- package/dist/cli/commands/finalize-selection.d.ts +65 -0
- package/dist/cli/commands/finalize-selection.js +35 -0
- package/dist/cli/commands/gate-commands.js +26 -8
- package/dist/cli/commands/job-checkpoint-commands.d.ts +3 -0
- package/dist/cli/commands/job-checkpoint-commands.js +157 -0
- package/dist/cli/commands/job-command-shared.d.ts +109 -0
- package/dist/cli/commands/job-command-shared.js +72 -0
- package/dist/cli/commands/job-commands.d.ts +4 -64
- package/dist/cli/commands/job-commands.js +42 -552
- package/dist/cli/commands/job-cost-check-command.d.ts +3 -0
- package/dist/cli/commands/job-cost-check-command.js +41 -0
- package/dist/cli/commands/job-init-status-commands.d.ts +3 -0
- package/dist/cli/commands/job-init-status-commands.js +149 -0
- package/dist/cli/commands/job-run-commands.d.ts +3 -0
- package/dist/cli/commands/job-run-commands.js +97 -0
- package/dist/cli/commands/job-state-root.d.ts +35 -0
- package/dist/cli/commands/job-state-root.js +76 -0
- package/dist/cli/commands/loop-eval-capture-index.d.ts +4 -0
- package/dist/cli/commands/loop-eval-capture-index.js +44 -0
- package/dist/cli/commands/loop-eval-commands.d.ts +8 -5
- package/dist/cli/commands/loop-eval-commands.js +12 -626
- package/dist/cli/commands/loop-eval-eval-command.d.ts +3 -0
- package/dist/cli/commands/loop-eval-eval-command.js +168 -0
- package/dist/cli/commands/loop-eval-monotonic-command.d.ts +3 -0
- package/dist/cli/commands/loop-eval-monotonic-command.js +90 -0
- package/dist/cli/commands/loop-eval-parents.d.ts +7 -0
- package/dist/cli/commands/loop-eval-parents.js +20 -0
- package/dist/cli/commands/loop-eval-run-code.d.ts +7 -0
- package/dist/cli/commands/loop-eval-run-code.js +40 -0
- package/dist/cli/commands/loop-eval-run-command.d.ts +3 -0
- package/dist/cli/commands/loop-eval-run-command.js +113 -0
- package/dist/cli/commands/loop-eval-spec-commands.d.ts +3 -0
- package/dist/cli/commands/loop-eval-spec-commands.js +165 -0
- package/dist/cli/commands/loop-eval-spec-lint-command.d.ts +3 -0
- package/dist/cli/commands/loop-eval-spec-lint-command.js +42 -0
- package/dist/cli/commands/loop-eval-workflow-commands.d.ts +3 -0
- package/dist/cli/commands/loop-eval-workflow-commands.js +141 -0
- package/dist/cli/commands/mcp-commands.d.ts +10 -0
- package/dist/cli/commands/mcp-commands.js +157 -0
- package/dist/cli/commands/request-command-options.d.ts +49 -0
- package/dist/cli/commands/request-command-options.js +1 -0
- package/dist/cli/commands/request-commands.d.ts +3 -9
- package/dist/cli/commands/request-commands.js +17 -522
- package/dist/cli/commands/request-init-command.d.ts +3 -0
- package/dist/cli/commands/request-init-command.js +100 -0
- package/dist/cli/commands/request-lint-command.d.ts +3 -0
- package/dist/cli/commands/request-lint-command.js +50 -0
- package/dist/cli/commands/request-list-command.d.ts +10 -0
- package/dist/cli/commands/request-list-command.js +53 -0
- package/dist/cli/commands/request-repair-status-command.d.ts +3 -0
- package/dist/cli/commands/request-repair-status-command.js +61 -0
- package/dist/cli/commands/request-show-command.d.ts +3 -0
- package/dist/cli/commands/request-show-command.js +56 -0
- package/dist/cli/commands/request-transition-command.d.ts +3 -0
- package/dist/cli/commands/request-transition-command.js +122 -0
- package/dist/cli/commands/request-transition-failures.d.ts +8 -0
- package/dist/cli/commands/request-transition-failures.js +90 -0
- package/dist/cli/commands/request-transition-hooks.d.ts +50 -0
- package/dist/cli/commands/request-transition-hooks.js +115 -0
- package/dist/cli/commands/request-transition-preflight.d.ts +10 -0
- package/dist/cli/commands/request-transition-preflight.js +107 -0
- package/dist/cli/commands/scan-command-shared.d.ts +96 -0
- package/dist/cli/commands/scan-command-shared.js +83 -0
- package/dist/cli/commands/scan-commands.d.ts +3 -2
- package/dist/cli/commands/scan-commands.js +23 -463
- package/dist/cli/commands/scan-inventory-commands.d.ts +3 -0
- package/dist/cli/commands/scan-inventory-commands.js +96 -0
- package/dist/cli/commands/scan-project-commands.d.ts +3 -0
- package/dist/cli/commands/scan-project-commands.js +65 -0
- package/dist/cli/commands/scan-scope-commands.d.ts +3 -0
- package/dist/cli/commands/scan-scope-commands.js +149 -0
- package/dist/cli/commands/scan-scope-helpers.d.ts +8 -0
- package/dist/cli/commands/scan-scope-helpers.js +54 -0
- package/dist/cli/commands/scan-structural-commands.d.ts +3 -0
- package/dist/cli/commands/scan-structural-commands.js +113 -0
- package/dist/cli/commands/share-commands.d.ts +12 -68
- package/dist/cli/commands/share-commands.js +47 -556
- package/dist/cli/commands/share-error-hints.d.ts +14 -0
- package/dist/cli/commands/share-error-hints.js +38 -0
- package/dist/cli/commands/share-identity.d.ts +13 -0
- package/dist/cli/commands/share-identity.js +22 -0
- package/dist/cli/commands/share-record-paths.d.ts +37 -0
- package/dist/cli/commands/share-record-paths.js +68 -0
- package/dist/cli/commands/share-runners.d.ts +3 -0
- package/dist/cli/commands/share-runners.js +158 -0
- package/dist/cli/commands/shared-read-runners.d.ts +3 -0
- package/dist/cli/commands/shared-read-runners.js +51 -0
- package/dist/cli/commands/slice-check-command.d.ts +3 -0
- package/dist/cli/commands/slice-check-command.js +54 -0
- package/dist/cli/commands/slice-commands.d.ts +2 -22
- package/dist/cli/commands/slice-commands.js +18 -517
- package/dist/cli/commands/slice-decompose-artifacts.d.ts +18 -0
- package/dist/cli/commands/slice-decompose-artifacts.js +79 -0
- package/dist/cli/commands/slice-decompose-command.d.ts +3 -0
- package/dist/cli/commands/slice-decompose-command.js +123 -0
- package/dist/cli/commands/slice-list-commands.d.ts +3 -0
- package/dist/cli/commands/slice-list-commands.js +182 -0
- package/dist/cli/commands/slice-pick-command.d.ts +3 -0
- package/dist/cli/commands/slice-pick-command.js +60 -0
- package/dist/cli/commands/slice-plan-command.d.ts +24 -0
- package/dist/cli/commands/slice-plan-command.js +111 -0
- package/dist/cli/commands/workflow-commands.d.ts +10 -1
- package/dist/cli/commands/workflow-commands.js +6 -594
- package/dist/cli/commands/workflow-gate-commands.d.ts +3 -0
- package/dist/cli/commands/workflow-gate-commands.js +116 -0
- package/dist/cli/commands/workflow-plan-helpers.d.ts +48 -0
- package/dist/cli/commands/workflow-plan-helpers.js +103 -0
- package/dist/cli/commands/workflow-planning-commands.d.ts +3 -0
- package/dist/cli/commands/workflow-planning-commands.js +56 -0
- package/dist/cli/commands/workflow-swarm-actions.d.ts +7 -0
- package/dist/cli/commands/workflow-swarm-actions.js +109 -0
- package/dist/cli/commands/workflow-swarm-commands.d.ts +3 -0
- package/dist/cli/commands/workflow-swarm-commands.js +138 -0
- package/dist/cli/commands/workflow-tech-actions.d.ts +10 -0
- package/dist/cli/commands/workflow-tech-actions.js +150 -0
- package/dist/cli/commands/workspace/init-actions.d.ts +10 -0
- package/dist/cli/commands/workspace/init-actions.js +199 -0
- package/dist/cli/commands/workspace/init-codegraph-stake.d.ts +10 -0
- package/dist/cli/commands/workspace/init-codegraph-stake.js +54 -0
- package/dist/cli/commands/workspace/init-command.d.ts +8 -124
- package/dist/cli/commands/workspace/init-command.js +59 -623
- package/dist/cli/commands/workspace/init-context.d.ts +58 -0
- package/dist/cli/commands/workspace/init-context.js +121 -0
- package/dist/cli/commands/workspace/init-envelope.d.ts +3 -0
- package/dist/cli/commands/workspace/init-envelope.js +34 -0
- package/dist/cli/commands/workspace/init-failures.d.ts +3 -0
- package/dist/cli/commands/workspace/init-failures.js +84 -0
- package/dist/cli/commands/workspace/init-hooks-decision.d.ts +24 -0
- package/dist/cli/commands/workspace/init-hooks-decision.js +189 -0
- package/dist/cli/commands/workspace/init-options.d.ts +102 -0
- package/dist/cli/commands/workspace/init-options.js +1 -0
- package/dist/cli/commands/worktree-lease-commands.d.ts +10 -6
- package/dist/cli/commands/worktree-lease-commands.js +42 -512
- package/dist/cli/commands/worktree-lease-gc-command.d.ts +12 -0
- package/dist/cli/commands/worktree-lease-gc-command.js +117 -0
- package/dist/cli/commands/worktree-lease-git.d.ts +22 -0
- package/dist/cli/commands/worktree-lease-git.js +48 -0
- package/dist/cli/commands/worktree-lease-list-command.d.ts +12 -0
- package/dist/cli/commands/worktree-lease-list-command.js +100 -0
- package/dist/cli/commands/worktree-lease-load.d.ts +37 -0
- package/dist/cli/commands/worktree-lease-load.js +28 -0
- package/dist/cli/commands/worktree-lease-release-command.d.ts +13 -0
- package/dist/cli/commands/worktree-lease-release-command.js +105 -0
- package/dist/cli/commands/worktree-lease-renew-command.d.ts +11 -0
- package/dist/cli/commands/worktree-lease-renew-command.js +99 -0
- package/dist/cli/commands/worktree-lease-session.d.ts +22 -0
- package/dist/cli/commands/worktree-lease-session.js +29 -0
- package/dist/cli/commands/worktree-lease-spawn-command.d.ts +11 -0
- package/dist/cli/commands/worktree-lease-spawn-command.js +119 -0
- package/dist/cli/commands/worktree-lease-status-command.d.ts +11 -0
- package/dist/cli/commands/worktree-lease-status-command.js +86 -0
- package/dist/cli/commands/worktree-lease-store.d.ts +19 -0
- package/dist/cli/commands/worktree-lease-store.js +24 -0
- package/dist/cli/program.js +5 -0
- package/dist/services/distribution/mcp-install-runner.d.ts +21 -0
- package/dist/services/distribution/mcp-install-runner.js +59 -0
- package/dist/services/distribution/mcp-install.d.ts +95 -0
- package/dist/services/distribution/mcp-install.js +179 -0
- package/dist/services/distribution/plugin-manifest.d.ts +97 -0
- package/dist/services/distribution/plugin-manifest.js +126 -0
- package/dist/services/hooks/mcp-surface-gate.d.ts +19 -0
- package/dist/services/hooks/mcp-surface-gate.js +87 -0
- package/dist/services/ide/adapters/claude-code-adapter.d.ts +4 -35
- package/dist/services/ide/adapters/claude-code-adapter.js +48 -171
- package/dist/services/ide/adapters/claude-code-local-state.d.ts +28 -0
- package/dist/services/ide/adapters/claude-code-local-state.js +112 -0
- package/dist/services/ide/adapters/claude-code-model-window.d.ts +37 -0
- package/dist/services/ide/adapters/claude-code-model-window.js +113 -0
- package/dist/services/ide/ide-mcp-install-types.d.ts +78 -0
- package/dist/services/ide/ide-mcp-install-types.js +104 -0
- package/dist/services/ide/ide-types.d.ts +45 -1
- package/dist/services/ide/mcp-tool-matcher.d.ts +34 -0
- package/dist/services/ide/mcp-tool-matcher.js +84 -0
- package/dist/services/lint/npx-resolver.js +7 -0
- package/dist/services/mcp/cli-executor.d.ts +36 -0
- package/dist/services/mcp/cli-executor.js +97 -0
- package/dist/services/mcp/json-rpc.d.ts +81 -0
- package/dist/services/mcp/json-rpc.js +116 -0
- package/dist/services/mcp/memory-tool.d.ts +3 -0
- package/dist/services/mcp/memory-tool.js +62 -0
- package/dist/services/mcp/server-main.d.ts +1 -0
- package/dist/services/mcp/server-main.js +66 -0
- package/dist/services/mcp/server.d.ts +22 -0
- package/dist/services/mcp/server.js +152 -0
- package/dist/services/mcp/surface.d.ts +62 -0
- package/dist/services/mcp/surface.js +198 -0
- package/dist/services/mcp/tool-core.d.ts +42 -0
- package/dist/services/mcp/tool-core.js +137 -0
- package/dist/services/mcp/tools.d.ts +13 -0
- package/dist/services/mcp/tools.js +58 -0
- package/dist/services/readonly-surface/argv-guard.d.ts +32 -0
- package/dist/services/readonly-surface/argv-guard.js +164 -0
- package/dist/services/readonly-surface/readonly-whitelist.d.ts +147 -0
- package/dist/services/readonly-surface/readonly-whitelist.js +107 -0
- package/dist/services/readonly-surface/whitelist-generator.d.ts +64 -0
- package/dist/services/readonly-surface/whitelist-generator.js +212 -0
- package/dist/services/skills/hooks-codegate-superpowers.d.ts +1 -0
- package/dist/services/skills/hooks-codegate-superpowers.js +26 -0
- package/dist/services/skills/hooks-settings-service.js +10 -2
- package/package.json +17 -6
- package/scripts/install-skills-bundles.mjs +233 -0
- package/scripts/install-skills-fs.mjs +148 -0
- package/scripts/install-skills-ide.mjs +279 -0
- package/scripts/install-skills-output-style-default.mjs +196 -0
- package/scripts/install-skills-output-styles.mjs +121 -0
- package/scripts/install-skills-report.mjs +42 -0
- package/scripts/install-skills-user-config.mjs +198 -0
- package/scripts/install-skills.mjs +36 -1066
- package/scripts/watch-tree.mjs +140 -0
- package/scripts/watch.mjs +4 -126
- package/skills/peaks-status/SKILL.md +31 -13
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { addJsonOption, getErrorMessage, printResult } from '../cli-helpers.js';
|
|
2
|
+
import { fail } from 'peaks-loop-shared/result';
|
|
3
|
+
import { runAutoCompact } from '../../services/code/auto-compact-orchestrator.js';
|
|
4
|
+
import { probeInFlightBatch } from '../../services/workflow/workflow-inflight-probe.js';
|
|
5
|
+
import { readActiveSid } from './code-runtime-session.js';
|
|
6
|
+
import { buildAutoCompactEnvelope } from './code-auto-compact-envelope.js';
|
|
7
|
+
const AUTO_COMPACT_DESCRIPTION = 'v2.13.0 AC-4: zero-human-intervention auto-compact. Probes current ' +
|
|
8
|
+
'context-fill % via the active IDE adapter; ≥ 0.85 writes a pre-compact ' +
|
|
9
|
+
'checkpoint + convergence plan + auto-decisions log; ≥ 0.95 ASKS the ' +
|
|
10
|
+
'harness to compact and reports that it is waiting for it — no ratio ' +
|
|
11
|
+
'blocks sub-agent dispatch, because peaks-loop has no way to compact a ' +
|
|
12
|
+
'running session and a gate nobody can satisfy gates nothing. The LLM / ' +
|
|
13
|
+
'runner keeps working at any ratio without human intervention. Pair with `peaks code ' +
|
|
14
|
+
'context-now` (AC-1), the read-only probe that reports the ratio this ' +
|
|
15
|
+
'command acts on. This command is also fired by the installed ' +
|
|
16
|
+
'PreToolUse hook, which passes `--project .` — without that argument ' +
|
|
17
|
+
'the hook could never run at all. rid-027 ' +
|
|
18
|
+
'adds `--mode <mode>`: `standard` (0.85/0.95) or `partial` (0.70/0.85 ' +
|
|
19
|
+
'for 24h long-run mode).';
|
|
20
|
+
/** The invalid-`--mode` branch, lifted verbatim out of the action body. */
|
|
21
|
+
function reportInvalidAutoCompactMode(io, modeName, json) {
|
|
22
|
+
printResult(io, fail('code.auto-compact', 'AUTO_COMPACT_INVALID_MODE', `Invalid --mode '${modeName}'. Valid values: standard | partial.`, null, ['Re-run with --mode standard or --mode partial.']), json);
|
|
23
|
+
process.exitCode = 1;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The `runAutoCompact` input object, lifted verbatim: it reads only its two
|
|
27
|
+
* parameters, so it has no ordering dependency on the call site.
|
|
28
|
+
*/
|
|
29
|
+
function buildAutoCompactInput(opts, modeName) {
|
|
30
|
+
// Slice 4.0.8 (D4d): production `inFlightBatch` MUST come from
|
|
31
|
+
// the workflow graph probe. The legacy `--in-flight-batch`
|
|
32
|
+
// boolean CLI flag is a TEST-ONLY seam (gated by
|
|
33
|
+
// `PEAKS_TEST_SEAM === '1'`). When the env flag is unset
|
|
34
|
+
// (the production case), we wire `probeInflightBatch` to the
|
|
35
|
+
// canonical `workflow-inflight-probe.ts` service so the
|
|
36
|
+
// production decision is graph-backed, not lease-age.
|
|
37
|
+
const isTestSeam = process.env.PEAKS_TEST_SEAM === '1';
|
|
38
|
+
return {
|
|
39
|
+
projectRoot: opts.project,
|
|
40
|
+
sessionId: opts.sessionId ?? readActiveSid(opts.project) ?? undefined,
|
|
41
|
+
...(isTestSeam && opts.inFlightBatch === true
|
|
42
|
+
? { inFlightBatch: { hasInFlightBatch: true } }
|
|
43
|
+
: {}),
|
|
44
|
+
...(!isTestSeam
|
|
45
|
+
? {
|
|
46
|
+
probeInflightBatch: () => {
|
|
47
|
+
// Synchronous probe: the workflow-inflight-probe
|
|
48
|
+
// service is pure / synchronous (no I/O). The
|
|
49
|
+
// empty `graphs` array is the production CLI
|
|
50
|
+
// default — callers that want a richer fixture
|
|
51
|
+
// (e.g. `peaks session 24h-mode`) should hand-roll
|
|
52
|
+
// a probe and pass it via the orchestrator's
|
|
53
|
+
// input. When no graph is materialized, the
|
|
54
|
+
// probe returns `inFlightBatch: false`, matching
|
|
55
|
+
// the 4.0.7 zero-pause contract for stock
|
|
56
|
+
// projects.
|
|
57
|
+
const out = probeInFlightBatch({ now: new Date().toISOString(), graphs: [] });
|
|
58
|
+
return out.inFlightBatch === true;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
: {}),
|
|
62
|
+
force: opts.force === true,
|
|
63
|
+
bypassRedLine: opts.bypassRedLine === true,
|
|
64
|
+
// Forward the FLAG verbatim — `undefined` when the user named no
|
|
65
|
+
// mode — so the orchestrator's fallback to the presence-derived
|
|
66
|
+
// mode can actually run. Forwarding the validated `modeName` is
|
|
67
|
+
// what disabled 24h → partial.
|
|
68
|
+
mode: opts.mode === undefined ? undefined : modeName
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/** The catch branch, lifted verbatim out of the action body. */
|
|
72
|
+
function reportAutoCompactFailure(io, err, json) {
|
|
73
|
+
printResult(io, fail('code.auto-compact', 'AUTO_COMPACT_FAILED', getErrorMessage(err), null, [
|
|
74
|
+
'Verify the project path + session id and try again'
|
|
75
|
+
]), json);
|
|
76
|
+
process.exitCode = 1;
|
|
77
|
+
}
|
|
78
|
+
/** The action body, lifted to a module-level function so both it and the registrar fit in 50 lines. */
|
|
79
|
+
async function runAutoCompactAction(opts, io) {
|
|
80
|
+
try {
|
|
81
|
+
const { isValidMode } = await import('../../services/code/auto-compact-modes.js');
|
|
82
|
+
const modeName = opts.mode ?? 'standard';
|
|
83
|
+
if (!isValidMode(modeName)) {
|
|
84
|
+
reportInvalidAutoCompactMode(io, modeName, opts.json);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const result = await runAutoCompact(buildAutoCompactInput(opts, modeName));
|
|
88
|
+
const code = result.code;
|
|
89
|
+
const exitOk = result.ok || code === 'AUTO_COMPACT_SKIP' || code === 'AUTO_COMPACT_WAIT';
|
|
90
|
+
// Adapt AutoCompactResult → ResultEnvelope so printResult's
|
|
91
|
+
// generic accepts it. The orchestrator envelope carries
|
|
92
|
+
// `data` on success-path and `nextActions` on the error
|
|
93
|
+
// path; surface both directly to the user.
|
|
94
|
+
printResult(io, buildAutoCompactEnvelope(result), opts.json);
|
|
95
|
+
if (!exitOk)
|
|
96
|
+
process.exitCode = 1;
|
|
97
|
+
}
|
|
98
|
+
catch (err) {
|
|
99
|
+
reportAutoCompactFailure(io, err, opts.json);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
export function registerCodeAutoCompactCommand(code, io) {
|
|
103
|
+
addJsonOption(code
|
|
104
|
+
.command('auto-compact')
|
|
105
|
+
.description(AUTO_COMPACT_DESCRIPTION)
|
|
106
|
+
.requiredOption('--project <path>', 'target project root')
|
|
107
|
+
.option('--session-id <sid>', 'override session id (default: read from active presence)')
|
|
108
|
+
.option('--in-flight-batch', 'defer if a sub-agent batch is in flight (D6.e)')
|
|
109
|
+
.option('--force', 'force compact at any ratio (test seam)')
|
|
110
|
+
// Accepted and inert. There is no longer a 95% gate to skip: peaks-loop
|
|
111
|
+
// cannot compact a running session, so the red line never blocked
|
|
112
|
+
// dispatch and `bypassRedLine` is read by nothing (slice
|
|
113
|
+
// rather than deleted because it is a published CLI surface — deleting it
|
|
114
|
+
// would make an existing caller fail on an unknown option, which is a
|
|
115
|
+
// harder break than a no-op — and because the honest fix here is to stop
|
|
116
|
+
// advertising it, not to change its meaning.
|
|
117
|
+
.option('--bypass-red-line', 'no-op: the 95% red line no longer gates dispatch, so there is nothing to bypass (accepted for backward compatibility)')
|
|
118
|
+
// No commander default here, deliberately. A declared default makes
|
|
119
|
+
// `opts.mode` permanently defined, which defeats the orchestrator's
|
|
120
|
+
// `input.mode ?? resolveAutoCompactMode(projectRoot)` fallback and
|
|
121
|
+
// silently disables "24h mode auto-selects partial" — the help text
|
|
122
|
+
// below promises it. Absence must stay absent.
|
|
123
|
+
.option('--mode <mode>', 'auto-compact mode (standard | partial). Default: standard. 24h mode auto-selects partial.')).action((opts) => runAutoCompactAction(opts, io));
|
|
124
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type ResultEnvelope } from 'peaks-loop-shared/result';
|
|
2
|
+
import { type AutoCompactResult } from '../../services/code/auto-compact-orchestrator.js';
|
|
3
|
+
/**
|
|
4
|
+
* Adapt `runAutoCompact`'s domain result to a `ResultEnvelope`.
|
|
5
|
+
*
|
|
6
|
+
* Extracted and exported so the CHANNEL each fact chooses can be asserted
|
|
7
|
+
* directly, without a real red-line probe.
|
|
8
|
+
*
|
|
9
|
+
* The harness-window CONFLICT ("peaks-loop divided this ratio by N but the
|
|
10
|
+
* settings file pins M") is a fact about the STATE, not an instruction, so it
|
|
11
|
+
* rides `warnings` — the very channel `peaks code context-now` already puts it
|
|
12
|
+
* on, via the same `harnessWindowSyncWarning`. Before this, the shim hard-coded
|
|
13
|
+
* `warnings: []`, so the identical fact reached a consumer as a sentence inside
|
|
14
|
+
* `nextActions` on this command and as a `warnings` entry on the other one. One
|
|
15
|
+
* fact, two shapes, depending on which of the two syncing commands a consumer
|
|
16
|
+
* happened to read: two parsers for one mechanism.
|
|
17
|
+
*
|
|
18
|
+
* The prose description (`describeHarnessWindowSync`) stays in `nextActions` on
|
|
19
|
+
* BOTH commands — that half is advice ("what to do about it") and both already
|
|
20
|
+
* agree on it.
|
|
21
|
+
*/
|
|
22
|
+
export declare function buildAutoCompactEnvelope(result: AutoCompactResult): ResultEnvelope<unknown>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// The `peaks code auto-compact` result adapter, on its own so the CHANNEL each
|
|
2
|
+
// fact chooses can be asserted directly, without a real red-line probe.
|
|
3
|
+
import { fail, ok } from 'peaks-loop-shared/result';
|
|
4
|
+
import { harnessWindowSyncWarning } from '../../services/context/harness-window-config.js';
|
|
5
|
+
/**
|
|
6
|
+
* Adapt `runAutoCompact`'s domain result to a `ResultEnvelope`.
|
|
7
|
+
*
|
|
8
|
+
* Extracted and exported so the CHANNEL each fact chooses can be asserted
|
|
9
|
+
* directly, without a real red-line probe.
|
|
10
|
+
*
|
|
11
|
+
* The harness-window CONFLICT ("peaks-loop divided this ratio by N but the
|
|
12
|
+
* settings file pins M") is a fact about the STATE, not an instruction, so it
|
|
13
|
+
* rides `warnings` — the very channel `peaks code context-now` already puts it
|
|
14
|
+
* on, via the same `harnessWindowSyncWarning`. Before this, the shim hard-coded
|
|
15
|
+
* `warnings: []`, so the identical fact reached a consumer as a sentence inside
|
|
16
|
+
* `nextActions` on this command and as a `warnings` entry on the other one. One
|
|
17
|
+
* fact, two shapes, depending on which of the two syncing commands a consumer
|
|
18
|
+
* happened to read: two parsers for one mechanism.
|
|
19
|
+
*
|
|
20
|
+
* The prose description (`describeHarnessWindowSync`) stays in `nextActions` on
|
|
21
|
+
* BOTH commands — that half is advice ("what to do about it") and both already
|
|
22
|
+
* agree on it.
|
|
23
|
+
*/
|
|
24
|
+
export function buildAutoCompactEnvelope(result) {
|
|
25
|
+
const data = 'data' in result ? result.data : null;
|
|
26
|
+
const nextActions = 'nextActions' in result ? result.nextActions : [];
|
|
27
|
+
const warning = harnessWindowSyncWarning(data?.harnessWindow ?? null);
|
|
28
|
+
const warnings = warning === null ? [] : [warning];
|
|
29
|
+
if (result.ok) {
|
|
30
|
+
return ok('code.auto-compact', data ?? {}, warnings, [result.message, ...nextActions]);
|
|
31
|
+
}
|
|
32
|
+
// `fail()` hard-codes `warnings: []`, so the warning is spread back over it —
|
|
33
|
+
// a refused write can disagree with the ratio just as easily on the failure
|
|
34
|
+
// path, and the state does not become less true because the dispatch failed.
|
|
35
|
+
return {
|
|
36
|
+
...fail('code.auto-compact', result.code, result.message, data, [...nextActions]),
|
|
37
|
+
warnings
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { addJsonOption, getErrorMessage, printResult } from '../cli-helpers.js';
|
|
2
|
+
import { ok } from 'peaks-loop-shared/result';
|
|
3
|
+
import { auditContext } from '../../services/context/context-audit.js';
|
|
4
|
+
import { resolveOuterSessionId } from '../../services/session/binding-status-service.js';
|
|
5
|
+
import { readActiveSid } from './code-runtime-session.js';
|
|
6
|
+
const CONTEXT_AUDIT_DESCRIPTION = "Slice 2026-09-10 Slice A: report what fills the current session's " +
|
|
7
|
+
'context window, grouped by tool + short input key (command line / ' +
|
|
8
|
+
"path tail / pattern), sorted by bytes. Locates the CURRENT session's " +
|
|
9
|
+
"IDE transcript through the active adapter's " +
|
|
10
|
+
'`compact.resolveTranscriptPath` (vendor-neutral); emits total bytes, ' +
|
|
11
|
+
'entry count, and the top-N groups ' +
|
|
12
|
+
'(`{tool, key, bytes, pctOfTotal, count}`). Read-only and fail-soft — ' +
|
|
13
|
+
'a missing/oversized/corrupt transcript returns `available:false` ' +
|
|
14
|
+
'with a reason and never blocks. Never dumps tool result content.';
|
|
15
|
+
/** The catch branch, lifted verbatim out of the action body (fail-soft, exit code untouched). */
|
|
16
|
+
function reportContextAuditFailure(io, err, json) {
|
|
17
|
+
printResult(io, ok('code.context-audit', {
|
|
18
|
+
available: false,
|
|
19
|
+
reason: `audit-failed: ${getErrorMessage(err)}`,
|
|
20
|
+
transcriptPath: null,
|
|
21
|
+
totalBytes: 0,
|
|
22
|
+
entryCount: 0,
|
|
23
|
+
groupCount: 0,
|
|
24
|
+
topN: 0,
|
|
25
|
+
entries: []
|
|
26
|
+
}, [], ['context-audit is a read-only probe; continue without it.']), json);
|
|
27
|
+
}
|
|
28
|
+
/** The action body, lifted to a module-level function so both it and the registrar fit in 50 lines. */
|
|
29
|
+
function runCodeContextAudit(opts, io) {
|
|
30
|
+
try {
|
|
31
|
+
// `resolveOuterSessionId` checks the env signal FIRST, so the peaks
|
|
32
|
+
// session id is only a fallback lookup key — mirror context-now's
|
|
33
|
+
// 'unknown' default so an unbound presence still resolves via env.
|
|
34
|
+
const sessionId = opts.sessionId ?? readActiveSid(opts.project) ?? 'unknown';
|
|
35
|
+
const outerSessionId = resolveOuterSessionId(opts.project, sessionId);
|
|
36
|
+
const result = auditContext({
|
|
37
|
+
outerSessionId: outerSessionId ?? null,
|
|
38
|
+
...(opts.top !== undefined ? { topN: opts.top } : {}),
|
|
39
|
+
...(opts.transcript !== undefined ? { transcriptPath: opts.transcript } : {})
|
|
40
|
+
});
|
|
41
|
+
// Fail-soft contract: unavailability is DATA, not an error. The exit
|
|
42
|
+
// code stays 0 so a `context-audit` call can never block a workflow.
|
|
43
|
+
const nextActions = result.available
|
|
44
|
+
? [
|
|
45
|
+
`${result.entryCount} tool result(s) across ${result.groupCount} group(s); showing top ${result.entries.length}.`
|
|
46
|
+
]
|
|
47
|
+
: [
|
|
48
|
+
`context-audit unavailable: ${result.reason ?? 'unknown'} — continue without it (read-only probe).`
|
|
49
|
+
];
|
|
50
|
+
printResult(io, ok('code.context-audit', { ...result }, [], nextActions), opts.json);
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
reportContextAuditFailure(io, err, opts.json);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export function registerCodeContextAuditCommand(code, io) {
|
|
57
|
+
// WHAT fills the orchestrator window. `context-now` returns a ratio; this
|
|
58
|
+
// returns the grouped byte breakdown of tool results from the live
|
|
59
|
+
// transcript. Read-only + fail-soft: an unavailable transcript reports
|
|
60
|
+
// `available:false` with a reason and NEVER sets a non-zero exit code.
|
|
61
|
+
addJsonOption(code
|
|
62
|
+
.command('context-audit')
|
|
63
|
+
.description(CONTEXT_AUDIT_DESCRIPTION)
|
|
64
|
+
.requiredOption('--project <path>', 'target project root')
|
|
65
|
+
.option('--session-id <sid>', 'override session id (default: read from active presence)')
|
|
66
|
+
.option('--top <n>', 'number of top entries to emit (default 15, max 100)', (value) => Number(value))
|
|
67
|
+
.option('--transcript <path>', 'override the transcript jsonl path (test seam)')).action((opts) => runCodeContextAudit(opts, io));
|
|
68
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { addJsonOption, getErrorMessage, printResult } from '../cli-helpers.js';
|
|
2
|
+
import { fail, ok } from 'peaks-loop-shared/result';
|
|
3
|
+
import { readJobShapeDecision, JobShapeDecisionError } from '../../services/code/job-shape-decision.js';
|
|
4
|
+
import { resolveOuterSessionId } from '../../services/session/binding-status-service.js';
|
|
5
|
+
import { resolveCanonicalProjectRoot } from '../../services/config/config-service.js';
|
|
6
|
+
import { readActiveSid } from './code-runtime-session.js';
|
|
7
|
+
import { buildContextNowData, buildContextNowNextActions, buildContextNowWarnings, readContextNowHarness, resolveContextNowDecision } from './code-context-now-envelope.js';
|
|
8
|
+
const CONTEXT_NOW_DESCRIPTION = "v2.13.0 AC-1: read the active IDE adapter's context-fill % " +
|
|
9
|
+
'without requiring the LLM to pass --prompt-size <bytes> manually. ' +
|
|
10
|
+
'Adapter-driven (no hard-coded IDE names): Claude Code is the MVP ' +
|
|
11
|
+
'implementation; trae / codex / cursor / qoder / tongyi-lingma / ' +
|
|
12
|
+
'hermes / openclaw register their own env-var via IdeAdapter.compact. ' +
|
|
13
|
+
"v3.1.2 / 2026-09-12: the mode's pre-compact line emits " +
|
|
14
|
+
'action=auto-compact-now (MANDATORY, single-rid included) and ' +
|
|
15
|
+
'the red line emits action=red-line (the installed PreToolUse hook re-runs ' +
|
|
16
|
+
'this command on the next Bash/Task tool call; nothing is blocked). ' +
|
|
17
|
+
'--enforce-job-mode only changes the reported `jobMode` label; ' +
|
|
18
|
+
'the thresholds are identical. ' +
|
|
19
|
+
'Context-window override: set env PEAKS_CONTEXT_WINDOW_TOKENS=<positive int> ' +
|
|
20
|
+
'or `peaks config set --key context.windowTokens --value <positive int>`; ' +
|
|
21
|
+
'the JSON envelope reports the winning layer as capacitySource ' +
|
|
22
|
+
'(env-override | config | model-heuristic | default).';
|
|
23
|
+
/**
|
|
24
|
+
* The two flags the action derives before any probe: the `--prompt-size`
|
|
25
|
+
* override (guarded) and the Job-mode label. Pure in `opts` — no ordering
|
|
26
|
+
* dependency on the call site.
|
|
27
|
+
*/
|
|
28
|
+
function resolveContextNowFlags(opts) {
|
|
29
|
+
// guard rejects non-finite / negative values; only finite
|
|
30
|
+
// non-negative numbers reach the reader. Undefined → no override.
|
|
31
|
+
let promptSizeBytes;
|
|
32
|
+
if (opts.promptSize !== undefined) {
|
|
33
|
+
const parsed = Number(opts.promptSize);
|
|
34
|
+
if (Number.isFinite(parsed) && parsed >= 0) {
|
|
35
|
+
promptSizeBytes = parsed;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// v3.1.2: detect Job mode from job-shape.json when --enforce-job-mode
|
|
39
|
+
// is not explicitly passed. The LLM is the source of truth for
|
|
40
|
+
// whether the request is Job-shaped; the recorded decision is.
|
|
41
|
+
let isJobMode = opts.enforceJobMode === true;
|
|
42
|
+
if (!isJobMode) {
|
|
43
|
+
try {
|
|
44
|
+
const sessionIdForDecision = opts.sessionId ?? readActiveSid(opts.project);
|
|
45
|
+
if (sessionIdForDecision !== null) {
|
|
46
|
+
const record = readJobShapeDecision(opts.project, sessionIdForDecision);
|
|
47
|
+
if (record.decision.isJob)
|
|
48
|
+
isJobMode = true;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
if (!(err instanceof JobShapeDecisionError))
|
|
53
|
+
throw err;
|
|
54
|
+
// missing/malformed decision file is fine — fall back to advisory.
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return { promptSizeBytes, isJobMode };
|
|
58
|
+
}
|
|
59
|
+
/** The catch branch, lifted verbatim out of the action body. */
|
|
60
|
+
function reportContextNowFailure(io, err, json) {
|
|
61
|
+
printResult(io, fail('code.context-now', 'CONTEXT_NOW_FAILED', getErrorMessage(err), null, [
|
|
62
|
+
'Verify the project path and try again'
|
|
63
|
+
]), json);
|
|
64
|
+
process.exitCode = 1;
|
|
65
|
+
}
|
|
66
|
+
/** The action body, lifted to a module-level function so both it and the registrar fit in 50 lines. */
|
|
67
|
+
async function runCodeContextNow(opts, io) {
|
|
68
|
+
try {
|
|
69
|
+
const { readContextPercent } = await import('../../services/context/auto-compact-reader.js');
|
|
70
|
+
const flags = resolveContextNowFlags(opts);
|
|
71
|
+
const sessionId = opts.sessionId ?? readActiveSid(opts.project) ?? 'unknown';
|
|
72
|
+
const outerSessionId = resolveOuterSessionId(opts.project, sessionId);
|
|
73
|
+
const probe = readContextPercent({
|
|
74
|
+
projectRoot: opts.project,
|
|
75
|
+
sessionId,
|
|
76
|
+
outerSessionId,
|
|
77
|
+
env: process.env,
|
|
78
|
+
promptSizeBytes: flags.promptSizeBytes
|
|
79
|
+
});
|
|
80
|
+
// Promote `--project .` (what the PreToolUse hook passes) to the git
|
|
81
|
+
// root ONCE, for both of the consumers below: the settings path the
|
|
82
|
+
// harness window is written to, and the session directory the witness
|
|
83
|
+
// is read from, must not depend on the caller's cwd — and an absolute
|
|
84
|
+
// path is what the envelope then reports back to the operator. This
|
|
85
|
+
// resolves through `git rev-parse --show-toplevel`, i.e. a whole
|
|
86
|
+
// process spawn (measured 2026-09-14: med 111.8 ms per call on this
|
|
87
|
+
// host), so calling it twice with the same argument charged the witness
|
|
88
|
+
// read it precedes — 0.027 ms — roughly 4,000x its own cost.
|
|
89
|
+
const canonicalProjectRoot = resolveCanonicalProjectRoot(opts.project);
|
|
90
|
+
const harness = readContextNowHarness(canonicalProjectRoot, sessionId, outerSessionId, probe);
|
|
91
|
+
const decision = resolveContextNowDecision(canonicalProjectRoot, probe.ratio, flags.isJobMode);
|
|
92
|
+
printResult(io, ok('code.context-now', buildContextNowData({
|
|
93
|
+
probe,
|
|
94
|
+
ratioPct: (probe.ratio * 100).toFixed(1),
|
|
95
|
+
isJobMode: flags.isJobMode,
|
|
96
|
+
promptSizeBytes: flags.promptSizeBytes,
|
|
97
|
+
decision,
|
|
98
|
+
harness
|
|
99
|
+
}), buildContextNowWarnings(harness), buildContextNowNextActions(decision, harness)),
|
|
100
|
+
// `true`, which made the declared `--json` flag a no-op and left the
|
|
101
|
+
// human with raw JSON and no `next:` lines — so a person running this
|
|
102
|
+
// command could not see that peaks-loop had just written their
|
|
103
|
+
// harness settings. The notices above (including the key, the value
|
|
104
|
+
// and the rollback command) are `nextActions`, which `printResult`
|
|
105
|
+
// prints as `next: …` lines ONLY in the non-JSON path. Honoring the
|
|
106
|
+
// flag is what puts them in front of a human. See the consumer audit
|
|
107
|
+
// in the slice's RD artifact: every in-repo caller (the PreToolUse
|
|
108
|
+
// hooks, `orchestrator-can-do`, the skill runbooks) passes `--json`
|
|
109
|
+
// explicitly, so their byte-for-byte output is unchanged.
|
|
110
|
+
opts.json === true);
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
reportContextNowFailure(io, err, opts.json);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
export function registerCodeContextNowCommand(code, io) {
|
|
117
|
+
addJsonOption(code
|
|
118
|
+
.command('context-now')
|
|
119
|
+
.description(CONTEXT_NOW_DESCRIPTION)
|
|
120
|
+
.requiredOption('--project <path>', 'target project root')
|
|
121
|
+
.option('--session-id <sid>', 'override session id (default: read from active presence)')
|
|
122
|
+
.option('--enforce-job-mode', 'v3.1.2: label the run as Job-shaped (jobMode=true). Auto-enabled when job-shape.json says isJob=true. Since 2026-09-12 the ≥0.85 MANDATORY auto-compact applies in single-rid mode too, so this flag no longer changes any action.')
|
|
123
|
+
.option('--prompt-size <bytes>', 'override the bytes-from-env path; takes priority over env / statusline / transcript. Useful when CLAUDE_CONTEXT_USAGE_PERCENT is absent (e.g. Mac Claude Code).')).action((opts) => runCodeContextNow(opts, io));
|
|
124
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { ContextPercentProbe } from '../../services/context/auto-compact-types.js';
|
|
2
|
+
/**
|
|
3
|
+
* The harness half of the probe: the window sync, its warning, the witness read
|
|
4
|
+
* and its notice. Lifted verbatim from the action body — it reads only its
|
|
5
|
+
* parameters.
|
|
6
|
+
*/
|
|
7
|
+
export declare function readContextNowHarness(canonicalProjectRoot: string, sessionId: string, outerSessionId: string | null | undefined, probe: ContextPercentProbe): {
|
|
8
|
+
harnessWindow: import("../../services/context/harness-window-config.js").HarnessWindowSyncResult | null;
|
|
9
|
+
harnessWindowWarning: string | null;
|
|
10
|
+
harnessWitness: import("../../services/context/harness-context-witness.js").HarnessWitnessComparison;
|
|
11
|
+
witnessNotice: string | null;
|
|
12
|
+
};
|
|
13
|
+
type ContextNowHarness = ReturnType<typeof readContextNowHarness>;
|
|
14
|
+
/**
|
|
15
|
+
* Slice H4 (rid=h4-context-now-mode-blind): ONE table, ONE mode
|
|
16
|
+
* resolver. The hard-coded ladder that used to live in the action read no mode
|
|
17
|
+
* at all, so on a 24h run (`partial` = 0.65/0.70/0.85) it answered `soft-warn`
|
|
18
|
+
* + `next: null` across [0.70, 0.85) — the band in which
|
|
19
|
+
* `peaks code auto-compact` had already decided to compact.
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveContextNowDecision(canonicalProjectRoot: string, ratio: number, isJobMode: boolean): {
|
|
22
|
+
action: "ok" | "soft-warn" | "red-line" | "auto-compact-now";
|
|
23
|
+
next: string | null;
|
|
24
|
+
verdict: string;
|
|
25
|
+
bands: {
|
|
26
|
+
softWarn: string;
|
|
27
|
+
preCompact: string;
|
|
28
|
+
redLine: string;
|
|
29
|
+
preCompactRatio: string;
|
|
30
|
+
redLineRatio: string;
|
|
31
|
+
};
|
|
32
|
+
gateModeNotice: string;
|
|
33
|
+
};
|
|
34
|
+
type ContextNowDecision = ReturnType<typeof resolveContextNowDecision>;
|
|
35
|
+
/** The envelope's `data` record, lifted verbatim out of the action body. */
|
|
36
|
+
export declare function buildContextNowData(args: {
|
|
37
|
+
probe: ContextPercentProbe;
|
|
38
|
+
ratioPct: string;
|
|
39
|
+
isJobMode: boolean;
|
|
40
|
+
promptSizeBytes: number | undefined;
|
|
41
|
+
decision: ContextNowDecision;
|
|
42
|
+
harness: ContextNowHarness;
|
|
43
|
+
}): {
|
|
44
|
+
ratio: number;
|
|
45
|
+
ratioPct: string;
|
|
46
|
+
verdict: string;
|
|
47
|
+
action: "ok" | "soft-warn" | "red-line" | "auto-compact-now";
|
|
48
|
+
next: string | null;
|
|
49
|
+
jobMode: boolean;
|
|
50
|
+
source: string;
|
|
51
|
+
ide: string;
|
|
52
|
+
capacityBytes: number | undefined;
|
|
53
|
+
rawBytes: number | null;
|
|
54
|
+
rawTokens: number | null;
|
|
55
|
+
capacityTokens: number | null;
|
|
56
|
+
capacitySource: string | null;
|
|
57
|
+
bytesPrompt: number | null;
|
|
58
|
+
capturedAt: string;
|
|
59
|
+
harnessWindow: import("../../services/context/harness-window-config.js").HarnessWindowSyncResult | null;
|
|
60
|
+
harnessWitness: import("../../services/context/harness-context-witness.js").HarnessWitnessComparison;
|
|
61
|
+
};
|
|
62
|
+
/** The envelope's `warnings` array, lifted verbatim out of the action body. */
|
|
63
|
+
export declare function buildContextNowWarnings(harness: ContextNowHarness): string[];
|
|
64
|
+
/** The envelope's `nextActions` array, lifted verbatim out of the action body. */
|
|
65
|
+
export declare function buildContextNowNextActions(decision: ContextNowDecision, harness: ContextNowHarness): string[];
|
|
66
|
+
export {};
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// The `peaks code context-now` envelope: the harness reading (window sync +
|
|
2
|
+
// witness), the mode-resolved decision, and the `data` / `warnings` /
|
|
3
|
+
// `nextActions` builders. Split out of `code-context-now-command.ts` when
|
|
4
|
+
// compressing its long function pushed that file past the 300-line cap; every
|
|
5
|
+
// body below is the original one, moved verbatim.
|
|
6
|
+
import { resolveAutoCompactProfile } from '../../services/mode/mode-status-service.js';
|
|
7
|
+
import { syncHarnessWindowForProject } from '../../services/context/auto-compact-reader.js';
|
|
8
|
+
import { describeHarnessWindowSync, harnessWindowSyncWarning } from '../../services/context/harness-window-config.js';
|
|
9
|
+
import { describeHarnessWitness, readAndCompareHarnessWitness } from '../../services/context/harness-context-witness.js';
|
|
10
|
+
import { contextNowActionFor, contextNowBandLabels } from './code-context-now-mapping.js';
|
|
11
|
+
/**
|
|
12
|
+
* The harness half of the probe: the window sync, its warning, the witness read
|
|
13
|
+
* and its notice. Lifted verbatim from the action body — it reads only its
|
|
14
|
+
* parameters.
|
|
15
|
+
*/
|
|
16
|
+
export function readContextNowHarness(canonicalProjectRoot, sessionId, outerSessionId, probe) {
|
|
17
|
+
// the window this probe just divided by into the harness's own settings,
|
|
18
|
+
// so "85%" here and the harness's own trigger are one point on one
|
|
19
|
+
// scale. Idempotent (no write when the value is already in force) and a
|
|
20
|
+
// no-op when the probe carried no token window — peaks-loop never
|
|
21
|
+
// invents a number it did not measure.
|
|
22
|
+
const harnessWindow = syncHarnessWindowForProject({
|
|
23
|
+
projectRoot: canonicalProjectRoot,
|
|
24
|
+
env: process.env,
|
|
25
|
+
tokens: probe.capacityTokens ?? null
|
|
26
|
+
});
|
|
27
|
+
// The machine half of 要告知. A refused write is not automatically a
|
|
28
|
+
// non-event: the file may pin a window that disagrees with the one this
|
|
29
|
+
// probe just divided by, and then the ratio above describes a trigger
|
|
30
|
+
// the harness is not going to fire. `nextActions` carries the full
|
|
31
|
+
// sentence; this one line rides `warnings` so a JSON consumer cannot
|
|
32
|
+
// miss it either.
|
|
33
|
+
const harnessWindowWarning = harnessWindowSyncWarning(harnessWindow);
|
|
34
|
+
// own number for the same quantity, captured by the statusline. This is
|
|
35
|
+
// OBSERVATION ONLY — it never feeds `verdict` / `action` / any threshold
|
|
36
|
+
// below. A wrong reading here must not be able to fire a compact.
|
|
37
|
+
const harnessWitness = readAndCompareHarnessWitness({
|
|
38
|
+
// The same promoted root as the harness-window write above, for the
|
|
39
|
+
// same reason: the statusline resolves its root from the harness
|
|
40
|
+
// payload (absolute), so a `--project .` from a hook would otherwise
|
|
41
|
+
// look for the witness somewhere else and report `absent` forever.
|
|
42
|
+
projectRoot: canonicalProjectRoot,
|
|
43
|
+
sessionId,
|
|
44
|
+
peaksRatio: probe.ratio,
|
|
45
|
+
peaksTokens: probe.rawTokens ?? null,
|
|
46
|
+
peaksWindowTokens: probe.capacityTokens ?? null,
|
|
47
|
+
outerSessionId: outerSessionId ?? null
|
|
48
|
+
});
|
|
49
|
+
const witnessNotice = describeHarnessWitness(harnessWitness);
|
|
50
|
+
return { harnessWindow, harnessWindowWarning, harnessWitness, witnessNotice };
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Slice H4 (rid=h4-context-now-mode-blind): ONE table, ONE mode
|
|
54
|
+
* resolver. The hard-coded ladder that used to live in the action read no mode
|
|
55
|
+
* at all, so on a 24h run (`partial` = 0.65/0.70/0.85) it answered `soft-warn`
|
|
56
|
+
* + `next: null` across [0.70, 0.85) — the band in which
|
|
57
|
+
* `peaks code auto-compact` had already decided to compact.
|
|
58
|
+
*/
|
|
59
|
+
export function resolveContextNowDecision(canonicalProjectRoot, ratio, isJobMode) {
|
|
60
|
+
const compactMode = resolveAutoCompactProfile(canonicalProjectRoot);
|
|
61
|
+
const decided = contextNowActionFor(ratio, compactMode);
|
|
62
|
+
const action = decided.action;
|
|
63
|
+
const next = decided.next;
|
|
64
|
+
const verdict = action === 'red-line' ? 'red-line' : action === 'auto-compact-now' ? 'pre-compact' : action;
|
|
65
|
+
const bands = contextNowBandLabels(compactMode);
|
|
66
|
+
// in behaviour ABOVE 0.50 — both auto-fire at ≥0.85 and both red-line at
|
|
67
|
+
// ≥0.95". That was false: `partial` fires at 0.70, red-lines at 0.85.
|
|
68
|
+
// The lines now come from the table for the mode in force.
|
|
69
|
+
const gateModeNotice = isJobMode
|
|
70
|
+
? `Job mode (job-shape.json isJob=true): the same ≥${bands.preCompactRatio} / ≥${bands.redLineRatio} thresholds apply, and the decision is recorded in job-shape.json.`
|
|
71
|
+
: `Single-rid mode: the same ≥${bands.preCompactRatio} / ≥${bands.redLineRatio} thresholds apply — ≥${bands.preCompactRatio} is MANDATORY auto-compact, not advisory.`;
|
|
72
|
+
return { action, next, verdict, bands, gateModeNotice };
|
|
73
|
+
}
|
|
74
|
+
/** The envelope's `data` record, lifted verbatim out of the action body. */
|
|
75
|
+
export function buildContextNowData(args) {
|
|
76
|
+
const { probe, decision, harness } = args;
|
|
77
|
+
return {
|
|
78
|
+
ratio: probe.ratio,
|
|
79
|
+
ratioPct: `${args.ratioPct}%`,
|
|
80
|
+
verdict: decision.verdict,
|
|
81
|
+
action: decision.action,
|
|
82
|
+
next: decision.next,
|
|
83
|
+
jobMode: args.isJobMode,
|
|
84
|
+
source: probe.source,
|
|
85
|
+
ide: probe.ide,
|
|
86
|
+
capacityBytes: probe.capacityBytes,
|
|
87
|
+
rawBytes: probe.rawBytes ?? null,
|
|
88
|
+
rawTokens: probe.rawTokens ?? null,
|
|
89
|
+
capacityTokens: probe.capacityTokens ?? null,
|
|
90
|
+
// capacityTokens (env-override | config | model-heuristic |
|
|
91
|
+
// default) — null for byte/percent sources, which have no window.
|
|
92
|
+
capacitySource: probe.capacitySource ?? null,
|
|
93
|
+
bytesPrompt: args.promptSizeBytes ?? null,
|
|
94
|
+
capturedAt: probe.capturedAt,
|
|
95
|
+
// window sync did on this probe. Reported rather than silent — the
|
|
96
|
+
// harness tells a user who overrides the window only via
|
|
97
|
+
// `/autocompact`, so peaks-loop must be the one that says it.
|
|
98
|
+
harnessWindow: harness.harnessWindow,
|
|
99
|
+
harnessWitness: harness.harnessWitness
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/** The envelope's `warnings` array, lifted verbatim out of the action body. */
|
|
103
|
+
export function buildContextNowWarnings(harness) {
|
|
104
|
+
return [
|
|
105
|
+
...(harness.harnessWindowWarning === null ? [] : [harness.harnessWindowWarning]),
|
|
106
|
+
// AC3: the disagreement rides `warnings` — it is a fact about the
|
|
107
|
+
// state, not an instruction — and it is one-way. Never an
|
|
108
|
+
// AskUserQuestion (see .peaks/memory/auto-compact-threshold-policy.md).
|
|
109
|
+
...(harness.witnessNotice === null ? [] : [harness.witnessNotice])
|
|
110
|
+
];
|
|
111
|
+
}
|
|
112
|
+
/** The envelope's `nextActions` array, lifted verbatim out of the action body. */
|
|
113
|
+
export function buildContextNowNextActions(decision, harness) {
|
|
114
|
+
const { action, next, bands, gateModeNotice } = decision;
|
|
115
|
+
return [
|
|
116
|
+
action === 'red-line'
|
|
117
|
+
? `RED LINE: ≥ ${bands.redLine}%. Next: \`${next}\` — peaks-loop asks the harness to compact and KEEPS WORKING (dispatch is not blocked); re-probe to confirm it landed.`
|
|
118
|
+
: action === 'auto-compact-now'
|
|
119
|
+
? `MANDATORY auto-compact (≥${bands.preCompact}%, every mode). Code MUST call \`${next}\` WITHOUT confirmation.`
|
|
120
|
+
: action === 'soft-warn'
|
|
121
|
+
? `Soft warn (${bands.softWarn}–${bands.preCompact}%). Continue working; the next \`peaks code auto-compact\` will re-check.`
|
|
122
|
+
: `Below ${bands.softWarn}%. No action required.`,
|
|
123
|
+
gateModeNotice,
|
|
124
|
+
// Single wording, shared with `peaks code auto-compact` — see
|
|
125
|
+
// `describeHarnessWindowSync`.
|
|
126
|
+
describeHarnessWindowSync(harness.harnessWindow),
|
|
127
|
+
// AC3: the one-way hint that accompanies the `warnings` entry. Both
|
|
128
|
+
// channels carry the SAME fact in the shape each is read for
|
|
129
|
+
// (machine-readable warning vs human/LLM advice) — see
|
|
130
|
+
// `harnessWindowSyncWarning` / `describeHarnessWindowSync` above for
|
|
131
|
+
// the same split, and note this one never asks a question.
|
|
132
|
+
...(harness.witnessNotice === null
|
|
133
|
+
? []
|
|
134
|
+
: ['Re-probe with `peaks code context-now` to confirm; this is reported, not blocking.'])
|
|
135
|
+
];
|
|
136
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type AutoCompactMode } from '../../services/code/auto-compact-modes.js';
|
|
2
|
+
/**
|
|
3
|
+
* Slice H4 (rid=h4-context-now-mode-blind) — the ONE mapping from the shared
|
|
4
|
+
* `CompactTrigger` to this command's `action` vocabulary, so the two cannot
|
|
5
|
+
* drift: the trigger is `evaluateCompactTrigger`, the same function `peaks
|
|
6
|
+
* code auto-compact` decides with.
|
|
7
|
+
*
|
|
8
|
+
* `auto-fire` maps to `soft-warn` in BOTH modes: that tier is `peaks skill
|
|
9
|
+
* presence`'s — the every-turn probe, which reads this same table and mode
|
|
10
|
+
* resolver — so `context-now` has no auto-fire tier of its own (SKILL.md
|
|
11
|
+
* "two probes, two thresholds"). Reporting it as `auto-compact-now` would
|
|
12
|
+
* change every non-24h session's output, which slice H4 forbids.
|
|
13
|
+
*/
|
|
14
|
+
export declare function contextNowActionFor(ratio: number, mode: AutoCompactMode): {
|
|
15
|
+
action: 'ok' | 'soft-warn' | 'auto-compact-now' | 'red-line';
|
|
16
|
+
next: string | null;
|
|
17
|
+
};
|
|
18
|
+
/** Slice H4: the labels `context-now` prints, read out of the table for the mode
|
|
19
|
+
* in force — the old hard-coded "≥0.85 / ≥0.95 / 50–85%" told a 24h operator
|
|
20
|
+
* the wrong lines. `*Ratio` is the `0.85` form `gateModeNotice` uses. */
|
|
21
|
+
export declare function contextNowBandLabels(mode: AutoCompactMode): {
|
|
22
|
+
softWarn: string;
|
|
23
|
+
preCompact: string;
|
|
24
|
+
redLine: string;
|
|
25
|
+
preCompactRatio: string;
|
|
26
|
+
redLineRatio: string;
|
|
27
|
+
};
|