gaunt-sloth 2.0.0-alpha.2 → 2.0.0-alpha.21

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 (127) hide show
  1. package/README.md +55 -5
  2. package/cli.js +43 -10
  3. package/dist/cli.js +33 -2
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/adkEvalRunner.d.ts +66 -0
  6. package/dist/commands/adkEvalRunner.js +69 -0
  7. package/dist/commands/adkEvalRunner.js.map +1 -0
  8. package/dist/commands/agUiEvalRunner.d.ts +73 -0
  9. package/dist/commands/agUiEvalRunner.js +216 -0
  10. package/dist/commands/agUiEvalRunner.js.map +1 -0
  11. package/dist/commands/askCommand.d.ts +3 -2
  12. package/dist/commands/askCommand.js +26 -7
  13. package/dist/commands/askCommand.js.map +1 -1
  14. package/dist/commands/batchCommand.d.ts +78 -0
  15. package/dist/commands/batchCommand.js +245 -0
  16. package/dist/commands/batchCommand.js.map +1 -0
  17. package/dist/commands/cliOptionParsers.d.ts +12 -0
  18. package/dist/commands/cliOptionParsers.js +18 -0
  19. package/dist/commands/cliOptionParsers.js.map +1 -0
  20. package/dist/commands/commandIntrospection.d.ts +6 -6
  21. package/dist/commands/commandIntrospection.js +12 -12
  22. package/dist/commands/commandIntrospection.js.map +1 -1
  23. package/dist/commands/commandUtils.d.ts +16 -16
  24. package/dist/commands/commandUtils.js +20 -20
  25. package/dist/commands/commandUtils.js.map +1 -1
  26. package/dist/commands/configCommand.d.ts +24 -0
  27. package/dist/commands/configCommand.js +117 -0
  28. package/dist/commands/configCommand.js.map +1 -0
  29. package/dist/commands/configSetup.d.ts +1 -1
  30. package/dist/commands/configSetup.js +17 -2
  31. package/dist/commands/configSetup.js.map +1 -1
  32. package/dist/commands/evalCommand.d.ts +41 -0
  33. package/dist/commands/evalCommand.js +483 -0
  34. package/dist/commands/evalCommand.js.map +1 -0
  35. package/dist/commands/execCommand.js +4 -1
  36. package/dist/commands/execCommand.js.map +1 -1
  37. package/dist/commands/firstRunDialog.d.ts +39 -5
  38. package/dist/commands/firstRunDialog.js +72 -10
  39. package/dist/commands/firstRunDialog.js.map +1 -1
  40. package/dist/commands/getCommand.js +7 -7
  41. package/dist/commands/getCommand.js.map +1 -1
  42. package/dist/commands/historyCommand.d.ts +17 -0
  43. package/dist/commands/historyCommand.js +102 -0
  44. package/dist/commands/historyCommand.js.map +1 -0
  45. package/dist/commands/initCommand.d.ts +3 -0
  46. package/dist/commands/initCommand.js +9 -4
  47. package/dist/commands/initCommand.js.map +1 -1
  48. package/dist/commands/insightsCommand.d.ts +8 -0
  49. package/dist/commands/insightsCommand.js +32 -0
  50. package/dist/commands/insightsCommand.js.map +1 -0
  51. package/dist/commands/modelsCommand.d.ts +25 -0
  52. package/dist/commands/modelsCommand.js +96 -0
  53. package/dist/commands/modelsCommand.js.map +1 -0
  54. package/dist/commands/prCommand.js +14 -15
  55. package/dist/commands/prCommand.js.map +1 -1
  56. package/dist/commands/prDiscovery.d.ts +2 -2
  57. package/dist/commands/prDiscovery.js +27 -29
  58. package/dist/commands/prDiscovery.js.map +1 -1
  59. package/dist/commands/reviewCommand.js +15 -10
  60. package/dist/commands/reviewCommand.js.map +1 -1
  61. package/dist/commands/workflowCommand.d.ts +19 -0
  62. package/dist/commands/workflowCommand.js +77 -0
  63. package/dist/commands/workflowCommand.js.map +1 -0
  64. package/dist/helpers/jira/jiraLogWork.js.map +1 -1
  65. package/dist/modules/startSession.js +9 -7
  66. package/dist/modules/startSession.js.map +1 -1
  67. package/dist/tools/gthJiraLogWorkTool.js +3 -3
  68. package/dist/tools/gthJiraLogWorkTool.js.map +1 -1
  69. package/dist/tui/components/App.js +321 -21
  70. package/dist/tui/components/App.js.map +1 -1
  71. package/dist/tui/components/ApprovalPrompt.d.ts +18 -0
  72. package/dist/tui/components/ApprovalPrompt.js +26 -0
  73. package/dist/tui/components/ApprovalPrompt.js.map +1 -0
  74. package/dist/tui/components/DebugPanel.d.ts +29 -9
  75. package/dist/tui/components/DebugPanel.js +46 -23
  76. package/dist/tui/components/DebugPanel.js.map +1 -1
  77. package/dist/tui/components/FetchProgress.d.ts +36 -0
  78. package/dist/tui/components/FetchProgress.js +39 -0
  79. package/dist/tui/components/FetchProgress.js.map +1 -0
  80. package/dist/tui/components/LiveTurn.d.ts +26 -4
  81. package/dist/tui/components/LiveTurn.js +104 -18
  82. package/dist/tui/components/LiveTurn.js.map +1 -1
  83. package/dist/tui/components/NoticeBar.d.ts +32 -0
  84. package/dist/tui/components/NoticeBar.js +39 -0
  85. package/dist/tui/components/NoticeBar.js.map +1 -0
  86. package/dist/tui/components/PromptInput.d.ts +26 -1
  87. package/dist/tui/components/PromptInput.js +93 -7
  88. package/dist/tui/components/PromptInput.js.map +1 -1
  89. package/dist/tui/components/Rule.js.map +1 -1
  90. package/dist/tui/components/SelectList.d.ts +98 -9
  91. package/dist/tui/components/SelectList.js +209 -26
  92. package/dist/tui/components/SelectList.js.map +1 -1
  93. package/dist/tui/components/SlashCommandMenu.d.ts +20 -0
  94. package/dist/tui/components/SlashCommandMenu.js +28 -0
  95. package/dist/tui/components/SlashCommandMenu.js.map +1 -0
  96. package/dist/tui/components/StatusBar.d.ts +7 -1
  97. package/dist/tui/components/StatusBar.js +7 -3
  98. package/dist/tui/components/StatusBar.js.map +1 -1
  99. package/dist/tui/components/Transcript.js +6 -1
  100. package/dist/tui/components/Transcript.js.map +1 -1
  101. package/dist/tui/debugRender.d.ts +41 -6
  102. package/dist/tui/debugRender.js +126 -12
  103. package/dist/tui/debugRender.js.map +1 -1
  104. package/dist/tui/debugSearch.d.ts +40 -0
  105. package/dist/tui/debugSearch.js +73 -0
  106. package/dist/tui/debugSearch.js.map +1 -0
  107. package/dist/tui/markdown.js +0 -0
  108. package/dist/tui/markdown.js.map +1 -1
  109. package/dist/tui/pasteParser.d.ts +21 -0
  110. package/dist/tui/pasteParser.js +24 -0
  111. package/dist/tui/pasteParser.js.map +1 -0
  112. package/dist/tui/selectCancelled.d.ts +13 -0
  113. package/dist/tui/selectCancelled.js +17 -0
  114. package/dist/tui/selectCancelled.js.map +1 -0
  115. package/dist/tui/slashCommands.d.ts +220 -1
  116. package/dist/tui/slashCommands.js +408 -1
  117. package/dist/tui/slashCommands.js.map +1 -1
  118. package/dist/tui/tuiSessionModule.js +249 -24
  119. package/dist/tui/tuiSessionModule.js.map +1 -1
  120. package/dist/tui/types.d.ts +96 -7
  121. package/dist/tui/viewModel.d.ts +34 -0
  122. package/dist/tui/viewModel.js +67 -0
  123. package/dist/tui/viewModel.js.map +1 -1
  124. package/dist/utils/stdinPolicy.d.ts +31 -0
  125. package/dist/utils/stdinPolicy.js +37 -0
  126. package/dist/utils/stdinPolicy.js.map +1 -0
  127. package/package.json +21 -17
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ApprovalPrompt.js","sourceRoot":"","sources":["../../../src/tui/components/ApprovalPrompt.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAC;AAGnD;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,cAAc,CAAC,EAC7B,OAAO,GAGR;IACC,MAAM,WAAW,GACf,OAAO,OAAO,CAAC,IAAI,CAAC,OAAO,KAAK,QAAQ;QACtC,CAAC,CAAE,OAAO,CAAC,IAAI,CAAC,OAAkB;QAClC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,+FAA+F;IAC/F,uEAAuE;IACvE,MAAM,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC;IACtC,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACzB,KAAC,IAAI,KAAG,EACR,KAAC,IAAI,IAAC,IAAI,QAAC,KAAK,EAAC,QAAQ,YACtB,8CAA8C,OAAO,CAAC,IAAI,EAAE,GACxD,EACP,KAAC,IAAI,IAAC,QAAQ,kBAAE,OAAO,WAAW,EAAE,GAAQ,EAC3C,OAAO,CAAC,CAAC,CAAC,CACT,KAAC,IAAI,IAAC,KAAK,EAAC,QAAQ,YAAE,mBAAmB,OAAO,CAAC,IAAI,MAAM,OAAO,CAAC,MAAM,EAAE,GAAQ,CACpF,CAAC,CAAC,CAAC,IAAI,EACR,KAAC,IAAI,IAAC,QAAQ,kBACX,uEAAuE,GACnE,IACH,CACP,CAAC;AACJ,CAAC"}
@@ -1,16 +1,24 @@
1
1
  import React from 'react';
