chainlesschain 0.162.158 → 0.162.160
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/README.md +1 -1
- package/package.json +1 -1
- package/src/assets/web-panel/assets/{AIOps-BwpTJTN_.js → AIOps-CkRHjW8e.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-BtQOoo3l.js → ActionButton-BP3MeNi2.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-Duf_rXZa.js → Analytics-CjbjQsOr.js} +2 -2
- package/src/assets/web-panel/assets/{AppLayout-XQK3wjvB.js → AppLayout-i0adH1M8.js} +5 -5
- package/src/assets/web-panel/assets/Artifacts-CCCG2GOU.js +1 -0
- package/src/assets/web-panel/assets/{Audit-DNjOGQLh.js → Audit-DrsgvwHC.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-FH9RAfB5.js → BackgroundAgents-DkXNkbZM.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-ZIbrR4-U.js → Backup-DarTWCex.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-DSt3NaND.js → BaseInput-DaDzhcto.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-CY-wvbjv.js → Chat-C4EzGw6V.js} +5 -5
- package/src/assets/web-panel/assets/ChatBubbleRenderer-lkavIWMS.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-8JVadE_B.js → Checkbox-gddNgaQi.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-CN83nPYI.js → Codegen-BKldFWf9.js} +1 -1
- package/src/assets/web-panel/assets/{Col-xPSvqdN8.js → Col-ChR-brDs.js} +1 -1
- package/src/assets/web-panel/assets/{Community-D78cnIjG.js → Community-DlHtZX86.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-CSw6Csbp.js → Compact-BAhfcBpC.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-E_HhjcYR.js → Compliance-gIrKkm6m.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-DybeQjmm.js → Cowork-BYnzLBO3.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-DS0BJeLY.js → Cron-ByUDIljI.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-BOwVgkbs.js → Crosschain-DOdNbHFp.js} +1 -1
- package/src/assets/web-panel/assets/{DID-DRUr9YuX.js → DID-BJHaNWD2.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-Cht-yUKW.js → Dashboard-Drm_tClz.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-BLr_EJ9X.js → Dropdown-CA1WLzGN.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-Drexuh5W.js → EmailListRenderer-Di1SKjNO.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-D9Q2Kq63.js → FamilyGuardDashboard-44Ve7ZFe.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-C-Z1xI-T.js → Federation-CubPwv_N.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-DLHPMkQF.js → FormItemContext-CsUFe5bU.js} +1 -1
- package/src/assets/web-panel/assets/GenericCardRenderer-D7xRjPjZ.js +1 -0
- package/src/assets/web-panel/assets/{Git-syATcaBt.js → Git-D-Qx9dhO.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-CYe_r8Zf.js → Governance-_YMYaU4n.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-GWxErB7k.js → Inference-J7Yzh-K_.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-qQvVCZoi.js → KnowledgeGraph-D37iI_Mo.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BenAU2W8.js → Logs-oMTSYfGY.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-7agE3Or1.js → MarkdownRenderer-BqaPmC0W.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-D4Jn5fpD.js → Marketplace-DKUqYDaF.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DtAwoqiQ.js → McpTools-BEv3Gx61.js} +4 -4
- package/src/assets/web-panel/assets/{Memory-BI_O50I8.js → Memory-CtA8XD2y.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-CQWE2lqx.js → MobileBridge-ug7c1mMj.js} +1 -1
- package/src/assets/web-panel/assets/MobileProjects-BpX5g9It.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-Dnr16qsn.js → Mtc-WJaMs4i2.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-CQ5Xe4-a.js → MtcAudit-DXnK_-ru.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-Bjr8O-wy.js → Multisig-C4Ev7726.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-CEe-KirU.js → NLProgramming-BMFb9_zk.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-spKJIKF9.js → Notes-Bl93nvBX.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-DRp83LFG.js → NotificationSettings-BN2W5cl6.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-h1A0XB2a.js → OrderTableRenderer-Dxc9oN4o.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-BlgB0IYg.js → Organization-CAs48637.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-a_35HqZI.js → Overflow-Bhq27Zoc.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-CSNHCNPC.js → P2P-D61-2542.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-C8M1JH-1.js → PdhVaultBrowser-C1j4iUxz.js} +5 -5
- package/src/assets/web-panel/assets/{Permissions-DmjJi9Ms.js → Permissions-rJ2-fScM.js} +3 -3
- package/src/assets/web-panel/assets/{PersonalDataHub-DfuwRyf4.js → PersonalDataHub-DFIlTok6.js} +2 -2
- package/src/assets/web-panel/assets/{Pipeline-B2-S4ekE.js → Pipeline-BjIgEWoZ.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-B1dOiBLC.js → Privacy-BQoH5wcX.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-_pNmc-DX.js → ProjectInit-CYR_-_Ub.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-DmwG2Ii1.js → ProjectSettings-nkatCq-9.js} +2 -2
- package/src/assets/web-panel/assets/Projects-SS9uZKCl.js +1 -0
- package/src/assets/web-panel/assets/{Providers-C6HSjg1d.js → Providers-BnKM9fsF.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-CrDmS7l1.js → QrScannerModal-Cfe82dbz.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-CfKvWt-x.js → QuickAsk-r1RbPufV.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-DMa6Kuzv.js → Recommend-CjCbM2WE.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-DrktUo5x.js → RemoteSession-BuMGPH6V.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-BTPQ1vjL.js → Reputation-Bmj3NY1F.js} +1 -1
- package/src/assets/web-panel/assets/{Row-B6Q7QkMG.js → Row-BIsNcE_1.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-B1IJhAmX.js → RssFeed-BObmojD2.js} +3 -3
- package/src/assets/web-panel/assets/{Search-xbea1kGD.js → Search-BRmbkQNS.js} +1 -1
- package/src/assets/web-panel/assets/{Security-7rs0cO3F.js → Security-_rF3DRpY.js} +2 -2
- package/src/assets/web-panel/assets/{Services-0fjixK0S.js → Services-D0If9ZV4.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-B_rVq9Cu.js → Skeleton-o7zIksUg.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-C5uM90b9.js → Skills-oUR7zi9u.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-U4pYCIZH.js → Sla-fqKyGi03.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-Cdz4yTWx.js → SpeechSettings-B1wZ_gxx.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-Me3aetHv.js → SyncSettings-B3qJWYXq.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-Cf6aNkL_.js → Tasks-BH5_dUfr.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-CYatk4tU.js → Templates-CCIVpjRP.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-DIMKLw7o.js → Tenant-2GZtTGnB.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-C_cp-uSJ.js → Terminal-BlMkfs_u.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-cUPVNADp.js → TimelineRenderer-U6hi5OMc.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-CiaEIXVf.js → Tokens-C-_BerGJ.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-DB1WU5lQ.js → Trigger-DaKzBgN3.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-Cfht9Ijy.js → Trust-CLvcsco3.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-K3P4Vt9S.js → UkeySign-BFn_Y1zZ.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-DWjhjXRh.js → VideoEditing-B0V18dLT.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-D9-Q1Kan.js → Wallet-BbmP7Imu.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-BDszy-oV.js → WebAuthn-Dewj_0kt.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-DIhij4rA.js → WorkflowEditor-DOxz3Lwa.js} +1 -1
- package/src/assets/web-panel/assets/{chat-D7VCiKbh.js → chat-B1OIpZnh.js} +1 -1
- package/src/assets/web-panel/assets/{colors-BvOd9pVn.js → colors-CSGNVdri.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-DoqXBiAO.js → compact-item-8S0vcg0u.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-CrKRzUtp.js → createContext-vZyc27TN.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-DYEZcY55.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-BWAev4WC.js → hasIn-DWw3-UhA.js} +1 -1
- package/src/assets/web-panel/assets/{index-DvDOpsJB.js → index-B4pP2ycr.js} +1 -1
- package/src/assets/web-panel/assets/{index-oY45XrkG.js → index-BDHyovnK.js} +1 -1
- package/src/assets/web-panel/assets/{index-CmJ6xKBO.js → index-BKEmQQvR.js} +1 -1
- package/src/assets/web-panel/assets/{index-BoYrS_L2.js → index-BQssf0EQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-ww1QtLnX.js → index-BZnauCqN.js} +1 -1
- package/src/assets/web-panel/assets/{index-BWWsaimP.js → index-BdyokEau.js} +1 -1
- package/src/assets/web-panel/assets/{index-CoD31Ndm.js → index-BeBv896m.js} +1 -1
- package/src/assets/web-panel/assets/{index-DlGu7As6.js → index-BjC-TrOb.js} +1 -1
- package/src/assets/web-panel/assets/{index-zH-tuuGZ.js → index-BkWd6YL7.js} +1 -1
- package/src/assets/web-panel/assets/{index-CEXfKSiI.js → index-BoIPHP4R.js} +1 -1
- package/src/assets/web-panel/assets/{index-CEPHMSih.js → index-BuB5P0TR.js} +1 -1
- package/src/assets/web-panel/assets/{index-PDxGjKRu.js → index-BwKrTVV0.js} +1 -1
- package/src/assets/web-panel/assets/{index-BkgnGX7v.js → index-C6r27A-o.js} +1 -1
- package/src/assets/web-panel/assets/{index-DV-Rfmfx.js → index-CB2MOS_8.js} +3 -3
- package/src/assets/web-panel/assets/{index-KR1-Em9C.js → index-CFQWZvak.js} +1 -1
- package/src/assets/web-panel/assets/{index-8g5TJCZ3.js → index-CI3slBKI.js} +1 -1
- package/src/assets/web-panel/assets/{index-BCyP071m.js → index-CJgKP2cm.js} +1 -1
- package/src/assets/web-panel/assets/{index-CSb-tnIo.js → index-CLPr2vC_.js} +1 -1
- package/src/assets/web-panel/assets/{index-1poMpMU0.js → index-CbZqw7pg.js} +1 -1
- package/src/assets/web-panel/assets/{index-BZGk8AbZ.js → index-CfEvacz7.js} +1 -1
- package/src/assets/web-panel/assets/{index-BXyl8O23.js → index-CwXBblm-.js} +1 -1
- package/src/assets/web-panel/assets/{index-BHOcVYrx.js → index-D1i_8oop.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bq_ctRpz.js → index-D8qXVfoV.js} +1 -1
- package/src/assets/web-panel/assets/{index-gmxqu5Kk.js → index-DKwl1AkQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-D23L1V76.js → index-DLAvUtOH.js} +1 -1
- package/src/assets/web-panel/assets/{index-CDGLdn12.js → index-DLgkAhEE.js} +1 -1
- package/src/assets/web-panel/assets/{index-YGDy7nNq.js → index-DPgY5GLy.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cx7M7PSF.js → index-Dc40pX3F.js} +1 -1
- package/src/assets/web-panel/assets/{index-JzUmJMvn.js → index-DcfLXAW7.js} +1 -1
- package/src/assets/web-panel/assets/{index-HwHdTusY.js → index-DeCS12Mh.js} +1 -1
- package/src/assets/web-panel/assets/{index-B30NvR21.js → index-Dg0Izipr.js} +1 -1
- package/src/assets/web-panel/assets/index-DmVFfcNR.js +1 -0
- package/src/assets/web-panel/assets/{index-B0vGEbJT.js → index-DtHWHJnj.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bf9YlbDn.js → index-Q6oyLnKC.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bj7EgmOp.js → index-dxocDVD_.js} +1 -1
- package/src/assets/web-panel/assets/{index-ISvPZ05r.js → index-t-q3rkVm.js} +1 -1
- package/src/assets/web-panel/assets/{index-C5kRmj3P.js → index-tr1x96W9.js} +1 -1
- package/src/assets/web-panel/assets/index-x7YyhMUa.js +1 -0
- package/src/assets/web-panel/assets/{index-BN9m4Ux2.js → index-xx5M5Rbj.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-XW-OR3mL.js → initDefaultProps-Di5YFId0.js} +1 -1
- package/src/assets/web-panel/assets/{motion-CeuEHh20.js → motion-BVSN0aeL.js} +1 -1
- package/src/assets/web-panel/assets/{move-Dva79Keg.js → move-DHNiaP2l.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-C0B6bD2j.js → mtc-parser-xJPf3gQD.js} +1 -1
- package/src/assets/web-panel/assets/{omit-AkZvO-a2.js → omit-C7qzUdkN.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-B4r55qGc.js → pickAttrs-pSpjg3Le.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-BLH-z7YE.js → placementArrow-cs_jL_UC.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-ksEGZ2Wf.js → responsiveObserve-DkS_Zs4r.js} +1 -1
- package/src/assets/web-panel/assets/{slide-Cth4OD1Z.js → slide-B5O1Kpxo.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-9S83ezxw.js → statusUtils-BX02GnZp.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-7yQmQGZ4.js → styleChecker-EmBYRftd.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-DpGnMmPc.js → useFlexGapSupport-ZGzN1cU8.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-C4zDZIXH.js → useFs-CfP7M1m7.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-CoLICdUZ.js → usePersonalDataHub-CbIPHgNh.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-CKyH-35X.js → vnode-7xh0If_O.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-DRDGit17.js → zoom-DmitvTR2.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-manifest.json +17 -3
- package/src/commands/agent.js +72 -6
- package/src/commands/background-session.js +173 -3
- package/src/commands/browse.js +86 -0
- package/src/commands/cloud.js +232 -0
- package/src/commands/doctor.js +61 -6
- package/src/commands/mcp.js +107 -0
- package/src/commands/plugin.js +63 -1
- package/src/commands/routine.js +367 -0
- package/src/commands/session.js +396 -0
- package/src/data/changelog.json +12 -2
- package/src/harness/jsonl-session-store.js +152 -3
- package/src/harness/mcp-client.js +50 -0
- package/src/harness/session-index.js +295 -0
- package/src/harness/session-mirror.js +142 -0
- package/src/harness/transcript-integrity.js +182 -0
- package/src/index.js +8 -0
- package/src/lib/agent-sandbox.js +68 -0
- package/src/lib/agents.js +12 -4
- package/src/lib/api-key-helper.js +62 -0
- package/src/lib/background-agent-supervisor.js +158 -2
- package/src/lib/channels/channel-manager.js +126 -0
- package/src/lib/channels/telegram-channel.js +112 -0
- package/src/lib/channels/webhook-channel.js +140 -0
- package/src/lib/chrome-connector.js +386 -0
- package/src/lib/cloud/bundle.js +110 -0
- package/src/lib/cloud/cloud-client.js +152 -0
- package/src/lib/computer-use/authorization.js +173 -0
- package/src/lib/computer-use/computer-use-server.js +276 -0
- package/src/lib/computer-use/control-backend.js +150 -0
- package/src/lib/dependency-install-policy.js +130 -0
- package/src/lib/doctor-checkup.js +652 -0
- package/src/lib/exit-codes.cjs +77 -0
- package/src/lib/headless-manifest.js +175 -0
- package/src/lib/hook-runner.cjs +70 -4
- package/src/lib/ide-context-redaction.js +130 -0
- package/src/lib/ide-context.js +89 -13
- package/src/lib/jsonl-session-store.js +6 -0
- package/src/lib/llm-config-defaults.js +24 -8
- package/src/lib/lsp/lsp-server-registry.js +48 -21
- package/src/lib/plugin-runtime/governance.js +174 -0
- package/src/lib/pr-link-ledger.js +221 -0
- package/src/lib/project-mcp-trust.js +87 -0
- package/src/lib/routine-store.js +352 -0
- package/src/lib/sensitive-file-guard.js +51 -0
- package/src/lib/session-store-guard.js +40 -0
- package/src/lib/session-usage.js +318 -2
- package/src/lib/sub-agent-context.js +30 -3
- package/src/repl/agent-repl.js +361 -3
- package/src/repl/bg-dashboard.js +355 -0
- package/src/repl/fast-mode.js +103 -0
- package/src/repl/fullscreen-tui.js +197 -0
- package/src/repl/slash-command-registry.js +11 -3
- package/src/repl/voice-dictation.js +132 -0
- package/src/runtime/agent-core.js +344 -7
- package/src/runtime/coding-agent-contract-shared.cjs +107 -2
- package/src/runtime/coding-agent-policy.cjs +17 -0
- package/src/runtime/headless-runner.js +137 -14
- package/src/runtime/headless-stream.js +43 -9
- package/src/runtime/mcp-config.js +32 -1
- package/src/runtime/policies/agent-policy.js +3 -0
- package/src/assets/web-panel/assets/Artifacts-DQvJoQ6E.js +0 -1
- package/src/assets/web-panel/assets/ChatBubbleRenderer-BAV9V-t-.js +0 -1
- package/src/assets/web-panel/assets/GenericCardRenderer-DxxEdn2r.js +0 -1
- package/src/assets/web-panel/assets/MobileProjects-CVtTqgtg.js +0 -1
- package/src/assets/web-panel/assets/Projects-COATmHxF.js +0 -1
- package/src/assets/web-panel/assets/devWarning-nDB--2xr.js +0 -1
- package/src/assets/web-panel/assets/index-B1_pRTtB.js +0 -1
- package/src/assets/web-panel/assets/index-TMM9FuW-.js +0 -1
|
@@ -521,7 +521,7 @@ const CODING_AGENT_TOOL_CONTRACTS = Object.freeze([
|
|
|
521
521
|
kind: "code",
|
|
522
522
|
tier: "extension",
|
|
523
523
|
description:
|
|
524
|
-
"Write and execute code in Python, Node.js, or Bash. Use this when the user needs data processing, calculations, file batch operations, API calls, or any task best solved with a script. Scripts
|
|
524
|
+
"Write and execute code in Python, Node.js, or Bash. Use this when the user needs data processing, calculations, file batch operations, API calls, or any task best solved with a script. Scripts run from a temp file unless persist:true. Missing Python packages are NOT auto-installed unless the user opted in (settings runCode.autoInstall).",
|
|
525
525
|
inputSchema: {
|
|
526
526
|
type: "object",
|
|
527
527
|
properties: {
|
|
@@ -538,7 +538,7 @@ const CODING_AGENT_TOOL_CONTRACTS = Object.freeze([
|
|
|
538
538
|
persist: {
|
|
539
539
|
type: "boolean",
|
|
540
540
|
description:
|
|
541
|
-
"If true
|
|
541
|
+
"If true, save the script in .chainlesschain/agent-scripts/ for reference. Default false: run from a temp file outside the project.",
|
|
542
542
|
},
|
|
543
543
|
},
|
|
544
544
|
required: ["language", "code"],
|
|
@@ -599,6 +599,23 @@ const CODING_AGENT_TOOL_CONTRACTS = Object.freeze([
|
|
|
599
599
|
description:
|
|
600
600
|
"Run the sub-agent in the BACKGROUND: the call returns immediately with a running handle and you continue working; the sub-agent's result is delivered to you automatically in a later turn (the run waits for stragglers before finishing). Use for independent subtasks you don't need before your next step.",
|
|
601
601
|
},
|
|
602
|
+
disallowedTools: {
|
|
603
|
+
type: "array",
|
|
604
|
+
items: { type: "string" },
|
|
605
|
+
description:
|
|
606
|
+
"Optional tool DENY-list for the sub-agent: these are removed from whatever tool set it would otherwise get (explicit `tools`, agent-file allowlist, or all).",
|
|
607
|
+
},
|
|
608
|
+
maxTurns: {
|
|
609
|
+
type: "number",
|
|
610
|
+
description:
|
|
611
|
+
"Optional iteration cap for the sub-agent's own loop (positive integer; default 8 or the profile's cap).",
|
|
612
|
+
},
|
|
613
|
+
isolation: {
|
|
614
|
+
type: "string",
|
|
615
|
+
enum: ["worktree"],
|
|
616
|
+
description:
|
|
617
|
+
"Optional isolation mode: \"worktree\" runs the sub-agent in a fresh git worktree so its file edits land on an isolated branch (diff/merge summary comes back with the result).",
|
|
618
|
+
},
|
|
602
619
|
},
|
|
603
620
|
required: ["task"],
|
|
604
621
|
},
|
|
@@ -1058,6 +1075,94 @@ const CODING_AGENT_TOOL_CONTRACTS = Object.freeze([
|
|
|
1058
1075
|
tags: ["tool:browser_state", "contract:coding-agent", "tier:extension"],
|
|
1059
1076
|
},
|
|
1060
1077
|
},
|
|
1078
|
+
{
|
|
1079
|
+
name: "browser_act",
|
|
1080
|
+
title: "Browser Actions",
|
|
1081
|
+
kind: "browser",
|
|
1082
|
+
tier: "extension",
|
|
1083
|
+
description:
|
|
1084
|
+
"Perform EXPLICIT actions in the user's connected Chrome over loopback CDP: click, type, press, navigate (http/https only), waitForSelector, screenshot (saved to a generated temp path — never a chosen one), assertText. Approval-gated (HIGH risk): use browser_state first to observe; only act when the task genuinely requires driving the browser. Steps run in order and fail fast unless continue_on_error; each returns {ok, action, detail, durationMs} and every executed step is audit-logged under ~/.chainlesschain/browser-actions/. Requires a debuggable Chrome (`cc browse chrome launch`).",
|
|
1085
|
+
inputSchema: {
|
|
1086
|
+
type: "object",
|
|
1087
|
+
properties: {
|
|
1088
|
+
actions: {
|
|
1089
|
+
type: "array",
|
|
1090
|
+
description:
|
|
1091
|
+
"Ordered action steps. Each item: {type: click|type|press|navigate|waitForSelector|screenshot|assertText} plus its fields — click/waitForSelector/assertText need selector; type needs selector+text; press needs key; navigate needs url (http/https); waitForSelector accepts timeout_ms (capped 30000); assertText needs expected (substring); screenshot takes NO path (generated internally).",
|
|
1092
|
+
items: {
|
|
1093
|
+
type: "object",
|
|
1094
|
+
properties: {
|
|
1095
|
+
type: {
|
|
1096
|
+
type: "string",
|
|
1097
|
+
enum: [
|
|
1098
|
+
"click",
|
|
1099
|
+
"type",
|
|
1100
|
+
"press",
|
|
1101
|
+
"navigate",
|
|
1102
|
+
"waitForSelector",
|
|
1103
|
+
"screenshot",
|
|
1104
|
+
"assertText",
|
|
1105
|
+
],
|
|
1106
|
+
description: "Action kind",
|
|
1107
|
+
},
|
|
1108
|
+
selector: {
|
|
1109
|
+
type: "string",
|
|
1110
|
+
description:
|
|
1111
|
+
"CSS selector (click/type/waitForSelector/assertText)",
|
|
1112
|
+
},
|
|
1113
|
+
text: { type: "string", description: "Text to type (type)" },
|
|
1114
|
+
key: {
|
|
1115
|
+
type: "string",
|
|
1116
|
+
description: "Key to press, e.g. Enter (press)",
|
|
1117
|
+
},
|
|
1118
|
+
url: {
|
|
1119
|
+
type: "string",
|
|
1120
|
+
description: "http(s):// URL to open (navigate)",
|
|
1121
|
+
},
|
|
1122
|
+
timeout_ms: {
|
|
1123
|
+
type: "number",
|
|
1124
|
+
description:
|
|
1125
|
+
"waitForSelector timeout in ms (default 5000, max 30000)",
|
|
1126
|
+
},
|
|
1127
|
+
expected: {
|
|
1128
|
+
type: "string",
|
|
1129
|
+
description: "Expected substring (assertText)",
|
|
1130
|
+
},
|
|
1131
|
+
},
|
|
1132
|
+
required: ["type"],
|
|
1133
|
+
},
|
|
1134
|
+
},
|
|
1135
|
+
cdp_url: {
|
|
1136
|
+
type: "string",
|
|
1137
|
+
description:
|
|
1138
|
+
"CDP endpoint — loopback-only, e.g. http://127.0.0.1:9222 (default port 9222)",
|
|
1139
|
+
},
|
|
1140
|
+
port: {
|
|
1141
|
+
type: "number",
|
|
1142
|
+
description: "CDP port of the debuggable Chrome (default 9222)",
|
|
1143
|
+
},
|
|
1144
|
+
tab: {
|
|
1145
|
+
type: "number",
|
|
1146
|
+
description: "Tab index to act in (default 0)",
|
|
1147
|
+
},
|
|
1148
|
+
continue_on_error: {
|
|
1149
|
+
type: "boolean",
|
|
1150
|
+
description:
|
|
1151
|
+
"Keep executing remaining steps after a failed one (default false: fail fast)",
|
|
1152
|
+
},
|
|
1153
|
+
},
|
|
1154
|
+
required: ["actions"],
|
|
1155
|
+
},
|
|
1156
|
+
...TOOL_POLICY_METADATA.browser_act,
|
|
1157
|
+
permissions: {
|
|
1158
|
+
level: "elevated",
|
|
1159
|
+
scopes: ["browser:act"],
|
|
1160
|
+
},
|
|
1161
|
+
telemetry: {
|
|
1162
|
+
category: "browser",
|
|
1163
|
+
tags: ["tool:browser_act", "contract:coding-agent", "tier:extension"],
|
|
1164
|
+
},
|
|
1165
|
+
},
|
|
1061
1166
|
]);
|
|
1062
1167
|
|
|
1063
1168
|
const CODING_AGENT_MVP_TOOL_NAMES = Object.freeze(
|
|
@@ -320,6 +320,23 @@ const TOOL_POLICY_METADATA = Object.freeze({
|
|
|
320
320
|
approvalFlow: "auto",
|
|
321
321
|
isReadOnly: true,
|
|
322
322
|
},
|
|
323
|
+
// DRIVES the user's connected Chrome over loopback CDP — clicks, typing,
|
|
324
|
+
// key presses, navigation, screenshots, text assertions. Unlike
|
|
325
|
+
// browser_state (pure observation, the default) this mutates the page and
|
|
326
|
+
// acts inside whatever session that browser is logged into, so it carries
|
|
327
|
+
// the same gating as run_shell/run_code: HIGH risk (the ApprovalGate
|
|
328
|
+
// CONFIRMs HIGH even on the trusted/auto tier, so auto mode still prompts),
|
|
329
|
+
// blocked in plan mode, plan approval + explicit confirmation required.
|
|
330
|
+
browser_act: {
|
|
331
|
+
riskLevel: RISK_LEVELS.HIGH,
|
|
332
|
+
category: TOOL_CATEGORIES.EXECUTE,
|
|
333
|
+
availableInPlanMode: false,
|
|
334
|
+
planModeBehavior: "blocked",
|
|
335
|
+
requiresPlanApproval: true,
|
|
336
|
+
requiresConfirmation: true,
|
|
337
|
+
approvalFlow: "policy",
|
|
338
|
+
isReadOnly: false,
|
|
339
|
+
},
|
|
323
340
|
});
|
|
324
341
|
|
|
325
342
|
function normalizeGitCommand(command) {
|
|
@@ -42,16 +42,30 @@ import {
|
|
|
42
42
|
appendUserMessage as jsonlAppendUserMessage,
|
|
43
43
|
appendAssistantMessage as jsonlAppendAssistantMessage,
|
|
44
44
|
appendTokenUsage as jsonlAppendTokenUsage,
|
|
45
|
+
appendToolCallCompact as jsonlAppendToolCallCompact,
|
|
45
46
|
appendCompactEvent as jsonlAppendCompactEvent,
|
|
46
47
|
rebuildMessages as jsonlRebuildMessages,
|
|
47
48
|
sessionExists as jsonlSessionExists,
|
|
48
49
|
getLastSessionId as jsonlGetLastSessionId,
|
|
50
|
+
verifySession as jsonlVerifySession,
|
|
49
51
|
} from "../harness/jsonl-session-store.js";
|
|
50
52
|
import { expandFileRefsAsync } from "./file-ref-expander.js";
|
|
51
53
|
import { composeSystemPrompt } from "./system-prompt.js";
|
|
52
54
|
import { buildUserContent } from "../lib/image-input.js";
|
|
53
55
|
import { mergeConsecutiveMessages } from "./message-roles.js";
|
|
54
56
|
import { isHeadlessConfigCommand } from "../lib/headless-config-command.js";
|
|
57
|
+
import {
|
|
58
|
+
STREAM_PROTOCOL_VERSION,
|
|
59
|
+
computePolicyDigest,
|
|
60
|
+
computeToolsHash,
|
|
61
|
+
buildLoadedSources,
|
|
62
|
+
} from "../lib/headless-manifest.js";
|
|
63
|
+
import {
|
|
64
|
+
HEADLESS_EXIT_CODES,
|
|
65
|
+
classifyLoopError,
|
|
66
|
+
exitCodeForEndReason,
|
|
67
|
+
} from "../lib/exit-codes.cjs";
|
|
68
|
+
import { isolationLevel } from "../lib/agent-sandbox.js";
|
|
55
69
|
import { withQuietStdout } from "./quiet-stdout.js";
|
|
56
70
|
import { CostBudget } from "../lib/cost-budget.js";
|
|
57
71
|
import {
|
|
@@ -198,13 +212,18 @@ export function parseToolList(value) {
|
|
|
198
212
|
* Persistence is intentionally OFF unless a resume/continue/persist intent is
|
|
199
213
|
* present, so a plain one-shot `cc agent -p "..."` writes nothing to disk.
|
|
200
214
|
*
|
|
201
|
-
*
|
|
215
|
+
* `--ephemeral` forces persistence OFF regardless of the above: a resume id
|
|
216
|
+
* still REPLAYS prior history into context, but nothing new is written — the
|
|
217
|
+
* deterministic-CI shape ("read context, leave no trace").
|
|
218
|
+
*
|
|
219
|
+
* @param {object} options { resume, continueSession, sessionId, persistSession, ephemeral }
|
|
202
220
|
* @param {object} store { getLastSessionId } (injection seam)
|
|
203
221
|
* @param {string} fallbackId used when nothing is being resumed
|
|
204
222
|
* @returns {{ sessionId:string, resumeId:string|null, persist:boolean, wantLatest:boolean }}
|
|
205
223
|
*/
|
|
206
224
|
export function resolveHeadlessSession(options = {}, store = {}, fallbackId) {
|
|
207
|
-
const { resume, continueSession, sessionId, persistSession } =
|
|
225
|
+
const { resume, continueSession, sessionId, persistSession, ephemeral } =
|
|
226
|
+
options;
|
|
208
227
|
const wantLatest = continueSession === true || resume === true;
|
|
209
228
|
let resumeId = null;
|
|
210
229
|
if (wantLatest) {
|
|
@@ -215,7 +234,10 @@ export function resolveHeadlessSession(options = {}, store = {}, fallbackId) {
|
|
|
215
234
|
} else if (typeof resume === "string" && resume.trim()) {
|
|
216
235
|
resumeId = resume.trim();
|
|
217
236
|
}
|
|
218
|
-
const persist =
|
|
237
|
+
const persist =
|
|
238
|
+
ephemeral === true
|
|
239
|
+
? false
|
|
240
|
+
: persistSession === true || resumeId != null || wantLatest;
|
|
219
241
|
const id = resumeId || sessionId || fallbackId;
|
|
220
242
|
return { sessionId: id, resumeId, persist, wantLatest };
|
|
221
243
|
}
|
|
@@ -436,8 +458,11 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
436
458
|
appendAssistantMessage:
|
|
437
459
|
deps.appendAssistantMessage || jsonlAppendAssistantMessage,
|
|
438
460
|
appendTokenUsage: deps.appendTokenUsage || jsonlAppendTokenUsage,
|
|
461
|
+
appendToolCallCompact:
|
|
462
|
+
deps.appendToolCallCompact || jsonlAppendToolCallCompact,
|
|
439
463
|
appendCompactEvent: deps.appendCompactEvent || jsonlAppendCompactEvent,
|
|
440
464
|
getLastSessionId: deps.getLastSessionId || jsonlGetLastSessionId,
|
|
465
|
+
verifySession: deps.verifySession || jsonlVerifySession,
|
|
441
466
|
};
|
|
442
467
|
const isStream = outputFormat === "stream-json";
|
|
443
468
|
const isJson = outputFormat === "json";
|
|
@@ -626,6 +651,30 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
626
651
|
// never duplicated.
|
|
627
652
|
let history = [];
|
|
628
653
|
if (resumeId && store.sessionExists(resumeId)) {
|
|
654
|
+
// Tamper gate: a broken transcript hash chain means the file was edited
|
|
655
|
+
// outside the store. Headless runs fail closed — a tampered transcript is
|
|
656
|
+
// never silently rebuilt into trusted model context. Escape hatch:
|
|
657
|
+
// CC_ALLOW_TAMPERED_RESUME=1 resumes with a stderr warning.
|
|
658
|
+
let trust = null;
|
|
659
|
+
try {
|
|
660
|
+
trust = store.verifySession(resumeId);
|
|
661
|
+
} catch {
|
|
662
|
+
trust = null; // verification unavailable → keep legacy behaviour
|
|
663
|
+
}
|
|
664
|
+
if (trust && trust.status === "tampered") {
|
|
665
|
+
if (process.env.CC_ALLOW_TAMPERED_RESUME !== "1") {
|
|
666
|
+
const msg =
|
|
667
|
+
`Session ${resumeId} transcript failed integrity verification (${trust.reason}` +
|
|
668
|
+
(trust.firstInvalidLine ? ` at line ${trust.firstInvalidLine}` : "") +
|
|
669
|
+
`). Refusing to resume tampered context; run 'cc session verify ${resumeId}', or set CC_ALLOW_TAMPERED_RESUME=1 to override.`;
|
|
670
|
+
emitHeadlessError(msg);
|
|
671
|
+
writeErr(msg + "\n");
|
|
672
|
+
return { exitCode: 1, result: msg, isError: true };
|
|
673
|
+
}
|
|
674
|
+
writeErr(
|
|
675
|
+
`⚠ Resuming a TAMPERED transcript (${trust.reason}) — restored context is untrusted.\n`,
|
|
676
|
+
);
|
|
677
|
+
}
|
|
629
678
|
try {
|
|
630
679
|
history = (store.rebuildMessages(resumeId) || []).filter(
|
|
631
680
|
(m) => m && m.role !== "system",
|
|
@@ -871,7 +920,12 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
871
920
|
} catch (err) {
|
|
872
921
|
writeErr(`Error: ${err.message}\n`);
|
|
873
922
|
emitHeadlessError(err.message);
|
|
874
|
-
|
|
923
|
+
// Bad --mcp-config / MCP wiring is a CONFIG error, not a run failure.
|
|
924
|
+
return {
|
|
925
|
+
exitCode: HEADLESS_EXIT_CODES.CONFIG_ERROR,
|
|
926
|
+
result: err.message,
|
|
927
|
+
isError: true,
|
|
928
|
+
};
|
|
875
929
|
}
|
|
876
930
|
}
|
|
877
931
|
|
|
@@ -914,7 +968,12 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
914
968
|
writeErr(`Error: ${err.message}\n`);
|
|
915
969
|
if (mcp?.mcpClient) await mcp.mcpClient.disconnectAll().catch(() => {});
|
|
916
970
|
emitHeadlessError(err.message);
|
|
917
|
-
|
|
971
|
+
// A bad --permission-prompt-tool reference is a CONFIG error.
|
|
972
|
+
return {
|
|
973
|
+
exitCode: HEADLESS_EXIT_CODES.CONFIG_ERROR,
|
|
974
|
+
result: err.message,
|
|
975
|
+
isError: true,
|
|
976
|
+
};
|
|
918
977
|
}
|
|
919
978
|
if (approvalGate && typeof approvalGate.setConfirmer === "function") {
|
|
920
979
|
approvalGate.setConfirmer(
|
|
@@ -1114,6 +1173,12 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
1114
1173
|
cache_read_input_tokens: 0,
|
|
1115
1174
|
cache_creation_input_tokens: 0,
|
|
1116
1175
|
};
|
|
1176
|
+
// 用量归因: attributed child-loop usage (spawn_sub_agent / isolated
|
|
1177
|
+
// run_skill). Kept OUT of the `usage` accumulator above so the result
|
|
1178
|
+
// envelope and the end-of-run aggregate token_usage event keep their
|
|
1179
|
+
// long-standing "main loop only" semantics — the attributed records are
|
|
1180
|
+
// persisted as their own token_usage events instead (no double count).
|
|
1181
|
+
const attributedUsage = [];
|
|
1117
1182
|
let finalText = "";
|
|
1118
1183
|
let endReason = "complete";
|
|
1119
1184
|
let stopForCost = false;
|
|
@@ -1140,11 +1205,32 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
1140
1205
|
emitStream({
|
|
1141
1206
|
type: "system",
|
|
1142
1207
|
subtype: "init",
|
|
1208
|
+
// Deterministic-headless manifest (gap-analysis 2026-07-11): protocol
|
|
1209
|
+
// version + persistence + live sources + policy/tool digests so CI can
|
|
1210
|
+
// assert the run shape. Mirrors agent-sdk PROTOCOL_VERSION.
|
|
1211
|
+
protocol_version: STREAM_PROTOCOL_VERSION,
|
|
1143
1212
|
session_id: sessionId,
|
|
1213
|
+
session_persistence: persist,
|
|
1144
1214
|
model,
|
|
1145
1215
|
provider,
|
|
1146
1216
|
permission_mode: options.permissionMode || "default",
|
|
1147
1217
|
tools: enabledToolNames,
|
|
1218
|
+
tools_hash: computeToolsHash(enabledToolNames),
|
|
1219
|
+
policy_digest: computePolicyDigest({
|
|
1220
|
+
permissionMode: options.permissionMode,
|
|
1221
|
+
allowedTools: options.allowedTools,
|
|
1222
|
+
disallowedTools: options.disallowedTools,
|
|
1223
|
+
permissionRules,
|
|
1224
|
+
}),
|
|
1225
|
+
loaded_sources: buildLoadedSources({
|
|
1226
|
+
permissionRules,
|
|
1227
|
+
settingsHooks,
|
|
1228
|
+
mcp: Boolean(mcp),
|
|
1229
|
+
enabledToolNames,
|
|
1230
|
+
}),
|
|
1231
|
+
// True isolation level for tool subprocesses: os-sandbox (bwrap) /
|
|
1232
|
+
// container (docker) / policy-only (no sandbox — rules are pre-execution).
|
|
1233
|
+
isolation_level: isolationLevel(options.sandbox),
|
|
1148
1234
|
max_turns: budget.limit,
|
|
1149
1235
|
resumed_from: resumeId,
|
|
1150
1236
|
history_messages: history.length,
|
|
@@ -1274,13 +1360,26 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
1274
1360
|
break;
|
|
1275
1361
|
}
|
|
1276
1362
|
case "token-usage": {
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1363
|
+
if (event.attribution) {
|
|
1364
|
+
// Child-loop (sub-agent / isolated-skill) spend: excluded from
|
|
1365
|
+
// the main `usage` envelope, persisted with its attribution
|
|
1366
|
+
// frame below, but still counted toward the cost budget — it
|
|
1367
|
+
// is real money on the same key.
|
|
1368
|
+
attributedUsage.push({
|
|
1369
|
+
provider: event.provider ?? null,
|
|
1370
|
+
model: event.model ?? null,
|
|
1371
|
+
usage: event.usage || null,
|
|
1372
|
+
attribution: event.attribution,
|
|
1373
|
+
});
|
|
1374
|
+
} else {
|
|
1375
|
+
usage.input_tokens += event.usage?.input_tokens || 0;
|
|
1376
|
+
usage.output_tokens += event.usage?.output_tokens || 0;
|
|
1377
|
+
// Carry prompt-cache tokens into accumulated usage (cost accuracy).
|
|
1378
|
+
usage.cache_read_input_tokens +=
|
|
1379
|
+
event.usage?.cache_read_input_tokens || 0;
|
|
1380
|
+
usage.cache_creation_input_tokens +=
|
|
1381
|
+
event.usage?.cache_creation_input_tokens || 0;
|
|
1382
|
+
}
|
|
1284
1383
|
emitStream({ type: "token_usage", usage: event.usage });
|
|
1285
1384
|
if (costBudget) {
|
|
1286
1385
|
costBudget.add({
|
|
@@ -1423,7 +1522,9 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
1423
1522
|
} else {
|
|
1424
1523
|
writeErr(`Error: ${message}\n`);
|
|
1425
1524
|
}
|
|
1426
|
-
|
|
1525
|
+
// Provider/transport failures get their own exit code (5) so CI can tell
|
|
1526
|
+
// "the model call failed" from "the run itself errored" (1).
|
|
1527
|
+
return { exitCode: classifyLoopError(err), result: message, isError: true };
|
|
1427
1528
|
} finally {
|
|
1428
1529
|
// Drop the signal handlers first — a normal return must not leave a
|
|
1429
1530
|
// process-wide SIGINT/SIGTERM listener behind (a later Ctrl-C would wrongly
|
|
@@ -1539,6 +1640,22 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
1539
1640
|
if (persist && !isError) {
|
|
1540
1641
|
try {
|
|
1541
1642
|
if (finalText) store.appendAssistantMessage(sessionId, finalText);
|
|
1643
|
+
// 用量归因: compact per-tool records (name + error flag + skill hint —
|
|
1644
|
+
// never args) so `cc session usage --by tool|mcp` can aggregate
|
|
1645
|
+
// headless sessions too.
|
|
1646
|
+
for (const tc of toolCalls) {
|
|
1647
|
+
store.appendToolCallCompact(sessionId, {
|
|
1648
|
+
tool: tc.tool,
|
|
1649
|
+
isError: Boolean(tc.is_error),
|
|
1650
|
+
skill:
|
|
1651
|
+
tc.tool === "run_skill" ? tc.args?.skill_name || null : undefined,
|
|
1652
|
+
});
|
|
1653
|
+
}
|
|
1654
|
+
// Attributed child-loop usage first (chronology: it happened during
|
|
1655
|
+
// the run), then the unchanged main-loop aggregate.
|
|
1656
|
+
for (const au of attributedUsage) {
|
|
1657
|
+
store.appendTokenUsage(sessionId, au);
|
|
1658
|
+
}
|
|
1542
1659
|
store.appendTokenUsage(sessionId, usage);
|
|
1543
1660
|
} catch {
|
|
1544
1661
|
// Persistence is best-effort — never fail the run over it.
|
|
@@ -1675,7 +1792,13 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
1675
1792
|
}
|
|
1676
1793
|
}
|
|
1677
1794
|
|
|
1678
|
-
|
|
1795
|
+
// Exit-code taxonomy: max-turns → 3, cost cap → 4 (both still non-zero, so
|
|
1796
|
+
// "any failure" checks keep working; scripts can now tell exhaustion apart).
|
|
1797
|
+
return {
|
|
1798
|
+
exitCode: exitCodeForEndReason(endReason, isError),
|
|
1799
|
+
result: finalText,
|
|
1800
|
+
isError,
|
|
1801
|
+
};
|
|
1679
1802
|
}
|
|
1680
1803
|
|
|
1681
1804
|
function buildResultEnvelope({
|
|
@@ -43,6 +43,12 @@ import {
|
|
|
43
43
|
makePermissionPromptConfirmer,
|
|
44
44
|
} from "./mcp-config.js";
|
|
45
45
|
import { maybeApplyToolSearch } from "./mcp-tool-search.js";
|
|
46
|
+
import {
|
|
47
|
+
STREAM_PROTOCOL_VERSION,
|
|
48
|
+
computePolicyDigest,
|
|
49
|
+
computeToolsHash,
|
|
50
|
+
buildLoadedSources,
|
|
51
|
+
} from "../lib/headless-manifest.js";
|
|
46
52
|
import { IterationBudget } from "../lib/iteration-budget.js";
|
|
47
53
|
import { CostBudget } from "../lib/cost-budget.js";
|
|
48
54
|
import {
|
|
@@ -494,14 +500,20 @@ async function runTurn(messages, loopOptions, { runLoop, emit, costBudget }) {
|
|
|
494
500
|
break;
|
|
495
501
|
}
|
|
496
502
|
case "token-usage":
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
//
|
|
500
|
-
//
|
|
501
|
-
|
|
502
|
-
event.usage?.
|
|
503
|
-
|
|
504
|
-
|
|
503
|
+
// 用量归因: attributed child-loop usage (sub-agent / isolated skill)
|
|
504
|
+
// is forwarded on the stream (same wire shape) and counted toward the
|
|
505
|
+
// cost budget, but stays out of the turn's `usage` envelope, which
|
|
506
|
+
// keeps its long-standing main-loop-only semantics.
|
|
507
|
+
if (!event.attribution) {
|
|
508
|
+
usage.input_tokens += event.usage?.input_tokens || 0;
|
|
509
|
+
usage.output_tokens += event.usage?.output_tokens || 0;
|
|
510
|
+
// Carry prompt-cache tokens into the turn's accumulated usage so the
|
|
511
|
+
// final `result` envelope (read by IDE panels) reflects caching too.
|
|
512
|
+
usage.cache_read_input_tokens +=
|
|
513
|
+
event.usage?.cache_read_input_tokens || 0;
|
|
514
|
+
usage.cache_creation_input_tokens +=
|
|
515
|
+
event.usage?.cache_creation_input_tokens || 0;
|
|
516
|
+
}
|
|
505
517
|
emit({ type: "token_usage", usage: event.usage });
|
|
506
518
|
if (costBudget) {
|
|
507
519
|
costBudget.add({
|
|
@@ -712,7 +724,9 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
712
724
|
deps.appendAssistantMessage || jsonlAppendAssistantMessage,
|
|
713
725
|
rebuildMessages: deps.rebuildMessages || jsonlRebuildMessages,
|
|
714
726
|
};
|
|
715
|
-
|
|
727
|
+
// --ephemeral forces persistence OFF even with an explicit session id (the
|
|
728
|
+
// id is kept for event correlation only; nothing is written or replayed).
|
|
729
|
+
const persist = Boolean(options.sessionId) && options.ephemeral !== true;
|
|
716
730
|
|
|
717
731
|
// ── Interactive approvals (--interactive-approvals; chat-panel UX) ────────
|
|
718
732
|
// CONFIRM-tier decisions (risky shell via the ApprovalGate, settings/hook
|
|
@@ -955,11 +969,31 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
955
969
|
emit({
|
|
956
970
|
type: "system",
|
|
957
971
|
subtype: "init",
|
|
972
|
+
// Deterministic-headless manifest (gap-analysis 2026-07-11): protocol
|
|
973
|
+
// version + persistence + live sources + policy/tool digests. The init
|
|
974
|
+
// event fires BEFORE MCP resolution here (stream consumers expect it
|
|
975
|
+
// promptly), so `mcp` in loaded_sources reflects the run's MCP intent
|
|
976
|
+
// (config file / registry auto-connect enabled), not connection outcome.
|
|
977
|
+
protocol_version: STREAM_PROTOCOL_VERSION,
|
|
958
978
|
session_id: sessionId,
|
|
979
|
+
session_persistence: persist,
|
|
959
980
|
model,
|
|
960
981
|
provider,
|
|
961
982
|
permission_mode: options.permissionMode || "default",
|
|
962
983
|
tools: enabledToolNames,
|
|
984
|
+
tools_hash: computeToolsHash(enabledToolNames),
|
|
985
|
+
policy_digest: computePolicyDigest({
|
|
986
|
+
permissionMode: options.permissionMode,
|
|
987
|
+
allowedTools: options.allowedTools,
|
|
988
|
+
disallowedTools: disabledTools,
|
|
989
|
+
permissionRules,
|
|
990
|
+
}),
|
|
991
|
+
loaded_sources: buildLoadedSources({
|
|
992
|
+
permissionRules,
|
|
993
|
+
settingsHooks,
|
|
994
|
+
mcp: Boolean(options.mcpConfig) || options.useRegisteredMcp !== false,
|
|
995
|
+
enabledToolNames,
|
|
996
|
+
}),
|
|
963
997
|
input_format: "stream-json",
|
|
964
998
|
additional_directories: additionalDirectories,
|
|
965
999
|
resumed_messages: resumedMessages,
|
|
@@ -631,17 +631,48 @@ export async function loadProjectMcp(opts = {}, deps = {}) {
|
|
|
631
631
|
if (root) files.push(path.join(root, ".mcp.json"));
|
|
632
632
|
files.push(path.join(cwd, ".mcp.json"));
|
|
633
633
|
|
|
634
|
+
// Fingerprint trust (gap 2026-07-11): the --project-mcp opt-in covers the
|
|
635
|
+
// file as last seen. First use records a sha256; a CHANGED file is refused
|
|
636
|
+
// (fail-closed) until re-trusted via CC_PROJECT_MCP_TRUST=1 or
|
|
637
|
+
// `cc mcp trust-project`. Injectable for tests.
|
|
638
|
+
const trust =
|
|
639
|
+
deps.projectMcpTrust ||
|
|
640
|
+
(await import("../lib/project-mcp-trust.js").catch(() => null));
|
|
641
|
+
|
|
634
642
|
const servers = {};
|
|
635
643
|
const seenFiles = [];
|
|
636
644
|
for (const file of files) {
|
|
637
645
|
if (!fileExists(file)) continue;
|
|
646
|
+
let content;
|
|
638
647
|
let raw;
|
|
639
648
|
try {
|
|
640
|
-
|
|
649
|
+
content = readFile(file);
|
|
650
|
+
raw = JSON.parse(content);
|
|
641
651
|
} catch (err) {
|
|
642
652
|
writeErr(` mcp: ignoring malformed ${file} (${err.message})\n`);
|
|
643
653
|
continue;
|
|
644
654
|
}
|
|
655
|
+
if (trust) {
|
|
656
|
+
try {
|
|
657
|
+
const check = trust.checkProjectMcpTrust(file, content);
|
|
658
|
+
if (check.status === "changed") {
|
|
659
|
+
if (trust.projectMcpRetrustRequested(env)) {
|
|
660
|
+
trust.recordProjectMcpTrust(file, content);
|
|
661
|
+
writeErr(` mcp: ${file} re-trusted (CC_PROJECT_MCP_TRUST).\n`);
|
|
662
|
+
} else {
|
|
663
|
+
writeErr(
|
|
664
|
+
` mcp: SKIPPING ${file} — its content changed since it was last trusted. ` +
|
|
665
|
+
`Review the diff, then re-trust with CC_PROJECT_MCP_TRUST=1 or \`cc mcp trust-project\`.\n`,
|
|
666
|
+
);
|
|
667
|
+
continue;
|
|
668
|
+
}
|
|
669
|
+
} else if (check.status === "first-use") {
|
|
670
|
+
trust.recordProjectMcpTrust(file, content);
|
|
671
|
+
}
|
|
672
|
+
} catch {
|
|
673
|
+
/* trust bookkeeping is best-effort; the opt-in gate above still holds */
|
|
674
|
+
}
|
|
675
|
+
}
|
|
645
676
|
const parsed = parseMcpServers(raw);
|
|
646
677
|
if (Object.keys(parsed).length > 0) {
|
|
647
678
|
Object.assign(servers, parsed); // later file (cwd) overrides earlier (root)
|
|
@@ -59,6 +59,9 @@ export function resolveAgentPolicy({
|
|
|
59
59
|
// --remote-control also applies interactively: the REPL starts the
|
|
60
60
|
// paired-device approval bridge at startup (批26).
|
|
61
61
|
remoteControl: overrides.remoteControl === true,
|
|
62
|
+
// --channels: inbound channel listeners (webhook/telegram) whose events
|
|
63
|
+
// become user turns in the interactive session (gap-2026-07-11 P0#5).
|
|
64
|
+
channels: overrides.channels || null,
|
|
62
65
|
};
|
|
63
66
|
}
|
|
64
67
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{E as J,b as z,r as C,I as k,J as y,U as _,c as r,K as o,S,V as B,o as V,f as D,P as d,Q as f,R as p,F as j}from"./vendor-Bn1JzzAn.js";import{M as Q}from"./MarkdownRenderer-7agE3Or1.js";import{u as F,_ as W,d as R}from"./index-DV-Rfmfx.js";import{R as q}from"./icons-DG5UD-6K.js";import"./markdown-Yo_c6Krv.js";import"./markdown-CsiA8-E5.js";const K=J("artifacts",()=>{const h=C([]),t=C(!1),u=C(""),e=C(""),w=C(null),b=C(!1),A=z(()=>[...new Set(h.value.map(a=>a.kind).filter(Boolean))].sort());async function l(){const n=F();t.value=!0;try{const a={type:"artifact-list"};u.value&&(a.kind=u.value),e.value&&(a.session=e.value);const s=await n.sendRaw(a);s&&Array.isArray(s.artifacts)&&(h.value=[...s.artifacts].reverse())}catch{}finally{t.value=!1}}async function g(n){const a=F();b.value=!0,w.value={entry:n,previewable:!1};try{const s=await a.sendRaw({type:"artifact-content",artifactId:n.id});w.value={entry:n,previewable:s?.previewable===!0,encoding:s?.encoding||null,content:s?.content||"",truncated:s?.truncated===!0,reason:s?.reason||null}}catch(s){w.value={entry:n,previewable:!1,reason:s?.message||"preview failed"}}finally{b.value=!1}}function i(){w.value=null}const m=z(()=>{const n=w.value;return!n?.previewable||n.encoding!=="base64"?null:`data:${n.entry?.mime||"image/png"};base64,${n.content}`}),O=z(()=>{const n=w.value;return n?.previewable===!0&&n.encoding==="utf8"&&String(n.entry?.mime||"").toLowerCase()==="text/markdown"});async function P(n,a={}){if(!n?.id)return!1;const s=a.fetch||globalThis.fetch,L=a.document||globalThis.document,T=a.URL||globalThis.URL,N=(a.config||globalThis.window?.__CC_CONFIG__)??{};try{const U=await s(`/api/artifacts/${n.id}/download`,{headers:N.wsToken?{Authorization:`Bearer ${N.wsToken}`}:{}});if(!U.ok)return!1;const G=await U.blob(),E=T.createObjectURL(G),I=L.createElement("a");return I.href=E,I.download=n.title||n.id,L.body.appendChild(I),I.click(),I.remove(),T.revokeObjectURL(E),!0}catch{return!1}}async function M(n){const a=F();if(!n)return!1;try{const s=await a.sendRaw({type:"artifact-remove",artifactId:n});return w.value?.entry?.id===n&&(w.value=null),await l(),s?.found===!0}catch{return!1}}async function c(){const n=F();try{const a=await n.sendRaw({type:"artifact-clean"});return await l(),Number(a?.removed)||0}catch{return 0}}function v(n){const a=Number(n)||0;return a<1024?`${a} B`:a<1024*1024?`${(a/1024).toFixed(1)} KB`:`${(a/(1024*1024)).toFixed(1)} MB`}function x(n){switch(n){case"report":return"blue";case"patch":return"purple";case"screenshot":return"cyan";case"log":return"default";case"data":return"green";default:return"default"}}return{artifacts:h,loading:t,kindFilter:u,sessionFilter:e,kinds:A,preview:w,previewLoading:b,previewImageSrc:m,previewIsMarkdown:O,fetchArtifacts:l,openPreview:g,closePreview:i,removeArtifact:M,cleanExpired:c,downloadArtifact:P,formatSize:v,kindColor:x}}),H={__name:"Artifacts",setup(h,{expose:t}){t();const u=K(),e=[{title:"标题",key:"title",dataIndex:"title",ellipsis:!0},{title:"类型",key:"kind",dataIndex:"kind",width:110},{title:"MIME",dataIndex:"mime",width:160,ellipsis:!0},{title:"大小",key:"size",dataIndex:"size",width:90},{title:"发布时间",key:"createdAt",dataIndex:"createdAt",width:170},{title:"会话",dataIndex:"sessionId",width:160,ellipsis:!0},{title:"操作",key:"actions",width:150}],w=z(()=>u.kinds.map(i=>({label:i,value:i})));async function b(i){await u.removeArtifact(i)?R.success("已删除"):R.error("删除失败")}async function A(){const i=await u.cleanExpired();R.info(i>0?`清理了 ${i} 个过期交付物`:"没有过期交付物")}async function l(i){await u.downloadArtifact(i)||R.error("下载失败")}V(()=>{u.fetchArtifacts()}),D(()=>{u.closePreview()});const g={store:u,columns:e,kindOptions:w,onRemove:b,onClean:A,onDownload:l,computed:z,onBeforeUnmount:D,onMounted:V,get ReloadOutlined(){return q},get message(){return R},MarkdownRenderer:Q,get useArtifactsStore(){return K}};return Object.defineProperty(g,"__isScriptSetup",{enumerable:!1,value:!0}),g}},X={class:"page-header"},Y=["onClick"],Z=["src"],$={key:1,class:"preview-markdown"},ee={key:2,class:"preview-text"},te={class:"preview-meta"},ne={key:0};function ae(h,t,u,e,w,b){const A=k("a-select"),l=k("a-button"),g=k("a-popconfirm"),i=k("a-space"),m=k("a-tag"),O=k("a-table"),P=k("a-empty"),M=k("a-card");return d(),y("div",null,[_("div",X,[t[7]||(t[7]=_("div",null,[_("h2",{class:"page-title"},"交付物"),_("p",{class:"page-sub"}," agent 用 publish_artifact 发布的交付物(报告 / patch / 截图 / 日志),在这里预览与管理(cc artifacts 同源)。 ")],-1)),r(i,null,{default:o(()=>[r(A,{value:e.store.kindFilter,"onUpdate:value":t[0]||(t[0]=c=>e.store.kindFilter=c),style:{"min-width":"120px"},placeholder:"全部类型","allow-clear":"",options:e.kindOptions,onChange:t[1]||(t[1]=c=>e.store.fetchArtifacts())},null,8,["value","options"]),r(g,{title:"删除所有过期交付物?",onConfirm:e.onClean},{default:o(()=>[r(l,null,{default:o(()=>[...t[5]||(t[5]=[f("清理过期",-1)])]),_:1})]),_:1}),r(l,{ghost:"",loading:e.store.loading,onClick:t[2]||(t[2]=c=>e.store.fetchArtifacts())},{icon:o(()=>[r(e.ReloadOutlined)]),default:o(()=>[t[6]||(t[6]=f(" 刷新 ",-1))]),_:1},8,["loading"])]),_:1})]),r(O,{"data-source":e.store.artifacts,columns:e.columns,"row-key":"id",size:"small",pagination:{pageSize:10,hideOnSinglePage:!0}},{bodyCell:o(({column:c,record:v})=>[c.key==="title"?(d(),y("a",{key:0,onClick:x=>e.store.openPreview(v)},p(v.title),9,Y)):c.key==="kind"?(d(),S(m,{key:1,color:e.store.kindColor(v.kind)},{default:o(()=>[f(p(v.kind),1)]),_:2},1032,["color"])):c.key==="size"?(d(),y(j,{key:2},[f(p(e.store.formatSize(v.size)),1)],64)):c.key==="createdAt"?(d(),y(j,{key:3},[f(p((v.createdAt||"").replace("T"," ").slice(0,19)),1)],64)):c.key==="actions"?(d(),S(i,{key:4},{default:o(()=>[r(l,{size:"small",onClick:x=>e.store.openPreview(v)},{default:o(()=>[...t[8]||(t[8]=[f("预览",-1)])]),_:1},8,["onClick"]),r(l,{size:"small",onClick:x=>e.onDownload(v)},{default:o(()=>[...t[9]||(t[9]=[f("下载",-1)])]),_:1},8,["onClick"]),r(g,{title:"删除该交付物?",onConfirm:x=>e.onRemove(v.id)},{default:o(()=>[r(l,{size:"small",danger:""},{default:o(()=>[...t[10]||(t[10]=[f("删除",-1)])]),_:1})]),_:1},8,["onConfirm"])]),_:2},1024)):B("v-if",!0)]),_:1},8,["data-source"]),e.store.preview?(d(),S(M,{key:0,size:"small",class:"preview-card",loading:e.store.previewLoading},{title:o(()=>[r(i,null,{default:o(()=>[_("span",null,p(e.store.preview.entry?.title),1),r(m,{color:e.store.kindColor(e.store.preview.entry?.kind)},{default:o(()=>[f(p(e.store.preview.entry?.kind),1)]),_:1},8,["color"]),r(m,{color:"default"},{default:o(()=>[f(p(e.store.preview.entry?.mime),1)]),_:1}),e.store.preview.truncated?(d(),S(m,{key:0,color:"warning"},{default:o(()=>[...t[11]||(t[11]=[f("已截断预览",-1)])]),_:1})):B("v-if",!0)]),_:1})]),extra:o(()=>[r(i,null,{default:o(()=>[r(l,{size:"small",onClick:t[3]||(t[3]=c=>e.onDownload(e.store.preview.entry))},{default:o(()=>[...t[12]||(t[12]=[f("下载",-1)])]),_:1}),r(l,{size:"small",onClick:t[4]||(t[4]=c=>e.store.closePreview())},{default:o(()=>[...t[13]||(t[13]=[f("关闭",-1)])]),_:1})]),_:1})]),default:o(()=>[e.store.previewImageSrc?(d(),y("img",{key:0,src:e.store.previewImageSrc,class:"preview-image",alt:"artifact preview"},null,8,Z)):e.store.previewIsMarkdown?(d(),y("div",$,[r(e.MarkdownRenderer,{content:e.store.preview.content||""},null,8,["content"])])):e.store.preview.previewable?(d(),y("pre",ee,p(e.store.preview.content||"(空文件)"),1)):(d(),S(P,{key:3,description:e.store.preview.reason||"该类型不支持在线预览,可在本机用 cc artifacts open <id> 打开"},null,8,["description"])),_("div",te,[_("span",null,p(e.store.preview.entry?.id),1),e.store.preview.entry?.sessionId?(d(),y("span",ne," · session "+p(e.store.preview.entry.sessionId),1)):B("v-if",!0),_("span",null," · sha256 "+p((e.store.preview.entry?.sha256||"").slice(0,12))+"…",1)])]),_:1},8,["loading"])):B("v-if",!0)])}const de=W(H,[["render",ae],["__scopeId","data-v-c8b48f8c"],["__file","/tmp/cc-web-panel-StwILP/repo/packages/web-panel/src/views/Artifacts.vue"]]);export{de as default};
|
|
@@ -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 w,V as x,_ as B,b as s}from"./vendor-Bn1JzzAn.js";import{_ as k}from"./index-DV-Rfmfx.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(),f=String(e.getMonth()+1).padStart(2,"0"),g=String(e.getDate()).padStart(2,"0"),b=String(e.getHours()).padStart(2,"0"),h=String(e.getMinutes()).padStart(2,"0");return`${p}-${f}-${g} ${b}:${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"},L={class:"meta"},M={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",L,[n("span",M,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(()=>[w(a(t.event.source.adapter),1)]),_:1},8,["color"])):x("v-if",!0)])],2)}const P=k(N,[["render",q],["__scopeId","data-v-49238629"],["__file","/tmp/cc-web-panel-StwILP/repo/packages/web-panel/src/components/pdh/renderers/ChatBubbleRenderer.vue"]]);export{P as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{I as x,P as s,J as i,U as l,R as n,c as g,K as u,Q as _,V as m,F as C,Z as N,S as T,b as p}from"./vendor-Bn1JzzAn.js";import{_ as w}from"./index-DV-Rfmfx.js";import"./icons-DG5UD-6K.js";const V={__name:"GenericCardRenderer",props:{event:{type:Object,required:!0}},setup(v,{expose:f}){f();const t=v,o=p(()=>{if(!t.event.occurredAt)return"";try{const e=new Date(t.event.occurredAt),c=e.getFullYear(),r=String(e.getMonth()+1).padStart(2,"0"),k=String(e.getDate()).padStart(2,"0"),b=String(e.getHours()).padStart(2,"0"),S=String(e.getMinutes()).padStart(2,"0");return`${c}-${r}-${k} ${b}:${S}`}catch{return""}}),h=p(()=>{const e=t.event.content||{};return e.text||e.title||e.subject||e.name||e.prompt||JSON.stringify(e).slice(0,200)}),y=p(()=>{const e=t.event.content||{};return e.body||e.snippet||e.description||e.from||e.counterparty||null}),d=p(()=>{const e=t.event.content||{},c=t.event.extra||{},r=[];return e.amount!=null&&r.push({k:"金额",v:e.amount,color:"gold"}),c.merchant&&r.push({k:"商户",v:c.merchant,color:"green"}),c.orderNo&&r.push({k:"订单",v:c.orderNo,color:"purple"}),e.from&&e.to&&r.push({k:"路线",v:`${e.from} → ${e.to}`,color:"cyan"}),e.trainNo&&r.push({k:"车次",v:e.trainNo,color:"cyan"}),e.model&&r.push({k:"模型",v:e.model,color:"magenta"}),t.event.place&&r.push({k:"地点",v:t.event.place,color:"geekblue"}),r}),a={props:t,formattedTime:o,primaryText:h,secondaryText:y,metaChips:d,computed:p};return Object.defineProperty(a,"__isScriptSetup",{enumerable:!1,value:!0}),a}},B={class:"event-card"},R={class:"card-head"},j={class:"time"},D={key:0,class:"actor"},F={class:"card-body"},G={class:"primary"},I={key:0,class:"secondary"},O={key:0,class:"card-meta"},P={class:"meta-k"};function A(v,f,t,o,h,y){const d=x("a-tag");return s(),i("div",B,[l("div",R,[l("span",j,n(o.formattedTime),1),g(d,{color:"blue",class:"adapter"},{default:u(()=>[_(n(t.event.source.adapter),1)]),_:1}),g(d,{class:"subtype"},{default:u(()=>[_(n(t.event.subtype),1)]),_:1}),t.event.actor?(s(),i("span",D,"@"+n(t.event.actor),1)):m("v-if",!0)]),l("div",F,[l("div",G,n(o.primaryText),1),o.secondaryText?(s(),i("div",I,n(o.secondaryText),1)):m("v-if",!0)]),o.metaChips.length>0?(s(),i("div",O,[(s(!0),i(C,null,N(o.metaChips,a=>(s(),T(d,{key:a.k,color:a.color},{default:u(()=>[l("span",P,n(a.k)+":",1),_(" "+n(a.v),1)]),_:2},1032,["color"]))),128))])):m("v-if",!0)])}const q=w(V,[["render",A],["__scopeId","data-v-c52d08ab"],["__file","/tmp/cc-web-panel-StwILP/repo/packages/web-panel/src/components/pdh/renderers/GenericCardRenderer.vue"]]);export{q 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-DV-Rfmfx.js";import{a8 as y,M}from"./icons-DG5UD-6K.js";const B={__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 M},get FolderOutlined(){return y}};return Object.defineProperty(s,"__isScriptSetup",{enumerable:!1,value:!0}),s}},x={class:"mobile-projects-placeholder"},O={class:"title"},w={class:"subtitle"},k={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",x,[l(j,null,{default:r(()=>[l(P,{description:!1},{image:r(()=>[l(e.MobileOutlined,{style:{fontSize:"64px",color:"#bfbfbf"}})]),default:r(()=>[o("h2",O,t(e.t("mobileProjects.title")),1),o("p",w,t(e.t("mobileProjects.subtitle")),1),l(s,{message:e.t("mobileProjects.v02Banner"),type:"info","show-icon":"",class:"banner"},null,8,["message"]),o("div",k,[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 C=v(B,[["render",T],["__scopeId","data-v-9262cc45"],["__file","/tmp/cc-web-panel-StwILP/repo/packages/web-panel/src/views/MobileProjects.vue"]]);export{C as default};
|