chainlesschain 0.162.169 → 0.162.171
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-DCeNRK8z.js → AIOps-Cf8yb18C.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-ZfD0HgVe.js → ActionButton-CsFT6FMt.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-Ccn40f9E.js → Analytics-DQe_hXMA.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-DyXs4nSt.js → AppLayout-Cl9Pp7jk.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-CYjMh5KR.js → Artifacts-CBEzLVjF.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-DZIhvx88.js → Audit-BS2Un14C.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-C1XJsa2d.js → BackgroundAgents-DmcDH8OK.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-CMXC0oUN.js → Backup-DvzjTkkn.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-CRVmIH1t.js → BaseInput-DnbpuyME.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-acBud5Yj.js → Chat-BJRRCm2P.js} +6 -6
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-CTjqFhdD.js → ChatBubbleRenderer-Bgpxyqd_.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-CZem825o.js → Checkbox-DFOrWmvm.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-B9UjZsww.js → Codegen-BIQ2kU6Q.js} +1 -1
- package/src/assets/web-panel/assets/{Col-Dtu6Frtj.js → Col-BI3R-N4I.js} +1 -1
- package/src/assets/web-panel/assets/{Community-9bV55Huv.js → Community-CPiAwsHT.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-g-kQ4c84.js → Compact-Bv4cslSK.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-CQjHzBO1.js → Compliance-CSlDG1NZ.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-D1Qm_Xhi.js → Cowork-CFcRumXf.js} +4 -4
- package/src/assets/web-panel/assets/{Cron-992qo8zX.js → Cron-DKYKMmOn.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-4TiqEwuc.js → Crosschain-CxPMByp2.js} +1 -1
- package/src/assets/web-panel/assets/{DID-BbsXzXCb.js → DID-DJqiYw1C.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-Dx5aO9d3.js → Dashboard-D2dLMxqy.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-BhzW6i6i.js → Dropdown-BnJc384A.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-qEib4yiq.js → EmailListRenderer-DctFvm-J.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-BZ3N-u3h.js → FamilyGuardDashboard-J_xg-Qop.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-CcOqwzHY.js → Federation-BckL07Uw.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-dbi8mohd.js → FormItemContext-B8s5ccSO.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-57dqulUe.js → GenericCardRenderer-hPMBK2No.js} +1 -1
- package/src/assets/web-panel/assets/{Git-DtSV7C5g.js → Git-CfMpYLo7.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-CLnmH-RD.js → Governance-Bt3OcrC7.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-wXiLeDnk.js → Inference-BlKc336N.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-NGdIX2Gx.js → KnowledgeGraph-B6p7og2c.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-Dz0HQn69.js → Logs-uv5Re6YR.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-CId5JWjX.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-DpPDmY3W.js → Marketplace-CfNbntHt.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-UMysoRQm.js → McpTools-YRXt74Yk.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-DsnBpQnY.js → Memory-BfQQs-Jd.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-DweooAfG.js → MobileBridge-BuGC-4S2.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-UdLfZOVA.js → MobileProjects-Czieqw1m.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-oXWhJNgC.js → Mtc-DHWHOVCO.js} +5 -5
- package/src/assets/web-panel/assets/{MtcAudit-CXTD7qrm.js → MtcAudit-DWSEbMW-.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-BKt5mJ9O.js → Multisig-DrhEv1vq.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-C-zcYzje.js → NLProgramming-D8wKCu7E.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-CGaZ_jep.js → Notes-AFeqq0I_.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-BwX-tDbq.js → NotificationSettings-D6qenYUo.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-Cc9Se8H-.js → OrderTableRenderer-CF0X4fyB.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-8BXdC7Im.js → Organization-DdfbNqf6.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-zCisFuGU.js → Overflow-BFEvnLfd.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-BehHH9Ro.js → P2P-DtL6wbkz.js} +2 -2
- package/src/assets/web-panel/assets/PdhVaultBrowser-CQPriTud.js +7 -0
- package/src/assets/web-panel/assets/{Permissions-BVDATm3p.js → Permissions-Bj25ANmR.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-C43nnYoi.js → PersonalDataHub-BNj2Oux0.js} +3 -3
- package/src/assets/web-panel/assets/{Pipeline-D9E7aSVD.js → Pipeline-Dyj8UEaG.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-CRbIchdL.js → Privacy-BBUrWRFz.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-CTsy8lhL.js → ProjectInit-BdX7uQn6.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-CPEKWWJ5.js → ProjectSettings-BghtW1zr.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-CNnW0v5N.js → Projects-9VTquZCz.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-BeZnDL9Y.js → Providers-D-0K_Eza.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-CaydwuIU.js → QrScannerModal-DDaN30_D.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-qYWbu7kw.js → QuickAsk-DfHlifOj.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-RV_ogHrM.js → Recommend-CgLIvYE2.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-Mah1i41_.js → RemoteSession-DpOPrwE4.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-xZQhGktc.js → Reputation-wMexlbCE.js} +1 -1
- package/src/assets/web-panel/assets/{Row-B6cVbPbJ.js → Row-D9aD_nrc.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-C6hKjDPz.js → RssFeed-Drg7l6zu.js} +3 -3
- package/src/assets/web-panel/assets/{Search-0jti_-Pe.js → Search-BKO1nrwN.js} +1 -1
- package/src/assets/web-panel/assets/{Security-Cy48feGz.js → Security-G3Kyk-TG.js} +3 -3
- package/src/assets/web-panel/assets/{Services-BW3ObFxH.js → Services-xJReTOna.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-CfrZRvAM.js → Skeleton-ldVDVTPG.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-yoccdk3t.js → Skills-emwNYV0j.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-AKBBdri6.js → Sla-CZYwGp1K.js} +1 -1
- package/src/assets/web-panel/assets/SpeechSettings-CyaPrzOF.js +1 -0
- package/src/assets/web-panel/assets/{SyncSettings-DUuO-ZSw.js → SyncSettings-Dcs5Hhj6.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-ZTUfOzMZ.js → Tasks-CerFAo26.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-shPrQ4NE.js → Templates-BdZUbOg3.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-C_inPunR.js → Tenant-B4c_7Bsw.js} +1 -1
- package/src/assets/web-panel/assets/Terminal-VVFLS3Ol.js +3 -0
- package/src/assets/web-panel/assets/{TimelineRenderer-Bzp_T3Xc.js → TimelineRenderer-tc6sp0TV.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-kUFRLdtp.js → Tokens-Bw_vkMJq.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-BsTU2blQ.js → Trigger-DkbJnpvz.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-DEKkuAsi.js → Trust-CIf9kqN1.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-D1KEEgbK.js → UkeySign-Cjwllnea.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-C2yYkm9W.js → VideoEditing-kgfkY7AN.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-BKKod4qb.js → Wallet-CYWXt4u9.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-XXUgED6d.js → WebAuthn-QgPwyWCO.js} +3 -3
- package/src/assets/web-panel/assets/{WorkflowEditor-DnlEyYTi.js → WorkflowEditor-Co0lha18.js} +1 -1
- package/src/assets/web-panel/assets/{chat-BaVjI6nu.js → chat-CI__Ox-r.js} +1 -1
- package/src/assets/web-panel/assets/{colors-DQ0yx43H.js → colors-Csv0eYYd.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-DEyWDp0v.js → compact-item-e53UCdHy.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-SuPOfylZ.js → createContext-BMPGRDhV.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-BIulobq7.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-CQz1JNtC.js → hasIn-Dz68qIAq.js} +1 -1
- package/src/assets/web-panel/assets/{index-BJEIjYhV.js → index--7tHEadk.js} +1 -1
- package/src/assets/web-panel/assets/{index-BIgWgye3.js → index-53ljQo_x.js} +1 -1
- package/src/assets/web-panel/assets/{index-C_fcNCoV.js → index-5iicv5af.js} +1 -1
- package/src/assets/web-panel/assets/{index-BffmUosH.js → index-B1s1B8Iy.js} +1 -1
- package/src/assets/web-panel/assets/{index-CgvnudM_.js → index-B4lKPJy1.js} +1 -1
- package/src/assets/web-panel/assets/index-BGkiYnET.js +1 -0
- package/src/assets/web-panel/assets/{index-COsmMpAO.js → index-BHkDRNA5.js} +1 -1
- package/src/assets/web-panel/assets/{index-57GdL9ro.js → index-BOpz2qS1.js} +1 -1
- package/src/assets/web-panel/assets/{index-DjZ6szGM.js → index-BT3CV4Nh.js} +1 -1
- package/src/assets/web-panel/assets/{index-DpPv8zeU.js → index-BW2dImbg.js} +1 -1
- package/src/assets/web-panel/assets/{index-CpR6M7eQ.js → index-C-NbcAbP.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dfh6OJKz.js → index-C53o-MdJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-CfVW-cd_.js → index-C5hLtxVz.js} +1 -1
- package/src/assets/web-panel/assets/{index-ByGF9ev7.js → index-CNtZMPKV.js} +1 -1
- package/src/assets/web-panel/assets/{index-ZKOZ-YFJ.js → index-CXuON9OG.js} +1 -1
- package/src/assets/web-panel/assets/{index-CGu-b0RE.js → index-CYUxs6J1.js} +1 -1
- package/src/assets/web-panel/assets/{index-3xcB2i6I.js → index-CoGSbW5J.js} +1 -1
- package/src/assets/web-panel/assets/{index-DB8AJ6T-.js → index-CpTzqJ0Z.js} +1 -1
- package/src/assets/web-panel/assets/{index-XjQfQBXH.js → index-CrsoSnQF.js} +1 -1
- package/src/assets/web-panel/assets/{index-CZrARoXd.js → index-CvLBQk_M.js} +1 -1
- package/src/assets/web-panel/assets/{index-DWIuZ9bI.js → index-CyLUaP2i.js} +1 -1
- package/src/assets/web-panel/assets/{index-CEfLMvKf.js → index-D0bg74e1.js} +1 -1
- package/src/assets/web-panel/assets/{index-ZMgCYtI7.js → index-DCl4Xb4N.js} +1 -1
- package/src/assets/web-panel/assets/{index-DXczrVij.js → index-DJqQL6so.js} +1 -1
- package/src/assets/web-panel/assets/{index-fGgx2f1y.js → index-DVCd2aMX.js} +1 -1
- package/src/assets/web-panel/assets/{index-BHJhyrFr.js → index-DctYrVMq.js} +1 -1
- package/src/assets/web-panel/assets/{index-v8PYYw05.js → index-Dk9Gi8xd.js} +1 -1
- package/src/assets/web-panel/assets/{index-fcA6tfBA.js → index-DnXm3Qsh.js} +1 -1
- package/src/assets/web-panel/assets/{index-C3Vlo45C.js → index-Dtjm1K1a.js} +1 -1
- package/src/assets/web-panel/assets/{index-wBsuJZcz.js → index-DyqcHiL1.js} +1 -1
- package/src/assets/web-panel/assets/index-Eyhrr_3u.js +1 -0
- package/src/assets/web-panel/assets/{index-CnhJU5To.js → index-HbhQRrM2.js} +1 -1
- package/src/assets/web-panel/assets/{index-D5SY6Lwu.js → index-K5E_wjut.js} +1 -1
- package/src/assets/web-panel/assets/{index-DhBeUGCp.js → index-N9DkR1i7.js} +1 -1
- package/src/assets/web-panel/assets/{index-CI5jlfyn.js → index-_LmPlyeV.js} +1 -1
- package/src/assets/web-panel/assets/{index-DNYVGZzG.js → index-ajz0E0pK.js} +1 -1
- package/src/assets/web-panel/assets/{index-C2k8eHyq.js → index-t6f80uqL.js} +17 -17
- package/src/assets/web-panel/assets/{index-C-IKjQD3.js → index-wcCouSNq.js} +1 -1
- package/src/assets/web-panel/assets/{index-D-gXgEsU.js → index-ygfUVVFv.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-KetDXPXx.js → initDefaultProps-DVCeQJrT.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BfAtwo2m.js → motion-chBCR_8v.js} +1 -1
- package/src/assets/web-panel/assets/{move-BnJvzHgx.js → move-BziPlrh6.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-DZxDclhM.js → mtc-parser-Cenk0OD7.js} +1 -1
- package/src/assets/web-panel/assets/{omit-CmqfX2P_.js → omit-D-AiRsei.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-B2B2ahzC.js → pickAttrs-CHw3Fvqt.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-C1SIgWRj.js → placementArrow-g8I-rCad.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-Dy_adDTl.js → responsiveObserve-BWffAr9k.js} +1 -1
- package/src/assets/web-panel/assets/{slide-hDO9sBPk.js → slide-BmUQqhkb.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-DlpTjRpg.js → statusUtils-B89gCO-y.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-DAv9eo6h.js → styleChecker-x1bnCF73.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-vfoXaeH8.js → useFlexGapSupport-B-k1_Ggw.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-Dzji-S7v.js → useFs-Bc3PUqQk.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-jKcLN_Gj.js → usePersonalDataHub-D8qFDX1I.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-DAWM5GgY.js → vnode-UaL5-WGg.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-q3XgSOUd.js → zoom-Dv7bsbLs.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/agent.js +39 -14
- package/src/commands/background-session.js +12 -1
- package/src/data/changelog.json +7 -2
- package/src/gateways/ws/ws-agent-handler.js +26 -1
- package/src/gateways/ws/ws-approval-gate.js +131 -0
- package/src/lib/agent-worktree.js +173 -5
- package/src/lib/background-agent-supervisor.js +234 -14
- package/src/lib/interaction-adapter.js +26 -5
- package/src/lib/packer/smoke-runner.js +5 -0
- package/src/lib/repl-rewind.js +62 -14
- package/src/lib/turn-binding.js +134 -0
- package/src/repl/agent-repl.js +75 -3
- package/src/repl/repl-turn-binding.js +91 -0
- package/src/runtime/headless-runner.js +59 -0
- package/src/assets/web-panel/assets/MarkdownRenderer-CSRZ9da3.js +0 -1
- package/src/assets/web-panel/assets/PdhVaultBrowser-DVuXYKAR.js +0 -7
- package/src/assets/web-panel/assets/SpeechSettings-DH87GbkH.js +0 -1
- package/src/assets/web-panel/assets/Terminal-CvVtx6ie.js +0 -3
- package/src/assets/web-panel/assets/devWarning-C_RK48j-.js +0 -1
- package/src/assets/web-panel/assets/index-CDqhisfz.js +0 -1
- package/src/assets/web-panel/assets/index-CKUoX6Yi.js +0 -1
package/src/lib/turn-binding.js
CHANGED
|
@@ -183,6 +183,35 @@ export class TurnBindingLog {
|
|
|
183
183
|
return this;
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
+
/**
|
|
187
|
+
* Drop every turn anchored AT or AFTER `offset` — the timeline-supersede rule
|
|
188
|
+
* for a live producer. After a `/rewind`, `/clear`, or compaction shrinks the
|
|
189
|
+
* live conversation, a new turn re-anchors at an offset an OLD record may
|
|
190
|
+
* still hold; under exact-offset matching (see `pickPersistedTurn`) that stale
|
|
191
|
+
* record would shadow the new one and could offer the wrong checkpoint. The
|
|
192
|
+
* discarded-timeline records are pruned instead — correctness over advisory
|
|
193
|
+
* completeness.
|
|
194
|
+
*
|
|
195
|
+
* @param {number} offset conversation offset the new timeline starts at
|
|
196
|
+
* @returns {number} how many records were removed
|
|
197
|
+
*/
|
|
198
|
+
pruneFromOffset(offset) {
|
|
199
|
+
const at = Number(offset);
|
|
200
|
+
if (!Number.isFinite(at)) return 0;
|
|
201
|
+
let removed = 0;
|
|
202
|
+
this._order = this._order.filter((id) => {
|
|
203
|
+
const rec = this._turns.get(id);
|
|
204
|
+
const off = rec ? Number(rec.conversationOffset) : NaN;
|
|
205
|
+
if (Number.isFinite(off) && off >= at) {
|
|
206
|
+
this._turns.delete(id);
|
|
207
|
+
removed += 1;
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
return true;
|
|
211
|
+
});
|
|
212
|
+
return removed;
|
|
213
|
+
}
|
|
214
|
+
|
|
186
215
|
/** One turn record with its computed coverage (or null). */
|
|
187
216
|
get(turnId) {
|
|
188
217
|
const rec = this._turns.get(String(turnId));
|
|
@@ -395,3 +424,108 @@ export function buildTurnBindingFromMarks(turns = [], marks = []) {
|
|
|
395
424
|
}
|
|
396
425
|
return log;
|
|
397
426
|
}
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Stateful feeder turning raw agent-loop events into TurnBindingLog records —
|
|
430
|
+
* the SHARED producer core for every runner (headless and the interactive
|
|
431
|
+
* REPL), so id synthesis and the event→table mapping can never drift between
|
|
432
|
+
* them. Provider tool_use ids are not visible on the yielded event stream, so
|
|
433
|
+
* tool-call ids are synthesized `<nonce>:c<seq>` and turn ids `<nonce>:t<seq>`
|
|
434
|
+
* (mirrors the side-effect ledger's op-id scheme — stable within a run, unique
|
|
435
|
+
* across resumes as long as `nonce` is per-run unique).
|
|
436
|
+
*
|
|
437
|
+
* Dirty-gating: `beginTurn` alone never marks the table dirty, so a tool-free
|
|
438
|
+
* turn costs the caller zero persistence writes; only a recorded signal
|
|
439
|
+
* (checkpoint / tool call / permission decision / child agent / a supersede
|
|
440
|
+
* prune) does.
|
|
441
|
+
*
|
|
442
|
+
* @param {{log?: TurnBindingLog, nonce?: string}} [opts]
|
|
443
|
+
*/
|
|
444
|
+
export function createTurnBindingFeed({
|
|
445
|
+
log = new TurnBindingLog(),
|
|
446
|
+
nonce = "run",
|
|
447
|
+
} = {}) {
|
|
448
|
+
let turnSeq = 0;
|
|
449
|
+
let callSeq = 0;
|
|
450
|
+
let currentTurnId = null;
|
|
451
|
+
let currentCallId = null;
|
|
452
|
+
let dirty = false;
|
|
453
|
+
return {
|
|
454
|
+
log,
|
|
455
|
+
/**
|
|
456
|
+
* Anchor a new turn at `conversationOffset` (= messages.length measured
|
|
457
|
+
* just AFTER the turn's user message was appended — the exact-match
|
|
458
|
+
* contract `pickPersistedTurn` relies on). `supersede: true` first prunes
|
|
459
|
+
* records at/after that offset (live-REPL rewind/clear/compaction rule);
|
|
460
|
+
* append-only runners leave it off. `worktreeId` stamps the run's isolation
|
|
461
|
+
* worktree onto the record (does NOT mark dirty by itself — a tool-free
|
|
462
|
+
* turn in a worktree still writes nothing).
|
|
463
|
+
*/
|
|
464
|
+
beginTurn(
|
|
465
|
+
conversationOffset,
|
|
466
|
+
{ supersede = false, worktreeId = null } = {},
|
|
467
|
+
) {
|
|
468
|
+
if (supersede && log.pruneFromOffset(conversationOffset) > 0) {
|
|
469
|
+
dirty = true;
|
|
470
|
+
}
|
|
471
|
+
currentTurnId = `${nonce}:t${turnSeq++}`;
|
|
472
|
+
log.startTurn(currentTurnId, { conversationOffset });
|
|
473
|
+
if (worktreeId != null) log.setWorktree(currentTurnId, worktreeId);
|
|
474
|
+
return currentTurnId;
|
|
475
|
+
},
|
|
476
|
+
currentTurnId: () => currentTurnId,
|
|
477
|
+
/** Fold one agent-loop event into the current turn's record. */
|
|
478
|
+
handleEvent(event) {
|
|
479
|
+
if (!event || !currentTurnId) return dirty;
|
|
480
|
+
const turnId = currentTurnId;
|
|
481
|
+
switch (event.type) {
|
|
482
|
+
case "checkpoint":
|
|
483
|
+
if (event.id != null) {
|
|
484
|
+
log.bindCheckpoint(turnId, event.id);
|
|
485
|
+
dirty = true;
|
|
486
|
+
}
|
|
487
|
+
break;
|
|
488
|
+
case "tool-executing": {
|
|
489
|
+
const callId = `${nonce}:c${callSeq++}`;
|
|
490
|
+
currentCallId = callId;
|
|
491
|
+
log.recordToolCall(turnId, callId, { name: event.tool });
|
|
492
|
+
dirty = true;
|
|
493
|
+
break;
|
|
494
|
+
}
|
|
495
|
+
case "tool-result": {
|
|
496
|
+
// A gated tool surfaces its permission decision on `result.policy`;
|
|
497
|
+
// re-derive a stable decision id feeder-side (core's own id hangs
|
|
498
|
+
// off the provider call id, which the event stream does not expose).
|
|
499
|
+
const policy = event.result?.policy;
|
|
500
|
+
if (policy && (policy.via || policy.decision)) {
|
|
501
|
+
log.recordPermissionDecision(
|
|
502
|
+
turnId,
|
|
503
|
+
`${currentCallId || "call"}:perm:${policy.via || policy.decision}`,
|
|
504
|
+
);
|
|
505
|
+
dirty = true;
|
|
506
|
+
}
|
|
507
|
+
// Foreground spawn_sub_agent reports its child id on the result.
|
|
508
|
+
if (event.result?.subAgentId) {
|
|
509
|
+
log.recordChildAgent(turnId, event.result.subAgentId);
|
|
510
|
+
dirty = true;
|
|
511
|
+
}
|
|
512
|
+
currentCallId = null;
|
|
513
|
+
break;
|
|
514
|
+
}
|
|
515
|
+
case "background-sub-agent-result":
|
|
516
|
+
if (event.subAgentId) {
|
|
517
|
+
log.recordChildAgent(turnId, event.subAgentId);
|
|
518
|
+
dirty = true;
|
|
519
|
+
}
|
|
520
|
+
break;
|
|
521
|
+
default:
|
|
522
|
+
break;
|
|
523
|
+
}
|
|
524
|
+
return dirty;
|
|
525
|
+
},
|
|
526
|
+
isDirty: () => dirty,
|
|
527
|
+
clearDirty() {
|
|
528
|
+
dirty = false;
|
|
529
|
+
},
|
|
530
|
+
};
|
|
531
|
+
}
|
package/src/repl/agent-repl.js
CHANGED
|
@@ -295,6 +295,17 @@ export async function agentLoop(messages, options) {
|
|
|
295
295
|
autoCompact: false,
|
|
296
296
|
onProviderFallback,
|
|
297
297
|
})) {
|
|
298
|
+
// P1 explicit turn→checkpoint binding — the REPL as PRODUCER: fold every
|
|
299
|
+
// loop event into the live table (checkpoint / tool / policy / child
|
|
300
|
+
// agent), mirroring the headless runner's feed. Advisory: a feeder failure
|
|
301
|
+
// must never disturb the turn. Absent by default → byte-identical.
|
|
302
|
+
if (options.turnBindingFeed) {
|
|
303
|
+
try {
|
|
304
|
+
options.turnBindingFeed.handleEvent(event);
|
|
305
|
+
} catch {
|
|
306
|
+
/* advisory — never break the turn */
|
|
307
|
+
}
|
|
308
|
+
}
|
|
298
309
|
if (event.type === "checkpoint") {
|
|
299
310
|
// Remember which file snapshot lines up with the live conversation so
|
|
300
311
|
// `/rewind <n>` can restore code + conversation together (Claude-Code
|
|
@@ -1078,6 +1089,11 @@ export async function startAgentRepl(options = {}) {
|
|
|
1078
1089
|
// it back (Claude-Code 2.1.191). Nulled on a context swap so a stash from one
|
|
1079
1090
|
// session can't be restored into another. { messages, marks } | null.
|
|
1080
1091
|
let _clearedConversation = null;
|
|
1092
|
+
// P1 explicit turn→checkpoint binding — the REPL as PRODUCER (mirrors the
|
|
1093
|
+
// headless runner's feed via the shared feeder core): one record per
|
|
1094
|
+
// interactive turn, persisted dirty-gated at each settle. Lazily created on
|
|
1095
|
+
// the first prompt turn of a persistable (JSONL) session; advisory only.
|
|
1096
|
+
let _turnBindingProducer = null;
|
|
1081
1097
|
// Apply --output-style or the settings.json `outputStyle` default at startup.
|
|
1082
1098
|
try {
|
|
1083
1099
|
const { resolveOutputStyle } = await import("../lib/output-styles.js");
|
|
@@ -3120,6 +3136,7 @@ export async function startAgentRepl(options = {}) {
|
|
|
3120
3136
|
buildBranchPlan,
|
|
3121
3137
|
renderBranchPlan,
|
|
3122
3138
|
parseRewindArg,
|
|
3139
|
+
pickPersistedTurn,
|
|
3123
3140
|
RESTORE_SCOPE,
|
|
3124
3141
|
} = await import("../lib/repl-rewind.js");
|
|
3125
3142
|
const arg = trimmed.slice("/rewind".length).trim();
|
|
@@ -3127,6 +3144,24 @@ export async function startAgentRepl(options = {}) {
|
|
|
3127
3144
|
// --files / --both). Claude-Code parity: a rewind can restore the
|
|
3128
3145
|
// conversation only, the files only, or both.
|
|
3129
3146
|
const parsed = parseRewindArg(arg);
|
|
3147
|
+
// P1 turn/checkpoint binding: load the session's PERSISTED explicit
|
|
3148
|
+
// turn-binding table (headless runs of this session feed it). A
|
|
3149
|
+
// --resume'd session's pre-resume turns have no process-local marks —
|
|
3150
|
+
// the explicit table is the only source of their checkpoint ids and
|
|
3151
|
+
// side-effect coverage. Best-effort advisory: never blocks /rewind.
|
|
3152
|
+
let _persistedBinding = null;
|
|
3153
|
+
if (
|
|
3154
|
+
sessionId &&
|
|
3155
|
+
(parsed.command === "turn" || parsed.command === "branch")
|
|
3156
|
+
) {
|
|
3157
|
+
try {
|
|
3158
|
+
const { loadTurnBindingLog } =
|
|
3159
|
+
await import("../lib/turn-binding-store.js");
|
|
3160
|
+
_persistedBinding = loadTurnBindingLog(sessionId);
|
|
3161
|
+
} catch {
|
|
3162
|
+
/* marks-only fallback */
|
|
3163
|
+
}
|
|
3164
|
+
}
|
|
3130
3165
|
if (parsed.command === "clear") {
|
|
3131
3166
|
// Restore the conversation stashed by /clear (Claude-Code 2.1.191).
|
|
3132
3167
|
const r = restoreClearedConversation(
|
|
@@ -3173,6 +3208,7 @@ export async function startAgentRepl(options = {}) {
|
|
|
3173
3208
|
{
|
|
3174
3209
|
parentSessionId: sessionId,
|
|
3175
3210
|
writeIntent: parsed.writeIntent,
|
|
3211
|
+
persistedLog: _persistedBinding,
|
|
3176
3212
|
},
|
|
3177
3213
|
);
|
|
3178
3214
|
if (!plan || !plan.branchSessionId) {
|
|
@@ -3277,6 +3313,7 @@ export async function startAgentRepl(options = {}) {
|
|
|
3277
3313
|
_checkpointMarks,
|
|
3278
3314
|
turnIndex,
|
|
3279
3315
|
scope,
|
|
3316
|
+
{ persistedLog: _persistedBinding },
|
|
3280
3317
|
);
|
|
3281
3318
|
for (const line of renderRewindWarnings(plan))
|
|
3282
3319
|
logger.log(chalk.yellow(line));
|
|
@@ -3286,11 +3323,21 @@ export async function startAgentRepl(options = {}) {
|
|
|
3286
3323
|
// 3) File restore (skipped for conversation-only). Match the turn to
|
|
3287
3324
|
// the snapshot taken just before it first mutated the tree, then
|
|
3288
3325
|
// offer to roll the working tree back to it (undoable — the restore
|
|
3289
|
-
// takes its own safety checkpoint first).
|
|
3290
|
-
//
|
|
3291
|
-
|
|
3326
|
+
// takes its own safety checkpoint first). Process-local marks win;
|
|
3327
|
+
// a --resume'd turn with no marks falls back to the checkpoint id
|
|
3328
|
+
// the PERSISTED binding table recorded for it (same checkpoint
|
|
3329
|
+
// store, so cross-process file rewind actually works — restore
|
|
3330
|
+
// still fails soft if the snapshot is gone). Prune dropped-turn
|
|
3331
|
+
// marks only when the conversation was actually truncated.
|
|
3332
|
+
let cp = restoreFiles
|
|
3292
3333
|
? pickCheckpointForTurn(_checkpointMarks, turnIndex)
|
|
3293
3334
|
: null;
|
|
3335
|
+
if (!cp && restoreFiles) {
|
|
3336
|
+
const persisted = pickPersistedTurn(_persistedBinding, turnIndex);
|
|
3337
|
+
if (persisted?.fileCheckpointId) {
|
|
3338
|
+
cp = { id: persisted.fileCheckpointId, fromPersisted: true };
|
|
3339
|
+
}
|
|
3340
|
+
}
|
|
3294
3341
|
if (rewindConversation)
|
|
3295
3342
|
pruneMarksAfter(_checkpointMarks, turnIndex);
|
|
3296
3343
|
if (cp) {
|
|
@@ -5159,6 +5206,25 @@ export async function startAgentRepl(options = {}) {
|
|
|
5159
5206
|
const _userMsg = { role: "user", content: _userMessageContent };
|
|
5160
5207
|
messages.push(_userMsg);
|
|
5161
5208
|
|
|
5209
|
+
// P1 turn→checkpoint binding: anchor this turn in the explicit table at
|
|
5210
|
+
// `conversationOffset = messages.length` measured just AFTER the user
|
|
5211
|
+
// message was appended (the exact-match contract pickPersistedTurn relies
|
|
5212
|
+
// on — same anchor as the headless runner). Only JSONL sessions can
|
|
5213
|
+
// persist the table; the producer supersedes stale records from a
|
|
5214
|
+
// discarded timeline (post-/rewind, /clear, compaction) itself.
|
|
5215
|
+
if (sessionId && useJsonl) {
|
|
5216
|
+
try {
|
|
5217
|
+
if (!_turnBindingProducer) {
|
|
5218
|
+
const { createReplTurnBindingProducer } =
|
|
5219
|
+
await import("./repl-turn-binding.js");
|
|
5220
|
+
_turnBindingProducer = createReplTurnBindingProducer({ sessionId });
|
|
5221
|
+
}
|
|
5222
|
+
_turnBindingProducer?.beginTurn(messages.length);
|
|
5223
|
+
} catch {
|
|
5224
|
+
/* advisory — never disturb the turn */
|
|
5225
|
+
}
|
|
5226
|
+
}
|
|
5227
|
+
|
|
5162
5228
|
// Slot-filling: detect intent and fill missing parameters interactively
|
|
5163
5229
|
try {
|
|
5164
5230
|
const { CLISlotFiller } = await import("../lib/slot-filler.js");
|
|
@@ -5368,6 +5434,9 @@ export async function startAgentRepl(options = {}) {
|
|
|
5368
5434
|
autoCheckpoint,
|
|
5369
5435
|
checkpointSession: sessionId,
|
|
5370
5436
|
checkpointMarks: _checkpointMarks,
|
|
5437
|
+
// Explicit turn-binding producer (null unless a JSONL session): the
|
|
5438
|
+
// wrapper folds every loop event into the live table.
|
|
5439
|
+
turnBindingFeed: _turnBindingProducer,
|
|
5371
5440
|
denialLog: _recentDenials,
|
|
5372
5441
|
persistRecentDenials: true,
|
|
5373
5442
|
permissionMode: _sessionTier,
|
|
@@ -5589,6 +5658,9 @@ export async function startAgentRepl(options = {}) {
|
|
|
5589
5658
|
// Non-critical
|
|
5590
5659
|
}
|
|
5591
5660
|
}
|
|
5661
|
+
// Persist the explicit turn-binding table for this settled turn
|
|
5662
|
+
// (dirty-gated: a tool-free Q&A turn writes nothing; never throws).
|
|
5663
|
+
_turnBindingProducer?.persistIfDirty();
|
|
5592
5664
|
// Auto-compact when context grows too large
|
|
5593
5665
|
if (
|
|
5594
5666
|
feature("PROMPT_COMPRESSOR") &&
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* REPL turn-binding PRODUCER — closes the incremental-gap 仍欠 item "REPL 自身
|
|
3
|
+
* 作为显式表生产者(交互 turn 实时喂+持久化,镜像 headless 接线;现 REPL 只消费)".
|
|
4
|
+
*
|
|
5
|
+
* Wraps the SHARED feeder core ([[turn-binding.js]] `createTurnBindingFeed` —
|
|
6
|
+
* the exact mapping the headless runner uses, so the two producers can never
|
|
7
|
+
* drift) with the three REPL-specific concerns:
|
|
8
|
+
*
|
|
9
|
+
* 1. Rehydrate: the first turn loads the session's persisted table
|
|
10
|
+
* (`loadTurnBindingLog`) so an interactive continuation of a headless (or
|
|
11
|
+
* earlier REPL) run APPENDS to the existing table instead of clobbering it.
|
|
12
|
+
* 2. Timeline supersede: the live REPL can shrink its conversation
|
|
13
|
+
* (`/rewind`, `/clear`, auto-compaction), so each new turn prunes records
|
|
14
|
+
* anchored at/after its own offset — under `pickPersistedTurn`'s
|
|
15
|
+
* exact-offset matching a stale record from the discarded timeline would
|
|
16
|
+
* otherwise shadow the new turn and could offer the wrong checkpoint.
|
|
17
|
+
* 3. Per-settle persistence: dirty-gated `persistTurnBinding` after each turn
|
|
18
|
+
* (a tool-free Q&A turn writes nothing), best-effort — the producer is
|
|
19
|
+
* advisory and must NEVER disturb the turn itself, so every method
|
|
20
|
+
* swallows its own failures.
|
|
21
|
+
*
|
|
22
|
+
* I/O goes through `_deps` so tests drive the producer hermetically.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import { createTurnBindingFeed } from "../lib/turn-binding.js";
|
|
26
|
+
import {
|
|
27
|
+
loadTurnBindingLog,
|
|
28
|
+
persistTurnBinding,
|
|
29
|
+
} from "../lib/turn-binding-store.js";
|
|
30
|
+
|
|
31
|
+
// Injected so tests can seed the persisted table / capture snapshots without
|
|
32
|
+
// touching the real sessions directory.
|
|
33
|
+
export const _deps = {
|
|
34
|
+
loadTurnBindingLog,
|
|
35
|
+
persistTurnBinding,
|
|
36
|
+
now: () => Date.now(),
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @param {{sessionId?: string, nonce?: string}} [opts]
|
|
41
|
+
* @returns {object|null} null when the session cannot persist (no sessionId)
|
|
42
|
+
*/
|
|
43
|
+
export function createReplTurnBindingProducer({ sessionId, nonce } = {}) {
|
|
44
|
+
if (!sessionId) return null;
|
|
45
|
+
// Per-process nonce (mirrors the headless runner's per-run nonce): restored
|
|
46
|
+
// turn ids keep their original nonce, new ids can't collide across resumes.
|
|
47
|
+
const runNonce = nonce || String(_deps.now());
|
|
48
|
+
let feed = null;
|
|
49
|
+
return {
|
|
50
|
+
/**
|
|
51
|
+
* Anchor a new interactive turn. Call just AFTER the user message was
|
|
52
|
+
* appended, with `conversationOffset = messages.length` — the exact-match
|
|
53
|
+
* contract `pickPersistedTurn` relies on.
|
|
54
|
+
*/
|
|
55
|
+
beginTurn(conversationOffset) {
|
|
56
|
+
try {
|
|
57
|
+
if (!feed) {
|
|
58
|
+
feed = createTurnBindingFeed({
|
|
59
|
+
log: _deps.loadTurnBindingLog(sessionId),
|
|
60
|
+
nonce: runNonce,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
return feed.beginTurn(conversationOffset, { supersede: true });
|
|
64
|
+
} catch {
|
|
65
|
+
return null; // advisory — never disturb the turn
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
/** Fold one agent-loop event into the current turn (fed by agentLoop). */
|
|
69
|
+
handleEvent(event) {
|
|
70
|
+
if (!feed) return false;
|
|
71
|
+
try {
|
|
72
|
+
return feed.handleEvent(event);
|
|
73
|
+
} catch {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
/** Persist the table after a settled turn (dirty-gated, best-effort). */
|
|
78
|
+
persistIfDirty() {
|
|
79
|
+
if (!feed || !feed.isDirty()) return false;
|
|
80
|
+
try {
|
|
81
|
+
const ok = _deps.persistTurnBinding(sessionId, feed.log);
|
|
82
|
+
if (ok) feed.clearDirty();
|
|
83
|
+
return ok;
|
|
84
|
+
} catch {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
/** The live table (for tests / future in-process consumers). */
|
|
89
|
+
log: () => (feed ? feed.log : null),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
@@ -57,6 +57,8 @@ import {
|
|
|
57
57
|
classifyToolSideEffect,
|
|
58
58
|
} from "../lib/side-effect-ledger.js";
|
|
59
59
|
import { SIDE_EFFECT_LEDGER_EVENT } from "../lib/side-effect-ledger-store.js";
|
|
60
|
+
import { TurnBindingLog, createTurnBindingFeed } from "../lib/turn-binding.js";
|
|
61
|
+
import { TURN_BINDING_EVENT } from "../lib/turn-binding-store.js";
|
|
60
62
|
import { operationIdempotencyKey } from "../lib/idempotency.js";
|
|
61
63
|
import { expandFileRefsAsync } from "./file-ref-expander.js";
|
|
62
64
|
import { composeSystemPrompt } from "./system-prompt.js";
|
|
@@ -730,6 +732,50 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
730
732
|
// best-effort — never fail the run over ledger persistence
|
|
731
733
|
}
|
|
732
734
|
};
|
|
735
|
+
// P1 explicit turn→checkpoint binding: feed the TurnBindingLog in real time
|
|
736
|
+
// off the yielded agent-loop events (checkpoint / tool / policy / child-agent)
|
|
737
|
+
// and persist the table as a hash-chained `turn_checkpoint_binding` session
|
|
738
|
+
// event at each turn boundary. Provider tool_use ids are not runner-visible,
|
|
739
|
+
// so tool-call ids are synthesized `<nonce>:c<seq>` (mirrors the side-effect
|
|
740
|
+
// ledger's op-id scheme — stable within a run, unique across resumes).
|
|
741
|
+
// rebuildMessages ignores this event type, so it never pollutes model
|
|
742
|
+
// context. Only writes when a turn actually recorded something, and only for
|
|
743
|
+
// persisted runs — a tool-free Q&A or ephemeral run stays byte-identical.
|
|
744
|
+
let turnBindingLog = new TurnBindingLog();
|
|
745
|
+
if (persist) {
|
|
746
|
+
try {
|
|
747
|
+
const events = store.readEvents(sessionId) || [];
|
|
748
|
+
for (let i = events.length - 1; i >= 0; i--) {
|
|
749
|
+
const e = events[i];
|
|
750
|
+
if (
|
|
751
|
+
e &&
|
|
752
|
+
e.type === TURN_BINDING_EVENT &&
|
|
753
|
+
e.data &&
|
|
754
|
+
Array.isArray(e.data.turns)
|
|
755
|
+
) {
|
|
756
|
+
turnBindingLog = TurnBindingLog.fromJSON(e.data);
|
|
757
|
+
break;
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
} catch {
|
|
761
|
+
// fresh log — best effort
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
// Event→table folding + id synthesis live in the SHARED feeder core
|
|
765
|
+
// (createTurnBindingFeed) so the interactive REPL producer can never drift
|
|
766
|
+
// from this runner's mapping. No feed at all for non-persisted runs.
|
|
767
|
+
const turnBindingFeed = persist
|
|
768
|
+
? createTurnBindingFeed({ log: turnBindingLog, nonce: sideEffectRunNonce })
|
|
769
|
+
: null;
|
|
770
|
+
const persistTurnBindingLog = () => {
|
|
771
|
+
if (!turnBindingFeed || !turnBindingFeed.isDirty()) return;
|
|
772
|
+
try {
|
|
773
|
+
store.appendEvent(sessionId, TURN_BINDING_EVENT, turnBindingLog.toJSON());
|
|
774
|
+
turnBindingFeed.clearDirty();
|
|
775
|
+
} catch {
|
|
776
|
+
// best-effort — never fail the run over binding persistence
|
|
777
|
+
}
|
|
778
|
+
};
|
|
733
779
|
if (persist) {
|
|
734
780
|
try {
|
|
735
781
|
const events = store.readEvents(sessionId) || [];
|
|
@@ -1703,7 +1749,17 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
1703
1749
|
try {
|
|
1704
1750
|
// eslint-disable-next-line no-constant-condition
|
|
1705
1751
|
while (true) {
|
|
1752
|
+
// P1 turn→checkpoint binding: one drain of the loop = one turn. Anchor
|
|
1753
|
+
// the conversation offset before the model sees the new user turn. A
|
|
1754
|
+
// `--worktree` run stamps its isolation worktree (branch name, threaded
|
|
1755
|
+
// from the command layer) onto each turn record.
|
|
1756
|
+
if (turnBindingFeed) {
|
|
1757
|
+
turnBindingFeed.beginTurn(messages.length, {
|
|
1758
|
+
worktreeId: options.worktreeId ?? null,
|
|
1759
|
+
});
|
|
1760
|
+
}
|
|
1706
1761
|
for await (const event of runLoop(messages, loopOptions)) {
|
|
1762
|
+
if (turnBindingFeed) turnBindingFeed.handleEvent(event);
|
|
1707
1763
|
switch (event.type) {
|
|
1708
1764
|
case "checkpoint": {
|
|
1709
1765
|
if (isText)
|
|
@@ -1876,6 +1932,9 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
1876
1932
|
// call is made (break out of the for-await, not just the switch).
|
|
1877
1933
|
if (stopForCost) break;
|
|
1878
1934
|
}
|
|
1935
|
+
// P1 turn→checkpoint binding: the turn settled — persist the explicit
|
|
1936
|
+
// table (latest snapshot wins on load; no-op when nothing was recorded).
|
|
1937
|
+
persistTurnBindingLog();
|
|
1879
1938
|
// ── auto-rewake re-drive (opt-in via --auto-rewake) ─────────────────
|
|
1880
1939
|
// Under auto-rewake, settle the async Stop hooks after EVERY turn (so the
|
|
1881
1940
|
// final turn's background check still runs). If an asyncRewake check
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{P as c,J as d,b as s}from"./vendor-Bn1JzzAn.js";import{r as a}from"./markdown-Yo_c6Krv.js";import{_ as p}from"./index-C2k8eHyq.js";const _={__name:"MarkdownRenderer",props:{content:{type:String,default:""}},setup(t,{expose:o}){o();const e=t,r=s(()=>a(e.content||"")),n={props:e,rendered:r,computed:s,get renderMarkdown(){return a}};return Object.defineProperty(n,"__isScriptSetup",{enumerable:!1,value:!0}),n}},i=["innerHTML"];function m(t,o,e,r,n,u){return c(),d("div",{class:"markdown-content",innerHTML:r.rendered},null,8,i)}const w=p(_,[["render",m],["__scopeId","data-v-0b0b9f63"],["__file","/tmp/cc-web-panel-4d4NxJ/repo/packages/web-panel/src/components/MarkdownRenderer.vue"]]);export{w as M};
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./ChatBubbleRenderer-CTjqFhdD.js","./vendor-Bn1JzzAn.js","./index-C2k8eHyq.js","./icons-DG5UD-6K.js","./index-Cq93VfoF.css","./ChatBubbleRenderer-gy5SDGw2.css","./OrderTableRenderer-Cc9Se8H-.js","./OrderTableRenderer-CfrDjSHT.css","./TimelineRenderer-Bzp_T3Xc.js","./TimelineRenderer-BlTAtkOc.css","./EmailListRenderer-qEib4yiq.js","./EmailListRenderer-DTPZPx_S.css","./GenericCardRenderer-57dqulUe.js","./GenericCardRenderer-o85VDYQS.css"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{E as ue,r as E,b as w,I as y,P as u,J as O,U as v,c,S as C,V as x,_ as J,F as B,Z as se,a0 as le,R,K as m,Q as b,W as L,o as M}from"./vendor-Bn1JzzAn.js";import{u as U}from"./usePersonalDataHub-jKcLN_Gj.js";import{_ as D,e as F,d as P}from"./index-C2k8eHyq.js";import{aa as q,ag as Q,M as z,aI as G,v as H,aH as K,aq as W,ac as Y,e as de,d as fe,k as pe,ai as me,aA as _e,R as ge}from"./icons-DG5UD-6K.js";const I=Object.freeze({q:"",category:null,adapter:null,subtype:null,since:null,until:null}),N=50,Z=300,X=ue("pdhBrowser",()=>{const r=E({...I}),t=E([]),n=E(null),e=E(!1),o=E(!1),l=E(null),a=E(null),s=E(!1),i=E({byCategory:{},byAdapter:{},bySubtype:{},total:0});let d=0,_=null;const A=w(()=>t.value.length>0),j=w(()=>n.value!=null);function h(S={}){const p={},f=r.value;return f.q&&f.q.trim()&&(p.q=f.q.trim()),f.category&&(p.category=f.category),f.adapter&&(p.adapter=f.adapter),f.subtype&&(p.subtype=f.subtype),Number.isFinite(f.since)&&(p.since=f.since),Number.isFinite(f.until)&&(p.until=f.until),{...p,...S}}async function g(){const S=++d;e.value=!0,l.value=null;const p=U();try{const[f,T]=await Promise.all([p.searchEvents(h({limit:N})),p.facetCounts({...r.value.q&&r.value.q.trim()?{q:r.value.q.trim()}:{},...Number.isFinite(r.value.since)?{since:r.value.since}:{},...Number.isFinite(r.value.until)?{until:r.value.until}:{}})]);if(S!==d)return;t.value=f.rows||[],n.value=f.nextCursor||null,a.value=f.mode||"like",s.value=!!f.shortQuery,i.value={byCategory:T.byCategory||{},byAdapter:T.byAdapter||{},bySubtype:T.bySubtype||{},total:T.total||0}}catch(f){if(S!==d)return;l.value=f&&f.message?f.message:String(f),t.value=[],n.value=null}finally{S===d&&(e.value=!1)}}async function k(){if(!n.value||o.value)return;o.value=!0,l.value=null;const S=U();try{const p=await S.searchEvents(h({cursor:n.value,limit:N}));t.value=t.value.concat(p.rows||[]),n.value=p.nextCursor||null,a.value=p.mode||a.value}catch(p){l.value=p&&p.message?p.message:String(p)}finally{o.value=!1}}function ae(S,p){if(!(S in I))throw new Error(`pdhBrowser.setFilter: unknown key "${S}"`);r.value={...r.value,[S]:p},_&&clearTimeout(_),_=setTimeout(()=>{_=null,g()},Z)}function ie(S){return r.value={...I,...S},_&&(clearTimeout(_),_=null),g()}function ce(){r.value={...I},t.value=[],n.value=null,l.value=null,i.value={byCategory:{},byAdapter:{},bySubtype:{},total:0}}return{filters:r,results:t,cursor:n,isLoading:e,isAppending:o,error:l,mode:a,shortQuery:s,facets:i,hasResults:A,canLoadMore:j,search:g,loadMore:k,setFilter:ae,setFilters:ie,reset:ce,PAGE_SIZE:N,SEARCH_DEBOUNCE_MS:Z}}),ye=Object.freeze(["chat","social","email","shopping","travel","system","ai-chat","other"]),ve=Object.freeze({chat:"社交聊天",social:"内容平台",email:"邮件",shopping:"支付订单",travel:"出行",system:"系统数据","ai-chat":"AI 对话",other:"其他"});function V(r){return ve[r]||r||"未知"}const be=Object.freeze([["wechat","chat"],["messaging-","chat"],["social-","social"],["email-","email"],["shopping-","shopping"],["alipay-","shopping"],["travel-","travel"],["system-data","system"],["browser-","system"],["vscode","system"],["win-recent","system"],["git-activity","system"],["shell-history","system"],["local-files","system"],["ai-chat-","ai-chat"]]);function $(r){if(typeof r!="string"||r.length===0)return"other";for(const[t,n]of be)if(t.endsWith("-")||t==="system-data"){if(r.startsWith(t))return n}else if(r===t)return n;return"other"}const he={__name:"CategorySidebar",props:{selected:{type:String,default:null},facets:{type:Object,default:()=>({byCategory:{},total:0})}},emits:["select"],setup(r,{expose:t}){t();const n=r,e=w(()=>n.facets.total||0),o={chat:Y,social:W,email:K,shopping:H,travel:G,system:z,"ai-chat":Q,other:q};function l(i){return o[i]||q}function a(i){return i?{backgroundColor:"#fff",color:"#1677ff"}:{backgroundColor:"#f0f0f0",color:"#666"}}const s={props:n,total:e,ICONS:o,iconFor:l,badgeStyle:a,computed:w,get AppstoreOutlined(){return q},get MessageOutlined(){return Y},get PlayCircleOutlined(){return W},get MailOutlined(){return K},get ShoppingOutlined(){return H},get CarOutlined(){return G},get MobileOutlined(){return z},get RobotOutlined(){return Q},get CATEGORIES(){return ye},get categoryLabel(){return V}};return Object.defineProperty(s,"__isScriptSetup",{enumerable:!1,value:!0}),s}},Se={class:"pdh-sidebar"},Oe=["onClick"],we={class:"label"};function Ce(r,t,n,e,o,l){const a=y("a-badge");return u(),O("div",Se,[t[2]||(t[2]=v("div",{class:"sidebar-title"},"数据类型",-1)),v("div",{class:J(["cat-item",{active:n.selected===null}]),onClick:t[0]||(t[0]=s=>r.$emit("select",null))},[c(e.AppstoreOutlined,{class:"icon"}),t[1]||(t[1]=v("span",{class:"label"},"全部",-1)),e.total>0?(u(),C(a,{key:0,count:e.total,"number-style":e.badgeStyle(n.selected===null),"overflow-count":9999},null,8,["count","number-style"])):x("v-if",!0)],2),(u(!0),O(B,null,se(e.CATEGORIES,s=>(u(),O("div",{key:s,class:J(["cat-item",{active:n.selected===s,dim:!n.facets.byCategory[s]}]),onClick:i=>r.$emit("select",s)},[(u(),C(le(e.iconFor(s)),{class:"icon"})),v("span",we,R(e.categoryLabel(s)),1),n.facets.byCategory[s]?(u(),C(a,{key:0,count:n.facets.byCategory[s],"number-style":e.badgeStyle(n.selected===s),"overflow-count":9999},null,8,["count","number-style"])):x("v-if",!0)],10,Oe))),128))])}const ke=D(he,[["render",Ce],["__scopeId","data-v-6b62a22e"],["__file","/tmp/cc-web-panel-4d4NxJ/repo/packages/web-panel/src/components/pdh/CategorySidebar.vue"]]),xe={__name:"SearchFilterBar",props:{filters:{type:Object,required:!0},facets:{type:Object,default:()=>({byAdapter:{}})},isLoading:{type:Boolean,default:!1},mode:{type:String,default:null},shortQuery:{type:Boolean,default:!1}},emits:["set-filter","reset"],setup(r,{expose:t,emit:n}){t();const e=r,o=n,l=w(()=>e.filters.category?`在「${e.filters.category}」类目内搜索…`:"搜索关键词(如:支付宝、罗技、Kotlin)…"),a=w(()=>Object.entries(e.facets.byAdapter||{}).sort((g,k)=>k[1]-g[1]).map(([g,k])=>({value:g,label:`${g} (${k})`}))),s=w(()=>!e.filters.since&&!e.filters.until?null:[e.filters.since?new Date(e.filters.since):null,e.filters.until?new Date(e.filters.until):null]),i=w(()=>!!(e.filters.q||e.filters.adapter||e.filters.subtype||e.filters.since||e.filters.until));function d(h){o("set-filter","q",h||"")}function _(h){o("set-filter","q",h||"")}function A(h){if(!h||h.length===0){o("set-filter","since",null),o("set-filter","until",null);return}const[g,k]=h;o("set-filter","since",g?+g:null),o("set-filter","until",k?+k:null)}const j={props:e,emit:o,placeholderText:l,adapterOptions:a,dateRangeValue:s,hasActiveFilters:i,onQInput:d,onSearch:_,onDateChange:A,computed:w,get SearchOutlined(){return pe},get CloseCircleOutlined(){return fe},get InfoCircleOutlined(){return de}};return Object.defineProperty(j,"__isScriptSetup",{enumerable:!1,value:!0}),j}},Ee={class:"pdh-filter-bar"},Re={key:1,class:"hint"},Ae={key:2,class:"hint"};function je(r,t,n,e,o,l){const a=y("a-input-search"),s=y("a-select"),i=y("a-range-picker"),d=y("a-button");return u(),O("div",Ee,[c(a,{value:n.filters.q,placeholder:e.placeholderText,"enter-button":"搜索","allow-clear":"",loading:n.isLoading,style:{flex:"1","max-width":"480px"},"onUpdate:value":e.onQInput,onSearch:e.onSearch},{prefix:m(()=>[c(e.SearchOutlined)]),_:1},8,["value","placeholder","loading"]),c(s,{value:n.filters.adapter,placeholder:"所有 adapter","allow-clear":"",options:e.adapterOptions,style:{width:"200px"},"onUpdate:value":t[0]||(t[0]=_=>r.$emit("set-filter","adapter",_||null))},null,8,["value","options"]),c(i,{value:e.dateRangeValue,placeholder:["开始日期","结束日期"],style:{width:"280px"},"onUpdate:value":e.onDateChange},null,8,["value"]),e.hasActiveFilters?(u(),C(d,{key:0,type:"link",danger:"",onClick:t[1]||(t[1]=_=>r.$emit("reset"))},{icon:m(()=>[c(e.CloseCircleOutlined)]),default:m(()=>[t[2]||(t[2]=b(" 清空筛选 ",-1))]),_:1})):x("v-if",!0),n.shortQuery?(u(),O("span",Re,[c(e.InfoCircleOutlined),t[3]||(t[3]=b(" 关键词需至少 3 字 (FTS5 trigram 限制) ",-1))])):n.mode==="like"?(u(),O("span",Ae,[c(e.InfoCircleOutlined),t[4]||(t[4]=b(" 当前为 LIKE 兜底模式 ",-1))])):x("v-if",!0)])}const Le=D(xe,[["render",je],["__scopeId","data-v-d7cce6e9"],["__file","/tmp/cc-web-panel-4d4NxJ/repo/packages/web-panel/src/components/pdh/SearchFilterBar.vue"]]),Fe={__name:"RendererDispatcher",props:{event:{type:Object,required:!0}},setup(r,{expose:t}){t();const n=L(()=>F(()=>import("./ChatBubbleRenderer-CTjqFhdD.js"),__vite__mapDeps([0,1,2,3,4,5]),import.meta.url)),e=L(()=>F(()=>import("./OrderTableRenderer-Cc9Se8H-.js"),__vite__mapDeps([6,1,2,3,4,7]),import.meta.url)),o=L(()=>F(()=>import("./TimelineRenderer-Bzp_T3Xc.js"),__vite__mapDeps([8,1,2,3,4,9]),import.meta.url)),l=L(()=>F(()=>import("./EmailListRenderer-qEib4yiq.js"),__vite__mapDeps([10,1,2,3,4,11]),import.meta.url)),a=L(()=>F(()=>import("./GenericCardRenderer-57dqulUe.js"),__vite__mapDeps([12,1,2,3,4,13]),import.meta.url));function s(d){const _=d&&d.source&&d.source.adapter;switch($(_)){case"chat":case"ai-chat":return n;case"shopping":return e;case"travel":return o;case"email":return l;default:return a}}const i={ChatBubbleRenderer:n,OrderTableRenderer:e,TimelineRenderer:o,EmailListRenderer:l,GenericCardRenderer:a,rendererFor:s,defineAsyncComponent:L,get getCategory(){return $}};return Object.defineProperty(i,"__isScriptSetup",{enumerable:!1,value:!0}),i}};function De(r,t,n,e,o,l){return u(),C(le(e.rendererFor(n.event)),{event:n.event},null,8,["event"])}const Te=D(Fe,[["render",De],["__file","/tmp/cc-web-panel-4d4NxJ/repo/packages/web-panel/src/components/pdh/renderers/RendererDispatcher.vue"]]);function ee(r){return JSON.stringify(r,null,2)}function te(r){return r.map(t=>JSON.stringify(t)).join(`
|
|
3
|
-
`)+`
|
|
4
|
-
`}function ne(r){const n=["id","subtype","occurredAt","occurredAtIso","actor","place","adapter","summary","contentJson","extraJson"].join(","),e=r.map(o=>{const l=Number.isFinite(o.occurredAt)?o.occurredAt:null,a=l?new Date(l).toISOString():"",s=o.source&&o.source.adapter||"",i=o.content&&(o.content.text||o.content.title||o.content.subject)||"";return[o.id||"",o.subtype||"",l!=null?String(l):"",a,o.actor||"",o.place||"",s,i,o.content?JSON.stringify(o.content):"",o.extra?JSON.stringify(o.extra):""].map(Ie).join(",")});return[n,...e].join(`
|
|
5
|
-
`)+`
|
|
6
|
-
`}function Ie(r){const t=String(r??"");return t.includes(",")||t.includes('"')||t.includes(`
|
|
7
|
-
`)||t.includes("\r")?'"'+t.replace(/"/g,'""')+'"':t}function re(r,t,n="application/octet-stream"){if(typeof window>"u"||typeof document>"u")return t;const e=new Blob([r],{type:n}),o=URL.createObjectURL(e),l=document.createElement("a");return l.href=o,l.download=t,document.body.appendChild(l),l.click(),document.body.removeChild(l),setTimeout(()=>URL.revokeObjectURL(o),1e3),t}function oe(r,t=null){const n=new Date,e=n.getFullYear(),o=String(n.getMonth()+1).padStart(2,"0"),l=String(n.getDate()).padStart(2,"0"),a=r==="ndjson"?"ndjson":r,s=t?`-${t}`:"";return`pdh-events-${e}-${o}-${l}${s}.${a}`}const Pe={__name:"ExportDropdown",props:{events:{type:Array,required:!0},category:{type:String,default:null}},setup(r,{expose:t}){t();const n=r,e=w(()=>n.events.length>0),o={json:"application/json;charset=utf-8",ndjson:"application/x-ndjson;charset=utf-8",csv:"text/csv;charset=utf-8"};function l(i){switch(i){case"json":return ee(n.events);case"ndjson":return te(n.events);case"csv":return ne(n.events);default:throw new Error(`unknown format: ${i}`)}}function a({key:i}){try{const d=l(i),_=oe(i,n.category);re(d,_,o[i]),P.success(`已导出 ${n.events.length} 条到 ${_}`)}catch(d){P.error(`导出失败: ${d.message||d}`)}}const s={props:n,hasResults:e,MIME:o,serialize:l,onClick:a,computed:w,get DownloadOutlined(){return _e},get DownOutlined(){return me},get message(){return P},get eventsToJson(){return ee},get eventsToNdjson(){return te},get eventsToCsv(){return ne},get downloadAs(){return re},get suggestFilename(){return oe}};return Object.defineProperty(s,"__isScriptSetup",{enumerable:!1,value:!0}),s}};function qe(r,t,n,e,o,l){const a=y("a-button"),s=y("a-menu-item"),i=y("a-menu"),d=y("a-dropdown");return u(),C(d,{disabled:!e.hasResults},{overlay:m(()=>[c(i,{onClick:e.onClick},{default:m(()=>[c(s,{key:"json"},{default:m(()=>[...t[0]||(t[0]=[b("JSON (.json)",-1)])]),_:1}),c(s,{key:"ndjson"},{default:m(()=>[...t[1]||(t[1]=[b("NDJSON (.ndjson)",-1)])]),_:1}),c(s,{key:"csv"},{default:m(()=>[...t[2]||(t[2]=[b("CSV (.csv)",-1)])]),_:1})]),_:1})]),default:m(()=>[c(a,{disabled:!e.hasResults},{icon:m(()=>[c(e.DownloadOutlined)]),default:m(()=>[b(" 导出 ("+R(n.events.length)+") ",1),c(e.DownOutlined)]),_:1},8,["disabled"])]),_:1},8,["disabled"])}const Ne=D(Pe,[["render",qe],["__file","/tmp/cc-web-panel-4d4NxJ/repo/packages/web-panel/src/components/pdh/ExportDropdown.vue"]]),Be={__name:"PdhVaultBrowser",setup(r,{expose:t}){t();const n=X(),e=w(()=>n.filters.q?`没有匹配 "${n.filters.q}" 的事件 — 试试更短的关键词或换个类目`:n.filters.category?`「${V(n.filters.category)}」类目下还没有数据 — 去采集页同步对应 adapter`:"Vault 里还没有数据 — 去「个人数据中台」页面同步任意 adapter");function o(s){n.filters.category=s,n.search()}function l(s,i){n.setFilter(s,i)}M(()=>{!n.hasResults&&!n.isLoading&&n.search()});const a={store:n,emptyHint:e,onCategorySelect:o,onSetFilter:l,onMounted:M,computed:w,get ReloadOutlined(){return ge},get usePdhBrowserStore(){return X},get categoryLabel(){return V},CategorySidebar:ke,SearchFilterBar:Le,RendererDispatcher:Te,ExportDropdown:Ne};return Object.defineProperty(a,"__isScriptSetup",{enumerable:!1,value:!0}),a}},Ve={class:"pdh-browser-page"},Je={class:"page-header"},Me={class:"main-pane"},Ue={class:"results-summary"},Qe={key:0},ze={key:0},Ge={key:1},He={class:"loaded-of"},Ke={class:"results-list"},We={key:2,class:"load-more"};function Ye(r,t,n,e,o,l){const a=y("a-tag"),s=y("a-button"),i=y("a-space"),d=y("a-col"),_=y("a-spin"),A=y("a-alert"),j=y("a-empty"),h=y("a-row");return u(),O("div",Ve,[v("div",Je,[t[6]||(t[6]=v("div",null,[v("h2",{class:"page-title"},"数据浏览器"),v("p",{class:"page-sub"}," Vault 里所有已采集的数据,按类目浏览 / 全文检索 / 时间窗口筛选。 完全离线,不外传。 ")],-1)),c(i,null,{default:m(()=>[e.store.mode==="fts5"?(u(),C(a,{key:0,color:"green"},{default:m(()=>[...t[3]||(t[3]=[b("FTS5 trigram",-1)])]),_:1})):e.store.mode==="like"?(u(),C(a,{key:1,color:"orange"},{default:m(()=>[...t[4]||(t[4]=[b("LIKE 兜底",-1)])]),_:1})):x("v-if",!0),c(e.ExportDropdown,{events:e.store.results,category:e.store.filters.category},null,8,["events","category"]),c(s,{onClick:t[0]||(t[0]=g=>e.store.search()),loading:e.store.isLoading},{icon:m(()=>[c(e.ReloadOutlined)]),default:m(()=>[t[5]||(t[5]=b(" 刷新 ",-1))]),_:1},8,["loading"])]),_:1})]),c(h,{gutter:16,class:"browser-layout"},{default:m(()=>[c(d,{xs:24,sm:24,md:6,lg:5,xl:4},{default:m(()=>[c(e.CategorySidebar,{selected:e.store.filters.category,facets:e.store.facets,onSelect:e.onCategorySelect},null,8,["selected","facets"])]),_:1}),c(d,{xs:24,sm:24,md:18,lg:19,xl:20},{default:m(()=>[v("div",Me,[c(e.SearchFilterBar,{filters:e.store.filters,facets:e.store.facets,"is-loading":e.store.isLoading,mode:e.store.mode,"short-query":e.store.shortQuery,onSetFilter:e.onSetFilter,onReset:t[1]||(t[1]=g=>{e.store.reset(),e.store.search()})},null,8,["filters","facets","is-loading","mode","short-query"]),v("div",Ue,[e.store.isLoading&&e.store.results.length===0?(u(),O("span",Qe,[c(_,{size:"small"}),t[7]||(t[7]=b(" 载入中… ",-1))])):(u(),O(B,{key:1},[v("strong",null,R(e.store.facets.total),1),t[11]||(t[11]=b(" 条事件 ",-1)),e.store.filters.category?(u(),O("span",ze,[t[8]||(t[8]=b(" / 当前类目 ",-1)),v("strong",null,R(e.categoryLabel(e.store.filters.category)),1),v("strong",null,R(e.store.facets.byCategory[e.store.filters.category]||0),1)])):x("v-if",!0),e.store.filters.q?(u(),O("span",Ge,[t[9]||(t[9]=b(' / 关键词 "',-1)),v("em",null,R(e.store.filters.q),1),t[10]||(t[10]=b('"',-1))])):x("v-if",!0),v("span",He," / 已显示 "+R(e.store.results.length),1)],64))]),e.store.error?(u(),C(A,{key:0,type:"error","show-icon":"",message:e.store.error,closable:"",style:{margin:"12px 0"}},null,8,["message"])):x("v-if",!0),!e.store.isLoading&&e.store.results.length===0&&!e.store.error?(u(),C(j,{key:1,description:e.emptyHint,style:{"margin-top":"40px"}},null,8,["description"])):x("v-if",!0),v("div",Ke,[(u(!0),O(B,null,se(e.store.results,(g,k)=>(u(),C(e.RendererDispatcher,{key:`r-${k}-${g.id}`,event:g},null,8,["event"]))),128))]),e.store.canLoadMore?(u(),O("div",We,[c(s,{loading:e.store.isAppending,onClick:t[2]||(t[2]=g=>e.store.loadMore()),block:""},{default:m(()=>[...t[12]||(t[12]=[b(" 加载下一页 (50 条) ",-1)])]),_:1},8,["loading"])])):x("v-if",!0)])]),_:1})]),_:1})])}const tt=D(Be,[["render",Ye],["__scopeId","data-v-0f7c02cd"],["__file","/tmp/cc-web-panel-4d4NxJ/repo/packages/web-panel/src/views/PdhVaultBrowser.vue"]]);export{tt as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{I as u,J as j,U as b,R as c,c as a,K as i,a as R,r as k,o as F,b as E,P as O,Q as p,S as z,V as N}from"./vendor-Bn1JzzAn.js";import{t as M,_ as Q,b as K,u as T,d as S}from"./index-C2k8eHyq.js";import{i as q,R as X}from"./icons-DG5UD-6K.js";const v=Object.freeze({defaultEngine:"webspeech",webSpeech:{lang:"zh-CN"},whisperAPI:{apiKey:"",baseURL:"https://api.openai.com/v1",model:"whisper-1",language:"zh",timeout:6e4},whisperLocal:{serverUrl:"http://localhost:8002",modelSize:"base",device:"auto",timeout:12e4}}),Y=["webspeech","whisper-api","whisper-local"];function B(g,t){if(typeof g=="number"&&Number.isFinite(g))return g;const s=parseFloat(g);return Number.isFinite(s)?s:t}function Z(g){return JSON.parse(JSON.stringify(g))}function D(g){const t=Z(v);if(!g)return t;const s=g.trim();if(!s||/key not found/i.test(s))return t;const e=M(s);if(!e||typeof e!="object"||Array.isArray(e))return t;if(typeof e.defaultEngine=="string"&&Y.includes(e.defaultEngine)&&(t.defaultEngine=e.defaultEngine),e.webSpeech&&typeof e.webSpeech=="object"&&typeof e.webSpeech.lang=="string"&&e.webSpeech.lang&&(t.webSpeech.lang=e.webSpeech.lang),e.whisperAPI&&typeof e.whisperAPI=="object"){const l=e.whisperAPI;typeof l.apiKey=="string"&&(t.whisperAPI.apiKey=l.apiKey),typeof l.baseURL=="string"&&l.baseURL&&(t.whisperAPI.baseURL=l.baseURL),typeof l.model=="string"&&l.model&&(t.whisperAPI.model=l.model),typeof l.language=="string"&&l.language&&(t.whisperAPI.language=l.language),l.timeout!==void 0&&(t.whisperAPI.timeout=B(l.timeout,v.whisperAPI.timeout))}if(e.whisperLocal&&typeof e.whisperLocal=="object"){const l=e.whisperLocal;typeof l.serverUrl=="string"&&l.serverUrl&&(t.whisperLocal.serverUrl=l.serverUrl),typeof l.modelSize=="string"&&l.modelSize&&(t.whisperLocal.modelSize=l.modelSize),typeof l.device=="string"&&l.device&&(t.whisperLocal.device=l.device),l.timeout!==void 0&&(t.whisperLocal.timeout=B(l.timeout,v.whisperLocal.timeout))}return t}function J(g,t){const s={};g.defaultEngine!==t.defaultEngine&&(s.defaultEngine=t.defaultEngine);for(const e of["webSpeech","whisperAPI","whisperLocal"]){const l=g[e]||{},w=t[e]||{};for(const o of Object.keys(v[e]))l[o]!==w[o]&&(s[`${e}.${o}`]=w[o])}return s}const $={__name:"SpeechSettings",setup(g,{expose:t}){t();const{t:s}=K(),e=T(),l=k(!1),w=k(!1),o=R(JSON.parse(JSON.stringify(v))),h=k(JSON.parse(JSON.stringify(v))),y=E(()=>[{value:"webspeech",label:s("speechSettings.engineOptions.webspeech")},{value:"whisper-api",label:s("speechSettings.engineOptions.whisper-api")},{value:"whisper-local",label:s("speechSettings.engineOptions.whisper-local")}]),f=E(()=>{const d=`speechSettings.engineHint.${o.defaultEngine}`,n=s(d);return n===d?"":n}),_=E(()=>Object.keys(J(h.value,o)).length>0);function m(d){o.defaultEngine=d.defaultEngine,Object.assign(o.webSpeech,d.webSpeech),Object.assign(o.whisperAPI,d.whisperAPI),Object.assign(o.whisperLocal,d.whisperLocal),h.value=JSON.parse(JSON.stringify(d))}async function r(){l.value=!0;try{const{output:d}=await e.execute("config get speech",1e4);m(D(d))}catch(d){/key not found/i.test(d.message)?m(JSON.parse(JSON.stringify(v))):S.error(s("speechSettings.messages.loadFailed",{err:d.message}))}finally{l.value=!1}}function C(){m(h.value)}async function x(){const d=J(h.value,o),n=Object.keys(d);if(n.length===0){S.info(s("speechSettings.messages.noChanges"));return}w.value=!0;let P=0,I=0;for(const A of n){const H=d[A],V=String(H).replace(/"/g,'\\"'),W=`config set speech.${A} "${V}"`;try{const{output:U,exitCode:G}=await e.execute(W,1e4);G!==0||/error|failed|失败/i.test(U)?(I++,S.error(s("speechSettings.messages.saveItemFailed",{key:A,err:U.slice(0,80)}))):P++}catch(U){I++,S.error(s("speechSettings.messages.saveItemFailed",{key:A,err:U.message}))}}w.value=!1,I===0?(S.success(s("speechSettings.messages.saveOk",{count:P})),h.value=JSON.parse(JSON.stringify(o))):P>0&&(S.warning(s("speechSettings.messages.savePartial",{ok:P,fail:I})),await r())}F(()=>{r()});const L={t:s,ws:e,loading:l,saving:w,form:o,baseline:h,engineOptions:y,engineHint:f,isDirty:_,applyConfig:m,loadConfig:r,resetForm:C,saveConfig:x,reactive:R,ref:k,computed:E,onMounted:F,get useI18n(){return K},get ReloadOutlined(){return X},get SoundOutlined(){return q},get message(){return S},get useWsStore(){return T},get parseSpeechConfig(){return D},get diffSpeechConfig(){return J},get SPEECH_DEFAULTS(){return v}};return Object.defineProperty(L,"__isScriptSetup",{enumerable:!1,value:!0}),L}},ee={style:{display:"flex","align-items":"center","justify-content":"space-between","margin-bottom":"24px"}},te={class:"page-title"},ae={class:"page-sub"},ie={style:{color:"var(--text-primary)"}},le={style:{color:"var(--text-muted)","font-size":"11px"}},ne={style:{color:"var(--text-primary)"}},se={style:{color:"var(--text-primary)"}},oe={style:{color:"var(--text-primary)"}},re={style:{display:"flex",gap:"12px","align-items":"center"}},de={key:0,style:{color:"#faad14","font-size":"12px"}};function pe(g,t,s,e,l,w){const o=u("a-button"),h=u("a-alert"),y=u("a-select"),f=u("a-form-item"),_=u("a-form"),m=u("a-card"),r=u("a-select-option"),C=u("a-input-password"),x=u("a-input"),L=u("a-input-number"),d=u("a-spin");return O(),j("div",null,[b("div",ee,[b("div",null,[b("h2",te,c(e.t("speechSettings.title")),1),b("p",ae,c(e.t("speechSettings.subtitle")),1)]),a(o,{loading:e.loading,onClick:e.loadConfig},{icon:i(()=>[a(e.ReloadOutlined)]),default:i(()=>[p(" "+c(e.t("speechSettings.refresh")),1)]),_:1},8,["loading"])]),a(h,{message:e.t("speechSettings.alert.message"),description:e.t("speechSettings.alert.description"),type:"info","show-icon":"",closable:"",style:{"margin-bottom":"16px"}},null,8,["message","description"]),a(d,{spinning:e.loading},{default:i(()=>[a(m,{style:{background:"var(--bg-card)","border-color":"var(--border-color)","margin-bottom":"16px"}},{title:i(()=>[b("span",ie,[a(e.SoundOutlined,{style:{"margin-right":"8px"}}),p(c(e.t("speechSettings.engineCardTitle")),1)])]),default:i(()=>[a(_,{"label-col":{span:6},"wrapper-col":{span:18},style:{"max-width":"720px"}},{default:i(()=>[a(f,{label:e.t("speechSettings.engineLabel")},{extra:i(()=>[b("span",le,c(e.engineHint),1)]),default:i(()=>[a(y,{value:e.form.defaultEngine,"onUpdate:value":t[0]||(t[0]=n=>e.form.defaultEngine=n),style:{width:"320px"},disabled:e.saving,options:e.engineOptions},null,8,["value","disabled","options"])]),_:1},8,["label"])]),_:1})]),_:1}),e.form.defaultEngine==="webspeech"?(O(),z(m,{key:0,style:{background:"var(--bg-card)","border-color":"var(--border-color)","margin-bottom":"16px"}},{title:i(()=>[b("span",ne,c(e.t("speechSettings.webSpeech.cardTitle")),1)]),default:i(()=>[a(_,{"label-col":{span:6},"wrapper-col":{span:18},style:{"max-width":"720px"}},{default:i(()=>[a(f,{label:e.t("speechSettings.webSpeech.langLabel")},{default:i(()=>[a(y,{value:e.form.webSpeech.lang,"onUpdate:value":t[1]||(t[1]=n=>e.form.webSpeech.lang=n),style:{width:"240px"},disabled:e.saving},{default:i(()=>[a(r,{value:"zh-CN"},{default:i(()=>[p(c(e.t("speechSettings.webSpeech.langOptions.zh-CN")),1)]),_:1}),a(r,{value:"zh-TW"},{default:i(()=>[p(c(e.t("speechSettings.webSpeech.langOptions.zh-TW")),1)]),_:1}),a(r,{value:"en-US"},{default:i(()=>[p(c(e.t("speechSettings.webSpeech.langOptions.en-US")),1)]),_:1}),a(r,{value:"en-GB"},{default:i(()=>[p(c(e.t("speechSettings.webSpeech.langOptions.en-GB")),1)]),_:1}),a(r,{value:"ja-JP"},{default:i(()=>[p(c(e.t("speechSettings.webSpeech.langOptions.ja-JP")),1)]),_:1}),a(r,{value:"ko-KR"},{default:i(()=>[p(c(e.t("speechSettings.webSpeech.langOptions.ko-KR")),1)]),_:1})]),_:1},8,["value","disabled"])]),_:1},8,["label"])]),_:1})]),_:1})):N("v-if",!0),e.form.defaultEngine==="whisper-api"?(O(),z(m,{key:1,style:{background:"var(--bg-card)","border-color":"var(--border-color)","margin-bottom":"16px"}},{title:i(()=>[b("span",se,c(e.t("speechSettings.whisperAPI.cardTitle")),1)]),default:i(()=>[a(_,{"label-col":{span:6},"wrapper-col":{span:18},style:{"max-width":"720px"}},{default:i(()=>[a(f,{label:e.t("speechSettings.whisperAPI.apiKeyLabel")},{default:i(()=>[a(C,{value:e.form.whisperAPI.apiKey,"onUpdate:value":t[2]||(t[2]=n=>e.form.whisperAPI.apiKey=n),placeholder:"sk-...",disabled:e.saving},null,8,["value","disabled"])]),_:1},8,["label"]),a(f,{label:e.t("speechSettings.whisperAPI.baseUrlLabel")},{default:i(()=>[a(x,{value:e.form.whisperAPI.baseURL,"onUpdate:value":t[3]||(t[3]=n=>e.form.whisperAPI.baseURL=n),disabled:e.saving},null,8,["value","disabled"])]),_:1},8,["label"]),a(f,{label:e.t("speechSettings.whisperAPI.modelLabel")},{default:i(()=>[a(x,{value:e.form.whisperAPI.model,"onUpdate:value":t[4]||(t[4]=n=>e.form.whisperAPI.model=n),disabled:e.saving},null,8,["value","disabled"])]),_:1},8,["label"]),a(f,{label:e.t("speechSettings.whisperAPI.languageLabel")},{default:i(()=>[a(x,{value:e.form.whisperAPI.language,"onUpdate:value":t[5]||(t[5]=n=>e.form.whisperAPI.language=n),disabled:e.saving},null,8,["value","disabled"])]),_:1},8,["label"]),a(f,{label:e.t("speechSettings.whisperAPI.timeoutLabel")},{default:i(()=>[a(L,{value:e.form.whisperAPI.timeout,"onUpdate:value":t[6]||(t[6]=n=>e.form.whisperAPI.timeout=n),min:1e3,max:6e5,step:1e3,style:{width:"200px"},disabled:e.saving},null,8,["value","disabled"])]),_:1},8,["label"])]),_:1})]),_:1})):N("v-if",!0),e.form.defaultEngine==="whisper-local"?(O(),z(m,{key:2,style:{background:"var(--bg-card)","border-color":"var(--border-color)","margin-bottom":"16px"}},{title:i(()=>[b("span",oe,c(e.t("speechSettings.whisperLocal.cardTitle")),1)]),default:i(()=>[a(_,{"label-col":{span:6},"wrapper-col":{span:18},style:{"max-width":"720px"}},{default:i(()=>[a(f,{label:e.t("speechSettings.whisperLocal.serverUrlLabel")},{default:i(()=>[a(x,{value:e.form.whisperLocal.serverUrl,"onUpdate:value":t[7]||(t[7]=n=>e.form.whisperLocal.serverUrl=n),placeholder:"http://localhost:8002",disabled:e.saving},null,8,["value","disabled"])]),_:1},8,["label"]),a(f,{label:e.t("speechSettings.whisperLocal.modelSizeLabel")},{default:i(()=>[a(y,{value:e.form.whisperLocal.modelSize,"onUpdate:value":t[8]||(t[8]=n=>e.form.whisperLocal.modelSize=n),style:{width:"180px"},disabled:e.saving},{default:i(()=>[a(r,{value:"tiny"},{default:i(()=>[...t[11]||(t[11]=[p("tiny",-1)])]),_:1}),a(r,{value:"base"},{default:i(()=>[...t[12]||(t[12]=[p("base",-1)])]),_:1}),a(r,{value:"small"},{default:i(()=>[...t[13]||(t[13]=[p("small",-1)])]),_:1}),a(r,{value:"medium"},{default:i(()=>[...t[14]||(t[14]=[p("medium",-1)])]),_:1}),a(r,{value:"large"},{default:i(()=>[...t[15]||(t[15]=[p("large",-1)])]),_:1})]),_:1},8,["value","disabled"])]),_:1},8,["label"]),a(f,{label:e.t("speechSettings.whisperLocal.deviceLabel")},{default:i(()=>[a(y,{value:e.form.whisperLocal.device,"onUpdate:value":t[9]||(t[9]=n=>e.form.whisperLocal.device=n),style:{width:"180px"},disabled:e.saving},{default:i(()=>[a(r,{value:"auto"},{default:i(()=>[...t[16]||(t[16]=[p("auto",-1)])]),_:1}),a(r,{value:"cpu"},{default:i(()=>[...t[17]||(t[17]=[p("cpu",-1)])]),_:1}),a(r,{value:"cuda"},{default:i(()=>[...t[18]||(t[18]=[p("cuda",-1)])]),_:1})]),_:1},8,["value","disabled"])]),_:1},8,["label"]),a(f,{label:e.t("speechSettings.whisperLocal.timeoutLabel")},{default:i(()=>[a(L,{value:e.form.whisperLocal.timeout,"onUpdate:value":t[10]||(t[10]=n=>e.form.whisperLocal.timeout=n),min:1e3,max:6e5,step:1e3,style:{width:"200px"},disabled:e.saving},null,8,["value","disabled"])]),_:1},8,["label"])]),_:1})]),_:1})):N("v-if",!0),b("div",re,[a(o,{onClick:e.resetForm,disabled:e.saving||e.loading},{default:i(()=>[p(c(e.t("speechSettings.buttons.reset")),1)]),_:1},8,["disabled"]),a(o,{type:"primary",loading:e.saving,disabled:!e.isDirty,onClick:e.saveConfig},{default:i(()=>[p(c(e.t("speechSettings.buttons.save")),1)]),_:1},8,["loading","disabled"]),e.isDirty?(O(),j("span",de,c(e.t("speechSettings.dirtyHint")),1)):N("v-if",!0)])]),_:1},8,["spinning"])])}const ue=Q($,[["render",pe],["__scopeId","data-v-2b18ccaa"],["__file","/tmp/cc-web-panel-4d4NxJ/repo/packages/web-panel/src/views/SpeechSettings.vue"]]);export{ue 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-C2k8eHyq.js";import{I as z,J as x,U as _,Q as D,S as Q,K as T,V as R,c as A,F as Y,Z,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-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 B(t){await q();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 K of v)m.write(K.data),t.lastSeq=K.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 J(){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 J()}),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 X={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:B,onCreate:re,onClose:se,removeSession:W,activate:le,refreshList:J,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(X,"__isScriptSetup",{enumerable:!1,value:!0}),X}},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(),Q(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(),Q(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(Y,null,Z(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(Y,null,Z(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 Fe=me(Se,[["render",Be],["__scopeId","data-v-65366a29"],["__file","/tmp/cc-web-panel-4d4NxJ/repo/packages/web-panel/src/views/Terminal.vue"]]);export{Fe as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{Q as r}from"./index-C2k8eHyq.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-B6cVbPbJ.js";import{a0 as t}from"./index-C2k8eHyq.js";import"./vendor-Bn1JzzAn.js";import"./responsiveObserve-Dy_adDTl.js";import"./useFlexGapSupport-vfoXaeH8.js";import"./styleChecker-DAv9eo6h.js";import"./index-DpPv8zeU.js";import"./icons-DG5UD-6K.js";const l=t(o);export{l as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{C as o}from"./Col-Dtu6Frtj.js";import{a0 as t}from"./index-C2k8eHyq.js";import"./vendor-Bn1JzzAn.js";import"./index-DpPv8zeU.js";import"./icons-DG5UD-6K.js";const s=t(o);export{s as default};
|