2
2
  import type { SubagentTreeViewModel } from '#src/tui/viewModel.js';
3
- /** The selectable sections of the docked panel, in tab order. */
4
- export declare const DEBUG_TABS: readonly ["subagents", "history", "request", "response"];
3
+ /**
4
+ * The selectable sections of the docked panel, in tab order. TUI-C16 split the old combined
5
+ * "Sent to model (system + tools)" section into two tabs — `system` and `tools` — so the tool
6
+ * catalogue no longer sits below the whole system prompt.
7
+ */
8
+ export declare const DEBUG_TABS: readonly ['subagents', 'system', 'tools', 'mcp', 'history', 'response'];
5
9
  export type DebugTab = (typeof DEBUG_TABS)[number];
6
10
  export interface DebugPanelProps {
7
11
  /** Subagent tree folded from `task` tool-call events. */
8
12
  subagents: SubagentTreeViewModel;
9
- /** Rendered lines for "Sent to model (chat history)" (already split on newlines). */
13
+ /** Rendered lines for the "Chat history" tab (already split on newlines). */
10
14
  historyLines: string[];
11
- /** Rendered lines for "Sent to model (system + tools)" — system/tools/params (split on newlines). */
12
- requestLines: string[];
13
- /** Rendered lines for "Raw model response" (already split on newlines). */
15
+ /** Rendered lines for the "System prompt" tab — model params/tool-choice/system prompt (TUI-C16). */
16
+ systemLines: string[];
17
+ /** Rendered lines for the "Tools" tab — tool name list then per-tool descriptors (TUI-C16). */
18
+ toolsLines: string[];
19
+ /** Rendered lines for the "MCP" tab — per-server instructions + prefixed tool names (TUI-C20). */
20
+ mcpLines: string[];
21
+ /** Rendered lines for the "Raw response" tab (already split on newlines). */
14
22
  responseLines: string[];
15
23
  /** Which tab is shown. */
16
24
  activeTab: DebugTab;
@@ -22,12 +30,24 @@ export interface DebugPanelProps {
22
30
  viewportHeight: number;
23
31
  /** Whether the pane is maximised (grown to most of the terminal height). */
24
32
  maximized: boolean;
33
+ /** Active `less`-style search query (empty when no search) — matches are highlighted (TUI-C21). */
34
+ searchQuery: string;
35
+ /** Whether the search input is actively being typed (draws the caret + a "type to search" hint). */
36
+ searchActive: boolean;
37
+ /** Number of matching lines for the current query (drives the `3/12` / `no matches` indicator). */
38
+ matchCount: number;
39
+ /** 0-based cursor into the match list (the `n`/`N` current match); only meaningful when count > 0. */
40
+ currentMatchIndex: number;
41
+ /** Absolute line index of the current match, or -1 — highlighted distinctly from the rest. */
42
+ currentMatchLine: number;
25
43
  }
26
44
  /** The data a debug section needs to resolve into renderable lines. */
27
45
  export interface DebugPanelLinesInput {
28
46
  subagents: SubagentTreeViewModel;
29
47
  historyLines: string[];
30
- requestLines: string[];
48
+ systemLines: string[];
49
+ toolsLines: string[];
50
+ mcpLines: string[];
31
51
  responseLines: string[];
32
52
  activeTab: DebugTab;
33
53
  }
@@ -36,7 +56,7 @@ export interface DebugPanelLinesInput {
36
56
  * (and pure) so `<App>` can compute the active section's length to clamp the scroll offset to
37
57
  * its real maximum — keeping keyboard scrolling and the rendered viewport in agreement (TUI-C11).
38
58
  */
39
- export declare function debugPanelLines({ subagents, historyLines, requestLines, responseLines, activeTab, }: DebugPanelLinesInput): string[];
59
+ export declare function debugPanelLines({ subagents, historyLines, systemLines, toolsLines, mcpLines, responseLines, activeTab, }: DebugPanelLinesInput): string[];
40
60
  /**
41
61
  * Full-width docked panel below the transcript / above the status bar (lives in the live,
42
62
  * non-static frame so it coexists with `<Static>` scrollback). Tabs select a section; the
@@ -44,4 +64,4 @@ export declare function debugPanelLines({ subagents, historyLines, requestLines,
44
64
  * the section's lines, with the window moved by `scrollOffset` (PageUp/PageDown while focused).
45
65
  * Pure presentational: all state (tab, offset, focus) is owned by `<App>`.
46
66
  */
47
- export declare function DebugPanel({ subagents, historyLines, requestLines, responseLines, activeTab, scrollOffset, focused, viewportHeight, maximized, }: DebugPanelProps): React.ReactElement;
67
+ export declare function DebugPanel({ subagents, historyLines, systemLines, toolsLines, mcpLines, responseLines, activeTab, scrollOffset, focused, viewportHeight, maximized, searchQuery, searchActive, matchCount, currentMatchIndex, currentMatchLine, }: DebugPanelProps): React.ReactElement;
@@ -1,32 +1,40 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Box, Text } from 'ink';
3
- /** The selectable sections of the docked panel, in tab order. */
4
- export const DEBUG_TABS = ['subagents', 'history', 'request', 'response'];
3
+ import { highlightSegments } from '#src/tui/debugSearch.js';
4
+ /**
5
+ * The selectable sections of the docked panel, in tab order. TUI-C16 split the old combined
6
+ * "Sent to model (system + tools)" section into two tabs — `system` and `tools` — so the tool
7
+ * catalogue no longer sits below the whole system prompt.
8
+ */
9
+ export const DEBUG_TABS = ['subagents', 'system', 'tools', 'mcp', 'history', 'response'];
5
10
  const TAB_LABELS = {
6
11
  subagents: 'Subagents',
7
- history: 'Sent to model (chat history)',
8
- request: 'Sent to model (system + tools)',
9
- response: 'Raw model response',
12
+ system: 'System prompt',
13
+ tools: 'Tools',
14
+ mcp: 'MCP',
15
+ history: 'Chat history',
16
+ response: 'Raw response',
10
17
  };
11
18
  /**
12
19
  * The exact lines the active section renders, including the empty-state placeholders. Exported
13
20
  * (and pure) so `<App>` can compute the active section's length to clamp the scroll offset to
14
21
  * its real maximum — keeping keyboard scrolling and the rendered viewport in agreement (TUI-C11).
15
22
  */
16
- export function debugPanelLines({ subagents, historyLines, requestLines, responseLines, activeTab, }) {
17
- return activeTab === 'subagents'
18
- ? subagentLines(subagents)
19
- : activeTab === 'history'
20
- ? historyLines.length
21
- ? historyLines
22
- : ['(no model call captured yet)']
23
- : activeTab === 'request'
24
- ? requestLines.length
25
- ? requestLines
26
- : ['(no request details captured yet)']
27
- : responseLines.length
28
- ? responseLines
29
- : ['(no model response captured yet)'];
23
+ export function debugPanelLines({ subagents, historyLines, systemLines, toolsLines, mcpLines, responseLines, activeTab, }) {
24
+ switch (activeTab) {
25
+ case 'subagents':
26
+ return subagentLines(subagents);
27
+ case 'system':
28
+ return systemLines.length ? systemLines : ['(no request details captured yet)'];
29
+ case 'tools':
30
+ return toolsLines.length ? toolsLines : ['(no tools captured yet)'];
31
+ case 'mcp':
32
+ return mcpLines.length ? mcpLines : ['(no MCP details captured yet)'];
33
+ case 'history':
34
+ return historyLines.length ? historyLines : ['(no model call captured yet)'];
35
+ case 'response':
36
+ return responseLines.length ? responseLines : ['(no model response captured yet)'];
37
+ }
30
38
  }
31
39
  /** Flatten the subagent tree into renderable lines for the bounded viewport. */
32
40
  function subagentLines(tree) {
@@ -53,11 +61,13 @@ function subagentLines(tree) {
53
61
  * the section's lines, with the window moved by `scrollOffset` (PageUp/PageDown while focused).
54
62
  * Pure presentational: all state (tab, offset, focus) is owned by `<App>`.
55
63
  */
56
- export function DebugPanel({ subagents, historyLines, requestLines, responseLines, activeTab, scrollOffset, focused, viewportHeight, maximized, }) {
64
+ export function DebugPanel({ subagents, historyLines, systemLines, toolsLines, mcpLines, responseLines, activeTab, scrollOffset, focused, viewportHeight, maximized, searchQuery, searchActive, matchCount, currentMatchIndex, currentMatchLine, }) {
57
65
  const lines = debugPanelLines({
58
66
  subagents,
59
67
  historyLines,
60
- requestLines,
68
+ systemLines,
69
+ toolsLines,
70
+ mcpLines,
61
71
  responseLines,
62
72
  activeTab,
63
73
  });
@@ -82,7 +92,20 @@ export function DebugPanel({ subagents, historyLines, requestLines, responseLine
82
92
  const label = TAB_LABELS[tab];
83
93
  return tab === activeTab ? (_jsx(Text, { color: "cyan", bold: true, children: ` ${label} ` }, tab)) : (_jsx(Text, { dimColor: true, children: ` ${label} ` }, tab));
84
94
  }) }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: focused
85
- ? `[Tab: section · ↑/↓: scroll · m: ${maximized ? 'restore' : 'maximise'} · Esc: unfocus]`
86
- : '[/debug to hide]' }) }), _jsx(Box, { height: viewportHeight, overflow: "hidden", flexDirection: "column", children: visible.map((line, i) => (_jsx(Text, { children: line }, top + i))) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: footer }) })] }));
95
+ ? `[Tab: section · ↑/↓: scroll · /: search · n/N: next/prev · m: ${maximized ? 'restore' : 'maximise'} · Esc: ${searchQuery ? 'clear search' : 'unfocus'}]`
96
+ : '[/debug to hide]' }) }), _jsx(Box, { height: viewportHeight, overflow: "hidden", flexDirection: "column", children: visible.map((line, i) => {
97
+ const abs = top + i;
98
+ // No active query → render the raw line (the common, zero-cost path). With a query, split
99
+ // the line into match / non-match runs and paint the matches; the CURRENT match line gets
100
+ // a distinct colour so the eye lands on where the viewport jumped (TUI-C21).
101
+ if (!searchQuery)
102
+ return _jsx(Text, { children: line }, abs);
103
+ const segs = highlightSegments(line, searchQuery);
104
+ return (_jsx(Text, { children: segs.map((seg, j) => seg.match ? (_jsx(Text, { backgroundColor: abs === currentMatchLine ? 'cyan' : 'yellow', color: "black", children: seg.text }, j)) : (_jsx(Text, { children: seg.text }, j))) }, abs));
105
+ }) }), searchActive || searchQuery ? (_jsx(Box, { children: _jsxs(Text, { children: [_jsx(Text, { color: "cyan", children: "/" }), _jsx(Text, { children: searchQuery }), searchActive ? _jsx(Text, { color: "cyan", children: "\u258F" }) : null, _jsx(Text, { dimColor: true, children: searchQuery.length === 0
106
+ ? ' (type to search)'
107
+ : matchCount === 0
108
+ ? ' no matches'
109
+ : ` ${currentMatchIndex + 1}/${matchCount}` })] }) })) : null, _jsx(Box, { children: _jsx(Text, { dimColor: true, children: footer }) })] }));
87
110
  }
