@dexto/tui 1.7.1 → 1.8.0

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.
Files changed (99) hide show
  1. package/dist/agent-backend.cjs +16 -2
  2. package/dist/agent-backend.d.ts +5 -2
  3. package/dist/agent-backend.d.ts.map +1 -1
  4. package/dist/agent-backend.js +15 -2
  5. package/dist/agent-backend.test.cjs +28 -2
  6. package/dist/agent-backend.test.js +28 -2
  7. package/dist/components/ApprovalPrompt.cjs +6 -5
  8. package/dist/components/ApprovalPrompt.d.ts +1 -1
  9. package/dist/components/ApprovalPrompt.d.ts.map +1 -1
  10. package/dist/components/ApprovalPrompt.js +6 -5
  11. package/dist/components/TextBufferInput.cjs +14 -1
  12. package/dist/components/TextBufferInput.d.ts +5 -1
  13. package/dist/components/TextBufferInput.d.ts.map +1 -1
  14. package/dist/components/TextBufferInput.js +14 -1
  15. package/dist/components/chat/QueuedMessagesDisplay.cjs +17 -8
  16. package/dist/components/chat/QueuedMessagesDisplay.d.ts +7 -1
  17. package/dist/components/chat/QueuedMessagesDisplay.d.ts.map +1 -1
  18. package/dist/components/chat/QueuedMessagesDisplay.js +16 -8
  19. package/dist/components/input/InputArea.cjs +4 -0
  20. package/dist/components/input/InputArea.d.ts +5 -1
  21. package/dist/components/input/InputArea.d.ts.map +1 -1
  22. package/dist/components/input/InputArea.js +4 -0
  23. package/dist/components/modes/AlternateBufferCLI.cjs +20 -1
  24. package/dist/components/modes/AlternateBufferCLI.d.ts.map +1 -1
  25. package/dist/components/modes/AlternateBufferCLI.js +21 -2
  26. package/dist/components/modes/StaticCLI.cjs +20 -1
  27. package/dist/components/modes/StaticCLI.d.ts.map +1 -1
  28. package/dist/components/modes/StaticCLI.js +21 -2
  29. package/dist/components/overlays/LoginOverlay.cjs +2 -10
  30. package/dist/components/overlays/LoginOverlay.d.ts.map +1 -1
  31. package/dist/components/overlays/LoginOverlay.js +3 -11
  32. package/dist/containers/InputContainer.cjs +119 -18
  33. package/dist/containers/InputContainer.d.ts +6 -2
  34. package/dist/containers/InputContainer.d.ts.map +1 -1
  35. package/dist/containers/InputContainer.js +119 -18
  36. package/dist/hooks/useAgentEvents.cjs +27 -5
  37. package/dist/hooks/useAgentEvents.d.ts +3 -2
  38. package/dist/hooks/useAgentEvents.d.ts.map +1 -1
  39. package/dist/hooks/useAgentEvents.js +27 -5
  40. package/dist/hooks/useCLIState.cjs +10 -4
  41. package/dist/hooks/useCLIState.d.ts +2 -0
  42. package/dist/hooks/useCLIState.d.ts.map +1 -1
  43. package/dist/hooks/useCLIState.js +10 -4
  44. package/dist/hooks/useInputOrchestrator.cjs +15 -14
  45. package/dist/hooks/useInputOrchestrator.d.ts +6 -6
  46. package/dist/hooks/useInputOrchestrator.d.ts.map +1 -1
  47. package/dist/hooks/useInputOrchestrator.js +15 -14
  48. package/dist/host/index.cjs +6 -6
  49. package/dist/host/index.d.ts +8 -17
  50. package/dist/host/index.d.ts.map +1 -1
  51. package/dist/host/index.js +5 -5
  52. package/dist/host/index.test.cjs +47 -0
  53. package/dist/host/index.test.d.ts +2 -0
  54. package/dist/host/index.test.d.ts.map +1 -0
  55. package/dist/host/index.test.js +50 -0
  56. package/dist/index.d.cts +10 -15
  57. package/dist/interactive-commands/command-parser.cjs +1 -0
  58. package/dist/interactive-commands/command-parser.d.ts.map +1 -1
  59. package/dist/interactive-commands/command-parser.js +1 -0
  60. package/dist/interactive-commands/commands.cjs +3 -0
  61. package/dist/interactive-commands/commands.d.ts.map +1 -1
  62. package/dist/interactive-commands/commands.js +3 -0
  63. package/dist/interactive-commands/commands.test.cjs +42 -0
  64. package/dist/interactive-commands/commands.test.js +42 -0
  65. package/dist/interactive-commands/prompt-commands.cjs +4 -66
  66. package/dist/interactive-commands/prompt-commands.d.ts +1 -2
  67. package/dist/interactive-commands/prompt-commands.d.ts.map +1 -1
  68. package/dist/interactive-commands/prompt-commands.js +4 -66
  69. package/dist/interactive-commands/skill-commands.cjs +73 -0
  70. package/dist/interactive-commands/skill-commands.d.ts +9 -0
  71. package/dist/interactive-commands/skill-commands.d.ts.map +1 -0
  72. package/dist/interactive-commands/skill-commands.js +49 -0
  73. package/dist/services/processStream.cjs +23 -4
  74. package/dist/services/processStream.d.ts +3 -1
  75. package/dist/services/processStream.d.ts.map +1 -1
  76. package/dist/services/processStream.js +23 -4
  77. package/dist/services/processStream.test.cjs +52 -2
  78. package/dist/services/processStream.test.js +52 -2
  79. package/dist/state/initialState.cjs +2 -1
  80. package/dist/state/initialState.d.ts.map +1 -1
  81. package/dist/state/initialState.js +2 -1
  82. package/dist/state/reducer.cjs +10 -5
  83. package/dist/state/reducer.d.ts.map +1 -1
  84. package/dist/state/reducer.js +10 -5
  85. package/dist/state/types.d.ts +2 -0
  86. package/dist/state/types.d.ts.map +1 -1
  87. package/dist/utils/messageFormatting.cjs +0 -23
  88. package/dist/utils/messageFormatting.d.ts +0 -13
  89. package/dist/utils/messageFormatting.d.ts.map +1 -1
  90. package/dist/utils/messageFormatting.js +0 -21
  91. package/dist/utils/queuedComposerContent.cjs +148 -0
  92. package/dist/utils/queuedComposerContent.d.ts +17 -0
  93. package/dist/utils/queuedComposerContent.d.ts.map +1 -0
  94. package/dist/utils/queuedComposerContent.js +123 -0
  95. package/dist/utils/queuedComposerContent.test.cjs +176 -0
  96. package/dist/utils/queuedComposerContent.test.d.ts +2 -0
  97. package/dist/utils/queuedComposerContent.test.d.ts.map +1 -0
  98. package/dist/utils/queuedComposerContent.test.js +175 -0
  99. package/package.json +4 -4
