@prestyj/cli 5.28.1 → 5.29.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/assets/motion/bin/contact-sheet.mjs +9 -3
- package/assets/motion/bin/cues.mjs +337 -0
- package/assets/motion/bin/library.mjs +53 -10
- package/assets/motion/bin/motion-blur.mjs +943 -0
- package/assets/motion/bin/motion-check.mjs +354 -3
- package/assets/motion/bin/music-fit.mjs +436 -0
- package/assets/motion/bin/pdf-extract.mjs +22 -10
- package/assets/motion/bin/reference-study.mjs +346 -0
- package/assets/motion/bin/score-synth.mjs +1052 -93
- package/assets/motion/library/README.md +50 -14
- package/assets/motion/library/kit/moves.js +1981 -0
- package/assets/motion/library/library.json +232 -0
- package/assets/motion/library/pieces/camera-rig/meta.json +13 -0
- package/assets/motion/library/pieces/camera-rig/piece.html +153 -0
- package/assets/motion/library/pieces/camera-rig/preview.jpg +0 -0
- package/assets/motion/library/pieces/chain-knock/meta.json +13 -0
- package/assets/motion/library/pieces/chain-knock/piece.html +195 -0
- package/assets/motion/library/pieces/chain-knock/preview.jpg +0 -0
- package/assets/motion/library/pieces/gather-to-logo/meta.json +13 -0
- package/assets/motion/library/pieces/gather-to-logo/piece.html +159 -0
- package/assets/motion/library/pieces/gather-to-logo/preview.jpg +0 -0
- package/assets/motion/library/pieces/morph-carry/meta.json +13 -0
- package/assets/motion/library/pieces/morph-carry/piece.html +173 -0
- package/assets/motion/library/pieces/morph-carry/preview.jpg +0 -0
- package/assets/motion/library/pieces/one-shape-journey/meta.json +13 -0
- package/assets/motion/library/pieces/one-shape-journey/piece.html +195 -0
- package/assets/motion/library/pieces/one-shape-journey/preview.jpg +0 -0
- package/assets/motion/library/pieces/open-from-subject/meta.json +13 -0
- package/assets/motion/library/pieces/open-from-subject/piece.html +168 -0
- package/assets/motion/library/pieces/open-from-subject/preview.jpg +0 -0
- package/assets/motion/library/pieces/request-to-result/meta.json +13 -0
- package/assets/motion/library/pieces/request-to-result/piece.html +212 -0
- package/assets/motion/library/pieces/request-to-result/preview.jpg +0 -0
- package/assets/motion/library/pieces/scale-dive/meta.json +13 -0
- package/assets/motion/library/pieces/scale-dive/piece.html +321 -0
- package/assets/motion/library/pieces/scale-dive/preview.jpg +0 -0
- package/assets/motion/library/pieces/screen-replica-steps/meta.json +13 -0
- package/assets/motion/library/pieces/screen-replica-steps/piece.html +366 -0
- package/assets/motion/library/pieces/screen-replica-steps/preview.jpg +0 -0
- package/assets/motion/library/pieces/zoom-into-card/meta.json +13 -0
- package/assets/motion/library/pieces/zoom-into-card/piece.html +179 -0
- package/assets/motion/library/pieces/zoom-into-card/preview.jpg +0 -0
- package/assets/motion/library/sheets/diagram.jpg +0 -0
- package/assets/motion/library/sheets/frame.jpg +0 -0
- package/assets/motion/library/sheets/transition.jpg +0 -0
- package/assets/motion/library/sheets/ui.jpg +0 -0
- package/assets/motion/references/build-sheet.md +206 -0
- package/assets/motion/references/runtime/determinism-rules.md +1 -1
- package/assets/motion/references/runtime/gsap-easing-and-stagger.md +29 -29
- package/assets/motion/references/runtime/inputs-and-assets.md +7 -12
- package/assets/motion/references/runtime/lint-validate-inspect.md +3 -3
- package/assets/motion/references/runtime/minimal-composition.md +1 -1
- package/assets/motion/references/runtime/preview-render.md +3 -3
- package/assets/motion/skills/app-walkthrough/SKILL.md +70 -0
- package/assets/motion/skills/before-after/SKILL.md +57 -0
- package/assets/motion/skills/brand-kit/SKILL.md +3 -3
- package/assets/motion/skills/dev-tool-video/SKILL.md +61 -0
- package/assets/motion/skills/launch-video/SKILL.md +66 -0
- package/assets/motion/skills/match-reference/SKILL.md +62 -0
- package/assets/motion/skills/motion/SKILL.md +148 -98
- package/assets/motion/skills/source-ingest/SKILL.md +17 -6
- package/assets/motion/skills/website-video/SKILL.md +76 -0
- package/assets/skills/bulletproof/SKILL.md +36 -11
- package/assets/skills/bulletproof/references/agent-surface.md +19 -9
- package/assets/skills/bulletproof/references/audit-protocol.md +20 -5
- package/assets/skills/bulletproof/references/platform-playbooks.md +5 -4
- package/assets/skills/bulletproof/references/provenance.md +26 -1
- package/assets/skills/bulletproof/references/secure-defaults.md +6 -5
- package/assets/skills/bulletproof/references/supply-chain.md +21 -17
- package/assets/skills/bulletproof/references/threat-landscape.md +28 -26
- package/assets/skills/bulletproof/references/verification.md +2 -0
- package/assets/skills/clarify/SKILL.md +25 -16
- package/assets/skills/code-review/SKILL.md +71 -13
- package/assets/skills/code-review/references/agent-diffs.md +27 -0
- package/assets/skills/code-review/references/tests.md +19 -0
- package/assets/skills/compliance-guard/SKILL.md +20 -5
- package/assets/skills/compliance-guard/references/artifacts.md +1 -1
- package/assets/skills/compliance-guard/references/eu-uk.md +16 -16
- package/assets/skills/compliance-guard/references/lawsuit-vectors.md +5 -5
- package/assets/skills/compliance-guard/references/provenance.md +41 -2
- package/assets/skills/compliance-guard/references/sector-gates.md +3 -3
- package/assets/skills/compliance-guard/references/security-baseline.md +2 -2
- package/assets/skills/compliance-guard/references/trigger-map.md +5 -5
- package/assets/skills/compliance-guard/references/us.md +27 -21
- package/assets/skills/durable/SKILL.md +87 -79
- package/assets/skills/durable/references/agent-db-safety.md +69 -0
- package/assets/skills/durable/references/backups-and-runtime.md +19 -12
- package/assets/skills/durable/references/migrations-and-schema.md +13 -6
- package/assets/skills/evidence-led-ui/SKILL.md +69 -127
- package/assets/skills/evidence-led-ui/references/anti-defaults.md +107 -208
- package/assets/skills/evidence-led-ui/references/direction.md +124 -0
- package/assets/skills/evidence-led-ui/references/production-contract.md +8 -0
- package/assets/skills/evidence-led-ui/references/provenance.md +24 -1
- package/assets/skills/lean/SKILL.md +90 -71
- package/assets/skills/lean/references/memory-and-processes.md +3 -2
- package/assets/skills/lean/references/playbooks.md +37 -12
- package/assets/skills/refactoring/SKILL.md +24 -3
- package/assets/skills/refactoring/references/agent-pitfalls.md +4 -1
- package/assets/skills/refactoring/references/legacy.md +21 -0
- package/assets/skills/root-cause/SKILL.md +20 -10
- package/assets/skills/shared-language/SKILL.md +16 -14
- package/assets/skills/tdd/SKILL.md +27 -15
- package/dist/app-sidecar.js +206 -47
- package/dist/app-sidecar.js.map +1 -1
- package/dist/cli/thinking-arg.d.ts +6 -0
- package/dist/cli/thinking-arg.js +13 -0
- package/dist/cli/thinking-arg.js.map +1 -0
- package/dist/cli.d.ts +1 -2
- package/dist/cli.js +18 -34
- package/dist/cli.js.map +1 -1
- package/dist/core/acceptance-checks.d.ts +48 -0
- package/dist/core/acceptance-checks.js +144 -0
- package/dist/core/acceptance-checks.js.map +1 -0
- package/dist/core/agent-session.d.ts +107 -72
- package/dist/core/agent-session.js +562 -407
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/agents.d.ts +6 -5
- package/dist/core/agents.js.map +1 -1
- package/dist/core/ask-user.d.ts +90 -8
- package/dist/core/ask-user.js +124 -13
- package/dist/core/ask-user.js.map +1 -1
- package/dist/core/bundled-agents.js +1 -3
- package/dist/core/bundled-agents.js.map +1 -1
- package/dist/core/cache-diagnostics.d.ts +68 -0
- package/dist/core/cache-diagnostics.js +196 -0
- package/dist/core/cache-diagnostics.js.map +1 -0
- package/dist/core/cache-expiry.d.ts +87 -0
- package/dist/core/cache-expiry.js +111 -0
- package/dist/core/cache-expiry.js.map +1 -0
- package/dist/core/codex-request-shape.d.ts +12 -0
- package/dist/core/codex-request-shape.js +31 -0
- package/dist/core/codex-request-shape.js.map +1 -0
- package/dist/core/compaction/compactor.js +84 -48
- package/dist/core/compaction/compactor.js.map +1 -1
- package/dist/core/compaction/plan-step-policy.d.ts +46 -0
- package/dist/core/compaction/plan-step-policy.js +57 -0
- package/dist/core/compaction/plan-step-policy.js.map +1 -0
- package/dist/core/destructive-git-guard.d.ts +90 -0
- package/dist/core/destructive-git-guard.js +871 -0
- package/dist/core/destructive-git-guard.js.map +1 -0
- package/dist/core/event-bus.d.ts +3 -0
- package/dist/core/event-bus.js +5 -0
- package/dist/core/event-bus.js.map +1 -1
- package/dist/core/injection-detect.d.ts +38 -0
- package/dist/core/injection-detect.js +232 -0
- package/dist/core/injection-detect.js.map +1 -0
- package/dist/core/keep-awake.d.ts +88 -0
- package/dist/core/keep-awake.js +251 -0
- package/dist/core/keep-awake.js.map +1 -0
- package/dist/core/mcp/client.d.ts +72 -0
- package/dist/core/mcp/client.js +264 -41
- package/dist/core/mcp/client.js.map +1 -1
- package/dist/core/mcp/content.js +6 -2
- package/dist/core/mcp/content.js.map +1 -1
- package/dist/core/mcp/store.d.ts +6 -1
- package/dist/core/mcp/store.js +12 -1
- package/dist/core/mcp/store.js.map +1 -1
- package/dist/core/mcp/types.d.ts +18 -0
- package/dist/core/model-unavailable.d.ts +14 -0
- package/dist/core/model-unavailable.js +23 -0
- package/dist/core/model-unavailable.js.map +1 -0
- package/dist/core/node-debugger.d.ts +148 -0
- package/dist/core/node-debugger.js +642 -0
- package/dist/core/node-debugger.js.map +1 -0
- package/dist/core/nolan-context.js +7 -3
- package/dist/core/nolan-context.js.map +1 -1
- package/dist/core/package-threats.d.ts +18 -0
- package/dist/core/package-threats.js +168 -0
- package/dist/core/package-threats.js.map +1 -0
- package/dist/core/persistent-shell.d.ts +58 -6
- package/dist/core/persistent-shell.js +331 -49
- package/dist/core/persistent-shell.js.map +1 -1
- package/dist/core/process-manager.d.ts +14 -0
- package/dist/core/process-manager.js +61 -0
- package/dist/core/process-manager.js.map +1 -1
- package/dist/core/progress/git-xp.js +8 -14
- package/dist/core/progress/git-xp.js.map +1 -1
- package/dist/core/session-history.d.ts +12 -0
- package/dist/core/session-history.js +27 -0
- package/dist/core/session-history.js.map +1 -1
- package/dist/core/session-manager.d.ts +13 -1
- package/dist/core/session-manager.js +38 -18
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-summary-index.d.ts +37 -0
- package/dist/core/session-summary-index.js +172 -0
- package/dist/core/session-summary-index.js.map +1 -0
- package/dist/core/settings-manager.d.ts +12 -0
- package/dist/core/settings-manager.js +20 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/shell-threats-popular-packages.d.ts +11 -0
- package/dist/core/shell-threats-popular-packages.js +675 -0
- package/dist/core/shell-threats-popular-packages.js.map +1 -0
- package/dist/core/shell-threats.d.ts +8 -0
- package/dist/core/shell-threats.js +186 -0
- package/dist/core/shell-threats.js.map +1 -0
- package/dist/core/skills.js +3 -1
- package/dist/core/skills.js.map +1 -1
- package/dist/core/stream-rules.d.ts +30 -0
- package/dist/core/stream-rules.js +151 -0
- package/dist/core/stream-rules.js.map +1 -0
- package/dist/core/subagent-manager.d.ts +20 -5
- package/dist/core/subagent-manager.js +22 -8
- package/dist/core/subagent-manager.js.map +1 -1
- package/dist/core/subagent-receipt.d.ts +54 -0
- package/dist/core/subagent-receipt.js +278 -0
- package/dist/core/subagent-receipt.js.map +1 -0
- package/dist/core/subagent-turn-record.d.ts +2 -0
- package/dist/core/subagent-turn-record.js.map +1 -1
- package/dist/core/test-impact.d.ts +73 -0
- package/dist/core/test-impact.js +467 -0
- package/dist/core/test-impact.js.map +1 -0
- package/dist/core/thinking-level.d.ts +1 -1
- package/dist/core/thinking-level.js +1 -1
- package/dist/core/thinking-level.js.map +1 -1
- package/dist/core/verification-gate.d.ts +2 -0
- package/dist/core/verification-gate.js +4 -0
- package/dist/core/verification-gate.js.map +1 -1
- package/dist/core/verification-snapshot.js +3 -5
- package/dist/core/verification-snapshot.js.map +1 -1
- package/dist/core/workspace-guard.d.ts +18 -7
- package/dist/core/workspace-guard.js +227 -60
- package/dist/core/workspace-guard.js.map +1 -1
- package/dist/interactive.js +2 -1
- package/dist/interactive.js.map +1 -1
- package/dist/modes/subagent-worker-mode.js +34 -6
- package/dist/modes/subagent-worker-mode.js.map +1 -1
- package/dist/motion-agent/motion-agent.d.ts +6 -2
- package/dist/motion-agent/motion-agent.js +5 -7
- package/dist/motion-agent/motion-agent.js.map +1 -1
- package/dist/motion-agent/motion-prompt.d.ts +1 -1
- package/dist/motion-agent/motion-prompt.js +16 -20
- package/dist/motion-agent/motion-prompt.js.map +1 -1
- package/dist/motion-agent/motion-review-session.js +7 -3
- package/dist/motion-agent/motion-review-session.js.map +1 -1
- package/dist/motion-agent/motion-review.d.ts +10 -3
- package/dist/motion-agent/motion-review.js +15 -7
- package/dist/motion-agent/motion-review.js.map +1 -1
- package/dist/motion-agent/motion-studio-context.js +1 -1
- package/dist/motion-agent/motion-studio-context.js.map +1 -1
- package/dist/system-prompt.js +15 -11
- package/dist/system-prompt.js.map +1 -1
- package/dist/test-support/keep-alive.d.ts +14 -0
- package/dist/test-support/keep-alive.js +17 -0
- package/dist/test-support/keep-alive.js.map +1 -0
- package/dist/tools/ask-user.js +3 -3
- package/dist/tools/ask-user.js.map +1 -1
- package/dist/tools/bash-read-evidence.d.ts +10 -0
- package/dist/tools/bash-read-evidence.js +133 -0
- package/dist/tools/bash-read-evidence.js.map +1 -0
- package/dist/tools/bash.d.ts +10 -1
- package/dist/tools/bash.js +115 -7
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/debug.d.ts +54 -0
- package/dist/tools/debug.js +233 -0
- package/dist/tools/debug.js.map +1 -0
- package/dist/tools/edit-targets.d.ts +10 -0
- package/dist/tools/edit-targets.js +31 -0
- package/dist/tools/edit-targets.js.map +1 -0
- package/dist/tools/edit.d.ts +11 -3
- package/dist/tools/edit.js +387 -305
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/goals.d.ts +1 -1
- package/dist/tools/index.d.ts +19 -2
- package/dist/tools/index.js +47 -7
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/prompt-hints.js +6 -1
- package/dist/tools/prompt-hints.js.map +1 -1
- package/dist/tools/read-tracker.d.ts +5 -0
- package/dist/tools/read-tracker.js +19 -9
- package/dist/tools/read-tracker.js.map +1 -1
- package/dist/tools/read.js +3 -2
- package/dist/tools/read.js.map +1 -1
- package/dist/tools/skill.js +11 -3
- package/dist/tools/skill.js.map +1 -1
- package/dist/tools/subagent-control.js +44 -8
- package/dist/tools/subagent-control.js.map +1 -1
- package/dist/tools/subagent-shared.d.ts +29 -8
- package/dist/tools/subagent-shared.js +45 -14
- package/dist/tools/subagent-shared.js.map +1 -1
- package/dist/tools/subagent.d.ts +14 -2
- package/dist/tools/subagent.js +43 -13
- package/dist/tools/subagent.js.map +1 -1
- package/dist/tools/task-output.js +3 -2
- package/dist/tools/task-output.js.map +1 -1
- package/dist/tools/task-send.d.ts +1 -1
- package/dist/tools/task-send.js +15 -1
- package/dist/tools/task-send.js.map +1 -1
- package/dist/tools/tool-tiers.d.ts +8 -2
- package/dist/tools/tool-tiers.js +10 -3
- package/dist/tools/tool-tiers.js.map +1 -1
- package/dist/tools/truncate.d.ts +21 -0
- package/dist/tools/truncate.js +187 -0
- package/dist/tools/truncate.js.map +1 -1
- package/dist/tools/ui-adopt.js +2 -0
- package/dist/tools/ui-adopt.js.map +1 -1
- package/dist/ui/App.d.ts +0 -4
- package/dist/ui/App.js +12 -31
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/components/ActivityIndicator.js +1 -0
- package/dist/ui/components/ActivityIndicator.js.map +1 -1
- package/dist/ui/components/ToolExecution.js +3 -2
- package/dist/ui/components/ToolExecution.js.map +1 -1
- package/dist/ui/hooks/useAgentLoop.d.ts +1 -8
- package/dist/ui/hooks/useAgentLoop.js +1 -119
- package/dist/ui/hooks/useAgentLoop.js.map +1 -1
- package/dist/ui/render.d.ts +0 -4
- package/dist/ui/render.js +0 -2
- package/dist/ui/render.js.map +1 -1
- package/dist/ui/terminal-history.js +3 -1
- package/dist/ui/terminal-history.js.map +1 -1
- package/dist/ui/tool-line-summary.js +3 -1
- package/dist/ui/tool-line-summary.js.map +1 -1
- package/dist/utils/format.js +5 -1
- package/dist/utils/format.js.map +1 -1
- package/dist/utils/git.d.ts +77 -0
- package/dist/utils/git.js +285 -21
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/github-ci.js +2 -1
- package/dist/utils/github-ci.js.map +1 -1
- package/dist/utils/github.js +11 -9
- package/dist/utils/github.js.map +1 -1
- package/dist/utils/image.d.ts +14 -0
- package/dist/utils/image.js +16 -0
- package/dist/utils/image.js.map +1 -1
- package/dist/utils/process.d.ts +20 -0
- package/dist/utils/process.js +98 -0
- package/dist/utils/process.js.map +1 -1
- package/package.json +4 -4
- package/assets/motion/references/motion-language.md +0 -128
- package/assets/motion/skills/video-qa/SKILL.md +0 -89
- package/dist/core/ideal-review-subagent.d.ts +0 -56
- package/dist/core/ideal-review-subagent.js +0 -112
- package/dist/core/ideal-review-subagent.js.map +0 -1
- package/dist/core/ideal-review.d.ts +0 -82
- package/dist/core/ideal-review.js +0 -242
- package/dist/core/ideal-review.js.map +0 -1
- package/dist/motion-agent/motion-check-tool.d.ts +0 -35
- package/dist/motion-agent/motion-check-tool.js +0 -514
- package/dist/motion-agent/motion-check-tool.js.map +0 -1
package/dist/app-sidecar.js
CHANGED
|
@@ -39,11 +39,12 @@ import { isWorkflowCommandText, countAssistantMessages, shouldStartAutopilotCycl
|
|
|
39
39
|
import { driveAutopilotCycle, frameAutopilotInjection } from "./core/autopilot-cycle.js";
|
|
40
40
|
import { describeRunVerification, describeTurnVerification } from "./core/run-status.js";
|
|
41
41
|
import { validateNolanModelPref, effectiveNolanModel, } from "./core/nolan-model.js";
|
|
42
|
-
import { normalizeAutopilotMarkersForHistory, normalizeAppMarkersForHistory, normalizeNolanTurnsForHistory, getHistoryMessageVisibility, replayMessagesInOrder, restoreUserRow, restoreAssistantTexts, resolveRestoredCommand, autopilotMarkerCopySeed, } from "./core/session-history.js";
|
|
42
|
+
import { normalizeAutopilotMarkersForHistory, normalizeAppMarkersForHistory, normalizeNolanTurnsForHistory, getHistoryMessageVisibility, replayMessagesInOrder, restoreUserRow, restoreAssistantTexts, resolveRestoredCommand, autopilotMarkerCopySeed, extractToolImagePaths, } from "./core/session-history.js";
|
|
43
43
|
import { sessionToMarkdown, defaultExportFilename, } from "./core/session-export.js";
|
|
44
44
|
import { AuthStorage } from "./core/auth-storage.js";
|
|
45
45
|
import { advancesPhase, explainPullFailure, isGgufShard, isValidHfRepoId, parseOllamaPullLine, pickGgufQuant, SHARDED_MESSAGE, toHfSearchRow, } from "./hf-pull.js";
|
|
46
46
|
import { cleanupToolOutputs } from "./tools/overflow.js";
|
|
47
|
+
import { spawnedTasks } from "./tools/subagent-shared.js";
|
|
47
48
|
import { readCappedBody } from "./utils/http-body.js";
|
|
48
49
|
import { fetchSubscriptionUsage, SubscriptionUsageError, XIAOMI_CREDITS_KEY, dualAuthProvider, oauthStorageKey, discoverLocalModels, findProbedModel, formatLocalModelId, parseLocalModelId, probeEndpoint, toModelInfo as localModelInfo, } from "@prestyj/core";
|
|
49
50
|
import { LocalEndpointError, addCustomEndpoint, listAllEndpoints, removeCustomEndpoint, syncEndpointCredentials, } from "./core/local-endpoint-store.js";
|
|
@@ -63,6 +64,7 @@ import { getGitHubOpenCounts, getGitHubRepoSlug } from "./utils/github.js";
|
|
|
63
64
|
import { startGitHubCIPoll } from "./utils/github-ci.js";
|
|
64
65
|
import { extractPlanSteps } from "./utils/plan-steps.js";
|
|
65
66
|
import { getNextThinkingLevel, getSupportedThinkingLevels, isThinkingLevelSupported, } from "./core/thinking-level.js";
|
|
67
|
+
import { parseThinkingLevel } from "./cli/thinking-arg.js";
|
|
66
68
|
import { PROMPT_COMMANDS } from "./core/prompt-commands.js";
|
|
67
69
|
import { loadCustomCommands } from "./core/custom-commands.js";
|
|
68
70
|
import { discoverProjects } from "./core/project-discovery.js";
|
|
@@ -70,20 +72,25 @@ import { listSidecarSessions } from "./app-sidecar-sessions.js";
|
|
|
70
72
|
import { loadTasksSync, saveTasksSync, pruneDoneTasksSync, getNextPendingTask, markTaskInProgress, } from "./core/task-store.js";
|
|
71
73
|
import { initLogger, log } from "./core/logger.js";
|
|
72
74
|
import { installTerminationHandlers } from "./core/shutdown.js";
|
|
75
|
+
import { KeepAwake } from "./core/keep-awake.js";
|
|
73
76
|
import { RADIO_STATIONS, getCurrentStation, getRadioVolume, playRadio, setRadioVolume, stopRadio, } from "./core/radio.js";
|
|
74
77
|
import { enrichProcessPath } from "./core/shell-path.js";
|
|
75
|
-
import { downscaleForPreview, shrinkToFit, validateVisionImage } from "./utils/image.js";
|
|
78
|
+
import { downscaleForPreview, IMAGE_MEDIA_TYPES, shrinkToFit, validateVisionImage, } from "./utils/image.js";
|
|
79
|
+
import { readFileBounded } from "./tools/operations.js";
|
|
76
80
|
import { startServeMode } from "./modes/serve-mode.js";
|
|
77
81
|
import { installSteroids, probeSteroids } from "./core/steroids.js";
|
|
78
82
|
import { loadTelegramConfig, saveTelegramConfig, verifyBotToken } from "./core/telegram-config.js";
|
|
79
83
|
import { loadServers, addServer, removeServer, getServer, parseMcpAddCommand, MCPClientManager, McpOAuthStore, createElicitationBridge, } from "./core/mcp/index.js";
|
|
80
|
-
import { createAskUserBridge } from "./core/ask-user.js";
|
|
84
|
+
import { askSoftDeadlineMs, createAskUserBridge, deliverLateAnswer, } from "./core/ask-user.js";
|
|
81
85
|
import { createAskUserTool } from "./tools/ask-user.js";
|
|
82
86
|
import { buildSnapshot, levelForXp, rankForLevel } from "./core/progress/ranks.js";
|
|
83
87
|
import { loadProgress, peekProgress, updateProgress } from "./core/progress/store.js";
|
|
84
88
|
import { awardPrompt, awardCommits } from "./core/progress/engine.js";
|
|
85
89
|
import { detectNewCommits, repoKey } from "./core/progress/git-xp.js";
|
|
86
90
|
import { rebuildFromSessions } from "./core/progress/rebuild.js";
|
|
91
|
+
/** App-wide idle-sleep guard: every window's runs share one OS assertion. The
|
|
92
|
+
* `keepAwake` setting is applied at daemon start and live via /keep-awake. */
|
|
93
|
+
const keepAwake = new KeepAwake();
|
|
87
94
|
const AUTOMATION_PROVENANCE = {
|
|
88
95
|
source: "runtime",
|
|
89
96
|
kind: "automation",
|
|
@@ -488,6 +495,7 @@ async function runJsonModeIfRequested() {
|
|
|
488
495
|
tools: { type: "string" },
|
|
489
496
|
"mcp-servers": { type: "string" },
|
|
490
497
|
"prompt-cache-key": { type: "string" },
|
|
498
|
+
thinking: { type: "string" },
|
|
491
499
|
},
|
|
492
500
|
allowPositionals: true,
|
|
493
501
|
strict: true,
|
|
@@ -524,6 +532,7 @@ async function runJsonModeIfRequested() {
|
|
|
524
532
|
allowedTools,
|
|
525
533
|
allowedMcpServers,
|
|
526
534
|
promptCacheKey: values["prompt-cache-key"],
|
|
535
|
+
thinkingLevel: parseThinkingLevel(values.thinking),
|
|
527
536
|
}).catch(async (err) => {
|
|
528
537
|
process.stderr.write((err instanceof Error ? err.message : String(err)) + "\n");
|
|
529
538
|
process.exit(1);
|
|
@@ -570,6 +579,8 @@ async function main() {
|
|
|
570
579
|
// ~/.ezcoder/debug.log (initLogger truncates on each start).
|
|
571
580
|
const sidecarLog = path.join(paths.agentDir, "ezcoder-app-sidecar.log");
|
|
572
581
|
initLogger(sidecarLog);
|
|
582
|
+
// Apply the saved keepAwake setting before any run can acquire the guard.
|
|
583
|
+
keepAwake.setEnabled((await new SettingsManager(paths.settingsFile).load()).keepAwake);
|
|
573
584
|
// The desktop sidecar previously omitted the stream diagnostic hook used by
|
|
574
585
|
// the CLI, leaving device-specific provider stalls impossible to distinguish from
|
|
575
586
|
// event-loop starvation or a broken streaming network path. Keep routine
|
|
@@ -908,6 +919,40 @@ async function main() {
|
|
|
908
919
|
daemonJson(res, 200, { ok: true });
|
|
909
920
|
return;
|
|
910
921
|
}
|
|
922
|
+
// Keep-awake is app-wide (one OS assertion for every window), so its
|
|
923
|
+
// setting lives at the daemon level and applies live to in-flight runs.
|
|
924
|
+
if (method === "GET" && url === "/keep-awake") {
|
|
925
|
+
daemonJson(res, 200, { enabled: keepAwake.isEnabled });
|
|
926
|
+
return;
|
|
927
|
+
}
|
|
928
|
+
if (method === "POST" && url === "/keep-awake") {
|
|
929
|
+
void daemonReadBody(req, res).then(async (raw) => {
|
|
930
|
+
if (raw === null)
|
|
931
|
+
return;
|
|
932
|
+
let enabled;
|
|
933
|
+
try {
|
|
934
|
+
enabled = JSON.parse(raw).enabled;
|
|
935
|
+
}
|
|
936
|
+
catch {
|
|
937
|
+
enabled = undefined;
|
|
938
|
+
}
|
|
939
|
+
if (typeof enabled !== "boolean") {
|
|
940
|
+
daemonJson(res, 400, { error: "enabled must be a boolean" });
|
|
941
|
+
return;
|
|
942
|
+
}
|
|
943
|
+
keepAwake.setEnabled(enabled);
|
|
944
|
+
try {
|
|
945
|
+
const sm = new SettingsManager(paths.settingsFile);
|
|
946
|
+
await sm.load();
|
|
947
|
+
await sm.set("keepAwake", enabled);
|
|
948
|
+
}
|
|
949
|
+
catch (err) {
|
|
950
|
+
log("WARN", "app-sidecar", "failed to persist keepAwake", { err: String(err) });
|
|
951
|
+
}
|
|
952
|
+
daemonJson(res, 200, { enabled });
|
|
953
|
+
});
|
|
954
|
+
return;
|
|
955
|
+
}
|
|
911
956
|
// Progress is daemon-level so the Home screen can paint before a project
|
|
912
957
|
// session exists; per-session callers still work through the same endpoint.
|
|
913
958
|
if (method === "GET" && url === "/progress") {
|
|
@@ -955,9 +1000,16 @@ async function main() {
|
|
|
955
1000
|
const shutdown = installTerminationHandlers({
|
|
956
1001
|
scope: "app-sidecar",
|
|
957
1002
|
teardown: async () => {
|
|
1003
|
+
// Before any await: background commands live outside the daemon's process
|
|
1004
|
+
// group, and the app force-kills that group after 3 s. If a slow session
|
|
1005
|
+
// teardown is still pending then, these would never be stopped.
|
|
1006
|
+
for (const c of sessions.values())
|
|
1007
|
+
c.stopBackgroundProcesses();
|
|
958
1008
|
clearInterval(parentWatch);
|
|
959
1009
|
// Radio playback is app-wide (one stream across all windows).
|
|
960
1010
|
stopRadio();
|
|
1011
|
+
// Drop the idle-sleep assertion first: session teardown may hang.
|
|
1012
|
+
keepAwake.dispose();
|
|
961
1013
|
// Close the ~/.ezcoder progress fs.watch handle.
|
|
962
1014
|
progress.dispose();
|
|
963
1015
|
await Promise.all([...sessions.values()].map((c) => c.dispose().catch(() => { })));
|
|
@@ -1312,9 +1364,33 @@ async function createSession(deps, opts) {
|
|
|
1312
1364
|
// MCP bridge above: broadcast over SSE, resolved when the webview POSTs
|
|
1313
1365
|
// /ask/:id. Registered ONLY here — a TUI/headless/subagent run has nobody to
|
|
1314
1366
|
// answer, so the tool is absent there rather than hanging on a dead channel.
|
|
1367
|
+
//
|
|
1368
|
+
// Soft deadline ("async ask"): past it the tool returns "no answer yet —
|
|
1369
|
+
// proceed on your best guess" and the question STAYS OPEN. A later answer
|
|
1370
|
+
// rides the ordinary user queue: steering into a live run, or the next turn
|
|
1371
|
+
// when idle. The deadline is short when nobody is watching (autopilot, task
|
|
1372
|
+
// run-all, a scheduled prompt).
|
|
1373
|
+
let scheduledRunActive = false;
|
|
1315
1374
|
const asks = createAskUserBridge({
|
|
1316
1375
|
broadcast: (prompt) => broadcast("ask_user", prompt),
|
|
1317
|
-
|
|
1376
|
+
timeoutMs: () => askSoftDeadlineMs(autopilot || autopilotActive || taskRunAll || scheduledRunActive),
|
|
1377
|
+
onTimeout: (prompt) => {
|
|
1378
|
+
log("WARN", "app-sidecar", "ask_user deadline passed; agent proceeding", { id: prompt.id });
|
|
1379
|
+
broadcast("ask_user_deferred", { id: prompt.id });
|
|
1380
|
+
},
|
|
1381
|
+
onClosed: (ids) => broadcast("ask_user_closed", { ids }),
|
|
1382
|
+
onLateAnswer: (late) => {
|
|
1383
|
+
log("INFO", "app-sidecar", "ask_user late answer queued", { id: late.prompt.id });
|
|
1384
|
+
deliverLateAnswer(late, {
|
|
1385
|
+
queueMessage: (text) => session.queueMessage(text),
|
|
1386
|
+
isBusy: () => running || runClaim.active || autopilotActive,
|
|
1387
|
+
onQueued: () => broadcast("queued", {
|
|
1388
|
+
count: session.getQueuedCount(),
|
|
1389
|
+
messages: session.listQueuedMessages(),
|
|
1390
|
+
}),
|
|
1391
|
+
startIdleRun: () => void runStrandedQueue(),
|
|
1392
|
+
});
|
|
1393
|
+
},
|
|
1318
1394
|
});
|
|
1319
1395
|
const askUserTool = createAskUserTool(asks.park);
|
|
1320
1396
|
// The session file path to resume (passed by the daemon's POST /session);
|
|
@@ -1867,11 +1943,14 @@ async function createSession(deps, opts) {
|
|
|
1867
1943
|
if (!d.silent)
|
|
1868
1944
|
broadcast("retry", { reason: d.reason, attempt: d.attempt, delayMs: d.delayMs });
|
|
1869
1945
|
});
|
|
1946
|
+
session.eventBus.on("stream_rule_triggered", (d) => broadcast("stream_rule_triggered", { rules: d.rules, source: d.source, toolName: d.toolName }));
|
|
1870
1947
|
session.eventBus.on("max_turns", (d) => broadcast("max_turns", d));
|
|
1871
1948
|
// The agent consumed queued steering at a turn boundary. Re-broadcast as the
|
|
1872
1949
|
// usual `queued` depth update so the webview drops the pending affordance the
|
|
1873
1950
|
// moment the message lands in the loop, not at run_end.
|
|
1874
1951
|
session.eventBus.on("queue_drained", (d) => broadcast("queued", { count: d.count, messages: session.listQueuedMessages() }));
|
|
1952
|
+
// A fresh/loaded session must not receive late answers to the old one's questions.
|
|
1953
|
+
session.eventBus.on("session_start", () => asks.closeDeferred());
|
|
1875
1954
|
session.eventBus.on("tool_call_start", (d) => {
|
|
1876
1955
|
toolCallNames.set(d.toolCallId, d.name);
|
|
1877
1956
|
broadcast("tool_call_start", d);
|
|
@@ -1931,12 +2010,38 @@ async function createSession(deps, opts) {
|
|
|
1931
2010
|
session.eventBus.on("hook", (d) => broadcast("hook", d));
|
|
1932
2011
|
session.eventBus.on("diagnostics", (d) => broadcast("diagnostics", d));
|
|
1933
2012
|
// Fires BEFORE the candidate final answer streams. The webview holds assistant
|
|
1934
|
-
// text back while armed, so an
|
|
2013
|
+
// text back while armed, so an injected follow-up supersedes a draft that was never
|
|
1935
2014
|
// painted instead of deleting one the user already started reading.
|
|
1936
2015
|
session.eventBus.on("hook_armed", (d) => broadcast("hook_armed", d));
|
|
1937
2016
|
session.eventBus.on("subagent_state", (d) => broadcast("subagent_state", d));
|
|
1938
2017
|
session.eventBus.on("compaction_start", (d) => broadcast("compaction_start", d));
|
|
1939
2018
|
session.eventBus.on("compaction_end", (d) => broadcast("compaction_end", d));
|
|
2019
|
+
// Cold-prompt-cache notice: push the fresh TTL anchor + context size whenever
|
|
2020
|
+
// a run or compaction settles. Expiry itself is time-based, so the webview
|
|
2021
|
+
// also re-reads `cacheExpiry` from /state when the user returns or types.
|
|
2022
|
+
for (const ev of ["agent_done", "compaction_end", "model_change"]) {
|
|
2023
|
+
session.eventBus.on(ev, () => broadcast("cache_expiry", session.getCacheExpiryStatus()));
|
|
2024
|
+
}
|
|
2025
|
+
// Keep the computer awake while this window's agent works: owned runs and
|
|
2026
|
+
// autopilot cycles (RunLifecycle state), Nolan replies, and background
|
|
2027
|
+
// sub-agents that outlive their parent run. Released on settle (completed,
|
|
2028
|
+
// failed or cancelled) and on session dispose.
|
|
2029
|
+
let releaseRunAwake = null;
|
|
2030
|
+
let releaseSubagentAwake = null;
|
|
2031
|
+
const activeSubagents = new Set();
|
|
2032
|
+
session.eventBus.on("subagent_state", (d) => {
|
|
2033
|
+
if (d.state === "starting" || d.state === "running")
|
|
2034
|
+
activeSubagents.add(d.agent_id);
|
|
2035
|
+
else
|
|
2036
|
+
activeSubagents.delete(d.agent_id);
|
|
2037
|
+
if (activeSubagents.size > 0) {
|
|
2038
|
+
releaseSubagentAwake ??= keepAwake.acquire("subagent");
|
|
2039
|
+
}
|
|
2040
|
+
else {
|
|
2041
|
+
releaseSubagentAwake?.();
|
|
2042
|
+
releaseSubagentAwake = null;
|
|
2043
|
+
}
|
|
2044
|
+
});
|
|
1940
2045
|
let running = false;
|
|
1941
2046
|
// Closes the window between `/prompt` deciding to start a run and `runAgent`
|
|
1942
2047
|
// flipping `running` — that stretch awaits, so Node yields inside it. See
|
|
@@ -1944,6 +2049,13 @@ async function createSession(deps, opts) {
|
|
|
1944
2049
|
const runClaim = new RunClaim();
|
|
1945
2050
|
const runLifecycle = new RunLifecycle((runState) => {
|
|
1946
2051
|
running = runState !== "idle";
|
|
2052
|
+
if (running) {
|
|
2053
|
+
releaseRunAwake ??= keepAwake.acquire("run");
|
|
2054
|
+
}
|
|
2055
|
+
else {
|
|
2056
|
+
releaseRunAwake?.();
|
|
2057
|
+
releaseRunAwake = null;
|
|
2058
|
+
}
|
|
1947
2059
|
if (runState === "cancelling")
|
|
1948
2060
|
broadcast("run_cancelling", { runState });
|
|
1949
2061
|
},
|
|
@@ -1970,10 +2082,8 @@ async function createSession(deps, opts) {
|
|
|
1970
2082
|
// Autopilot (auto-review) toggle for THIS window's project. Loaded from
|
|
1971
2083
|
// ezcoder-app.json on boot; flipped via POST /autopilot. When on, POST /prompt runs
|
|
1972
2084
|
// runAutopilotCycle after the user's turn settles — Nolan auto-reviews the work
|
|
1973
|
-
// and drives the review→prompt→review loop.
|
|
1974
|
-
// owner in this mode, so suppress the build session's redundant Ideal hook.
|
|
2085
|
+
// and drives the review→prompt→review loop.
|
|
1975
2086
|
let autopilot = mode === "code" && (await loadAutopilot(cwd));
|
|
1976
|
-
session.setIdealReviewSuppressed(autopilot);
|
|
1977
2087
|
// True while an autopilot review is in flight (used to defer nolanAuto model
|
|
1978
2088
|
// switches, like nolanRunning does for chat Nolan, and to drive the spinner).
|
|
1979
2089
|
let autopilotReviewing = false;
|
|
@@ -2173,9 +2283,6 @@ async function createSession(deps, opts) {
|
|
|
2173
2283
|
// (often >5 min) regardless of the user's global speedProfile pick.
|
|
2174
2284
|
forceLongCacheRetention: true,
|
|
2175
2285
|
});
|
|
2176
|
-
// Nolan is already the independent autopilot reviewer; recursively running
|
|
2177
|
-
// his own Ideal self-review adds latency and can corrupt the verdict shape.
|
|
2178
|
-
nolanAgent.setIdealReviewSuppressed(true);
|
|
2179
2286
|
await nolanAgent.initialize();
|
|
2180
2287
|
// Keep review text/tools silent; report usage only for whole-task accounting.
|
|
2181
2288
|
nolanAgent.eventBus.on("turn_end", (d) => {
|
|
@@ -2444,7 +2551,6 @@ async function createSession(deps, opts) {
|
|
|
2444
2551
|
const generation = runLifecycle.begin(abortOwnedWork).generation;
|
|
2445
2552
|
pendingCancelDrain = null;
|
|
2446
2553
|
autopilotActive = true;
|
|
2447
|
-
session.setIdealReviewSuppressed(true);
|
|
2448
2554
|
// Generation captured by the last plan review; acceptPlan re-checks it so
|
|
2449
2555
|
// a user Accept/Reject landing mid-review always wins.
|
|
2450
2556
|
let planGenAtReview = -1;
|
|
@@ -2562,7 +2668,6 @@ async function createSession(deps, opts) {
|
|
|
2562
2668
|
}
|
|
2563
2669
|
finally {
|
|
2564
2670
|
autopilotActive = false;
|
|
2565
|
-
session.setIdealReviewSuppressed(autopilot);
|
|
2566
2671
|
finishOwnedGeneration(generation, true, session.getVerificationProblem() ? "unverified" : "completed");
|
|
2567
2672
|
queueMicrotask(() => void runStrandedQueue());
|
|
2568
2673
|
}
|
|
@@ -2861,6 +2966,7 @@ async function createSession(deps, opts) {
|
|
|
2861
2966
|
supportedThinkingLevels: getSupportedThinkingLevels(st.provider, st.model),
|
|
2862
2967
|
supportsVideo: getModel(st.model)?.supportsVideo ?? false,
|
|
2863
2968
|
autopilot,
|
|
2969
|
+
cacheExpiry: session.getCacheExpiryStatus(),
|
|
2864
2970
|
...nolanStatePayload(),
|
|
2865
2971
|
...footerExtras(),
|
|
2866
2972
|
});
|
|
@@ -3340,7 +3446,16 @@ async function createSession(deps, opts) {
|
|
|
3340
3446
|
// Pre-index tool results by toolCallId so we can pair tool calls with
|
|
3341
3447
|
// their results (for sub-agent status + image extraction).
|
|
3342
3448
|
const toolResultMap = new Map();
|
|
3449
|
+
// Tool name per call, so restore only trusts generate_image's own text
|
|
3450
|
+
// when it reads extra images from disk (an MCP server could fake it).
|
|
3451
|
+
const toolNameById = new Map();
|
|
3343
3452
|
for (const msg of messages) {
|
|
3453
|
+
if (msg.role === "assistant" && typeof msg.content !== "string") {
|
|
3454
|
+
for (const c of msg.content) {
|
|
3455
|
+
if (c.type === "tool_call")
|
|
3456
|
+
toolNameById.set(c.id, c.name);
|
|
3457
|
+
}
|
|
3458
|
+
}
|
|
3344
3459
|
if (msg.role !== "tool")
|
|
3345
3460
|
continue;
|
|
3346
3461
|
for (const tr of msg.content) {
|
|
@@ -3500,31 +3615,43 @@ async function createSession(deps, opts) {
|
|
|
3500
3615
|
const imageBlocks = tr.content.filter((c) => c.type === "image");
|
|
3501
3616
|
if (imageBlocks.length === 0)
|
|
3502
3617
|
continue;
|
|
3503
|
-
// Extract the path from the text block
|
|
3618
|
+
// Extract the path from the text block so the restored image
|
|
3619
|
+
// stays clickable (read / screenshot / generate_image formats).
|
|
3504
3620
|
const textBlock = tr.content.find((c) => c.type === "text" && "text" in c && typeof c.text === "string");
|
|
3505
3621
|
const textContent = textBlock && textBlock.type === "text" ? textBlock.text : "";
|
|
3506
|
-
const
|
|
3507
|
-
|
|
3508
|
-
//
|
|
3622
|
+
const imgPaths = extractToolImagePaths(textContent);
|
|
3623
|
+
// Downscale each image for the webview preview. Paths pair with
|
|
3624
|
+
// image blocks in order (a tool saves one file per image).
|
|
3509
3625
|
const toolImages = [];
|
|
3626
|
+
let blockIndex = 0;
|
|
3510
3627
|
for (const block of imageBlocks) {
|
|
3511
3628
|
if (block.type !== "image")
|
|
3512
3629
|
continue;
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3630
|
+
const imgPath = imgPaths[blockIndex++];
|
|
3631
|
+
const previewBuf = await downscaleForPreview(Buffer.from(block.data, "base64"));
|
|
3632
|
+
toolImages.push({
|
|
3633
|
+
src: `data:${block.mediaType};base64,${previewBuf.toString("base64")}`,
|
|
3634
|
+
path: imgPath,
|
|
3635
|
+
});
|
|
3636
|
+
}
|
|
3637
|
+
// generate_image persists only its first image's pixels; the
|
|
3638
|
+
// rest exist only on disk, so preview them from their files.
|
|
3639
|
+
// Skip silently if a file was moved or deleted since.
|
|
3640
|
+
const extraPaths = toolNameById.get(tr.toolCallId) === "generate_image"
|
|
3641
|
+
? imgPaths.slice(blockIndex)
|
|
3642
|
+
: [];
|
|
3643
|
+
for (const extraPath of extraPaths) {
|
|
3644
|
+
const mediaType = IMAGE_MEDIA_TYPES[path.extname(extraPath).toLowerCase()];
|
|
3645
|
+
if (!mediaType)
|
|
3646
|
+
continue;
|
|
3647
|
+
const raw = await readFileBounded(extraPath).catch(() => null);
|
|
3648
|
+
if (!raw)
|
|
3649
|
+
continue;
|
|
3650
|
+
const previewBuf = await downscaleForPreview(raw);
|
|
3651
|
+
toolImages.push({
|
|
3652
|
+
src: `data:${mediaType};base64,${previewBuf.toString("base64")}`,
|
|
3653
|
+
path: extraPath,
|
|
3654
|
+
});
|
|
3528
3655
|
}
|
|
3529
3656
|
if (toolImages.length > 0) {
|
|
3530
3657
|
history.push({
|
|
@@ -3609,18 +3736,25 @@ async function createSession(deps, opts) {
|
|
|
3609
3736
|
if (msg.role === "assistant" && typeof msg.content !== "string") {
|
|
3610
3737
|
const subagentCalls = msg.content.filter((c) => c.type === "tool_call" && (c.name === "subagent" || c.name === "spawn_agent"));
|
|
3611
3738
|
if (subagentCalls.length > 0) {
|
|
3612
|
-
const agents = subagentCalls.
|
|
3739
|
+
const agents = subagentCalls.flatMap((c) => {
|
|
3613
3740
|
const result = toolResultMap.get(c.id);
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
}
|
|
3741
|
+
// Async workers are intentionally non-resumable; restored rows are historical.
|
|
3742
|
+
const status = result?.isError ? "error" : "done";
|
|
3743
|
+
if (c.name === "spawn_agent") {
|
|
3744
|
+
// One row per child: a batch call starts several.
|
|
3745
|
+
return spawnedTasks(c.args).map((spawn) => ({
|
|
3746
|
+
agentName: spawn.task_name ?? spawn.agent,
|
|
3747
|
+
status,
|
|
3748
|
+
toolUseCount: 0,
|
|
3749
|
+
}));
|
|
3750
|
+
}
|
|
3751
|
+
return [
|
|
3752
|
+
{
|
|
3753
|
+
agentName: typeof c.args?.agent === "string" ? c.args.agent : undefined,
|
|
3754
|
+
status,
|
|
3755
|
+
toolUseCount: 0,
|
|
3756
|
+
},
|
|
3757
|
+
];
|
|
3624
3758
|
});
|
|
3625
3759
|
history.push({
|
|
3626
3760
|
role: "assistant",
|
|
@@ -3754,6 +3888,8 @@ async function createSession(deps, opts) {
|
|
|
3754
3888
|
// Claim the run NOW, synchronously. Everything below this line may
|
|
3755
3889
|
// yield, and `running` does not flip until runAgent begins.
|
|
3756
3890
|
claimedStart = runClaim.claim();
|
|
3891
|
+
// A scheduled prompt has nobody watching: short ask deadline.
|
|
3892
|
+
scheduledRunActive = meta?.scheduled === true;
|
|
3757
3893
|
json(res, 202, { accepted: true });
|
|
3758
3894
|
// Gate inputs captured around the run: whether this turn is a workflow
|
|
3759
3895
|
// slash command (attachment prompts skip slash expansion entirely), and
|
|
@@ -3852,8 +3988,10 @@ async function createSession(deps, opts) {
|
|
|
3852
3988
|
await runStrandedQueue();
|
|
3853
3989
|
})
|
|
3854
3990
|
.finally(() => {
|
|
3855
|
-
if (claimedStart)
|
|
3991
|
+
if (claimedStart) {
|
|
3992
|
+
scheduledRunActive = false;
|
|
3856
3993
|
runClaim.release();
|
|
3994
|
+
}
|
|
3857
3995
|
});
|
|
3858
3996
|
return;
|
|
3859
3997
|
}
|
|
@@ -3889,6 +4027,7 @@ async function createSession(deps, opts) {
|
|
|
3889
4027
|
}
|
|
3890
4028
|
json(res, 202, { accepted: true });
|
|
3891
4029
|
nolanRunning = true;
|
|
4030
|
+
const releaseNolanAwake = keepAwake.acquire("nolan");
|
|
3892
4031
|
broadcast("nolan_run_start", { text });
|
|
3893
4032
|
try {
|
|
3894
4033
|
const nolanAgent = await ensureNolanSession();
|
|
@@ -3905,6 +4044,7 @@ async function createSession(deps, opts) {
|
|
|
3905
4044
|
broadcastError("nolan_error", "nolan run failed", err);
|
|
3906
4045
|
}
|
|
3907
4046
|
finally {
|
|
4047
|
+
releaseNolanAwake();
|
|
3908
4048
|
nolanRunning = false;
|
|
3909
4049
|
broadcast("nolan_run_end", {});
|
|
3910
4050
|
const pending = pendingNolanModel;
|
|
@@ -3943,9 +4083,6 @@ async function createSession(deps, opts) {
|
|
|
3943
4083
|
return;
|
|
3944
4084
|
}
|
|
3945
4085
|
autopilot = enabled;
|
|
3946
|
-
// A toggle-off during an active cycle takes effect after Nolan finishes;
|
|
3947
|
-
// until then, injected build runs must not re-enable Ideal self-review.
|
|
3948
|
-
session.setIdealReviewSuppressed(enabled || autopilotActive);
|
|
3949
4086
|
await saveAutopilot(cwd, enabled);
|
|
3950
4087
|
log("INFO", "app-sidecar", "autopilot toggled", { enabled: String(enabled) });
|
|
3951
4088
|
broadcast("autopilot", { autopilot: enabled });
|
|
@@ -4471,6 +4608,18 @@ async function createSession(deps, opts) {
|
|
|
4471
4608
|
json(res, 200, payload);
|
|
4472
4609
|
return;
|
|
4473
4610
|
}
|
|
4611
|
+
if (method === "POST" && url === "/prewarm") {
|
|
4612
|
+
// Best-effort Anthropic cache prewarm on the composer's first keystroke.
|
|
4613
|
+
// Fire-and-forget: AgentSession.prewarm() applies its own gating (provider,
|
|
4614
|
+
// setting, history size, TTL, in-flight) and swallows request errors.
|
|
4615
|
+
if (!running) {
|
|
4616
|
+
void session.prewarm().catch((err) => {
|
|
4617
|
+
log("WARN", "app-sidecar", "prewarm failed", { err: String(err) });
|
|
4618
|
+
});
|
|
4619
|
+
}
|
|
4620
|
+
json(res, 202, { accepted: !running });
|
|
4621
|
+
return;
|
|
4622
|
+
}
|
|
4474
4623
|
if (method === "POST" && url === "/cancel") {
|
|
4475
4624
|
void (async () => {
|
|
4476
4625
|
// Even between task runs, cancellation stops the sweep. Active provider
|
|
@@ -5327,6 +5476,10 @@ async function createSession(deps, opts) {
|
|
|
5327
5476
|
json(res, 404, { error: "not found" });
|
|
5328
5477
|
}
|
|
5329
5478
|
async function dispose() {
|
|
5479
|
+
releaseRunAwake?.();
|
|
5480
|
+
releaseRunAwake = null;
|
|
5481
|
+
releaseSubagentAwake?.();
|
|
5482
|
+
releaseSubagentAwake = null;
|
|
5330
5483
|
elicitations.cancelAll();
|
|
5331
5484
|
asks.cancelAll();
|
|
5332
5485
|
tasksPollStopped = true;
|
|
@@ -5350,6 +5503,11 @@ async function createSession(deps, opts) {
|
|
|
5350
5503
|
await nolanAutoSession?.dispose().catch(() => { });
|
|
5351
5504
|
await session.dispose().catch(() => { });
|
|
5352
5505
|
}
|
|
5506
|
+
function stopBackgroundProcesses() {
|
|
5507
|
+
session.stopBackgroundProcesses();
|
|
5508
|
+
nolanSession?.stopBackgroundProcesses();
|
|
5509
|
+
nolanAutoSession?.stopBackgroundProcesses();
|
|
5510
|
+
}
|
|
5353
5511
|
return {
|
|
5354
5512
|
id: opts.id,
|
|
5355
5513
|
mode,
|
|
@@ -5363,6 +5521,7 @@ async function createSession(deps, opts) {
|
|
|
5363
5521
|
broadcast,
|
|
5364
5522
|
handle,
|
|
5365
5523
|
dispose,
|
|
5524
|
+
stopBackgroundProcesses,
|
|
5366
5525
|
};
|
|
5367
5526
|
}
|
|
5368
5527
|
main().catch(async (err) => {
|