88
111
  //# sourceMappingURL=DebugPanel.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DebugPanel.js","sourceRoot":"","sources":["../../../src/tui/components/DebugPanel.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DebugPanel.js","sourceRoot":"","sources":["../../../src/tui/components/DebugPanel.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import React from 'react';
2
+ /**
3
+ * CFG-21 — the transient "fetching models" indicator shown on the interactive TTY path while the
4
+ * first-run dialog awaits a provider's live model list (a large cloud catalog can take a moment).
5
+ *
6
+ * Deliberately a bare spinner + label with NO `useInput`: without an input subscriber Ink never
7
+ * enables raw mode, so the stdin `readable` listener that would intercept Ctrl+C is never attached
8
+ * (see ink's App component). A Ctrl+C during the fetch therefore reaches Node as an ordinary SIGINT
9
+ * — the process exits without writing a config, consistent with CFG-20's abort semantics (part d)
10
+ * — rather than being swallowed by an Ink key handler.
11
+ */
12
+ export declare function FetchProgress({ label }: {
13
+ label: string;
14
+ }): React.ReactElement;
15
+ /**
16
+ * The subset of Ink's `render` that {@link runWithInkProgress} relies on. Declared as a seam
17
+ * (mirroring {@link import('./SelectList.js').InkRenderFn}) so a unit test can inject a fake
18
+ * renderer and assert the indicator mounted / cleared without a live TTY — Ink's real render is
19
+ * otherwise un-unit-testable (it needs a raw-mode-capable stdin).
20
+ */
21
+ export type InkProgressRenderFn = (node: React.ReactElement) => {
22
+ clear: () => void;
23
+ unmount: () => void;
24
+ };
25
+ /**
26
+ * Mount {@link FetchProgress} with Ink for the duration of `run`, then clear + unmount it however
27
+ * `run` settles. Imports `ink` dynamically (unless a `render` is injected) so a readline-only run
28
+ * never pulls Ink in. Intended for use only after the caller has confirmed an interactive TTY +
29
+ * Ink availability.
30
+ *
31
+ * `clear()` before `unmount()` wipes the spinner line so it does not linger above the following
32
+ * prompt — Ink otherwise leaves the last rendered frame on screen.
33
+ *
34
+ * @param render - injectable Ink renderer (defaults to Ink's `render`); for tests only.
35
+ */
36
+ export declare function runWithInkProgress<T>(label: string, run: () => Promise<T>, render?: InkProgressRenderFn): Promise<T>;
@@ -0,0 +1,39 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Text } from 'ink';
3
+ import Spinner from 'ink-spinner';
4
+ /**
5
+ * CFG-21 — the transient "fetching models" indicator shown on the interactive TTY path while the
6
+ * first-run dialog awaits a provider's live model list (a large cloud catalog can take a moment).
7
+ *
8
+ * Deliberately a bare spinner + label with NO `useInput`: without an input subscriber Ink never
9
+ * enables raw mode, so the stdin `readable` listener that would intercept Ctrl+C is never attached
10
+ * (see ink's App component). A Ctrl+C during the fetch therefore reaches Node as an ordinary SIGINT
11
+ * — the process exits without writing a config, consistent with CFG-20's abort semantics (part d)
12
+ * — rather than being swallowed by an Ink key handler.
13
+ */
14
+ export function FetchProgress({ label }) {
15
+ return (_jsxs(Text, { children: [_jsx(Spinner, { type: "dots" }), " ", label] }));
16
+ }
17
+ /**
18
+ * Mount {@link FetchProgress} with Ink for the duration of `run`, then clear + unmount it however
19
+ * `run` settles. Imports `ink` dynamically (unless a `render` is injected) so a readline-only run
20
+ * never pulls Ink in. Intended for use only after the caller has confirmed an interactive TTY +
21
+ * Ink availability.
22
+ *
23
+ * `clear()` before `unmount()` wipes the spinner line so it does not linger above the following
24
+ * prompt — Ink otherwise leaves the last rendered frame on screen.
25
+ *
26
+ * @param render - injectable Ink renderer (defaults to Ink's `render`); for tests only.
27
+ */
28
+ export async function runWithInkProgress(label, run, render) {
29
+ const renderFn = render ?? (await import('ink')).render;
30
+ const instance = renderFn(_jsx(FetchProgress, { label: label }));
31
+ try {
32
+ return await run();
33
+ }
34
+ finally {
35
+ instance.clear();
36
+ instance.unmount();
37
+ }
38
+ }
39
+ //# sourceMappingURL=FetchProgress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FetchProgress.js","sourceRoot":"","sources":["../../../src/tui/components/FetchProgress.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC3B,OAAO,OAAO,MAAM,aAAa,CAAC;AAElC;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAAC,EAAE,KAAK,EAAqB;IACxD,OAAO,CACL,MAAC,IAAI,eACH,KAAC,OAAO,IAAC,IAAI,EAAC,MAAM,GAAG,OAAE,KAAK,IACzB,CACR,CAAC;AACJ,CAAC;AAaD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,KAAa,EACb,GAAqB,EACrB,MAA4B;IAE5B,MAAM,QAAQ,GAAwB,MAAM,IAAI,CAAC,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;IAC7E,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAC,aAAa,IAAC,KAAK,EAAE,KAAK,GAAI,CAAC,CAAC;IAC3D,IAAI,CAAC;QACH,OAAO,MAAM,GAAG,EAAE,CAAC;IACrB,CAAC;YAAS,CAAC;QACT,QAAQ,CAAC,KAAK,EAAE,CAAC;QACjB,QAAQ,CAAC,OAAO,EAAE,CAAC;IACrB,CAAC;AACH,CAAC"}
@@ -1,10 +1,32 @@
1
1
  import React from 'react';
