chainlesschain 0.162.193 → 0.162.197
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 +29 -6
- package/completions/_cc +2 -2
- package/completions/cc.bash +2 -2
- package/completions/cc.fish +2 -2
- package/completions/cc.ps1 +2 -2
- package/package.json +1 -1
- package/src/assets/web-panel/assets/{AIOps-DBLkaTje.js → AIOps-D3Gu1a5d.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-BAy-Qebo.js → ActionButton-DrwAoKaz.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-Dfb1Mlau.js → Analytics-C7Q-gd_3.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-BbFkN8m0.js → AppLayout-DgBtae-n.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-kM4-cEEH.js → Artifacts-pQ6LcA-W.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-BSQfYWf3.js → Audit-DK61tocB.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-CWDbI_fG.js → BackgroundAgents-BOKgDFRh.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-BxLPbq_Q.js → Backup-Bo9G4vTP.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-DuIbdrp6.js → BaseInput-Do_dE9_v.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-NEmjGahU.js → Chat-COVvZzOL.js} +5 -5
- package/src/assets/web-panel/assets/ChatBubbleRenderer-BUUyJ5QO.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-CaoeG3Ns.js → Checkbox-Z9MJMolt.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-BFf_g3xY.js → Codegen-BVzWKVbf.js} +1 -1
- package/src/assets/web-panel/assets/{Col-CNOd8mdQ.js → Col-C8MnYcbT.js} +1 -1
- package/src/assets/web-panel/assets/{Community-BhpDqz-i.js → Community-DQxqw15l.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-CQ42T7Z6.js → Compact-BAUmrh3y.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-DI5PcLMN.js → Compliance-jPAkQ3zK.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-wYYZe0wR.js → Cowork-BBQyxbh8.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-Dlq03DD_.js → Cron-W5koq8Z5.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-BzqS8PP3.js → Crosschain-BQhnu5hS.js} +1 -1
- package/src/assets/web-panel/assets/{DID-It55Yem7.js → DID-DD7PlI18.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-9HkH6oxn.js → Dashboard-w_ILuwKI.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-00e2YWRB.js → Dropdown-qiDUAyAo.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-By-ugRDL.js → EmailListRenderer-PDeBcI5H.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-C396yu5m.js → FamilyGuardDashboard-SuArscRM.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-BME5sbZY.js → Federation-BCovZaUn.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-B4TEZCr-.js → FormItemContext-DjlFdVFk.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-_9CX9ieY.js → GenericCardRenderer-DoEZ7fcS.js} +1 -1
- package/src/assets/web-panel/assets/{Git-BrS6WVSr.js → Git-CV0-6GPI.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-BMdCWnKF.js → Governance-B_SFN50w.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-Bcp3vzcA.js → Inference-heI0Eo6k.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DlLuqGY5.js → KnowledgeGraph-Cz5INS5p.js} +1 -1
- package/src/assets/web-panel/assets/Logs-BSFxiHkg.js +2 -0
- package/src/assets/web-panel/assets/MarkdownRenderer-1mNozZ8v.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-Dzn2guvI.js → Marketplace-0TWTpE7k.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-uPict-KL.js → McpTools-CV4-wBLm.js} +6 -6
- package/src/assets/web-panel/assets/{Memory-BCw43kOb.js → Memory-x5bH5rw5.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-DmV8Wv7F.js → MobileBridge-DaBmUu9G.js} +1 -1
- package/src/assets/web-panel/assets/MobileProjects-DqnoFPgR.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-C6jxJ34Y.js → Mtc-B_zKEBif.js} +6 -6
- package/src/assets/web-panel/assets/{MtcAudit-Za8ExwhQ.js → MtcAudit-BCfKD2yg.js} +5 -5
- package/src/assets/web-panel/assets/{Multisig-KKDbuEgb.js → Multisig-DgYfj6c_.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-Dj97zbCk.js → NLProgramming-Dz09lFUm.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-DBXvMraU.js → Notes-Cuj6ugBE.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-DOxITLYl.js → NotificationSettings-DK2WXjhg.js} +1 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-D1IAOQoo.js +1 -0
- package/src/assets/web-panel/assets/{Organization-D1i73mjb.js → Organization-9fqnPvTw.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-kW6Q3rvg.js → Overflow-n5xHkhow.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-C-v_8p2v.js → P2P-B5AUWwH-.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-tUbbY64W.js → PdhVaultBrowser-CoUDV6dy.js} +5 -5
- package/src/assets/web-panel/assets/{Permissions-DkHxEZ58.js → Permissions-DPRmQf_H.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-DWuMPGrK.js → PersonalDataHub-B37bsbEN.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-30IYXWWm.js → Pipeline-CCAuPqu9.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-DZNQ4RrH.js → Privacy-B81msZdv.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-De2MCElf.js → ProjectInit-B-Py2NbF.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-5uHk9wsC.js → ProjectSettings-CYsneiRB.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-XjDfrFLb.js → Projects-Y975Mh6R.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-Bgwj6gcE.js → Providers-uO-10aP1.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-gKql9umv.js → QrScannerModal-Bj_6gJ0l.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-BWvmwkh7.js → QuickAsk-BgpBCMPE.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-Uok4hZPd.js → Recommend-DhUW3YUA.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-DLJzTk9a.js → RemoteSession-DdeyfbkA.js} +3 -3
- package/src/assets/web-panel/assets/{Reputation-ZVwIPMSO.js → Reputation-fxW421xd.js} +1 -1
- package/src/assets/web-panel/assets/{Row-CN04HxWR.js → Row-De73w1og.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-BdSrEG4g.js → RssFeed-3US_Q_lj.js} +3 -3
- package/src/assets/web-panel/assets/{Search-5PwVd0IR.js → Search-DbZ_DU74.js} +1 -1
- package/src/assets/web-panel/assets/{Security-DdBo4zjN.js → Security-DoIU1vMF.js} +4 -4
- package/src/assets/web-panel/assets/{Services-D3letU7M.js → Services-DB_RGqpc.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton--Jb83f1v.js → Skeleton-DnzLaayC.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-Bg-CulHX.js → Skills-VzVXHENF.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-7QOa7S-X.js → Sla-DMfvjCAI.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-DQwppjRw.js → SpeechSettings-DQQOYWbF.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-dNPQGL-s.js → SyncSettings-Bmx3FG1P.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-Ggs-Z48q.js → Tasks-DOQyfb-2.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-78TYHgRO.js → Templates-D6hTRT7c.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-xHwwv9vO.js → Tenant-CTPQZAzs.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-BJXSJfm4.js → Terminal-B7vII3oH.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-fLbjRhJw.js → TimelineRenderer-BkiFJeXV.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-oMSBSBmB.js → Tokens-BPPdQMNo.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-CfnY_wX_.js → Trigger-BxG8JAEI.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-AdyTgYKO.js → Trust-DHD7nMpM.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-C5K_81dS.js → UkeySign-B4BJpU47.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-vcGVDqki.js → VideoEditing-CRiGpFx2.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-hhOc3hlY.js → Wallet-BSDSNiem.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-CVloC11s.js → WebAuthn-DLTUh5Zv.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-CYeE32R5.js → WorkflowEditor-tW2MwjhD.js} +1 -1
- package/src/assets/web-panel/assets/{chat-CNROR5bN.js → chat-SgsLQ3FC.js} +1 -1
- package/src/assets/web-panel/assets/{colors-Cjx-cnwU.js → colors-BHjjLIKO.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-DOIfelvD.js → compact-item-VceErdKq.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-DfA7UZ8u.js → createContext-BZ332MYl.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-DosMaL-k.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-BMSCzcfM.js → hasIn-CBTjJOjn.js} +1 -1
- package/src/assets/web-panel/assets/index-0O5ePnUq.js +1 -0
- package/src/assets/web-panel/assets/{index-CshQbilz.js → index-1n7xjKDU.js} +1 -1
- package/src/assets/web-panel/assets/{index-DPAWBrMf.js → index-29wVzi-k.js} +1 -1
- package/src/assets/web-panel/assets/{index-BbQ2eQ8H.js → index-B2u26AS3.js} +1 -1
- package/src/assets/web-panel/assets/{index-DBpWXFed.js → index-B40dQn0G.js} +3 -3
- package/src/assets/web-panel/assets/{index-5-HXgOX5.js → index-B5KAGxNo.js} +1 -1
- package/src/assets/web-panel/assets/{index-BxOk9vkG.js → index-BC1xuQgX.js} +1 -1
- package/src/assets/web-panel/assets/{index-BemJ2u_E.js → index-BETEjuNr.js} +1 -1
- package/src/assets/web-panel/assets/{index-BEMwBBHk.js → index-BOtvPdHt.js} +1 -1
- package/src/assets/web-panel/assets/{index-B4iYzpkL.js → index-BPXFLYdW.js} +1 -1
- package/src/assets/web-panel/assets/{index-B7gf77CJ.js → index-BQSmZGgs.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cs6l7uRu.js → index-BRWhLbWF.js} +1 -1
- package/src/assets/web-panel/assets/{index-C7xn0Nub.js → index-BTlc-Bve.js} +1 -1
- package/src/assets/web-panel/assets/{index-CVm1_i3t.js → index-BY1wexYG.js} +1 -1
- package/src/assets/web-panel/assets/{index-CNC5onm4.js → index-BcUenmCX.js} +1 -1
- package/src/assets/web-panel/assets/{index-DLmn0BoK.js → index-BeiqkxJG.js} +1 -1
- package/src/assets/web-panel/assets/{index-m2vG9gG_.js → index-BhXZEUAc.js} +1 -1
- package/src/assets/web-panel/assets/{index-BM1y_9hM.js → index-By5jBtkV.js} +1 -1
- package/src/assets/web-panel/assets/{index-By61ojUx.js → index-CLc19alH.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cyweh0Hy.js → index-CMVvxIS8.js} +1 -1
- package/src/assets/web-panel/assets/{index-ClNMrqEY.js → index-C_B9rFQE.js} +1 -1
- package/src/assets/web-panel/assets/{index-CEKMcOyU.js → index-CaIS_TNX.js} +1 -1
- package/src/assets/web-panel/assets/{index-CAnvhwg6.js → index-CawpdGTW.js} +1 -1
- package/src/assets/web-panel/assets/index-ChAzPigF.js +1 -0
- package/src/assets/web-panel/assets/{index-C3L5gdiD.js → index-CpumS98o.js} +1 -1
- package/src/assets/web-panel/assets/{index-FBc_CJBd.js → index-Cr4rjlW5.js} +1 -1
- package/src/assets/web-panel/assets/{index-CdYBye8B.js → index-CrUgDQkf.js} +1 -1
- package/src/assets/web-panel/assets/{index-AWg-0M1S.js → index-CtjLcCNU.js} +1 -1
- package/src/assets/web-panel/assets/{index-DjEsxO5h.js → index-DUkVN794.js} +1 -1
- package/src/assets/web-panel/assets/{index-dCd8cSUq.js → index-D_SePDWj.js} +1 -1
- package/src/assets/web-panel/assets/{index-Icdoqmzt.js → index-DaCCy6lq.js} +1 -1
- package/src/assets/web-panel/assets/{index-BolaOQxx.js → index-DdefYBSw.js} +1 -1
- package/src/assets/web-panel/assets/{index-C2K9SNVX.js → index-DePOeMDM.js} +1 -1
- package/src/assets/web-panel/assets/{index-B5Udeb_6.js → index-DgPvuIn2.js} +1 -1
- package/src/assets/web-panel/assets/{index-ti_lnTWl.js → index-FJ3zC9LK.js} +1 -1
- package/src/assets/web-panel/assets/{index-BUonmKSE.js → index-_PHrIO4O.js} +1 -1
- package/src/assets/web-panel/assets/{index-mTpHoEzr.js → index-fU7wNHDB.js} +1 -1
- package/src/assets/web-panel/assets/{index-DHtpHZAQ.js → index-iYQNU9za.js} +1 -1
- package/src/assets/web-panel/assets/{index-CVL27kXC.js → index-vIXOpcjD.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-Bu8k7H1Y.js → initDefaultProps-D1oZNz0D.js} +1 -1
- package/src/assets/web-panel/assets/{motion-s3iVK41k.js → motion-C8k6doMO.js} +1 -1
- package/src/assets/web-panel/assets/{move-B6B-E5Jz.js → move-DJ4qSbYt.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-BiYgTidA.js → mtc-parser-CdpJD85j.js} +1 -1
- package/src/assets/web-panel/assets/{omit-pU1RdUDA.js → omit-B0V4slKA.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-Cdoq_SeM.js → pickAttrs-Di5NiW1F.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-DIuvAn2K.js → placementArrow-B5OMHgEM.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-8w16YR2D.js → responsiveObserve-C6U9IWql.js} +1 -1
- package/src/assets/web-panel/assets/{slide-VZ01cZe3.js → slide-BMyTH3rN.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-lh8YMN8Z.js → statusUtils-C7d6BG7Z.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-CmDyreec.js → styleChecker-CR50QnQy.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-hiJWMU5y.js → useFlexGapSupport-DBEeoMb8.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-Thnu-Iaj.js → useFs-3r099cjv.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-LBdOxjwY.js → usePersonalDataHub-C5IYNdTK.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-Cg6lFY_X.js → vnode-DmEOLRHf.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-DVfsR1YO.js → zoom-DnpUiVCB.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-manifest.json +214 -50
- package/src/command-surface-policy.js +115 -0
- package/src/data/changelog.json +5 -5
- package/src/lib/public-ide-capability-manifest.js +6 -0
- package/src/repl/agent-repl.js +175 -8
- package/src/repl/prompt-interactions.js +67 -7
- package/src/repl/slash-command-registry.js +3 -4
- package/src/assets/web-panel/assets/ChatBubbleRenderer-DfJEo-5_.js +0 -1
- package/src/assets/web-panel/assets/Logs-D-W_6x09.js +0 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-DElGPxCZ.js +0 -1
- package/src/assets/web-panel/assets/MobileProjects-C-HaCmSM.js +0 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-7DVjZwMM.js +0 -1
- package/src/assets/web-panel/assets/devWarning-ChcCBGs7.js +0 -1
- package/src/assets/web-panel/assets/index-Q2IajL54.js +0 -1
- package/src/assets/web-panel/assets/index-bRkHgOMc.js +0 -1
package/src/repl/agent-repl.js
CHANGED
|
@@ -123,7 +123,7 @@ import {
|
|
|
123
123
|
} from "../runtime/agent-core.js";
|
|
124
124
|
import { formatBackgroundTasks } from "./tasks-status.js";
|
|
125
125
|
import { expandFileRefsAsync } from "../runtime/file-ref-expander.js";
|
|
126
|
-
import { prepareVisionTurn } from "../lib/image-input.js";
|
|
126
|
+
import { prepareVisionTurn, resolveVisionLlm } from "../lib/image-input.js";
|
|
127
127
|
import { composeSystemPrompt } from "../runtime/system-prompt.js";
|
|
128
128
|
import { installPipeSafety } from "../runtime/pipe-safety.js";
|
|
129
129
|
import {
|
|
@@ -145,6 +145,10 @@ import {
|
|
|
145
145
|
} from "./btw-command.js";
|
|
146
146
|
import { shouldStreamLive } from "./stream-decision.js";
|
|
147
147
|
import { emptyTurnNotice } from "./empty-turn-notice.js";
|
|
148
|
+
import {
|
|
149
|
+
createPromptInteractionSurface,
|
|
150
|
+
mergeClipboardImageChips,
|
|
151
|
+
} from "./prompt-interactions.js";
|
|
148
152
|
import {
|
|
149
153
|
buildPermissionPrompt,
|
|
150
154
|
resolveAskIdleTimeoutMs,
|
|
@@ -2134,6 +2138,8 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
|
|
|
2134
2138
|
// an auto-detected image path so the REPL switches to a vision-capable model
|
|
2135
2139
|
// for that turn only (resolveVisionLlm falls back to the default when unset).
|
|
2136
2140
|
let _visionModel;
|
|
2141
|
+
let _promptInteractionConfig = {};
|
|
2142
|
+
let _persistPromptSuggestionsEnabled = null;
|
|
2137
2143
|
// Hard stream inactivity timeout override (config.llm.streamStallTimeoutMs,
|
|
2138
2144
|
// ms): a stream silent that long is aborted + retried instead of hanging.
|
|
2139
2145
|
// Unset → agent-core's 180s default (matches cc chat/ask). Set to 0 to
|
|
@@ -2148,8 +2154,11 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
|
|
|
2148
2154
|
// CC_PERMISSION_ASK_TIMEOUT_MS env > config permissions.askTimeoutMs > off.
|
|
2149
2155
|
let _askIdleTimeoutMs = resolveAskIdleTimeoutMs();
|
|
2150
2156
|
try {
|
|
2151
|
-
const
|
|
2152
|
-
const _cfg = loadConfig();
|
|
2157
|
+
const configManager = await import("../lib/config-manager.js");
|
|
2158
|
+
const _cfg = configManager.loadConfig();
|
|
2159
|
+
_promptInteractionConfig = _cfg || {};
|
|
2160
|
+
_persistPromptSuggestionsEnabled = (enabled) =>
|
|
2161
|
+
configManager.setConfigValue("cli.promptSuggestions", enabled === true);
|
|
2153
2162
|
_visionModel = _cfg?.llm?.visionModel || undefined;
|
|
2154
2163
|
_autoPinCfgValue = _cfg?.context?.autoPin;
|
|
2155
2164
|
_askIdleTimeoutMs = resolveAskIdleTimeoutMs({
|
|
@@ -3588,11 +3597,13 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
|
|
|
3588
3597
|
"/note-next",
|
|
3589
3598
|
"/output-style",
|
|
3590
3599
|
"/permissions",
|
|
3600
|
+
"/paste-image",
|
|
3591
3601
|
"/plan",
|
|
3592
3602
|
"/pr-comments",
|
|
3593
3603
|
"/profile",
|
|
3594
3604
|
"/provider",
|
|
3595
3605
|
"/quit",
|
|
3606
|
+
"/recap",
|
|
3596
3607
|
"/reindex",
|
|
3597
3608
|
"/release-notes",
|
|
3598
3609
|
"/reload-plugins",
|
|
@@ -3606,7 +3617,9 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
|
|
|
3606
3617
|
"/stats",
|
|
3607
3618
|
"/status",
|
|
3608
3619
|
"/statusline",
|
|
3620
|
+
"/stash",
|
|
3609
3621
|
"/sub-agents",
|
|
3622
|
+
"/suggestions",
|
|
3610
3623
|
"/task",
|
|
3611
3624
|
"/tasks",
|
|
3612
3625
|
"/terminal-setup",
|
|
@@ -3617,6 +3630,7 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
|
|
|
3617
3630
|
"/ultrathink",
|
|
3618
3631
|
"/vim",
|
|
3619
3632
|
"/voice",
|
|
3633
|
+
"/editor",
|
|
3620
3634
|
],
|
|
3621
3635
|
// User/project custom commands (.claude/commands/*.md) join TAB completion
|
|
3622
3636
|
// alongside the built-ins above. Sync + best-effort; the completer
|
|
@@ -3660,6 +3674,28 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
|
|
|
3660
3674
|
// "close" cleanup instead of a bare exit.
|
|
3661
3675
|
_replRl = rl;
|
|
3662
3676
|
|
|
3677
|
+
// Prompt-side interaction modules share the production readline surface.
|
|
3678
|
+
// A per-REPL registry avoids singleton handlers retaining an old session.
|
|
3679
|
+
const _promptInteractionSurface = createPromptInteractionSurface({
|
|
3680
|
+
readline: rl,
|
|
3681
|
+
config: _promptInteractionConfig,
|
|
3682
|
+
keybindings: _promptInteractionConfig,
|
|
3683
|
+
getSessionId: () => sessionId,
|
|
3684
|
+
getSuggestionContext: () => ({ messages: messages.slice() }),
|
|
3685
|
+
persistSuggestionEnabled: _persistPromptSuggestionsEnabled,
|
|
3686
|
+
clipboardBinding: options.clipboardBinding || null,
|
|
3687
|
+
generateSuggestions: options.generatePromptSuggestions,
|
|
3688
|
+
suggestionDebounceMs: options.promptSuggestionDebounceMs,
|
|
3689
|
+
screenReader: _screenReaderMode,
|
|
3690
|
+
write: (text) => process.stdout.write(String(text)),
|
|
3691
|
+
writeError: (text) => process.stderr.write(String(text)),
|
|
3692
|
+
getColumns: () => process.stdout.columns || 80,
|
|
3693
|
+
});
|
|
3694
|
+
const _promptInteractions = _promptInteractionSurface.controller;
|
|
3695
|
+
for (const diagnostic of _promptInteractions.diagnostics().keybindingErrors) {
|
|
3696
|
+
logger.warn(`prompt keybinding ignored: ${diagnostic}`);
|
|
3697
|
+
}
|
|
3698
|
+
|
|
3663
3699
|
// MCP elicitation in the interactive REPL uses the same readline surface as
|
|
3664
3700
|
// approvals, while MCPClient retains the protocol-level response shape.
|
|
3665
3701
|
const mcpElicitationClients = [_adhocMcp?.mcpClient, _bundleMcpClient].filter(
|
|
@@ -3757,9 +3793,34 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
|
|
|
3757
3793
|
// Vim-mode plumbing: capture readline's OWN keypress listeners now so we can
|
|
3758
3794
|
// suspend them while in NORMAL mode (the engine drives editing then) and
|
|
3759
3795
|
// reattach them for INSERT mode (readline's rich editing/history/completion).
|
|
3760
|
-
const
|
|
3796
|
+
const _nativeReadlineKeypressListeners = process.stdin.isTTY
|
|
3761
3797
|
? process.stdin.listeners("keypress").slice()
|
|
3762
3798
|
: [];
|
|
3799
|
+
const _consumedReadlineKeypresses = new WeakSet();
|
|
3800
|
+
const _consumeReadlineKeypress = (key) => {
|
|
3801
|
+
if (key && typeof key === "object") _consumedReadlineKeypresses.add(key);
|
|
3802
|
+
};
|
|
3803
|
+
const _rlKeypressListeners = _nativeReadlineKeypressListeners.map(
|
|
3804
|
+
(listener) =>
|
|
3805
|
+
function guardedReadlineKeypress(input, key) {
|
|
3806
|
+
if (
|
|
3807
|
+
key &&
|
|
3808
|
+
typeof key === "object" &&
|
|
3809
|
+
_consumedReadlineKeypresses.has(key)
|
|
3810
|
+
) {
|
|
3811
|
+
return;
|
|
3812
|
+
}
|
|
3813
|
+
return listener.call(this, input, key);
|
|
3814
|
+
},
|
|
3815
|
+
);
|
|
3816
|
+
if (process.stdin.isTTY) {
|
|
3817
|
+
for (const listener of _nativeReadlineKeypressListeners) {
|
|
3818
|
+
process.stdin.removeListener("keypress", listener);
|
|
3819
|
+
}
|
|
3820
|
+
for (const listener of _rlKeypressListeners) {
|
|
3821
|
+
process.stdin.on("keypress", listener);
|
|
3822
|
+
}
|
|
3823
|
+
}
|
|
3763
3824
|
const _suspendReadlineKeys = () => {
|
|
3764
3825
|
for (const l of _rlKeypressListeners)
|
|
3765
3826
|
process.stdin.removeListener("keypress", l);
|
|
@@ -3809,11 +3870,13 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
|
|
|
3809
3870
|
// sequences (arrows etc.) never reach here as bare "escape".
|
|
3810
3871
|
let _turnAbort = null;
|
|
3811
3872
|
let _lastIdleEscAt = 0;
|
|
3873
|
+
let _replKeypressHandler = null;
|
|
3812
3874
|
if (process.stdin.isTTY) {
|
|
3813
|
-
|
|
3875
|
+
_replKeypressHandler = (_str, key) => {
|
|
3814
3876
|
const k = key || {};
|
|
3815
3877
|
// 1) Turn abort always wins, regardless of vim mode.
|
|
3816
3878
|
if (k.name === "escape" && !k.meta && _turnAbort) {
|
|
3879
|
+
_consumeReadlineKeypress(key);
|
|
3817
3880
|
process.stdout.write(chalk.yellow("\n⎋ interrupting…\n"));
|
|
3818
3881
|
try {
|
|
3819
3882
|
_turnAbort.abort();
|
|
@@ -3849,6 +3912,7 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
|
|
|
3849
3912
|
const isShiftTab =
|
|
3850
3913
|
(k.name === "tab" && k.shift) || k.sequence === "\u001b[Z";
|
|
3851
3914
|
if (isShiftTab) {
|
|
3915
|
+
_consumeReadlineKeypress(key);
|
|
3852
3916
|
if (
|
|
3853
3917
|
_approvalGate &&
|
|
3854
3918
|
sessionId &&
|
|
@@ -3877,14 +3941,30 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
|
|
|
3877
3941
|
return;
|
|
3878
3942
|
}
|
|
3879
3943
|
|
|
3944
|
+
// 1.75) Prompt interaction keybindings share the controller used by
|
|
3945
|
+
// slash commands. They are idle-only and stay out of Vim NORMAL mode,
|
|
3946
|
+
// where the modal editor owns every key.
|
|
3947
|
+
if (
|
|
3948
|
+
!_turnAbort &&
|
|
3949
|
+
(!_vimEnabled || !_vim) &&
|
|
3950
|
+
_promptInteractions.handleKeypress(_str, k)
|
|
3951
|
+
) {
|
|
3952
|
+
_consumeReadlineKeypress(key);
|
|
3953
|
+
return;
|
|
3954
|
+
}
|
|
3955
|
+
|
|
3880
3956
|
// 2) Vim mode: modal editing on the current input line.
|
|
3881
3957
|
if (_vimEnabled && !_turnAbort) {
|
|
3882
3958
|
if (!_vim) {
|
|
3883
3959
|
// INSERT mode — readline owns the keys; Esc switches to NORMAL.
|
|
3884
|
-
if (k.name === "escape" && !k.meta)
|
|
3960
|
+
if (k.name === "escape" && !k.meta) {
|
|
3961
|
+
_consumeReadlineKeypress(key);
|
|
3962
|
+
_vimEnterNormal();
|
|
3963
|
+
}
|
|
3885
3964
|
return;
|
|
3886
3965
|
}
|
|
3887
3966
|
// NORMAL mode — readline suspended; the engine interprets every key.
|
|
3967
|
+
_consumeReadlineKeypress(key);
|
|
3888
3968
|
const res = feedNormalKey(_vim, _str || "", k);
|
|
3889
3969
|
if (res.submit) {
|
|
3890
3970
|
// Hand the line to readline as a normal Enter (fires 'line', clears).
|
|
@@ -3906,6 +3986,7 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
|
|
|
3906
3986
|
|
|
3907
3987
|
// 3) Non-vim: double-Esc while idle → rewind picker shortcut.
|
|
3908
3988
|
if (k.name !== "escape" || k.meta) return;
|
|
3989
|
+
_consumeReadlineKeypress(key);
|
|
3909
3990
|
const nowTs = Date.now();
|
|
3910
3991
|
if (nowTs - _lastIdleEscAt < 600) {
|
|
3911
3992
|
_lastIdleEscAt = 0;
|
|
@@ -3930,7 +4011,8 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
|
|
|
3930
4011
|
} else {
|
|
3931
4012
|
_lastIdleEscAt = nowTs;
|
|
3932
4013
|
}
|
|
3933
|
-
}
|
|
4014
|
+
};
|
|
4015
|
+
process.stdin.prependListener("keypress", _replKeypressHandler);
|
|
3934
4016
|
}
|
|
3935
4017
|
|
|
3936
4018
|
logger.log(chalk.bold("\nChainlessChain Agent"));
|
|
@@ -4206,6 +4288,19 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
|
|
|
4206
4288
|
return;
|
|
4207
4289
|
}
|
|
4208
4290
|
|
|
4291
|
+
// The interaction commands are registered through the shared registry,
|
|
4292
|
+
// while the mature REPL handlers below remain on their existing direct
|
|
4293
|
+
// paths. --disable-slash-commands replaces `trimmed` with a sentinel, so
|
|
4294
|
+
// it cannot accidentally reach this dispatcher.
|
|
4295
|
+
if (trimmed.startsWith("/")) {
|
|
4296
|
+
const commandName = trimmed.split(/\s+/, 1)[0];
|
|
4297
|
+
if (_promptInteractionSurface.commandNames.has(commandName)) {
|
|
4298
|
+
await _promptInteractionSurface.dispatchSlash(trimmed);
|
|
4299
|
+
prompt();
|
|
4300
|
+
return;
|
|
4301
|
+
}
|
|
4302
|
+
}
|
|
4303
|
+
|
|
4209
4304
|
if (trimmed === "/help") {
|
|
4210
4305
|
logger.log(chalk.bold("\nCommands:"));
|
|
4211
4306
|
logger.log(
|
|
@@ -4264,6 +4359,21 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
|
|
|
4264
4359
|
logger.log(
|
|
4265
4360
|
` ${chalk.cyan("/output-style")} Response persona (/output-style <name|list>; explanatory/learning built-in)`,
|
|
4266
4361
|
);
|
|
4362
|
+
logger.log(
|
|
4363
|
+
` ${chalk.cyan("/editor")} Edit a draft prompt in an external editor`,
|
|
4364
|
+
);
|
|
4365
|
+
logger.log(
|
|
4366
|
+
` ${chalk.cyan("/stash")} Stash/list/pop/clear draft prompts`,
|
|
4367
|
+
);
|
|
4368
|
+
logger.log(
|
|
4369
|
+
` ${chalk.cyan("/recap")} Show a lightweight session recap`,
|
|
4370
|
+
);
|
|
4371
|
+
logger.log(
|
|
4372
|
+
` ${chalk.cyan("/suggestions")} Prompt suggestions on|off|status|refresh`,
|
|
4373
|
+
);
|
|
4374
|
+
logger.log(
|
|
4375
|
+
` ${chalk.cyan("/paste-image")} Attach a clipboard image from a supporting host`,
|
|
4376
|
+
);
|
|
4267
4377
|
logger.log(
|
|
4268
4378
|
` ${chalk.cyan("/config")} Show config; ${chalk.cyan("/config <key>")} read, ${chalk.cyan("/config <key>=<val>")} set, ${chalk.cyan("/config --help")} keys`,
|
|
4269
4379
|
);
|
|
@@ -7364,6 +7474,35 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
|
|
|
7364
7474
|
return;
|
|
7365
7475
|
}
|
|
7366
7476
|
|
|
7477
|
+
// Explicit clipboard attachment chips are consumed only when a real model
|
|
7478
|
+
// turn is about to start. They compose with auto-detected path images and
|
|
7479
|
+
// enter the same provider-neutral multimodal message/vision override.
|
|
7480
|
+
const clipboardImageChips = _promptInteractions.takeClipboardImageChips();
|
|
7481
|
+
const clipboardMerge = mergeClipboardImageChips(
|
|
7482
|
+
_userMessageContent,
|
|
7483
|
+
clipboardImageChips,
|
|
7484
|
+
);
|
|
7485
|
+
if (clipboardMerge.attached > 0) {
|
|
7486
|
+
_userMessageContent = clipboardMerge.content;
|
|
7487
|
+
if (!_visionLlm) {
|
|
7488
|
+
_visionLlm = resolveVisionLlm({
|
|
7489
|
+
hasImage: true,
|
|
7490
|
+
flags: {},
|
|
7491
|
+
llm: {
|
|
7492
|
+
provider,
|
|
7493
|
+
baseUrl,
|
|
7494
|
+
apiKey,
|
|
7495
|
+
visionModel: _visionModel,
|
|
7496
|
+
},
|
|
7497
|
+
});
|
|
7498
|
+
}
|
|
7499
|
+
logger.info(
|
|
7500
|
+
chalk.gray(
|
|
7501
|
+
`[image] ${clipboardMerge.attached} clipboard image(s) attached -> vision model ${_visionLlm.model}`,
|
|
7502
|
+
),
|
|
7503
|
+
);
|
|
7504
|
+
}
|
|
7505
|
+
|
|
7367
7506
|
// Add user message (keep the object ref so /note-next can be injected for
|
|
7368
7507
|
// this turn's model call and then stripped before persistence).
|
|
7369
7508
|
const _userMsg = { role: "user", content: _userMessageContent };
|
|
@@ -7426,7 +7565,17 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
|
|
|
7426
7565
|
.map(([k, v]) => `${k}: ${v}`);
|
|
7427
7566
|
// Append context to the last user message
|
|
7428
7567
|
const lastMsg = messages[messages.length - 1];
|
|
7429
|
-
|
|
7568
|
+
const slotContext = `[Context - user provided: ${parts.join(", ")}]`;
|
|
7569
|
+
if (Array.isArray(lastMsg.content)) {
|
|
7570
|
+
const textPart = lastMsg.content.find(
|
|
7571
|
+
(part) => part?.type === "text",
|
|
7572
|
+
);
|
|
7573
|
+
if (textPart)
|
|
7574
|
+
textPart.text = `${textPart.text}\n\n${slotContext}`;
|
|
7575
|
+
else lastMsg.content.unshift({ type: "text", text: slotContext });
|
|
7576
|
+
} else {
|
|
7577
|
+
lastMsg.content = `${lastMsg.content}\n\n${slotContext}`;
|
|
7578
|
+
}
|
|
7430
7579
|
logger.info(chalk.gray(`[slot-fill] ${parts.join(", ")}`));
|
|
7431
7580
|
}
|
|
7432
7581
|
}
|
|
@@ -7868,6 +8017,15 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
|
|
|
7868
8017
|
);
|
|
7869
8018
|
}
|
|
7870
8019
|
|
|
8020
|
+
// Generate follow-up suggestions from the settled assistant turn. The
|
|
8021
|
+
// controller snapshots the actual conversation context and debounces in
|
|
8022
|
+
// the background, so readline and persistence remain non-blocking.
|
|
8023
|
+
const suggestionRun = _promptInteractions.scheduleSuggestions({
|
|
8024
|
+
messages: messages.slice(),
|
|
8025
|
+
lastAssistantText: effectiveResponse || "",
|
|
8026
|
+
});
|
|
8027
|
+
void suggestionRun.promise;
|
|
8028
|
+
|
|
7871
8029
|
// Auto-save session
|
|
7872
8030
|
if (sessionId) {
|
|
7873
8031
|
try {
|
|
@@ -8046,6 +8204,15 @@ async function startAgentReplInWorkspace(options = {}, startupAdmission) {
|
|
|
8046
8204
|
});
|
|
8047
8205
|
|
|
8048
8206
|
rl.on("close", async () => {
|
|
8207
|
+
_promptInteractions.dispose();
|
|
8208
|
+
if (process.stdin.isTTY) {
|
|
8209
|
+
if (_replKeypressHandler) {
|
|
8210
|
+
process.stdin.removeListener("keypress", _replKeypressHandler);
|
|
8211
|
+
}
|
|
8212
|
+
for (const listener of _rlKeypressListeners) {
|
|
8213
|
+
process.stdin.removeListener("keypress", listener);
|
|
8214
|
+
}
|
|
8215
|
+
}
|
|
8049
8216
|
// Leave the alternate screen buffer first so the terminal is restored to
|
|
8050
8217
|
// the user's scrollback no matter how the REPL exits.
|
|
8051
8218
|
if (_tuiMode === "fullscreen" && process.stdout.isTTY) {
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
readClipboardImageChip,
|
|
22
22
|
} from "./clipboard-image.js";
|
|
23
23
|
import { layoutTerminalText } from "./terminal-layout.js";
|
|
24
|
+
import { SlashCommandRegistry } from "./slash-command-registry.js";
|
|
24
25
|
|
|
25
26
|
function commandArgs(line, command) {
|
|
26
27
|
const text = String(line || "");
|
|
@@ -80,6 +81,29 @@ export function registerPromptInteractionCommands(registry, controller) {
|
|
|
80
81
|
return PROMPT_INTERACTION_SLASH_COMMANDS.map((command) => command.name);
|
|
81
82
|
}
|
|
82
83
|
|
|
84
|
+
/** Build one session-local controller + registry dispatcher for production. */
|
|
85
|
+
export function createPromptInteractionSurface(options = {}) {
|
|
86
|
+
const controller =
|
|
87
|
+
options.controller || new PromptInteractionController(options);
|
|
88
|
+
const registry = options.registry || new SlashCommandRegistry();
|
|
89
|
+
const commandNames = new Set(
|
|
90
|
+
registerPromptInteractionCommands(registry, controller),
|
|
91
|
+
);
|
|
92
|
+
return {
|
|
93
|
+
controller,
|
|
94
|
+
registry,
|
|
95
|
+
commandNames,
|
|
96
|
+
async dispatchSlash(line) {
|
|
97
|
+
const text = String(line || "").trim();
|
|
98
|
+
const commandName = text.split(/\s+/, 1)[0];
|
|
99
|
+
if (!commandNames.has(commandName)) return { handled: false };
|
|
100
|
+
const command = registry.getCommand(commandName);
|
|
101
|
+
const args = text.slice(commandName.length).trim();
|
|
102
|
+
return command.handler(args);
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
83
107
|
export class PromptInteractionController {
|
|
84
108
|
constructor(options = {}) {
|
|
85
109
|
this.readline = options.readline || null;
|
|
@@ -96,6 +120,10 @@ export class PromptInteractionController {
|
|
|
96
120
|
typeof options.getSessionId === "function"
|
|
97
121
|
? options.getSessionId
|
|
98
122
|
: () => options.sessionId || null;
|
|
123
|
+
this.getSuggestionContext =
|
|
124
|
+
typeof options.getSuggestionContext === "function"
|
|
125
|
+
? options.getSuggestionContext
|
|
126
|
+
: () => ({});
|
|
99
127
|
this.screenReader = options.screenReader === true;
|
|
100
128
|
this.getColumns =
|
|
101
129
|
typeof options.getColumns === "function"
|
|
@@ -160,6 +188,22 @@ export class PromptInteractionController {
|
|
|
160
188
|
this._print(`\n${renderPromptSuggestions(suggestions)}`, { refresh: true });
|
|
161
189
|
}
|
|
162
190
|
|
|
191
|
+
_suggestionContext(overrides = {}) {
|
|
192
|
+
let live = {};
|
|
193
|
+
try {
|
|
194
|
+
const value = this.getSuggestionContext();
|
|
195
|
+
if (value && typeof value === "object") live = value;
|
|
196
|
+
} catch {
|
|
197
|
+
// Suggestion context is optional polish and cannot break prompt input.
|
|
198
|
+
}
|
|
199
|
+
return {
|
|
200
|
+
...live,
|
|
201
|
+
...overrides,
|
|
202
|
+
sessionId:
|
|
203
|
+
overrides.sessionId || live.sessionId || this.getSessionId() || null,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
|
|
163
207
|
diagnostics() {
|
|
164
208
|
return {
|
|
165
209
|
keybindingErrors: this.keybindingDiagnostics.slice(),
|
|
@@ -219,7 +263,7 @@ export class PromptInteractionController {
|
|
|
219
263
|
const result = runPromptSuggestionsCommand(suggestionArgs, {
|
|
220
264
|
controller: this.suggestions,
|
|
221
265
|
persistEnabled: this.persistSuggestionEnabled,
|
|
222
|
-
context:
|
|
266
|
+
context: this._suggestionContext(),
|
|
223
267
|
});
|
|
224
268
|
this._print(result.message, { error: !result.ok });
|
|
225
269
|
return { handled: true, ...result };
|
|
@@ -321,10 +365,7 @@ export class PromptInteractionController {
|
|
|
321
365
|
}
|
|
322
366
|
|
|
323
367
|
scheduleSuggestions(context = {}) {
|
|
324
|
-
return this.suggestions.schedule(
|
|
325
|
-
...context,
|
|
326
|
-
sessionId: context.sessionId || this.getSessionId(),
|
|
327
|
-
});
|
|
368
|
+
return this.suggestions.schedule(this._suggestionContext(context));
|
|
328
369
|
}
|
|
329
370
|
|
|
330
371
|
takeClipboardImageChips() {
|
|
@@ -339,6 +380,25 @@ export class PromptInteractionController {
|
|
|
339
380
|
}
|
|
340
381
|
}
|
|
341
382
|
|
|
342
|
-
|
|
343
|
-
|
|
383
|
+
/**
|
|
384
|
+
* Merge host-provided clipboard image chips into a prepared user message.
|
|
385
|
+
* Only bounded data-image blocks produced by clipboard-image.js are accepted;
|
|
386
|
+
* a host cannot smuggle a remote URL into the model through this seam.
|
|
387
|
+
*/
|
|
388
|
+
export function mergeClipboardImageChips(content, chips = []) {
|
|
389
|
+
const accepted = (Array.isArray(chips) ? chips : []).filter(
|
|
390
|
+
(chip) =>
|
|
391
|
+
chip?.type === "image_url" &&
|
|
392
|
+
/^data:image\/(?:png|jpeg|gif|webp);base64,[A-Za-z0-9+/]+={0,2}$/u.test(
|
|
393
|
+
String(chip.image_url?.url || ""),
|
|
394
|
+
),
|
|
395
|
+
);
|
|
396
|
+
if (!accepted.length) return { content, attached: 0 };
|
|
397
|
+
const parts = Array.isArray(content)
|
|
398
|
+
? content.slice()
|
|
399
|
+
: String(content || "")
|
|
400
|
+
? [{ type: "text", text: String(content) }]
|
|
401
|
+
: [];
|
|
402
|
+
parts.push(...accepted);
|
|
403
|
+
return { content: parts, attached: accepted.length };
|
|
344
404
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { formatBackgroundTasks } from "./tasks-status.js";
|
|
7
|
-
import {
|
|
7
|
+
import { buildDoctorChecks, renderDoctor } from "./doctor-status.js";
|
|
8
8
|
|
|
9
9
|
export class SlashCommandRegistry {
|
|
10
10
|
static _instance = null;
|
|
@@ -124,9 +124,8 @@ export class SlashCommandRegistry {
|
|
|
124
124
|
[
|
|
125
125
|
"/doctor",
|
|
126
126
|
"Check system health",
|
|
127
|
-
|
|
128
|
-
write(
|
|
129
|
-
await runDoctorChecks(write);
|
|
127
|
+
(args, { write, doctorInput = {} }) => {
|
|
128
|
+
write(renderDoctor(buildDoctorChecks(doctorInput)));
|
|
130
129
|
},
|
|
131
130
|
],
|
|
132
131
|
[
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{I as v,P as u,J as S,U as n,R as a,S as y,K as C,Q as x,V as w,_ as B,b as s}from"./vendor-Bn1JzzAn.js";import{_ as T}from"./index-DBpWXFed.js";import"./icons-DG5UD-6K.js";const k={__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}),_}},N={class:"bubble"},R={class:"meta"},M={class:"actor"},V={class:"time"},q={class:"body"};function D(c,d,t,r,i,l){const o=v("a-tag");return u(),S("div",{class:B(["chat-row",{mine:r.isMine}])},[n("div",N,[n("div",R,[n("span",M,a(r.actorLabel),1),n("span",V,a(r.formattedTime),1)]),n("div",q,a(r.messageText),1),t.event.source.adapter?(u(),y(o,{key:0,class:"src",color:r.adapterColor},{default:C(()=>[x(a(t.event.source.adapter),1)]),_:1},8,["color"])):w("v-if",!0)])],2)}const j=T(k,[["render",D],["__scopeId","data-v-49238629"],["__file","/tmp/cc-web-panel-RQTT6I/repo/packages/web-panel/src/components/pdh/renderers/ChatBubbleRenderer.vue"]]);export{j as default};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{I as s,J as g,U as d,c as n,K as _,V as k,S as V,R as S,F as W,Z as K,w as H,n as C,o as M,b as T,r,P as p,Q as O,_ as U}from"./vendor-Bn1JzzAn.js";import{_ as E,u as N}from"./index-DBpWXFed.js";import{R as I}from"./icons-DG5UD-6K.js";const j={__name:"Logs",setup(Q,{expose:a}){a();const x=N(),e=r("status"),y=r(!1),v=r(""),i=r(""),c=r(""),f=r(!0),o=r(null),h={status:"status",doctor:"doctor","skill-sources":"skill sources","llm-providers":"llm providers"},m=T(()=>i.value.split(`
|
|
2
|
-
`)),b=T(()=>{if(!c.value)return m.value;const t=c.value.toLowerCase();return m.value.filter(u=>u.toLowerCase().includes(t))});function L(t){return t.includes("✖")||t.includes("error")||t.includes("Error")||t.includes("failed")?"line-error":t.includes("✔")||t.includes("✓")||t.includes("success")||t.includes("running")?"line-success":t.includes("warn")||t.includes("Warn")||t.includes("○")?"line-warn":t.startsWith(" ")||t.startsWith(" ")?"line-indent":""}function l(t){return t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function w(t){if(!c.value)return t;const u=c.value.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return t.replace(new RegExp(`(${u})`,"gi"),"<mark>$1</mark>")}async function R(){y.value=!0,v.value="",i.value="";const t=h[e.value]||"status";try{const{output:u}=await x.execute(t,3e4);i.value=u,f.value&&(await C(),o.value&&(o.value.scrollTop=o.value.scrollHeight))}catch(u){v.value=`执行失败: ${u.message}`,i.value=v.value}finally{y.value=!1}}H(b,async()=>{f.value&&(await C(),o.value&&(o.value.scrollTop=o.value.scrollHeight))}),M(R);const B={ws:x,activeTab:e,loading:y,error:v,rawOutput:i,searchQuery:c,autoScroll:f,logContainer:o,TAB_COMMANDS:h,allLines:m,filteredLines:b,lineClass:L,escapeHtml:l,highlightSearch:w,loadLog:R,ref:r,computed:T,watch:H,nextTick:C,onMounted:M,get ReloadOutlined(){return I},get useWsStore(){return N}};return Object.defineProperty(B,"__isScriptSetup",{enumerable:!1,value:!0}),B}},q={style:{display:"flex","align-items":"center","justify-content":"space-between","margin-bottom":"24px"}},z={style:{display:"flex",gap:"10px",margin:"12px 0"}},A={ref:"logContainer",class:"log-box"},D={key:0,style:{"text-align":"center",padding:"40px",color:"var(--text-muted)"}},F={key:1,style:{"text-align":"center",padding:"40px",color:"var(--text-muted)"}},P={key:2},J=["innerHTML"];function Z(Q,a,x,e,y,v){const i=s("a-checkbox"),c=s("a-button"),f=s("a-space"),o=s("a-tab-pane"),h=s("a-tabs"),m=s("a-input-search"),b=s("a-tag"),L=s("a-spin");return p(),g("div",null,[d("div",q,[a[5]||(a[5]=d("div",null,[d("h2",{class:"page-title"},"日志查看"),d("p",{class:"page-sub"},"系统运行日志与诊断输出")],-1)),n(f,null,{default:_(()=>[n(i,{checked:e.autoScroll,"onUpdate:checked":a[0]||(a[0]=l=>e.autoScroll=l)},{default:_(()=>[...a[3]||(a[3]=[O("自动滚动",-1)])]),_:1},8,["checked"]),n(c,{type:"primary",ghost:"",loading:e.loading,onClick:e.loadLog},{icon:_(()=>[n(e.ReloadOutlined)]),default:_(()=>[a[4]||(a[4]=O(" 刷新 ",-1))]),_:1},8,["loading"])]),_:1})]),k(" Tab Selector "),n(h,{activeKey:e.activeTab,"onUpdate:activeKey":a[1]||(a[1]=l=>e.activeTab=l),onChange:e.loadLog,style:{"margin-bottom":"0"}},{default:_(()=>[n(o,{key:"status",tab:"系统状态"}),n(o,{key:"doctor",tab:"环境诊断"}),n(o,{key:"skill-sources",tab:"技能来源"}),n(o,{key:"llm-providers",tab:"LLM 提供商"})]),_:1},8,["activeKey"]),k(" Search Bar "),d("div",z,[n(m,{value:e.searchQuery,"onUpdate:value":a[2]||(a[2]=l=>e.searchQuery=l),placeholder:"搜索日志内容...","allow-clear":"",style:{flex:"1"}},null,8,["value"]),e.filteredLines.length!==e.allLines.length?(p(),V(b,{key:0,color:"blue"},{default:_(()=>[O(S(e.filteredLines.length)+" / "+S(e.allLines.length)+" 行 ",1)]),_:1})):k("v-if",!0)]),k(" Log Output "),d("div",A,[e.loading?(p(),g("div",D,[n(L,{size:"large"}),a[6]||(a[6]=d("div",{style:{"margin-top":"10px"}},"加载中...",-1))])):e.filteredLines.length?(p(),g("div",P,[(p(!0),g(W,null,K(e.filteredLines,(l,w)=>(p(),g("div",{key:w,class:U(["log-line",e.lineClass(l)]),innerHTML:e.highlightSearch(e.escapeHtml(l))},null,10,J))),128))])):(p(),g("div",F,S(e.error||"暂无日志内容,点击刷新加载"),1))],512)])}const $=E(j,[["render",Z],["__scopeId","data-v-8c2906e0"],["__file","/tmp/cc-web-panel-RQTT6I/repo/packages/web-panel/src/views/Logs.vue"]]);export{$ as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{P as c,J as p,b as s}from"./vendor-Bn1JzzAn.js";import{r as a}from"./markdown-Yo_c6Krv.js";import{_ as d}from"./index-DBpWXFed.js";const _={__name:"MarkdownRenderer",props:{content:{type:String,default:""}},setup(t,{expose:o}){o();const e=t,r=s(()=>a(e.content||"")),n={props:e,rendered:r,computed:s,get renderMarkdown(){return a}};return Object.defineProperty(n,"__isScriptSetup",{enumerable:!1,value:!0}),n}},i=["innerHTML"];function m(t,o,e,r,n,u){return c(),p("div",{class:"markdown-content",innerHTML:r.rendered},null,8,i)}const w=d(_,[["render",m],["__scopeId","data-v-0b0b9f63"],["__file","/tmp/cc-web-panel-RQTT6I/repo/packages/web-panel/src/components/MarkdownRenderer.vue"]]);export{w as M};
|
|
@@ -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-DBpWXFed.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"},T={class:"subtitle"},k={class:"explainer"};function w(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",T,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 N=v(B,[["render",w],["__scopeId","data-v-9262cc45"],["__file","/tmp/cc-web-panel-RQTT6I/repo/packages/web-panel/src/views/MobileProjects.vue"]]);export{N as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{I as w,P as l,J as u,U as s,R as n,c as i,K as v,Q as _,V as T,b as a}from"./vendor-Bn1JzzAn.js";import{_ as S}from"./index-DBpWXFed.js";import"./icons-DG5UD-6K.js";const k={__name:"OrderTableRenderer",props:{event:{type:Object,required:!0}},setup(p,{expose:r}){r();const o=p,e=a(()=>o.event.content||{}),d=a(()=>o.event.extra||{}),m=a(()=>d.value.merchant||e.value.merchant||e.value.counterparty||"—"),c=a(()=>e.value.title||e.value.name||e.value.itemName||e.value.text||"—"),g=a(()=>{const t=e.value.amount??e.value.price??e.value.total;return t==null?"—":`${e.value.currency||"¥"} ${typeof t=="number"?t.toFixed(2):t}`}),y=a(()=>d.value.orderNo||e.value.orderNo||e.value.orderId),f=a(()=>e.value.status||e.value.state),b=a(()=>{const t=(f.value||"").toLowerCase();return t.includes("成功")||t.includes("succe")||t.includes("paid")?"green":t.includes("退")||t.includes("refund")?"orange":t.includes("失败")||t.includes("fail")?"red":"default"}),h=a(()=>{if(!o.event.occurredAt)return"";const t=new Date(o.event.occurredAt);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")} ${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}`}),x={props:o,c:e,e:d,merchantText:m,itemText:c,amountText:g,orderNo:y,statusText:f,statusColor:b,formattedTime:h,computed:a};return Object.defineProperty(x,"__isScriptSetup",{enumerable:!1,value:!0}),x}},N={class:"order-card"},C={class:"head"},O={class:"time"},R={class:"row"},V={class:"val"},I={class:"row"},B={class:"val"},D={class:"row amount-row"},j={class:"val amount"},A={key:0,class:"row"},F={class:"val mono"},M={key:1,class:"row"};function P(p,r,o,e,d,m){const c=w("a-tag");return l(),u("div",N,[s("div",C,[s("span",O,n(e.formattedTime),1),i(c,{color:"gold"},{default:v(()=>[_(n(o.event.source.adapter),1)]),_:1}),i(c,null,{default:v(()=>[_(n(o.event.subtype),1)]),_:1})]),s("div",R,[r[0]||(r[0]=s("span",{class:"key"},"商户",-1)),s("span",V,n(e.merchantText),1)]),s("div",I,[r[1]||(r[1]=s("span",{class:"key"},"商品/项目",-1)),s("span",B,n(e.itemText),1)]),s("div",D,[r[2]||(r[2]=s("span",{class:"key"},"金额",-1)),s("span",j,n(e.amountText),1)]),e.orderNo?(l(),u("div",A,[r[3]||(r[3]=s("span",{class:"key"},"单号",-1)),s("span",F,n(e.orderNo),1)])):T("v-if",!0),e.statusText?(l(),u("div",M,[r[4]||(r[4]=s("span",{class:"key"},"状态",-1)),i(c,{color:e.statusColor},{default:v(()=>[_(n(e.statusText),1)]),_:1},8,["color"])])):T("v-if",!0)])}const J=S(k,[["render",P],["__scopeId","data-v-5ed5524d"],["__file","/tmp/cc-web-panel-RQTT6I/repo/packages/web-panel/src/components/pdh/renderers/OrderTableRenderer.vue"]]);export{J as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{Q as r}from"./index-DBpWXFed.js";const o=((n,a,e)=>{r(n,`[ant-design-vue: ${a}] ${e}`)});export{o as d};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{A as o}from"./Row-CN04HxWR.js";import{a0 as t}from"./index-DBpWXFed.js";import"./vendor-Bn1JzzAn.js";import"./responsiveObserve-8w16YR2D.js";import"./useFlexGapSupport-hiJWMU5y.js";import"./styleChecker-CmDyreec.js";import"./index-AWg-0M1S.js";import"./icons-DG5UD-6K.js";const l=t(o);export{l as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{C as o}from"./Col-CNOd8mdQ.js";import{a0 as t}from"./index-DBpWXFed.js";import"./vendor-Bn1JzzAn.js";import"./index-AWg-0M1S.js";import"./icons-DG5UD-6K.js";const s=t(o);export{s as default};
|