zidane 8.2.2 → 8.2.4
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/dist/{acp-oYRjlh71.js → acp-BIInKhVI.js} +6 -6
- package/dist/{acp-oYRjlh71.js.map → acp-BIInKhVI.js.map} +1 -1
- package/dist/acp-cli.js +4 -4
- package/dist/acp.d.ts +2 -2
- package/dist/acp.js +1 -1
- package/dist/{agent-CBQglXtH.js → agent-CmhCOmyO.js} +10 -5
- package/dist/{agent-CBQglXtH.js.map → agent-CmhCOmyO.js.map} +1 -1
- package/dist/agent.d.ts +1 -1
- package/dist/agent.js +1 -1
- package/dist/chat/pure.d.ts +4 -4
- package/dist/chat/pure.js +7 -7
- package/dist/chat.d.ts +3 -3
- package/dist/chat.js +16 -16
- package/dist/{cli-shared-E5m_pI8A.js → cli-shared-GOehTeqk.js} +2 -2
- package/dist/{cli-shared-E5m_pI8A.js.map → cli-shared-GOehTeqk.js.map} +1 -1
- package/dist/{client-core-BdD20sOv.d.ts → client-core-Dz8hELs4.d.ts} +15 -5
- package/dist/client-core-Dz8hELs4.d.ts.map +1 -0
- package/dist/codemode-worker.js +1 -1
- package/dist/codemode.js +1 -1
- package/dist/{connection-loop-DTk82YVl.d.ts → connection-loop-dm_TN-QD.d.ts} +3 -3
- package/dist/{connection-loop-DTk82YVl.d.ts.map → connection-loop-dm_TN-QD.d.ts.map} +1 -1
- package/dist/contexts/daytona.d.ts +1 -1
- package/dist/contexts/e2b.d.ts +1 -1
- package/dist/{credentials-B9DfBJP9.js → credentials-DxOQmset.js} +2 -2
- package/dist/{credentials-B9DfBJP9.js.map → credentials-DxOQmset.js.map} +1 -1
- package/dist/daemon-cli.js +2 -2
- package/dist/{dispatcher-BICXFGiJ.js → dispatcher-Dclv6HXn.js} +22 -18
- package/dist/dispatcher-Dclv6HXn.js.map +1 -0
- package/dist/{engine-QCX3GV-i.js → engine-C_U6kDfA.js} +6 -6
- package/dist/{engine-QCX3GV-i.js.map → engine-C_U6kDfA.js.map} +1 -1
- package/dist/{eval-CfQlBR81.js → eval-CIHIF_Ns.js} +3 -3
- package/dist/{eval-CfQlBR81.js.map → eval-CIHIF_Ns.js.map} +1 -1
- package/dist/eval.d.ts +1 -1
- package/dist/eval.js +1 -1
- package/dist/{executor-B8GoXaaE.js → executor-BFaR2nfc.js} +3 -3
- package/dist/{executor-B8GoXaaE.js.map → executor-BFaR2nfc.js.map} +1 -1
- package/dist/{extensions-BeH3D-bq.js → extensions-DIbpUj5R.js} +3 -3
- package/dist/{extensions-BeH3D-bq.js.map → extensions-DIbpUj5R.js.map} +1 -1
- package/dist/extensions.d.ts +1 -1
- package/dist/extensions.js +1 -1
- package/dist/{fold-rules-DSypi36k.d.ts → fold-rules-CMpWNPqk.d.ts} +2 -2
- package/dist/{fold-rules-DSypi36k.d.ts.map → fold-rules-CMpWNPqk.d.ts.map} +1 -1
- package/dist/{headless-R4pbpTkm.js → headless-Bs9Lb4vs.js} +4 -4
- package/dist/{headless-R4pbpTkm.js.map → headless-Bs9Lb4vs.js.map} +1 -1
- package/dist/headless.d.ts +1 -1
- package/dist/headless.js +1 -1
- package/dist/history-worker.js +1 -1
- package/dist/{host-scoped-settings-CCnaBkCV.js → host-scoped-settings-DxxI_yRo.js} +2 -2
- package/dist/{host-scoped-settings-CCnaBkCV.js.map → host-scoped-settings-DxxI_yRo.js.map} +1 -1
- package/dist/{host-signals-DI9JQvR9.js → host-signals-CQ2jZR-2.js} +5 -5
- package/dist/{host-signals-DI9JQvR9.js.map → host-signals-CQ2jZR-2.js.map} +1 -1
- package/dist/{index-DyQyDLX1.d.ts → index-4mDRyTGJ.d.ts} +1722 -1691
- package/dist/index-4mDRyTGJ.d.ts.map +1 -0
- package/dist/{index-lcuvhQfF.d.ts → index-Dlmu8HnG.d.ts} +5 -5
- package/dist/{index-lcuvhQfF.d.ts.map → index-Dlmu8HnG.d.ts.map} +1 -1
- package/dist/{index-BkNeiJYI.d.ts → index-QsAN9yjZ.d.ts} +3 -3
- package/dist/{index-BkNeiJYI.d.ts.map → index-QsAN9yjZ.d.ts.map} +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +8 -8
- package/dist/ipc/remote.d.ts +5 -5
- package/dist/ipc/remote.js +3 -3
- package/dist/ipc.d.ts +5 -5
- package/dist/ipc.js +9 -9
- package/dist/{links-CN5JFFde.js → links-D5itfH8P.js} +10 -10
- package/dist/{links-CN5JFFde.js.map → links-D5itfH8P.js.map} +1 -1
- package/dist/{mcp-allowlist-BQ5MvhHi.js → mcp-allowlist-BbnTBKNN.js} +15 -4
- package/dist/mcp-allowlist-BbnTBKNN.js.map +1 -0
- package/dist/mcp.d.ts +1 -1
- package/dist/{oauth-TVPPye84.js → oauth-Ck3wQX4Q.js} +133 -43
- package/dist/oauth-Ck3wQX4Q.js.map +1 -0
- package/dist/output/stream-json.d.ts +1 -1
- package/dist/output/terminal.d.ts +1 -1
- package/dist/plugins.d.ts +1 -1
- package/dist/{prelude-HzY_JEGq.js → prelude-qjPUkw4f.js} +26 -2
- package/dist/prelude-qjPUkw4f.js.map +1 -0
- package/dist/{presets-DXeHsd24.js → presets-C4hkykN-.js} +2 -2
- package/dist/{presets-DXeHsd24.js.map → presets-C4hkykN-.js.map} +1 -1
- package/dist/presets.d.ts +1 -1
- package/dist/presets.js +1 -1
- package/dist/{protocol-BIv1Yuvl.js → protocol-Do_i6Ras.js} +3 -1
- package/dist/protocol-Do_i6Ras.js.map +1 -0
- package/dist/providers/anthropic.d.ts +1 -1
- package/dist/providers/arcee.d.ts +1 -1
- package/dist/providers/baseten.d.ts +1 -1
- package/dist/providers/cerebras.d.ts +1 -1
- package/dist/providers/google.d.ts +1 -1
- package/dist/providers/local.d.ts +1 -1
- package/dist/providers/neuralwatt.d.ts +1 -1
- package/dist/providers/openai-compat.d.ts +1 -1
- package/dist/providers/openai.d.ts +1 -1
- package/dist/providers/openrouter.d.ts +1 -1
- package/dist/providers/xai.d.ts +1 -1
- package/dist/providers.d.ts +1 -1
- package/dist/{registry-PNi9rsGi.js → registry-DxPP_tAt.js} +3 -3
- package/dist/{registry-PNi9rsGi.js.map → registry-DxPP_tAt.js.map} +1 -1
- package/dist/{remote-hosts-b6Luwdhu.js → remote-hosts-BkOwRszu.js} +4 -4
- package/dist/{remote-hosts-b6Luwdhu.js.map → remote-hosts-BkOwRszu.js.map} +1 -1
- package/dist/restate.d.ts +1 -1
- package/dist/{secret-shapes-CEoGmfEE.js → secret-shapes-HvaYVzwc.js} +17 -4
- package/dist/secret-shapes-HvaYVzwc.js.map +1 -0
- package/dist/session/sqlite.d.ts +1 -1
- package/dist/{session-7TUHs42_.js → session-CCsKXID6.js} +6 -2
- package/dist/session-CCsKXID6.js.map +1 -0
- package/dist/{session-factory-CMwIXE-7.js → session-factory-Ct7J9CK1.js} +6 -6
- package/dist/{session-factory-CMwIXE-7.js.map → session-factory-Ct7J9CK1.js.map} +1 -1
- package/dist/session.d.ts +2 -2
- package/dist/session.js +1 -1
- package/dist/{settings-keys-DssjmqAV.js → settings-keys-QoGJ5n3e.js} +4 -4
- package/dist/{settings-keys-DssjmqAV.js.map → settings-keys-QoGJ5n3e.js.map} +1 -1
- package/dist/{shell-path-BUFwqU_A.js → shell-path-BXXtRmEA.js} +4 -4
- package/dist/{shell-path-BUFwqU_A.js.map → shell-path-BXXtRmEA.js.map} +1 -1
- package/dist/skills.d.ts +1 -1
- package/dist/{spaces-CyjMh5Zf.js → spaces-C_x2bvEl.js} +14 -4
- package/dist/spaces-C_x2bvEl.js.map +1 -0
- package/dist/{store-L01W0gGI.js → store-BpkWIaSH.js} +10 -30
- package/dist/store-BpkWIaSH.js.map +1 -0
- package/dist/{todo-edits-H77ROt6X.js → todo-edits-DKoxu7Ss.js} +3 -3
- package/dist/{todo-edits-H77ROt6X.js.map → todo-edits-DKoxu7Ss.js.map} +1 -1
- package/dist/tools/fetch-url.d.ts +1 -1
- package/dist/tools/web-search.d.ts +1 -1
- package/dist/{tools-pZVFIJ_K.js → tools-FHEIKGkh.js} +2 -2
- package/dist/{tools-pZVFIJ_K.js.map → tools-FHEIKGkh.js.map} +1 -1
- package/dist/tools.d.ts +1 -1
- package/dist/tools.js +2 -2
- package/dist/{transcript-anchors-s-yxh0jt.js → transcript-anchors-D8jWLpe5.js} +10 -10
- package/dist/{transcript-anchors-s-yxh0jt.js.map → transcript-anchors-D8jWLpe5.js.map} +1 -1
- package/dist/{transcript-cache-DXdgVuoy.js → transcript-cache-CdHKtx9y.js} +4 -4
- package/dist/{transcript-cache-DXdgVuoy.js.map → transcript-cache-CdHKtx9y.js.map} +1 -1
- package/dist/{transcript-reconcile-DeFLIQ14.js → transcript-reconcile-D_SWw6dX.js} +11 -3
- package/dist/transcript-reconcile-D_SWw6dX.js.map +1 -0
- package/dist/tui.d.ts +7 -7
- package/dist/tui.js +24 -23
- package/dist/tui.js.map +1 -1
- package/dist/{turn-operations-BbGJ-KSt.d.ts → turn-operations-Dbk3xPKu.d.ts} +19 -4
- package/dist/turn-operations-Dbk3xPKu.d.ts.map +1 -0
- package/dist/{types-C0PJmBaO.d.ts → types-CMXR7A0b.d.ts} +2 -2
- package/dist/{types-C0PJmBaO.d.ts.map → types-CMXR7A0b.d.ts.map} +1 -1
- package/dist/types-CzmghX7C.js.map +1 -1
- package/dist/types.d.ts +2 -2
- package/dist/{url-CLl0u4Z8.js → url-D4vG7lzO.js} +2 -2
- package/dist/{url-CLl0u4Z8.js.map → url-D4vG7lzO.js.map} +1 -1
- package/dist/{version-v77Y4A3C.js → version-DDRBX7K6.js} +2 -2
- package/dist/{version-v77Y4A3C.js.map → version-DDRBX7K6.js.map} +1 -1
- package/dist/{workspace-exec-stream-kqARO8iC.js → workspace-exec-stream-iHv9cooF.js} +5 -5
- package/dist/{workspace-exec-stream-kqARO8iC.js.map → workspace-exec-stream-iHv9cooF.js.map} +1 -1
- package/dist/{write-file-QYrcDdl3.js → write-file-ChtRPdEL.js} +3 -3
- package/dist/{write-file-QYrcDdl3.js.map → write-file-ChtRPdEL.js.map} +1 -1
- package/dist/{ws-BD9FN98u.js → ws-B2HB87nz.js} +6 -6
- package/dist/{ws-BD9FN98u.js.map → ws-B2HB87nz.js.map} +1 -1
- package/dist/{ws-client-D7eb2UbH.js → ws-client-DPC9ZJHr.js} +4 -4
- package/dist/{ws-client-D7eb2UbH.js.map → ws-client-DPC9ZJHr.js.map} +1 -1
- package/docs/CODEMODE.md +6 -0
- package/docs/IPC.md +2 -0
- package/docs/ONBOARDING.md +1 -1
- package/package.json +1 -1
- package/dist/client-core-BdD20sOv.d.ts.map +0 -1
- package/dist/dispatcher-BICXFGiJ.js.map +0 -1
- package/dist/index-DyQyDLX1.d.ts.map +0 -1
- package/dist/mcp-allowlist-BQ5MvhHi.js.map +0 -1
- package/dist/oauth-TVPPye84.js.map +0 -1
- package/dist/prelude-HzY_JEGq.js.map +0 -1
- package/dist/protocol-BIv1Yuvl.js.map +0 -1
- package/dist/secret-shapes-CEoGmfEE.js.map +0 -1
- package/dist/session-7TUHs42_.js.map +0 -1
- package/dist/spaces-CyjMh5Zf.js.map +0 -1
- package/dist/store-L01W0gGI.js.map +0 -1
- package/dist/transcript-reconcile-DeFLIQ14.js.map +0 -1
- package/dist/turn-operations-BbGJ-KSt.d.ts.map +0 -1
package/dist/types.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { $T as
|
|
1
|
+
import { $T as ToolDef, $w as McpServerConfig, Aw as DecisionSuccess, B as MutationValidationHooksOptions, BT as ToolResultDocumentContent, Ba as AgentOptions, C as statsByModel, CE as SkillConfig, CT as SessionMessage, Cw as DecisionQuestions, DE as SkillsConfig, Dx as ProviderCapabilities, EC as AnthropicParams, Er as ValidationResult, Ex as Provider, Fa as Agent, Fw as AgentStats, GT as ToolResultTextContent, Gr as InteractionToolOptions, H as MutationValidationResult, HT as ToolResultImageContent, IT as ToolHookContext, Ix as ToolCall, JT as TurnUsage, KT as ToolResultVideoContent, Kw as DEFAULT_AGENT_CLOCK, LT as ToolOutcome, Lx as ToolResult, Mw as AgentBehavior, Nw as AgentClock, Nx as StreamCallbacks, Pw as AgentRunOptions, Px as StreamOptions, QT as ToolContext, Qu as ChildAgent, R as MutationValidationBatch, RT as ToolResultAudioContent, Rx as ToolSpec, ST as SessionHookContext, Sa as Preset, Sw as DecisionQuestion, TE as SkillResource, TT as SpawnHookContext, Tw as DecisionRequest, U as SuccessfulMutationOutcome, UT as ToolResultImageRefContent, V as MutationValidationMutation, VT as ToolResultDocumentRefContent, Va as AgentToolState, WT as ToolResultMetadata, XT as toolOutputByteLength, YE as ThinkingLevel, YT as toolOutputBudgetByteLength, ZT as toolResultToText, Zx as OpenRouterParams, _E as ToolStateStore, _T as ResolveContentRefBlock, _w as DecisionInput, aD as Session, aE as ReadStateEntry, aT as OAuthRefreshHookContext, bT as SessionContentBlock, cT as PromptAudioPart, cw as AgentDecisionsOptions, dD as SessionStore, dT as PromptPart, dw as DecisionAnswers, eE as ToolDescriptionOverride, eT as McpToolHookContext, ex as AgentHookBus, fT as PromptTextPart, gE as ToolStateOp, gT as ResolveContentRef, gw as DecisionFailureReason, hE as ToolStateController, hT as RepeatGuardToolMatcher, hw as DecisionFailure, id as SpawnToolState, ix as DecideHookContext, jw as DecisionUsage, kE as McpConnection, kT as StreamHookContext, kw as DecisionStartHookContext, lD as SessionRun, lT as PromptDocumentPart, lw as DecisionAnswer, mE as StagedToolState, mT as RepeatGuardConfig, mw as DecisionEndHookContext, nE as ToolDescriptions, nx as AgentHookMap, oC as CerebrasParams, oD as SessionData, oE as ReadStateMap, oT as ProgressNudgeKind, pT as PromptVideoPart, qT as TurnFinishReason, rD as CreateSessionOptions, rE as ToolMap, rd as SpawnToolOptions, rx as AgentHooks, sT as ProgressNudgeMessage, sw as AgentDecide, tE as ToolDescriptionTarget, tx as AgentHookHandlers, uT as PromptImagePart, vE as ToolStateView, vT as RetryConfig, wT as SessionTurn, x as flattenTurns, xD as RemoteStoreOptions, xS as OpenAIParams, xT as SessionEndStatus, y as ModelUsage, yT as RunHookMap, yw as DecisionOutcome, z as MutationValidationFailure, zT as ToolResultContent, zw as ChildRunStats, zx as TurnResult } from "./index-4mDRyTGJ.js";
|
|
2
|
+
import { d as ClassifiedErrorKind, i as AgentContextExceededError, l as CONTEXT_EXCEEDED_MESSAGE_PATTERNS, n as AgentAbortedError, o as AgentProviderError, r as AgentBudgetExceededError, s as AgentToolNotAllowedError, u as ClassifiedError, y as matchesContextExceeded } from "./timeout-BcfGsZZG.js";
|
|
2
3
|
import { C as TaskExitInfo, S as TaskEntry, T as TaskStallInfo, b as SpawnConfig, f as ContextType, g as ExecutionHandle, h as ExecutionContext, l as ContextCapabilities, m as ExecResult, p as DetachedTasksCapability, s as BackgroundTaskStatus, u as ContextHardening, w as TaskHandle } from "./isolation-CbGNAEhQ.js";
|
|
3
4
|
import { t as SandboxProvider } from "./sandbox--bc6zacQ.js";
|
|
4
|
-
import { d as ClassifiedErrorKind, i as AgentContextExceededError, l as CONTEXT_EXCEEDED_MESSAGE_PATTERNS, n as AgentAbortedError, o as AgentProviderError, r as AgentBudgetExceededError, s as AgentToolNotAllowedError, u as ClassifiedError, y as matchesContextExceeded } from "./timeout-BcfGsZZG.js";
|
|
5
5
|
import { t as ToolPrompts } from "./prompts-DmY13jvF.js";
|
|
6
6
|
export { type Agent, AgentAbortedError, type AgentBehavior, AgentBudgetExceededError, type AgentClock, AgentContextExceededError, type AgentDecide, type AgentDecisionsOptions, type AgentHookBus, type AgentHookHandlers, type AgentHookMap, type AgentHooks, type AgentOptions, AgentProviderError, type AgentRunOptions, type AgentStats, AgentToolNotAllowedError, type AgentToolState, type AnthropicParams, type BackgroundTaskStatus, CONTEXT_EXCEEDED_MESSAGE_PATTERNS, type CerebrasParams, type ChildAgent, type ChildRunStats, type ClassifiedError, type ClassifiedErrorKind, type ContextCapabilities, type ContextHardening, type ContextType, type CreateSessionOptions, DEFAULT_AGENT_CLOCK, type DecideHookContext, type DecisionAnswer, type DecisionAnswers, type DecisionEndHookContext, type DecisionFailure, type DecisionFailureReason, type DecisionInput, type DecisionOutcome, type DecisionQuestion, type DecisionQuestions, type DecisionRequest, type DecisionStartHookContext, type DecisionSuccess, type DecisionUsage, type DetachedTasksCapability, type ExecResult, type ExecutionContext, type ExecutionHandle, type InteractionToolOptions, type McpConnection, type McpServerConfig, type McpToolHookContext, type ModelUsage, type MutationValidationBatch, type MutationValidationFailure, type MutationValidationHooksOptions, type MutationValidationMutation, type MutationValidationResult, type OAuthRefreshHookContext, type OpenAIParams, type OpenRouterParams, type Preset, type ProgressNudgeKind, type ProgressNudgeMessage, type PromptAudioPart, type PromptDocumentPart, type PromptImagePart, type PromptPart, type PromptTextPart, type PromptVideoPart, type Provider, type ProviderCapabilities, type ReadStateEntry, type ReadStateMap, type RemoteStoreOptions, type RepeatGuardConfig, type RepeatGuardToolMatcher, type ResolveContentRef, type ResolveContentRefBlock, type RetryConfig, type RunHookMap, type SandboxProvider, type Session, type SessionContentBlock, type SessionData, type SessionEndStatus, type SessionHookContext, type SessionMessage, type SessionRun, type SessionStore, type SessionTurn, type SkillConfig, type SkillResource, type SkillsConfig, type SpawnConfig, type SpawnHookContext, type SpawnToolOptions, type SpawnToolState, type StagedToolState, type StreamCallbacks, type StreamHookContext, type StreamOptions, type SuccessfulMutationOutcome, type TaskEntry, type TaskExitInfo, type TaskHandle, type TaskStallInfo, type ThinkingLevel, type ToolCall, type ToolContext, type ToolDef, type ToolDescriptionOverride, type ToolDescriptionTarget, type ToolDescriptions, type ToolHookContext, type ToolMap, type ToolOutcome, type ToolPrompts, type ToolResult, type ToolResultAudioContent, type ToolResultContent, type ToolResultDocumentContent, type ToolResultDocumentRefContent, type ToolResultImageContent, type ToolResultImageRefContent, type ToolResultMetadata, type ToolResultTextContent, type ToolResultVideoContent, type ToolSpec, type ToolStateController, type ToolStateOp, type ToolStateStore, type ToolStateView, type TurnFinishReason, type TurnResult, type TurnUsage, type ValidationResult, flattenTurns, matchesContextExceeded, statsByModel, toolOutputBudgetByteLength, toolOutputByteLength, toolResultToText };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as isSecretPathSegment } from "./secret-shapes-
|
|
1
|
+
import { r as isSecretPathSegment } from "./secret-shapes-HvaYVzwc.js";
|
|
2
2
|
//#region src/chat/hosts/url.ts
|
|
3
3
|
/**
|
|
4
4
|
* Host URLs a client accepts: `wss://`, or `ws://` to this machine only (a
|
|
@@ -78,4 +78,4 @@ function parseRemoteHostUrl(raw) {
|
|
|
78
78
|
//#endregion
|
|
79
79
|
export { urlCarriesSecrets as i, displayHostUrl as n, parseRemoteHostUrl as r, RemoteHostError as t };
|
|
80
80
|
|
|
81
|
-
//# sourceMappingURL=url-
|
|
81
|
+
//# sourceMappingURL=url-D4vG7lzO.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"url-
|
|
1
|
+
{"version":3,"file":"url-D4vG7lzO.js","names":[],"sources":["../src/chat/hosts/url.ts"],"sourcesContent":["/**\n * Host URLs a client accepts: `wss://`, or `ws://` to this machine only (a\n * token must not cross the network in the clear), with no credentials in\n * them: no `user:pass@`, no query string, no fragment, no token-looking\n * path segment (`wss://h/zds_…`, a long random id: the shapes the MCP\n * catalog redacts, `../secret-shapes`). Tokens go in the token field, and a\n * URL ends up in hosts.json, error messages and the GUI's renderer.\n * Messages show {@link displayHostUrl}, never the input. Node-free.\n */\nimport { isSecretPathSegment } from '../secret-shapes'\n\n/** Error thrown for a host URL a client refuses. */\nexport class RemoteHostError extends Error {\n /**\n * Creates the error.\n * @param message - Human-readable description.\n */\n constructor(message: string) {\n super(message)\n this.name = 'RemoteHostError'\n }\n}\n\n/**\n * A loopback host: `localhost`, `127.x.x.x` or `::1` (bracketed, as in a URL,\n * or bare, as an interface to bind). The one check for both ends: a client\n * allowing `ws://`, a server refusing to listen in the clear.\n */\nexport function isLoopbackHost(host: string): boolean {\n const bare = host.startsWith('[') && host.endsWith(']') ? host.slice(1, -1) : host\n return bare === 'localhost' || bare === '::1' || /^127\\.\\d+\\.\\d+\\.\\d+$/.test(bare)\n}\n\n/** Shown in place of a path segment that looks like a credential. */\nconst REDACTED_SEGMENT = '<redacted>'\n\n/**\n * Scheme, host, port and path of a URL (token-looking path segments redacted): what is safe to show or log.\n *\n * @param raw - URL as entered. An invalid URL reads as `<invalid URL>`.\n */\nexport function displayHostUrl(raw: string): string {\n try {\n const url = new URL(raw.trim())\n const path = url.pathname.split('/').map(segment => isSecretPathSegment(segment) ? REDACTED_SEGMENT : segment).join('/')\n return `${url.protocol}//${url.host}${path.replace(/\\/$/, '')}`\n }\n catch {\n return '<invalid URL>'\n }\n}\n\n/** `raw` carries something {@link parseRemoteHostUrl} refuses as a credential (userinfo, query, fragment, a token-looking path segment). */\nexport function urlCarriesSecrets(raw: string): boolean {\n if (/[@?#]/.test(raw))\n return true\n try {\n return new URL(raw.trim()).pathname.split('/').some(isSecretPathSegment)\n }\n catch {\n return false\n }\n}\n\n/**\n * Validate and normalize a host URL (no trailing slash); throws {@link RemoteHostError}.\n *\n * @param raw - URL as entered.\n */\nexport function parseRemoteHostUrl(raw: string): string {\n let url: URL\n try {\n url = new URL(raw.trim())\n }\n catch {\n throw new RemoteHostError('Invalid host URL: expected wss://host[:port].')\n }\n const shown = displayHostUrl(raw)\n if (url.username !== '' || url.password !== '')\n throw new RemoteHostError(`Host URLs can't carry a user or password (${shown}): put the token in the token field (or --token-file), not in the URL.`)\n if (url.search !== '' || raw.includes('?'))\n throw new RemoteHostError(`Host URLs can't carry a query string (${shown}): remove it; a token goes in the token field (or --token-file).`)\n if (url.hash !== '' || raw.includes('#'))\n throw new RemoteHostError(`Host URLs can't carry a fragment (${shown}): remove it.`)\n if (url.pathname.split('/').some(isSecretPathSegment))\n throw new RemoteHostError(`Host URLs can't carry a token in their path (${url.protocol}//${url.host}): remove it; a token goes in the token field (or --token-file).`)\n if (url.protocol === 'wss:' || (url.protocol === 'ws:' && isLoopbackHost(url.hostname)))\n return url.href.replace(/\\/$/, '')\n if (url.protocol === 'ws:')\n throw new RemoteHostError(`Refusing ws://${url.host}: the token would travel unencrypted. Use wss:// (ws:// is only for 127.0.0.1 / localhost).`)\n throw new RemoteHostError(`Invalid host URL ${shown}: expected wss://host[:port].`)\n}\n"],"mappings":";;;;;;;;;;;;AAYA,IAAa,kBAAb,cAAqC,MAAM;;;;;CAKzC,YAAY,SAAiB;EAC3B,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF;;;;;;AAOA,SAAgB,eAAe,MAAuB;CACpD,MAAM,OAAO,KAAK,WAAW,GAAG,KAAK,KAAK,SAAS,GAAG,IAAI,KAAK,MAAM,GAAG,EAAE,IAAI;CAC9E,OAAO,SAAS,eAAe,SAAS,SAAS,uBAAuB,KAAK,IAAI;AACnF;;AAGA,MAAM,mBAAmB;;;;;;AAOzB,SAAgB,eAAe,KAAqB;CAClD,IAAI;EACF,MAAM,MAAM,IAAI,IAAI,IAAI,KAAK,CAAC;EAC9B,MAAM,OAAO,IAAI,SAAS,MAAM,GAAG,CAAC,CAAC,KAAI,YAAW,oBAAoB,OAAO,IAAI,mBAAmB,OAAO,CAAC,CAAC,KAAK,GAAG;EACvH,OAAO,GAAG,IAAI,SAAS,IAAI,IAAI,OAAO,KAAK,QAAQ,OAAO,EAAE;CAC9D,QACM;EACJ,OAAO;CACT;AACF;;AAGA,SAAgB,kBAAkB,KAAsB;CACtD,IAAI,QAAQ,KAAK,GAAG,GAClB,OAAO;CACT,IAAI;EACF,OAAO,IAAI,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,SAAS,MAAM,GAAG,CAAC,CAAC,KAAK,mBAAmB;CACzE,QACM;EACJ,OAAO;CACT;AACF;;;;;;AAOA,SAAgB,mBAAmB,KAAqB;CACtD,IAAI;CACJ,IAAI;EACF,MAAM,IAAI,IAAI,IAAI,KAAK,CAAC;CAC1B,QACM;EACJ,MAAM,IAAI,gBAAgB,+CAA+C;CAC3E;CACA,MAAM,QAAQ,eAAe,GAAG;CAChC,IAAI,IAAI,aAAa,MAAM,IAAI,aAAa,IAC1C,MAAM,IAAI,gBAAgB,6CAA6C,MAAM,uEAAuE;CACtJ,IAAI,IAAI,WAAW,MAAM,IAAI,SAAS,GAAG,GACvC,MAAM,IAAI,gBAAgB,yCAAyC,MAAM,iEAAiE;CAC5I,IAAI,IAAI,SAAS,MAAM,IAAI,SAAS,GAAG,GACrC,MAAM,IAAI,gBAAgB,qCAAqC,MAAM,cAAc;CACrF,IAAI,IAAI,SAAS,MAAM,GAAG,CAAC,CAAC,KAAK,mBAAmB,GAClD,MAAM,IAAI,gBAAgB,gDAAgD,IAAI,SAAS,IAAI,IAAI,KAAK,iEAAiE;CACvK,IAAI,IAAI,aAAa,UAAW,IAAI,aAAa,SAAS,eAAe,IAAI,QAAQ,GACnF,OAAO,IAAI,KAAK,QAAQ,OAAO,EAAE;CACnC,IAAI,IAAI,aAAa,OACnB,MAAM,IAAI,gBAAgB,iBAAiB,IAAI,KAAK,4FAA4F;CAClJ,MAAM,IAAI,gBAAgB,oBAAoB,MAAM,8BAA8B;AACpF"}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* retires it, so an upgrade can never leave windows silently executing on a
|
|
12
12
|
* process started from the previous release.
|
|
13
13
|
*/
|
|
14
|
-
const ZIDANE_VERSION = "8.2.
|
|
14
|
+
const ZIDANE_VERSION = "8.2.4";
|
|
15
15
|
/**
|
|
16
16
|
* Compare two dotted versions (`7.0.19`, `7.1.0-beta.1`): negative when `a`
|
|
17
17
|
* is older, positive when newer, 0 when equal. Pre-release tags are ignored
|
|
@@ -39,4 +39,4 @@ function parse(v) {
|
|
|
39
39
|
//#endregion
|
|
40
40
|
export { compareVersions as n, ZIDANE_VERSION as t };
|
|
41
41
|
|
|
42
|
-
//# sourceMappingURL=version-
|
|
42
|
+
//# sourceMappingURL=version-DDRBX7K6.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version-
|
|
1
|
+
{"version":3,"file":"version-DDRBX7K6.js","names":["(pkg as { version?: string }).version"],"sources":["../package.json","../src/version.ts"],"sourcesContent":["","/**\n * The version of the zidane code this process is running — `package.json`\n * inlined at build time (Bun `--compile`, tsdown for `dist/`, and Vite for\n * the GUI main all fold JSON imports into the bundle, so this never reads\n * the filesystem at runtime and cannot report a NEIGHBOUR package's version\n * the way a `require('../package.json')` from a bundled chunk can).\n *\n * Used by the daemon handshake: a client running newer code than the daemon\n * retires it, so an upgrade can never leave windows silently executing on a\n * process started from the previous release.\n */\nimport pkg from '../package.json' with { type: 'json' }\n\nexport const ZIDANE_VERSION: string = (pkg as { version?: string }).version ?? '0.0.0'\n\n/**\n * Compare two dotted versions (`7.0.19`, `7.1.0-beta.1`): negative when `a`\n * is older, positive when newer, 0 when equal. Pre-release tags are ignored\n * — same release train, same code as far as the daemon fence is concerned.\n * Unparseable input compares equal (never fences on garbage).\n */\nexport function compareVersions(a: string, b: string): number {\n const pa = parse(a)\n const pb = parse(b)\n if (!pa || !pb)\n return 0\n for (let i = 0; i < 3; i++) {\n const d = (pa[i] ?? 0) - (pb[i] ?? 0)\n if (d !== 0)\n return d\n }\n return 0\n}\n\nfunction parse(v: string): number[] | null {\n const m = /^v?(\\d+)\\.(\\d+)\\.(\\d+)/.exec(v.trim())\n return m ? [Number(m[1]), Number(m[2]), Number(m[3])] : null\n}\n"],"mappings":";;;;;;;;;;;;;ACaA,MAAa,iBAAyBA;;;;;;;AAQtC,SAAgB,gBAAgB,GAAW,GAAmB;CAC5D,MAAM,KAAK,MAAM,CAAC;CAClB,MAAM,KAAK,MAAM,CAAC;CAClB,IAAI,CAAC,MAAM,CAAC,IACV,OAAO;CACT,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;EAC1B,MAAM,KAAK,GAAG,MAAM,MAAM,GAAG,MAAM;EACnC,IAAI,MAAM,GACR,OAAO;CACX;CACA,OAAO;AACT;AAEA,SAAS,MAAM,GAA4B;CACzC,MAAM,IAAI,yBAAyB,KAAK,EAAE,KAAK,CAAC;CAChD,OAAO,IAAI;EAAC,OAAO,EAAE,EAAE;EAAG,OAAO,EAAE,EAAE;EAAG,OAAO,EAAE,EAAE;CAAC,IAAI;AAC1D"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { S as startOAuthCallback } from "./mcp-BnXLqb2R.js";
|
|
2
|
-
import { t as ZIDANE_VERSION } from "./version-
|
|
2
|
+
import { t as ZIDANE_VERSION } from "./version-DDRBX7K6.js";
|
|
3
3
|
import { n as JsonRpcRemoteError, t as JsonRpcConnectionClosedError } from "./json-rpc-G0rBfEar.js";
|
|
4
4
|
import { a as isMethodNotFound } from "./connection-BaHd3T-D.js";
|
|
5
|
-
import { s as IPC_BUILD_ID } from "./settings-keys-
|
|
6
|
-
import "./protocol-
|
|
7
|
-
import { t as createHostDispatcher } from "./dispatcher-
|
|
5
|
+
import { s as IPC_BUILD_ID } from "./settings-keys-QoGJ5n3e.js";
|
|
6
|
+
import "./protocol-Do_i6Ras.js";
|
|
7
|
+
import { t as createHostDispatcher } from "./dispatcher-Dclv6HXn.js";
|
|
8
8
|
//#region src/ipc/memory.ts
|
|
9
9
|
/** JSON round-trip: what crossing the socket does to a value. */
|
|
10
10
|
function wire(value) {
|
|
@@ -382,4 +382,4 @@ async function buffered(client, params, options, started) {
|
|
|
382
382
|
//#endregion
|
|
383
383
|
export { runRemoteOAuth as n, startInProcessHost as r, runWorkspaceExecStream as t };
|
|
384
384
|
|
|
385
|
-
//# sourceMappingURL=workspace-exec-stream-
|
|
385
|
+
//# sourceMappingURL=workspace-exec-stream-iHv9cooF.js.map
|
package/dist/{workspace-exec-stream-kqARO8iC.js.map → workspace-exec-stream-iHv9cooF.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-exec-stream-kqARO8iC.js","names":[],"sources":["../src/ipc/memory.ts","../src/ipc/remote-oauth.ts","../src/ipc/workspace-exec-stream.ts"],"sourcesContent":["/**\n * In-process transport: the host dispatcher in the window's own process, and\n * `IpcClient`s that call it directly instead of over a unix socket.\n *\n * For a window that runs its own host (TUI local mode on the shared engine):\n * the same dispatcher, method table and signal fan-out a daemon serves, with\n * no socket, no spawn and no second process. A caller sees what a socket\n * client would, so the daemon-mode code paths run on it unchanged:\n * - params, results and signals are JSON copies (as on the wire: a top-level\n * `undefined` result arrives as `null`, nested `undefined` fields are\n * dropped, and nothing is shared between the window and the host);\n * - a failed request rejects with `JsonRpcRemoteError` carrying the\n * dispatcher's code; a closed connection rejects with\n * `JsonRpcConnectionClosedError`, in-flight requests included;\n * - responses and signals arrive asynchronously, through one queue in the\n * order the host produced them (a socket reads them in write order);\n * - `close()` detaches quietly; the host shutting down calls `onClose`.\n *\n * Two socket behaviors are deliberately absent. Request deadlines exist on\n * the socket to recover from a wedged daemon by dropping the connection and\n * reconnecting; in-process there is nothing to reconnect to. And\n * `daemon.shutdown` from a client does not stop the host: its lifetime\n * belongs to the embedding window (`InProcessHost.close()`).\n */\nimport type { ChatHost } from '../chat/host/engine'\nimport type { IpcClient } from './client'\nimport type { HostPeer } from './daemon/dispatcher'\nimport type { DaemonEnvironment } from './daemon/environment'\nimport type { HelloResult, HostSignal } from './protocol'\nimport type { SignalListener } from './transports/client-core'\nimport { JsonRpcConnectionClosedError, JsonRpcRemoteError } from '../acp/json-rpc'\nimport { ZIDANE_VERSION } from '../version'\nimport { createHostDispatcher } from './daemon/dispatcher'\nimport { IPC_BUILD_ID } from './daemon/lifecycle'\nimport { IPC_PROTOCOL_VERSION } from './protocol'\n\n/** Options for {@link startInProcessHost}. */\nexport interface InProcessHostOptions {\n /** The host's environment, given the broadcast sink wired to client fan-out. */\n createEnvironment: (broadcast: (signal: HostSignal) => void) => DaemonEnvironment | Promise<DaemonEnvironment>\n /** Reported to clients as the host's `appVersion`. */\n appVersion?: string\n}\n\n/** Options for {@link InProcessHost.connect}. */\nexport interface InProcessClientOptions {\n /** Client version, surfaced in the host's diagnostics. */\n appVersion?: string\n /** Called when the host shuts down under a still-open client. */\n onClose?: () => void\n}\n\n/** A chat host running in the caller's process, with clients that call it directly. */\nexport interface InProcessHost {\n /** The chat host. */\n host: ChatHost\n /** A new client, already past the `ipc.hello` handshake. */\n connect: (options?: InProcessClientOptions) => Promise<IpcClient>\n /** Number of open clients. */\n peerCount: () => number\n /**\n * Shut the host down: refuse new work, abort and await every run, then\n * close the clients still open (their `onClose` fires). Idempotent.\n */\n close: () => Promise<void>\n}\n\n/** JSON round-trip: what crossing the socket does to a value. */\nfunction wire<T>(value: T): T {\n return value === undefined ? (null as T) : JSON.parse(JSON.stringify(value)) as T\n}\n\n/** One open client, from the host's side. */\ninterface Connection {\n peer: HostPeer\n /** The host is shutting down: reject what is pending, then tell the client. */\n hostClosed: () => void\n}\n\n/**\n * Starts a chat host in this process. Clients from `connect` behave like socket clients, without a socket or a second process.\n * @param options - Environment factory and version.\n * @returns The host handle.\n */\nexport async function startInProcessHost(options: InProcessHostOptions): Promise<InProcessHost> {\n const connections = new Set<Connection>()\n let closing: Promise<void> | null = null\n\n const dispatcher = await createHostDispatcher({\n createEnvironment: options.createEnvironment,\n appVersion: options.appVersion ?? 'dev',\n startedAt: Date.now(),\n identity: { kind: 'in-process' },\n lifecycle: {\n // Owned by the embedding window, see the module header.\n shutdown: () => undefined,\n // Clients are this build by construction: never a newer one to retire for.\n retireWhenIdle: () => undefined,\n isRetiring: () => false,\n },\n })\n\n async function connect(clientOptions: InProcessClientOptions = {}): Promise<IpcClient> {\n if (closing)\n throw new JsonRpcConnectionClosedError()\n const listeners = new Set<SignalListener>()\n const pending = new Set<(err: Error) => void>()\n let closed = false\n\n /*\n * Everything bound for the client goes through one FIFO drained in a\n * microtask: signals, and request outcomes once the dispatcher settles\n * them. A signal the host emits after answering a request is therefore\n * delivered after that answer, as a socket would read them.\n */\n const outbox: Array<() => void> = []\n let draining = false\n const deliver = (item: () => void): void => {\n outbox.push(item)\n if (draining)\n return\n draining = true\n queueMicrotask(() => {\n try {\n while (outbox.length > 0) {\n try {\n outbox.shift()!()\n }\n catch {\n // A throwing listener costs that one message, as on the socket\n // (the JSON-RPC reader catches it), never the connection.\n }\n }\n }\n finally {\n draining = false\n }\n })\n }\n\n const peer: HostPeer = {\n ready: false,\n watching: null,\n send(signal, seq, encoded) {\n if (closed)\n return\n const meta = seq === undefined ? undefined : { seq }\n let copy: HostSignal\n try {\n // The fan-out's one serialization, when it has one.\n const json = encoded ? encoded.json() : JSON.stringify(signal)\n if (json === undefined)\n return\n copy = JSON.parse(json) as HostSignal\n }\n catch {\n // Not JSON-able: the socket server drops it the same way, and a\n // bad signal must never break fan-out to the other clients.\n return\n }\n deliver(() => {\n if (closed)\n return\n for (const listener of listeners)\n listener(copy, meta)\n })\n },\n }\n\n const request = (method: string, params: unknown): Promise<unknown> => {\n if (closed)\n return Promise.reject(new JsonRpcConnectionClosedError())\n return new Promise((resolve, reject) => {\n pending.add(reject)\n const settle = (outcome: () => void): void => {\n deliver(() => {\n if (!pending.delete(reject))\n return\n outcome()\n })\n }\n dispatcher.handleRequest(method, params === undefined ? undefined : wire(params), peer).then(\n (result) => {\n settle(() => {\n // The reject is already out of `pending`: a throw here (a result\n // that is not JSON-able) must fail the request, not hang it.\n try {\n if (result.ok)\n resolve(wire(result.result))\n else\n reject(new JsonRpcRemoteError(result.message, result.code, result.data))\n }\n catch (err) {\n reject(err instanceof Error ? err : new Error(String(err)))\n }\n })\n },\n err => settle(() => reject(err)),\n )\n })\n }\n\n /** Stop delivering and fail what is in flight, as a socket closing does. */\n const shut = (): void => {\n closed = true\n listeners.clear()\n outbox.length = 0\n for (const reject of pending)\n reject(new JsonRpcConnectionClosedError())\n pending.clear()\n }\n\n const connection: Connection = {\n peer,\n hostClosed: () => {\n if (closed)\n return\n shut()\n clientOptions.onClose?.()\n },\n }\n\n dispatcher.addPeer(peer)\n connections.add(connection)\n const detach = (): void => {\n if (closed)\n return\n shut()\n connections.delete(connection)\n dispatcher.removePeer(peer)\n }\n\n let hello: HelloResult\n try {\n hello = await request('ipc.hello', {\n protocolVersion: IPC_PROTOCOL_VERSION,\n appVersion: clientOptions.appVersion ?? 'dev',\n pid: process.pid,\n buildId: IPC_BUILD_ID,\n codeVersion: ZIDANE_VERSION,\n }) as HelloResult\n }\n catch (err) {\n detach()\n throw err\n }\n\n return {\n hello,\n request: request as IpcClient['request'],\n notify: (method, params) => {\n if (closed)\n return\n const copy = params === undefined ? undefined : wire(params)\n // Off the caller's stack, as a socket write would be.\n queueMicrotask(() => {\n if (!closed)\n void dispatcher.handleNotification(method, copy, peer)\n })\n },\n onSignal: (listener) => {\n listeners.add(listener)\n return () => listeners.delete(listener)\n },\n close: detach,\n }\n }\n\n function close(): Promise<void> {\n // Same order as the socket server's shutdown: drain the host, close\n // every connection, then forget the peers without per-peer cleanup.\n closing ??= (async () => {\n await dispatcher.host.drain()\n for (const connection of connections)\n connection.hostClosed()\n connections.clear()\n dispatcher.detachAll()\n })()\n return closing\n }\n\n return {\n host: dispatcher.host,\n connect,\n peerCount: () => dispatcher.peerCount(),\n close,\n }\n}\n","/**\n * The client half of a remote OAuth sign-in (`auth.oauth.*`): the host runs\n * the login and keeps its secrets; this machine has the browser. For an MCP\n * server it opens a loopback listener first (any free port) and hands its\n * URI to the host; for a provider it listens on the provider's fixed\n * `redirect_uri` once the host names it (a busy port falls back to pasting\n * the address the browser lands on). It opens the URL, forwards the code\n * (or what the user pasted) to the host, and resolves with the host's\n * outcome, which never carries a token. Device and polling flows just wait.\n *\n * The provider's own questions (a choice between flows, a free-text\n * prompt: `HostOAuthStep`) come back from `begin` / `complete`; the UI\n * answers them (`select` / `prompt`; a prompt falls back to `paste`). A UI\n * that can't answers nothing: the sign-in ends with why, never a default.\n */\nimport type { McpOAuthCallbackPageRenderer, OAuthCallbackHandle } from '../mcp/oauth-callback'\nimport type { HostOAuthBegin, HostOAuthComplete, HostOAuthStep } from './protocol'\nimport type { IpcClient } from './transports/client-core'\nimport { startOAuthCallback } from '../mcp/oauth-callback'\n\n/** What to sign in to: a provider by key, or an MCP server by name. */\nexport type RemoteOAuthTarget = { provider: string } | { mcpServer: string, cwd?: string, kind?: string }\n\nexport interface RemoteOAuthStart extends HostOAuthBegin {\n /** This machine catches the redirect (else: paste, or wait for a device / polling flow). */\n listening: boolean\n /** Why it doesn't (a busy port). */\n listenError?: string\n}\n\n/** Hooks a window supplies to {@link runRemoteOAuth}: open the browser, take pasted input, answer the provider's questions, and abort. */\nexport interface RemoteOAuthUi {\n /** Open the browser here (best effort; the URL is shown too). */\n openUrl: (url: string) => void | Promise<void>\n /** The flow started: the URL, the mode, a device code, whether the loopback listens. */\n onStart?: (start: RemoteOAuthStart) => void\n /** What the user pastes (a code or the address the browser landed on); offered in every mode. */\n paste?: () => Promise<string>\n /** Aborts the sign-in. The run rejects with \"OAuth login aborted\". */\n signal?: AbortSignal\n /** The page the browser lands on at the loopback. */\n renderPage?: McpOAuthCallbackPageRenderer\n /** The provider asks the user to choose (its option id; `undefined` cancels). */\n select?: (step: Extract<HostOAuthStep, { kind: 'select' }>) => Promise<string | undefined>\n /** The provider asks the user a question (default: {@link paste}). */\n prompt?: (step: Extract<HostOAuthStep, { kind: 'prompt' }>) => Promise<string>\n}\n\n/** The UI's answer to `step`, or why it can't give one. */\nasync function answerStep(ui: RemoteOAuthUi, step: HostOAuthStep): Promise<string | undefined> {\n if (step.kind === 'select' && ui.select)\n return ui.select(step)\n if (step.kind === 'prompt' && (ui.prompt || ui.paste))\n return ui.prompt ? ui.prompt(step) : ui.paste!()\n throw new Error(`The sign-in asks \"${step.message}\", and this window can't answer it here: sign in on the server machine or use an API key.`)\n}\n\nconst abortError = (): Error => new Error('OAuth login aborted')\n\nfunction whenAborted(signal: AbortSignal | undefined): Promise<never> {\n return new Promise<never>((_, reject) => {\n if (signal?.aborted)\n reject(abortError())\n signal?.addEventListener('abort', () => reject(abortError()), { once: true })\n })\n}\n\n/**\n * Runs the client half of a remote OAuth sign-in against a host.\n * Starts the flow on the host, opens the URL through the UI, forwards the code from the loopback listener or from `paste`, and resolves with the host's outcome, which never carries a token. Rejects when aborted or when the UI cannot answer a question the provider asks.\n * @param client - Client used for the `auth.oauth.*` requests.\n * @param target - Provider or MCP server to sign in to.\n * @param ui - Browser, prompt and abort hooks.\n * @returns The sign-in outcome: the provider status or the MCP server name.\n */\nexport async function runRemoteOAuth(\n client: Pick<IpcClient, 'request'>,\n target: RemoteOAuthTarget,\n ui: RemoteOAuthUi,\n): Promise<HostOAuthComplete> {\n const { signal } = ui\n signal?.throwIfAborted()\n const isMcp = 'mcpServer' in target\n let loopback: OAuthCallbackHandle | undefined\n const listenOptions = { ...(signal ? { signal } : {}), ...(ui.renderPage ? { renderPage: ui.renderPage } : {}), provider: isMcp ? target.mcpServer : target.provider }\n if (isMcp)\n loopback = await startOAuthCallback({ ...listenOptions, port: 0 })\n let begin: HostOAuthBegin | undefined\n try {\n begin = await client.request('auth.oauth.begin', isMcp\n ? { mcpServer: target.mcpServer, ...(target.cwd !== undefined ? { cwd: target.cwd } : {}), ...(target.kind !== undefined ? { kind: target.kind } : {}), redirectUri: loopback!.redirectUri }\n : { provider: target.provider })\n const flowId = begin.flowId\n const respond = async (step: HostOAuthStep): Promise<HostOAuthBegin> => {\n const value = await answerStep(ui, step)\n signal?.throwIfAborted()\n return client.request('auth.oauth.respond', { flowId, stepId: step.id, ...(value !== undefined ? { value } : {}) })\n }\n // Questions before the URL.\n while (begin.step)\n begin = await respond(begin.step)\n let listenError: string | undefined\n // The host pinned another redirect (an MCP server's pre-registered\n // client, `oauth.callbackPort`): listen there instead.\n if (loopback && begin.redirectUri && begin.redirectUri !== loopback.redirectUri) {\n loopback.promise.catch(() => undefined) // closing rejects it; nothing waits on it\n await loopback.close()\n loopback = undefined\n }\n if (!loopback && begin.mode === 'loopback' && begin.redirectUri) {\n const redirect = new URL(begin.redirectUri)\n try {\n loopback = await startOAuthCallback({ ...listenOptions, port: Number(redirect.port), path: redirect.pathname })\n }\n catch (err) {\n listenError = `Port ${redirect.port} is busy on this computer (${err instanceof Error ? err.message : String(err)}): paste the address the browser lands on instead.`\n }\n }\n ui.onStart?.({ ...begin, listening: loopback !== undefined, ...(listenError ? { listenError } : {}) })\n await ui.openUrl(begin.url)\n\n /** Deliver (once), then wait; a question after the URL is answered and the wait goes on. */\n const complete = async (params: { code?: string, state?: string, input?: string }): Promise<HostOAuthComplete> => {\n let outcome = await client.request('auth.oauth.complete', { flowId, ...params })\n while (outcome.step) {\n await respond(outcome.step)\n outcome = await client.request('auth.oauth.complete', { flowId })\n }\n return outcome\n }\n const ways: Promise<HostOAuthComplete>[] = [whenAborted(signal)]\n if (loopback) {\n const handle = loopback\n ways.push(handle.promise.then(({ code, state }) => complete({ code, ...(state !== undefined ? { state } : {}) })))\n }\n if (ui.paste)\n ways.push(ui.paste().then(input => complete({ input })))\n // Device and polling flows finish on the host's side: wait for it.\n if (begin.mode !== 'loopback')\n ways.push(complete({}))\n for (const way of ways)\n way.catch(() => undefined)\n return await Promise.race(ways)\n }\n catch (err) {\n if (begin)\n void client.request('auth.oauth.cancel', { flowId: begin.flowId }).catch(() => undefined)\n throw err\n }\n finally {\n await loopback?.close()\n }\n}\n","/**\n * The client half of a streamed workspace command (`!` on a remote host):\n * starts `sessions.workspaceExecStream`, gathers its `workspace:exec:*`\n * signals (which may beat the reply) into one output in arrival order, and\n * cancels on the host when `signal` aborts. The result has the shape of a\n * local `!` run (`BashRunResult`), so both format and persist alike. A host\n * without the method gets the buffered `sessions.workspaceExec`, where an\n * abort stops waiting, not the command.\n */\nimport type { HostSignal } from './protocol'\nimport type { IpcClient } from './transports/client-core'\nimport { isMethodNotFound } from '../chat/hosts/connection'\n\n/** Outcome of {@link runWorkspaceExecStream}, shaped like a local `!` run. */\nexport interface WorkspaceExecStreamResult {\n /** stdout and stderr in arrival order (the buffered fallback: stdout, then stderr). */\n output: string\n /** `null` when the host killed it (cancel, output cap). */\n exitCode: number | null\n /** Wall-clock time of the run in milliseconds. */\n durationMs: number\n /** Cancelled through `signal`. */\n aborted: boolean\n /** The host's output cap was reached and the process stopped. */\n overflowed: boolean\n /** `false`: an older host answered with the buffered exec. */\n streamed: boolean\n}\n\n/** Options for {@link runWorkspaceExecStream}. */\nexport interface WorkspaceExecStreamOptions {\n /** Cancels the command on the host when aborted. */\n signal?: AbortSignal\n /** The whole output so far, on every chunk. */\n onChunk?: (accumulated: string) => void\n /** The buffered fallback's bound. Default 600 s. */\n fallbackTimeoutSeconds?: number\n /** How long to wait for the host's exit after a cancel before giving up on it. Default 10 s. */\n cancelGraceMs?: number\n}\n\ntype ExecSignal = Extract<HostSignal, { kind: 'workspace:exec:data' | 'workspace:exec:exit' }>\n\n/**\n * Runs a command in a session's workspace on a host and streams its output.\n * The result has the shape of a local `!` run. A host without `sessions.workspaceExecStream` gets the buffered `sessions.workspaceExec` instead, and then an abort stops the wait, not the command.\n * @param client - Client used for requests and signals.\n * @param params - Session, command and optional working directory.\n * @param options - Abort signal, chunk callback and timeouts.\n * @returns The output, exit code and flags describing how it ended.\n */\nexport async function runWorkspaceExecStream(\n client: Pick<IpcClient, 'request' | 'onSignal'>,\n params: { sessionId: string, command: string, cwd?: string },\n options: WorkspaceExecStreamOptions = {},\n): Promise<WorkspaceExecStreamResult> {\n const { signal } = options\n const started = Date.now()\n signal?.throwIfAborted()\n\n let execId: string | null = null\n /** Signals that arrived before the reply named the exec. */\n const early: ExecSignal[] = []\n let output = ''\n let finish: (exit: Extract<ExecSignal, { kind: 'workspace:exec:exit' }> | null) => void = () => undefined\n const exited = new Promise<Extract<ExecSignal, { kind: 'workspace:exec:exit' }> | null>((resolve) => {\n finish = resolve\n })\n const apply = (event: ExecSignal): void => {\n if (event.kind === 'workspace:exec:data') {\n output += event.chunk\n options.onChunk?.(output)\n return\n }\n finish(event)\n }\n const unsubscribe = client.onSignal((event) => {\n if (event.kind !== 'workspace:exec:data' && event.kind !== 'workspace:exec:exit')\n return\n if (execId === null)\n early.push(event)\n else if (event.execId === execId)\n apply(event)\n })\n\n try {\n try {\n execId = (await client.request('sessions.workspaceExecStream', { sessionId: params.sessionId, command: params.command, ...(params.cwd !== undefined ? { cwd: params.cwd } : {}) })).execId\n }\n catch (err) {\n if (!isMethodNotFound(err))\n throw err\n return await buffered(client, params, options, started)\n }\n for (const event of early.splice(0)) {\n if (event.execId === execId)\n apply(event)\n }\n\n const id = execId\n const onAbort = (): void => {\n void client.request('sessions.workspaceExecCancel', { execId: id }).catch(() => undefined)\n // The exit normally follows the kill; a connection lost meanwhile must not hang the caller.\n setTimeout(finish, options.cancelGraceMs ?? 10_000, null).unref?.()\n }\n signal?.addEventListener('abort', onAbort, { once: true })\n if (signal?.aborted)\n onAbort()\n let exit: Awaited<typeof exited>\n try {\n exit = await exited\n }\n finally {\n signal?.removeEventListener('abort', onAbort)\n }\n return {\n output,\n exitCode: exit === null || exit.signal !== null ? null : exit.code,\n durationMs: Date.now() - started,\n aborted: signal?.aborted === true,\n overflowed: exit?.truncated === true,\n streamed: true,\n }\n }\n finally {\n unsubscribe()\n }\n}\n\n/** An older host: one buffered exec; `signal` stops waiting for it. */\nasync function buffered(\n client: Pick<IpcClient, 'request'>,\n params: { sessionId: string, command: string, cwd?: string },\n options: WorkspaceExecStreamOptions,\n started: number,\n): Promise<WorkspaceExecStreamResult> {\n const { signal } = options\n const request = client.request('sessions.workspaceExec', {\n sessionId: params.sessionId,\n command: params.command,\n ...(params.cwd !== undefined ? { cwd: params.cwd } : {}),\n timeoutSeconds: options.fallbackTimeoutSeconds ?? 600,\n })\n const stopped = new Promise<null>((resolve) => {\n if (signal?.aborted)\n resolve(null)\n signal?.addEventListener('abort', () => resolve(null), { once: true })\n })\n request.catch(() => undefined)\n const result = await Promise.race([request, stopped])\n if (!result)\n return { output: '', exitCode: null, durationMs: Date.now() - started, aborted: true, overflowed: false, streamed: false }\n const output = [result.stdout, result.stderr].filter(part => part.trim() !== '').map(part => part.replace(/\\n$/, '')).join('\\n')\n options.onChunk?.(output)\n return { output, exitCode: result.exitCode, durationMs: Date.now() - started, aborted: false, overflowed: false, streamed: false }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"workspace-exec-stream-iHv9cooF.js","names":[],"sources":["../src/ipc/memory.ts","../src/ipc/remote-oauth.ts","../src/ipc/workspace-exec-stream.ts"],"sourcesContent":["/**\n * In-process transport: the host dispatcher in the window's own process, and\n * `IpcClient`s that call it directly instead of over a unix socket.\n *\n * For a window that runs its own host (TUI local mode on the shared engine):\n * the same dispatcher, method table and signal fan-out a daemon serves, with\n * no socket, no spawn and no second process. A caller sees what a socket\n * client would, so the daemon-mode code paths run on it unchanged:\n * - params, results and signals are JSON copies (as on the wire: a top-level\n * `undefined` result arrives as `null`, nested `undefined` fields are\n * dropped, and nothing is shared between the window and the host);\n * - a failed request rejects with `JsonRpcRemoteError` carrying the\n * dispatcher's code; a closed connection rejects with\n * `JsonRpcConnectionClosedError`, in-flight requests included;\n * - responses and signals arrive asynchronously, through one queue in the\n * order the host produced them (a socket reads them in write order);\n * - `close()` detaches quietly; the host shutting down calls `onClose`.\n *\n * Two socket behaviors are deliberately absent. Request deadlines exist on\n * the socket to recover from a wedged daemon by dropping the connection and\n * reconnecting; in-process there is nothing to reconnect to. And\n * `daemon.shutdown` from a client does not stop the host: its lifetime\n * belongs to the embedding window (`InProcessHost.close()`).\n */\nimport type { ChatHost } from '../chat/host/engine'\nimport type { IpcClient } from './client'\nimport type { HostPeer } from './daemon/dispatcher'\nimport type { DaemonEnvironment } from './daemon/environment'\nimport type { HelloResult, HostSignal } from './protocol'\nimport type { SignalListener } from './transports/client-core'\nimport { JsonRpcConnectionClosedError, JsonRpcRemoteError } from '../acp/json-rpc'\nimport { ZIDANE_VERSION } from '../version'\nimport { createHostDispatcher } from './daemon/dispatcher'\nimport { IPC_BUILD_ID } from './daemon/lifecycle'\nimport { IPC_PROTOCOL_VERSION } from './protocol'\n\n/** Options for {@link startInProcessHost}. */\nexport interface InProcessHostOptions {\n /** The host's environment, given the broadcast sink wired to client fan-out. */\n createEnvironment: (broadcast: (signal: HostSignal) => void) => DaemonEnvironment | Promise<DaemonEnvironment>\n /** Reported to clients as the host's `appVersion`. */\n appVersion?: string\n}\n\n/** Options for {@link InProcessHost.connect}. */\nexport interface InProcessClientOptions {\n /** Client version, surfaced in the host's diagnostics. */\n appVersion?: string\n /** Called when the host shuts down under a still-open client. */\n onClose?: () => void\n}\n\n/** A chat host running in the caller's process, with clients that call it directly. */\nexport interface InProcessHost {\n /** The chat host. */\n host: ChatHost\n /** A new client, already past the `ipc.hello` handshake. */\n connect: (options?: InProcessClientOptions) => Promise<IpcClient>\n /** Number of open clients. */\n peerCount: () => number\n /**\n * Shut the host down: refuse new work, abort and await every run, then\n * close the clients still open (their `onClose` fires). Idempotent.\n */\n close: () => Promise<void>\n}\n\n/** JSON round-trip: what crossing the socket does to a value. */\nfunction wire<T>(value: T): T {\n return value === undefined ? (null as T) : JSON.parse(JSON.stringify(value)) as T\n}\n\n/** One open client, from the host's side. */\ninterface Connection {\n peer: HostPeer\n /** The host is shutting down: reject what is pending, then tell the client. */\n hostClosed: () => void\n}\n\n/**\n * Starts a chat host in this process. Clients from `connect` behave like socket clients, without a socket or a second process.\n * @param options - Environment factory and version.\n * @returns The host handle.\n */\nexport async function startInProcessHost(options: InProcessHostOptions): Promise<InProcessHost> {\n const connections = new Set<Connection>()\n let closing: Promise<void> | null = null\n\n const dispatcher = await createHostDispatcher({\n createEnvironment: options.createEnvironment,\n appVersion: options.appVersion ?? 'dev',\n startedAt: Date.now(),\n identity: { kind: 'in-process' },\n lifecycle: {\n // Owned by the embedding window, see the module header.\n shutdown: () => undefined,\n // Clients are this build by construction: never a newer one to retire for.\n retireWhenIdle: () => undefined,\n isRetiring: () => false,\n },\n })\n\n async function connect(clientOptions: InProcessClientOptions = {}): Promise<IpcClient> {\n if (closing)\n throw new JsonRpcConnectionClosedError()\n const listeners = new Set<SignalListener>()\n const pending = new Set<(err: Error) => void>()\n let closed = false\n\n /*\n * Everything bound for the client goes through one FIFO drained in a\n * microtask: signals, and request outcomes once the dispatcher settles\n * them. A signal the host emits after answering a request is therefore\n * delivered after that answer, as a socket would read them.\n */\n const outbox: Array<() => void> = []\n let draining = false\n const deliver = (item: () => void): void => {\n outbox.push(item)\n if (draining)\n return\n draining = true\n queueMicrotask(() => {\n try {\n while (outbox.length > 0) {\n try {\n outbox.shift()!()\n }\n catch {\n // A throwing listener costs that one message, as on the socket\n // (the JSON-RPC reader catches it), never the connection.\n }\n }\n }\n finally {\n draining = false\n }\n })\n }\n\n const peer: HostPeer = {\n ready: false,\n watching: null,\n send(signal, seq, encoded) {\n if (closed)\n return\n const meta = seq === undefined ? undefined : { seq }\n let copy: HostSignal\n try {\n // The fan-out's one serialization, when it has one.\n const json = encoded ? encoded.json() : JSON.stringify(signal)\n if (json === undefined)\n return\n copy = JSON.parse(json) as HostSignal\n }\n catch {\n // Not JSON-able: the socket server drops it the same way, and a\n // bad signal must never break fan-out to the other clients.\n return\n }\n deliver(() => {\n if (closed)\n return\n for (const listener of listeners)\n listener(copy, meta)\n })\n },\n }\n\n const request = (method: string, params: unknown): Promise<unknown> => {\n if (closed)\n return Promise.reject(new JsonRpcConnectionClosedError())\n return new Promise((resolve, reject) => {\n pending.add(reject)\n const settle = (outcome: () => void): void => {\n deliver(() => {\n if (!pending.delete(reject))\n return\n outcome()\n })\n }\n dispatcher.handleRequest(method, params === undefined ? undefined : wire(params), peer).then(\n (result) => {\n settle(() => {\n // The reject is already out of `pending`: a throw here (a result\n // that is not JSON-able) must fail the request, not hang it.\n try {\n if (result.ok)\n resolve(wire(result.result))\n else\n reject(new JsonRpcRemoteError(result.message, result.code, result.data))\n }\n catch (err) {\n reject(err instanceof Error ? err : new Error(String(err)))\n }\n })\n },\n err => settle(() => reject(err)),\n )\n })\n }\n\n /** Stop delivering and fail what is in flight, as a socket closing does. */\n const shut = (): void => {\n closed = true\n listeners.clear()\n outbox.length = 0\n for (const reject of pending)\n reject(new JsonRpcConnectionClosedError())\n pending.clear()\n }\n\n const connection: Connection = {\n peer,\n hostClosed: () => {\n if (closed)\n return\n shut()\n clientOptions.onClose?.()\n },\n }\n\n dispatcher.addPeer(peer)\n connections.add(connection)\n const detach = (): void => {\n if (closed)\n return\n shut()\n connections.delete(connection)\n dispatcher.removePeer(peer)\n }\n\n let hello: HelloResult\n try {\n hello = await request('ipc.hello', {\n protocolVersion: IPC_PROTOCOL_VERSION,\n appVersion: clientOptions.appVersion ?? 'dev',\n pid: process.pid,\n buildId: IPC_BUILD_ID,\n codeVersion: ZIDANE_VERSION,\n }) as HelloResult\n }\n catch (err) {\n detach()\n throw err\n }\n\n return {\n hello,\n request: request as IpcClient['request'],\n notify: (method, params) => {\n if (closed)\n return\n const copy = params === undefined ? undefined : wire(params)\n // Off the caller's stack, as a socket write would be.\n queueMicrotask(() => {\n if (!closed)\n void dispatcher.handleNotification(method, copy, peer)\n })\n },\n onSignal: (listener) => {\n listeners.add(listener)\n return () => listeners.delete(listener)\n },\n close: detach,\n }\n }\n\n function close(): Promise<void> {\n // Same order as the socket server's shutdown: drain the host, close\n // every connection, then forget the peers without per-peer cleanup.\n closing ??= (async () => {\n await dispatcher.host.drain()\n for (const connection of connections)\n connection.hostClosed()\n connections.clear()\n dispatcher.detachAll()\n })()\n return closing\n }\n\n return {\n host: dispatcher.host,\n connect,\n peerCount: () => dispatcher.peerCount(),\n close,\n }\n}\n","/**\n * The client half of a remote OAuth sign-in (`auth.oauth.*`): the host runs\n * the login and keeps its secrets; this machine has the browser. For an MCP\n * server it opens a loopback listener first (any free port) and hands its\n * URI to the host; for a provider it listens on the provider's fixed\n * `redirect_uri` once the host names it (a busy port falls back to pasting\n * the address the browser lands on). It opens the URL, forwards the code\n * (or what the user pasted) to the host, and resolves with the host's\n * outcome, which never carries a token. Device and polling flows just wait.\n *\n * The provider's own questions (a choice between flows, a free-text\n * prompt: `HostOAuthStep`) come back from `begin` / `complete`; the UI\n * answers them (`select` / `prompt`; a prompt falls back to `paste`). A UI\n * that can't answers nothing: the sign-in ends with why, never a default.\n */\nimport type { McpOAuthCallbackPageRenderer, OAuthCallbackHandle } from '../mcp/oauth-callback'\nimport type { HostOAuthBegin, HostOAuthComplete, HostOAuthStep } from './protocol'\nimport type { IpcClient } from './transports/client-core'\nimport { startOAuthCallback } from '../mcp/oauth-callback'\n\n/** What to sign in to: a provider by key, or an MCP server by name. */\nexport type RemoteOAuthTarget = { provider: string } | { mcpServer: string, cwd?: string, kind?: string }\n\nexport interface RemoteOAuthStart extends HostOAuthBegin {\n /** This machine catches the redirect (else: paste, or wait for a device / polling flow). */\n listening: boolean\n /** Why it doesn't (a busy port). */\n listenError?: string\n}\n\n/** Hooks a window supplies to {@link runRemoteOAuth}: open the browser, take pasted input, answer the provider's questions, and abort. */\nexport interface RemoteOAuthUi {\n /** Open the browser here (best effort; the URL is shown too). */\n openUrl: (url: string) => void | Promise<void>\n /** The flow started: the URL, the mode, a device code, whether the loopback listens. */\n onStart?: (start: RemoteOAuthStart) => void\n /** What the user pastes (a code or the address the browser landed on); offered in every mode. */\n paste?: () => Promise<string>\n /** Aborts the sign-in. The run rejects with \"OAuth login aborted\". */\n signal?: AbortSignal\n /** The page the browser lands on at the loopback. */\n renderPage?: McpOAuthCallbackPageRenderer\n /** The provider asks the user to choose (its option id; `undefined` cancels). */\n select?: (step: Extract<HostOAuthStep, { kind: 'select' }>) => Promise<string | undefined>\n /** The provider asks the user a question (default: {@link paste}). */\n prompt?: (step: Extract<HostOAuthStep, { kind: 'prompt' }>) => Promise<string>\n}\n\n/** The UI's answer to `step`, or why it can't give one. */\nasync function answerStep(ui: RemoteOAuthUi, step: HostOAuthStep): Promise<string | undefined> {\n if (step.kind === 'select' && ui.select)\n return ui.select(step)\n if (step.kind === 'prompt' && (ui.prompt || ui.paste))\n return ui.prompt ? ui.prompt(step) : ui.paste!()\n throw new Error(`The sign-in asks \"${step.message}\", and this window can't answer it here: sign in on the server machine or use an API key.`)\n}\n\nconst abortError = (): Error => new Error('OAuth login aborted')\n\nfunction whenAborted(signal: AbortSignal | undefined): Promise<never> {\n return new Promise<never>((_, reject) => {\n if (signal?.aborted)\n reject(abortError())\n signal?.addEventListener('abort', () => reject(abortError()), { once: true })\n })\n}\n\n/**\n * Runs the client half of a remote OAuth sign-in against a host.\n * Starts the flow on the host, opens the URL through the UI, forwards the code from the loopback listener or from `paste`, and resolves with the host's outcome, which never carries a token. Rejects when aborted or when the UI cannot answer a question the provider asks.\n * @param client - Client used for the `auth.oauth.*` requests.\n * @param target - Provider or MCP server to sign in to.\n * @param ui - Browser, prompt and abort hooks.\n * @returns The sign-in outcome: the provider status or the MCP server name.\n */\nexport async function runRemoteOAuth(\n client: Pick<IpcClient, 'request'>,\n target: RemoteOAuthTarget,\n ui: RemoteOAuthUi,\n): Promise<HostOAuthComplete> {\n const { signal } = ui\n signal?.throwIfAborted()\n const isMcp = 'mcpServer' in target\n let loopback: OAuthCallbackHandle | undefined\n const listenOptions = { ...(signal ? { signal } : {}), ...(ui.renderPage ? { renderPage: ui.renderPage } : {}), provider: isMcp ? target.mcpServer : target.provider }\n if (isMcp)\n loopback = await startOAuthCallback({ ...listenOptions, port: 0 })\n let begin: HostOAuthBegin | undefined\n try {\n begin = await client.request('auth.oauth.begin', isMcp\n ? { mcpServer: target.mcpServer, ...(target.cwd !== undefined ? { cwd: target.cwd } : {}), ...(target.kind !== undefined ? { kind: target.kind } : {}), redirectUri: loopback!.redirectUri }\n : { provider: target.provider })\n const flowId = begin.flowId\n const respond = async (step: HostOAuthStep): Promise<HostOAuthBegin> => {\n const value = await answerStep(ui, step)\n signal?.throwIfAborted()\n return client.request('auth.oauth.respond', { flowId, stepId: step.id, ...(value !== undefined ? { value } : {}) })\n }\n // Questions before the URL.\n while (begin.step)\n begin = await respond(begin.step)\n let listenError: string | undefined\n // The host pinned another redirect (an MCP server's pre-registered\n // client, `oauth.callbackPort`): listen there instead.\n if (loopback && begin.redirectUri && begin.redirectUri !== loopback.redirectUri) {\n loopback.promise.catch(() => undefined) // closing rejects it; nothing waits on it\n await loopback.close()\n loopback = undefined\n }\n if (!loopback && begin.mode === 'loopback' && begin.redirectUri) {\n const redirect = new URL(begin.redirectUri)\n try {\n loopback = await startOAuthCallback({ ...listenOptions, port: Number(redirect.port), path: redirect.pathname })\n }\n catch (err) {\n listenError = `Port ${redirect.port} is busy on this computer (${err instanceof Error ? err.message : String(err)}): paste the address the browser lands on instead.`\n }\n }\n ui.onStart?.({ ...begin, listening: loopback !== undefined, ...(listenError ? { listenError } : {}) })\n await ui.openUrl(begin.url)\n\n /** Deliver (once), then wait; a question after the URL is answered and the wait goes on. */\n const complete = async (params: { code?: string, state?: string, input?: string }): Promise<HostOAuthComplete> => {\n let outcome = await client.request('auth.oauth.complete', { flowId, ...params })\n while (outcome.step) {\n await respond(outcome.step)\n outcome = await client.request('auth.oauth.complete', { flowId })\n }\n return outcome\n }\n const ways: Promise<HostOAuthComplete>[] = [whenAborted(signal)]\n if (loopback) {\n const handle = loopback\n ways.push(handle.promise.then(({ code, state }) => complete({ code, ...(state !== undefined ? { state } : {}) })))\n }\n if (ui.paste)\n ways.push(ui.paste().then(input => complete({ input })))\n // Device and polling flows finish on the host's side: wait for it.\n if (begin.mode !== 'loopback')\n ways.push(complete({}))\n for (const way of ways)\n way.catch(() => undefined)\n return await Promise.race(ways)\n }\n catch (err) {\n if (begin)\n void client.request('auth.oauth.cancel', { flowId: begin.flowId }).catch(() => undefined)\n throw err\n }\n finally {\n await loopback?.close()\n }\n}\n","/**\n * The client half of a streamed workspace command (`!` on a remote host):\n * starts `sessions.workspaceExecStream`, gathers its `workspace:exec:*`\n * signals (which may beat the reply) into one output in arrival order, and\n * cancels on the host when `signal` aborts. The result has the shape of a\n * local `!` run (`BashRunResult`), so both format and persist alike. A host\n * without the method gets the buffered `sessions.workspaceExec`, where an\n * abort stops waiting, not the command.\n */\nimport type { HostSignal } from './protocol'\nimport type { IpcClient } from './transports/client-core'\nimport { isMethodNotFound } from '../chat/hosts/connection'\n\n/** Outcome of {@link runWorkspaceExecStream}, shaped like a local `!` run. */\nexport interface WorkspaceExecStreamResult {\n /** stdout and stderr in arrival order (the buffered fallback: stdout, then stderr). */\n output: string\n /** `null` when the host killed it (cancel, output cap). */\n exitCode: number | null\n /** Wall-clock time of the run in milliseconds. */\n durationMs: number\n /** Cancelled through `signal`. */\n aborted: boolean\n /** The host's output cap was reached and the process stopped. */\n overflowed: boolean\n /** `false`: an older host answered with the buffered exec. */\n streamed: boolean\n}\n\n/** Options for {@link runWorkspaceExecStream}. */\nexport interface WorkspaceExecStreamOptions {\n /** Cancels the command on the host when aborted. */\n signal?: AbortSignal\n /** The whole output so far, on every chunk. */\n onChunk?: (accumulated: string) => void\n /** The buffered fallback's bound. Default 600 s. */\n fallbackTimeoutSeconds?: number\n /** How long to wait for the host's exit after a cancel before giving up on it. Default 10 s. */\n cancelGraceMs?: number\n}\n\ntype ExecSignal = Extract<HostSignal, { kind: 'workspace:exec:data' | 'workspace:exec:exit' }>\n\n/**\n * Runs a command in a session's workspace on a host and streams its output.\n * The result has the shape of a local `!` run. A host without `sessions.workspaceExecStream` gets the buffered `sessions.workspaceExec` instead, and then an abort stops the wait, not the command.\n * @param client - Client used for requests and signals.\n * @param params - Session, command and optional working directory.\n * @param options - Abort signal, chunk callback and timeouts.\n * @returns The output, exit code and flags describing how it ended.\n */\nexport async function runWorkspaceExecStream(\n client: Pick<IpcClient, 'request' | 'onSignal'>,\n params: { sessionId: string, command: string, cwd?: string },\n options: WorkspaceExecStreamOptions = {},\n): Promise<WorkspaceExecStreamResult> {\n const { signal } = options\n const started = Date.now()\n signal?.throwIfAborted()\n\n let execId: string | null = null\n /** Signals that arrived before the reply named the exec. */\n const early: ExecSignal[] = []\n let output = ''\n let finish: (exit: Extract<ExecSignal, { kind: 'workspace:exec:exit' }> | null) => void = () => undefined\n const exited = new Promise<Extract<ExecSignal, { kind: 'workspace:exec:exit' }> | null>((resolve) => {\n finish = resolve\n })\n const apply = (event: ExecSignal): void => {\n if (event.kind === 'workspace:exec:data') {\n output += event.chunk\n options.onChunk?.(output)\n return\n }\n finish(event)\n }\n const unsubscribe = client.onSignal((event) => {\n if (event.kind !== 'workspace:exec:data' && event.kind !== 'workspace:exec:exit')\n return\n if (execId === null)\n early.push(event)\n else if (event.execId === execId)\n apply(event)\n })\n\n try {\n try {\n execId = (await client.request('sessions.workspaceExecStream', { sessionId: params.sessionId, command: params.command, ...(params.cwd !== undefined ? { cwd: params.cwd } : {}) })).execId\n }\n catch (err) {\n if (!isMethodNotFound(err))\n throw err\n return await buffered(client, params, options, started)\n }\n for (const event of early.splice(0)) {\n if (event.execId === execId)\n apply(event)\n }\n\n const id = execId\n const onAbort = (): void => {\n void client.request('sessions.workspaceExecCancel', { execId: id }).catch(() => undefined)\n // The exit normally follows the kill; a connection lost meanwhile must not hang the caller.\n setTimeout(finish, options.cancelGraceMs ?? 10_000, null).unref?.()\n }\n signal?.addEventListener('abort', onAbort, { once: true })\n if (signal?.aborted)\n onAbort()\n let exit: Awaited<typeof exited>\n try {\n exit = await exited\n }\n finally {\n signal?.removeEventListener('abort', onAbort)\n }\n return {\n output,\n exitCode: exit === null || exit.signal !== null ? null : exit.code,\n durationMs: Date.now() - started,\n aborted: signal?.aborted === true,\n overflowed: exit?.truncated === true,\n streamed: true,\n }\n }\n finally {\n unsubscribe()\n }\n}\n\n/** An older host: one buffered exec; `signal` stops waiting for it. */\nasync function buffered(\n client: Pick<IpcClient, 'request'>,\n params: { sessionId: string, command: string, cwd?: string },\n options: WorkspaceExecStreamOptions,\n started: number,\n): Promise<WorkspaceExecStreamResult> {\n const { signal } = options\n const request = client.request('sessions.workspaceExec', {\n sessionId: params.sessionId,\n command: params.command,\n ...(params.cwd !== undefined ? { cwd: params.cwd } : {}),\n timeoutSeconds: options.fallbackTimeoutSeconds ?? 600,\n })\n const stopped = new Promise<null>((resolve) => {\n if (signal?.aborted)\n resolve(null)\n signal?.addEventListener('abort', () => resolve(null), { once: true })\n })\n request.catch(() => undefined)\n const result = await Promise.race([request, stopped])\n if (!result)\n return { output: '', exitCode: null, durationMs: Date.now() - started, aborted: true, overflowed: false, streamed: false }\n const output = [result.stdout, result.stderr].filter(part => part.trim() !== '').map(part => part.replace(/\\n$/, '')).join('\\n')\n options.onChunk?.(output)\n return { output, exitCode: result.exitCode, durationMs: Date.now() - started, aborted: false, overflowed: false, streamed: false }\n}\n"],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@ import { n as reconcileImageMediaType } from "./media-sniff-DZaaJt2S.js";
|
|
|
3
3
|
import { t as alwaysQuote } from "./shell-quote-BmnhZmdM.js";
|
|
4
4
|
import { t as isSpawnTool } from "./is-spawn-tool-BWxYvCYU.js";
|
|
5
5
|
import { a as ARTIFACT_KIND_PATTERN, s as ARTIFACT_URI_MAX_CHARS } from "./metadata-merge-Cb1TiYVU.js";
|
|
6
|
-
import { s as resumeChainRunIds } from "./session-
|
|
6
|
+
import { s as resumeChainRunIds } from "./session-CCsKXID6.js";
|
|
7
7
|
import { i as styleReplacementForVia, n as resolveOldString, r as stripLineNumberPrefixes, t as describeVia } from "./edit-utils-BkGnT1Rv.js";
|
|
8
8
|
import { a as readFileTargets, r as readFileBatchHeader } from "./format-bytes-LHrZVMIt.js";
|
|
9
9
|
import { c as readStateKey, l as resolveReadStateMap, r as hashContent, s as noteStaleRejection, u as staleRefusalHint } from "./read-state-BkoUdmZ9.js";
|
|
@@ -193,7 +193,7 @@ let agentModule;
|
|
|
193
193
|
* `createSpawnTool` starts the load, so a child's first run doesn't wait on it.
|
|
194
194
|
*/
|
|
195
195
|
function loadAgentModule() {
|
|
196
|
-
agentModule ??= import("./agent-
|
|
196
|
+
agentModule ??= import("./agent-CmhCOmyO.js").then((n) => n.t);
|
|
197
197
|
return agentModule;
|
|
198
198
|
}
|
|
199
199
|
/**
|
|
@@ -1896,4 +1896,4 @@ const writeFile = {
|
|
|
1896
1896
|
//#endregion
|
|
1897
1897
|
export { readFileAsBase64 as a, edit as c, recordArtifact as d, createSpawnTool as f, imageMediaTypeFor as i, wholeReadRefusal as l, readFile as n, multiEdit as o, withIsolatedSpawnTool as p, readFileLineNumbers as r, listFiles as s, writeFile as t, RECORD_ARTIFACT_TOOL as u };
|
|
1898
1898
|
|
|
1899
|
-
//# sourceMappingURL=write-file-
|
|
1899
|
+
//# sourceMappingURL=write-file-ChtRPdEL.js.map
|