2
2
  import type { TurnViewModel } from '#src/tui/viewModel.js';
3
3
  /**
4
- * Renders one assistant turn from the pure {@link TurnViewModel}: a dim reasoning region,
5
- * one collapsible panel per tool call, then the assistant text. Used both for the in-progress
6
- * live turn and (frozen) for committed turns in the transcript, so the look is identical once
7
- * done.
4
+ * The `💭 Thinking` region: the model's reasoning/chain-of-thought, rendered as a distinct
5
+ * *layer* from the answer. Collapsible like {@link ToolCallPanel} (shares the turn's Ctrl+T
6
+ * detail toggle) and collapsed by default, so ephemeral thinking never competes with the answer
7
+ * — worst case a lone 👍 answer drowned by paragraphs of thought. When expanded, each line is
8
+ * drawn behind a `│ ` gutter. The label + gutter are **cyan** (DL-8 "informational") rather than
9
+ * dim-only: dim is the least reliably-rendered ANSI attribute and vanishes on many themes, so a
10
+ * dim-only region reads as the answer. Cyan carries the layer boundary as colour; the body stays
11
+ * dim+italic underneath the coloured gutter.
12
+ */
13
+ export declare function ReasoningPanel({ reasoning, expanded, live, label, }: {
14
+ reasoning: string;
15
+ expanded: boolean;
16
+ /** True for the in-progress turn, where Ctrl+T can toggle the detail in place. */
17
+ live: boolean;
18
+ /**
19
+ * Header text after the `💭` glyph. Defaults to `Thinking` for the in-turn region; the
20
+ * `/reasoning` reprint (TUI-C18) passes a turn-tagged label so a recalled block is single-sourced
21
+ * with the live styling yet says which committed turn it came from.
22
+ */
23
+ label?: string;
24
+ }): React.ReactElement;
25
+ /**
26
+ * Renders one assistant turn from the pure {@link TurnViewModel}: a collapsible `💭 Thinking`
27
+ * reasoning region, one collapsible panel per tool call, then the assistant text. Used both for
28
+ * the in-progress live turn and (frozen) for committed turns in the transcript, so the look is
29
+ * identical once done.
8
30
  *
9
31
  * Assistant text is rendered as terminal **markdown** once the segment is complete; while a
10
32
  * turn is still streaming (`streaming` true) we render it as plain text so the live region
@@ -1,38 +1,115 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Box, Text } from 'ink';
3
+ import { buildToolBodyLines, buildToolPreviewLines, getToolGlyph, summariseToolCall, } from '@gaunt-sloth/core/core/toolDisplay.js';
4
+ import { CHECKLIST_TOOL_NAME, parseChecklistArgs } from '#src/tui/viewModel.js';
3
5
  import { renderMarkdown } from '#src/tui/markdown.js';
4
6
  /** Status glyph + word for a tool call's compact summary line. */
