chainlesschain 0.162.42 → 0.162.44
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/package.json +1 -1
- package/src/assets/web-panel/assets/{AIOps-Dsw5p7A7.js → AIOps-DKzTpK-Y.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-sk89dGuT.js → ActionButton-CMAlqdwe.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-kd8hzeK3.js → Analytics-QMe2cbkc.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-CxlLp7J8.js → AppLayout-DWSbQ4Li.js} +5 -5
- package/src/assets/web-panel/assets/{Audit-CQnGmRxA.js → Audit-B2m5_PZ1.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-BioBFWVV.js → Backup-CfTZgrj4.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-DiYG1n7T.js → BaseInput-DQMQQpXM.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-BBuQf6VM.js → Chat-XSNjF8Mp.js} +6 -6
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-BwgFmlRu.js → ChatBubbleRenderer-BjWwWSBW.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-B-9WwFTA.js → Checkbox-DcHFXGYe.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-DCkpThQa.js → Codegen-CbGi3e7e.js} +1 -1
- package/src/assets/web-panel/assets/{Col-BowFdito.js → Col-uRz8SHXE.js} +1 -1
- package/src/assets/web-panel/assets/{Community-BWGa92rE.js → Community-CneB2EQd.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-CqJYYK0v.js → Compact-C9t4kI4u.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-DiFqpJrM.js → Compliance-BSgNNAgN.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-qZNWcSQ9.js → Cowork-BOJD_XKQ.js} +4 -4
- package/src/assets/web-panel/assets/{Cron-BK70XYci.js → Cron-DBZVqJWg.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-DoM9N2kO.js → Crosschain-BPBndx_n.js} +1 -1
- package/src/assets/web-panel/assets/{DID-B1F1RhQr.js → DID-BFeOnAbj.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-CmDxx07G.js → Dashboard-DR_krdui.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-5GRByJY9.js → Dropdown-DBFIX9zX.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-CyNgNjLG.js → EmailListRenderer-j7nUo0EN.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-Jwg-Wuye.js → FamilyGuardDashboard-BNrIZkRp.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-BQvoY2_5.js → Federation-D1cPCDKh.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-DKy8Zatd.js → FormItemContext-C24JXiJZ.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-n7VGwZNh.js → GenericCardRenderer-g-EsfuMZ.js} +1 -1
- package/src/assets/web-panel/assets/{Git-CFCUe_so.js → Git-BVEJZ29p.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-DuZbRElA.js → Governance-B-fAe2v1.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-DSEsBonV.js → Inference-DBYa0ztr.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DQoaeSnN.js → KnowledgeGraph-B0S0at2T.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-u7UMHPnz.js → Logs-BUHn58RG.js} +2 -2
- package/src/assets/web-panel/assets/{Marketplace--gDqWnX8.js → Marketplace-DSYpWtgR.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-btiDEQ_G.js → McpTools-Cm_GD-uS.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-CYrqC903.js → Memory-CB9uRtzi.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-CktV5fRJ.js → MobileBridge-vgX_FQ74.js} +2 -2
- package/src/assets/web-panel/assets/{MobileProjects-CTVZQD7g.js → MobileProjects-DCMhJceG.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-CRq5Ir7q.js → Mtc-Atr0Zh0n.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-HvY-N0XZ.js → MtcAudit-DxQjtoAG.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-CWmUSW7g.js → Multisig-DBc1IRY-.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-BUwhn6xG.js → NLProgramming-C55Qg6EX.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-BI8NqNSW.js → Notes-CVRXn9dM.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-DVa8gbo1.js → NotificationSettings-B8_Y2rYz.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-XNEr64wi.js → OrderTableRenderer-BvbjrcIW.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-a0imltNQ.js → Organization-fmONrEpS.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-DJ2P1mNg.js → Overflow-DtS9U-lj.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-pRJPEJ7a.js → P2P-BCp9IFsu.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-eJa8vkF5.js → PdhVaultBrowser-FB03lQ_0.js} +5 -5
- package/src/assets/web-panel/assets/{Permissions-fxa21qzR.js → Permissions-BD3VCCBY.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-C3JggyPn.js → PersonalDataHub-I_dIzQfI.js} +2 -2
- package/src/assets/web-panel/assets/{Pipeline-iR9fwke0.js → Pipeline-BfqiuVgI.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-oBf4gwv0.js → Privacy-Dnm-Lxv0.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-DZU2PVgs.js → ProjectInit-D12saZXQ.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-amcXcSet.js → ProjectSettings-BHk78dtG.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-QoksY3-i.js → Projects-BQgMcz56.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-uquz_5KZ.js → Providers-Bs7dxjKE.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-Wxx-iIH9.js → QuickAsk-CqhoJCPD.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-CD8OJGJF.js → Recommend-D-l-eJFr.js} +1 -1
- package/src/assets/web-panel/assets/{Reputation-BuJMHfco.js → Reputation-CPrlP2Ux.js} +1 -1
- package/src/assets/web-panel/assets/{Row-DvfqASM7.js → Row-C3Q9Dshq.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-TGSmYgmV.js → RssFeed-DlLlpbtD.js} +3 -3
- package/src/assets/web-panel/assets/{Search-ndSDi33l.js → Search-EIs5mUs2.js} +1 -1
- package/src/assets/web-panel/assets/{Security-CL1FLyzy.js → Security-NJbvreOk.js} +3 -3
- package/src/assets/web-panel/assets/{Services--AeNKFrY.js → Services-B-GS4dFT.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-CMllAeqY.js → Skeleton-Bycye0oO.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-DD29bVTm.js → Skills-D9gOTB8D.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-DU_Mdrad.js → Sla-hR2sLl6u.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-Cu0ncgI_.js → SpeechSettings-xNkqwlx_.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-Bfk00Eb9.js → SyncSettings-C53VuHwk.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-C-2V1COO.js → Tasks-XIDFrKjD.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-CWO4Aw1l.js → Templates-JA8aUZm3.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-BnDkNC6u.js → Tenant-DjGO2SFi.js} +1 -1
- package/src/assets/web-panel/assets/Terminal-D_8L6tYA.js +3 -0
- package/src/assets/web-panel/assets/{TimelineRenderer-DMjbfev0.js → TimelineRenderer-Cfalxtc_.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-j1ZGEgBP.js → Tokens-lvG8zW-n.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-BKVNLlOB.js → Trigger-G3EmMFkS.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-Bbfv8AJr.js → Trust-BDXSbpLN.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-C0_Gllsu.js → UkeySign-9GtCtwS7.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-CE__3Owf.js → VideoEditing-DorUOflW.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-Cjzavume.js → Wallet-B1PSsoH7.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-KbjxueWc.js → WebAuthn-BlawNPwk.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-Bz7UuLhK.js → WorkflowEditor-DT5tXYHC.js} +1 -1
- package/src/assets/web-panel/assets/{chat-BrSAQ_Gd.js → chat-Db1ggy-d.js} +1 -1
- package/src/assets/web-panel/assets/{colors-Bn8oqI93.js → colors-DvKRY65P.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-jxrLqj8Q.js → compact-item-ChJE-s12.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-B0uxIvgB.js → createContext-C_n8N7R0.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-8RHlZueh.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-BFsfry47.js → hasIn-f5qrOyO8.js} +1 -1
- package/src/assets/web-panel/assets/{index-BRkK0yoO.js → index-6-pawsDV.js} +1 -1
- package/src/assets/web-panel/assets/{index-E6sYKDbw.js → index-B889nFIK.js} +1 -1
- package/src/assets/web-panel/assets/{index-CAIdm73g.js → index-BGcNc2FC.js} +1 -1
- package/src/assets/web-panel/assets/{index-CovEs7is.js → index-BLbUSjRl.js} +1 -1
- package/src/assets/web-panel/assets/{index-DSDgBgrL.js → index-BRPjpA9x.js} +1 -1
- package/src/assets/web-panel/assets/{index-D08W2YxD.js → index-B_Db3y-q.js} +1 -1
- package/src/assets/web-panel/assets/{index-_fgTMPd1.js → index-BlXvSz68.js} +1 -1
- package/src/assets/web-panel/assets/{index-C6AmzUjG.js → index-BmDr3_dh.js} +1 -1
- package/src/assets/web-panel/assets/{index-9iuxVwRC.js → index-Bv3rnRcv.js} +1 -1
- package/src/assets/web-panel/assets/{index-DcHQBw3b.js → index-BzfpAd-L.js} +1 -1
- package/src/assets/web-panel/assets/{index-BiXyJmcf.js → index-C99Tx6W3.js} +1 -1
- package/src/assets/web-panel/assets/{index-DeHd8uSh.js → index-CBtvIJ1P.js} +1 -1
- package/src/assets/web-panel/assets/{index-LLFwwG0R.js → index-CRpYACac.js} +1 -1
- package/src/assets/web-panel/assets/{index-BY4oOQaA.js → index-CZM-f_GP.js} +1 -1
- package/src/assets/web-panel/assets/{index-D1WrY_4z.js → index-CgVhpbwl.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bd-zsWvY.js → index-CkSc1UD0.js} +1 -1
- package/src/assets/web-panel/assets/{index-CZ8gyTGc.js → index-CnBPm5VW.js} +1 -1
- package/src/assets/web-panel/assets/{index-xRD9Fctn.js → index-Cwx25An4.js} +1 -1
- package/src/assets/web-panel/assets/{index-Crqzhccj.js → index-D2vRDPxa.js} +1 -1
- package/src/assets/web-panel/assets/{index-BPpGWBAU.js → index-DBDuh9Q_.js} +1 -1
- package/src/assets/web-panel/assets/{index-DjxJSCB8.js → index-DDwTm4HW.js} +1 -1
- package/src/assets/web-panel/assets/{index-pMVcl-a3.js → index-DLJldKpu.js} +1 -1
- package/src/assets/web-panel/assets/{index-CireH7ze.js → index-DNcqoZEW.js} +1 -1
- package/src/assets/web-panel/assets/{index-BzZfG8Ft.js → index-DSn8UWj1.js} +1 -1
- package/src/assets/web-panel/assets/{index-DmD-qtjF.js → index-DVWPEAS_.js} +1 -1
- package/src/assets/web-panel/assets/{index-DdjhDnIk.js → index-D_ca6G9G.js} +1 -1
- package/src/assets/web-panel/assets/index-DiVQYFZe.js +1 -0
- package/src/assets/web-panel/assets/{index-BQZsB8nt.js → index-LADrnz2q.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bk_Tv7Ey.js → index-MW_Zh_HW.js} +1 -1
- package/src/assets/web-panel/assets/index-QQHpE5N6.js +1 -0
- package/src/assets/web-panel/assets/{index-CCVF9irI.js → index-ZIg1Yi8T.js} +1 -1
- package/src/assets/web-panel/assets/{index-DOJYoYG7.js → index-aRdl6HAc.js} +1 -1
- package/src/assets/web-panel/assets/{index-DMPQqeLb.js → index-bYgSwFp_.js} +3 -3
- package/src/assets/web-panel/assets/{index-CR3QNisI.js → index-cNZUziLU.js} +1 -1
- package/src/assets/web-panel/assets/{index-BQvlv_iE.js → index-dbd8KVOi.js} +1 -1
- package/src/assets/web-panel/assets/{index-B9ZDJUc0.js → index-gEBZrC4a.js} +1 -1
- package/src/assets/web-panel/assets/{index-DteDdzDQ.js → index-ru1UNElJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-vma7bVdQ.js → index-xytEYrmf.js} +1 -1
- package/src/assets/web-panel/assets/{index-C7q_gApa.js → index-zDFZeRny.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-AKS5cCeZ.js → initDefaultProps-BmuULb3C.js} +1 -1
- package/src/assets/web-panel/assets/{motion-SDjWiFhF.js → motion-BPAdGPV0.js} +1 -1
- package/src/assets/web-panel/assets/{move-LEZnOtYR.js → move-CfQuWRIA.js} +1 -1
- package/src/assets/web-panel/assets/{omit-DhLBVNzX.js → omit-B4X1FaKf.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-DdVSELea.js → pickAttrs-CnNXE2Fs.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-BaEGCCq9.js → placementArrow-Bb5asP1f.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-DV6XM19W.js → responsiveObserve-CFYMBsLT.js} +1 -1
- package/src/assets/web-panel/assets/{slide-BOUnaBay.js → slide-Pf9K-RqE.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-BAaMQ0VA.js → statusUtils-DmGXqpMA.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-CsoP0nmm.js → styleChecker-3ymOCpPp.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-t20RbINy.js → useFlexGapSupport-CiCbo3Hx.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-DH_Emn7A.js → useFs-BbhWqkvH.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-CeYW427U.js → usePersonalDataHub-BNjAwFwx.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-CX5gGmGb.js → vnode-Dsmjnl6v.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-CofyY9oD.js → zoom-Dx0p7V8W.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/agent.js +66 -51
- package/src/lib/llm-config-defaults.js +31 -0
- package/src/runtime/headless-stream.js +183 -4
- package/src/assets/web-panel/assets/Terminal-VR0JLDdw.js +0 -3
- package/src/assets/web-panel/assets/devWarning-rqonNzey.js +0 -1
- package/src/assets/web-panel/assets/index-BI1fCgPX.js +0 -1
- package/src/assets/web-panel/assets/index-D8iCZ8gl.js +0 -1
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config-default LLM resolution for `cc agent` (parity with `cc ask`/`chat`):
|
|
3
|
+
* a bare run honors `~/.chainlesschain/config.json` `llm` —
|
|
4
|
+
* provider/model/baseUrl/apiKey — instead of silently assuming local ollama
|
|
5
|
+
* (the historical default that broke every cloud-configured setup the moment
|
|
6
|
+
* no --provider flag was passed, e.g. the editor chat panel's spawn).
|
|
7
|
+
*
|
|
8
|
+
* Rules (pure; mutates and returns `options` for call-site convenience):
|
|
9
|
+
* - An explicit --provider wins outright: config is NOT consulted at all
|
|
10
|
+
* (mixing config's model/key into a different provider would be wrong).
|
|
11
|
+
* - With no --provider but a configured one: provider + any of
|
|
12
|
+
* model/baseUrl/apiKey the user did not explicitly set come from config.
|
|
13
|
+
* - Model pairing: when the provider is adopted from config, the model must
|
|
14
|
+
* pair with it — only an EXPLICIT --model (opts.explicitModel) survives;
|
|
15
|
+
* a model that leaked in from .claude/settings.json (meant for whatever
|
|
16
|
+
* provider that file assumed) is replaced by config's own model. Same
|
|
17
|
+
* lesson as the --settings "opus"→404 vision trap.
|
|
18
|
+
* - No configured provider → unchanged (runner defaults apply: ollama).
|
|
19
|
+
*/
|
|
20
|
+
export function applyConfigLlmDefaults(options = {}, cfgLlm = {}, opts = {}) {
|
|
21
|
+
if (options.provider || !cfgLlm.provider) return options;
|
|
22
|
+
options.provider = cfgLlm.provider;
|
|
23
|
+
if (opts.explicitModel) {
|
|
24
|
+
options.model = opts.explicitModel;
|
|
25
|
+
} else if (cfgLlm.model) {
|
|
26
|
+
options.model = cfgLlm.model;
|
|
27
|
+
}
|
|
28
|
+
if (!options.baseUrl && cfgLlm.baseUrl) options.baseUrl = cfgLlm.baseUrl;
|
|
29
|
+
if (!options.apiKey && cfgLlm.apiKey) options.apiKey = cfgLlm.apiKey;
|
|
30
|
+
return options;
|
|
31
|
+
}
|
|
@@ -37,6 +37,33 @@ import {
|
|
|
37
37
|
rebuildMessages as jsonlRebuildMessages,
|
|
38
38
|
sessionExists as jsonlSessionExists,
|
|
39
39
|
} from "../harness/jsonl-session-store.js";
|
|
40
|
+
import { getPlanModeManager } from "../lib/plan-mode.js";
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Structured view of the global plan-mode state for `plan_update` events
|
|
44
|
+
* (the chat panel renders its plan card from this). Pure read; never throws.
|
|
45
|
+
*/
|
|
46
|
+
export function planSnapshot(pm) {
|
|
47
|
+
let items = [];
|
|
48
|
+
let risk = null;
|
|
49
|
+
try {
|
|
50
|
+
const plan = pm.currentPlan;
|
|
51
|
+
items = (plan?.items || []).map((i) => ({
|
|
52
|
+
id: i.id,
|
|
53
|
+
title: i.title,
|
|
54
|
+
tool: i.tool,
|
|
55
|
+
impact: i.estimatedImpact || "low",
|
|
56
|
+
status: i.status,
|
|
57
|
+
}));
|
|
58
|
+
if (items.length > 0) {
|
|
59
|
+
const r = pm.getRiskAssessment();
|
|
60
|
+
if (r) risk = { level: r.level, totalScore: r.totalScore };
|
|
61
|
+
}
|
|
62
|
+
} catch {
|
|
63
|
+
/* snapshot is best-effort */
|
|
64
|
+
}
|
|
65
|
+
return { active: pm.isActive(), state: pm.state || null, items, risk };
|
|
66
|
+
}
|
|
40
67
|
import { withQuietStdout } from "./quiet-stdout.js";
|
|
41
68
|
|
|
42
69
|
/**
|
|
@@ -51,6 +78,17 @@ export function parseInputEvent(line) {
|
|
|
51
78
|
} catch {
|
|
52
79
|
return { error: `invalid JSON line: ${trimmed.slice(0, 80)}` };
|
|
53
80
|
}
|
|
81
|
+
// Plan-mode control events (chat-panel plan UI):
|
|
82
|
+
// {"type":"plan","action":"enter"|"approve"|"reject"}
|
|
83
|
+
if (obj && typeof obj === "object" && obj.type === "plan") {
|
|
84
|
+
const action = String(obj.action || "").toLowerCase();
|
|
85
|
+
return action ? { plan: action } : null;
|
|
86
|
+
}
|
|
87
|
+
// Turn interrupt (panel Stop / Claude-Code Esc parity): aborts the
|
|
88
|
+
// in-flight turn without ending the conversation. {"type":"interrupt"}
|
|
89
|
+
if (obj && typeof obj === "object" && obj.type === "interrupt") {
|
|
90
|
+
return { interrupt: true };
|
|
91
|
+
}
|
|
54
92
|
const msg = obj && typeof obj === "object" ? obj.message || obj : {};
|
|
55
93
|
let content = msg.content ?? obj.text ?? obj.prompt;
|
|
56
94
|
if (Array.isArray(content)) {
|
|
@@ -441,9 +479,48 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
441
479
|
let turns = 0;
|
|
442
480
|
let sawError = false;
|
|
443
481
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
482
|
+
// ── Concurrent stdin pump (turn-interrupt support) ────────────────────────
|
|
483
|
+
// Input is consumed AS IT ARRIVES — not between turns — so an
|
|
484
|
+
// {"type":"interrupt"} can abort the IN-FLIGHT turn immediately (chat-panel
|
|
485
|
+
// Stop / Claude-Code Esc parity) instead of waiting in line behind it.
|
|
486
|
+
// Normal events queue for the serial turn loop below; interrupts act on the
|
|
487
|
+
// live per-turn AbortController and are never queued.
|
|
488
|
+
const queue = [];
|
|
489
|
+
let wakeQueue = null;
|
|
490
|
+
let inputDone = false;
|
|
491
|
+
let currentAbort = null;
|
|
492
|
+
(async () => {
|
|
493
|
+
try {
|
|
494
|
+
for await (const line of readJsonLines(input)) {
|
|
495
|
+
const parsed = parseInputEvent(line);
|
|
496
|
+
if (parsed == null) continue;
|
|
497
|
+
if (parsed.interrupt) {
|
|
498
|
+
currentAbort?.abort();
|
|
499
|
+
continue;
|
|
500
|
+
}
|
|
501
|
+
queue.push(parsed);
|
|
502
|
+
if (wakeQueue) wakeQueue();
|
|
503
|
+
}
|
|
504
|
+
} catch {
|
|
505
|
+
/* input stream error → treat as EOF */
|
|
506
|
+
}
|
|
507
|
+
inputDone = true;
|
|
508
|
+
if (wakeQueue) wakeQueue();
|
|
509
|
+
})();
|
|
510
|
+
const nextEvent = async () => {
|
|
511
|
+
for (;;) {
|
|
512
|
+
if (queue.length > 0) return queue.shift();
|
|
513
|
+
if (inputDone) return null;
|
|
514
|
+
await new Promise((r) => {
|
|
515
|
+
wakeQueue = r;
|
|
516
|
+
});
|
|
517
|
+
wakeQueue = null;
|
|
518
|
+
}
|
|
519
|
+
};
|
|
520
|
+
|
|
521
|
+
for (;;) {
|
|
522
|
+
const parsed = await nextEvent();
|
|
523
|
+
if (parsed == null) break; // stdin closed
|
|
447
524
|
if (parsed.error) {
|
|
448
525
|
emit({
|
|
449
526
|
type: "result",
|
|
@@ -455,6 +532,69 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
455
532
|
continue;
|
|
456
533
|
}
|
|
457
534
|
|
|
535
|
+
// Plan-mode control events (chat-panel plan UI). Mirrors the REPL's
|
|
536
|
+
// /plan verbs: enter blocks write tools (blocked calls become plan items),
|
|
537
|
+
// approve unlocks them and IMMEDIATELY runs a continuation turn, reject
|
|
538
|
+
// exits plan mode. Every control answers with a `plan_update` event.
|
|
539
|
+
if (parsed.plan) {
|
|
540
|
+
const pm = getPlanModeManager();
|
|
541
|
+
if (parsed.plan === "enter") {
|
|
542
|
+
if (!pm.isActive()) {
|
|
543
|
+
pm.enterPlanMode({ title: "Agent Plan" });
|
|
544
|
+
messages.push({
|
|
545
|
+
role: "system",
|
|
546
|
+
content:
|
|
547
|
+
"[PLAN MODE ACTIVE] You are now in plan mode. You can read " +
|
|
548
|
+
"files, search, and analyze — but write/execute tools are " +
|
|
549
|
+
"blocked. Any blocked tool calls will be recorded as plan " +
|
|
550
|
+
"items. Analyze the task thoroughly, then the user will " +
|
|
551
|
+
"approve your plan.",
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
emit({
|
|
555
|
+
type: "plan_update",
|
|
556
|
+
...planSnapshot(pm),
|
|
557
|
+
session_id: sessionId,
|
|
558
|
+
});
|
|
559
|
+
continue;
|
|
560
|
+
}
|
|
561
|
+
if (parsed.plan === "reject") {
|
|
562
|
+
if (pm.isActive()) pm.rejectPlan("User rejected");
|
|
563
|
+
emit({
|
|
564
|
+
type: "plan_update",
|
|
565
|
+
...planSnapshot(pm),
|
|
566
|
+
session_id: sessionId,
|
|
567
|
+
});
|
|
568
|
+
continue;
|
|
569
|
+
}
|
|
570
|
+
if (parsed.plan === "approve") {
|
|
571
|
+
if (!pm.isActive() || !(pm.currentPlan?.items?.length > 0)) {
|
|
572
|
+
emit({
|
|
573
|
+
type: "plan_update",
|
|
574
|
+
...planSnapshot(pm),
|
|
575
|
+
session_id: sessionId,
|
|
576
|
+
note: "nothing to approve",
|
|
577
|
+
});
|
|
578
|
+
continue;
|
|
579
|
+
}
|
|
580
|
+
pm.approvePlan();
|
|
581
|
+
messages.push({
|
|
582
|
+
role: "system",
|
|
583
|
+
content: `[PLAN APPROVED] The user has approved your plan with ${pm.currentPlan.items.length} items. You can now use all tools including write_file, edit_file, run_shell, and run_skill. Execute the plan items in order.`,
|
|
584
|
+
});
|
|
585
|
+
emit({
|
|
586
|
+
type: "plan_update",
|
|
587
|
+
...planSnapshot(pm),
|
|
588
|
+
session_id: sessionId,
|
|
589
|
+
});
|
|
590
|
+
// Fall through into the normal turn machinery with a continuation
|
|
591
|
+
// prompt — the agent starts executing without an extra user message.
|
|
592
|
+
parsed.text = "Proceed with the approved plan.";
|
|
593
|
+
} else if (!parsed.text) {
|
|
594
|
+
continue; // unknown plan action — ignored
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
|
|
458
598
|
// Per-turn iteration budget so one turn can't starve the rest.
|
|
459
599
|
const budget = Number.isFinite(options.maxTurns)
|
|
460
600
|
? new IterationBudget({
|
|
@@ -521,14 +661,39 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
521
661
|
}
|
|
522
662
|
turns += 1;
|
|
523
663
|
|
|
664
|
+
// Per-turn abort scope: an {"type":"interrupt"} from the pump above
|
|
665
|
+
// aborts THIS turn (LLM fetch included — the signal reaches chatWithTools)
|
|
666
|
+
// while the conversation/process stays alive for the next message.
|
|
667
|
+
currentAbort = new AbortController();
|
|
668
|
+
const turnSignal = options.signal
|
|
669
|
+
? AbortSignal.any([options.signal, currentAbort.signal])
|
|
670
|
+
: currentAbort.signal;
|
|
671
|
+
|
|
524
672
|
let outcome;
|
|
525
673
|
try {
|
|
526
674
|
outcome = await runTurn(
|
|
527
675
|
messages,
|
|
528
|
-
{ ...loopOptionsBase, iterationBudget: budget },
|
|
676
|
+
{ ...loopOptionsBase, iterationBudget: budget, signal: turnSignal },
|
|
529
677
|
{ runLoop, emit },
|
|
530
678
|
);
|
|
531
679
|
} catch (err) {
|
|
680
|
+
currentAbort = null;
|
|
681
|
+
const isAbort =
|
|
682
|
+
err?.name === "AbortError" || /abort/i.test(err?.message || "");
|
|
683
|
+
if (isAbort && !options.signal?.aborted) {
|
|
684
|
+
// User-initiated turn interrupt — not an error; no assistant message
|
|
685
|
+
// is recorded (the dangling user turn is fine for the next exchange).
|
|
686
|
+
emit({
|
|
687
|
+
type: "result",
|
|
688
|
+
subtype: "interrupted",
|
|
689
|
+
is_error: false,
|
|
690
|
+
interrupted: true,
|
|
691
|
+
session_id: sessionId,
|
|
692
|
+
turn: turns,
|
|
693
|
+
});
|
|
694
|
+
continue;
|
|
695
|
+
}
|
|
696
|
+
if (isAbort) break; // outer options.signal — caller is shutting down
|
|
532
697
|
emit({
|
|
533
698
|
type: "result",
|
|
534
699
|
subtype: "error",
|
|
@@ -539,6 +704,7 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
539
704
|
sawError = true;
|
|
540
705
|
continue;
|
|
541
706
|
}
|
|
707
|
+
currentAbort = null;
|
|
542
708
|
|
|
543
709
|
// Grow the conversation so the next turn has context.
|
|
544
710
|
messages.push({ role: "assistant", content: outcome.finalText });
|
|
@@ -565,6 +731,19 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
565
731
|
turn: turns,
|
|
566
732
|
usage: outcome.usage,
|
|
567
733
|
});
|
|
734
|
+
|
|
735
|
+
// While planning, blocked tool calls grew the plan during this turn —
|
|
736
|
+
// push the fresh snapshot so the panel's plan card stays live.
|
|
737
|
+
{
|
|
738
|
+
const pm = getPlanModeManager();
|
|
739
|
+
if (pm.isActive()) {
|
|
740
|
+
emit({
|
|
741
|
+
type: "plan_update",
|
|
742
|
+
...planSnapshot(pm),
|
|
743
|
+
session_id: sessionId,
|
|
744
|
+
});
|
|
745
|
+
}
|
|
746
|
+
}
|
|
568
747
|
}
|
|
569
748
|
|
|
570
749
|
// Tear down ad-hoc MCP servers (--mcp-config) when stdin closes.
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./xterm-BZcWGsqw.js","./markdown-CsiA8-E5.js","./markdown-Dfs9RUU9.css","./addon-fit-CK6X9sAG.js","./xterm-DFuMZ0ql.css"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{u as fe,_ as me,d as V,e as U}from"./index-DMPQqeLb.js";import{I as z,J as x,U as _,Q as D,S as K,K as T,V as R,c as A,F as Q,Z as Y,R as E,o as G,f as H,w as $,n as q,b as ee,r as S,P as y,_ as ve,a2 as we,a3 as he,a4 as _e}from"./vendor-BvqAck49.js";import{R as ye,b as pe,as as ge}from"./icons-DP3uiYxy.js";const k=new Map,C=new Map,F=new Set,I=new Set;let te=!1;function xe(c){te||(te=!0,c.onMessage(o=>{if(!(!o||typeof o.type!="string")){if(o.type==="terminal.stdout"){const{sessionId:s,data:e,seq:i}=o.payload||{};if(!s)return;let w;try{const d=atob(e||""),f=new Uint8Array(d.length);for(let n=0;n<d.length;n++)f[n]=d.charCodeAt(n);w=new TextDecoder("utf-8").decode(f)}catch{w=""}const u={sessionId:s,data:w,seq:i};k.get(s)?.forEach(d=>d(u)),F.forEach(d=>d(u))}else if(o.type==="terminal.exit"){const{sessionId:s,exitCode:e,signal:i}=o.payload||{};if(!s)return;const w={sessionId:s,exitCode:e,signal:i};C.get(s)?.forEach(u=>u(w)),I.forEach(u=>u(w))}}}))}function ne(c){const o=new TextEncoder().encode(c);let s="";for(let e=0;e<o.length;e++)s+=String.fromCharCode(o[e]);return btoa(s)}function ae(c){const o=atob(c||""),s=new Uint8Array(o.length);for(let e=0;e<o.length;e++)s[e]=o.charCodeAt(e);return new TextDecoder("utf-8").decode(s)}function oe(){const c=fe();xe(c);async function o(n={}){const a=await c.sendRaw({type:"terminal.create",payload:{shell:n.shell,cwd:n.cwd,env:n.env,cols:n.cols,rows:n.rows}});if(a.ok===!1)throw new Error(a.error||"terminal_create_failed");return a.result??a}async function s(){const n=await c.sendRaw({type:"terminal.list",payload:{}});if(n.ok===!1)throw new Error(n.error||"terminal_list_failed");const a=n.result??n;return Array.isArray(a.sessions)?a.sessions:[]}async function e(n,a){const r=await c.sendRaw({type:"terminal.stdin",payload:{sessionId:n,data:ne(String(a))}});if(r.ok===!1)throw new Error(r.error||"terminal_stdin_failed");return r.result??r}async function i(n,a,r){const h=await c.sendRaw({type:"terminal.resize",payload:{sessionId:n,cols:a,rows:r}});if(h.ok===!1)throw new Error(h.error||"terminal_resize_failed");return h.result??h}async function w(n){const a=await c.sendRaw({type:"terminal.close",payload:{sessionId:n}});if(a.ok===!1)throw new Error(a.error||"terminal_close_failed");return a.result??a}async function u(n,a=0){const r=await c.sendRaw({type:"terminal.history",payload:{sessionId:n,fromSeq:a}});if(r.ok===!1)throw new Error(r.error||"terminal_history_failed");const h=r.result??r;return{truncated:!!h.truncated,chunks:(h.chunks||[]).map(L=>({seq:L.seq,data:ae(L.data)}))}}function d(n,a){return n?(k.has(n)||k.set(n,new Set),k.get(n).add(a),()=>{k.get(n)?.delete(a),k.get(n)?.size===0&&k.delete(n)}):(F.add(a),()=>F.delete(a))}function f(n,a){return n?(C.has(n)||C.set(n,new Set),C.get(n).add(a),()=>{C.get(n)?.delete(a),C.get(n)?.size===0&&C.delete(n)}):(I.add(a),()=>I.delete(a))}return{create:o,list:s,stdin:e,resize:i,close:w,history:u,onStdout:d,onExit:f,_internal:{stdoutSubs:k,exitSubs:C,toBase64Utf8:ne,fromBase64Utf8:ae}}}const Se={__name:"Terminal",setup(c,{expose:o}){o();const s=oe(),e=S([]),i=S(null),w=S("pwsh"),u=S(!1),d=S(!1),f=S(""),n=S(""),a=S([]),r=[{value:"pwsh",label:"PowerShell"},{value:"cmd",label:"CMD"},{value:"bash",label:"Bash"},{value:"wsl",label:"WSL"}],h=ee(()=>e.value.find(t=>t.id===i.value));function L(t){return t?t.slice(0,8):""}let O=null,M=null;async function N(){if(O)return{xtermMod:O,fitAddonMod:M};try{O=await U(()=>import("./xterm-BZcWGsqw.js").then(t=>t.x),__vite__mapDeps([0,1,2]),import.meta.url),M=await U(()=>import("./addon-fit-CK6X9sAG.js").then(t=>t.a),__vite__mapDeps([3,1,2]),import.meta.url),await U(()=>Promise.resolve({}),__vite__mapDeps([4]),import.meta.url)}catch(t){throw n.value="xterm 资源加载失败:"+(t?.message||"未知错误"),t}return{xtermMod:O,fitAddonMod:M}}async function B(t){await q();const{xtermMod:l,fitAddonMod:p}=await N(),b=a.value.find(v=>v?.dataset?.sessionId===t.id);if(!b)return;const m=new l.Terminal({cursorBlink:!0,fontFamily:'Consolas, "Courier New", monospace',fontSize:13,theme:{background:"#1e1e1e",foreground:"#d4d4d4"},convertEol:!1}),P=new p.FitAddon;m.loadAddon(P),m.open(b);try{P.fit()}catch{}t.xterm=m,t.fitAddon=P;const ie=m.onData(v=>{s.stdin(t.id,v).catch(g=>{String(g?.message||"").includes("dangerous_keyword_blocked")?V.warning("该命令被桌面端拦截(高危关键字)"):V.error("stdin 失败: "+(g?.message||g))})}),ce=s.onStdout(t.id,({data:v,seq:g})=>{t.lastSeq=g,m.write(v)}),de=s.onExit(t.id,({exitCode:v,signal:g})=>{t.alive=!1,t.exitCode=v,t.signal=g,m.writeln(`\r
|
|
3
|
-
\x1B[33m[session exited, code=${v}, signal=${g??"-"}]\x1B[0m`)});t.offs=()=>{try{ie.dispose?.()}catch{}ce(),de()};try{const{chunks:v,truncated:g}=await s.history(t.id,0);g&&m.writeln("\x1B[2m[history truncated — earlier output was evicted]\x1B[0m");for(const J of v)m.write(J.data),t.lastSeq=J.seq}catch(v){m.writeln(`\x1B[31m[history fetch failed: ${v?.message||v}]\x1B[0m`)}const j=new ResizeObserver(()=>{try{P.fit(),s.resize(t.id,m.cols,m.rows).catch(()=>{})}catch{}});j.observe(b);const ue=t.offs;t.offs=()=>{try{j.disconnect()}catch{}ue()}}async function re(){u.value=!0,f.value="";try{const t=await s.create({shell:w.value,cols:80,rows:24}),l={id:t.sessionId,shell:t.shell,cwd:"",alive:!0,lastSeq:0,exitCode:null,xterm:null,fitAddon:null,offs:()=>{}};e.value.push(l),i.value=l.id,await B(l)}catch(t){f.value=t?.message||String(t)}finally{u.value=!1}}async function se(t){try{await s.close(t)}catch(l){f.value=l?.message||String(l)}setTimeout(()=>W(t),500)}function W(t){const l=e.value.findIndex(b=>b.id===t);if(l===-1)return;const p=e.value[l];try{p.offs?.()}catch{}try{p.xterm?.dispose?.()}catch{}e.value.splice(l,1),i.value===t&&(i.value=e.value[0]?.id||null)}function le(t){i.value=t,q(()=>{const l=e.value.find(p=>p.id===t);try{l?.fitAddon?.fit()}catch{}})}async function X(){d.value=!0,f.value="";try{const t=await s.list();for(const l of t){const p=e.value.find(m=>m.id===l.id);if(p){p.alive=l.alive,p.lastSeq=l.lastSeq;continue}const b={id:l.id,shell:l.shell,cwd:l.cwd,alive:l.alive,lastSeq:l.lastSeq,exitCode:null,xterm:null,fitAddon:null,offs:()=>{}};e.value.push(b),await B(b)}!i.value&&e.value.length>0&&(i.value=e.value[0].id)}catch(t){f.value=t?.message||String(t)}finally{d.value=!1}}G(async()=>{await X()}),H(()=>{for(const t of e.value){try{t.offs?.()}catch{}try{t.xterm?.dispose?.()}catch{}}}),$(i,()=>{q(()=>{const t=h.value;try{t?.fitAddon?.fit()}catch{}})});const Z={term:s,sessions:e,activeId:i,newShell:w,creating:u,loadingList:d,error:f,warning:n,xtermContainers:a,shellOptions:r,active:h,shortId:L,get xtermMod(){return O},set xtermMod(t){O=t},get fitAddonMod(){return M},set fitAddonMod(t){M=t},loadXterm:N,mountXterm:B,onCreate:re,onClose:se,removeSession:W,activate:le,refreshList:X,ref:S,computed:ee,onMounted:G,onBeforeUnmount:H,nextTick:q,watch:$,get message(){return V},get PlusOutlined(){return ge},get CloseOutlined(){return pe},get ReloadOutlined(){return ye},get useTerminal(){return oe}};return Object.defineProperty(Z,"__isScriptSetup",{enumerable:!1,value:!0}),Z}},be={class:"terminal-page"},ke={class:"terminal-header"},Ce={class:"page-sub"},Ae={class:"terminal-body"},Ee={class:"session-tabs"},Oe=["onClick"],Te={class:"session-shell"},Re={class:"session-id"},Me={key:0,class:"session-empty"},ze={class:"xterm-host"},Le=["data-session-id"],Pe={key:0,class:"xterm-placeholder"},De={key:1,class:"terminal-footer"},qe={key:0,class:"footer-exit"};function Be(c,o,s,e,i,w){const u=z("a-tag"),d=z("a-select"),f=z("a-button"),n=z("a-space"),a=z("a-alert");return y(),x("div",be,[_("div",ke,[_("div",null,[o[3]||(o[3]=_("h2",{class:"page-title"},"远程终端",-1)),_("p",Ce,[o[2]||(o[2]=D(" 桌面端托管的 PTY 会话;Android 端可远程操控同一通道 ",-1)),e.warning?(y(),K(u,{key:0,color:"orange",style:{"margin-left":"8px"}},{default:T(()=>[D(E(e.warning),1)]),_:1})):R("v-if",!0)])]),A(n,null,{default:T(()=>[A(d,{value:e.newShell,"onUpdate:value":o[0]||(o[0]=r=>e.newShell=r),style:{width:"130px"},size:"small",options:e.shellOptions},null,8,["value"]),A(f,{type:"primary",size:"small",loading:e.creating,onClick:e.onCreate},{icon:T(()=>[A(e.PlusOutlined)]),default:T(()=>[o[4]||(o[4]=D(" 新会话 ",-1))]),_:1},8,["loading"]),A(f,{size:"small",loading:e.loadingList,onClick:e.refreshList},{icon:T(()=>[A(e.ReloadOutlined)]),default:T(()=>[o[5]||(o[5]=D(" 刷新 ",-1))]),_:1},8,["loading"])]),_:1})]),e.error?(y(),K(a,{key:0,message:e.error,type:"error","show-icon":"",closable:"",style:{"margin-bottom":"12px"},onClose:o[1]||(o[1]=r=>e.error="")},null,8,["message"])):R("v-if",!0),_("div",Ae,[_("div",Ee,[(y(!0),x(Q,null,Y(e.sessions,r=>(y(),x("div",{key:r.id,class:ve(["session-tab",{active:r.id===e.activeId,dead:!r.alive}]),onClick:h=>e.activate(r.id)},[_("span",Te,E(r.shell),1),_("span",Re,E(e.shortId(r.id)),1),A(e.CloseOutlined,{class:"session-close",onClick:we(h=>e.onClose(r.id),["stop"])},null,8,["onClick"])],10,Oe))),128)),e.sessions.length===0?(y(),x("div",Me,' 点击 "新会话" 创建第一个终端 ')):R("v-if",!0)]),_("div",ze,[(y(!0),x(Q,null,Y(e.sessions,r=>he((y(),x("div",{key:r.id,ref_for:!0,ref:"xtermContainers","data-session-id":r.id,class:"xterm-container"},null,8,Le)),[[_e,r.id===e.activeId]])),128)),e.sessions.length===0?(y(),x("div",Pe,[...o[6]||(o[6]=[_("span",null,"无活跃会话",-1)])])):R("v-if",!0)])]),e.active?(y(),x("div",De,[_("span",null,E(e.active.shell)+" · "+E(e.active.cwd||"(默认 cwd)")+" · seq "+E(e.active.lastSeq),1),e.active.alive?R("v-if",!0):(y(),x("span",qe,"已退出 (code="+E(e.active.exitCode??"-")+")",1))])):R("v-if",!0)])}const Ie=me(Se,[["render",Be],["__scopeId","data-v-65366a29"],["__file","/tmp/cc-web-panel-Fa41ZI/repo/packages/web-panel/src/views/Terminal.vue"]]);export{Ie as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{O as r}from"./index-DMPQqeLb.js";const o=((n,a,e)=>{r(n,`[ant-design-vue: ${a}] ${e}`)});export{o as d};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{A as o}from"./Row-DvfqASM7.js";import{U as t}from"./index-DMPQqeLb.js";import"./vendor-BvqAck49.js";import"./responsiveObserve-DV6XM19W.js";import"./useFlexGapSupport-t20RbINy.js";import"./styleChecker-CsoP0nmm.js";import"./index-CR3QNisI.js";import"./icons-DP3uiYxy.js";const l=t(o);export{l as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{C as o}from"./Col-BowFdito.js";import{U as t}from"./index-DMPQqeLb.js";import"./vendor-BvqAck49.js";import"./index-CR3QNisI.js";import"./icons-DP3uiYxy.js";const s=t(o);export{s as default};
|