@@ -26,11 +26,13 @@ __export(agent_backend_exports, {
26
26
  supportsPrompts: () => supportsPrompts,
27
27
  supportsReasoningCycle: () => supportsReasoningCycle,
28
28
  supportsResources: () => supportsResources,
29
+ supportsSkills: () => supportsSkills,
29
30
  supportsStartupInfo: () => supportsStartupInfo
30
31
  });
31
32
  module.exports = __toCommonJS(agent_backend_exports);
32
33
  const DEFAULT_CAPABILITIES = {
33
34
  prompts: true,
35
+ skills: true,
34
36
  resources: true,
35
37
  attachments: true,
36
38
  reasoningCycle: true,
@@ -42,6 +44,10 @@ const COMMAND_CAPABILITY_GATES = [
42
44
  capability: "prompts",
43
45
  commands: ["prompts", "sysprompt"]
44
46
  },
47
+ {
48
+ capability: "skills",
49
+ commands: ["skills"]
50
+ },
45
51
  {
46
52
  capability: "reasoningCycle",
47
53
  commands: ["reasoning"]
@@ -55,9 +61,13 @@ function normalizeCommandName(command) {
55
61
  return command.trim().toLowerCase();
56
62
  }
57
63
  function getTuiCapabilities(agent) {
58
- return {
64
+ const mergedCapabilities = {
59
65
  ...DEFAULT_CAPABILITIES,
60
- ...agent.capabilities,
66
+ ...agent.capabilities
67
+ };
68
+ return {
69
+ ...mergedCapabilities,
70
+ skills: mergedCapabilities.skills === false ? false : Boolean(agent.skillManager),
61
71
  ...agent.capabilities?.supportedCommands ? {
62
72
  supportedCommands: agent.capabilities.supportedCommands.map(normalizeCommandName)
63
73
  } : {}
@@ -89,6 +99,9 @@ function isCommandDefinitionSupported(agent, definition) {
89
99
  function supportsPrompts(agent) {
90
100
  return getTuiCapabilities(agent).prompts ?? true;
91
101
  }
102
+ function supportsSkills(agent) {
103
+ return getTuiCapabilities(agent).skills ?? true;
104
+ }
92
105
  function supportsResources(agent) {
93
106
  return getTuiCapabilities(agent).resources ?? true;
94
107
  }
@@ -114,5 +127,6 @@ function supportsStartupInfo(agent) {
114
127
  supportsPrompts,
115
128
  supportsReasoningCycle,
116
129
  supportsResources,
130
+ supportsSkills,
117
131
  supportsStartupInfo
118
132
  });
@@ -1,8 +1,9 @@
1
- import type { AgentEventMap, DextoAgent, EventListener, SessionMetadata } from '@dexto/core';
1
+ import type { AgentEventMap, DextoAgent, EventListener, SessionMetadata, SkillManager } from '@dexto/core';
2
2
  import type { CommandDefinition } from './interactive-commands/command-parser.js';
3
3
  export interface TuiAgentCapabilities {
4
4
  supportedCommands?: readonly string[];
5
5
  prompts?: boolean;
6
+ skills?: boolean;
6
7
  resources?: boolean;
7
8
  attachments?: boolean;
8
9
  reasoningCycle?: boolean;
@@ -33,7 +34,7 @@ export interface TuiEffectiveConfig {
33
34
  prompts?: unknown[] | undefined;
34
35
  [key: string]: unknown;
35
36
  }
36
- export interface TuiAgentBackend extends Pick<DextoAgent, 'stream' | 'stop' | 'run' | 'listSessions' | 'getSessionMetadata' | 'getSessionHistory' | 'getSessionTitle' | 'setSessionTitle' | 'generateSessionTitle' | 'forkSession' | 'getCurrentLLMConfig' | 'hasSessionLLMOverride' | 'switchLLM' | 'getSupportedProviders' | 'getSupportedModels' | 'getContextStats' | 'clearContext' | 'compactContext' | 'queueMessage' | 'getQueuedMessages' | 'removeQueuedMessage' | 'clearMessageQueue' | 'cancel' | 'searchMessages' | 'listPrompts' | 'refreshPrompts' | 'resolvePrompt' | 'getSystemPrompt' | 'loadToolkits' | 'listResources' | 'setLogLevel' | 'getAllTools' | 'getEnabledTools' | 'getAllMcpTools' | 'setGlobalDisabledTools' | 'setSessionDisabledTools' | 'setSessionAutoApproveTools' | 'getSessionAutoApproveTools' | 'getMcpServersWithStatus' | 'addMcpServer' | 'enableMcpServer' | 'disableMcpServer' | 'removeMcpServer' | 'restartMcpServer' | 'getMcpClients' | 'getMcpFailedConnections'> {
37
+ export interface TuiAgentBackend extends Pick<DextoAgent, 'stream' | 'stop' | 'run' | 'listSessions' | 'getSessionMetadata' | 'getSessionHistory' | 'getSessionTitle' | 'setSessionTitle' | 'generateSessionTitle' | 'forkSession' | 'getCurrentLLMConfig' | 'hasSessionLLMOverride' | 'switchLLM' | 'getSupportedProviders' | 'getSupportedModels' | 'getContextStats' | 'clearContext' | 'compactContext' | 'steer' | 'followUp' | 'getSteerMessages' | 'getFollowUpMessages' | 'removeSteerMessage' | 'removeFollowUpMessage' | 'clearSteerQueue' | 'clearFollowUpQueue' | 'cancel' | 'searchMessages' | 'listPrompts' | 'refreshPrompts' | 'resolvePrompt' | 'getSystemPrompt' | 'loadToolkits' | 'listResources' | 'setLogLevel' | 'getAllTools' | 'getEnabledTools' | 'getAllMcpTools' | 'setGlobalDisabledTools' | 'setSessionDisabledTools' | 'setSessionAutoApproveTools' | 'getSessionAutoApproveTools' | 'getMcpServersWithStatus' | 'addMcpServer' | 'enableMcpServer' | 'disableMcpServer' | 'removeMcpServer' | 'restartMcpServer' | 'getMcpClients' | 'getMcpFailedConnections'> {
37
38
  createSession: (sessionId?: string) => Promise<{
38
39
  id: string;
39
40
  logger: Pick<RootLogger, 'getLevel' | 'getLogFilePath'>;
@@ -67,12 +68,14 @@ export interface TuiAgentBackend extends Pick<DextoAgent, 'stream' | 'stop' | 'r
67
68
  getHookNames: () => string[];
68
69
  };
69
70
  };
71
+ skillManager?: SkillManager | undefined;
70
72
  capabilities?: TuiAgentCapabilities;
71
73
  }
72
74
  export declare function getTuiCapabilities(agent: TuiAgentBackend): TuiAgentCapabilities;
73
75
  export declare function isCommandSupported(agent: TuiAgentBackend, command: string, definition?: Pick<CommandDefinition, 'name' | 'aliases'>): boolean;
74
76
  export declare function isCommandDefinitionSupported(agent: TuiAgentBackend, definition: Pick<CommandDefinition, 'name' | 'aliases'>): boolean;
75
77
  export declare function supportsPrompts(agent: TuiAgentBackend): boolean;
78
+ export declare function supportsSkills(agent: TuiAgentBackend): boolean;
76
79
  export declare function supportsResources(agent: TuiAgentBackend): boolean;
77
80
  export declare function supportsAttachments(agent: TuiAgentBackend): boolean;
78
81
  export declare function supportsReasoningCycle(agent: TuiAgentBackend): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"agent-backend.d.ts","sourceRoot":"","sources":["../src/agent-backend.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent-backend.d.ts","sourceRoot":"","sources":["../src/agent-backend.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  const DEFAULT_CAPABILITIES = {
2
2
  prompts: true,
3
+ skills: true,
3
4
  resources: true,
4
5
  attachments: true,
5
6
  reasoningCycle: true,
@@ -11,6 +12,10 @@ const COMMAND_CAPABILITY_GATES = [
11
12
  capability: "prompts",
12
13
  commands: ["prompts", "sysprompt"]
13
14
  },
15
+ {
16
+ capability: "skills",
17
+ commands: ["skills"]
18
+ },
14
19
  {
15
20
  capability: "reasoningCycle",
16
21
  commands: ["reasoning"]
@@ -24,9 +29,13 @@ function normalizeCommandName(command) {
24
29
  return command.trim().toLowerCase();
25
30
  }
26
31
  function getTuiCapabilities(agent) {
27
- return {
32
+ const mergedCapabilities = {
28
33
  ...DEFAULT_CAPABILITIES,
29
- ...agent.capabilities,
34
+ ...agent.capabilities
35
+ };
36
+ return {
37
+ ...mergedCapabilities,
38
+ skills: mergedCapabilities.skills === false ? false : Boolean(agent.skillManager),
30
39
  ...agent.capabilities?.supportedCommands ? {
31
40
  supportedCommands: agent.capabilities.supportedCommands.map(normalizeCommandName)
32
41
  } : {}
@@ -58,6 +67,9 @@ function isCommandDefinitionSupported(agent, definition) {
58
67
  function supportsPrompts(agent) {
59
68
  return getTuiCapabilities(agent).prompts ?? true;
60
69
  }
70
+ function supportsSkills(agent) {
71
+ return getTuiCapabilities(agent).skills ?? true;
72
+ }
61
73
  function supportsResources(agent) {
62
74
  return getTuiCapabilities(agent).resources ?? true;
63
75
  }
@@ -82,5 +94,6 @@ export {
82
94
  supportsPrompts,
83
95
  supportsReasoningCycle,
84
96
  supportsResources,
97
+ supportsSkills,
85
98
  supportsStartupInfo
86
99
  };
@@ -1,8 +1,20 @@
1
1
  "use strict";
2
2
  var import_vitest = require("vitest");
3
3
  var import_agent_backend = require("./agent-backend.js");
4
- function createAgent(capabilities) {
5
- return { capabilities };
4
+ function createAgent(capabilities, options = {}) {
5
+ return {
6
+ capabilities,
7
+ ...options.hasSkillManager ? {
8
+ skillManager: {
9
+ list: async () => [],
10
+ get: async () => null,
11
+ readFile: async () => null,
12
+ invoke: async () => null,
13
+ refresh: async () => {
14
+ }
15
+ }
16
+ } : {}
17
+ };
6
18
  }
7
19
  (0, import_vitest.describe)("isCommandSupported", () => {
8
20
  (0, import_vitest.it)("blocks capability-gated commands when the capability is disabled", () => {
@@ -25,4 +37,18 @@ function createAgent(capabilities) {
25
37
  const agent = createAgent({ prompts: false });
26
38
  (0, import_vitest.expect)((0, import_agent_backend.isCommandSupported)(agent, "help", { name: "help", aliases: ["h"] })).toBe(true);
27
39
  });
40
+ (0, import_vitest.it)("gates skill commands separately from prompt commands", () => {
41
+ const promptlessAgent = createAgent({ prompts: false }, { hasSkillManager: true });
42
+ const skilllessAgent = createAgent({ skills: false }, { hasSkillManager: true });
43
+ (0, import_vitest.expect)((0, import_agent_backend.isCommandSupported)(promptlessAgent, "skills", { name: "skills", aliases: [] })).toBe(
44
+ true
45
+ );
46
+ (0, import_vitest.expect)((0, import_agent_backend.isCommandSupported)(skilllessAgent, "skills", { name: "skills", aliases: [] })).toBe(
47
+ false
48
+ );
49
+ });
50
+ (0, import_vitest.it)("requires a real SkillManager for skill commands", () => {
51
+ const agent = createAgent();
52
+ (0, import_vitest.expect)((0, import_agent_backend.isCommandSupported)(agent, "skills", { name: "skills", aliases: [] })).toBe(false);
53
+ });
28
54
  });
@@ -2,8 +2,20 @@ import { describe, expect, it } from "vitest";
2
2
  import {
3
3
  isCommandSupported
4
4
  } from "./agent-backend.js";
5
- function createAgent(capabilities) {
6
- return { capabilities };
5
+ function createAgent(capabilities, options = {}) {
6
+ return {
7
+ capabilities,
8
+ ...options.hasSkillManager ? {
9
+ skillManager: {
10
+ list: async () => [],
11
+ get: async () => null,
12
+ readFile: async () => null,
13
+ invoke: async () => null,
14
+ refresh: async () => {
15
+ }
16
+ }
17
+ } : {}
18
+ };
7
19
  }
8
20
  describe("isCommandSupported", () => {
9
21
  it("blocks capability-gated commands when the capability is disabled", () => {
@@ -26,4 +38,18 @@ describe("isCommandSupported", () => {
26
38
  const agent = createAgent({ prompts: false });
27
39
  expect(isCommandSupported(agent, "help", { name: "help", aliases: ["h"] })).toBe(true);
28
40
  });
41
+ it("gates skill commands separately from prompt commands", () => {
42
+ const promptlessAgent = createAgent({ prompts: false }, { hasSkillManager: true });
43
+ const skilllessAgent = createAgent({ skills: false }, { hasSkillManager: true });
44
+ expect(isCommandSupported(promptlessAgent, "skills", { name: "skills", aliases: [] })).toBe(
45
+ true
46
+ );
47
+ expect(isCommandSupported(skilllessAgent, "skills", { name: "skills", aliases: [] })).toBe(
48
+ false
49
+ );
50
+ });
51
+ it("requires a real SkillManager for skill commands", () => {
52
+ const agent = createAgent();
53
+ expect(isCommandSupported(agent, "skills", { name: "skills", aliases: [] })).toBe(false);
54
+ });
29
55
  });
@@ -24,17 +24,18 @@ module.exports = __toCommonJS(ApprovalPrompt_exports);
24
24
  var import_jsx_runtime = require("react/jsx-runtime");
25
25
  var import_react = require("react");
26
26
  var import_ink = require("ink");
27
+ var import_core = require("@dexto/core");
27
28
  var import_ElicitationForm = require("./ElicitationForm.js");
28
29
  var import_renderers = require("./renderers/index.js");
29
30
  var import_toolUtils = require("../utils/toolUtils.js");
30
31
  var import_messageFormatting = require("../utils/messageFormatting.js");
31
32
  const ApprovalPrompt = (0, import_react.forwardRef)(
32
33
  ({ approval, onApprove, onDeny, onCancel }, ref) => {
33
- const isCommandConfirmation = approval.type === "command_confirmation";
34
+ const isCommandApproval = approval.type === import_core.ApprovalType.COMMAND_APPROVAL;
34
35
  const isElicitation = approval.type === "elicitation";
35
36
  const isDirectoryAccess = approval.type === "directory_access";
36
37
  const directoryAccess = approval.metadata.directoryAccess;
37
- const hasToolDirectoryAccess = approval.type === "tool_confirmation" && directoryAccess !== void 0 && typeof directoryAccess === "object" && directoryAccess !== null;
38
+ const hasToolDirectoryAccess = approval.type === import_core.ApprovalType.TOOL_APPROVAL && directoryAccess !== void 0 && typeof directoryAccess === "object" && directoryAccess !== null;
38
39
  const directoryAccessParentDir = hasToolDirectoryAccess && typeof directoryAccess.parentDir === "string" ? directoryAccess.parentDir : null;
39
40
  const toolName = approval.metadata.toolName;
40
41
  const toolArgs = approval.metadata.args || {};
@@ -93,7 +94,7 @@ const ApprovalPrompt = (0, import_react.forwardRef)(
93
94
  });
94
95
  options.push({ id: "yes-session", label: "Yes, allow this tool (session)" });
95
96
  options.push({ id: "no", label: "No" });
96
- } else if (isCommandConfirmation) {
97
+ } else if (isCommandApproval) {
97
98
  options.push({ id: "yes", label: "Yes" });
98
99
  options.push({ id: "no", label: "No" });
99
100
  } else if (isDirectoryAccess) {
@@ -273,12 +274,12 @@ const ApprovalPrompt = (0, import_react.forwardRef)(
273
274
  args: directoryPath ?? parentDir ? { path: directoryPath ?? parentDir } : {},
274
275
  ...presentationSnapshot !== void 0 && { presentationSnapshot }
275
276
  }).header;
276
- const showHeaderBlock = isDirectoryAccess || isCommandConfirmation || !displayPreview;
277
+ const showHeaderBlock = isDirectoryAccess || isCommandApproval || !displayPreview;
277
278
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink.Box, { paddingX: 0, paddingY: 0, flexDirection: "column", children: [
278
279
  showHeaderBlock && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Box, { flexDirection: "column", marginBottom: 0, children: isDirectoryAccess ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
279
280
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Box, { marginBottom: 0, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Text, { color: "cyan", bold: true, children: directoryAccessTitle ?? "Directory access" }) }),
280
281
  directoryAccessToolHeader && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Box, { marginBottom: 0, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Text, { wrap: "wrap", children: directoryAccessToolHeader }) })
281
- ] }) : isCommandConfirmation ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
282
+ ] }) : isCommandApproval ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
282
283
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Box, { flexDirection: "row", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink.Text, { color: "yellowBright", bold: true, children: [
283
284
  "Confirm command:",
284
285
  " "
@@ -37,7 +37,7 @@ interface ApprovalPromptProps {
37
37
  /**
38
38
  * Compact approval prompt component that displays above the input area
39
39
  * Shows options based on approval type:
40
- * - Tool confirmation: Yes, Yes (Session), No
40
+ * - Tool approval: Yes, Yes (Session), No
41
41
  * - Tool with patterns: Yes (once), pattern options, Yes (session), No
42
42
  * - Elicitation: Form with input fields
43
43
  */
@@ -1 +1 @@
1
- {"version":3,"file":"ApprovalPrompt.d.ts","sourceRoot":"","sources":["../../src/components/ApprovalPrompt.tsx"],"names":[],"mappings":"AAAA,OAAO,KAON,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EACR,kBAAkB,EAIrB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kCAAkC,CAAC;AAM5D,MAAM,WAAW,eAAe;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,oBAAoB;IACjC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC5B,oEAAoE;IACpE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,mDAAmD;IACnD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,gFAAgF;IAChF,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,gDAAgD;IAChD,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,UAAU,mBAAmB;IACzB,QAAQ,EAAE,eAAe,CAAC;IAC1B,SAAS,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;IAC9C,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACxB;AAiBD;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,kGAwe1B,CAAC"}
1
+ {"version":3,"file":"ApprovalPrompt.d.ts","sourceRoot":"","sources":["../../src/components/ApprovalPrompt.tsx"],"names":[],"mappings":"AAAA,OAAO,KAON,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EACR,kBAAkB,EAIrB,MAAM,aAAa,CAAC;AAErB,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kCAAkC,CAAC;AAM5D,MAAM,WAAW,eAAe;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,oBAAoB;IACjC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC5B,oEAAoE;IACpE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,mDAAmD;IACnD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,gFAAgF;IAChF,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,gDAAgD;IAChD,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,UAAU,mBAAmB;IACzB,QAAQ,EAAE,eAAe,CAAC;IAC1B,SAAS,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;IAC9C,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACxB;AAiBD;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,kGAwe1B,CAAC"}
@@ -8,17 +8,18 @@ import {
8
8
  useMemo
9
9
  } from "react";
10
10
  import { Box, Text } from "ink";
11
+ import { ApprovalType } from "@dexto/core";
11
12
  import { ElicitationForm } from "./ElicitationForm.js";
12
13
  import { DiffPreview, CreateFilePreview } from "./renderers/index.js";
13
14
  import { isEditWriteTool } from "../utils/toolUtils.js";
14
15
  import { formatPathForDisplay, formatToolHeader } from "../utils/messageFormatting.js";
15
16
  const ApprovalPrompt = forwardRef(
16
17
  ({ approval, onApprove, onDeny, onCancel }, ref) => {
17
- const isCommandConfirmation = approval.type === "command_confirmation";
18
+ const isCommandApproval = approval.type === ApprovalType.COMMAND_APPROVAL;
18
19
  const isElicitation = approval.type === "elicitation";
19
20
  const isDirectoryAccess = approval.type === "directory_access";
20
21
  const directoryAccess = approval.metadata.directoryAccess;
21
- const hasToolDirectoryAccess = approval.type === "tool_confirmation" && directoryAccess !== void 0 && typeof directoryAccess === "object" && directoryAccess !== null;
22
+ const hasToolDirectoryAccess = approval.type === ApprovalType.TOOL_APPROVAL && directoryAccess !== void 0 && typeof directoryAccess === "object" && directoryAccess !== null;
22
23
  const directoryAccessParentDir = hasToolDirectoryAccess && typeof directoryAccess.parentDir === "string" ? directoryAccess.parentDir : null;
23
24
  const toolName = approval.metadata.toolName;
24
25
  const toolArgs = approval.metadata.args || {};
@@ -77,7 +78,7 @@ const ApprovalPrompt = forwardRef(
77
78
  });
78
79
  options.push({ id: "yes-session", label: "Yes, allow this tool (session)" });
79
80
  options.push({ id: "no", label: "No" });
80
- } else if (isCommandConfirmation) {
81
+ } else if (isCommandApproval) {
81
82
  options.push({ id: "yes", label: "Yes" });
82
83
  options.push({ id: "no", label: "No" });
83
84
  } else if (isDirectoryAccess) {
@@ -257,12 +258,12 @@ const ApprovalPrompt = forwardRef(
257
258
  args: directoryPath ?? parentDir ? { path: directoryPath ?? parentDir } : {},
258
259
  ...presentationSnapshot !== void 0 && { presentationSnapshot }
259
260
  }).header;
260
- const showHeaderBlock = isDirectoryAccess || isCommandConfirmation || !displayPreview;
261
+ const showHeaderBlock = isDirectoryAccess || isCommandApproval || !displayPreview;
261
262
  return /* @__PURE__ */ jsxs(Box, { paddingX: 0, paddingY: 0, flexDirection: "column", children: [
262
263
  showHeaderBlock && /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginBottom: 0, children: isDirectoryAccess ? /* @__PURE__ */ jsxs(Fragment, { children: [
263
264
  /* @__PURE__ */ jsx(Box, { marginBottom: 0, children: /* @__PURE__ */ jsx(Text, { color: "cyan", bold: true, children: directoryAccessTitle ?? "Directory access" }) }),
264
265
  directoryAccessToolHeader && /* @__PURE__ */ jsx(Box, { marginBottom: 0, children: /* @__PURE__ */ jsx(Text, { wrap: "wrap", children: directoryAccessToolHeader }) })
265
- ] }) : isCommandConfirmation ? /* @__PURE__ */ jsxs(Fragment, { children: [
266
+ ] }) : isCommandApproval ? /* @__PURE__ */ jsxs(Fragment, { children: [
266
267
  /* @__PURE__ */ jsx(Box, { flexDirection: "row", children: /* @__PURE__ */ jsxs(Text, { color: "yellowBright", bold: true, children: [
267
268
  "Confirm command:",
268
269
  " "
@@ -62,9 +62,11 @@ function HighlightedText({ text, query }) {
62
62
  function TextBufferInput({
63
63
  buffer,
64
64
  onSubmit,
65
+ onQueueSubmit,
65
66
  placeholder,
66
67
  isDisabled = false,
67
68
  onHistoryNavigate,
69
+ onCurrentTurnEdit,
68
70
  onTriggerOverlay,
69
71
  maxViewportLines = 10,
70
72
  isActive,
@@ -210,10 +212,16 @@ function TextBufferInput({
210
212
  })();
211
213
  return;
212
214
  }
215
+ if (key.name === "return" && key.meta && !key.paste && onQueueSubmit) {
216
+ if (currentText.trim()) {
217
+ onQueueSubmit(currentText);
218
+ }
219
+ return;
220
+ }
213
221
  const isCtrlJ = key.sequence === "\n";
214
222
  const isShiftEnter = key.sequence === "\\\r" || key.name === "return" && key.shift || key.sequence === "\x1B[13;2u" || key.sequence === "\x1BOM";
215
223
  const isPasteReturn = key.name === "return" && key.paste;
216
- const wantsNewline = isCtrlJ || isShiftEnter || key.name === "return" && key.meta || isPasteReturn;
224
+ const wantsNewline = isCtrlJ || isShiftEnter || isPasteReturn;
217
225
  if (wantsNewline) {
218
226
  buffer.newline();
219
227
  return;
@@ -284,6 +292,9 @@ function TextBufferInput({
284
292
  return;
285
293
  }
286
294
  if (key.meta && key.name === "up") {
295
+ if (onCurrentTurnEdit?.()) {
296
+ return;
297
+ }
287
298
  buffer.moveToOffset(0);
288
299
  return;
289
300
  }
@@ -374,7 +385,9 @@ function TextBufferInput({
374
385
  buffer,
375
386
  isDisabled,
376
387
  onSubmit,
388
+ onQueueSubmit,
377
389
  onHistoryNavigate,
390
+ onCurrentTurnEdit,
378
391
  onTriggerOverlay,
379
392
  onKeyboardScroll,
380
393
  // imageCount intentionally omitted - callback uses imageCountRef which is synced via useEffect
@@ -14,12 +14,16 @@ interface TextBufferInputProps {
14
14
  buffer: TextBuffer;
15
15
  /** Called when user presses Enter to submit */
16
16
  onSubmit: (value: string) => void;
17
+ /** Called when user presses Alt+Enter to queue a follow-up */
18
+ onQueueSubmit?: ((value: string) => void) | undefined;
17
19
  /** Placeholder text when empty */
18
20
  placeholder?: string | undefined;
19
21
  /** Whether input handling is disabled (e.g., during processing) */
20
22
  isDisabled?: boolean | undefined;
21
23
  /** Called for history navigation (up/down at boundaries) */
22
24
  onHistoryNavigate?: ((direction: 'up' | 'down') => void) | undefined;
25
+ /** Called before Alt+Up jumps to top; return true to consume */
26
+ onCurrentTurnEdit?: (() => boolean) | undefined;
23
27
  /** Called to trigger overlay (slash command, @mention) */
24
28
  onTriggerOverlay?: ((trigger: OverlayTrigger) => void) | undefined;
25
29
  /** Maximum lines to show in viewport */
@@ -49,6 +53,6 @@ interface TextBufferInputProps {
49
53
  /** Cycle the current reasoning variant. */
50
54
  onCycleReasoningVariant?: (() => void) | undefined;
51
55
  }
52
- export declare function TextBufferInput({ buffer, onSubmit, placeholder, isDisabled, onHistoryNavigate, onTriggerOverlay, maxViewportLines, isActive, onKeyboardScroll, imageCount, onImagePaste, images, onImageRemove, pastedBlocks, onPasteBlock, onPasteBlockUpdate, onPasteBlockRemove, highlightQuery, onCycleReasoningVariant, }: TextBufferInputProps): import("react/jsx-runtime").JSX.Element;
56
+ export declare function TextBufferInput({ buffer, onSubmit, onQueueSubmit, placeholder, isDisabled, onHistoryNavigate, onCurrentTurnEdit, onTriggerOverlay, maxViewportLines, isActive, onKeyboardScroll, imageCount, onImagePaste, images, onImageRemove, pastedBlocks, onPasteBlock, onPasteBlockUpdate, onPasteBlockRemove, highlightQuery, onCycleReasoningVariant, }: TextBufferInputProps): import("react/jsx-runtime").JSX.Element;
53
57
  export {};
54
58
  //# sourceMappingURL=TextBufferInput.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TextBufferInput.d.ts","sourceRoot":"","sources":["../../src/components/TextBufferInput.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGnE,+DAA+D;AAC/D,MAAM,MAAM,cAAc,GAAG,oBAAoB,GAAG,uBAAuB,GAAG,OAAO,CAAC;AActF,UAAU,oBAAoB;IAC1B,oCAAoC;IACpC,MAAM,EAAE,UAAU,CAAC;IACnB,+CAA+C;IAC/C,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,kCAAkC;IAClC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,mEAAmE;IACnE,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACjC,4DAA4D;IAC5D,iBAAiB,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,IAAI,GAAG,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACrE,0DAA0D;IAC1D,gBAAgB,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACnE,wCAAwC;IACxC,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,kDAAkD;IAClD,QAAQ,EAAE,OAAO,CAAC;IAClB,2EAA2E;IAC3E,gBAAgB,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,IAAI,GAAG,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACpE,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,iDAAiD;IACjD,YAAY,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC3D,iEAAiE;IACjE,MAAM,CAAC,EAAE,YAAY,EAAE,GAAG,SAAS,CAAC;IACpC,4DAA4D;IAC5D,aAAa,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACxD,wDAAwD;IACxD,YAAY,CAAC,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC;IACzC,oEAAoE;IACpE,YAAY,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC1D,8DAA8D;IAC9D,kBAAkB,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC5F,iEAAiE;IACjE,kBAAkB,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC7D,4DAA4D;IAC5D,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,2CAA2C;IAC3C,uBAAuB,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;CACtD;AAuCD,wBAAgB,eAAe,CAAC,EAC5B,MAAM,EACN,QAAQ,EACR,WAAW,EACX,UAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAqB,EACrB,QAAQ,EACR,gBAAgB,EAChB,UAAc,EACd,YAAY,EACZ,MAAW,EACX,aAAa,EACb,YAAiB,EACjB,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,uBAAuB,GAC1B,EAAE,oBAAoB,2CAuiBtB"}
1
+ {"version":3,"file":"TextBufferInput.d.ts","sourceRoot":"","sources":["../../src/components/TextBufferInput.tsx"],"names":[],"mappings":"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"}
@@ -39,9 +39,11 @@ function HighlightedText({ text, query }) {
39
39
  function TextBufferInput({
40
40
  buffer,
41
41
  onSubmit,
42
+ onQueueSubmit,
42
43
  placeholder,
43
44
  isDisabled = false,
44
45
  onHistoryNavigate,
46
+ onCurrentTurnEdit,
45
47
  onTriggerOverlay,
46
48
  maxViewportLines = 10,
47
49
  isActive,
@@ -187,10 +189,16 @@ function TextBufferInput({
187
189
  })();
188
190
  return;
189
191
  }
192
+ if (key.name === "return" && key.meta && !key.paste && onQueueSubmit) {
193
+ if (currentText.trim()) {
194
+ onQueueSubmit(currentText);
195
+ }
196
+ return;
197
+ }
190
198
  const isCtrlJ = key.sequence === "\n";
191
199
  const isShiftEnter = key.sequence === "\\\r" || key.name === "return" && key.shift || key.sequence === "\x1B[13;2u" || key.sequence === "\x1BOM";
192
200
  const isPasteReturn = key.name === "return" && key.paste;
193
- const wantsNewline = isCtrlJ || isShiftEnter || key.name === "return" && key.meta || isPasteReturn;
201
+ const wantsNewline = isCtrlJ || isShiftEnter || isPasteReturn;
194
202
  if (wantsNewline) {
195
203
  buffer.newline();
196
204
  return;
@@ -261,6 +269,9 @@ function TextBufferInput({
261
269
  return;
262
270
  }
263
271
  if (key.meta && key.name === "up") {
272
+ if (onCurrentTurnEdit?.()) {
273
+ return;
274
+ }
264
275
  buffer.moveToOffset(0);
265
276
  return;
266
277
  }
@@ -351,7 +362,9 @@ function TextBufferInput({
351
362
  buffer,
352
363
  isDisabled,
353
364
  onSubmit,
365
+ onQueueSubmit,
354
366
  onHistoryNavigate,
367
+ onCurrentTurnEdit,
355
368
  onTriggerOverlay,
356
369
  onKeyboardScroll,
357
370
  // imageCount intentionally omitted - callback uses imageCountRef which is synced via useEffect
@@ -18,15 +18,18 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var QueuedMessagesDisplay_exports = {};
20
20
  __export(QueuedMessagesDisplay_exports, {
21
+ QUEUE_EDIT_SHORTCUTS: () => QUEUE_EDIT_SHORTCUTS,
21
22
  QueuedMessagesDisplay: () => QueuedMessagesDisplay
22
23
  });
23
24
  module.exports = __toCommonJS(QueuedMessagesDisplay_exports);
24
25
  var import_jsx_runtime = require("react/jsx-runtime");
25
26
  var import_ink = require("ink");
26
- function getMessageText(content) {
27
- const textParts = content.filter((part) => part.type === "text").map((part) => part.text);
28
- return textParts.join(" ") || "[attachment]";
29
- }
27
+ var import_queuedComposerContent = require("../../utils/queuedComposerContent.js");
28
+ const isMac = process.platform === "darwin";
29
+ const QUEUE_EDIT_SHORTCUTS = {
30
+ currentTurn: isMac ? "\u2325 + \u2191 edit" : "Alt + \u2191 edit",
31
+ followUp: "\u2191 edit"
32
+ };
30
33
  function truncateText(text, maxLength = 60) {
31
34
  const singleLine = text.replace(/\n/g, " ").trim();
32
35
  if (singleLine.length <= maxLength) {
@@ -34,7 +37,11 @@ function truncateText(text, maxLength = 60) {
34
37
  }
35
38
  return singleLine.slice(0, maxLength - 3) + "...";
36
39
  }
37
- function QueuedMessagesDisplay({ messages }) {
40
+ function QueuedMessagesDisplay({
41
+ messages,
42
+ label = "queued",
43
+ hint = "\u2191 to edit"
44
+ }) {
38
45
  if (messages.length === 0) return null;
39
46
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink.Box, { flexDirection: "column", marginBottom: 1, children: [
40
47
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink.Box, { children: [
@@ -42,18 +49,20 @@ function QueuedMessagesDisplay({ messages }) {
42
49
  messages.length,
43
50
  " message",
44
51
  messages.length !== 1 ? "s" : "",
45
- " queued"
52
+ " ",
53
+ label
46
54
  ] }),
47
55
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Text, { color: "gray", children: " \u2022 " }),
48
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Text, { color: "gray", children: "\u2191 to edit" })
56
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Text, { color: "gray", children: hint })
49
57
  ] }),
50
58
  messages.map((message, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink.Box, { flexDirection: "row", children: [
51
59
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Text, { color: "gray", children: index === messages.length - 1 ? "\u21B3 " : "\u2502 " }),
52
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Text, { color: "gray", italic: true, children: truncateText(getMessageText(message.content)) })
60
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Text, { color: "gray", italic: true, children: truncateText((0, import_queuedComposerContent.previewQueuedContent)(message.content)) })
53
61
  ] }, message.id))
54
62
  ] });
55
63
  }
56
64
  // Annotate the CommonJS export names for ESM import in node:
57
65
  0 && (module.exports = {
66
+ QUEUE_EDIT_SHORTCUTS,
58
67
  QueuedMessagesDisplay
59
68
  });
@@ -8,9 +8,15 @@
8
8
  * - Truncated preview of each queued message
9
9
  */
10
10
  import type { QueuedMessage } from '@dexto/core';
11
+ export declare const QUEUE_EDIT_SHORTCUTS: {
12
+ currentTurn: string;
13
+ followUp: string;
14
+ };
11
15
  interface QueuedMessagesDisplayProps {
12
16
  messages: QueuedMessage[];
17
+ label?: string;
18
+ hint?: string;
13
19
  }
14
- export declare function QueuedMessagesDisplay({ messages }: QueuedMessagesDisplayProps): import("react/jsx-runtime").JSX.Element | null;
20
+ export declare function QueuedMessagesDisplay({ messages, label, hint, }: QueuedMessagesDisplayProps): import("react/jsx-runtime").JSX.Element | null;
15
21
  export {};
16
22
  //# sourceMappingURL=QueuedMessagesDisplay.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"QueuedMessagesDisplay.d.ts","sourceRoot":"","sources":["../../../src/components/chat/QueuedMessagesDisplay.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAe,MAAM,aAAa,CAAC;AAE9D,UAAU,0BAA0B;IAChC,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC7B;AAwBD,wBAAgB,qBAAqB,CAAC,EAAE,QAAQ,EAAE,EAAE,0BAA0B,kDA2B7E"}
1
+ {"version":3,"file":"QueuedMessagesDisplay.d.ts","sourceRoot":"","sources":["../../../src/components/chat/QueuedMessagesDisplay.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAKjD,eAAO,MAAM,oBAAoB;;;CAGhC,CAAC;AAEF,UAAU,0BAA0B;IAChC,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAcD,wBAAgB,qBAAqB,CAAC,EAClC,QAAQ,EACR,KAAgB,EAChB,IAAkB,GACrB,EAAE,0BAA0B,kDA2B5B"}
@@ -1,9 +1,11 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { Box, Text } from "ink";
3
- function getMessageText(content) {
4
- const textParts = content.filter((part) => part.type === "text").map((part) => part.text);
5
- return textParts.join(" ") || "[attachment]";
6
- }
3
+ import { previewQueuedContent } from "../../utils/queuedComposerContent.js";
4
+ const isMac = process.platform === "darwin";
5
+ const QUEUE_EDIT_SHORTCUTS = {
6
+ currentTurn: isMac ? "\u2325 + \u2191 edit" : "Alt + \u2191 edit",
7
+ followUp: "\u2191 edit"
8
+ };
7
9
  function truncateText(text, maxLength = 60) {
8
10
  const singleLine = text.replace(/\n/g, " ").trim();
9
11
  if (singleLine.length <= maxLength) {
@@ -11,7 +13,11 @@ function truncateText(text, maxLength = 60) {
11
13
  }
12
14
  return singleLine.slice(0, maxLength - 3) + "...";
13
15
  }
14
- function QueuedMessagesDisplay({ messages }) {
16
+ function QueuedMessagesDisplay({
17
+ messages,
18
+ label = "queued",
19
+ hint = "\u2191 to edit"
20
+ }) {
15
21
  if (messages.length === 0) return null;
16
22
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
17
23
  /* @__PURE__ */ jsxs(Box, { children: [
@@ -19,17 +25,19 @@ function QueuedMessagesDisplay({ messages }) {
19
25
  messages.length,
20
26
  " message",
21
27
  messages.length !== 1 ? "s" : "",
22
- " queued"
28
+ " ",
29
+ label
23
30
  ] }),
24
31
  /* @__PURE__ */ jsx(Text, { color: "gray", children: " \u2022 " }),
25
- /* @__PURE__ */ jsx(Text, { color: "gray", children: "\u2191 to edit" })
32
+ /* @__PURE__ */ jsx(Text, { color: "gray", children: hint })
26
33
  ] }),
27
34
  messages.map((message, index) => /* @__PURE__ */ jsxs(Box, { flexDirection: "row", children: [
28
35
  /* @__PURE__ */ jsx(Text, { color: "gray", children: index === messages.length - 1 ? "\u21B3 " : "\u2502 " }),
29
- /* @__PURE__ */ jsx(Text, { color: "gray", italic: true, children: truncateText(getMessageText(message.content)) })
36
+ /* @__PURE__ */ jsx(Text, { color: "gray", italic: true, children: truncateText(previewQueuedContent(message.content)) })
30
37
  ] }, message.id))
31
38
  ] });
32
39
  }
33
40
  export {
41
+ QUEUE_EDIT_SHORTCUTS,
34
42
  QueuedMessagesDisplay
35
43
  };