5
7
  function toolStatus(tc) {
6
8
  if (tc.status === 'done') {
7
- // A tool whose result text looks like an error gets the error affordance.
8
- const errored = !!tc.result && /^\s*(error|err:|exception|failed)/i.test(tc.result);
9
- return errored
9
+ // Drive the error affordance from the real tool-result signal (LangChain
10
+ // `ToolMessage.status === 'error'`, threaded through as `isError`), never from sniffing
11
+ // the result text — legitimate output may simply begin with "Error handling…".
12
+ return tc.isError
10
13
  ? { glyph: '✗', label: 'error', color: 'red' }
11
14
  : { glyph: '✓', label: 'done', color: 'magenta' };
12
15
  }
13
16
  return { glyph: '⋯', label: 'running', color: 'yellow' };
14
17
  }
15
18
  /**
16
- * One tool call rendered as a collapsible panel: a compact summary line (glyph + name +
17
- * status) that, when `expanded`, also shows the streamed args and the result. Collapsed by
18
- * default so the transcript stays readable; the whole turn's tool calls expand together via
19
- * the App-level toggle (Ctrl+T), mirroring the docked debug panel's single-key detail flip.
19
+ * TUI-C30 — map one registry-styled body/preview line onto Ink `<Text>` props: `dim` = greyed
20
+ * preview text, `added`/`removed` = diff green/red (DL-8 colour semantics). The 4-space indent
21
+ * keeps the body visually nested under the call line.
22
+ */
23
+ function ToolBodyLine({ line }) {
24
+ if (line.style === 'added')
25
+ return _jsx(Text, { color: "green", children: ` ${line.text}` });
26
+ if (line.style === 'removed')
27
+ return _jsx(Text, { color: "red", children: ` ${line.text}` });
28
+ return _jsx(Text, { dimColor: true, children: ` ${line.text}` });
29
+ }
30
+ /**
31
+ * One tool call rendered as a collapsible panel (TUI-C30 rendering, via the surface-agnostic
32
+ * registry in `@gaunt-sloth/core/core/toolDisplay.js` — shared with the plain surface):
33
+ *
34
+ * - The call line shows the params INLINE, shortened + secret-redacted:
35
+ * `▸ ✓ 📁 read_file(path=README.md) [done]` (DL-4 transparency without a raw JSON dump).
36
+ * - Collapsed (default) it still previews up to the canonical 10 lines of the tool's output as
37
+ * greyed text with a `… (+N more lines)` overflow marker — inspectable without expanding
38
+ * (DL-2 progressive disclosure with the head of the story visible).
39
+ * - `write_file`/`edit_file` render their change as a diff (added green / removed red) derived
40
+ * from the args instead of an args/output dump.
41
+ * - Expanded (`/tools` / Ctrl+T, unchanged) shows the FULL body: raw args, the routed
42
+ * "Executing" notice, and the uncapped formatter output (deduped for shell calls whose
43
+ * result repeats the live output).
44
+ *
45
+ * The whole turn's tool calls expand together via the App-level toggle; committed turns are
46
+ * frozen in Ink's `<Static>` and cannot re-fold.
20
47
  */
