@tea-agent/loop-agent 0.43.0-next.1 → 0.43.0-next.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +129 -9
- package/dist/application/dag/run-dag.js +5 -0
- package/dist/application/evaluation/budget.js +19 -1
- package/dist/application/task-lifecycle/advance.js +17 -4
- package/dist/application/task-lifecycle/observe.js +43 -29
- package/dist/application/task-lifecycle/plan-transitions.js +5 -4
- package/dist/build-stamp.json +3 -3
- package/dist/executors/dag-pi-executor.js +1214 -584
- package/dist/executors/pi-executor.js +22 -1
- package/dist/executors/pi-sdk-executor.js +140 -39
- package/dist/executors/shell-executor.js +5 -2
- package/dist/shared/frontend-execution-policy.js +23 -0
- package/dist/task/config-types.js +4 -0
- package/dist/task/source-prepare/ledger-reconciliation.js +2 -2
- package/dist/task/source-prepare/ledger-review.js +6 -9
- package/dist/task/source-prepare/semantic-intake.js +16 -26
- package/dist/task/source-prepare/source-fidelity-pi.js +28 -9
- package/dist/task/source-references.js +48 -23
- package/dist/worker/console/chat/assistant-content.js +23 -2
- package/dist/worker/console/chat/browser-policy.js +143 -0
- package/dist/worker/console/chat/browser-routes.js +148 -0
- package/dist/worker/console/chat/explore-tools.js +13 -0
- package/dist/worker/console/chat/pi-runtime/custom-tools/ask-user-question.js +44 -0
- package/dist/worker/console/chat/pi-runtime/custom-tools/explore-tools.js +202 -0
- package/dist/worker/console/chat/pi-runtime/custom-tools/goal-tools.js +78 -0
- package/dist/worker/console/chat/pi-runtime/custom-tools/operator-tools.js +86 -0
- package/dist/worker/console/chat/pi-runtime/custom-tools/todo-write.js +38 -0
- package/dist/worker/console/chat/pi-runtime/inspection-types.js +28 -0
- package/dist/worker/console/chat/pi-runtime/inspection.js +439 -0
- package/dist/worker/console/chat/pi-runtime/sdk-bindings.js +153 -0
- package/dist/worker/console/chat/pi-runtime/sdk-session.js +5 -0
- package/dist/worker/console/chat/pi-runtime.js +213 -1181
- package/dist/worker/console/chat/routes.js +212 -71
- package/dist/worker/console/chat/scm-routes.js +217 -0
- package/dist/worker/console/chat/scm-service.js +283 -0
- package/dist/worker/console/chat/scm-tools.js +111 -0
- package/dist/worker/console/chat/sdd-data-alignment.js +65 -9
- package/dist/worker/console/chat/session-catalog.js +32 -0
- package/dist/worker/console/chat/session-mode-view.js +48 -0
- package/dist/worker/console/chat/session-mode.js +218 -0
- package/dist/worker/console/chat/session-store.js +22 -6
- package/dist/worker/console/chat/shortcuts.js +6 -0
- package/dist/worker/console/chat/terminal-routes.js +216 -0
- package/dist/worker/console/chat/terminal-sessions.js +348 -0
- package/dist/worker/console/chat/terminal-tools.js +211 -0
- package/dist/worker/console/chat/tool-preview.js +11 -0
- package/dist/worker/console/chat/tools.js +2 -0
- package/dist/worker/console/server.js +2 -28
- package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-B0Q0nClf.js → abnfDiagram-N423BO3Z-D_fNbWc_.js} +1 -1
- package/dist/worker/console/static/assets/{arc-DCPjC19G.js → arc-_HuqLW6m.js} +1 -1
- package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-CP5n9jmG.js → architectureDiagram-T3A2C74G-Djy2qY1m.js} +1 -1
- package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-CmaWi_Wg.js → blockDiagram-VBNYF7ZC-bB-1TSyY.js} +1 -1
- package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-Ct5tcMfZ.js → c4Diagram-5PPSVZJV-C5Hmghrz.js} +1 -1
- package/dist/worker/console/static/assets/channel-C0A6UEIa.js +1 -0
- package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-C0osm1Zf.js → chunk-2GRJ4B5K-Duyl39oy.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-CDWviED7.js → chunk-2Q5K7J3B-x6mdnSyf.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5RXB4S5H-mtSk1-j7.js → chunk-5RXB4S5H-WlBuFj7W.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5VM5RSS4-D5J9PHC7.js → chunk-5VM5RSS4-CTF429HX.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-Begg4WAa.js → chunk-6Q2QTUOP-Dwd6r-SF.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-GF5L2VYU-sF1AEy7T.js → chunk-GF5L2VYU-C-Br82D1.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-JWPE2WC7-BqbsWXZb.js → chunk-JWPE2WC7-CuGp0DeE.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-KBJHAD2P-BKJrPcJ6.js → chunk-KBJHAD2P-CJhFX6Lh.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-RYQCIY6F-CcwNMRho.js → chunk-RYQCIY6F-DpGOa_jT.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-XXDRQBXY-BEJi3iIs.js → chunk-XXDRQBXY-DXJaTynd.js} +1 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-DzguNppy.js +1 -0
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-DzguNppy.js +1 -0
- package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-DRLgTvVu.js → cose-bilkent-JH36ORCC-CRBZWjE4.js} +1 -1
- package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-BoAVG3cs.js → cynefin-VYW2F7L2-BdXcxtlb.js} +1 -1
- package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-Bzol06hR.js → cynefinDiagram-MW4NZA55-07UKsOts.js} +1 -1
- package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-UmliJM77.js → dagre-VZM6K2ZE-D38p9__S.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-7IWD3JNH-BWLcJkFo.js → diagram-7IWD3JNH-nSiBNNjH.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-CgApOm-O.js → diagram-B4RE2ZJO-BFOTot5D.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-LBJQPF4R-Bh3RgTLs.js → diagram-LBJQPF4R-DypKaZ6k.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-Q27KOJAE-Dsh-D5nE.js → diagram-Q27KOJAE-B6yoOQeW.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-UB23O5K3-Dkbbpcpb.js → diagram-UB23O5K3-BHYS6viX.js} +1 -1
- package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-3EBaA3t3.js → ebnfDiagram-BXEA7PRR-D2VD5Snj.js} +1 -1
- package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-Bq2Dc5ok.js → erDiagram-JOGREHBK-E98mWxN1.js} +1 -1
- package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-De7y55ha.js → flowDiagram-UKHOOZJN-CT1zxhqP.js} +1 -1
- package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-fLiDbQRh.js → ganttDiagram-PKOTCBZU-6GcngNcy.js} +1 -1
- package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-Du617mp1.js → gitGraphDiagram-DS77QQ5N-DCL6NvKe.js} +1 -1
- package/dist/worker/console/static/assets/index-24jp3aBh.js +468 -0
- package/dist/worker/console/static/assets/index-CY6y6I8M.css +1 -0
- package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-BwmlF-XP.js → infoDiagram-6WML65LV-C0627e-9.js} +1 -1
- package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-zsGtS59u.js → ishikawaDiagram-WSZJBQD7-C_u3P6Ik.js} +1 -1
- package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-DTTPTe3f.js → journeyDiagram-NVQOT4AX-DPDPv9HL.js} +1 -1
- package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-BkXg9aP-.js → kanban-definition-27J2QSJJ-D3OHdWiO.js} +1 -1
- package/dist/worker/console/static/assets/{linear-7U2ue5IE.js → linear-DI88zD7n.js} +1 -1
- package/dist/worker/console/static/assets/{mermaid.core-BUuGHmWO.js → mermaid.core-p2l8IrWY.js} +5 -5
- package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-7q6fX0Sv.js → mindmap-definition-FAOFIHXS-B1bAX-oS.js} +1 -1
- package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-CkQPJN55.js → pegDiagram-VL7TDLO6-DwOnWxdD.js} +1 -1
- package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-CCal_tfX.js → pieDiagram-7S7Q4E2Y-xRkTXnJC.js} +1 -1
- package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-B7bpxyAZ.js → quadrantDiagram-CIZ2JOQS-_9UC5Zio.js} +1 -1
- package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-CJmww7D-.js → railroadDiagram-AXF67PYL-CgEUirWJ.js} +1 -1
- package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-D6ldWJEv.js → requirementDiagram-LRYGKXZP-Czbpwiyz.js} +1 -1
- package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-VGh33I9e.js → sankeyDiagram-W5VNT64P-_j7_KiqY.js} +1 -1
- package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-CCkDrIjU.js → sequenceDiagram-SI44F4Z6-BNJa6Hyi.js} +1 -1
- package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-NC8f5Otb.js → sizeCapture-X5ZJPWSS-DedpKtOc.js} +1 -1
- package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-_92ezZdF.js → stateDiagram-OKZ733FA-BBvthr7c.js} +1 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-BABVQnfM.js +1 -0
- package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-BdUCGtbP.js → swimlanes-SLNWSIFB-Ds7umgEM.js} +2 -2
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-D0qsLaxR.js +8 -0
- package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-CdD1H8ia.js → timeline-definition-Z64GVDOM-CKa-p1nF.js} +1 -1
- package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-Dkdk3oFo.js → vennDiagram-T6HMQDX7-LoUNR56o.js} +1 -1
- package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-CKu2uPPY.js → wardleyDiagram-T6FBY63Y-Bqbl6ym7.js} +1 -1
- package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-ClqAnuG8.js → xychartDiagram-ELKLHX3M-B8dUg4lf.js} +1 -1
- package/dist/worker/console/static/index.html +2 -2
- package/dist/worker/console/static-src/operator-chat/active-turn-tail.js +10 -0
- package/dist/worker/console/static-src/operator-chat/chat-link.js +94 -0
- package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +122 -10
- package/dist/worker/console/static-src/operator-chat/compaction-message.js +7 -0
- package/dist/worker/console/static-src/operator-chat/pending-user-message.js +27 -15
- package/dist/worker/console/static-src/operator-chat/process-label.js +41 -0
- package/dist/worker/console/static-src/operator-chat/turn-group-equality.js +13 -0
- package/dist/worker/console/static-src/operator-chat/turn-process-disclosure.js +10 -0
- package/dist/worker/console/static-src/operator-chat/use-searchable-hidden.js +51 -0
- package/dist/worker/console/static-src/operator-chat/useChatSessions.js +44 -24
- package/dist/worker/console/static-src/operator-chat/useChatStream.js +18 -2
- package/dist/worker/console/static-src/operator-chat/useChatThread.js +41 -8
- package/dist/worker/console/static-src/operator-chat/useComposer.js +26 -11
- package/dist/worker/console/static-src/operator-chat/user-turn-anchor-equality.js +21 -0
- package/dist/worker/console/workspace-context.js +15 -1
- package/dist/worker/observe/node-transparency.js +81 -72
- package/dist/worker/observe/routes.js +20 -1
- package/dist/worker/observe/static/dag-inspector-humanize.js +3 -0
- package/dist/worker/observe/static/dom.js +20 -1
- package/dist/worker/observe/static/format-pool.d.ts +2 -0
- package/dist/worker/observe/static/format-pool.js +6 -0
- package/dist/worker/observe/static/format.js +7 -0
- package/dist/worker/observe/static/inspect-workspace.js +34 -7
- package/dist/worker/observe/static/inspector-submission.js +32 -0
- package/dist/worker/observe/static/kpi.js +1 -0
- package/dist/worker/observe/static/relations.js +2 -0
- package/dist/worker/observe/static/router.js +13 -0
- package/dist/worker/observe/static/run-processing.js +2 -0
- package/dist/worker/observe/static/shell-chrome.js +36 -3
- package/dist/worker/observe/static/state.js +35 -2
- package/dist/worker/observe/static/styles.css +263 -39
- package/dist/worker/observe/static/task-failure-labels.d.ts +4 -0
- package/dist/worker/observe/static/task-failure-labels.js +67 -0
- package/dist/worker/observe/static/task-history.js +12 -0
- package/dist/worker/observe/static/views/batch.js +6 -13
- package/dist/worker/observe/static/views/dag-graph.js +50 -3
- package/dist/worker/observe/static/views/dag-inspector.js +742 -268
- package/dist/worker/observe/static/views/dag-trajectory.js +3 -0
- package/dist/worker/observe/static/views/dag.d.ts +6 -0
- package/dist/worker/observe/static/views/dag.js +49 -11
- package/dist/worker/observe/static/views/dags.js +2 -0
- package/dist/worker/observe/static/views/dashboard.js +21 -12
- package/dist/worker/observe/static/views/failures.js +21 -11
- package/dist/worker/observe/static/views/feature.js +11 -29
- package/dist/worker/observe/static/views/pool.js +37 -28
- package/dist/worker/observe/static/views/run.js +48 -5
- package/dist/worker/observe/static/views/session-timeline.js +189 -240
- package/dist/worker/observe/static/views/task.js +81 -62
- package/dist/workflows/dag/budget-enforcement.js +53 -3
- package/dist/workflows/dag/frontend-capacity.js +9 -0
- package/dist/workflows/dag/frontend-design-policy.js +2 -1
- package/dist/workflows/dag/frontend-durable-tools.js +193 -0
- package/dist/workflows/dag/frontend-execution-groups.js +24 -0
- package/dist/workflows/dag/frontend-implementation-contract.js +13 -0
- package/dist/workflows/dag/frontend-input-projection.js +76 -0
- package/dist/workflows/dag/frontend-plan-completeness.js +186 -0
- package/dist/workflows/dag/frontend-plan-recovery-policy.js +18 -0
- package/dist/workflows/dag/frontend-plan-render.js +10 -3
- package/dist/workflows/dag/frontend-recovery-controller.js +7 -7
- package/dist/workflows/dag/frontend-recovery-lineage.js +13 -0
- package/dist/workflows/dag/frontend-recovery-run.js +4 -0
- package/dist/workflows/dag/frontend-review-scopes.js +139 -0
- package/dist/workflows/dag/frontend-session-budget.js +249 -0
- package/dist/workflows/dag/frontend-shadow-dual-write.js +20 -2
- package/dist/workflows/dag/frontend-shape-facts.js +12 -2
- package/dist/workflows/dag/frontend-shape.js +30 -1
- package/dist/workflows/dag/frontend-test-execution-evidence.js +3 -2
- package/dist/workflows/dag/frontend-typed-event-store.js +11 -0
- package/dist/workflows/dag/init-hybrid.js +16 -10
- package/dist/workflows/dag/node-execution.js +38 -155
- package/dist/workflows/dag/prompt.js +4 -0
- package/dist/workflows/dag/rerun-plan.js +7 -1
- package/dist/workflows/dag/runner.js +26 -1
- package/dist/workflows/dag/types.js +6 -0
- package/docs/operations/README.md +1 -0
- package/docs/templates/frontend-design-contract.md +4 -4
- package/docs/templates/frontend-implementation-contract.schema.json +34 -2
- package/docs/templates/frontend-implementation-dag.json +5 -5
- package/package.json +6 -3
- package/skills/frontend-contract/SKILL.md +2 -1
- package/skills/frontend-contract/references/contract-protocol.md +19 -3
- package/skills/frontend-design-review/SKILL.md +12 -11
- package/skills/frontend-plan/SKILL.md +9 -2
- package/skills/frontend-plan/references/decision-contract.md +18 -5
- package/skills/frontend-review/SKILL.md +10 -11
- package/skills/frontend-scout/references/scout-evidence.md +4 -0
- package/dist/worker/console/static/assets/channel-DAS07MdS.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-Cwk-5jiW.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-Cwk-5jiW.js +0 -1
- package/dist/worker/console/static/assets/index-C0O48S_P.js +0 -449
- package/dist/worker/console/static/assets/index-CzKf4U8P.css +0 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-DyJg5gzW.js +0 -1
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-B1cw_0Uy.js +0 -8
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Operator Chat — model-facing persistent terminal tools (DSH-style).
|
|
3
|
+
*
|
|
4
|
+
* Registers `terminal` (single tool managing named persistent shells) so the
|
|
5
|
+
* model can run commands in a REAL persistent PTY: cwd, env vars, activated
|
|
6
|
+
* virtualenvs and background jobs survive across calls, exactly like the DSH
|
|
7
|
+
* persistent bash/pwsh tools.
|
|
8
|
+
*
|
|
9
|
+
* Protocol (completion-marker, same idea as DSH):
|
|
10
|
+
* 1. tool writes `command + unique echo marker + newline`
|
|
11
|
+
* 2. waits until the marker line appears in PTY output
|
|
12
|
+
* 3. returns output captured since the send (bounded), plus exit-code echo
|
|
13
|
+
*
|
|
14
|
+
* Lifecycle: shells are owned by the chat session id; `terminal_list`,
|
|
15
|
+
* `terminal_kill` manage them. Console UI can attach to the same PTYs via the
|
|
16
|
+
* terminal HTTP API (same registry).
|
|
17
|
+
*/
|
|
18
|
+
import { TerminalSessionError, availableShellKinds, } from "./terminal-sessions.js";
|
|
19
|
+
const MAX_OUTPUT_CHARS = 16_000;
|
|
20
|
+
const DEFAULT_TIMEOUT_MS = 120_000;
|
|
21
|
+
const MARKER_PREFIX = "__DSH_TERM_DONE_";
|
|
22
|
+
const TOOL_DESCRIPTION = "Run commands in a persistent terminal (real PTY). State survives across calls: cwd, env vars, activated environments, functions, and background jobs. " +
|
|
23
|
+
"Actions: 'run' executes a command in the owner's shell of the given kind (auto-creates on first use, reuses afterwards; avoid interactive commands that wait for stdin); " +
|
|
24
|
+
"'list' shows active shells; 'kill' stops one. Prefer this over one-shot bash for multi-step work needing shared state (build → test → inspect) or long-running dev servers. " +
|
|
25
|
+
"Output is bounded; long output keeps the earliest readable prefix. On timeout the command output so far is returned (the shell keeps running — use 'kill' or run an interrupt to stop it). " +
|
|
26
|
+
"The shell parameter accepts only kinds available on the host platform.";
|
|
27
|
+
export async function buildPersistentTerminalTools(deps) {
|
|
28
|
+
const [{ Type }, { defineTool }] = await Promise.all([
|
|
29
|
+
import("typebox"),
|
|
30
|
+
import("@earendil-works/pi-coding-agent"),
|
|
31
|
+
]);
|
|
32
|
+
/** Resolve the owner's shell for a kind, spawning on first use. */
|
|
33
|
+
const ensureShell = (kind, cwd) => {
|
|
34
|
+
const existing = deps.registry
|
|
35
|
+
.list(deps.ownerSessionId)
|
|
36
|
+
.find((s) => s.shell === kind && !s.exited);
|
|
37
|
+
if (existing)
|
|
38
|
+
return existing;
|
|
39
|
+
return deps.registry.spawn({
|
|
40
|
+
ownerSessionId: deps.ownerSessionId,
|
|
41
|
+
name: kind,
|
|
42
|
+
shell: kind,
|
|
43
|
+
cwd: cwd ?? deps.defaultCwd ?? process.cwd(),
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
const runInShell = async (kind, command, timeoutMs) => {
|
|
47
|
+
const shellInfo = ensureShell(kind);
|
|
48
|
+
const marker = `${MARKER_PREFIX}${Date.now().toString(36)}${Math.random()
|
|
49
|
+
.toString(36)
|
|
50
|
+
.slice(2, 8)}`;
|
|
51
|
+
// Exit-code echo per shell:
|
|
52
|
+
// - PowerShell: $LASTEXITCODE
|
|
53
|
+
// - bash / zsh: $?
|
|
54
|
+
// - cmd.exe: %ERRORLEVEL% (interpolation happens before echo runs,
|
|
55
|
+
// so we use `prompt` substitution style `echo MARKER:%ERRORLEVEL%`).
|
|
56
|
+
const exitEcho = kind === "powershell"
|
|
57
|
+
? `Write-Host "${marker}:$LASTEXITCODE"`
|
|
58
|
+
: kind === "cmd"
|
|
59
|
+
? `echo ${marker}:%ERRORLEVEL%`
|
|
60
|
+
: `echo "${marker}:$?"`;
|
|
61
|
+
const wrapped = `${command}\n${exitEcho}\n`;
|
|
62
|
+
// Capture output from the moment of send until the marker line shows up.
|
|
63
|
+
const pending = [];
|
|
64
|
+
let settled = false;
|
|
65
|
+
const unsubscribe = deps.registry.subscribe(shellInfo.sessionId, (chunk) => {
|
|
66
|
+
pending.push(chunk);
|
|
67
|
+
});
|
|
68
|
+
// Drain anything already in the ring buffer boundary: we only want output
|
|
69
|
+
// produced after this send, so snapshot totalOutputChars first.
|
|
70
|
+
const startTotal = deps.registry.get(shellInfo.sessionId).totalOutputChars;
|
|
71
|
+
// Re-read after subscribing; chunks between snapshot and send are benign
|
|
72
|
+
// (they precede the marker) and get filtered by the marker search below.
|
|
73
|
+
let captured = "";
|
|
74
|
+
const collect = () => {
|
|
75
|
+
captured = pending.join("");
|
|
76
|
+
};
|
|
77
|
+
try {
|
|
78
|
+
deps.registry.send(shellInfo.sessionId, wrapped);
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
unsubscribe();
|
|
82
|
+
return `error: ${error instanceof TerminalSessionError
|
|
83
|
+
? `${error.code} ${error.message}`
|
|
84
|
+
: error instanceof Error
|
|
85
|
+
? error.message
|
|
86
|
+
: String(error)}`;
|
|
87
|
+
}
|
|
88
|
+
const deadline = Date.now() + timeoutMs;
|
|
89
|
+
const markerRe = new RegExp(`${marker}:(\\d+)\\s*(${"\\r"}|\\n|$)`);
|
|
90
|
+
let exitCode;
|
|
91
|
+
return await new Promise((resolve) => {
|
|
92
|
+
const poll = () => {
|
|
93
|
+
collect();
|
|
94
|
+
const text = pending.join("");
|
|
95
|
+
const match = markerRe.exec(text);
|
|
96
|
+
if (match) {
|
|
97
|
+
settled = true;
|
|
98
|
+
exitCode = Number(match[1]);
|
|
99
|
+
// Output up to the start of the marker line.
|
|
100
|
+
const output = text.slice(0, match.index);
|
|
101
|
+
finish(output);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (Date.now() > deadline) {
|
|
105
|
+
settled = true;
|
|
106
|
+
finish(text, true);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
setTimeout(poll, 120);
|
|
110
|
+
};
|
|
111
|
+
const finish = (output, timedOut = false) => {
|
|
112
|
+
unsubscribe();
|
|
113
|
+
let result = stripAnsi(output).trimEnd();
|
|
114
|
+
if (result.length > MAX_OUTPUT_CHARS) {
|
|
115
|
+
result =
|
|
116
|
+
result.slice(0, MAX_OUTPUT_CHARS) +
|
|
117
|
+
`\n…[truncated ${result.length - MAX_OUTPUT_CHARS} chars]`;
|
|
118
|
+
}
|
|
119
|
+
if (exitCode !== undefined && exitCode !== 0) {
|
|
120
|
+
result += `\n[exit code: ${exitCode}]`;
|
|
121
|
+
}
|
|
122
|
+
if (timedOut) {
|
|
123
|
+
result += `\n[timeout after ${timeoutMs}ms — shell still running; output may be partial]`;
|
|
124
|
+
}
|
|
125
|
+
resolve(result || "(no output)");
|
|
126
|
+
};
|
|
127
|
+
poll();
|
|
128
|
+
});
|
|
129
|
+
};
|
|
130
|
+
const kinds = availableShellKinds().kinds;
|
|
131
|
+
// Default precedence: bash (most posix-feel for cross-platform models) →
|
|
132
|
+
// cmd (native Windows shell, offered when bash is absent) → zsh (macOS
|
|
133
|
+
// default on some dev boxes) → powershell (universal Windows fallback).
|
|
134
|
+
const defaultKind = kinds.includes("bash")
|
|
135
|
+
? "bash"
|
|
136
|
+
: kinds.includes("cmd")
|
|
137
|
+
? "cmd"
|
|
138
|
+
: kinds.includes("zsh")
|
|
139
|
+
? "zsh"
|
|
140
|
+
: "powershell";
|
|
141
|
+
const kindLabels = {
|
|
142
|
+
powershell: "PowerShell",
|
|
143
|
+
bash: "bash",
|
|
144
|
+
zsh: "zsh",
|
|
145
|
+
cmd: "cmd",
|
|
146
|
+
};
|
|
147
|
+
const tool = defineTool({
|
|
148
|
+
name: "terminal",
|
|
149
|
+
label: "Terminal",
|
|
150
|
+
description: TOOL_DESCRIPTION,
|
|
151
|
+
promptSnippet: `terminal: persistent PTY shells (${kinds.join(" + ")}). State (cwd/env/jobs) survives across calls. Actions: run / list / kill.`,
|
|
152
|
+
parameters: Type.Object({
|
|
153
|
+
action: Type.Union([Type.Literal("run"), Type.Literal("list"), Type.Literal("kill")], {
|
|
154
|
+
description: "run = execute command; list = active shells; kill = stop a shell",
|
|
155
|
+
}),
|
|
156
|
+
command: Type.Optional(Type.String({ description: "Command for action=run (no trailing newline)." })),
|
|
157
|
+
shell: Type.Optional(Type.Union(kinds.map((k) => Type.Literal(k)), {
|
|
158
|
+
description: `Shell kind for action=run (available on this platform: ${kinds.map((k) => kindLabels[k]).join(", ")}). Default ${kindLabels[defaultKind]}.`,
|
|
159
|
+
})),
|
|
160
|
+
sessionId: Type.Optional(Type.String({ description: "Terminal session id for action=kill." })),
|
|
161
|
+
timeoutMs: Type.Optional(Type.Number({ description: "Wall-clock limit for action=run. Default 120000." })),
|
|
162
|
+
}, { additionalProperties: false }),
|
|
163
|
+
async execute(_toolCallId, params, signal) {
|
|
164
|
+
const action = params.action;
|
|
165
|
+
try {
|
|
166
|
+
if (action === "list") {
|
|
167
|
+
const shells = deps.registry.list(deps.ownerSessionId);
|
|
168
|
+
return text(JSON.stringify(shells.map(({ sessionId, shell, name, exited, exitCode, createdAt }) => ({
|
|
169
|
+
sessionId,
|
|
170
|
+
shell,
|
|
171
|
+
name,
|
|
172
|
+
exited,
|
|
173
|
+
...(exitCode !== undefined ? { exitCode } : {}),
|
|
174
|
+
createdAt,
|
|
175
|
+
})), null, 2));
|
|
176
|
+
}
|
|
177
|
+
if (action === "kill") {
|
|
178
|
+
if (!params.sessionId)
|
|
179
|
+
return text(`error: sessionId required for kill`);
|
|
180
|
+
const info = deps.registry.list(deps.ownerSessionId).find((s) => s.sessionId === params.sessionId);
|
|
181
|
+
if (!info)
|
|
182
|
+
return text(`error: no terminal ${params.sessionId} owned by this chat session`);
|
|
183
|
+
await deps.registry.kill(params.sessionId);
|
|
184
|
+
return text(`terminal ${params.sessionId} stopped`);
|
|
185
|
+
}
|
|
186
|
+
// action === "run"
|
|
187
|
+
const command = (params.command ?? "").trim();
|
|
188
|
+
if (!command)
|
|
189
|
+
return text("error: command required for action=run");
|
|
190
|
+
const kind = kinds.includes(params.shell)
|
|
191
|
+
? params.shell
|
|
192
|
+
: defaultKind;
|
|
193
|
+
const timeoutMs = Math.min(Math.max(params.timeoutMs ?? DEFAULT_TIMEOUT_MS, 1_000), 600_000);
|
|
194
|
+
const output = await runInShell(kind, command, timeoutMs);
|
|
195
|
+
return text(output);
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
return text(`error: ${error instanceof Error ? error.message : String(error)}`);
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
});
|
|
202
|
+
return [tool];
|
|
203
|
+
}
|
|
204
|
+
function text(body) {
|
|
205
|
+
return { content: [{ type: "text", text: body }], details: { output: body } };
|
|
206
|
+
}
|
|
207
|
+
/** Minimal ANSI escape stripper for tool-result readability. */
|
|
208
|
+
export function stripAnsi(input) {
|
|
209
|
+
// eslint-disable-next-line no-control-regex
|
|
210
|
+
return input.replace(/\u001b\[[0-9;?]*[A-Za-z]/g, "");
|
|
211
|
+
}
|
|
@@ -193,6 +193,17 @@ export function getToolPresentation(toolName) {
|
|
|
193
193
|
}
|
|
194
194
|
return { kind: "tool", label: raw };
|
|
195
195
|
}
|
|
196
|
+
/** A tool call that failed on its own. A call interrupted by Stop carries
|
|
197
|
+
* `interrupted: true` and must never render (or count) as a failure — every
|
|
198
|
+
* error affordance goes through this single predicate (2026-09-08). */
|
|
199
|
+
export function isToolFailure(entry) {
|
|
200
|
+
return entry.status === "error" && entry.interrupted !== true;
|
|
201
|
+
}
|
|
202
|
+
/** Built-in subagent delegations surface as the `Agent` tool. DSH counts them
|
|
203
|
+
* in a separate「N 个 subagent」bucket instead of the tool-call bucket. */
|
|
204
|
+
export function isSubagentTool(toolName) {
|
|
205
|
+
return (toolName ?? "").trim().toLowerCase() === "agent";
|
|
206
|
+
}
|
|
196
207
|
/** Section labels for ToolCard expand body. */
|
|
197
208
|
export function getToolSectionLabels(toolName) {
|
|
198
209
|
const name = (toolName ?? "").toLowerCase();
|
|
@@ -23,6 +23,8 @@ const EXECUTABLE_GATE_ONLY = new Set(EXECUTABLE_GATE_ONLY_ACTIONS);
|
|
|
23
23
|
/** Built-in Chat custom tools that are not operator registry actions. */
|
|
24
24
|
export const OPERATOR_CHAT_BUILTIN_CUSTOM_TOOLS = Object.freeze([
|
|
25
25
|
OPERATOR_CHAT_AGENT_TOOL_NAME,
|
|
26
|
+
"terminal",
|
|
27
|
+
"scm",
|
|
26
28
|
]);
|
|
27
29
|
/**
|
|
28
30
|
* Actions the model MAY invoke. Derived from the registry but filtered by the
|
|
@@ -9,7 +9,7 @@ import { DAG_ABSOLUTE_MAX_WALL_CLOCK_MS } from "../../shared/timeout-policy.js";
|
|
|
9
9
|
import { openConsoleAppData } from "../../infrastructure/console/app-data.js";
|
|
10
10
|
import { isLoopbackHost } from "./loopback.js";
|
|
11
11
|
import { ChatSessionStore } from "./chat/session-store.js";
|
|
12
|
-
import { ChatSessionCatalog } from "./chat/session-catalog.js";
|
|
12
|
+
import { ChatSessionCatalog, projectChatSessionCatalogListItem, } from "./chat/session-catalog.js";
|
|
13
13
|
import { matchRepoHtmlPreviewRoute } from "./chat/repo-browser.js";
|
|
14
14
|
import { handleConsoleHealthRequest, handleWorkspaceRoutes, sendJson, serveConsoleStatic, } from "./routes.js";
|
|
15
15
|
import { issueBootCapabilityToken, injectConfirmationTokenScript, } from "./security.js";
|
|
@@ -430,33 +430,7 @@ export async function createConsoleServer(options) {
|
|
|
430
430
|
.get(entry.workspaceId)
|
|
431
431
|
?.chatRouteDeps.events.getActiveTurn(entry.sessionId)
|
|
432
432
|
: undefined;
|
|
433
|
-
return
|
|
434
|
-
sessionId: entry.sessionId,
|
|
435
|
-
...(entry.workspaceId ? { workspaceId: entry.workspaceId } : {}),
|
|
436
|
-
state: entry.state,
|
|
437
|
-
createdAt: entry.createdAt,
|
|
438
|
-
updatedAt: entry.updatedAt,
|
|
439
|
-
...(entry.title !== undefined ? { title: entry.title } : {}),
|
|
440
|
-
...(entry.displayTitle !== undefined
|
|
441
|
-
? { displayTitle: entry.displayTitle }
|
|
442
|
-
: {}),
|
|
443
|
-
...(entry.modelProvider !== undefined
|
|
444
|
-
? { modelProvider: entry.modelProvider }
|
|
445
|
-
: {}),
|
|
446
|
-
...(entry.modelId !== undefined ? { modelId: entry.modelId } : {}),
|
|
447
|
-
...(entry.thinkingLevel !== undefined
|
|
448
|
-
? { thinkingLevel: entry.thinkingLevel }
|
|
449
|
-
: {}),
|
|
450
|
-
activeTurnId: active?.turnId,
|
|
451
|
-
turnPhase: active?.abortRequestedAt
|
|
452
|
-
? "stopping"
|
|
453
|
-
: active
|
|
454
|
-
? "running"
|
|
455
|
-
: "idle",
|
|
456
|
-
deferredTurn: entry.deferredTurn,
|
|
457
|
-
deferredTurns: entry.deferredTurns,
|
|
458
|
-
isBlank: entry.isBlank && !active,
|
|
459
|
-
};
|
|
433
|
+
return projectChatSessionCatalogListItem(entry, active);
|
|
460
434
|
});
|
|
461
435
|
sendJson(res, 200, {
|
|
462
436
|
ok: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as p,r as u,d as a}from"./chunk-6Q2QTUOP-
|
|
1
|
+
import{g as p,r as u,d as a}from"./chunk-6Q2QTUOP-Dwd6r-SF.js";import{p as f}from"./chunk-JWPE2WC7-CuGp0DeE.js";import{_ as n,l as o}from"./mermaid.core-p2l8IrWY.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-BdXcxtlb.js";import"./index-24jp3aBh.js";var v=d().RailroadAbnf.parser.LangiumParser,i=n(e=>{const r=e.alternatives.map(g);return r.length===1?r[0]:{type:"choice",alternatives:r}},"transformAlternation"),g=n(e=>{const r=e.elements.map(y);return r.length===1?r[0]:{type:"sequence",elements:r}},"transformConcatenation"),b=n(e=>{if(e.includes("*")){const[t,s]=e.split("*"),l=t?parseInt(t,10):0,m=s?parseInt(s,10):1/0;return{min:l,max:m}}const r=parseInt(e,10);return{min:r,max:r}},"parseRepeat"),y=n(e=>{const r=A(e.primary);if(!e.repeat)return r;const{min:t,max:s}=b(e.repeat);return t===0&&s===1?{type:"optional",element:r}:{type:"repetition",element:r,min:t,max:s}},"transformElement"),A=n(e=>{switch(e.$type){case"AbnfStringLiteral":return{type:"terminal",value:e.value};case"AbnfNumVal":return{type:"terminal",value:e.value};case"AbnfRuleName":return{type:"nonterminal",name:e.name};case"AbnfGroup":return i(e.element);case"AbnfOptionalGroup":return{type:"optional",element:i(e.element)};default:throw new Error(`Unsupported ABNF primary node: ${e.$type}`)}},"transformPrimary"),P=n(e=>({name:e.name,definition:i(e.definition)}),"transformRule"),h=n(e=>{f(e,a),e.title&&a.setTitle(e.title),e.rules.map(r=>a.addRule(P(r)))},"populateDb"),R={parse:n(e=>{a.clear(),o.debug("[ABNF Parser] Starting Langium parse");const r=v.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new c(r);const t=r.value;o.debug("[ABNF Parser] Parsed rules:",t.rules.length),h(t),o.debug("[ABNF Parser] Parse complete")},"parse"),parser:{yy:a}},B={parser:R,db:a,renderer:u,styles:p};export{B as diagram};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Y as ln,$ as an,a0 as F,a1 as q,a2 as j,a3 as un,a4 as y,a5 as tn,a6 as J,a7 as _,a8 as rn,a9 as o,aa as on,ab as sn,ac as fn}from"./mermaid.core-
|
|
1
|
+
import{Y as ln,$ as an,a0 as F,a1 as q,a2 as j,a3 as un,a4 as y,a5 as tn,a6 as J,a7 as _,a8 as rn,a9 as o,aa as on,ab as sn,ac as fn}from"./mermaid.core-p2l8IrWY.js";function cn(l){return l.innerRadius}function yn(l){return l.outerRadius}function gn(l){return l.startAngle}function dn(l){return l.endAngle}function mn(l){return l&&l.padAngle}function pn(l,h,I,D,v,A,z,a){var O=I-l,i=D-h,n=z-v,d=a-A,u=d*O-n*i;if(!(u*u<y))return u=(n*(h-A)-d*(l-v))/u,[l+u*O,h+u*i]}function U(l,h,I,D,v,A,z){var a=l-I,O=h-D,i=(z?A:-A)/J(a*a+O*O),n=i*O,d=-i*a,u=l+n,s=h+d,f=I+n,c=D+d,B=(u+f)/2,t=(s+c)/2,m=f-u,g=c-s,R=m*m+g*g,T=v-A,P=u*c-f*s,S=(g<0?-1:1)*J(on(0,T*T*R-P*P)),Y=(P*g-m*S)/R,$=(-P*m-g*S)/R,w=(P*g+m*S)/R,p=(-P*m+g*S)/R,x=Y-B,e=$-t,r=w-B,C=p-t;return x*x+e*e>r*r+C*C&&(Y=w,$=p),{cx:Y,cy:$,x01:-n,y01:-d,x11:Y*(v/T-1),y11:$*(v/T-1)}}function hn(){var l=cn,h=yn,I=j(0),D=null,v=gn,A=dn,z=mn,a=null,O=ln(i);function i(){var n,d,u=+l.apply(this,arguments),s=+h.apply(this,arguments),f=v.apply(this,arguments)-un,c=A.apply(this,arguments)-un,B=rn(c-f),t=c>f;if(a||(a=n=O()),s<u&&(d=s,s=u,u=d),!(s>y))a.moveTo(0,0);else if(B>tn-y)a.moveTo(s*F(f),s*q(f)),a.arc(0,0,s,f,c,!t),u>y&&(a.moveTo(u*F(c),u*q(c)),a.arc(0,0,u,c,f,t));else{var m=f,g=c,R=f,T=c,P=B,S=B,Y=z.apply(this,arguments)/2,$=Y>y&&(D?+D.apply(this,arguments):J(u*u+s*s)),w=_(rn(s-u)/2,+I.apply(this,arguments)),p=w,x=w,e,r;if($>y){var C=sn($/u*q(Y)),K=sn($/s*q(Y));(P-=C*2)>y?(C*=t?1:-1,R+=C,T-=C):(P=0,R=T=(f+c)/2),(S-=K*2)>y?(K*=t?1:-1,m+=K,g-=K):(S=0,m=g=(f+c)/2)}var G=s*F(m),H=s*q(m),L=u*F(T),M=u*q(T);if(w>y){var N=s*F(g),Q=s*q(g),V=u*F(R),W=u*q(R),E;if(B<an)if(E=pn(G,H,V,W,N,Q,L,M)){var X=G-E[0],Z=H-E[1],b=N-E[0],k=Q-E[1],nn=1/q(fn((X*b+Z*k)/(J(X*X+Z*Z)*J(b*b+k*k)))/2),en=J(E[0]*E[0]+E[1]*E[1]);p=_(w,(u-en)/(nn-1)),x=_(w,(s-en)/(nn+1))}else p=x=0}S>y?x>y?(e=U(V,W,G,H,s,x,t),r=U(N,Q,L,M,s,x,t),a.moveTo(e.cx+e.x01,e.cy+e.y01),x<w?a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,s,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),!t),a.arc(r.cx,r.cy,x,o(r.y11,r.x11),o(r.y01,r.x01),!t))):(a.moveTo(G,H),a.arc(0,0,s,m,g,!t)):a.moveTo(G,H),!(u>y)||!(P>y)?a.lineTo(L,M):p>y?(e=U(L,M,N,Q,u,-p,t),r=U(G,H,V,W,u,-p,t),a.lineTo(e.cx+e.x01,e.cy+e.y01),p<w?a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,u,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),t),a.arc(r.cx,r.cy,p,o(r.y11,r.x11),o(r.y01,r.x01),!t))):a.arc(0,0,u,T,R,t)}if(a.closePath(),n)return a=null,n+""||null}return i.centroid=function(){var n=(+l.apply(this,arguments)+ +h.apply(this,arguments))/2,d=(+v.apply(this,arguments)+ +A.apply(this,arguments))/2-an/2;return[F(d)*n,q(d)*n]},i.innerRadius=function(n){return arguments.length?(l=typeof n=="function"?n:j(+n),i):l},i.outerRadius=function(n){return arguments.length?(h=typeof n=="function"?n:j(+n),i):h},i.cornerRadius=function(n){return arguments.length?(I=typeof n=="function"?n:j(+n),i):I},i.padRadius=function(n){return arguments.length?(D=n==null?null:typeof n=="function"?n:j(+n),i):D},i.startAngle=function(n){return arguments.length?(v=typeof n=="function"?n:j(+n),i):v},i.endAngle=function(n){return arguments.length?(A=typeof n=="function"?n:j(+n),i):A},i.padAngle=function(n){return arguments.length?(z=typeof n=="function"?n:j(+n),i):z},i.context=function(n){return arguments.length?(a=n??null,i):a},i}export{hn as d};
|