chainlesschain 0.162.168 → 0.162.170
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 +2 -2
- package/src/assets/web-panel/assets/{AIOps-CDzzuWZV.js → AIOps-BTXN24I3.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-Dy-8MmQi.js → ActionButton-BBB1VF4j.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-BtJ_VWkx.js → Analytics-BVCXq0k6.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-DkjiI4VS.js → AppLayout-C3EOo2s5.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-h8PyDO86.js → Artifacts-CsJTZSMv.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-DiDV0C6l.js → Audit-CP0AllJ_.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-DTw_aOaf.js → BackgroundAgents-BCAjs08m.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-CihFuUO9.js → Backup-BxQI5XH4.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-CqP2QNoR.js → BaseInput-Bu-PNzC5.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-tm-ygX-p.js → Chat-DjPQynup.js} +5 -5
- package/src/assets/web-panel/assets/ChatBubbleRenderer-CygkRopu.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-BFMyRN3Q.js → Checkbox-BxL6xm7Z.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-B1gTeoAS.js → Codegen-CcyB7h_6.js} +1 -1
- package/src/assets/web-panel/assets/{Col-1GP8MvKL.js → Col-8NQiKJJx.js} +1 -1
- package/src/assets/web-panel/assets/{Community-BLY938F6.js → Community-B31qy5OS.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-DVt_p36I.js → Compact-C-5fAsZ4.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-DxqEBXVG.js → Compliance-BTSccvF0.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-CyWrM-T8.js → Cowork-BXctU9IK.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-Domu6aI9.js → Cron-CxVFX9NG.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-C8LKpjHJ.js → Crosschain-DEF3dq8M.js} +1 -1
- package/src/assets/web-panel/assets/{DID-XBy15RZ5.js → DID-BmKcE9he.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-DDAyPD-V.js → Dashboard-CECBq_wG.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-BHV0MZ13.js → Dropdown-U-iuPB0n.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-DmFGW4PX.js → EmailListRenderer-D8BIlSPL.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-CqYdbKvd.js → FamilyGuardDashboard-BzQGfUH-.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-YP5-Puv5.js → Federation-4_WlOqLZ.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-BOmcIcTe.js → FormItemContext-gtrW-DdF.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-CvTZdoc4.js → GenericCardRenderer-BLcvJJB6.js} +1 -1
- package/src/assets/web-panel/assets/{Git-Q2oxua0L.js → Git-Bk0janGD.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-D-WpyWEU.js → Governance-CcfyMlV8.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-NUtsYHQo.js → Inference-CBLrAf4M.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-BHQLa8fr.js → KnowledgeGraph-ClguhteZ.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-6WsR5Q1G.js → Logs-Dp_oeKfJ.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-DuWoDwMx.js → MarkdownRenderer-RQ1HbTY5.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-CigohRRW.js → Marketplace-BHk50smM.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-jcp6jVLf.js → McpTools-BAY3CV6J.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-B00NU1ph.js → Memory-w0pG2AKx.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-Cs_p3PzU.js → MobileBridge-C0VkDUE3.js} +1 -1
- package/src/assets/web-panel/assets/MobileProjects-BCvQ80I9.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-CSEflwzw.js → Mtc-DSIl41Tt.js} +6 -6
- package/src/assets/web-panel/assets/{MtcAudit-dxSiEZ96.js → MtcAudit-D1mzUlIr.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-CDAFEAyq.js → Multisig-CeJz4VSS.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-HoFpZNiB.js → NLProgramming-_O3aweu8.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-tAoQvVcE.js → Notes-Dt7_pO86.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-Czo2M9F4.js → NotificationSettings-Dhg3Nktv.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-CM1kNTp6.js → OrderTableRenderer-QsAPcTb2.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-Cudr0VOC.js → Organization-BuiaUPkv.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-BSXeDKiN.js → Overflow-C3jb6knl.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-Cqv_g-F9.js → P2P-BOMyrLkb.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-7rjprPh8.js → PdhVaultBrowser-UvLStCgS.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-97pIDQKE.js → Permissions-B9cN0dJH.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-bparK9eQ.js → PersonalDataHub-DNjW5qro.js} +2 -2
- package/src/assets/web-panel/assets/{Pipeline-CJgerM09.js → Pipeline-CFLyZ6Sh.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-JqFS3PN7.js → Privacy-D3w6vOxf.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-DMITd-2c.js → ProjectInit-cwcVsn8K.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-1UkdJ8Ii.js → ProjectSettings-aUoAroc-.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-CYZqegqw.js → Projects-CrzQv7Zv.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-ChfXz3U0.js → Providers-jZaPizKR.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-Rzkka-mf.js → QrScannerModal-DNzmwcfg.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-DEz9HaON.js → QuickAsk-m-5Gwt70.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-EFGP8AVu.js → Recommend-CrrAjNxP.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-6um0lGGy.js → RemoteSession-BDCMjRFe.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-CA1BXTup.js → Reputation-CPCt1Jc8.js} +1 -1
- package/src/assets/web-panel/assets/{Row-stTnDJ9y.js → Row-C-RorxHs.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-B10qCCoG.js → RssFeed-CnQs4TuY.js} +3 -3
- package/src/assets/web-panel/assets/{Search-DSJroZ6p.js → Search-B1jkeFZY.js} +1 -1
- package/src/assets/web-panel/assets/{Security-BpXkwiMW.js → Security-CGKI3vvd.js} +4 -4
- package/src/assets/web-panel/assets/{Services-BPQxjwK6.js → Services-DQjesYF8.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-CfbKAMul.js → Skeleton-C9Ipj0A6.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-CttYTfX0.js → Skills-D2j54i9O.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-ByluHich.js → Sla-xhrVjTeb.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-BdZXKsfV.js → SpeechSettings-C6KMOUCa.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-xCR7iDzy.js → SyncSettings-CmIPU5wR.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-qTko_INn.js → Tasks-B-T1J42r.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-CkIzhgDJ.js → Templates-Aq669sjw.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-BIaCaaK8.js → Tenant-BKWUWNXB.js} +1 -1
- package/src/assets/web-panel/assets/Terminal-DEeAvA8L.js +3 -0
- package/src/assets/web-panel/assets/{TimelineRenderer-D5eQDnEF.js → TimelineRenderer-C465ySdn.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-DmeJ8NMQ.js → Tokens-BgVqF-bX.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-C5sgb3C7.js → Trigger-BMNHmxwH.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-H2vOb3Rb.js → Trust-B_adk89L.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-NmPtHK2u.js → UkeySign-Biw38mog.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-DHv-Ti7K.js → VideoEditing-AC-eaw5k.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-BYZ3-PRP.js → Wallet-8lQ5_t0X.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-BaSlP7om.js → WebAuthn-JDmH_-DF.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-CZ7IHuIi.js → WorkflowEditor-DHQAdITG.js} +1 -1
- package/src/assets/web-panel/assets/{chat-Dd9kY8gn.js → chat-C3qauUVv.js} +1 -1
- package/src/assets/web-panel/assets/{colors-yhzo6QSV.js → colors-DLP70JGe.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-C1JneVdM.js → compact-item-DjsoqA5t.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-C_waVCg2.js → createContext-CfEdl1in.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-Cwuuqc_f.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-CkVg0Xnh.js → hasIn-DWwHHlBG.js} +1 -1
- package/src/assets/web-panel/assets/{index-DapftLUr.js → index-ArZCi1rK.js} +1 -1
- package/src/assets/web-panel/assets/{index-C-Sscgnv.js → index-B-rD2rhi.js} +1 -1
- package/src/assets/web-panel/assets/{index-CGtoL5mR.js → index-B4gCFHtB.js} +1 -1
- package/src/assets/web-panel/assets/{index-Diquc7-l.js → index-BcDeMCUK.js} +1 -1
- package/src/assets/web-panel/assets/index-BkTk-zJK.js +1 -0
- package/src/assets/web-panel/assets/{index-D6UXDH2D.js → index-Bp_WNm2_.js} +1 -1
- package/src/assets/web-panel/assets/{index-DhZgULsY.js → index-BqPuyN4p.js} +1 -1
- package/src/assets/web-panel/assets/{index-DuGtLiTW.js → index-BydBh7oT.js} +1 -1
- package/src/assets/web-panel/assets/index-C-BSTEhe.js +1 -0
- package/src/assets/web-panel/assets/{index-D7kQ_4uL.js → index-C0xMzvk8.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bx3A6X4J.js → index-C47EiQ7d.js} +1 -1
- package/src/assets/web-panel/assets/{index-C4HNdMCt.js → index-C4k6JGm_.js} +1 -1
- package/src/assets/web-panel/assets/{index-BsSsurcn.js → index-C8wrUFzY.js} +1 -1
- package/src/assets/web-panel/assets/{index-CUDjGt_V.js → index-CNeLedtU.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dez7TUgG.js → index-CbF27GqZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-BlJNvg-2.js → index-CgruUvB3.js} +1 -1
- package/src/assets/web-panel/assets/{index-BYOyb5X2.js → index-CnhJbWsl.js} +1 -1
- package/src/assets/web-panel/assets/{index-_M8El5iz.js → index-CsEk9s04.js} +1 -1
- package/src/assets/web-panel/assets/{index-ClQhh6v3.js → index-D-te-S9f.js} +1 -1
- package/src/assets/web-panel/assets/{index-_rZxgFtc.js → index-D5VL0NYy.js} +1 -1
- package/src/assets/web-panel/assets/{index-BrN2hAeE.js → index-DAcBi6F-.js} +1 -1
- package/src/assets/web-panel/assets/{index-DPkqQ2Pr.js → index-DKsWujXP.js} +1 -1
- package/src/assets/web-panel/assets/{index-CErewFeT.js → index-DTDpF8MS.js} +1 -1
- package/src/assets/web-panel/assets/{index-C_qqYZT7.js → index-DTEcPJGf.js} +1 -1
- package/src/assets/web-panel/assets/{index-U_nLXGIx.js → index-DbFnfyKh.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bwuu3Bf3.js → index-DbjUePgq.js} +1 -1
- package/src/assets/web-panel/assets/{index-CfEMjbhu.js → index-Dfka-vzJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-C_riAa6d.js → index-DgQ92xdO.js} +1 -1
- package/src/assets/web-panel/assets/{index-D1xIbAxQ.js → index-Dmt1HDWZ.js} +3 -3
- package/src/assets/web-panel/assets/{index-BlzbSUK9.js → index-Dn2rNMmv.js} +1 -1
- package/src/assets/web-panel/assets/{index-ewb0-LoH.js → index-Ds1BfT_C.js} +1 -1
- package/src/assets/web-panel/assets/{index-BjDnI7oM.js → index-Lh0e2afo.js} +1 -1
- package/src/assets/web-panel/assets/{index-DUA96wEj.js → index-OfMwkFIo.js} +1 -1
- package/src/assets/web-panel/assets/{index-CmiLmG0i.js → index-T5emAyFT.js} +1 -1
- package/src/assets/web-panel/assets/{index-_VmzCYFn.js → index-UEbYl2pu.js} +1 -1
- package/src/assets/web-panel/assets/{index-1VYhIr6D.js → index-VtCz3A64.js} +1 -1
- package/src/assets/web-panel/assets/{index-DXHk9Vof.js → index-_g5q2hF3.js} +1 -1
- package/src/assets/web-panel/assets/{index-CBwmwTNa.js → index-gu8zBhtp.js} +1 -1
- package/src/assets/web-panel/assets/{index-BTMiVIBI.js → index-nuZaMsMy.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-DNN6qtGa.js → initDefaultProps-C_pMmi75.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BcM9exeo.js → motion-BvKgS96o.js} +1 -1
- package/src/assets/web-panel/assets/{move-DsKJ-YvA.js → move-C-1U4R1I.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-glgGkxaK.js → mtc-parser-D6BC968-.js} +1 -1
- package/src/assets/web-panel/assets/{omit-BwHCU50S.js → omit-DxOZvcGQ.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-BVp-bLt7.js → pickAttrs-LpzmHdkw.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-CZNe0r-w.js → placementArrow-Bm--qom1.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-DUafj9pU.js → responsiveObserve-CVZZlhJf.js} +1 -1
- package/src/assets/web-panel/assets/{slide-H4NqXQxu.js → slide-DD1xINGx.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-UjMzzGZ5.js → statusUtils-LrjHAy63.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-qO5aCjyk.js → styleChecker-BqknYxTe.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-ChecYwC8.js → useFlexGapSupport-Dljy3diT.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-BR0QvwO3.js → useFs-OedUtPLc.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-DitK2Qgz.js → usePersonalDataHub-Cz-kxbP_.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-dxSb40dY.js → vnode-C8ZuTk8W.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-ekJk8YB2.js → zoom-CjbgJYXQ.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/plugin.js +49 -5
- package/src/data/changelog.json +22 -4
- package/src/lib/background-agent-phase.js +22 -0
- package/src/lib/background-agent-supervisor.js +41 -10
- package/src/lib/background-phase-reporter.js +37 -0
- package/src/lib/install-command-policy.js +29 -0
- package/src/lib/packer/smoke-runner.js +5 -0
- package/src/lib/session-lifecycle.js +3 -0
- package/src/runtime/agent-core.js +31 -7
- package/src/runtime/headless-runner.js +42 -9
- package/src/runtime/headless-stream.js +158 -2
- package/src/workers/background-agent-worker.js +17 -4
- package/src/assets/web-panel/assets/ChatBubbleRenderer-BVKEhj_y.js +0 -1
- package/src/assets/web-panel/assets/MobileProjects-BFs2WljZ.js +0 -1
- package/src/assets/web-panel/assets/Terminal-B2Qq38XP.js +0 -3
- package/src/assets/web-panel/assets/devWarning-DaDlyVDY.js +0 -1
- package/src/assets/web-panel/assets/index-BtsLExcc.js +0 -1
- package/src/assets/web-panel/assets/index-C3qDvvIb.js +0 -1
|
@@ -95,6 +95,43 @@ export function createBackgroundPhaseReporter(opts = {}) {
|
|
|
95
95
|
patch({ pendingApprovals: pending });
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
|
+
/**
|
|
99
|
+
* A resumed run found side-effect ops whose outcome is UNKNOWN (the
|
|
100
|
+
* ledger reconcile "inspect" bucket): surface `uncertain_side_effect` so
|
|
101
|
+
* the dashboard demands a look before anything is replayed. The worker
|
|
102
|
+
* clears the count at the next turn/idle boundary (the verify turn has
|
|
103
|
+
* then run its course), so this is a within-window annotation, not a
|
|
104
|
+
* sticky flag. Best-effort; returns whether the state was patched.
|
|
105
|
+
*/
|
|
106
|
+
reportUncertainSideEffects(count) {
|
|
107
|
+
if (!enabled) return false;
|
|
108
|
+
const n = Number(count);
|
|
109
|
+
if (!Number.isFinite(n) || n <= 0) return false;
|
|
110
|
+
return patch({
|
|
111
|
+
phase: "uncertain_side_effect",
|
|
112
|
+
uncertainSideEffects: Math.floor(n),
|
|
113
|
+
});
|
|
114
|
+
},
|
|
115
|
+
/**
|
|
116
|
+
* The model asked the user a question in a background turn
|
|
117
|
+
* (`ask_user_question`): there is no live channel to a human mid-turn, so
|
|
118
|
+
* the question is PARKED — recorded in the shared state as
|
|
119
|
+
* `pendingQuestion` with `phase: "needs_input"` (distinct from
|
|
120
|
+
* waiting_permission: this is a question, not an approval). The worker
|
|
121
|
+
* keeps `needs_input` through the idle boundary while the question is
|
|
122
|
+
* unanswered and clears it when the user's reply starts the next turn.
|
|
123
|
+
*/
|
|
124
|
+
reportQuestion(question) {
|
|
125
|
+
if (!enabled) return false;
|
|
126
|
+
const q = question && typeof question === "object" ? question : null;
|
|
127
|
+
return patch({
|
|
128
|
+
phase: "needs_input",
|
|
129
|
+
pendingQuestion: {
|
|
130
|
+
question: typeof q?.question === "string" ? q.question : "",
|
|
131
|
+
options: Array.isArray(q?.options) ? q.options : null,
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
},
|
|
98
135
|
/**
|
|
99
136
|
* Wrap a (potentially human-blocking) confirmer so the pending window is
|
|
100
137
|
* visible in the background state. Disabled → returns `confirmer`
|
|
@@ -279,6 +279,35 @@ export function classifyCodeAcquisition(command) {
|
|
|
279
279
|
};
|
|
280
280
|
}
|
|
281
281
|
|
|
282
|
+
/**
|
|
283
|
+
* Classify a PLUGIN install (`cc plugin add`/`upgrade`) into the unified
|
|
284
|
+
* "downloading and running third-party code" trail. A plugin ships executable
|
|
285
|
+
* components (bin/hooks/LSP/MCP servers run as processes), so installing one
|
|
286
|
+
* is the plugin-runtime sibling of a global package install — same audit
|
|
287
|
+
* file, same opt-in policy. Pure; returns null for a nameless input.
|
|
288
|
+
*/
|
|
289
|
+
export function classifyPluginInstall({
|
|
290
|
+
name,
|
|
291
|
+
version,
|
|
292
|
+
scope,
|
|
293
|
+
source,
|
|
294
|
+
capabilities,
|
|
295
|
+
} = {}) {
|
|
296
|
+
if (!name || typeof name !== "string") return null;
|
|
297
|
+
return {
|
|
298
|
+
manager: "cc-plugin",
|
|
299
|
+
packages: [version ? `${name}@${version}` : name],
|
|
300
|
+
// A user-scope plugin loads in EVERY repo the user runs cc in — the
|
|
301
|
+
// plugin-runtime analogue of `npm install -g`. Project/local scopes stay
|
|
302
|
+
// confined to one repository.
|
|
303
|
+
global: scope === "user",
|
|
304
|
+
...(source ? { source: String(source) } : {}),
|
|
305
|
+
...(Array.isArray(capabilities) && capabilities.length
|
|
306
|
+
? { capabilities }
|
|
307
|
+
: {}),
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
|
|
282
311
|
/**
|
|
283
312
|
* Resolve the install-command policy from env/settings (opt-in, so the default
|
|
284
313
|
* shell path is byte-unchanged). `audit` enables the audit trail; `riskFloor`
|
|
@@ -111,6 +111,11 @@ export async function smokeTestExe(ctx) {
|
|
|
111
111
|
// child.kill on Windows doesn't traverse the process tree; taskkill
|
|
112
112
|
// does. We spawned a single exe with no subprocesses so plain kill
|
|
113
113
|
// is enough in practice, but /T protects us if that ever changes.
|
|
114
|
+
// Skip when the child has ALREADY exited: Windows recycles pids
|
|
115
|
+
// within seconds, so taskkilling a dead child's pid can murder an
|
|
116
|
+
// unrelated process tree that inherited the number (on CI: another
|
|
117
|
+
// vitest worker or a test's helper child).
|
|
118
|
+
if (child.exitCode !== null || child.signalCode !== null) return;
|
|
114
119
|
spawn("taskkill", ["/F", "/T", "/PID", String(child.pid)], {
|
|
115
120
|
stdio: "ignore",
|
|
116
121
|
}).unref();
|
|
@@ -86,6 +86,9 @@ const STATE_ALIASES = new Map([
|
|
|
86
86
|
["waiting-permission", SESSION_STATES.WAITING_APPROVAL],
|
|
87
87
|
["waiting_approval", SESSION_STATES.WAITING_APPROVAL],
|
|
88
88
|
["awaiting_approval", SESSION_STATES.WAITING_APPROVAL],
|
|
89
|
+
// A resumed turn with UNKNOWN-outcome side effects blocks on confirmation.
|
|
90
|
+
["uncertain_side_effect", SESSION_STATES.WAITING_APPROVAL],
|
|
91
|
+
["uncertain-side-effect", SESSION_STATES.WAITING_APPROVAL],
|
|
89
92
|
// supervisor liveness — a running process that vanished is a failure.
|
|
90
93
|
["lost", SESSION_STATES.FAILED],
|
|
91
94
|
// IDE connection / transport
|
|
@@ -2210,17 +2210,29 @@ const EDIT_DIAGNOSTICS_WALL_MS = 6000;
|
|
|
2210
2210
|
* never cold-starts a server that isn't there) and fully bounded in time.
|
|
2211
2211
|
* Disable entirely with CC_EDIT_DIAGNOSTICS=0.
|
|
2212
2212
|
*/
|
|
2213
|
-
async function _postEditDiagnostics(filePath, cwd) {
|
|
2213
|
+
async function _postEditDiagnostics(filePath, cwd, additionalDirectories) {
|
|
2214
2214
|
if (process.env.CC_EDIT_DIAGNOSTICS === "0") return null;
|
|
2215
|
+
// Multi-root workspace: resolve the server against the root that CONTAINS
|
|
2216
|
+
// the edited file (mirrors the code_intelligence handler) — editing a file
|
|
2217
|
+
// inside an `--add-dir` root probes/uses THAT project's language server
|
|
2218
|
+
// instead of degrading to "no diagnostics" via the cwd root. Single-root
|
|
2219
|
+
// sessions (no additionalDirectories) resolve to cwd exactly as before.
|
|
2220
|
+
let root;
|
|
2221
|
+
try {
|
|
2222
|
+
root = pickRootForFile(
|
|
2223
|
+
path.resolve(cwd || process.cwd(), filePath),
|
|
2224
|
+
workspaceRootsFor(cwd, additionalDirectories),
|
|
2225
|
+
);
|
|
2226
|
+
} catch {
|
|
2227
|
+
root = path.resolve(cwd || process.cwd());
|
|
2228
|
+
}
|
|
2215
2229
|
let hasServer = false;
|
|
2216
2230
|
try {
|
|
2217
2231
|
const { languageIdForFile, resolveServer } =
|
|
2218
2232
|
await import("../lib/lsp/lsp-server-registry.js");
|
|
2219
2233
|
const languageId = languageIdForFile(filePath);
|
|
2220
2234
|
if (!languageId) return null; // unsupported file type — no LSP, no cost
|
|
2221
|
-
hasServer = Boolean(
|
|
2222
|
-
resolveServer(languageId, path.resolve(cwd || process.cwd())),
|
|
2223
|
-
);
|
|
2235
|
+
hasServer = Boolean(resolveServer(languageId, root));
|
|
2224
2236
|
} catch {
|
|
2225
2237
|
return null;
|
|
2226
2238
|
}
|
|
@@ -2228,7 +2240,7 @@ async function _postEditDiagnostics(filePath, cwd) {
|
|
|
2228
2240
|
|
|
2229
2241
|
const query = (async () => {
|
|
2230
2242
|
try {
|
|
2231
|
-
const ci = await _getSharedCodeIntel(
|
|
2243
|
+
const ci = await _getSharedCodeIntel(root);
|
|
2232
2244
|
const res = await ci.refreshFile(filePath, { timeoutMs: 3000 });
|
|
2233
2245
|
if (!res || res.available === false) return null;
|
|
2234
2246
|
const diags = (res.diagnostics || []).filter(
|
|
@@ -2263,8 +2275,17 @@ async function _postEditDiagnostics(filePath, cwd) {
|
|
|
2263
2275
|
}
|
|
2264
2276
|
|
|
2265
2277
|
/** Merge post-edit diagnostics into a successful edit result (no-op if none). */
|
|
2266
|
-
async function _withPostEditDiagnostics(
|
|
2267
|
-
|
|
2278
|
+
async function _withPostEditDiagnostics(
|
|
2279
|
+
result,
|
|
2280
|
+
filePath,
|
|
2281
|
+
cwd,
|
|
2282
|
+
additionalDirectories,
|
|
2283
|
+
) {
|
|
2284
|
+
const newDiagnostics = await _postEditDiagnostics(
|
|
2285
|
+
filePath,
|
|
2286
|
+
cwd,
|
|
2287
|
+
additionalDirectories,
|
|
2288
|
+
);
|
|
2268
2289
|
return newDiagnostics ? { ...result, newDiagnostics } : result;
|
|
2269
2290
|
}
|
|
2270
2291
|
|
|
@@ -2570,6 +2591,7 @@ async function executeToolInner(
|
|
|
2570
2591
|
{ success: true, path: filePath, size: wrote.size },
|
|
2571
2592
|
filePath,
|
|
2572
2593
|
cwd,
|
|
2594
|
+
additionalDirectories,
|
|
2573
2595
|
),
|
|
2574
2596
|
filePath,
|
|
2575
2597
|
cwd,
|
|
@@ -2668,6 +2690,7 @@ async function executeToolInner(
|
|
|
2668
2690
|
},
|
|
2669
2691
|
filePath,
|
|
2670
2692
|
cwd,
|
|
2693
|
+
additionalDirectories,
|
|
2671
2694
|
),
|
|
2672
2695
|
filePath,
|
|
2673
2696
|
cwd,
|
|
@@ -2731,6 +2754,7 @@ async function executeToolInner(
|
|
|
2731
2754
|
},
|
|
2732
2755
|
filePath,
|
|
2733
2756
|
cwd,
|
|
2757
|
+
additionalDirectories,
|
|
2734
2758
|
),
|
|
2735
2759
|
filePath,
|
|
2736
2760
|
cwd,
|
|
@@ -703,6 +703,15 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
703
703
|
// mid-flight does NOT blindly replay an effect that may already have landed.
|
|
704
704
|
// Only active when persisting (an ephemeral/one-shot run can't be resumed);
|
|
705
705
|
// the byte-for-byte default path is untouched when no dangerous tool runs.
|
|
706
|
+
// Background phase reporter (P0 state-machine producer): when this run IS a
|
|
707
|
+
// background agent's turn child (CC_BACKGROUND_AGENT_ID set by the worker),
|
|
708
|
+
// human-blocking windows are surfaced into the shared state file. Created
|
|
709
|
+
// here — before the resume reconcile below — so an UNKNOWN-outcome side
|
|
710
|
+
// effect found on resume can be reported too. For every non-background run
|
|
711
|
+
// this is a disabled no-op.
|
|
712
|
+
const _bgPhase =
|
|
713
|
+
deps.backgroundPhaseReporter || createBackgroundPhaseReporter();
|
|
714
|
+
|
|
706
715
|
const sideEffectRunNonce = String(deps.now ? deps.now() : Date.now());
|
|
707
716
|
let sideEffectLedger = new SideEffectLedger({ clock: deps.now || null });
|
|
708
717
|
let sideEffectSeq = 0;
|
|
@@ -765,6 +774,11 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
765
774
|
writeErr(
|
|
766
775
|
`⚠ ${plan.inspect.length} interrupted side-effect(s) need verification before replay (resume ${resumeId}).\n`,
|
|
767
776
|
);
|
|
777
|
+
// P0 state machine: a background child resuming with UNKNOWN-outcome
|
|
778
|
+
// ops advertises `uncertain_side_effect` (dashboard: Needs input) —
|
|
779
|
+
// someone must confirm before any replay. No-op unless this run is a
|
|
780
|
+
// background turn child; best-effort by construction.
|
|
781
|
+
_bgPhase.reportUncertainSideEffects(plan.inspect.length);
|
|
768
782
|
}
|
|
769
783
|
} catch {
|
|
770
784
|
resumeSideEffectContext = null;
|
|
@@ -1156,15 +1170,9 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
1156
1170
|
// IDE context is optional polish — never fail the run over it.
|
|
1157
1171
|
}
|
|
1158
1172
|
|
|
1159
|
-
//
|
|
1160
|
-
//
|
|
1161
|
-
//
|
|
1162
|
-
// `phase: "waiting_permission"` + `pendingApprovals` in the shared state
|
|
1163
|
-
// file so the dashboard's "Needs input" group is real, not inferred. For
|
|
1164
|
-
// every non-background run this is a disabled no-op (wrapConfirmer returns
|
|
1165
|
-
// the same function object).
|
|
1166
|
-
const _bgPhase =
|
|
1167
|
-
deps.backgroundPhaseReporter || createBackgroundPhaseReporter();
|
|
1173
|
+
// (`_bgPhase` — the background phase reporter — is created before the resume
|
|
1174
|
+
// reconcile block above; the confirmers below reuse it to surface their
|
|
1175
|
+
// pending window as `phase: "waiting_permission"` + `pendingApprovals`.)
|
|
1168
1176
|
|
|
1169
1177
|
// --permission-prompt-tool: route every CONFIRM-tier approval to an MCP tool
|
|
1170
1178
|
// (loaded via --mcp-config) instead of headless fail-closed. Overrides the
|
|
@@ -1328,6 +1336,31 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
1328
1336
|
enabledToolNames,
|
|
1329
1337
|
disabledTools,
|
|
1330
1338
|
iterationBudget: budget,
|
|
1339
|
+
// `ask_user_question` in a BACKGROUND turn child (P0 state-machine
|
|
1340
|
+
// producer for `needs_input`): there is no live channel to a human
|
|
1341
|
+
// mid-turn, but the question IS the structured needs-input signal. Park
|
|
1342
|
+
// it — record `phase: "needs_input"` + the question in the shared state
|
|
1343
|
+
// file (dashboard "Needs input" gets real data; the user's reply arrives
|
|
1344
|
+
// as the next attach prompt) and tell the model to end the turn. A
|
|
1345
|
+
// non-background run supplies no interaction → the handler's existing
|
|
1346
|
+
// `user_not_reachable` path stays byte-identical.
|
|
1347
|
+
...(_bgPhase.enabled
|
|
1348
|
+
? {
|
|
1349
|
+
interaction: {
|
|
1350
|
+
askUser: async ({ question, options: qOptions } = {}) => {
|
|
1351
|
+
_bgPhase.reportQuestion({
|
|
1352
|
+
question: typeof question === "string" ? question : "",
|
|
1353
|
+
options: Array.isArray(qOptions) ? qOptions : null,
|
|
1354
|
+
});
|
|
1355
|
+
throw new Error(
|
|
1356
|
+
"question parked for the user (background session). End this " +
|
|
1357
|
+
"turn now — the user's reply will arrive as the next " +
|
|
1358
|
+
"message. Do not repeat the question.",
|
|
1359
|
+
);
|
|
1360
|
+
},
|
|
1361
|
+
},
|
|
1362
|
+
}
|
|
1363
|
+
: {}),
|
|
1331
1364
|
// --mcp-config wiring: tool defs for the LLM + dispatch map + live client.
|
|
1332
1365
|
mcpClient: mcp?.mcpClient || null,
|
|
1333
1366
|
extraToolDefinitions: mcp?.extraToolDefinitions || undefined,
|
|
@@ -75,6 +75,15 @@ import {
|
|
|
75
75
|
rebuildMessages as jsonlRebuildMessages,
|
|
76
76
|
sessionExists as jsonlSessionExists,
|
|
77
77
|
} from "../harness/jsonl-session-store.js";
|
|
78
|
+
import {
|
|
79
|
+
reconcileSideEffects,
|
|
80
|
+
classifyToolSideEffect,
|
|
81
|
+
} from "../lib/side-effect-ledger.js";
|
|
82
|
+
import {
|
|
83
|
+
loadSideEffectLedger,
|
|
84
|
+
persistSideEffectLedger,
|
|
85
|
+
} from "../lib/side-effect-ledger-store.js";
|
|
86
|
+
import { operationIdempotencyKey } from "../lib/idempotency.js";
|
|
78
87
|
import { getPlanModeManager } from "../lib/plan-mode.js";
|
|
79
88
|
|
|
80
89
|
/**
|
|
@@ -527,6 +536,46 @@ export async function* readJsonLines(input, opts = {}) {
|
|
|
527
536
|
if (!overflow && buf.trim()) yield buf;
|
|
528
537
|
}
|
|
529
538
|
|
|
539
|
+
/**
|
|
540
|
+
* P0-2: on a stream resume, surface any irreversible tool that was in flight
|
|
541
|
+
* when the prior run died. Same reconcile + wording as the single-prompt
|
|
542
|
+
* runner (headless-runner.js) and the WS bridge (session-protocol.js): a
|
|
543
|
+
* `started`-but-unsettled op's outcome is UNKNOWN, so the model must VERIFY
|
|
544
|
+
* before any replay rather than silently re-issue the effect. Returns
|
|
545
|
+
* {count, items, notice} or null when nothing needs verification — a clean
|
|
546
|
+
* (or absent) ledger keeps the resume byte-identical to today.
|
|
547
|
+
*/
|
|
548
|
+
function buildSideEffectRecovery(ledger) {
|
|
549
|
+
try {
|
|
550
|
+
const plan = reconcileSideEffects(ledger);
|
|
551
|
+
if (!plan.inspect.length) return null;
|
|
552
|
+
const items = plan.plans
|
|
553
|
+
.filter((p) => p.action === "inspect")
|
|
554
|
+
.map((p) => {
|
|
555
|
+
const op = ledger.get(p.opId) || {};
|
|
556
|
+
return {
|
|
557
|
+
kind: op.kind || "unknown",
|
|
558
|
+
key: op.key || null,
|
|
559
|
+
reason: p.reason,
|
|
560
|
+
};
|
|
561
|
+
});
|
|
562
|
+
const notice =
|
|
563
|
+
"Recovery notice — the previous run was interrupted while these " +
|
|
564
|
+
"irreversible operations were in flight; their outcome is UNKNOWN. Do " +
|
|
565
|
+
"NOT blindly re-run them. Verify whether each already took effect before " +
|
|
566
|
+
"repeating it, and ask the user if unsure:\n" +
|
|
567
|
+
items
|
|
568
|
+
.map(
|
|
569
|
+
(it) =>
|
|
570
|
+
` • [${it.kind}]${it.key ? ` (${it.key})` : ""} — ${it.reason}`,
|
|
571
|
+
)
|
|
572
|
+
.join("\n");
|
|
573
|
+
return { count: items.length, items, notice };
|
|
574
|
+
} catch {
|
|
575
|
+
return null;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
|
|
530
579
|
/**
|
|
531
580
|
* Run a single turn through the core agent loop, emitting NDJSON events.
|
|
532
581
|
* Returns the turn outcome so the caller can grow history + the result line.
|
|
@@ -534,7 +583,7 @@ export async function* readJsonLines(input, opts = {}) {
|
|
|
534
583
|
async function runTurn(
|
|
535
584
|
messages,
|
|
536
585
|
loopOptions,
|
|
537
|
-
{ runLoop, emit, costBudget, nextToolUseId },
|
|
586
|
+
{ runLoop, emit, costBudget, nextToolUseId, sideEffects },
|
|
538
587
|
) {
|
|
539
588
|
const usage = {
|
|
540
589
|
input_tokens: 0,
|
|
@@ -546,6 +595,10 @@ async function runTurn(
|
|
|
546
595
|
let finalText = "";
|
|
547
596
|
let endReason = "complete";
|
|
548
597
|
let stopForCost = false;
|
|
598
|
+
// P0-2: the side-effect op currently in flight (at most one — the loop runs
|
|
599
|
+
// tools serially). Non-null only between a dangerous tool's tool-executing
|
|
600
|
+
// and its tool-result.
|
|
601
|
+
let currentSideEffectOpId = null;
|
|
549
602
|
|
|
550
603
|
// Collapse consecutive same-role turns before the model call ONLY when the
|
|
551
604
|
// caller flags a resume-degenerate transcript (`mergeRoles`): a resumed
|
|
@@ -583,10 +636,52 @@ async function runTurn(
|
|
|
583
636
|
tool: event.tool,
|
|
584
637
|
args: event.args,
|
|
585
638
|
});
|
|
639
|
+
// P0-2: record an irreversible effect as STARTED (persisted before it
|
|
640
|
+
// settles) so a crash before the matching tool-result leaves a
|
|
641
|
+
// reconcilable "in flight" marker instead of a silent replay — mirrors
|
|
642
|
+
// the single-prompt runner and the WS bridge. `sideEffects` is null
|
|
643
|
+
// when the session doesn't persist, keeping that path byte-identical.
|
|
644
|
+
currentSideEffectOpId = null;
|
|
645
|
+
if (sideEffects) {
|
|
646
|
+
const se = classifyToolSideEffect(event.tool, event.args);
|
|
647
|
+
if (se) {
|
|
648
|
+
const opId = sideEffects.nextOpId();
|
|
649
|
+
currentSideEffectOpId = opId;
|
|
650
|
+
sideEffects.ledger
|
|
651
|
+
.prepare(opId, {
|
|
652
|
+
kind: se.kind,
|
|
653
|
+
key: se.key,
|
|
654
|
+
// Content-addressed key: a resumed replay of the SAME effect
|
|
655
|
+
// derives the SAME key, so an external provider can de-dupe
|
|
656
|
+
// and countDuplicateCommittedEffects can measure `0` repeats.
|
|
657
|
+
meta: {
|
|
658
|
+
tool: event.tool,
|
|
659
|
+
idempotencyKey: operationIdempotencyKey({
|
|
660
|
+
tool: event.tool,
|
|
661
|
+
args: event.args,
|
|
662
|
+
}),
|
|
663
|
+
},
|
|
664
|
+
})
|
|
665
|
+
.start(opId);
|
|
666
|
+
sideEffects.persist();
|
|
667
|
+
}
|
|
668
|
+
}
|
|
586
669
|
break;
|
|
587
670
|
}
|
|
588
671
|
case "tool-result": {
|
|
589
672
|
const err = event.error || event.result?.error || null;
|
|
673
|
+
// P0-2: settle the in-flight side-effect (commit on success, fail on
|
|
674
|
+
// a clean error) and persist the updated ledger snapshot.
|
|
675
|
+
if (sideEffects && currentSideEffectOpId) {
|
|
676
|
+
if (err)
|
|
677
|
+
sideEffects.ledger.fail(
|
|
678
|
+
currentSideEffectOpId,
|
|
679
|
+
String(err).slice(0, 200),
|
|
680
|
+
);
|
|
681
|
+
else sideEffects.ledger.commit(currentSideEffectOpId);
|
|
682
|
+
sideEffects.persist();
|
|
683
|
+
currentSideEffectOpId = null;
|
|
684
|
+
}
|
|
590
685
|
// The loop runs tools serially, so this result settles the most
|
|
591
686
|
// recent tool_use (same adjacency rule the is_error attribution
|
|
592
687
|
// below has always used).
|
|
@@ -846,6 +941,39 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
846
941
|
// id is kept for event correlation only; nothing is written or replayed).
|
|
847
942
|
const persist = Boolean(options.sessionId) && options.ephemeral !== true;
|
|
848
943
|
|
|
944
|
+
// ── P0-2: crash-safe side-effect ledger — the stream twin of the
|
|
945
|
+
// single-prompt runner (headless-runner.js) and the WS bridge
|
|
946
|
+
// (ws-agent-handler.js). Dangerous tools (file writes, opaque shell,
|
|
947
|
+
// git push, publish/schedule/notify/browser actions) are recorded
|
|
948
|
+
// prepare→start→commit|fail with the snapshot persisted BEFORE the effect
|
|
949
|
+
// settles, so an IDE chat-panel worker killed mid-flight is surfaced for
|
|
950
|
+
// verification on resume instead of being blindly replayed. Only active when
|
|
951
|
+
// persisting (an anonymous/--ephemeral stream can't be resumed); a run that
|
|
952
|
+
// touches no dangerous tool writes nothing.
|
|
953
|
+
const loadLedger = deps.loadSideEffectLedger || loadSideEffectLedger;
|
|
954
|
+
const persistLedger = deps.persistSideEffectLedger || persistSideEffectLedger;
|
|
955
|
+
let sideEffectLedger = null;
|
|
956
|
+
if (persist) {
|
|
957
|
+
try {
|
|
958
|
+
sideEffectLedger = loadLedger(sessionId);
|
|
959
|
+
} catch {
|
|
960
|
+
// ledger is best-effort — never block the stream over it
|
|
961
|
+
sideEffectLedger = null;
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
let sideEffectSeq = 0;
|
|
965
|
+
// Run-scoped nonce keeps op ids unique even when two runs resume the same
|
|
966
|
+
// session (prepare() is idempotent on opId, so a collision would silently
|
|
967
|
+
// drop the newer record).
|
|
968
|
+
const sideEffectRunNonce = String(deps.now ? deps.now() : Date.now());
|
|
969
|
+
const sideEffects = sideEffectLedger
|
|
970
|
+
? {
|
|
971
|
+
ledger: sideEffectLedger,
|
|
972
|
+
persist: () => persistLedger(sessionId, sideEffectLedger),
|
|
973
|
+
nextOpId: () => `${sideEffectRunNonce}:${sideEffectSeq++}`,
|
|
974
|
+
}
|
|
975
|
+
: null;
|
|
976
|
+
|
|
849
977
|
// ── Interactive approvals (--interactive-approvals; chat-panel UX) ────────
|
|
850
978
|
// CONFIRM-tier decisions (risky shell via the ApprovalGate, settings/hook
|
|
851
979
|
// `ask`) normally fail closed in headless. With this opt-in they become a
|
|
@@ -1163,9 +1291,21 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
1163
1291
|
// Resume: replay the persisted conversation (fresh system prompt always
|
|
1164
1292
|
// leads; persisted system turns are dropped, mirroring runAgentHeadless).
|
|
1165
1293
|
let resumedMessages = 0;
|
|
1294
|
+
let sideEffectRecovery = null;
|
|
1166
1295
|
if (persist) {
|
|
1167
1296
|
try {
|
|
1168
1297
|
if (store.sessionExists(sessionId)) {
|
|
1298
|
+
// P0-2: reconcile the crash-safe ledger on resume (parity with
|
|
1299
|
+
// runAgentHeadless + the WS bridge). The verify-before-replay system
|
|
1300
|
+
// note goes BEFORE the replayed history — the same slot the
|
|
1301
|
+
// single-prompt runner uses — which also keeps the trailing-role
|
|
1302
|
+
// resume-degeneracy check below intact.
|
|
1303
|
+
if (sideEffectLedger) {
|
|
1304
|
+
sideEffectRecovery = buildSideEffectRecovery(sideEffectLedger);
|
|
1305
|
+
}
|
|
1306
|
+
if (sideEffectRecovery) {
|
|
1307
|
+
messages.push({ role: "system", content: sideEffectRecovery.notice });
|
|
1308
|
+
}
|
|
1169
1309
|
const history = (store.rebuildMessages(sessionId) || []).filter(
|
|
1170
1310
|
(m) => m && m.role !== "system",
|
|
1171
1311
|
);
|
|
@@ -1225,6 +1365,22 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
1225
1365
|
resumed_messages: resumedMessages,
|
|
1226
1366
|
});
|
|
1227
1367
|
|
|
1368
|
+
// P0-2 visible recovery notice: same `raw` info-line contract as
|
|
1369
|
+
// provider_fallback / version_skew (the shipped IDE panels map `raw` → an
|
|
1370
|
+
// info line), so both panels render it with zero IDE changes. Emitted right
|
|
1371
|
+
// after `init` so consumers keep seeing init as the first line; absent
|
|
1372
|
+
// entirely on a clean (or ledger-free) resume.
|
|
1373
|
+
if (sideEffectRecovery) {
|
|
1374
|
+
emit({
|
|
1375
|
+
type: "raw",
|
|
1376
|
+
subtype: "side_effect_recovery",
|
|
1377
|
+
text: `⚠️ ${sideEffectRecovery.count} interrupted side-effect(s) need verification before replay (resume ${sessionId}).`,
|
|
1378
|
+
count: sideEffectRecovery.count,
|
|
1379
|
+
items: sideEffectRecovery.items,
|
|
1380
|
+
session_id: sessionId,
|
|
1381
|
+
});
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1228
1384
|
// Goal binding (cc goal, Phase 1) — resolved once and injected on every turn.
|
|
1229
1385
|
// `--goal <id>` binds explicitly; `--goal` with no value auto-resolves.
|
|
1230
1386
|
let goalPrepareCallFn;
|
|
@@ -2010,7 +2166,7 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
2010
2166
|
// Resume-degenerate role merge for the first live model call only.
|
|
2011
2167
|
mergeRoles: mergeRolesThisTurn,
|
|
2012
2168
|
},
|
|
2013
|
-
{ runLoop, emit, costBudget, nextToolUseId },
|
|
2169
|
+
{ runLoop, emit, costBudget, nextToolUseId, sideEffects },
|
|
2014
2170
|
);
|
|
2015
2171
|
} catch (err) {
|
|
2016
2172
|
currentAbort = null;
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
writeBackgroundAgentState,
|
|
25
25
|
} from "../lib/background-agent-supervisor.js";
|
|
26
26
|
import { startBackgroundSessionServer } from "../lib/background-session-transport.js";
|
|
27
|
+
import { idlePhaseFor } from "../lib/background-agent-phase.js";
|
|
27
28
|
|
|
28
29
|
const jobFile = process.argv[2];
|
|
29
30
|
let job;
|
|
@@ -128,6 +129,11 @@ function startTurn(argv, promptText) {
|
|
|
128
129
|
// if the previous turn's child was hard-killed mid-approval (the child's
|
|
129
130
|
// phase reporter clears on settle, but SIGKILL never settles).
|
|
130
131
|
pendingApprovals: 0,
|
|
132
|
+
// The incoming prompt IS the user's reply to any parked question, and the
|
|
133
|
+
// uncertain-side-effect annotation only covers the verify turn it was
|
|
134
|
+
// raised in — both reset at the turn boundary.
|
|
135
|
+
pendingQuestion: null,
|
|
136
|
+
uncertainSideEffects: 0,
|
|
131
137
|
agentPid: child.pid,
|
|
132
138
|
// Identity anchor for the supervisor's orphan reclaim (Gap 2): pairs
|
|
133
139
|
// with agentPid the way startedAt pairs with the worker pid, so a
|
|
@@ -167,13 +173,20 @@ function maybeContinue() {
|
|
|
167
173
|
return;
|
|
168
174
|
}
|
|
169
175
|
if (server && server.clientCount() > 0) {
|
|
170
|
-
|
|
176
|
+
// Parked between turns. Normally `idle` — but a turn that parked an
|
|
177
|
+
// unanswered ask_user_question stays `needs_input` until the user's reply
|
|
178
|
+
// starts the next turn (the reply prompt clears pendingQuestion).
|
|
179
|
+
phase = idlePhaseFor(current);
|
|
171
180
|
mergeState({
|
|
172
181
|
phase,
|
|
173
|
-
// Between turns
|
|
174
|
-
// exited. Honest zero keeps a killed-mid-approval count from
|
|
175
|
-
// the session in "Needs input" forever.
|
|
182
|
+
// Between turns no APPROVAL can be pending — the approval-owning child
|
|
183
|
+
// has exited. Honest zero keeps a killed-mid-approval count from
|
|
184
|
+
// parking the session in "Needs input" forever. (A parked QUESTION is
|
|
185
|
+
// different: it awaits the user, so pendingQuestion survives idle.)
|
|
176
186
|
pendingApprovals: 0,
|
|
187
|
+
// The verify turn for any uncertain side effects has now run its
|
|
188
|
+
// course — the annotation does not outlive it.
|
|
189
|
+
uncertainSideEffects: 0,
|
|
177
190
|
agentPid: null,
|
|
178
191
|
agentStartedAt: null,
|
|
179
192
|
heartbeatAt: Date.now(),
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{I as v,P as u,J as S,U as n,R as a,S as y,K as C,Q as x,V as w,_ as B,b as s}from"./vendor-Bn1JzzAn.js";import{_ as k}from"./index-D1xIbAxQ.js";import"./icons-DG5UD-6K.js";const N={__name:"ChatBubbleRenderer",props:{event:{type:Object,required:!0}},setup(c,{expose:d}){d();const t=c,r=s(()=>{const e=t.event.content||{};return e.text||e.body||e.message||e.title||JSON.stringify(e).slice(0,200)}),i=s(()=>{const e=t.event.content||{};return e.from||e.sender||e.senderName||t.event.actor||"(unknown)"}),l=s(()=>{const e=(t.event.actor||"").toLowerCase();return e.includes("self")||e==="me"||e.endsWith("_self")}),o=s(()=>{const e=t.event.source.adapter||"";return e.startsWith("messaging-qq")?"magenta":e==="wechat"?"green":"blue"}),m=s(()=>{if(!t.event.occurredAt)return"";try{const e=new Date(t.event.occurredAt),p=e.getFullYear(),b=String(e.getMonth()+1).padStart(2,"0"),f=String(e.getDate()).padStart(2,"0"),g=String(e.getHours()).padStart(2,"0"),h=String(e.getMinutes()).padStart(2,"0");return`${p}-${b}-${f} ${g}:${h}`}catch{return""}}),_={props:t,messageText:r,actorLabel:i,isMine:l,adapterColor:o,formattedTime:m,computed:s};return Object.defineProperty(_,"__isScriptSetup",{enumerable:!1,value:!0}),_}},T={class:"bubble"},M={class:"meta"},O={class:"actor"},R={class:"time"},V={class:"body"};function q(c,d,t,r,i,l){const o=v("a-tag");return u(),S("div",{class:B(["chat-row",{mine:r.isMine}])},[n("div",T,[n("div",M,[n("span",O,a(r.actorLabel),1),n("span",R,a(r.formattedTime),1)]),n("div",V,a(r.messageText),1),t.event.source.adapter?(u(),y(o,{key:0,class:"src",color:r.adapterColor},{default:C(()=>[x(a(t.event.source.adapter),1)]),_:1},8,["color"])):w("v-if",!0)])],2)}const A=k(N,[["render",q],["__scopeId","data-v-49238629"],["__file","/tmp/cc-web-panel-tGOYbB/repo/packages/web-panel/src/components/pdh/renderers/ChatBubbleRenderer.vue"]]);export{A as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{I as n,J as g,c as l,K as r,N as u,P as h,U as o,R as t,Q as b}from"./vendor-Bn1JzzAn.js";import{_ as v,b as m}from"./index-D1xIbAxQ.js";import{a8 as y,M as B}from"./icons-DG5UD-6K.js";const M={__name:"MobileProjects",setup(p,{expose:i}){i();const c=u(),{t:e}=m();function a(){c.push("/projects")}function _(){c.push("/mobile-bridge")}const s={router:c,t:e,goToProjects:a,goToMobileBridge:_,get useRouter(){return u},get useI18n(){return m},get MobileOutlined(){return B},get FolderOutlined(){return y}};return Object.defineProperty(s,"__isScriptSetup",{enumerable:!1,value:!0}),s}},O={class:"mobile-projects-placeholder"},x={class:"title"},k={class:"subtitle"},w={class:"explainer"};function T(p,i,c,e,a,_){const s=n("a-alert"),d=n("a-button"),f=n("a-space"),P=n("a-empty"),j=n("a-card");return h(),g("div",O,[l(j,null,{default:r(()=>[l(P,{description:!1},{image:r(()=>[l(e.MobileOutlined,{style:{fontSize:"64px",color:"#bfbfbf"}})]),default:r(()=>[o("h2",x,t(e.t("mobileProjects.title")),1),o("p",k,t(e.t("mobileProjects.subtitle")),1),l(s,{message:e.t("mobileProjects.v02Banner"),type:"info","show-icon":"",class:"banner"},null,8,["message"]),o("div",w,[o("h3",null,t(e.t("mobileProjects.currentDirection")),1),o("p",null,t(e.t("mobileProjects.currentDirectionBody")),1),o("ul",null,[o("li",null,t(e.t("mobileProjects.stepPhone")),1),o("li",null,t(e.t("mobileProjects.stepTap")),1),o("li",null,t(e.t("mobileProjects.stepPull")),1)]),o("h3",null,t(e.t("mobileProjects.reverseDirection")),1),o("p",null,t(e.t("mobileProjects.reverseDirectionBody")),1)]),l(f,{class:"actions"},{default:r(()=>[l(d,{type:"primary",onClick:e.goToProjects},{default:r(()=>[l(e.FolderOutlined),b(" "+t(e.t("mobileProjects.viewLocalProjects")),1)]),_:1}),l(d,{onClick:e.goToMobileBridge},{default:r(()=>[l(e.MobileOutlined),b(" "+t(e.t("mobileProjects.checkBridge")),1)]),_:1})]),_:1})]),_:1})]),_:1})])}const N=v(M,[["render",T],["__scopeId","data-v-9262cc45"],["__file","/tmp/cc-web-panel-tGOYbB/repo/packages/web-panel/src/views/MobileProjects.vue"]]);export{N as default};
|
|
@@ -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-D1xIbAxQ.js";import{I as z,J as x,U as _,Q as B,S as J,K as T,V as R,c as A,F as K,Z as Q,R as E,o as Z,f as H,w as $,n as D,b as ee,r as S,P as y,_ as ve,a2 as we,a3 as he,a4 as _e}from"./vendor-Bn1JzzAn.js";import{R as ye,b as pe,at as ge}from"./icons-DG5UD-6K.js";const k=new Map,C=new Map,N=new Set,F=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)),N.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)),F.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)}):(N.add(a),()=>N.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)}):(F.add(a),()=>F.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 I(){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 q(t){await D();const{xtermMod:l,fitAddonMod:p}=await I(),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 G of v)m.write(G.data),t.lastSeq=G.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 q(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,D(()=>{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 q(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}}Z(async()=>{await X()}),H(()=>{for(const t of e.value){try{t.offs?.()}catch{}try{t.xterm?.dispose?.()}catch{}}}),$(i,()=>{D(()=>{const t=h.value;try{t?.fitAddon?.fit()}catch{}})});const Y={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:I,mountXterm:q,onCreate:re,onClose:se,removeSession:W,activate:le,refreshList:X,ref:S,computed:ee,onMounted:Z,onBeforeUnmount:H,nextTick:D,watch:$,get message(){return V},get PlusOutlined(){return ge},get CloseOutlined(){return pe},get ReloadOutlined(){return ye},get useTerminal(){return oe}};return Object.defineProperty(Y,"__isScriptSetup",{enumerable:!1,value:!0}),Y}},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"},Be={key:1,class:"terminal-footer"},De={key:0,class:"footer-exit"};function qe(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]=B(" 桌面端托管的 PTY 会话;Android 端可远程操控同一通道 ",-1)),e.warning?(y(),J(u,{key:0,color:"orange",style:{"margin-left":"8px"}},{default:T(()=>[B(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]=B(" 新会话 ",-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]=B(" 刷新 ",-1))]),_:1},8,["loading"])]),_:1})]),e.error?(y(),J(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(K,null,Q(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(K,null,Q(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",Be,[_("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",De,"已退出 (code="+E(e.active.exitCode??"-")+")",1))])):R("v-if",!0)])}const Fe=me(Se,[["render",qe],["__scopeId","data-v-65366a29"],["__file","/tmp/cc-web-panel-tGOYbB/repo/packages/web-panel/src/views/Terminal.vue"]]);export{Fe as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{Q as r}from"./index-D1xIbAxQ.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-stTnDJ9y.js";import{a0 as t}from"./index-D1xIbAxQ.js";import"./vendor-Bn1JzzAn.js";import"./responsiveObserve-DUafj9pU.js";import"./useFlexGapSupport-ChecYwC8.js";import"./styleChecker-qO5aCjyk.js";import"./index-DhZgULsY.js";import"./icons-DG5UD-6K.js";const l=t(o);export{l as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{C as o}from"./Col-1GP8MvKL.js";import{a0 as t}from"./index-D1xIbAxQ.js";import"./vendor-Bn1JzzAn.js";import"./index-DhZgULsY.js";import"./icons-DG5UD-6K.js";const s=t(o);export{s as default};
|