21
48
  function ToolCallPanel({ tc, expanded, live, }) {
22
49
  const { glyph, label, color } = toolStatus(tc);
23
- const name = tc.name || '(tool)';
24
- // Collapsed-state affordance: a ▸/▾ caret so it reads as foldable, plus a hint there is
25
- // detail to expand. Expanded shows ▾ and the args/result body. The Ctrl+T hint only shows
26
- // on the live turn — committed turns are frozen in Ink's <Static> and cannot re-fold.
50
+ // Inline shortened params (summariseToolCall handles the empty/unparsable-args fallbacks).
51
+ const summary = summariseToolCall(tc.name, tc.argsText);
52
+ const caret = expanded ? '▾' : '▸';
53
+ const hasDetail = !!tc.argsText || !!tc.result || !!tc.output || !!tc.notice;
54
+ const displayInput = {
55
+ name: tc.name,
56
+ argsText: tc.argsText,
57
+ result: tc.result,
58
+ output: tc.output,
59
+ isError: tc.isError,
60
+ };
61
+ // Collapsed: the canonical 10-line capped preview. Expanded: the full uncapped body.
62
+ const body = expanded ? buildToolBodyLines(displayInput) : buildToolPreviewLines(displayInput);
63
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: color, children: [`${caret} ${glyph} ${getToolGlyph(tc.name)} ${summary}`, _jsx(Text, { dimColor: true, children: ` [${label}]` }), live && !expanded && hasDetail ? _jsx(Text, { dimColor: true, children: ' (Ctrl+T to expand)' }) : null] }), expanded && tc.argsText ? (_jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: ' args: ' }), _jsx(Text, { dimColor: true, children: tc.argsText })] })) : null, expanded && tc.notice
64
+ ? tc.notice.split('\n').map((line, i) => (_jsx(Text, { dimColor: true, children: ` ${line}` }, `n${i}`)))
65
+ : null, body.map((line, i) => (_jsx(ToolBodyLine, { line: line }, i)))] }));
66
+ }
67
+ /**
68
+ * The `💭 Thinking` region: the model's reasoning/chain-of-thought, rendered as a distinct
69
+ * *layer* from the answer. Collapsible like {@link ToolCallPanel} (shares the turn's Ctrl+T
70
+ * detail toggle) and collapsed by default, so ephemeral thinking never competes with the answer
71
+ * — worst case a lone 👍 answer drowned by paragraphs of thought. When expanded, each line is
72
+ * drawn behind a `│ ` gutter. The label + gutter are **cyan** (DL-8 "informational") rather than
73
+ * dim-only: dim is the least reliably-rendered ANSI attribute and vanishes on many themes, so a
74
+ * dim-only region reads as the answer. Cyan carries the layer boundary as colour; the body stays
75
+ * dim+italic underneath the coloured gutter.
76
+ */
77
+ export function ReasoningPanel({ reasoning, expanded, live, label = 'Thinking', }) {
27
78
  const caret = expanded ? '▾' : '▸';
28
- const hasDetail = !!tc.argsText || !!tc.result;
29
- return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: color, children: [`${caret} ${glyph} ${name}`, _jsx(Text, { dimColor: true, children: ` [${label}]` }), live && !expanded && hasDetail ? _jsx(Text, { dimColor: true, children: ' (Ctrl+T to expand)' }) : null] }), expanded && tc.argsText ? (_jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: ' args: ' }), _jsx(Text, { dimColor: true, children: tc.argsText })] })) : null, expanded && tc.result ? (_jsx(Box, { flexDirection: "column", children: tc.result.split('\n').map((line, i) => (_jsx(Text, { dimColor: true, children: ` ${line}` }, i))) })) : null] }));
79
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: "cyan", children: [`${caret} 💭 ${label}`, live && !expanded ? _jsx(Text, { dimColor: true, children: ' (Ctrl+T to expand)' }) : null] }), expanded
80
+ ? reasoning.split('\n').map((line, i) => (_jsxs(Box, { children: [_jsx(Text, { color: "cyan", children: '│ ' }), _jsx(Text, { dimColor: true, italic: true, children: line })] }, i)))
81
+ : null] }));
82
+ }
83
+ /** Glyph + colour for one checklist row's status (DL colour semantics). */
84
+ function checklistRow(status) {
85
+ switch (status) {
86
+ case 'completed':
87
+ return { glyph: '[x]', color: 'green' };
88
+ case 'in_progress':
89
+ return { glyph: '[~]', color: 'yellow' };
90
+ default:
91
+ return { glyph: '[ ]', color: 'gray' };
92
+ }
93
+ }
94
+ /**
95
+ * A `gth_checklist` tool call rendered as a live plan: a `📋 Checklist (done/total)` header and one
96
+ * checkbox row per item, coloured by status. Shown expanded (unlike generic tool panels) because
97
+ * the plan is meant to be seen — it is the lean agent's answer to deepagents' `write_todos`. The
98
+ * caller only routes here once {@link parseChecklistArgs} yields rows; a still-streaming/partial
99
+ * args buffer falls back to the generic {@link ToolCallPanel}.
100
+ */
101
+ function ChecklistPanel({ items }) {
102
+ const done = items.filter((i) => i.status === 'completed').length;
103
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "cyan", children: `📋 Checklist (${done}/${items.length})` }), items.map((item, i) => {
104
+ const { glyph, color } = checklistRow(item.status);
105
+ return (_jsxs(Box, { children: [_jsx(Text, { color: color, children: ` ${glyph} ` }), _jsx(Text, { dimColor: item.status === 'completed', strikethrough: item.status === 'completed', children: item.content })] }, i));
106
+ })] }));
30
107
  }
