zidane 5.14.1 → 5.14.2
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/chat.d.ts +1 -1
- package/dist/chat.js +1 -1
- package/dist/restate.d.ts.map +1 -1
- package/dist/restate.js +50 -20
- package/dist/restate.js.map +1 -1
- package/dist/{transcript-anchors-CjKRKZVx.d.ts → transcript-anchors-BHIgMlPq.d.ts} +2 -2
- package/dist/transcript-anchors-BHIgMlPq.d.ts.map +1 -0
- package/dist/{transcript-anchors-HyCGJhsK.js → transcript-anchors-DsoBHg43.js} +8 -1
- package/dist/transcript-anchors-DsoBHg43.js.map +1 -0
- package/dist/tui.d.ts +7 -1
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +383 -73
- package/dist/tui.js.map +1 -1
- package/docs/RESTATE.md +2 -0
- package/docs/TUI.md +1 -0
- package/package.json +1 -1
- package/dist/transcript-anchors-CjKRKZVx.d.ts.map +0 -1
- package/dist/transcript-anchors-HyCGJhsK.js.map +0 -1
package/dist/tui.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Jn as McpToolSchema, L as SkillConfig, U as Session, W as SessionData, _r as ThinkingLevel, mr as SessionTurn } from "./agent-EFWt6uQ_.js";
|
|
2
|
-
import { D as InteractionRequest, Kt as KeyBindings, O as InteractionResponse, S as splitMarkdownCodeBlocks, cn as hintsLength, dt as ChatOptions, et as EnabledAllowlistKey, fn as AgentRegistry, g as SessionExportFormat, it as DiscoveryError, jt as marginTopFor, l as Theme, ln as truncateTrailing, n as computeTurnAnchors, on as Hint, pt as ResolvedConfig, rn as CompletionState, rt as DiscoveredMcp, sn as clipHintsToWidth, t as TranscriptItem, u as ThemeColors, x as MarkdownSegment, yn as accentColor } from "./transcript-anchors-
|
|
2
|
+
import { D as InteractionRequest, Kt as KeyBindings, O as InteractionResponse, S as splitMarkdownCodeBlocks, cn as hintsLength, dt as ChatOptions, et as EnabledAllowlistKey, fn as AgentRegistry, g as SessionExportFormat, it as DiscoveryError, jt as marginTopFor, l as Theme, ln as truncateTrailing, n as computeTurnAnchors, on as Hint, pt as ResolvedConfig, rn as CompletionState, rt as DiscoveredMcp, sn as clipHintsToWidth, t as TranscriptItem, u as ThemeColors, x as MarkdownSegment, yn as accentColor } from "./transcript-anchors-BHIgMlPq.js";
|
|
3
3
|
import { A as SessionMeta, G as ProviderKey, L as CompletionProvider, M as StreamEvent, R as CompletionReference, W as ProviderAuth, X as ModelOption, Y as ModelInfo, _ as isEditErrorResult, a as formatToolCall, b as selectableTurnIds, c as splitPromptSegments, i as displayNameFor, j as Settings, l as ApprovalDecision, n as ToolDisplayMeta, o as PromptSegment, r as ToolFormatLine, s as PromptSegmentRef, t as TOOL_DISPLAY, u as ApprovalRequest, v as isTurnHighlighted, x as turnSelectionOwnership, y as isVisible } from "./tool-formatters-C6iLgc9f.js";
|
|
4
4
|
import { Buffer } from "node:buffer";
|
|
5
5
|
import { ReactNode } from "react";
|
|
@@ -605,6 +605,7 @@ declare function ChatScreen({
|
|
|
605
605
|
onPopupOpenChange,
|
|
606
606
|
selectedTurnId,
|
|
607
607
|
promptTriggerHints,
|
|
608
|
+
attachImageBinding,
|
|
608
609
|
liveSession
|
|
609
610
|
}: {
|
|
610
611
|
cwd: string;
|
|
@@ -695,6 +696,11 @@ declare function ChatScreen({
|
|
|
695
696
|
* triggers entirely on narrow terminals.
|
|
696
697
|
*/
|
|
697
698
|
promptTriggerHints?: readonly Hint[];
|
|
699
|
+
/**
|
|
700
|
+
* Resolved keybinding spec for "attach image from clipboard", threaded
|
|
701
|
+
* into {@link PromptBlock} so it can read the OS clipboard on that key.
|
|
702
|
+
*/
|
|
703
|
+
attachImageBinding?: string;
|
|
698
704
|
/**
|
|
699
705
|
* Live `Session` reference for surfaces that read metadata directly
|
|
700
706
|
* (currently {@link TodoIndicator}'s `useActiveTodos` slice). The
|
package/dist/tui.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tui.d.ts","names":[],"sources":["../src/tui/agent-picker.tsx","../src/tui/app.tsx","../src/tui/completion-popup.tsx","../src/tui/components.tsx","../src/tui/effort-picker.tsx","../src/tui/interaction-block.tsx","../src/tui/mcps-settings.tsx","../src/tui/modal.tsx","../src/tui/model-options-picker.tsx","../src/tui/model-picker.tsx","../src/tui/screens.tsx","../src/tui/session-details-modal.tsx","../src/tui/settings-modal.tsx","../src/tui/skills-settings.tsx","../src/tui/theme.ts","../src/tui/toggle-list-modal.tsx","../src/tui/turn-details-modal.tsx","../src/tui/index.tsx"],"mappings":"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
|
|
1
|
+
{"version":3,"file":"tui.d.ts","names":[],"sources":["../src/tui/agent-picker.tsx","../src/tui/app.tsx","../src/tui/completion-popup.tsx","../src/tui/components.tsx","../src/tui/effort-picker.tsx","../src/tui/interaction-block.tsx","../src/tui/mcps-settings.tsx","../src/tui/modal.tsx","../src/tui/model-options-picker.tsx","../src/tui/model-picker.tsx","../src/tui/screens.tsx","../src/tui/session-details-modal.tsx","../src/tui/settings-modal.tsx","../src/tui/skills-settings.tsx","../src/tui/theme.ts","../src/tui/toggle-list-modal.tsx","../src/tui/turn-details-modal.tsx","../src/tui/index.tsx"],"mappings":"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"}
|
package/dist/tui.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as useMcpAuthDispatch, $t as KEYBINDING_DEFS, A as runOAuthLogin, At as SettingsProvider, B as refreshMcpToolsCatalog, Cr as stripSpawnTokensLine, D as formatPathForCwd, Dr as toolResultText, Dt as SETTINGS_CATEGORIES, En as discoverAgentsMd, Er as toolCallPreview, Et as DEFAULT_SETTINGS, Fn as accentColor, Ft as resolveChipColor, Gt as DiscoveryProvider, H as subscribeMcpToolsCache, It as resolveTheme, J as parentServerName, Jt as ConfigProvider, K as buildVisibleMcpRows, Kt as useDiscovery, M as buildMcpServers, Mt as useSettings, O as fetchOAuthRedirect, On as findGitRoot, Or as updateToolEventOutcomes, Ot as SETTINGS_CHOICES, P as discoverProjectMcps, Q as McpAuthProvider, R as loadMcpToolsCache, Sr as serverToolResultSummary, St as buildHints, T as suggestSafelistEntries, Tn as chatAutoCompactBehavior, Tt as useEnabledToggleSet, Vn as TODO_STATUS_GLYPHS, W as useMcpToolToggleMap, Wt as createDiscoverySlot, Xt as resolveConfig, Y as createFileMcpCredentialStore, Yt as useConfig, Zn as useActiveTodos, _ as useSafeModeQueue, _r as lastContextSizeFromTurns, _t as clipHintsToWidth, a as useSurfaces, an as keybindingsPath, b as getSafelist, br as marginTopFor, c as useStreamBuffer, cr as buildBuildSystem, ct as buildResumedToolResultsTurn, d as discoverProjectSkills, dn as useCompletion, dr as chatReferenceTokensForPrompt, dt as makeRequestInteraction, et as useMcpAuthState, fn as tryOpenBrowser, fr as createChatTurnsReadTool, ft as pendingInteractionsFromTurns, g as useSafeModeActions, gn as useUpdateCheck, gr as eventsFromTurns, gt as EMPTY_HINTS, h as SafeModeProvider, hn as buildUpdateHint, hr as deriveSessionTitle, ht as useInteractionsQueue, i as useSelectStyle, in as groupBindings, it as splitMarkdownCodeBlocks, j as supportsOAuth, jt as clampFps, k as oauthUsesManualCodePaste, kt as SETTINGS_TOGGLES, l as buildSkillsConfig, lr as buildPlanSystem, lt as createInteractionTools, m as writeSessionExport, mn as bootTick, mt as useInteractionsActions, n as ThemeProvider, nn as ensureKeybindingsFile, on as matchesBinding, ot as InteractionsProvider, pr as compactSummaryEvent, q as indexOfServerRow, qt as useDiscoveryOptional, r as useColors, rn as formatBindingForDisplay, rt as normalizeMarkdownCodeFences, s as useTheme, t as computeTurnAnchors, tn as KEYBINDING_KEY_COL_WIDTH, tt as getMcpAuthStatus, u as defaultSkillScanPaths, ur as envSection, vr as listSessionMeta, vt as hintsLength, wr as sumRunCosts, wt as listProjectFiles, x as isOnSafelist, xt as generateSessionTitle, y as addToSafelist, yt as truncateTrailing } from "./transcript-anchors-
|
|
1
|
+
import { $ as useMcpAuthDispatch, $t as KEYBINDING_DEFS, A as runOAuthLogin, At as SettingsProvider, B as refreshMcpToolsCatalog, Cr as stripSpawnTokensLine, D as formatPathForCwd, Dr as toolResultText, Dt as SETTINGS_CATEGORIES, En as discoverAgentsMd, Er as toolCallPreview, Et as DEFAULT_SETTINGS, Fn as accentColor, Ft as resolveChipColor, Gt as DiscoveryProvider, H as subscribeMcpToolsCache, It as resolveTheme, J as parentServerName, Jt as ConfigProvider, K as buildVisibleMcpRows, Kt as useDiscovery, M as buildMcpServers, Mt as useSettings, O as fetchOAuthRedirect, On as findGitRoot, Or as updateToolEventOutcomes, Ot as SETTINGS_CHOICES, P as discoverProjectMcps, Q as McpAuthProvider, R as loadMcpToolsCache, Sr as serverToolResultSummary, St as buildHints, T as suggestSafelistEntries, Tn as chatAutoCompactBehavior, Tt as useEnabledToggleSet, Vn as TODO_STATUS_GLYPHS, W as useMcpToolToggleMap, Wt as createDiscoverySlot, Xt as resolveConfig, Y as createFileMcpCredentialStore, Yt as useConfig, Zn as useActiveTodos, _ as useSafeModeQueue, _r as lastContextSizeFromTurns, _t as clipHintsToWidth, a as useSurfaces, an as keybindingsPath, b as getSafelist, br as marginTopFor, c as useStreamBuffer, cr as buildBuildSystem, ct as buildResumedToolResultsTurn, d as discoverProjectSkills, dn as useCompletion, dr as chatReferenceTokensForPrompt, dt as makeRequestInteraction, et as useMcpAuthState, fn as tryOpenBrowser, fr as createChatTurnsReadTool, ft as pendingInteractionsFromTurns, g as useSafeModeActions, gn as useUpdateCheck, gr as eventsFromTurns, gt as EMPTY_HINTS, h as SafeModeProvider, hn as buildUpdateHint, hr as deriveSessionTitle, ht as useInteractionsQueue, i as useSelectStyle, in as groupBindings, it as splitMarkdownCodeBlocks, j as supportsOAuth, jt as clampFps, k as oauthUsesManualCodePaste, kt as SETTINGS_TOGGLES, l as buildSkillsConfig, lr as buildPlanSystem, lt as createInteractionTools, m as writeSessionExport, mn as bootTick, mt as useInteractionsActions, n as ThemeProvider, nn as ensureKeybindingsFile, on as matchesBinding, ot as InteractionsProvider, pr as compactSummaryEvent, q as indexOfServerRow, qt as useDiscoveryOptional, r as useColors, rn as formatBindingForDisplay, rt as normalizeMarkdownCodeFences, s as useTheme, t as computeTurnAnchors, tn as KEYBINDING_KEY_COL_WIDTH, tt as getMcpAuthStatus, u as defaultSkillScanPaths, ur as envSection, vr as listSessionMeta, vt as hintsLength, wr as sumRunCosts, wt as listProjectFiles, x as isOnSafelist, xt as generateSessionTitle, y as addToSafelist, yt as truncateTrailing } from "./transcript-anchors-DsoBHg43.js";
|
|
2
2
|
import { A as compactConversation, C as resolveMcpWarningsDir, E as buildPostCompactAttachments, O as selectFilesFromSession, T as resolveTasksDir, U as summaryToTurn, X as OUTPUT_RESERVE_TOKENS, Z as effectiveContextWindow, t as createAgent, w as resolvePersistDir, x as cleanupPersistedSession } from "./agent-Cch2ayTt.js";
|
|
3
3
|
import { a as formatTaskStatus, c as shortId, i as formatDuration, n as compactPath, o as formatTaskSummary, r as fmtTokens, s as previewLine, t as ageString } from "./format-BNOXpl-1.js";
|
|
4
4
|
import { n as createProcessContext } from "./contexts-Lzf5huID.js";
|
|
@@ -20,8 +20,9 @@ import { basename, join, relative } from "node:path";
|
|
|
20
20
|
import { Buffer } from "node:buffer";
|
|
21
21
|
import * as fs from "node:fs";
|
|
22
22
|
import { createWriteStream, mkdirSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
23
|
+
import { readFile, unlink } from "node:fs/promises";
|
|
23
24
|
import { spawn } from "node:child_process";
|
|
24
|
-
import { homedir } from "node:os";
|
|
25
|
+
import { homedir, tmpdir } from "node:os";
|
|
25
26
|
import { Fzf, byLengthAsc } from "fzf";
|
|
26
27
|
import { createContext, createElement, memo, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
27
28
|
import { BoxRenderable, CodeRenderable, RGBA, SyntaxStyle, TextRenderable, addDefaultParsers, createCliRenderer, decodePasteBytes, defaultTextareaKeyBindings, getTreeSitterClient, stripAnsiSequences } from "@opentui/core";
|
|
@@ -1742,34 +1743,30 @@ function UserPromptBlock({ text, refs, attachments }) {
|
|
|
1742
1743
|
paddingLeft: 1,
|
|
1743
1744
|
paddingRight: 1
|
|
1744
1745
|
};
|
|
1746
|
+
const hasRefs = !!(refs && refs.length > 0);
|
|
1745
1747
|
const attachmentChips = attachments && attachments.length > 0 ? /* @__PURE__ */ jsx("box", {
|
|
1746
1748
|
style: {
|
|
1747
1749
|
flexDirection: "row",
|
|
1748
1750
|
flexWrap: "wrap",
|
|
1749
|
-
paddingTop:
|
|
1751
|
+
paddingTop: hasRefs ? 1 : 0
|
|
1750
1752
|
},
|
|
1751
1753
|
children: attachments.map((att, idx) => {
|
|
1752
1754
|
const sz = att.size;
|
|
1753
1755
|
const label = sz < 1024 ? `${sz}B` : sz < 1024 * 1024 ? `${(sz / 1024).toFixed(1)}KB` : `${(sz / (1024 * 1024)).toFixed(1)}MB`;
|
|
1754
|
-
const icon = att.mediaType.startsWith("image/") ? "🖼" : "📎";
|
|
1755
1756
|
const chipColor = resolveChipColor(SURFACE.chips, "file");
|
|
1756
|
-
return /* @__PURE__ */ jsxs("text", { children: [
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
" "
|
|
1770
|
-
]
|
|
1771
|
-
})
|
|
1772
|
-
] }, `att-${idx}`);
|
|
1757
|
+
return /* @__PURE__ */ jsxs("text", { children: [idx > 0 ? " " : "", /* @__PURE__ */ jsxs("span", {
|
|
1758
|
+
fg: chipColor.fg,
|
|
1759
|
+
bg: chipColor.bg,
|
|
1760
|
+
children: [
|
|
1761
|
+
" ",
|
|
1762
|
+
att.name,
|
|
1763
|
+
" ",
|
|
1764
|
+
"(",
|
|
1765
|
+
label,
|
|
1766
|
+
")",
|
|
1767
|
+
" "
|
|
1768
|
+
]
|
|
1769
|
+
})] }, `att-${idx}`);
|
|
1773
1770
|
})
|
|
1774
1771
|
}) : null;
|
|
1775
1772
|
if (!refs || refs.length === 0) return /* @__PURE__ */ jsxs("box", {
|
|
@@ -4246,6 +4243,224 @@ function describeModel(m) {
|
|
|
4246
4243
|
return parts.join(" · ");
|
|
4247
4244
|
}
|
|
4248
4245
|
//#endregion
|
|
4246
|
+
//#region src/tui/clipboard-image.ts
|
|
4247
|
+
/**
|
|
4248
|
+
* Read an IMAGE from the OS clipboard.
|
|
4249
|
+
*
|
|
4250
|
+
* The companion to the write-only {@link import('./clipboard')} module. Pasting
|
|
4251
|
+
* a clipboard image into a terminal is fundamentally different from pasting
|
|
4252
|
+
* text: terminals deliver text via bracketed paste (`PasteEvent`), but they do
|
|
4253
|
+
* NOT transmit binary clipboard image data that way — on macOS a `cmd+V` of a
|
|
4254
|
+
* screenshot usually produces no paste event at all. So to support "paste the
|
|
4255
|
+
* image I just copied" we have to read the OS clipboard directly via a
|
|
4256
|
+
* platform helper, on an explicit trigger.
|
|
4257
|
+
*
|
|
4258
|
+
* Every outcome is classified (never thrown) so the caller can show the right
|
|
4259
|
+
* message:
|
|
4260
|
+
* - `ok` → bytes + sniffed media type, ready to attach.
|
|
4261
|
+
* - `no-image` → clipboard holds no image (probably text) — soft no-op.
|
|
4262
|
+
* - `helper-missing` → the platform helper isn't installed (`detail` carries
|
|
4263
|
+
* an install hint).
|
|
4264
|
+
* - `unsupported-env` → remote session (SSH): the helper would read the
|
|
4265
|
+
* REMOTE box's clipboard, not the user's.
|
|
4266
|
+
* - `failed` → helper ran but produced no usable image.
|
|
4267
|
+
*
|
|
4268
|
+
* SSH note: like OSC 52 on the write side, there's no portable way to reach the
|
|
4269
|
+
* user's LOCAL clipboard image over SSH, so we detect it and bail with a clear
|
|
4270
|
+
* message rather than silently reading the wrong machine's clipboard.
|
|
4271
|
+
*/
|
|
4272
|
+
/** True in a remote session, where a local clipboard helper would read the wrong box. */
|
|
4273
|
+
function isRemoteSession(env = process.env) {
|
|
4274
|
+
return !!(env.SSH_CONNECTION || env.SSH_TTY || env.SSH_CLIENT);
|
|
4275
|
+
}
|
|
4276
|
+
/** Spawn a helper and capture its (binary) stdout. Never throws. */
|
|
4277
|
+
function captureViaSpawn(cmd, args, timeoutMs = 5e3) {
|
|
4278
|
+
return new Promise((resolveP) => {
|
|
4279
|
+
let child;
|
|
4280
|
+
try {
|
|
4281
|
+
child = spawn(cmd, [...args], { stdio: [
|
|
4282
|
+
"ignore",
|
|
4283
|
+
"pipe",
|
|
4284
|
+
"pipe"
|
|
4285
|
+
] });
|
|
4286
|
+
} catch {
|
|
4287
|
+
resolveP({
|
|
4288
|
+
code: null,
|
|
4289
|
+
stdout: Buffer.alloc(0),
|
|
4290
|
+
stderr: "",
|
|
4291
|
+
spawnError: true
|
|
4292
|
+
});
|
|
4293
|
+
return;
|
|
4294
|
+
}
|
|
4295
|
+
const out = [];
|
|
4296
|
+
const err = [];
|
|
4297
|
+
const timer = setTimeout(() => child.kill("SIGKILL"), timeoutMs);
|
|
4298
|
+
child.stdout?.on("data", (chunk) => out.push(chunk));
|
|
4299
|
+
child.stderr?.setEncoding("utf8");
|
|
4300
|
+
child.stderr?.on("data", (chunk) => err.push(chunk));
|
|
4301
|
+
child.on("error", () => {
|
|
4302
|
+
clearTimeout(timer);
|
|
4303
|
+
resolveP({
|
|
4304
|
+
code: null,
|
|
4305
|
+
stdout: Buffer.alloc(0),
|
|
4306
|
+
stderr: "",
|
|
4307
|
+
spawnError: true
|
|
4308
|
+
});
|
|
4309
|
+
});
|
|
4310
|
+
child.on("close", (code) => {
|
|
4311
|
+
clearTimeout(timer);
|
|
4312
|
+
resolveP({
|
|
4313
|
+
code,
|
|
4314
|
+
stdout: Buffer.concat(out),
|
|
4315
|
+
stderr: err.join(""),
|
|
4316
|
+
spawnError: false
|
|
4317
|
+
});
|
|
4318
|
+
});
|
|
4319
|
+
});
|
|
4320
|
+
}
|
|
4321
|
+
/** Turn captured bytes into an `ok` result, sniffing the format. Exported for tests. */
|
|
4322
|
+
function classifyClipboardBytes(bytes) {
|
|
4323
|
+
if (bytes.length === 0) return {
|
|
4324
|
+
ok: false,
|
|
4325
|
+
reason: "no-image"
|
|
4326
|
+
};
|
|
4327
|
+
const mediaType = sniffImageMediaType(bytes);
|
|
4328
|
+
if (!mediaType) return {
|
|
4329
|
+
ok: false,
|
|
4330
|
+
reason: "failed",
|
|
4331
|
+
detail: "clipboard data was not a recognized image format"
|
|
4332
|
+
};
|
|
4333
|
+
return {
|
|
4334
|
+
ok: true,
|
|
4335
|
+
data: bytes,
|
|
4336
|
+
mediaType
|
|
4337
|
+
};
|
|
4338
|
+
}
|
|
4339
|
+
async function readMac(capture) {
|
|
4340
|
+
const png = await capture("pngpaste", ["-"]);
|
|
4341
|
+
if (!png.spawnError) {
|
|
4342
|
+
if (png.code === 0 && png.stdout.length > 0) return classifyClipboardBytes(png.stdout);
|
|
4343
|
+
return {
|
|
4344
|
+
ok: false,
|
|
4345
|
+
reason: "no-image"
|
|
4346
|
+
};
|
|
4347
|
+
}
|
|
4348
|
+
const tmp = join(tmpdir(), `zidane-clip-${process.pid}-${Date.now()}.png`);
|
|
4349
|
+
const osa = await capture("osascript", [
|
|
4350
|
+
"try",
|
|
4351
|
+
"set thePNG to (the clipboard as «class PNGf»)",
|
|
4352
|
+
"on error",
|
|
4353
|
+
"return \"NOIMG\"",
|
|
4354
|
+
"end try",
|
|
4355
|
+
`set fp to open for access (POSIX file ${JSON.stringify(tmp)}) with write permission`,
|
|
4356
|
+
"set eof fp to 0",
|
|
4357
|
+
"write thePNG to fp",
|
|
4358
|
+
"close access fp",
|
|
4359
|
+
"return \"OK\""
|
|
4360
|
+
].flatMap((line) => ["-e", line]));
|
|
4361
|
+
if (osa.spawnError) return {
|
|
4362
|
+
ok: false,
|
|
4363
|
+
reason: "helper-missing",
|
|
4364
|
+
detail: "install pngpaste to paste images (brew install pngpaste)"
|
|
4365
|
+
};
|
|
4366
|
+
if (osa.stdout.toString("utf8").includes("NOIMG")) return {
|
|
4367
|
+
ok: false,
|
|
4368
|
+
reason: "no-image"
|
|
4369
|
+
};
|
|
4370
|
+
try {
|
|
4371
|
+
return classifyClipboardBytes(await readFile(tmp));
|
|
4372
|
+
} catch {
|
|
4373
|
+
return {
|
|
4374
|
+
ok: false,
|
|
4375
|
+
reason: "failed"
|
|
4376
|
+
};
|
|
4377
|
+
} finally {
|
|
4378
|
+
unlink(tmp).catch(() => {});
|
|
4379
|
+
}
|
|
4380
|
+
}
|
|
4381
|
+
async function readWayland(capture) {
|
|
4382
|
+
const res = await capture("wl-paste", ["--type", "image/png"]);
|
|
4383
|
+
if (res.spawnError) return {
|
|
4384
|
+
ok: false,
|
|
4385
|
+
reason: "helper-missing",
|
|
4386
|
+
detail: "install wl-clipboard to paste images"
|
|
4387
|
+
};
|
|
4388
|
+
if (res.code === 0 && res.stdout.length > 0) return classifyClipboardBytes(res.stdout);
|
|
4389
|
+
return {
|
|
4390
|
+
ok: false,
|
|
4391
|
+
reason: "no-image"
|
|
4392
|
+
};
|
|
4393
|
+
}
|
|
4394
|
+
async function readX11(capture) {
|
|
4395
|
+
const res = await capture("xclip", [
|
|
4396
|
+
"-selection",
|
|
4397
|
+
"clipboard",
|
|
4398
|
+
"-t",
|
|
4399
|
+
"image/png",
|
|
4400
|
+
"-o"
|
|
4401
|
+
]);
|
|
4402
|
+
if (res.spawnError) return {
|
|
4403
|
+
ok: false,
|
|
4404
|
+
reason: "helper-missing",
|
|
4405
|
+
detail: "install xclip to paste images"
|
|
4406
|
+
};
|
|
4407
|
+
if (res.code === 0 && res.stdout.length > 0) return classifyClipboardBytes(res.stdout);
|
|
4408
|
+
return {
|
|
4409
|
+
ok: false,
|
|
4410
|
+
reason: "no-image"
|
|
4411
|
+
};
|
|
4412
|
+
}
|
|
4413
|
+
async function readWindows(capture) {
|
|
4414
|
+
const res = await capture("powershell", [
|
|
4415
|
+
"-NoProfile",
|
|
4416
|
+
"-NonInteractive",
|
|
4417
|
+
"-Command",
|
|
4418
|
+
[
|
|
4419
|
+
"Add-Type -AssemblyName System.Windows.Forms,System.Drawing;",
|
|
4420
|
+
"$img=[System.Windows.Forms.Clipboard]::GetImage();",
|
|
4421
|
+
"if($img -eq $null){ exit 3 }",
|
|
4422
|
+
"$ms=New-Object System.IO.MemoryStream;",
|
|
4423
|
+
"$img.Save($ms,[System.Drawing.Imaging.ImageFormat]::Png);",
|
|
4424
|
+
"$bytes=$ms.ToArray();",
|
|
4425
|
+
"$out=[Console]::OpenStandardOutput();",
|
|
4426
|
+
"$out.Write($bytes,0,$bytes.Length);"
|
|
4427
|
+
].join(" ")
|
|
4428
|
+
]);
|
|
4429
|
+
if (res.spawnError) return {
|
|
4430
|
+
ok: false,
|
|
4431
|
+
reason: "helper-missing",
|
|
4432
|
+
detail: "PowerShell is required to paste images"
|
|
4433
|
+
};
|
|
4434
|
+
if (res.code === 0 && res.stdout.length > 0) return classifyClipboardBytes(res.stdout);
|
|
4435
|
+
return {
|
|
4436
|
+
ok: false,
|
|
4437
|
+
reason: "no-image"
|
|
4438
|
+
};
|
|
4439
|
+
}
|
|
4440
|
+
/**
|
|
4441
|
+
* Read an image from the OS clipboard, classified per {@link ClipboardImageResult}.
|
|
4442
|
+
* Picks the platform helper; on Linux prefers Wayland when present, else X11.
|
|
4443
|
+
*/
|
|
4444
|
+
async function readClipboardImage(hooks = {}) {
|
|
4445
|
+
const platform = hooks.platform ?? process.platform;
|
|
4446
|
+
const env = hooks.env ?? process.env;
|
|
4447
|
+
const capture = hooks.capture ?? captureViaSpawn;
|
|
4448
|
+
if (isRemoteSession(env)) return {
|
|
4449
|
+
ok: false,
|
|
4450
|
+
reason: "unsupported-env",
|
|
4451
|
+
detail: "clipboard image paste is unavailable over SSH — paste the image file path instead"
|
|
4452
|
+
};
|
|
4453
|
+
if (platform === "darwin") return readMac(capture);
|
|
4454
|
+
if (platform === "win32") return readWindows(capture);
|
|
4455
|
+
if (env.WAYLAND_DISPLAY) return readWayland(capture);
|
|
4456
|
+
if (env.DISPLAY) return readX11(capture);
|
|
4457
|
+
return {
|
|
4458
|
+
ok: false,
|
|
4459
|
+
reason: "helper-missing",
|
|
4460
|
+
detail: "no clipboard helper available in this environment"
|
|
4461
|
+
};
|
|
4462
|
+
}
|
|
4463
|
+
//#endregion
|
|
4249
4464
|
//#region src/tui/completion-popup.tsx
|
|
4250
4465
|
/**
|
|
4251
4466
|
* Popover above the textarea showing the active provider's items. Provider-
|
|
@@ -6295,6 +6510,24 @@ function TodoIndicator({ session }) {
|
|
|
6295
6510
|
}
|
|
6296
6511
|
//#endregion
|
|
6297
6512
|
//#region src/tui/screens.tsx
|
|
6513
|
+
/** How long a clipboard-paste status line stays before self-clearing. */
|
|
6514
|
+
const NOTICE_TTL_MS = 5e3;
|
|
6515
|
+
/**
|
|
6516
|
+
* Cap on a pasted clipboard image (raw bytes). Base64 inflates ~33%, so this
|
|
6517
|
+
* keeps the encoded payload comfortably under Anthropic's ~5 MB image ceiling
|
|
6518
|
+
* while covering essentially every screenshot.
|
|
6519
|
+
*/
|
|
6520
|
+
const MAX_IMAGE_BYTES = 3.5 * 1024 * 1024;
|
|
6521
|
+
/** `image/png` → `png` etc., for naming the synthesized clipboard attachment. */
|
|
6522
|
+
function extForImageMediaType(mediaType) {
|
|
6523
|
+
const sub = mediaType.split("/")[1] ?? "png";
|
|
6524
|
+
return sub === "jpeg" ? "jpg" : sub;
|
|
6525
|
+
}
|
|
6526
|
+
function formatBytes(n) {
|
|
6527
|
+
if (n < 1024) return `${n} B`;
|
|
6528
|
+
if (n < 1024 * 1024) return `${Math.round(n / 1024)} KB`;
|
|
6529
|
+
return `${(n / (1024 * 1024)).toFixed(1)} MB`;
|
|
6530
|
+
}
|
|
6298
6531
|
/**
|
|
6299
6532
|
* Build a key-binding set for the prompt textarea / API-key input. Strips the
|
|
6300
6533
|
* default `return` action and reinstalls it with our preferred meaning, so the
|
|
@@ -7455,7 +7688,7 @@ const MIME_BY_EXT = {
|
|
|
7455
7688
|
* default-value reference at the prop destructure.
|
|
7456
7689
|
*/
|
|
7457
7690
|
const EMPTY_QUEUED_MESSAGES = [];
|
|
7458
|
-
function ChatScreen({ cwd, events, busy, compacting = false, queuedMessages = EMPTY_QUEUED_MESSAGES, queueSelectionIndex = null, queueShortcuts, onEnterQueueFromEmptyPrompt, settings, onSubmit, session, pending, onApproval, pendingInteraction, onInteraction, completionProviders, onCompletionTab, onPopupOpenChange, selectedTurnId, promptTriggerHints, liveSession = null }) {
|
|
7691
|
+
function ChatScreen({ cwd, events, busy, compacting = false, queuedMessages = EMPTY_QUEUED_MESSAGES, queueSelectionIndex = null, queueShortcuts, onEnterQueueFromEmptyPrompt, settings, onSubmit, session, pending, onApproval, pendingInteraction, onInteraction, completionProviders, onCompletionTab, onPopupOpenChange, selectedTurnId, promptTriggerHints, attachImageBinding, liveSession = null }) {
|
|
7459
7692
|
const COLOR = useColors();
|
|
7460
7693
|
const titleText = session?.title ?? "untitled";
|
|
7461
7694
|
const showSessionShortcut = !!session && !busy && !pending && !pendingInteraction && settings.uiMode !== "minimal";
|
|
@@ -7571,7 +7804,8 @@ function ChatScreen({ cwd, events, busy, compacting = false, queuedMessages = EM
|
|
|
7571
7804
|
selectMode: queueSelectionIndex != null ? "queue" : selectedTurnId != null ? "turn" : null,
|
|
7572
7805
|
triggerHints: promptTriggerHints,
|
|
7573
7806
|
busy,
|
|
7574
|
-
onEnterQueueFromEmpty: onEnterQueueFromEmptyPrompt
|
|
7807
|
+
onEnterQueueFromEmpty: onEnterQueueFromEmptyPrompt,
|
|
7808
|
+
attachImageBinding
|
|
7575
7809
|
})
|
|
7576
7810
|
] }),
|
|
7577
7811
|
/* @__PURE__ */ jsx(TitleOverlay, {
|
|
@@ -7884,7 +8118,7 @@ function previewText(text) {
|
|
|
7884
8118
|
}
|
|
7885
8119
|
/** Stable empty providers reference — avoids `useCompletion` rerun on every render when no providers are wired. */
|
|
7886
8120
|
const EMPTY_PROVIDERS = [];
|
|
7887
|
-
function PromptBlock({ userPrompts, onSubmit, completionProviders, onCompletionTab, onPopupOpenChange, selectMode = null, triggerHints, busy = false, onEnterQueueFromEmpty }) {
|
|
8121
|
+
function PromptBlock({ userPrompts, onSubmit, completionProviders, onCompletionTab, onPopupOpenChange, selectMode = null, triggerHints, busy = false, onEnterQueueFromEmpty, attachImageBinding }) {
|
|
7888
8122
|
const focused = useModalAwareFocus();
|
|
7889
8123
|
const COLOR = useColors();
|
|
7890
8124
|
const SURFACE = useSurfaces();
|
|
@@ -7894,6 +8128,45 @@ function PromptBlock({ userPrompts, onSubmit, completionProviders, onCompletionT
|
|
|
7894
8128
|
/** Auto-grow: visible content rows the textarea currently occupies (clamped 1..5). */
|
|
7895
8129
|
const [contentLines, setContentLines] = useState(MIN_CONTENT_LINES);
|
|
7896
8130
|
const [attachments, setAttachments] = useState([]);
|
|
8131
|
+
const [notice, setNotice] = useState(null);
|
|
8132
|
+
const noticeTimerRef = useRef(null);
|
|
8133
|
+
const showNotice = useCallback((message) => {
|
|
8134
|
+
setNotice(message);
|
|
8135
|
+
if (noticeTimerRef.current) clearTimeout(noticeTimerRef.current);
|
|
8136
|
+
noticeTimerRef.current = setTimeout(setNotice, NOTICE_TTL_MS, null);
|
|
8137
|
+
}, []);
|
|
8138
|
+
useEffect(() => () => {
|
|
8139
|
+
if (noticeTimerRef.current) clearTimeout(noticeTimerRef.current);
|
|
8140
|
+
}, []);
|
|
8141
|
+
/**
|
|
8142
|
+
* Read an image from the OS clipboard and attach it. Fired by the dedicated
|
|
8143
|
+
* keybinding and by the empty-paste probe. Every outcome lands in the
|
|
8144
|
+
* transient notice line — including the soft "no image" / "helper missing" /
|
|
8145
|
+
* "over SSH" cases — so the user always gets feedback.
|
|
8146
|
+
*/
|
|
8147
|
+
const attachClipboardImage = useCallback(async () => {
|
|
8148
|
+
if (!attachmentsEnabled) {
|
|
8149
|
+
showNotice("attachments are disabled — enable them in Settings → Agent");
|
|
8150
|
+
return;
|
|
8151
|
+
}
|
|
8152
|
+
const result = await readClipboardImage();
|
|
8153
|
+
if (!result.ok) {
|
|
8154
|
+
showNotice(result.reason === "no-image" ? "no image in the clipboard" : result.detail ?? "could not read a clipboard image");
|
|
8155
|
+
return;
|
|
8156
|
+
}
|
|
8157
|
+
if (result.data.length > MAX_IMAGE_BYTES) {
|
|
8158
|
+
showNotice(`clipboard image too large (${formatBytes(result.data.length)}) — max ${formatBytes(MAX_IMAGE_BYTES)}`);
|
|
8159
|
+
return;
|
|
8160
|
+
}
|
|
8161
|
+
setAttachments((prev) => {
|
|
8162
|
+
const n = prev.filter((a) => a.name.startsWith("clipboard-")).length + 1;
|
|
8163
|
+
return [...prev, {
|
|
8164
|
+
name: `clipboard-${n}.${extForImageMediaType(result.mediaType)}`,
|
|
8165
|
+
content: result.data,
|
|
8166
|
+
mediaType: result.mediaType
|
|
8167
|
+
}];
|
|
8168
|
+
});
|
|
8169
|
+
}, [attachmentsEnabled, showNotice]);
|
|
7897
8170
|
/**
|
|
7898
8171
|
* Mirror of the textarea buffer + cursor, updated on every `onContentChange`.
|
|
7899
8172
|
* Drives `useCompletion` — the textarea stays uncontrolled (we don't push
|
|
@@ -7978,7 +8251,10 @@ function PromptBlock({ userPrompts, onSubmit, completionProviders, onCompletionT
|
|
|
7978
8251
|
const ta = textareaRef.current;
|
|
7979
8252
|
if (!ta) return;
|
|
7980
8253
|
const normalized = stripAnsiSequences(decodePasteBytes(event.bytes)).replace(/\r\n?/g, "\n");
|
|
7981
|
-
if (normalized.length === 0)
|
|
8254
|
+
if (normalized.length === 0) {
|
|
8255
|
+
if (attachmentsEnabled) attachClipboardImage();
|
|
8256
|
+
return;
|
|
8257
|
+
}
|
|
7982
8258
|
if (attachmentsEnabled && !normalized.includes("\n")) {
|
|
7983
8259
|
const trimmed = normalized.trim().replace(/^["']|["']$/g, "");
|
|
7984
8260
|
let resolved = trimmed.startsWith("file://") ? decodeURIComponent(trimmed.slice(7)) : trimmed;
|
|
@@ -8012,7 +8288,11 @@ function PromptBlock({ userPrompts, onSubmit, completionProviders, onCompletionT
|
|
|
8012
8288
|
if (part && part.length > 0) ta.insertText(part);
|
|
8013
8289
|
}
|
|
8014
8290
|
syncBuffer();
|
|
8015
|
-
}, [
|
|
8291
|
+
}, [
|
|
8292
|
+
syncBuffer,
|
|
8293
|
+
attachmentsEnabled,
|
|
8294
|
+
attachClipboardImage
|
|
8295
|
+
]);
|
|
8016
8296
|
const cycleHistory = useCallback((direction) => {
|
|
8017
8297
|
if (userPrompts.length === 0 || !textareaRef.current) return;
|
|
8018
8298
|
if (historyRef.current === null) historyRef.current = {
|
|
@@ -8051,6 +8331,20 @@ function PromptBlock({ userPrompts, onSubmit, completionProviders, onCompletionT
|
|
|
8051
8331
|
* through so the textarea moves the cursor as usual.
|
|
8052
8332
|
*/
|
|
8053
8333
|
const onKeyDown = useCallback((event) => {
|
|
8334
|
+
if (attachImageBinding && matchesBinding(event, attachImageBinding)) {
|
|
8335
|
+
event.preventDefault();
|
|
8336
|
+
attachClipboardImage();
|
|
8337
|
+
return;
|
|
8338
|
+
}
|
|
8339
|
+
if ((event.name === "backspace" || event.name === "delete") && !event.meta && !event.shift && attachments.length > 0) {
|
|
8340
|
+
const buf = textareaRef.current;
|
|
8341
|
+
const emptyPrompt = !buf || buf.plainText.length === 0;
|
|
8342
|
+
if (event.ctrl || emptyPrompt) {
|
|
8343
|
+
event.preventDefault();
|
|
8344
|
+
setAttachments((prev) => prev.slice(0, -1));
|
|
8345
|
+
return;
|
|
8346
|
+
}
|
|
8347
|
+
}
|
|
8054
8348
|
if (popupOpen) {
|
|
8055
8349
|
if (event.ctrl || event.meta) return;
|
|
8056
8350
|
switch (event.name) {
|
|
@@ -8112,7 +8406,11 @@ function PromptBlock({ userPrompts, onSubmit, completionProviders, onCompletionT
|
|
|
8112
8406
|
cycleHistory,
|
|
8113
8407
|
onEnterQueueFromEmpty,
|
|
8114
8408
|
onCompletionTab,
|
|
8115
|
-
syncBuffer
|
|
8409
|
+
syncBuffer,
|
|
8410
|
+
attachImageBinding,
|
|
8411
|
+
attachClipboardImage,
|
|
8412
|
+
attachments,
|
|
8413
|
+
showNotice
|
|
8116
8414
|
]);
|
|
8117
8415
|
const boxHeight = Math.min(MAX_CONTENT_LINES, contentLines) + 2;
|
|
8118
8416
|
return /* @__PURE__ */ jsxs("box", {
|
|
@@ -8137,57 +8435,68 @@ function PromptBlock({ userPrompts, onSubmit, completionProviders, onCompletionT
|
|
|
8137
8435
|
children: attachments.map((att, idx) => {
|
|
8138
8436
|
const sz = att.content.length;
|
|
8139
8437
|
const label = sz < 1024 ? `${sz}B` : sz < 1024 * 1024 ? `${(sz / 1024).toFixed(1)}KB` : `${(sz / (1024 * 1024)).toFixed(1)}MB`;
|
|
8140
|
-
const icon = att.mediaType.startsWith("image/") ? "🖼" : "📎";
|
|
8141
8438
|
const chipColor = resolveChipColor(SURFACE.chips, "file");
|
|
8142
|
-
return /* @__PURE__ */ jsxs("text", { children: [
|
|
8143
|
-
|
|
8144
|
-
|
|
8145
|
-
|
|
8146
|
-
|
|
8147
|
-
|
|
8148
|
-
|
|
8149
|
-
|
|
8150
|
-
|
|
8151
|
-
|
|
8152
|
-
|
|
8153
|
-
|
|
8154
|
-
|
|
8155
|
-
" "
|
|
8156
|
-
]
|
|
8157
|
-
})
|
|
8158
|
-
] }, `${att.name}-${idx}`);
|
|
8439
|
+
return /* @__PURE__ */ jsxs("text", { children: [idx > 0 ? " " : "", /* @__PURE__ */ jsxs("span", {
|
|
8440
|
+
fg: chipColor.fg,
|
|
8441
|
+
bg: chipColor.bg,
|
|
8442
|
+
children: [
|
|
8443
|
+
" ",
|
|
8444
|
+
att.name,
|
|
8445
|
+
" ",
|
|
8446
|
+
"(",
|
|
8447
|
+
label,
|
|
8448
|
+
")",
|
|
8449
|
+
" "
|
|
8450
|
+
]
|
|
8451
|
+
})] }, `${att.name}-${idx}`);
|
|
8159
8452
|
})
|
|
8160
8453
|
}),
|
|
8161
|
-
/* @__PURE__ */ jsx("box", {
|
|
8454
|
+
notice !== null && /* @__PURE__ */ jsx("box", {
|
|
8162
8455
|
style: {
|
|
8163
|
-
|
|
8164
|
-
borderColor: selectMode ? COLOR.warn : COLOR.borderActive,
|
|
8456
|
+
flexDirection: "row",
|
|
8165
8457
|
paddingLeft: 1,
|
|
8166
|
-
paddingRight: 1
|
|
8167
|
-
height: boxHeight,
|
|
8168
|
-
flexDirection: "column"
|
|
8458
|
+
paddingRight: 1
|
|
8169
8459
|
},
|
|
8170
|
-
children: /* @__PURE__ */ jsx("
|
|
8171
|
-
|
|
8172
|
-
|
|
8173
|
-
keyBindings: TEXTAREA_BINDINGS,
|
|
8174
|
-
wrapMode: "word",
|
|
8175
|
-
placeholder: selectMode === "turn" ? "— turn-select mode — press ⎋ to resume typing —" : selectMode === "queue" ? "— queue-select mode — press ⎋ to resume typing —" : "Ask zidane…",
|
|
8176
|
-
syntaxStyle: chipStyle,
|
|
8177
|
-
style: {
|
|
8178
|
-
flexGrow: 1,
|
|
8179
|
-
height: "100%"
|
|
8180
|
-
},
|
|
8181
|
-
onSubmit: submit,
|
|
8182
|
-
onContentChange: syncBuffer,
|
|
8183
|
-
onKeyDown,
|
|
8184
|
-
onPaste
|
|
8460
|
+
children: /* @__PURE__ */ jsx("text", {
|
|
8461
|
+
fg: COLOR.dim,
|
|
8462
|
+
children: notice
|
|
8185
8463
|
})
|
|
8186
8464
|
}),
|
|
8187
|
-
/* @__PURE__ */
|
|
8188
|
-
|
|
8189
|
-
|
|
8190
|
-
|
|
8465
|
+
/* @__PURE__ */ jsxs("box", {
|
|
8466
|
+
style: {
|
|
8467
|
+
flexDirection: "column",
|
|
8468
|
+
flexShrink: 0
|
|
8469
|
+
},
|
|
8470
|
+
children: [/* @__PURE__ */ jsx("box", {
|
|
8471
|
+
style: {
|
|
8472
|
+
border: true,
|
|
8473
|
+
borderColor: selectMode ? COLOR.warn : COLOR.borderActive,
|
|
8474
|
+
paddingLeft: 1,
|
|
8475
|
+
paddingRight: 1,
|
|
8476
|
+
height: boxHeight,
|
|
8477
|
+
flexDirection: "column"
|
|
8478
|
+
},
|
|
8479
|
+
children: /* @__PURE__ */ jsx("textarea", {
|
|
8480
|
+
ref: textareaRef,
|
|
8481
|
+
focused: focused && !selectMode,
|
|
8482
|
+
keyBindings: TEXTAREA_BINDINGS,
|
|
8483
|
+
wrapMode: "word",
|
|
8484
|
+
placeholder: selectMode === "turn" ? "— turn-select mode — press ⎋ to resume typing —" : selectMode === "queue" ? "— queue-select mode — press ⎋ to resume typing —" : "Ask zidane…",
|
|
8485
|
+
syntaxStyle: chipStyle,
|
|
8486
|
+
style: {
|
|
8487
|
+
flexGrow: 1,
|
|
8488
|
+
height: "100%"
|
|
8489
|
+
},
|
|
8490
|
+
onSubmit: submit,
|
|
8491
|
+
onContentChange: syncBuffer,
|
|
8492
|
+
onKeyDown,
|
|
8493
|
+
onPaste
|
|
8494
|
+
})
|
|
8495
|
+
}), /* @__PURE__ */ jsx(PromptHints, {
|
|
8496
|
+
selectMode,
|
|
8497
|
+
triggerHints,
|
|
8498
|
+
busy
|
|
8499
|
+
})]
|
|
8191
8500
|
})
|
|
8192
8501
|
]
|
|
8193
8502
|
}), !selectMode && /* @__PURE__ */ jsx("box", {
|
|
@@ -13597,11 +13906,11 @@ function AppShell() {
|
|
|
13597
13906
|
},
|
|
13598
13907
|
{
|
|
13599
13908
|
key: "#",
|
|
13600
|
-
label:
|
|
13909
|
+
label: "chat",
|
|
13601
13910
|
keyColor: resolveChipColor(SURFACE.chips, "chats").bg
|
|
13602
13911
|
}
|
|
13603
13912
|
];
|
|
13604
|
-
}, [SURFACE
|
|
13913
|
+
}, [SURFACE]);
|
|
13605
13914
|
const contextUsage = useMemo(() => {
|
|
13606
13915
|
if (screen !== "chat" || !picked) return null;
|
|
13607
13916
|
const descriptor = providerRegistry[picked.provider.key];
|
|
@@ -13675,7 +13984,8 @@ function AppShell() {
|
|
|
13675
13984
|
},
|
|
13676
13985
|
onPopupOpenChange,
|
|
13677
13986
|
selectedTurnId,
|
|
13678
|
-
promptTriggerHints
|
|
13987
|
+
promptTriggerHints,
|
|
13988
|
+
attachImageBinding: keybindings.attachClipboardImage
|
|
13679
13989
|
})
|
|
13680
13990
|
]
|
|
13681
13991
|
}),
|