chainlesschain 0.162.38 → 0.162.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/assets/web-panel/assets/{AIOps-DV0Q9zKL.js → AIOps-DCjoAX_u.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-C6vH8rhL.js → ActionButton-XHoOmsbP.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-BvPDc2ui.js → Analytics--xaFkDnL.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-CWnyqTqY.js → AppLayout-CSa3FBn8.js} +5 -5
- package/src/assets/web-panel/assets/{Audit-BzenidV4.js → Audit-ONWXiAwG.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-CSl7bNwK.js → Backup-CKOPNdgy.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-DAY3iHIq.js → BaseInput-PNj4uVqg.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-Jyhm9fgk.js → Chat-CZCulyXV.js} +5 -5
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-CwlAnVjy.js → ChatBubbleRenderer-CjuJpfpV.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-D4rwURAi.js → Checkbox-jvy668lD.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-DYdjTEfC.js → Codegen-DhUebOQD.js} +1 -1
- package/src/assets/web-panel/assets/{Col-DsVyZ_fS.js → Col-BiBvHfdT.js} +1 -1
- package/src/assets/web-panel/assets/{Community-CjCpl27Q.js → Community-CmEdEti-.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-kt18dsjm.js → Compact-CtxpF4R5.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-BV5urquU.js → Compliance-CvPTrTAJ.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-C4SovPWC.js → Cowork-BMafGHjy.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-uuNs_xzA.js → Cron-mdg_4TR1.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-DR5a65tR.js → Crosschain--dGxsUvn.js} +1 -1
- package/src/assets/web-panel/assets/{DID-B1KTf2-5.js → DID-C9oKaCml.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-Dkj7XgED.js → Dashboard-CoGxKMvy.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-BhXCuJ19.js → Dropdown-CDDu3ZZ3.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-DG8365Iv.js → EmailListRenderer-Dy7_r9Ag.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-BdHGPu39.js → FamilyGuardDashboard-CNg6vImJ.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-Dwvxl0zR.js → Federation-CT61bf3u.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-BVmhCVWU.js → FormItemContext-CSLRnXhg.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-DDPjvF2s.js → GenericCardRenderer-CZ4NE5N3.js} +1 -1
- package/src/assets/web-panel/assets/{Git-foK6WTSr.js → Git-DBuOma3L.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-CfqMdu6Y.js → Governance-BTU_SEef.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-BKrLO4GO.js → Inference-47SAmLC_.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-6o6Q-mmF.js → KnowledgeGraph-DCrK5vP4.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-L5ZIW0Dz.js → Logs-BqiDxdav.js} +2 -2
- package/src/assets/web-panel/assets/{Marketplace-BWkfEocP.js → Marketplace-CReUjsDt.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-BPebQbWU.js → McpTools-agZBV3p8.js} +6 -6
- package/src/assets/web-panel/assets/{Memory-C0Dq-X3C.js → Memory-C_YvUtyS.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-DRBoutTY.js → MobileBridge-41fP1Tui.js} +3 -3
- package/src/assets/web-panel/assets/{MobileProjects-BMP6eLp1.js → MobileProjects-BkqLvGfL.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-Cj3QPM9p.js → Mtc-JFJCXUnk.js} +5 -5
- package/src/assets/web-panel/assets/{MtcAudit-rBQYbfQR.js → MtcAudit-BHNpPZC9.js} +6 -6
- package/src/assets/web-panel/assets/{Multisig-Dbuy4OY4.js → Multisig-DuCRumiz.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-CMnt1se-.js → NLProgramming-DK-g0fKY.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-BX9tSCiF.js → Notes-BSMcjsPf.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-BFeirVRq.js → NotificationSettings-9ouC118H.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-ybiMlKQW.js → OrderTableRenderer-LG2nUO5y.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-kTfRxKqk.js → Organization-DSV7oRnR.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-CtuCAzwV.js → Overflow-DVkkORc3.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-KfbciaP3.js → P2P-BXXjkkQD.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-bqEUFhgC.js → PdhVaultBrowser-O5hNnLTP.js} +5 -5
- package/src/assets/web-panel/assets/{Permissions-BgMypz-z.js → Permissions-D_s0H5Av.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-C3zUE-1z.js → PersonalDataHub-CzMDrwUi.js} +3 -3
- package/src/assets/web-panel/assets/{Pipeline-iX-pYHpC.js → Pipeline-i9krLVTL.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-B01uzeFM.js → Privacy-cMQcj9I8.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-TsfbzJp7.js → ProjectInit-Ca_l7avo.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-iGvMp8sM.js → ProjectSettings-BkaIhd6b.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-Be9k29iQ.js → Projects-Dy9yNmDg.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-C9Pc8dqo.js → Providers-D0nzYiqz.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-DN_yFiVO.js → QuickAsk-Bzzr9d0f.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-CvSNgl7H.js → Recommend-C-UFbQnX.js} +1 -1
- package/src/assets/web-panel/assets/{Reputation-S6BCz8xH.js → Reputation-BKMIKO5F.js} +1 -1
- package/src/assets/web-panel/assets/{Row-CTRYCaqP.js → Row-Bs7htK1T.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-Cu8_P5ll.js → RssFeed-v6MdULUh.js} +3 -3
- package/src/assets/web-panel/assets/{Search-rZ1Xza_U.js → Search-DlRWYzvz.js} +1 -1
- package/src/assets/web-panel/assets/{Security-CF43IJHX.js → Security-DXWO37xX.js} +4 -4
- package/src/assets/web-panel/assets/{Services-BobNHzne.js → Services-C2tWA-O0.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-DWJ2kfuI.js → Skeleton-Q8pIYY4a.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-AmEZgHYr.js → Skills-D7XBlErj.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-DTS-fBiY.js → Sla-CiyMVPJ1.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-DEr6MHRU.js → SpeechSettings-CadCeeiR.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-CVs9alv_.js → SyncSettings-DzNAUhQq.js} +2 -2
- package/src/assets/web-panel/assets/Tasks-BjdHjZeb.js +1 -0
- package/src/assets/web-panel/assets/{Templates-CTNjZRKA.js → Templates-DfgEpUa4.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-DPbXg0Pg.js → Tenant-C8ajkuYi.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-DhKXcPw2.js → Terminal-B9rHwQQx.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-B0DMZOpk.js → TimelineRenderer-D1ZVNezX.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-RvWuBXgg.js → Tokens-CAkED4mx.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-2O-BaTQG.js → Trigger-CJSrm6X0.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-6qY35L-C.js → Trust-B-TeorSk.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-DhV1wYtQ.js → UkeySign-Di7Ymofy.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-DgqA5UZm.js → VideoEditing-DM1eYNZe.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-DJRYdUAK.js → Wallet-DvRWkbmR.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-C2W-x0cg.js → WebAuthn-CeZ3Y622.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-BP2tkDHe.js → WorkflowEditor-Cq8c4h5j.js} +1 -1
- package/src/assets/web-panel/assets/{chat-CGVfeoTn.js → chat-7-WfML6Q.js} +1 -1
- package/src/assets/web-panel/assets/{colors-BmjRolM1.js → colors-D6FgCmB-.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-BvJJkjZE.js → compact-item-ClYV25qi.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-DyhlvRYs.js → createContext-CDhtjdkV.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-O0FVFeZg.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-BoBMR89s.js → hasIn-DZSH5LQd.js} +1 -1
- package/src/assets/web-panel/assets/{index-BuQrONgf.js → index---azBCXl.js} +1 -1
- package/src/assets/web-panel/assets/index--ANIKvhL.js +1 -0
- package/src/assets/web-panel/assets/{index-DgbWSwr5.js → index-B13QnrnE.js} +1 -1
- package/src/assets/web-panel/assets/{index-Te0ruvY_.js → index-B4PMzmOx.js} +1 -1
- package/src/assets/web-panel/assets/{index-DtKdCXHW.js → index-B6VWGnwq.js} +1 -1
- package/src/assets/web-panel/assets/{index-ZNIms1nA.js → index-B78X5S22.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bm_MmdwP.js → index-BHeK8I5A.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cbh-lCxq.js → index-BJ7mrOaB.js} +1 -1
- package/src/assets/web-panel/assets/{index-39VDXdn6.js → index-BUOPjAUM.js} +1 -1
- package/src/assets/web-panel/assets/{index-BycpeGfj.js → index-B_mMFQ4S.js} +1 -1
- package/src/assets/web-panel/assets/{index-DyS4I4L-.js → index-Bj8hZiyL.js} +1 -1
- package/src/assets/web-panel/assets/{index-FKFT-QTk.js → index-BlBF_l8m.js} +1 -1
- package/src/assets/web-panel/assets/{index-wLAjVpmJ.js → index-BpzOUiSb.js} +1 -1
- package/src/assets/web-panel/assets/{index-Czsbrn75.js → index-BqOIoEo6.js} +1 -1
- package/src/assets/web-panel/assets/{index-Beh7jDbS.js → index-C7pQa2is.js} +1 -1
- package/src/assets/web-panel/assets/{index-D-93XwJd.js → index-C7sC56w8.js} +1 -1
- package/src/assets/web-panel/assets/{index-n-N19np-.js → index-CDX4QU3k.js} +1 -1
- package/src/assets/web-panel/assets/{index-CSgbOGaP.js → index-CKgS8E_X.js} +1 -1
- package/src/assets/web-panel/assets/{index-CIaGw7vl.js → index-CSjoWPxB.js} +1 -1
- package/src/assets/web-panel/assets/{index-BvvNnWXe.js → index-CWOkL-8O.js} +1 -1
- package/src/assets/web-panel/assets/{index-Y1b8i0NV.js → index-CmU631Je.js} +3 -3
- package/src/assets/web-panel/assets/{index-xPSzUoWT.js → index-CrTmxbL8.js} +1 -1
- package/src/assets/web-panel/assets/{index-C0xn6hOr.js → index-CxwfFZ1u.js} +1 -1
- package/src/assets/web-panel/assets/{index-D0YToIi_.js → index-D0YzTJJO.js} +1 -1
- package/src/assets/web-panel/assets/{index-vF1pR00A.js → index-DGJK8D0l.js} +1 -1
- package/src/assets/web-panel/assets/{index-CzDVBBcg.js → index-DGj1orXm.js} +1 -1
- package/src/assets/web-panel/assets/{index-xZdOioVg.js → index-DL6GFJAd.js} +1 -1
- package/src/assets/web-panel/assets/{index-CDPMHKQi.js → index-DLizxxId.js} +1 -1
- package/src/assets/web-panel/assets/{index-81tWFqfN.js → index-DPEYvNvq.js} +1 -1
- package/src/assets/web-panel/assets/index-DUfp4rnQ.js +1 -0
- package/src/assets/web-panel/assets/{index-BqGNmoKy.js → index-DWRoh3_3.js} +1 -1
- package/src/assets/web-panel/assets/{index-VXVukhBA.js → index-DZ4zuoCP.js} +1 -1
- package/src/assets/web-panel/assets/{index-BT1SQ9nj.js → index-DgaF1F0W.js} +1 -1
- package/src/assets/web-panel/assets/{index-DwTgvhOL.js → index-Di9pFrHV.js} +1 -1
- package/src/assets/web-panel/assets/{index-CQJVedQ3.js → index-DjG82V0v.js} +1 -1
- package/src/assets/web-panel/assets/{index-C1t-r7yV.js → index-Or_McYjX.js} +1 -1
- package/src/assets/web-panel/assets/{index-ByWpNjTj.js → index-rCs9VJJp.js} +1 -1
- package/src/assets/web-panel/assets/{index-DeeLHcMY.js → index-tU6pZ1TP.js} +1 -1
- package/src/assets/web-panel/assets/{index-DIPZ6hbJ.js → index-z-R0KaJS.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-BLKSE8he.js → initDefaultProps-CSdsIGy3.js} +1 -1
- package/src/assets/web-panel/assets/{motion-Bb59qqLK.js → motion-Do-AcZV4.js} +1 -1
- package/src/assets/web-panel/assets/{move-CB3pYCk6.js → move-BmgOoMsi.js} +1 -1
- package/src/assets/web-panel/assets/{omit-iImQWuU7.js → omit-D4Tm7-s9.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-DRP2Chqo.js → pickAttrs-CuWA8-lj.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-BrlfD4tF.js → placementArrow-BSbEF5op.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-Cqxkuh5H.js → responsiveObserve-GIMJwB_9.js} +1 -1
- package/src/assets/web-panel/assets/{slide-nxKEuLMj.js → slide-DlZxpIBe.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-30E47KSk.js → statusUtils-BZ26LPlh.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-Dn2_-5bn.js → styleChecker-Yn_3FZ0l.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-DkZ00X6F.js → useFlexGapSupport-O_LOE1AB.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-ByrwSCOr.js → useFs-VFMyQqtl.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-BDY6jtUD.js → usePersonalDataHub-B_hyrGB-.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-BL2q5BLv.js → vnode-D4LttGy7.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-BSkPKE42.js → zoom-KnTK1fjj.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/lib/ide-context.js +271 -0
- package/src/lib/repl-completer.js +139 -0
- package/src/repl/agent-repl.js +36 -0
- package/src/runtime/agent-core.js +33 -0
- package/src/runtime/headless-runner.js +19 -0
- package/src/runtime/headless-stream.js +19 -9
- package/src/assets/web-panel/assets/Tasks-BcVDAxdi.js +0 -1
- package/src/assets/web-panel/assets/devWarning-CetO0WH0.js +0 -1
- package/src/assets/web-panel/assets/index-BZVz-WfV.js +0 -1
- package/src/assets/web-panel/assets/index-D0-bvFy3.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{u as f}from"./index-
|
|
1
|
+
import{u as f}from"./index-CmU631Je.js";function d(n){if(!n)return n;if(n.error)throw new Error(n.error);return n.result!==void 0?n.result:n}function p(n,t,a,e,r){return typeof n.onMessage!="function"||typeof n.sendRaw!="function"?n.sendRaw({type:t,...a},r).then(d):new Promise((u,s)=>{const l=typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2)}`,w=`${t}.event`,g=`${t}.end`;let c=!1,y=()=>{};const o=(i,b)=>{if(!c){c=!0,clearTimeout(m);try{y()}catch{}i(b)}},m=setTimeout(()=>{o(s,new Error(`stream timeout (${r}ms): ${t}`))},r),h=n.onMessage(i=>{if(!(c||!i)&&!(i.id!==l&&i.requestId!==l)){if(i.type===w){if(typeof e=="function")try{e(i.event||i)}catch{}return}if(i.type===g){o(u,d(i));return}i.type==="error"&&o(s,new Error(i.message||"stream error"))}});y=typeof h=="function"?h:()=>{},Promise.resolve(n.sendRaw({id:l,type:t,...a},r)).catch(()=>{})})}function D(){const n=f(),t=(a,e={},r=3e4)=>n.sendRaw({type:a,...e},r).then(d);return{async health(){return await t("personal-data-hub.health",{},8e3)},async stats(){return await t("personal-data-hub.stats",{},8e3)},async listAdapters(){return await t("personal-data-hub.list-adapters",{},5e3)},async pickFile(a={}){try{const e=await n.sendRaw({type:"fs.openDialog",title:a.title,filters:a.filters},6e4),r=e&&e.result!==void 0?e.result:e;return r&&r.ok&&typeof r.filePath=="string"?r.filePath:null}catch{return null}},async adapterReadiness(a){return await t("personal-data-hub.adapter-readiness",Number.isInteger(a)?{timeoutMs:a}:{},15e3)},async syncAdapter(a,e={}){return await t("personal-data-hub.sync-adapter",{name:a,options:e},12e4)},async syncAll(a={}){return await t("personal-data-hub.sync-all",{options:a},6e5)},async registerMock({name:a="mock",count:e=20,seed:r=1}={}){return await t("personal-data-hub.register-mock",{name:a,count:e,seed:r})},async unregister(a){return await t("personal-data-hub.unregister",{name:a})},async ask(a,e={}){return await t("personal-data-hub.ask",{question:a,options:e},18e4)},async queryEvents(a={}){return await t("personal-data-hub.query-events",a,1e4)},async recentAudit(a={}){return await t("personal-data-hub.recent-audit",a,1e4)},async searchEvents(a={}){return await t("personal-data-hub.search-events",a,15e3)},async facetCounts(a={}){return await t("personal-data-hub.facet-counts",a,1e4)},async testEmailAuth(a){return await t("personal-data-hub.test-email-auth",{account:a},3e4)},async registerEmail(a,e={}){return await t("personal-data-hub.register-email",{account:a,opts:e},15e3)},async unregisterEmail(a){return await t("personal-data-hub.unregister-email",{email:a},5e3)},async listEmailAccounts(){return await t("personal-data-hub.list-email-accounts",{},5e3)},async eventDetail(a){return await t("personal-data-hub.event-detail",{eventId:a},5e3)},async syncAdapterStream(a,e={},r){return await p(n,"personal-data-hub.sync-adapter-stream",{name:a,options:e},r,6e5)},async syncAllStream(a={},e){return await p(n,"personal-data-hub.sync-all-stream",{options:a},e,9e5)},async registerAlipay(a,e={}){return await t("personal-data-hub.register-alipay",{account:a,opts:e},15e3)},async unregisterAlipay(a){return await t("personal-data-hub.unregister-alipay",{email:a},5e3)},async listAlipayAccounts(){return await t("personal-data-hub.list-alipay-accounts",{},5e3)},async importAlipayBill({zipPath:a,csvPath:e,zipPassword:r}={}){return await t("personal-data-hub.import-alipay-bill",{zipPath:a,csvPath:e,zipPassword:r},3e5)},async reviewQueueList(a=50){return await t("personal-data-hub.review-queue-list",{limit:a},5e3)},async reviewDecision(a,e){return await t("personal-data-hub.review-decision",{reviewId:a,decision:e},5e3)},async manualMerge(a,e){return await t("personal-data-hub.manual-merge",{aId:a,bId:e},5e3)},async manualUnmerge(a){return await t("personal-data-hub.manual-unmerge",{personId:a},5e3)},async resolverDrain(a=50){return await t("personal-data-hub.resolver-drain",{limit:a},18e4)},async resolverStats(){return await t("personal-data-hub.resolver-stats",{},5e3)},async skillsList(){return await t("personal-data-hub.skills-list",{},5e3)},async runSkill(a,e={}){return await t("personal-data-hub.run-skill",{name:a,options:e},12e4)},async openAichatLogin(a,e={}){return await t("personal-data-hub.aichat-open-login",{vendor:a,opts:e},1e4)},async probeAichatCookies(a,e){return await t("personal-data-hub.aichat-probe-cookies",{vendor:a,cookieHeader:e},1e4)},async registerAichatVendor(a,e,r={}){return await t("personal-data-hub.aichat-register-vendor",{vendor:a,cookies:e,opts:r},3e4)},async rotateAichatLogin(a){return await t("personal-data-hub.aichat-rotate-login",{vendor:a},1e4)},async listAichatAccounts(){return await t("personal-data-hub.list-aichat-accounts",{},5e3)},async unregisterAichat(a){return await t("personal-data-hub.unregister-aichat",{vendor:a},5e3)},async aichatHealthCheckOnce(){return await t("personal-data-hub.aichat-health-check-once",{},3e4)},async probeWechatEnv(){return await t("personal-data-hub.wechat-env-probe",{},15e3)},async registerWechat({account:a,dbPath:e,wechatDataPath:r,fridaOpts:u,keyProviderOverride:s}={}){return await t("personal-data-hub.register-wechat",{account:a,dbPath:e,wechatDataPath:r,fridaOpts:u,keyProviderOverride:s},45e3)},async listWechatAccounts(){return await t("personal-data-hub.list-wechat-accounts",{},5e3)},async unregisterWechat(a){return await t("personal-data-hub.unregister-wechat",{uin:a},5e3)},async bilibiliAdbSync(a={}){return await t("personal-data-hub.bilibili-adb-sync",{limits:a.limits,stagingDir:a.stagingDir,displayName:a.displayName},12e4)},async bilibiliAdbDoctor(){return await t("personal-data-hub.bilibili-adb-doctor",{},15e3)},async weiboAdbSync(a={}){return await t("personal-data-hub.weibo-adb-sync",{limits:a.limits,stagingDir:a.stagingDir,displayName:a.displayName},6e4)},async xhsAdbSync(a={}){return await t("personal-data-hub.xhs-adb-sync",{limits:a.limits,stagingDir:a.stagingDir,displayName:a.displayName},6e4)},async toutiaoAdbSync(a={}){return await t("personal-data-hub.toutiao-adb-sync",{limits:a.limits,stagingDir:a.stagingDir,displayName:a.displayName},9e4)},async kuaishouAdbSync(a={}){return await t("personal-data-hub.kuaishou-adb-sync",{limits:a.limits,stagingDir:a.stagingDir,displayName:a.displayName},12e4)},async bridgeDoctor(){return await t("personal-data-hub.bridge-doctor",{},6e4)},async douyinAdbSync(a={}){return await t("personal-data-hub.douyin-adb-sync",{uid:a.uid,limits:a.limits,stagingDir:a.stagingDir,displayName:a.displayName},6e4)}}}export{D as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{M as i,h as a,w as l}from"./index-
|
|
1
|
+
import{M as i,h as a,w as l}from"./index-CmU631Je.js";import{a7 as o,k as g,C as d,F as f,A as p}from"./vendor-BvqAck49.js";function c(e){let r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},t=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0,s=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!1,u=e;if(Array.isArray(e)&&(u=i(e)[0]),!u)return null;const n=o(u,r,s);return n.props=t?a(a({},n.props),r):n.props,l(typeof n.props.class!="object","class must be string"),n}function v(e){let r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},t=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0;return e.map(s=>c(s,r,t))}function N(e,r,t){p(o(e,a({},r)),t)}const m=e=>(e||[]).some(r=>g(r)?!(r.type===d||r.type===f&&!m(r.children)):!0)?e:null;function h(e,r,t,s){var u;const n=(u=e[r])===null||u===void 0?void 0:u.call(e,t);return m(n)?n:s?.()}export{h as a,v as b,c,N as t};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{K as o}from"./index-
|
|
1
|
+
import{K as o}from"./index-CmU631Je.js";import{i as f}from"./motion-Do-AcZV4.js";const c=new o("antZoomIn",{"0%":{transform:"scale(0.2)",opacity:0},"100%":{transform:"scale(1)",opacity:1}}),y=new o("antZoomOut",{"0%":{transform:"scale(1)"},"100%":{transform:"scale(0.2)",opacity:0}}),a=new o("antZoomBigIn",{"0%":{transform:"scale(0.8)",opacity:0},"100%":{transform:"scale(1)",opacity:1}}),s=new o("antZoomBigOut",{"0%":{transform:"scale(1)"},"100%":{transform:"scale(0.8)",opacity:0}}),g=new o("antZoomUpIn",{"0%":{transform:"scale(0.8)",transformOrigin:"50% 0%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"50% 0%"}}),O=new o("antZoomUpOut",{"0%":{transform:"scale(1)",transformOrigin:"50% 0%"},"100%":{transform:"scale(0.8)",transformOrigin:"50% 0%",opacity:0}}),l=new o("antZoomLeftIn",{"0%":{transform:"scale(0.8)",transformOrigin:"0% 50%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"0% 50%"}}),u=new o("antZoomLeftOut",{"0%":{transform:"scale(1)",transformOrigin:"0% 50%"},"100%":{transform:"scale(0.8)",transformOrigin:"0% 50%",opacity:0}}),p=new o("antZoomRightIn",{"0%":{transform:"scale(0.8)",transformOrigin:"100% 50%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"100% 50%"}}),z=new o("antZoomRightOut",{"0%":{transform:"scale(1)",transformOrigin:"100% 50%"},"100%":{transform:"scale(0.8)",transformOrigin:"100% 50%",opacity:0}}),K=new o("antZoomDownIn",{"0%":{transform:"scale(0.8)",transformOrigin:"50% 100%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"50% 100%"}}),w=new o("antZoomDownOut",{"0%":{transform:"scale(1)",transformOrigin:"50% 100%"},"100%":{transform:"scale(0.8)",transformOrigin:"50% 100%",opacity:0}}),I={zoom:{inKeyframes:c,outKeyframes:y},"zoom-big":{inKeyframes:a,outKeyframes:s},"zoom-big-fast":{inKeyframes:a,outKeyframes:s},"zoom-left":{inKeyframes:l,outKeyframes:u},"zoom-right":{inKeyframes:p,outKeyframes:z},"zoom-up":{inKeyframes:g,outKeyframes:O},"zoom-down":{inKeyframes:K,outKeyframes:w}},h=(n,r)=>{const{antCls:m}=n,t=`${m}-${r}`,{inKeyframes:i,outKeyframes:e}=I[r];return[f(t,i,e,r==="zoom-big-fast"?n.motionDurationFast:n.motionDurationMid),{[`
|
|
2
2
|
${t}-enter,
|
|
3
3
|
${t}-appear
|
|
4
4
|
`]:{transform:"scale(0)",opacity:0,animationTimingFunction:n.motionEaseOutCirc,"&-prepare":{transform:"none"}},[`${t}-leave`]:{animationTimingFunction:n.motionEaseInOutCirc}}]};export{h as i,c as z};
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
// Injected by web-ui-server.js at serve time
|
|
9
9
|
window.__CC_CONFIG__ = __CC_CONFIG_PLACEHOLDER__;
|
|
10
10
|
</script>
|
|
11
|
-
<script type="module" crossorigin src="./assets/index-
|
|
11
|
+
<script type="module" crossorigin src="./assets/index-CmU631Je.js"></script>
|
|
12
12
|
<link rel="modulepreload" crossorigin href="./assets/vendor-BvqAck49.js">
|
|
13
13
|
<link rel="modulepreload" crossorigin href="./assets/icons-DP3uiYxy.js">
|
|
14
14
|
<link rel="stylesheet" crossorigin href="./assets/index-Cq93VfoF.css">
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IDE live prompt context (Claude-Code parity) — when an IDE bridge is
|
|
3
|
+
* connected (lib/ide-bridge.js → mcp-config.js `loadIdeMcp`, server `ide`),
|
|
4
|
+
* automatically share the editor's state at the moment a prompt is submitted:
|
|
5
|
+
* the active file, the open editor tabs, and the current selection. The agent
|
|
6
|
+
* no longer has to *choose* to call mcp__ide__getSelection — the context rides
|
|
7
|
+
* along with every user turn, exactly like Claude Code's at-submit selection
|
|
8
|
+
* sharing.
|
|
9
|
+
*
|
|
10
|
+
* The context is EPHEMERAL by design: entry points append it to the in-flight
|
|
11
|
+
* user content only, after session persistence, so a resumed session replays
|
|
12
|
+
* the user's words, not a stale editor snapshot.
|
|
13
|
+
*
|
|
14
|
+
* Everything here is best-effort and bounded: a missing/slow IDE server can
|
|
15
|
+
* never block or fail a turn (short timeout, all errors → null), and the
|
|
16
|
+
* injected block is capped. `CC_IDE_CONTEXT=0` disables the feature without
|
|
17
|
+
* disconnecting the IDE tools themselves.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/** Hard cap on the selected text we inline into the prompt. */
|
|
21
|
+
const SELECTION_TEXT_CAP = 2000;
|
|
22
|
+
/** At most this many open-editor entries are listed. */
|
|
23
|
+
const OPEN_EDITORS_CAP = 10;
|
|
24
|
+
/** Per-tool-call budget; the IDE answers from memory, so this is generous. */
|
|
25
|
+
const DEFAULT_TIMEOUT_MS = 1500;
|
|
26
|
+
|
|
27
|
+
/** Env kill-switch: CC_IDE_CONTEXT=0|false|off disables injection. */
|
|
28
|
+
export function ideContextEnabled(env = process.env) {
|
|
29
|
+
const v = String(env?.CC_IDE_CONTEXT ?? "").toLowerCase();
|
|
30
|
+
return !(v === "0" || v === "false" || v === "off");
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Does this resolved MCP bundle expose the IDE bridge's selection tool?
|
|
35
|
+
* (`resolveAgentMcp` connects the bridge as server `ide`, so its tools land in
|
|
36
|
+
* `externalToolExecutors` as mcp__ide__*.)
|
|
37
|
+
*/
|
|
38
|
+
export function hasIdeContextTools(mcp) {
|
|
39
|
+
return !!(
|
|
40
|
+
mcp?.mcpClient?.callTool &&
|
|
41
|
+
mcp.externalToolExecutors?.mcp__ide__getSelection?.kind === "mcp"
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Read an MCP tools/call result's first text block as JSON. The IDE bridge
|
|
47
|
+
* servers always wrap handler data as
|
|
48
|
+
* `{content:[{type:"text",text:JSON.stringify(data)}]}`. Returns null for
|
|
49
|
+
* isError results, non-text content, or unparsable text.
|
|
50
|
+
*/
|
|
51
|
+
export function parseToolResultJson(result) {
|
|
52
|
+
if (!result || result.isError) return null;
|
|
53
|
+
const block = Array.isArray(result.content)
|
|
54
|
+
? result.content.find((b) => b && b.type === "text")
|
|
55
|
+
: null;
|
|
56
|
+
if (!block || typeof block.text !== "string") return null;
|
|
57
|
+
try {
|
|
58
|
+
return JSON.parse(block.text);
|
|
59
|
+
} catch {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Resolve to the promise's value, or null after `ms` / on rejection. */
|
|
65
|
+
function withTimeout(promise, ms) {
|
|
66
|
+
return new Promise((resolve) => {
|
|
67
|
+
const timer = setTimeout(() => resolve(null), ms);
|
|
68
|
+
promise.then(
|
|
69
|
+
(v) => {
|
|
70
|
+
clearTimeout(timer);
|
|
71
|
+
resolve(v);
|
|
72
|
+
},
|
|
73
|
+
() => {
|
|
74
|
+
clearTimeout(timer);
|
|
75
|
+
resolve(null);
|
|
76
|
+
},
|
|
77
|
+
);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Query the connected IDE for its live state. Returns
|
|
83
|
+
* `{ selection, openEditors }` (either field may be null) or null when the
|
|
84
|
+
* feature is disabled, no IDE tools are connected, or nothing useful came
|
|
85
|
+
* back. Never throws.
|
|
86
|
+
*
|
|
87
|
+
* @param {object} mcp resolved bundle from resolveAgentMcp
|
|
88
|
+
* @param {object} opts { env?, timeoutMs? }
|
|
89
|
+
*/
|
|
90
|
+
export async function collectIdeContext(mcp, opts = {}) {
|
|
91
|
+
if (!ideContextEnabled(opts.env || process.env)) return null;
|
|
92
|
+
if (!hasIdeContextTools(mcp)) return null;
|
|
93
|
+
const timeoutMs = opts.timeoutMs || DEFAULT_TIMEOUT_MS;
|
|
94
|
+
const executors = mcp.externalToolExecutors;
|
|
95
|
+
const call = (name) => {
|
|
96
|
+
const exec = executors[name];
|
|
97
|
+
if (!exec || exec.kind !== "mcp") return Promise.resolve(null);
|
|
98
|
+
let p;
|
|
99
|
+
try {
|
|
100
|
+
p = mcp.mcpClient.callTool(exec.serverName, exec.toolName, {});
|
|
101
|
+
} catch {
|
|
102
|
+
return Promise.resolve(null);
|
|
103
|
+
}
|
|
104
|
+
return withTimeout(p.then(parseToolResultJson), timeoutMs);
|
|
105
|
+
};
|
|
106
|
+
const [selection, editors] = await Promise.all([
|
|
107
|
+
call("mcp__ide__getSelection"),
|
|
108
|
+
call("mcp__ide__getOpenEditors"),
|
|
109
|
+
]);
|
|
110
|
+
const openEditors = Array.isArray(editors?.editors) ? editors.editors : null;
|
|
111
|
+
if (!selection && !(openEditors && openEditors.length > 0)) return null;
|
|
112
|
+
return { selection: selection || null, openEditors };
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Render collected IDE state as a compact tagged block for the user turn.
|
|
117
|
+
* Returns null when there is nothing worth saying.
|
|
118
|
+
*/
|
|
119
|
+
export function formatIdeContext(ctx) {
|
|
120
|
+
if (!ctx) return null;
|
|
121
|
+
const lines = [];
|
|
122
|
+
const editors = Array.isArray(ctx.openEditors) ? ctx.openEditors : [];
|
|
123
|
+
const active = editors.find((e) => e && e.active);
|
|
124
|
+
if (active?.file) lines.push(`Active file: ${active.file}`);
|
|
125
|
+
if (editors.length > 0) {
|
|
126
|
+
const names = editors
|
|
127
|
+
.filter((e) => e && e.file)
|
|
128
|
+
.slice(0, OPEN_EDITORS_CAP)
|
|
129
|
+
.map((e) => (e.active ? `${e.file} (active)` : e.file));
|
|
130
|
+
const more = editors.length - names.length;
|
|
131
|
+
lines.push(
|
|
132
|
+
`Open editors: ${names.join(", ")}${more > 0 ? ` (+${more} more)` : ""}`,
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
const sel = ctx.selection;
|
|
136
|
+
if (sel && typeof sel.text === "string" && sel.text.length > 0) {
|
|
137
|
+
const start = sel.selection?.start?.line;
|
|
138
|
+
const end = sel.selection?.end?.line;
|
|
139
|
+
const range =
|
|
140
|
+
Number.isInteger(start) && Number.isInteger(end)
|
|
141
|
+
? `:${start + 1}-${end + 1}` // editor lines are 0-based
|
|
142
|
+
: "";
|
|
143
|
+
const text =
|
|
144
|
+
sel.text.length > SELECTION_TEXT_CAP
|
|
145
|
+
? sel.text.slice(0, SELECTION_TEXT_CAP) + "\n...(selection truncated)"
|
|
146
|
+
: sel.text;
|
|
147
|
+
lines.push(`Selected text in ${sel.file || "the active editor"}${range}:`);
|
|
148
|
+
lines.push(text);
|
|
149
|
+
} else if (sel?.file && !active) {
|
|
150
|
+
lines.push(`Active file: ${sel.file}`);
|
|
151
|
+
}
|
|
152
|
+
if (lines.length === 0) return null;
|
|
153
|
+
return (
|
|
154
|
+
"<ide-context>\n" +
|
|
155
|
+
"Live editor state, shared automatically at prompt time (an IDE is " +
|
|
156
|
+
"connected). This reflects what the user is looking at NOW:\n" +
|
|
157
|
+
lines.join("\n") +
|
|
158
|
+
"\n</ide-context>"
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Append extra text to user-turn content, preserving multimodal arrays
|
|
164
|
+
* (OpenAI-style content parts from --image runs).
|
|
165
|
+
*/
|
|
166
|
+
export function appendTextToContent(content, extra) {
|
|
167
|
+
if (!extra) return content;
|
|
168
|
+
if (typeof content === "string") {
|
|
169
|
+
return content.length > 0 ? `${content}\n\n${extra}` : extra;
|
|
170
|
+
}
|
|
171
|
+
if (Array.isArray(content)) {
|
|
172
|
+
return [...content, { type: "text", text: extra }];
|
|
173
|
+
}
|
|
174
|
+
return content;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* One-call convenience for entry points: collect + format. Returns the tagged
|
|
179
|
+
* block string or null. Never throws.
|
|
180
|
+
*/
|
|
181
|
+
export async function buildIdePromptContext(mcp, opts = {}) {
|
|
182
|
+
try {
|
|
183
|
+
const ctx = await collectIdeContext(mcp, opts);
|
|
184
|
+
return ctx ? formatIdeContext(ctx) : null;
|
|
185
|
+
} catch {
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// ─── Post-edit diagnostics feedback (Claude-Code parity) ────────────────────
|
|
191
|
+
//
|
|
192
|
+
// After the agent mutates a file, the connected IDE's language servers see the
|
|
193
|
+
// change and update their diagnostics. Pulling them right back into the tool
|
|
194
|
+
// result lets the model fix what it just broke in the SAME loop instead of
|
|
195
|
+
// discovering it turns later. The IDE needs a beat to re-lint, hence the
|
|
196
|
+
// settle delay (CC_IDE_DIAG_SETTLE_MS overrides; 0 skips the wait).
|
|
197
|
+
|
|
198
|
+
/** Give language servers this long to notice the disk change before asking. */
|
|
199
|
+
const DIAG_SETTLE_MS = 600;
|
|
200
|
+
/** At most this many diagnostics are surfaced per edit. */
|
|
201
|
+
const DIAG_CAP = 10;
|
|
202
|
+
/** Only these severities are worth interrupting the model for. */
|
|
203
|
+
const DIAG_SEVERITIES = new Set(["error", "warning"]);
|
|
204
|
+
|
|
205
|
+
/** Does this MCP surface expose the IDE bridge's diagnostics tool? */
|
|
206
|
+
export function hasIdeDiagnosticsTool(mcp) {
|
|
207
|
+
return !!(
|
|
208
|
+
mcp?.mcpClient?.callTool &&
|
|
209
|
+
mcp.externalToolExecutors?.mcp__ide__getDiagnostics?.kind === "mcp"
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Pull the IDE's current error/warning diagnostics for one file. `mcp` accepts
|
|
215
|
+
* either a resolveAgentMcp bundle or agent-core's tool context (both carry
|
|
216
|
+
* `mcpClient` + `externalToolExecutors`). Returns a non-empty array or null.
|
|
217
|
+
* Never throws.
|
|
218
|
+
*
|
|
219
|
+
* @param {object} mcp { mcpClient, externalToolExecutors }
|
|
220
|
+
* @param {string} filePath absolute path of the just-edited file
|
|
221
|
+
* @param {object} opts { env?, settleMs?, timeoutMs? }
|
|
222
|
+
*/
|
|
223
|
+
export async function collectIdeDiagnostics(mcp, filePath, opts = {}) {
|
|
224
|
+
const env = opts.env || process.env;
|
|
225
|
+
if (!ideContextEnabled(env)) return null;
|
|
226
|
+
if (!filePath || !hasIdeDiagnosticsTool(mcp)) return null;
|
|
227
|
+
const settle =
|
|
228
|
+
opts.settleMs ??
|
|
229
|
+
(Number.isFinite(Number(env.CC_IDE_DIAG_SETTLE_MS))
|
|
230
|
+
? Number(env.CC_IDE_DIAG_SETTLE_MS)
|
|
231
|
+
: DIAG_SETTLE_MS);
|
|
232
|
+
if (settle > 0) await new Promise((r) => setTimeout(r, settle));
|
|
233
|
+
const exec = mcp.externalToolExecutors.mcp__ide__getDiagnostics;
|
|
234
|
+
let p;
|
|
235
|
+
try {
|
|
236
|
+
p = mcp.mcpClient.callTool(exec.serverName, exec.toolName, {
|
|
237
|
+
path: filePath,
|
|
238
|
+
});
|
|
239
|
+
} catch {
|
|
240
|
+
return null;
|
|
241
|
+
}
|
|
242
|
+
const data = await withTimeout(
|
|
243
|
+
p.then(parseToolResultJson),
|
|
244
|
+
opts.timeoutMs || DEFAULT_TIMEOUT_MS,
|
|
245
|
+
);
|
|
246
|
+
const all = Array.isArray(data?.diagnostics) ? data.diagnostics : null;
|
|
247
|
+
if (!all) return null;
|
|
248
|
+
const relevant = all.filter(
|
|
249
|
+
(d) => d && DIAG_SEVERITIES.has(String(d.severity).toLowerCase()),
|
|
250
|
+
);
|
|
251
|
+
return relevant.length > 0 ? relevant : null;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Render pulled diagnostics as a compact feedback string for the tool result.
|
|
256
|
+
* Returns null when there is nothing to report.
|
|
257
|
+
*/
|
|
258
|
+
export function formatIdeDiagnostics(diags, { cap = DIAG_CAP } = {}) {
|
|
259
|
+
if (!Array.isArray(diags) || diags.length === 0) return null;
|
|
260
|
+
const shown = diags.slice(0, cap).map((d) => {
|
|
261
|
+
const loc = Number.isInteger(d.line) ? `:${d.line + 1}` : "";
|
|
262
|
+
const src = d.source ? ` (${d.source})` : "";
|
|
263
|
+
return ` [${d.severity}] ${d.file || ""}${loc} ${d.message || ""}${src}`.trimEnd();
|
|
264
|
+
});
|
|
265
|
+
const more = diags.length - shown.length;
|
|
266
|
+
return (
|
|
267
|
+
`IDE diagnostics after this edit (${diags.length} problem${diags.length === 1 ? "" : "s"}):\n` +
|
|
268
|
+
shown.join("\n") +
|
|
269
|
+
(more > 0 ? `\n (+${more} more)` : "")
|
|
270
|
+
);
|
|
271
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* REPL `@` file-reference tab-completion (Claude-Code @-mention parity).
|
|
3
|
+
*
|
|
4
|
+
* Typing `@src/fo<TAB>` in the agent REPL completes file/dir paths the same
|
|
5
|
+
* way the @-token will later be expanded by file-ref-expander. Two candidate
|
|
6
|
+
* sources, merged:
|
|
7
|
+
* 1. the filesystem under cwd (dirs get a trailing `/` so TAB can descend)
|
|
8
|
+
* 2. the connected IDE's OPEN EDITOR TABS (when the IDE bridge is up) —
|
|
9
|
+
* the files you are working on rank first, before any fs listing.
|
|
10
|
+
*
|
|
11
|
+
* IDE tabs come from an injected async `getIdeOpenFiles()`; the completer
|
|
12
|
+
* caches the last list (TTL) and refreshes in the background, so completion
|
|
13
|
+
* stays synchronous-fast and a slow/dead IDE costs nothing (first TAB simply
|
|
14
|
+
* has no IDE entries yet).
|
|
15
|
+
*/
|
|
16
|
+
import fs from "fs";
|
|
17
|
+
import path from "path";
|
|
18
|
+
|
|
19
|
+
/** Refresh the IDE open-editors list at most this often. */
|
|
20
|
+
const IDE_CACHE_TTL_MS = 5000;
|
|
21
|
+
/** Hard cap on candidates shown per TAB. */
|
|
22
|
+
const MAX_CANDIDATES = 30;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Find a trailing `@token` being typed at the end of the line. Returns
|
|
26
|
+
* `{ prefix }` (token without `@`, may be "") or null when the cursor is not
|
|
27
|
+
* on an @-token. An @ must start the line or follow whitespace, mirroring
|
|
28
|
+
* file-ref-expander's token rules.
|
|
29
|
+
*/
|
|
30
|
+
export function extractAtPrefix(line) {
|
|
31
|
+
const m = /(^|\s)@([^\s@]*)$/.exec(line || "");
|
|
32
|
+
return m ? { prefix: m[2] } : null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Normalize to forward slashes (what @refs use on every platform). */
|
|
36
|
+
function fwd(p) {
|
|
37
|
+
return String(p).replace(/\\/g, "/");
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Filesystem candidates for an @-prefix, relative to cwd. Directories get a
|
|
42
|
+
* trailing `/`. Missing dirs / unreadable entries → empty (best-effort).
|
|
43
|
+
*/
|
|
44
|
+
export function fileCandidates(prefix, { cwd = process.cwd(), deps } = {}) {
|
|
45
|
+
const readdir = deps?.readdir || ((d) => fs.readdirSync(d));
|
|
46
|
+
const isDir =
|
|
47
|
+
deps?.isDir ||
|
|
48
|
+
((p) => {
|
|
49
|
+
try {
|
|
50
|
+
return fs.statSync(p).isDirectory();
|
|
51
|
+
} catch {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
const norm = fwd(prefix);
|
|
56
|
+
const slash = norm.lastIndexOf("/");
|
|
57
|
+
const dirPart = slash >= 0 ? norm.slice(0, slash + 1) : "";
|
|
58
|
+
const basePart = slash >= 0 ? norm.slice(slash + 1) : norm;
|
|
59
|
+
const absDir = path.resolve(cwd, dirPart || ".");
|
|
60
|
+
let names;
|
|
61
|
+
try {
|
|
62
|
+
names = readdir(absDir);
|
|
63
|
+
} catch {
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
const out = [];
|
|
67
|
+
for (const name of names) {
|
|
68
|
+
if (basePart && !name.toLowerCase().startsWith(basePart.toLowerCase())) {
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
if (name === "node_modules" || name === ".git") continue;
|
|
72
|
+
const rel = dirPart + name;
|
|
73
|
+
out.push(isDir(path.join(absDir, name)) ? `${rel}/` : rel);
|
|
74
|
+
if (out.length >= MAX_CANDIDATES) break;
|
|
75
|
+
}
|
|
76
|
+
return out;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Build a readline completer. Returns `completer(line)` → `[hits, replaced]`
|
|
81
|
+
* per the readline contract; non-@ lines complete to nothing.
|
|
82
|
+
*
|
|
83
|
+
* @param {object} opts { cwd?, getIdeOpenFiles?: () => Promise<string[]>, deps? }
|
|
84
|
+
*/
|
|
85
|
+
export function makeAtCompleter(opts = {}) {
|
|
86
|
+
const cwd = opts.cwd || process.cwd();
|
|
87
|
+
const getIde = opts.getIdeOpenFiles || null;
|
|
88
|
+
const now = opts.deps?.now || Date.now;
|
|
89
|
+
let ideFiles = [];
|
|
90
|
+
let ideFetchedAt = -Infinity; // "never" — the first @ must always fetch
|
|
91
|
+
let ideInFlight = false;
|
|
92
|
+
|
|
93
|
+
const refreshIde = () => {
|
|
94
|
+
if (!getIde || ideInFlight || now() - ideFetchedAt < IDE_CACHE_TTL_MS) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
ideInFlight = true;
|
|
98
|
+
Promise.resolve()
|
|
99
|
+
.then(() => getIde())
|
|
100
|
+
.then((files) => {
|
|
101
|
+
ideFiles = Array.isArray(files)
|
|
102
|
+
? files
|
|
103
|
+
.filter((f) => typeof f === "string" && f.length > 0)
|
|
104
|
+
.map((f) => {
|
|
105
|
+
const rel = path.relative(cwd, f);
|
|
106
|
+
// Keep workspace files relative (the natural @ref form);
|
|
107
|
+
// out-of-workspace files keep their absolute path.
|
|
108
|
+
return rel && !rel.startsWith("..") ? fwd(rel) : fwd(f);
|
|
109
|
+
})
|
|
110
|
+
: [];
|
|
111
|
+
ideFetchedAt = now();
|
|
112
|
+
})
|
|
113
|
+
.catch(() => {
|
|
114
|
+
ideFetchedAt = now(); // don't hammer a dead IDE
|
|
115
|
+
})
|
|
116
|
+
.finally(() => {
|
|
117
|
+
ideInFlight = false;
|
|
118
|
+
});
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const completer = (line) => {
|
|
122
|
+
const at = extractAtPrefix(line);
|
|
123
|
+
if (!at) return [[], line];
|
|
124
|
+
refreshIde(); // async top-up for the NEXT tab; this one uses the cache
|
|
125
|
+
const norm = fwd(at.prefix).toLowerCase();
|
|
126
|
+
const fromIde = ideFiles.filter((f) => f.toLowerCase().startsWith(norm));
|
|
127
|
+
const fromFs = fileCandidates(at.prefix, { cwd, deps: opts.deps });
|
|
128
|
+
const merged = [...new Set([...fromIde, ...fromFs])].slice(
|
|
129
|
+
0,
|
|
130
|
+
MAX_CANDIDATES,
|
|
131
|
+
);
|
|
132
|
+
// readline replaces `replaced` with the chosen hit — keep the `@`.
|
|
133
|
+
return [merged.map((m) => `@${m}`), `@${at.prefix}`];
|
|
134
|
+
};
|
|
135
|
+
// test seam: expose the cache refresher state
|
|
136
|
+
completer._refreshIde = refreshIde;
|
|
137
|
+
completer._ideState = () => ({ ideFiles, ideFetchedAt });
|
|
138
|
+
return completer;
|
|
139
|
+
}
|
package/src/repl/agent-repl.js
CHANGED
|
@@ -732,11 +732,35 @@ export async function startAgentRepl(options = {}) {
|
|
|
732
732
|
return chalk.green("> ");
|
|
733
733
|
};
|
|
734
734
|
|
|
735
|
+
// `@` tab-completion (Claude-Code @-mention parity): filesystem paths +
|
|
736
|
+
// (when the IDE bridge is connected) the editor's open tabs ranked first.
|
|
737
|
+
const { makeAtCompleter } = await import("../lib/repl-completer.js");
|
|
738
|
+
const atCompleter = makeAtCompleter({
|
|
739
|
+
cwd: process.cwd(),
|
|
740
|
+
getIdeOpenFiles: async () => {
|
|
741
|
+
const exec = _adhocMcp?.externalToolExecutors?.mcp__ide__getOpenEditors;
|
|
742
|
+
if (!exec || exec.kind !== "mcp" || !_adhocMcp?.mcpClient?.callTool) {
|
|
743
|
+
return [];
|
|
744
|
+
}
|
|
745
|
+
const { parseToolResultJson } = await import("../lib/ide-context.js");
|
|
746
|
+
const res = await _adhocMcp.mcpClient.callTool(
|
|
747
|
+
exec.serverName,
|
|
748
|
+
exec.toolName,
|
|
749
|
+
{},
|
|
750
|
+
);
|
|
751
|
+
const data = parseToolResultJson(res);
|
|
752
|
+
return Array.isArray(data?.editors)
|
|
753
|
+
? data.editors.map((e) => e?.file).filter(Boolean)
|
|
754
|
+
: [];
|
|
755
|
+
},
|
|
756
|
+
});
|
|
757
|
+
|
|
735
758
|
const rl = readline.createInterface({
|
|
736
759
|
input: process.stdin,
|
|
737
760
|
output: process.stdout,
|
|
738
761
|
prompt: getPrompt(),
|
|
739
762
|
terminal: true,
|
|
763
|
+
completer: atCompleter,
|
|
740
764
|
});
|
|
741
765
|
|
|
742
766
|
logger.log(chalk.bold("\nChainlessChain Agent"));
|
|
@@ -1922,6 +1946,18 @@ export async function startAgentRepl(options = {}) {
|
|
|
1922
1946
|
}
|
|
1923
1947
|
}
|
|
1924
1948
|
|
|
1949
|
+
// IDE live context (Claude-Code parity): re-shared on every prompt while
|
|
1950
|
+
// an IDE bridge is connected — the user's selection moves between turns.
|
|
1951
|
+
// Ephemeral: persistence stores effectivePrompt, not this snapshot.
|
|
1952
|
+
// Best-effort; CC_IDE_CONTEXT=0 disables.
|
|
1953
|
+
try {
|
|
1954
|
+
const { buildIdePromptContext } = await import("../lib/ide-context.js");
|
|
1955
|
+
const ideCtx = await buildIdePromptContext(_adhocMcp);
|
|
1956
|
+
if (ideCtx) userContent += `\n\n${ideCtx}`;
|
|
1957
|
+
} catch (_err) {
|
|
1958
|
+
// optional polish — never fail the turn over it
|
|
1959
|
+
}
|
|
1960
|
+
|
|
1925
1961
|
// Add user message
|
|
1926
1962
|
messages.push({ role: "user", content: userContent });
|
|
1927
1963
|
|
|
@@ -930,6 +930,39 @@ export async function executeTool(name, args, context = {}) {
|
|
|
930
930
|
}
|
|
931
931
|
}
|
|
932
932
|
|
|
933
|
+
// IDE post-edit diagnostics (Claude-Code parity): after a successful file
|
|
934
|
+
// mutation with an IDE bridge connected, pull the editor's fresh
|
|
935
|
+
// error/warning diagnostics for that file into the tool result so the model
|
|
936
|
+
// can fix what it just broke in the same loop. Best-effort, bounded;
|
|
937
|
+
// CC_IDE_CONTEXT=0 disables alongside prompt-time context.
|
|
938
|
+
if (
|
|
939
|
+
(name === "write_file" ||
|
|
940
|
+
name === "edit_file" ||
|
|
941
|
+
name === "edit_file_hashed") &&
|
|
942
|
+
toolResult &&
|
|
943
|
+
typeof toolResult === "object" &&
|
|
944
|
+
!toolResult.error &&
|
|
945
|
+
args?.path &&
|
|
946
|
+
context.mcpClient &&
|
|
947
|
+
context.externalToolExecutors
|
|
948
|
+
) {
|
|
949
|
+
try {
|
|
950
|
+
const { collectIdeDiagnostics, formatIdeDiagnostics } =
|
|
951
|
+
await import("../lib/ide-context.js");
|
|
952
|
+
const diags = await collectIdeDiagnostics(
|
|
953
|
+
{
|
|
954
|
+
mcpClient: context.mcpClient,
|
|
955
|
+
externalToolExecutors: context.externalToolExecutors,
|
|
956
|
+
},
|
|
957
|
+
path.resolve(cwd, args.path),
|
|
958
|
+
);
|
|
959
|
+
const feedback = formatIdeDiagnostics(diags);
|
|
960
|
+
if (feedback) toolResult.ideDiagnostics = feedback;
|
|
961
|
+
} catch (_err) {
|
|
962
|
+
// diagnostics feedback is optional polish — never fail the tool
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
|
|
933
966
|
return toolResult;
|
|
934
967
|
}
|
|
935
968
|
|
|
@@ -546,6 +546,25 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
546
546
|
}
|
|
547
547
|
}
|
|
548
548
|
|
|
549
|
+
// IDE live context (Claude-Code parity): when an IDE bridge is connected,
|
|
550
|
+
// share the editor's selection/active file/open tabs with this turn. Appended
|
|
551
|
+
// to the in-flight user message only — AFTER persistence — so a resumed
|
|
552
|
+
// session replays the prompt, not a stale editor snapshot. Best-effort with
|
|
553
|
+
// a short timeout; CC_IDE_CONTEXT=0 disables.
|
|
554
|
+
try {
|
|
555
|
+
const { buildIdePromptContext, appendTextToContent } =
|
|
556
|
+
await import("../lib/ide-context.js");
|
|
557
|
+
const ideCtx = await (deps.buildIdePromptContext || buildIdePromptContext)(
|
|
558
|
+
mcp,
|
|
559
|
+
);
|
|
560
|
+
if (ideCtx) {
|
|
561
|
+
const last = messages[messages.length - 1];
|
|
562
|
+
last.content = appendTextToContent(last.content, ideCtx);
|
|
563
|
+
}
|
|
564
|
+
} catch {
|
|
565
|
+
// IDE context is optional polish — never fail the run over it.
|
|
566
|
+
}
|
|
567
|
+
|
|
549
568
|
// --permission-prompt-tool: route every CONFIRM-tier approval to an MCP tool
|
|
550
569
|
// (loaded via --mcp-config) instead of headless fail-closed. Overrides the
|
|
551
570
|
// permission-mode confirmer on the gate for this session.
|
|
@@ -245,9 +245,8 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
245
245
|
// settings.json SessionStart hooks → inject session context once (observe-only).
|
|
246
246
|
if (settingsHooks) {
|
|
247
247
|
try {
|
|
248
|
-
const { runSessionStartHooks } =
|
|
249
|
-
"../lib/settings-hook-events.cjs"
|
|
250
|
-
);
|
|
248
|
+
const { runSessionStartHooks } =
|
|
249
|
+
await import("../lib/settings-hook-events.cjs");
|
|
251
250
|
const ctx = runSessionStartHooks(settingsHooks, {
|
|
252
251
|
source: "startup",
|
|
253
252
|
cwd,
|
|
@@ -428,9 +427,8 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
428
427
|
// settings.json UserPromptSubmit hooks. block → skip this turn; context → inject.
|
|
429
428
|
if (settingsHooks) {
|
|
430
429
|
try {
|
|
431
|
-
const { runUserPromptSubmitHooks } =
|
|
432
|
-
"../lib/settings-hook-events.cjs"
|
|
433
|
-
);
|
|
430
|
+
const { runUserPromptSubmitHooks } =
|
|
431
|
+
await import("../lib/settings-hook-events.cjs");
|
|
434
432
|
const ups = runUserPromptSubmitHooks(settingsHooks, {
|
|
435
433
|
prompt: userContent,
|
|
436
434
|
cwd,
|
|
@@ -454,6 +452,19 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
454
452
|
}
|
|
455
453
|
}
|
|
456
454
|
|
|
455
|
+
// IDE live context (Claude-Code parity): re-shared on every turn while an
|
|
456
|
+
// IDE bridge is connected — the user's selection moves between prompts.
|
|
457
|
+
// Best-effort; CC_IDE_CONTEXT=0 disables.
|
|
458
|
+
try {
|
|
459
|
+
const { buildIdePromptContext } = await import("../lib/ide-context.js");
|
|
460
|
+
const ideCtx = await (
|
|
461
|
+
deps.buildIdePromptContext || buildIdePromptContext
|
|
462
|
+
)(mcp);
|
|
463
|
+
if (ideCtx) userContent += `\n\n${ideCtx}`;
|
|
464
|
+
} catch {
|
|
465
|
+
// optional polish — never fail the turn over it
|
|
466
|
+
}
|
|
467
|
+
|
|
457
468
|
messages.push({ role: "user", content: userContent });
|
|
458
469
|
turns += 1;
|
|
459
470
|
|
|
@@ -508,9 +519,8 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
508
519
|
// settings.json SessionEnd hooks (observe-only) when stdin closes.
|
|
509
520
|
if (settingsHooks) {
|
|
510
521
|
try {
|
|
511
|
-
const { runObserveHooks } =
|
|
512
|
-
"../lib/settings-hook-events.cjs"
|
|
513
|
-
);
|
|
522
|
+
const { runObserveHooks } =
|
|
523
|
+
await import("../lib/settings-hook-events.cjs");
|
|
514
524
|
runObserveHooks(
|
|
515
525
|
settingsHooks,
|
|
516
526
|
"SessionEnd",
|