31
108
  /**
32
- * Renders one assistant turn from the pure {@link TurnViewModel}: a dim reasoning region,
33
- * one collapsible panel per tool call, then the assistant text. Used both for the in-progress
34
- * live turn and (frozen) for committed turns in the transcript, so the look is identical once
35
- * done.
109
+ * Renders one assistant turn from the pure {@link TurnViewModel}: a collapsible `💭 Thinking`
110
+ * reasoning region, one collapsible panel per tool call, then the assistant text. Used both for
111
+ * the in-progress live turn and (frozen) for committed turns in the transcript, so the look is
112
+ * identical once done.
36
113
  *
37
114
  * Assistant text is rendered as terminal **markdown** once the segment is complete; while a
38
115
  * turn is still streaming (`streaming` true) we render it as plain text so the live region
@@ -41,6 +118,15 @@ function ToolCallPanel({ tc, expanded, live, }) {
41
118
  * fails, so plain prose always reads correctly.
42
119
  */
43
120
  export function LiveTurn({ turn, toolsExpanded = false, streaming = false, }) {
44
- return (_jsxs(Box, { flexDirection: "column", children: [turn.reasoning ? _jsx(Text, { dimColor: true, children: turn.reasoning }) : null, turn.toolCalls.map((tc) => (_jsx(ToolCallPanel, { tc: tc, expanded: toolsExpanded, live: streaming }, tc.id))), turn.text ? _jsx(Text, { children: streaming ? turn.text : renderMarkdown(turn.text) }) : null] }));
121
+ return (_jsxs(Box, { flexDirection: "column", children: [turn.reasoning ? (_jsx(ReasoningPanel, { reasoning: turn.reasoning, expanded: toolsExpanded, live: streaming })) : null, turn.toolCalls.map((tc) => {
122
+ // The checklist tool renders as a dedicated live plan panel once its args parse; until
123
+ // then (or if it never parses) it falls back to the generic collapsible tool panel.
124
+ if (tc.name === CHECKLIST_TOOL_NAME) {
125
+ const items = parseChecklistArgs(tc.argsText);
126
+ if (items)
127
+ return _jsx(ChecklistPanel, { items: items }, tc.id);
128
+ }
129
+ return _jsx(ToolCallPanel, { tc: tc, expanded: toolsExpanded, live: streaming }, tc.id);
130
+ }), turn.text ? _jsx(Text, { children: streaming ? turn.text : renderMarkdown(turn.text) }) : null] }));
45
131
  }
46
132
  //# sourceMappingURL=LiveTurn.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LiveTurn.js","sourceRoot":"","sources":["../../../src/tui/components/LiveTurn.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"LiveTurn.js","sourceRoot":"","sources":["../../../src/tui/components/LiveTurn.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import React from 'react';
2
+ import type { McpConnectionFailure } from '@gaunt-sloth/core/core/types.js';
3
+ /**
4
+ * TUI-C19 — a persistent, single-line advisory bar for non-fatal startup advisories.
5
+ *
6
+ * Rendered in the live (non-`<Static>`) chrome next to the status bar (see `App.tsx`), so — unlike
7
+ * a transient `displayWarning` that scrolls away the moment Ink takes over — it stays pinned and
8
+ * survives transcript growth (DL-1: no important thing is silent). It shows ONLY when there is at
9
+ * least one advisory; a clean startup renders nothing (returns `null`), so the chrome is unchanged
10
+ * when there's nothing to say.
11
+ *
12
+ * The advisory list is intentionally generic (a plain string list) so other non-fatal startup
13
+ * advisories can post here later. Today the only producer is config validation (unknown keys /
14
+ * deprecated names captured around `initConfig`), so the standing line points at `/config`, which
15
+ * renders the actual warning text (DL-2 progressive disclosure: the pointer here, the detail there).
16
+ * Yellow + `⚠` matches the warn tone used elsewhere in the chrome (DL-8 meaningful colour).
17
+ */
18
+ export declare function NoticeBar({ advisories }: {
19
+ advisories?: string[];
20
+ }): React.ReactElement | null;
21
+ /**
22
+ * A sibling of {@link NoticeBar} for MCP connection failures captured during agent init. Kept
23
+ * separate from the config-advisory bar on purpose: a server that failed to connect is not a config
24
+ * problem and its detail lives in the `/debug` MCP tab, not `/config`. Same persistence rationale —
25
+ * without this pinned line the only signal is a `displayWarning` the Ink TUI immediately paints
26
+ * over, so a failed MCP server would look identical to a healthy one with no tools. Names the
27
+ * server(s) here (the pointer); the tab carries the full reason (DL-2 progressive disclosure).
28
+ * Renders nothing when every configured server connected.
29
+ */
30
+ export declare function McpFailureBar({ failures, }: {
31
+ failures?: McpConnectionFailure[];
32
+ }): React.ReactElement | null;
@@ -0,0 +1,39 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Box, Text } from 'ink';
3
+ /**
4
+ * TUI-C19 — a persistent, single-line advisory bar for non-fatal startup advisories.
5
+ *
6
+ * Rendered in the live (non-`<Static>`) chrome next to the status bar (see `App.tsx`), so — unlike
7
+ * a transient `displayWarning` that scrolls away the moment Ink takes over — it stays pinned and
8
+ * survives transcript growth (DL-1: no important thing is silent). It shows ONLY when there is at
9
+ * least one advisory; a clean startup renders nothing (returns `null`), so the chrome is unchanged
10
+ * when there's nothing to say.
11
+ *
12
+ * The advisory list is intentionally generic (a plain string list) so other non-fatal startup
13
+ * advisories can post here later. Today the only producer is config validation (unknown keys /
14
+ * deprecated names captured around `initConfig`), so the standing line points at `/config`, which
15
+ * renders the actual warning text (DL-2 progressive disclosure: the pointer here, the detail there).
16
+ * Yellow + `⚠` matches the warn tone used elsewhere in the chrome (DL-8 meaningful colour).
17
+ */
18
+ export function NoticeBar({ advisories }) {
19
+ if (!advisories || advisories.length === 0)
20
+ return null;
21
+ return (_jsx(Box, { children: _jsx(Text, { color: "yellow", children: '⚠ Your config has problems · type /config to see details' }) }));
22
+ }
23
+ /**
24
+ * A sibling of {@link NoticeBar} for MCP connection failures captured during agent init. Kept
25
+ * separate from the config-advisory bar on purpose: a server that failed to connect is not a config
26
+ * problem and its detail lives in the `/debug` MCP tab, not `/config`. Same persistence rationale —
27
+ * without this pinned line the only signal is a `displayWarning` the Ink TUI immediately paints
28
+ * over, so a failed MCP server would look identical to a healthy one with no tools. Names the
29
+ * server(s) here (the pointer); the tab carries the full reason (DL-2 progressive disclosure).
30
+ * Renders nothing when every configured server connected.
31
+ */
32
+ export function McpFailureBar({ failures, }) {
33
+ if (!failures || failures.length === 0)
34
+ return null;
35
+ const names = failures.map((f) => f.server).join(', ');
36
+ const noun = failures.length === 1 ? 'server' : 'servers';
37
+ return (_jsx(Box, { children: _jsx(Text, { color: "yellow", children: `⚠ MCP ${noun} unavailable: ${names} · type /debug and open the MCP tab for details` }) }));
38
+ }
39
+ //# sourceMappingURL=NoticeBar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NoticeBar.js","sourceRoot":"","sources":["../../../src/tui/components/NoticeBar.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAGhC;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,SAAS,CAAC,EAAE,UAAU,EAA6B;IACjE,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACxD,OAAO,CACL,KAAC,GAAG,cACF,KAAC,IAAI,IAAC,KAAK,EAAC,QAAQ,YAAE,0DAA0D,GAAQ,GACpF,CACP,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAAC,EAC5B,QAAQ,GAGT;IACC,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACpD,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvD,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;IAC1D,OAAO,CACL,KAAC,GAAG,cACF,KAAC,IAAI,IAAC,KAAK,EAAC,QAAQ,YACjB,SAAS,IAAI,iBAAiB,KAAK,iDAAiD,GAChF,GACH,CACP,CAAC;AACJ,CAAC"}
@@ -1,8 +1,33 @@
1
1
  import React from 'react';
2
+ import { type SlashCommand } from '#src/tui/slashCommands.js';
2
3
  /**
3
4
  * The user prompt line. Mirrors the readline ` > ` prompt. Clears on submit; the parent
4
5
  * hides it while a turn is running so Ink owns stdin uncontended during streaming.
6
+ *
7
+ * TUI-C10 — while the user is typing a bare slash command (input starts with `/`, no space yet),
8
+ * a discovery menu of the matching registered commands appears just above the prompt. The registry
9
+ * (`commands`) is the single source, so extension-registered commands show automatically. Arrow
10
+ * keys move the highlight, Tab completes the highlighted name, Enter dispatches it, Esc dismisses
11
+ * the menu. The keyboard split is clean: `ink-text-input` ignores Up/Down/Tab and only fires
12
+ * `onSubmit` on Enter, so this component's `useInput` owns the arrows/Tab/Esc while `onSubmit` owns
13
+ * Enter — no double-handling. A fully-typed command still dispatches exactly as before (Enter with
14
+ * the menu open just submits the highlighted command, which equals what was typed).
15
+ *
16
+ * TUI-C24 — multiline paste. `ink-text-input` is single-line: an embedded newline in a pasted
17
+ * burst would otherwise be read as Enter and submit the turn mid-paste (or jam the lines together).
18
+ * `usePaste` puts the terminal into bracketed-paste mode (`\x1b[?2004h`) while the prompt is mounted
19
+ * and disables it on unmount, and Ink delivers the pasted text on a channel separate from
20
+ * `useInput` — so the payload never reaches `TextInput`'s Enter handling. We append the normalized
21
+ * paste (CRLF/CR → `\n`) to the buffer without submitting; a subsequent explicit Enter submits the
22
+ * whole multi-line value through the existing `onSubmit` path. Rich multi-line cursor editing /
23
+ * continuation-line rendering is intentionally NOT handled here — that is node TUI-C25; a buffered
24
+ * multi-line value may render imperfectly, but the submitted value is correct and intact.
5
25
  */
6
- export declare function PromptInput({ onSubmit, }: {
26
+ export declare function PromptInput({ onSubmit, commands, onMenuStateChange, }: {
7
27
  onSubmit: (value: string) => void;
28
+ /** The slash-command registry (App builds it once) — the menu's single source of truth. */
29
+ commands?: SlashCommand[];
30
+ /** Notifies the parent whether the menu currently owns navigation keys (so App can stand down
31
+ * its own Tab handler while the menu is open). */
32
+ onMenuStateChange?: (active: boolean) => void;
8
33
  }): React.ReactElement;