@stigmer/ink 0.0.88

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 (85) hide show
  1. package/LICENSE +190 -0
  2. package/app/SessionApp.d.ts +42 -0
  3. package/app/SessionApp.d.ts.map +1 -0
  4. package/app/SessionApp.js +38 -0
  5. package/app/SessionApp.js.map +1 -0
  6. package/app/SessionView.d.ts +32 -0
  7. package/app/SessionView.d.ts.map +1 -0
  8. package/app/SessionView.js +58 -0
  9. package/app/SessionView.js.map +1 -0
  10. package/cli/stigmer-ink.d.ts +3 -0
  11. package/cli/stigmer-ink.d.ts.map +1 -0
  12. package/cli/stigmer-ink.js +117 -0
  13. package/cli/stigmer-ink.js.map +1 -0
  14. package/components/ApprovalPrompt.d.ts +21 -0
  15. package/components/ApprovalPrompt.d.ts.map +1 -0
  16. package/components/ApprovalPrompt.js +60 -0
  17. package/components/ApprovalPrompt.js.map +1 -0
  18. package/components/ExecutionProgress.d.ts +16 -0
  19. package/components/ExecutionProgress.d.ts.map +1 -0
  20. package/components/ExecutionProgress.js +47 -0
  21. package/components/ExecutionProgress.js.map +1 -0
  22. package/components/FollowUpInput.d.ts +19 -0
  23. package/components/FollowUpInput.d.ts.map +1 -0
  24. package/components/FollowUpInput.js +27 -0
  25. package/components/FollowUpInput.js.map +1 -0
  26. package/components/MessageEntry.d.ts +18 -0
  27. package/components/MessageEntry.d.ts.map +1 -0
  28. package/components/MessageEntry.js +42 -0
  29. package/components/MessageEntry.js.map +1 -0
  30. package/components/MessageThread.d.ts +31 -0
  31. package/components/MessageThread.d.ts.map +1 -0
  32. package/components/MessageThread.js +146 -0
  33. package/components/MessageThread.js.map +1 -0
  34. package/components/SubAgentBlock.d.ts +19 -0
  35. package/components/SubAgentBlock.d.ts.map +1 -0
  36. package/components/SubAgentBlock.js +73 -0
  37. package/components/SubAgentBlock.js.map +1 -0
  38. package/components/TodoList.d.ts +17 -0
  39. package/components/TodoList.d.ts.map +1 -0
  40. package/components/TodoList.js +43 -0
  41. package/components/TodoList.js.map +1 -0
  42. package/components/ToolCallGroup.d.ts +20 -0
  43. package/components/ToolCallGroup.d.ts.map +1 -0
  44. package/components/ToolCallGroup.js +51 -0
  45. package/components/ToolCallGroup.js.map +1 -0
  46. package/components/ToolCallItem.d.ts +14 -0
  47. package/components/ToolCallItem.d.ts.map +1 -0
  48. package/components/ToolCallItem.js +33 -0
  49. package/components/ToolCallItem.js.map +1 -0
  50. package/components/UsageWidget.d.ts +16 -0
  51. package/components/UsageWidget.d.ts.map +1 -0
  52. package/components/UsageWidget.js +18 -0
  53. package/components/UsageWidget.js.map +1 -0
  54. package/index.d.ts +16 -0
  55. package/index.d.ts.map +1 -0
  56. package/index.js +21 -0
  57. package/index.js.map +1 -0
  58. package/markdown.d.ts +21 -0
  59. package/markdown.d.ts.map +1 -0
  60. package/markdown.js +44 -0
  61. package/markdown.js.map +1 -0
  62. package/package.json +48 -0
  63. package/provider.d.ts +46 -0
  64. package/provider.d.ts.map +1 -0
  65. package/provider.js +33 -0
  66. package/provider.js.map +1 -0
  67. package/src/__tests__/components.test.tsx +162 -0
  68. package/src/__tests__/markdown.test.ts +46 -0
  69. package/src/app/SessionApp.tsx +74 -0
  70. package/src/app/SessionView.tsx +164 -0
  71. package/src/cli/stigmer-ink.tsx +148 -0
  72. package/src/components/ApprovalPrompt.tsx +139 -0
  73. package/src/components/ExecutionProgress.tsx +75 -0
  74. package/src/components/FollowUpInput.tsx +70 -0
  75. package/src/components/MessageEntry.tsx +80 -0
  76. package/src/components/MessageThread.tsx +264 -0
  77. package/src/components/SubAgentBlock.tsx +146 -0
  78. package/src/components/TodoList.tsx +75 -0
  79. package/src/components/ToolCallGroup.tsx +92 -0
  80. package/src/components/ToolCallItem.tsx +74 -0
  81. package/src/components/UsageWidget.tsx +35 -0
  82. package/src/index.ts +28 -0
  83. package/src/markdown.ts +48 -0
  84. package/src/provider.tsx +62 -0
  85. package/src/types/marked-terminal.d.ts +19 -0
@@ -0,0 +1,47 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ import Spinner from "ink-spinner";
4
+ import { ExecutionPhase } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
5
+ const PHASE_DISPLAY = new Map([
6
+ [ExecutionPhase.EXECUTION_PENDING, { label: "Pending", showSpinner: true }],
7
+ [
8
+ ExecutionPhase.EXECUTION_IN_PROGRESS,
9
+ { label: "Running", color: "yellow", showSpinner: true },
10
+ ],
11
+ [
12
+ ExecutionPhase.EXECUTION_COMPLETED,
13
+ { label: "Completed", color: "green", showSpinner: false },
14
+ ],
15
+ [
16
+ ExecutionPhase.EXECUTION_FAILED,
17
+ { label: "Failed", color: "red", showSpinner: false },
18
+ ],
19
+ [
20
+ ExecutionPhase.EXECUTION_CANCELLED,
21
+ { label: "Cancelled", showSpinner: false },
22
+ ],
23
+ [
24
+ ExecutionPhase.EXECUTION_TERMINATED,
25
+ { label: "Terminated", color: "red", showSpinner: false },
26
+ ],
27
+ [
28
+ ExecutionPhase.EXECUTION_WAITING_FOR_APPROVAL,
29
+ { label: "Waiting for approval", color: "yellow", showSpinner: false },
30
+ ],
31
+ [ExecutionPhase.EXECUTION_PAUSED, { label: "Paused", showSpinner: false }],
32
+ ]);
33
+ /**
34
+ * Displays the current execution phase as a compact terminal badge.
35
+ *
36
+ * Shows a spinner for active phases (pending, in-progress) and
37
+ * static indicators for terminal phases.
38
+ *
39
+ * Renders nothing for unspecified phases.
40
+ */
41
+ export function ExecutionProgress({ phase }) {
42
+ const display = PHASE_DISPLAY.get(phase);
43
+ if (!display)
44
+ return null;
45
+ return (_jsxs(Box, { gap: 1, paddingLeft: 1, children: [display.showSpinner ? (_jsx(Text, { color: display.color ?? "cyan", children: _jsx(Spinner, { type: "dots" }) })) : (_jsx(Text, { color: display.color, children: phase === ExecutionPhase.EXECUTION_COMPLETED ? "✓" : "●" })), _jsx(Text, { color: display.color, dimColor: !display.color, children: display.label })] }));
46
+ }
47
+ //# sourceMappingURL=ExecutionProgress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExecutionProgress.js","sourceRoot":"","sources":["../../src/components/ExecutionProgress.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,OAAO,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,cAAc,EAAE,MAAM,8DAA8D,CAAC;AAc9F,MAAM,aAAa,GAA8C,IAAI,GAAG,CAAC;IACvE,CAAC,cAAc,CAAC,iBAAiB,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IAC3E;QACE,cAAc,CAAC,qBAAqB;QACpC,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE;KACzD;IACD;QACE,cAAc,CAAC,mBAAmB;QAClC,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE;KAC3D;IACD;QACE,cAAc,CAAC,gBAAgB;QAC/B,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE;KACtD;IACD;QACE,cAAc,CAAC,mBAAmB;QAClC,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,EAAE;KAC3C;IACD;QACE,cAAc,CAAC,oBAAoB;QACnC,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE;KAC1D;IACD;QACE,cAAc,CAAC,8BAA8B;QAC7C,EAAE,KAAK,EAAE,sBAAsB,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE;KACvE;IACD,CAAC,cAAc,CAAC,gBAAgB,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;CAC3E,CAAC,CAAC;AAEH;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,EAAE,KAAK,EAA0B;IACjE,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACzC,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAE1B,OAAO,CACL,MAAC,GAAG,IAAC,GAAG,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,aACxB,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CACrB,KAAC,IAAI,IAAC,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,MAAM,YAClC,KAAC,OAAO,IAAC,IAAI,EAAC,MAAM,GAAG,GAClB,CACR,CAAC,CAAC,CAAC,CACF,KAAC,IAAI,IAAC,KAAK,EAAE,OAAO,CAAC,KAAK,YACvB,KAAK,KAAK,cAAc,CAAC,mBAAmB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GACpD,CACR,EACD,KAAC,IAAI,IAAC,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,YACjD,OAAO,CAAC,KAAK,GACT,IACH,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,19 @@
1
+ /** Props for {@link FollowUpInput}. */
2
+ export interface FollowUpInputProps {
3
+ /** Called when the user submits a message (Enter key). */
4
+ readonly onSubmit: (message: string) => void;
5
+ /** Shows a "sending" indicator and disables input. */
6
+ readonly isSubmitting?: boolean;
7
+ /** Disables the input entirely. */
8
+ readonly disabled?: boolean;
9
+ /** Placeholder text. Default: "Reply..." */
10
+ readonly placeholder?: string;
11
+ }
12
+ /**
13
+ * Terminal text input for sending follow-up messages in a session.
14
+ *
15
+ * Renders a single-line text input with a submit hint. Press Enter
16
+ * to submit, Ctrl+C to exit the application.
17
+ */
18
+ export declare function FollowUpInput({ onSubmit, isSubmitting, disabled, placeholder, }: FollowUpInputProps): import("react/jsx-runtime").JSX.Element;
19
+ //# sourceMappingURL=FollowUpInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FollowUpInput.d.ts","sourceRoot":"","sources":["../../src/components/FollowUpInput.tsx"],"names":[],"mappings":"AAIA,uCAAuC;AACvC,MAAM,WAAW,kBAAkB;IACjC,0DAA0D;IAC1D,QAAQ,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,sDAAsD;IACtD,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAChC,mCAAmC;IACnC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,4CAA4C;IAC5C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,YAAoB,EACpB,QAAgB,EAChB,WAAwB,GACzB,EAAE,kBAAkB,2CA0CpB"}
@@ -0,0 +1,27 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { Box, Text, useStdin } from "ink";
4
+ import TextInput from "ink-text-input";
5
+ /**
6
+ * Terminal text input for sending follow-up messages in a session.
7
+ *
8
+ * Renders a single-line text input with a submit hint. Press Enter
9
+ * to submit, Ctrl+C to exit the application.
10
+ */
11
+ export function FollowUpInput({ onSubmit, isSubmitting = false, disabled = false, placeholder = "Reply...", }) {
12
+ const [value, setValue] = useState("");
13
+ const { isRawModeSupported } = useStdin();
14
+ const isDisabled = disabled || isSubmitting || !isRawModeSupported;
15
+ const handleSubmit = (input) => {
16
+ const trimmed = input.trim();
17
+ if (!trimmed)
18
+ return;
19
+ onSubmit(trimmed);
20
+ setValue("");
21
+ };
22
+ if (isDisabled) {
23
+ return (_jsx(Box, { paddingLeft: 1, paddingTop: 1, children: _jsx(Text, { dimColor: true, children: isSubmitting ? "Sending..." : placeholder }) }));
24
+ }
25
+ return (_jsxs(Box, { paddingLeft: 1, paddingTop: 1, flexDirection: "column", children: [_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: "cyan", bold: true, children: "\u276F" }), _jsx(TextInput, { value: value, onChange: setValue, onSubmit: handleSubmit, placeholder: placeholder })] }), _jsx(Box, { paddingLeft: 2, children: _jsx(Text, { dimColor: true, children: "Enter to send \u00B7 Ctrl+C to exit" }) })] }));
26
+ }
27
+ //# sourceMappingURL=FollowUpInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FollowUpInput.js","sourceRoot":"","sources":["../../src/components/FollowUpInput.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC1C,OAAO,SAAS,MAAM,gBAAgB,CAAC;AAcvC;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,EAC5B,QAAQ,EACR,YAAY,GAAG,KAAK,EACpB,QAAQ,GAAG,KAAK,EAChB,WAAW,GAAG,UAAU,GACL;IACnB,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IACvC,MAAM,EAAE,kBAAkB,EAAE,GAAG,QAAQ,EAAE,CAAC;IAC1C,MAAM,UAAU,GAAG,QAAQ,IAAI,YAAY,IAAI,CAAC,kBAAkB,CAAC;IAEnE,MAAM,YAAY,GAAG,CAAC,KAAa,EAAE,EAAE;QACrC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,CAAC,OAAO;YAAE,OAAO;QACrB,QAAQ,CAAC,OAAO,CAAC,CAAC;QAClB,QAAQ,CAAC,EAAE,CAAC,CAAC;IACf,CAAC,CAAC;IAEF,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,CACL,KAAC,GAAG,IAAC,WAAW,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,YAChC,KAAC,IAAI,IAAC,QAAQ,kBACX,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,WAAW,GACrC,GACH,CACP,CAAC;IACJ,CAAC;IAED,OAAO,CACL,MAAC,GAAG,IAAC,WAAW,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,EAAC,QAAQ,aACxD,MAAC,GAAG,IAAC,GAAG,EAAE,CAAC,aACT,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,IAAI,6BAEhB,EACP,KAAC,SAAS,IACR,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,YAAY,EACtB,WAAW,EAAE,WAAW,GACxB,IACE,EACN,KAAC,GAAG,IAAC,WAAW,EAAE,CAAC,YACjB,KAAC,IAAI,IAAC,QAAQ,0DAEP,GACH,IACF,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { AgentMessage } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/message_pb";
2
+ /** Props for {@link MessageEntry}. */
3
+ export interface MessageEntryProps {
4
+ /** The agent message to render. */
5
+ readonly message: AgentMessage;
6
+ }
7
+ /**
8
+ * Renders a single message in the terminal conversation thread.
9
+ *
10
+ * - `MESSAGE_HUMAN` — plain text prefixed with a "You" indicator
11
+ * - `MESSAGE_AI` — markdown rendered to ANSI-styled terminal output,
12
+ * with a cursor indicator while streaming
13
+ * - `MESSAGE_SYSTEM` — dimmed text
14
+ * - `MESSAGE_TOOL` / `UNSPECIFIED` — renders nothing (tool results
15
+ * are handled by {@link ToolCallGroup})
16
+ */
17
+ export declare function MessageEntry({ message }: MessageEntryProps): import("react/jsx-runtime").JSX.Element | null;
18
+ //# sourceMappingURL=MessageEntry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MessageEntry.d.ts","sourceRoot":"","sources":["../../src/components/MessageEntry.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iEAAiE,CAAC;AAIpG,sCAAsC;AACtC,MAAM,WAAW,iBAAiB;IAChC,mCAAmC;IACnC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;CAChC;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,EAAE,OAAO,EAAE,EAAE,iBAAiB,kDAa1D"}
@@ -0,0 +1,42 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useMemo } from "react";
3
+ import { Box, Text } from "ink";
4
+ import { MessageType } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
5
+ import { renderMarkdown } from "../markdown.js";
6
+ /**
7
+ * Renders a single message in the terminal conversation thread.
8
+ *
9
+ * - `MESSAGE_HUMAN` — plain text prefixed with a "You" indicator
10
+ * - `MESSAGE_AI` — markdown rendered to ANSI-styled terminal output,
11
+ * with a cursor indicator while streaming
12
+ * - `MESSAGE_SYSTEM` — dimmed text
13
+ * - `MESSAGE_TOOL` / `UNSPECIFIED` — renders nothing (tool results
14
+ * are handled by {@link ToolCallGroup})
15
+ */
16
+ export function MessageEntry({ message }) {
17
+ switch (message.type) {
18
+ case MessageType.MESSAGE_HUMAN:
19
+ return _jsx(HumanMessage, { content: message.content });
20
+ case MessageType.MESSAGE_AI:
21
+ return (_jsx(AiMessage, { content: message.content, isStreaming: message.isStreaming }));
22
+ case MessageType.MESSAGE_SYSTEM:
23
+ return _jsx(SystemMessage, { content: message.content });
24
+ default:
25
+ return null;
26
+ }
27
+ }
28
+ function HumanMessage({ content }) {
29
+ return (_jsxs(Box, { flexDirection: "column", paddingLeft: 1, children: [_jsx(Text, { bold: true, color: "cyan", children: "You" }), _jsx(Text, { children: content })] }));
30
+ }
31
+ function AiMessage({ content, isStreaming, }) {
32
+ const rendered = useMemo(() => {
33
+ if (!content.trim())
34
+ return "";
35
+ return renderMarkdown(content);
36
+ }, [content]);
37
+ return (_jsxs(Box, { flexDirection: "column", paddingLeft: 1, children: [_jsx(Text, { bold: true, color: "green", children: "Agent" }), rendered ? _jsx(Text, { children: rendered }) : null, isStreaming && !rendered && _jsx(Text, { dimColor: true, children: "Thinking..." })] }));
38
+ }
39
+ function SystemMessage({ content }) {
40
+ return (_jsx(Box, { paddingLeft: 1, children: _jsx(Text, { dimColor: true, italic: true, children: content }) }));
41
+ }
42
+ //# sourceMappingURL=MessageEntry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MessageEntry.js","sourceRoot":"","sources":["../../src/components/MessageEntry.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAEhC,OAAO,EAAE,WAAW,EAAE,MAAM,8DAA8D,CAAC;AAC3F,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAQhD;;;;;;;;;GASG;AACH,MAAM,UAAU,YAAY,CAAC,EAAE,OAAO,EAAqB;IACzD,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;QACrB,KAAK,WAAW,CAAC,aAAa;YAC5B,OAAO,KAAC,YAAY,IAAC,OAAO,EAAE,OAAO,CAAC,OAAO,GAAI,CAAC;QACpD,KAAK,WAAW,CAAC,UAAU;YACzB,OAAO,CACL,KAAC,SAAS,IAAC,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,GAAI,CAC1E,CAAC;QACJ,KAAK,WAAW,CAAC,cAAc;YAC7B,OAAO,KAAC,aAAa,IAAC,OAAO,EAAE,OAAO,CAAC,OAAO,GAAI,CAAC;QACrD;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,EAAE,OAAO,EAAuB;IACpD,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,WAAW,EAAE,CAAC,aACxC,KAAC,IAAI,IAAC,IAAI,QAAC,KAAK,EAAC,MAAM,oBAEhB,EACP,KAAC,IAAI,cAAE,OAAO,GAAQ,IAClB,CACP,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAC,EACjB,OAAO,EACP,WAAW,GAIZ;IACC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,EAAE;QAC5B,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;YAAE,OAAO,EAAE,CAAC;QAC/B,OAAO,cAAc,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAEd,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,WAAW,EAAE,CAAC,aACxC,KAAC,IAAI,IAAC,IAAI,QAAC,KAAK,EAAC,OAAO,sBAEjB,EACN,QAAQ,CAAC,CAAC,CAAC,KAAC,IAAI,cAAE,QAAQ,GAAQ,CAAC,CAAC,CAAC,IAAI,EACzC,WAAW,IAAI,CAAC,QAAQ,IAAI,KAAC,IAAI,IAAC,QAAQ,kCAAmB,IAC1D,CACP,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,EAAE,OAAO,EAAuB;IACrD,OAAO,CACL,KAAC,GAAG,IAAC,WAAW,EAAE,CAAC,YACjB,KAAC,IAAI,IAAC,QAAQ,QAAC,MAAM,kBAClB,OAAO,GACH,GACH,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,31 @@
1
+ import type { AgentExecution } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
2
+ import { ApprovalAction } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
3
+ /** Props for {@link MessageThread}. */
4
+ export interface MessageThreadProps {
5
+ /** Completed executions in chronological order. */
6
+ readonly executions: readonly AgentExecution[];
7
+ /** The currently streaming execution (appended after `executions`). */
8
+ readonly activeStreamExecution?: AgentExecution | null;
9
+ /** Optimistic user message shown before the stream delivers it. */
10
+ readonly pendingUserMessage?: string | null;
11
+ /** Callback for approval actions. Shows approval UI when provided. */
12
+ readonly onApprovalSubmit?: (toolCallId: string, action: ApprovalAction) => void;
13
+ /** Set of tool call IDs currently being submitted for approval. */
14
+ readonly submittingApprovalIds?: ReadonlySet<string>;
15
+ /** Whether tool call groups should be rendered in expanded mode. Toggled via Ctrl+O. */
16
+ readonly expandToolCalls?: boolean;
17
+ }
18
+ /**
19
+ * Renders a continuous conversation thread from one or more
20
+ * `AgentExecution` snapshots in the terminal.
21
+ *
22
+ * Composes {@link MessageEntry}, {@link ToolCallGroup},
23
+ * {@link ExecutionProgress}, and {@link ApprovalPrompt} into a
24
+ * scrolling terminal log.
25
+ *
26
+ * Historical items are rendered via Ink's `<Static>` component so
27
+ * they are written once and don't re-render, keeping terminal
28
+ * output efficient for long conversations.
29
+ */
30
+ export declare function MessageThread({ executions, activeStreamExecution, pendingUserMessage, onApprovalSubmit, submittingApprovalIds, expandToolCalls, }: MessageThreadProps): import("react/jsx-runtime").JSX.Element;
31
+ //# sourceMappingURL=MessageThread.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MessageThread.d.ts","sourceRoot":"","sources":["../../src/components/MessageThread.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6DAA6D,CAAC;AAQlG,OAAO,EACL,cAAc,EAGf,MAAM,8DAA8D,CAAC;AAQtE,uCAAuC;AACvC,MAAM,WAAW,kBAAkB;IACjC,mDAAmD;IACnD,QAAQ,CAAC,UAAU,EAAE,SAAS,cAAc,EAAE,CAAC;IAC/C,uEAAuE;IACvE,QAAQ,CAAC,qBAAqB,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IACvD,mEAAmE;IACnE,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,sEAAsE;IACtE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAC1B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,cAAc,KACnB,IAAI,CAAC;IACV,mEAAmE;IACnE,QAAQ,CAAC,qBAAqB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACrD,wFAAwF;IACxF,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;CACpC;AA6GD;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,EAC5B,UAAU,EACV,qBAAqB,EACrB,kBAAkB,EAClB,gBAAgB,EAChB,qBAAqB,EACrB,eAAuB,GACxB,EAAE,kBAAkB,2CAiCpB"}
@@ -0,0 +1,146 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useMemo } from "react";
3
+ import { Box, Text, Static } from "ink";
4
+ import { create } from "@bufbuild/protobuf";
5
+ import { AgentMessageSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/message_pb";
6
+ import { ExecutionPhase, MessageType, } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
7
+ import { isTerminalPhase } from "@stigmer/react";
8
+ import { MessageEntry } from "./MessageEntry.js";
9
+ import { ToolCallGroup } from "./ToolCallGroup.js";
10
+ import { SubAgentBlock } from "./SubAgentBlock.js";
11
+ import { ExecutionProgress } from "./ExecutionProgress.js";
12
+ import { ApprovalPrompt } from "./ApprovalPrompt.js";
13
+ function buildThreadItems(executions, activeStreamExecution, pendingUserMessage, includeApprovals) {
14
+ const items = [];
15
+ const allExecutions = activeStreamExecution
16
+ ? [...executions, activeStreamExecution]
17
+ : executions;
18
+ for (let ei = 0; ei < allExecutions.length; ei++) {
19
+ const exec = allExecutions[ei];
20
+ const messages = exec.status?.messages ?? [];
21
+ const subAgents = exec.status?.subAgentExecutions ?? [];
22
+ const specMessage = exec.spec?.message;
23
+ if (specMessage && specMessage !== "execute") {
24
+ const humanMsg = create(AgentMessageSchema);
25
+ humanMsg.type = MessageType.MESSAGE_HUMAN;
26
+ humanMsg.content = specMessage;
27
+ items.push({ kind: "message", message: humanMsg, key: `e${ei}-spec` });
28
+ }
29
+ for (let mi = 0; mi < messages.length; mi++) {
30
+ const msg = messages[mi];
31
+ if (msg.type === MessageType.MESSAGE_TOOL)
32
+ continue;
33
+ const isEmptyAi = msg.type === MessageType.MESSAGE_AI && !msg.content.trim();
34
+ if (!isEmptyAi) {
35
+ items.push({ kind: "message", message: msg, key: `e${ei}-m${mi}` });
36
+ }
37
+ if (msg.type === MessageType.MESSAGE_AI && msg.toolCalls.length > 0) {
38
+ // Split tool calls: "task" tools become sub-agent blocks,
39
+ // everything else goes into a regular tool group.
40
+ const regularTools = msg.toolCalls.filter((tc) => tc.name !== "task");
41
+ const taskTools = msg.toolCalls.filter((tc) => tc.name === "task");
42
+ if (regularTools.length > 0) {
43
+ items.push({
44
+ kind: "tool-group",
45
+ toolCalls: regularTools,
46
+ key: `e${ei}-m${mi}-tc`,
47
+ });
48
+ }
49
+ for (let ti = 0; ti < taskTools.length; ti++) {
50
+ const matchedSub = subAgents.find((sa) => sa.id === taskTools[ti].id);
51
+ if (matchedSub) {
52
+ items.push({
53
+ kind: "sub-agent",
54
+ subAgent: matchedSub,
55
+ key: `e${ei}-m${mi}-sa-${ti}`,
56
+ });
57
+ }
58
+ }
59
+ }
60
+ }
61
+ }
62
+ const lastExec = allExecutions[allExecutions.length - 1];
63
+ const lastPhase = lastExec?.status?.phase ?? ExecutionPhase.EXECUTION_PHASE_UNSPECIFIED;
64
+ if (isTerminalPhase(lastPhase) &&
65
+ lastPhase !== ExecutionPhase.EXECUTION_COMPLETED) {
66
+ items.push({ kind: "phase", phase: lastPhase, key: `phase-${lastPhase}` });
67
+ }
68
+ if (includeApprovals) {
69
+ const approvals = lastExec?.status?.pendingApprovals ?? [];
70
+ for (let ai = 0; ai < approvals.length; ai++) {
71
+ items.push({
72
+ kind: "approval",
73
+ pendingApproval: approvals[ai],
74
+ key: `approval-${approvals[ai].toolCallId || ai}`,
75
+ });
76
+ }
77
+ }
78
+ if (pendingUserMessage) {
79
+ const alreadySynthesized = lastExec?.spec?.message === pendingUserMessage;
80
+ if (!alreadySynthesized) {
81
+ items.push({
82
+ kind: "pending-message",
83
+ content: pendingUserMessage,
84
+ key: "pending-user-msg",
85
+ });
86
+ }
87
+ }
88
+ return items;
89
+ }
90
+ /**
91
+ * Renders a continuous conversation thread from one or more
92
+ * `AgentExecution` snapshots in the terminal.
93
+ *
94
+ * Composes {@link MessageEntry}, {@link ToolCallGroup},
95
+ * {@link ExecutionProgress}, and {@link ApprovalPrompt} into a
96
+ * scrolling terminal log.
97
+ *
98
+ * Historical items are rendered via Ink's `<Static>` component so
99
+ * they are written once and don't re-render, keeping terminal
100
+ * output efficient for long conversations.
101
+ */
102
+ export function MessageThread({ executions, activeStreamExecution, pendingUserMessage, onApprovalSubmit, submittingApprovalIds, expandToolCalls = false, }) {
103
+ const includeApprovals = onApprovalSubmit != null;
104
+ const items = useMemo(() => buildThreadItems(executions, activeStreamExecution, pendingUserMessage, includeApprovals), [executions, activeStreamExecution, pendingUserMessage, includeApprovals]);
105
+ const historyItems = activeStreamExecution ? items.slice(0, -getActiveCount(items)) : items;
106
+ const liveItems = activeStreamExecution ? items.slice(items.length - getActiveCount(items)) : [];
107
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Static, { items: historyItems, children: (item) => (_jsx(Box, { flexDirection: "column", marginBottom: 1, children: renderItem(item, onApprovalSubmit, submittingApprovalIds, expandToolCalls) }, item.key)) }), liveItems.map((item) => (_jsx(Box, { flexDirection: "column", marginBottom: 1, children: renderItem(item, onApprovalSubmit, submittingApprovalIds, expandToolCalls) }, item.key)))] }));
108
+ }
109
+ function getActiveCount(items) {
110
+ let count = 0;
111
+ for (let i = items.length - 1; i >= 0; i--) {
112
+ const item = items[i];
113
+ if (item.kind === "approval" ||
114
+ item.kind === "pending-message" ||
115
+ item.kind === "phase") {
116
+ count++;
117
+ }
118
+ else if (item.kind === "message" &&
119
+ item.message.type === MessageType.MESSAGE_AI &&
120
+ item.message.isStreaming) {
121
+ count++;
122
+ break;
123
+ }
124
+ else {
125
+ break;
126
+ }
127
+ }
128
+ return count;
129
+ }
130
+ function renderItem(item, onApprovalSubmit, submittingApprovalIds, expandToolCalls) {
131
+ switch (item.kind) {
132
+ case "message":
133
+ return _jsx(MessageEntry, { message: item.message });
134
+ case "tool-group":
135
+ return _jsx(ToolCallGroup, { toolCalls: item.toolCalls, defaultExpanded: expandToolCalls });
136
+ case "sub-agent":
137
+ return _jsx(SubAgentBlock, { subAgent: item.subAgent, defaultExpanded: expandToolCalls });
138
+ case "phase":
139
+ return _jsx(ExecutionProgress, { phase: item.phase });
140
+ case "approval":
141
+ return onApprovalSubmit ? (_jsx(ApprovalPrompt, { pendingApproval: item.pendingApproval, onSubmit: (action) => onApprovalSubmit(item.pendingApproval.toolCallId, action), isSubmitting: submittingApprovalIds?.has(item.pendingApproval.toolCallId) ?? false })) : null;
142
+ case "pending-message":
143
+ return (_jsx(Box, { paddingLeft: 1, children: _jsx(Text, { dimColor: true, italic: true, children: item.content }) }));
144
+ }
145
+ }
146
+ //# sourceMappingURL=MessageThread.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MessageThread.js","sourceRoot":"","sources":["../../src/components/MessageThread.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { SubAgentExecution } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/subagent_pb";
2
+ /** Props for {@link SubAgentBlock}. */
3
+ export interface SubAgentBlockProps {
4
+ /** The sub-agent execution data. */
5
+ readonly subAgent: SubAgentExecution;
6
+ /** Whether this block starts expanded. */
7
+ readonly defaultExpanded?: boolean;
8
+ /** Whether this component can receive keyboard focus for toggling. */
9
+ readonly isFocused?: boolean;
10
+ }
11
+ /**
12
+ * Renders a sub-agent execution as a collapsible block in the terminal.
13
+ *
14
+ * Shows a summary line with status glyph, name/subject, and duration.
15
+ * When expanded, renders the sub-agent's internal message thread using
16
+ * the same MessageEntry and ToolCallGroup components as the main thread.
17
+ */
18
+ export declare function SubAgentBlock({ subAgent, defaultExpanded, isFocused, }: SubAgentBlockProps): import("react/jsx-runtime").JSX.Element;
19
+ //# sourceMappingURL=SubAgentBlock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SubAgentBlock.d.ts","sourceRoot":"","sources":["../../src/components/SubAgentBlock.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kEAAkE,CAAC;AAM1G,uCAAuC;AACvC,MAAM,WAAW,kBAAkB;IACjC,oCAAoC;IACpC,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IACrC,0CAA0C;IAC1C,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC,sEAAsE;IACtE,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC9B;AAyBD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,eAAuB,EACvB,SAAiB,GAClB,EAAE,kBAAkB,2CA4DpB"}
@@ -0,0 +1,73 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { Box, Text, useInput } from "ink";
4
+ import { SubAgentStatus } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
5
+ import { MessageType } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
6
+ import { MessageEntry } from "./MessageEntry.js";
7
+ import { ToolCallGroup } from "./ToolCallGroup.js";
8
+ const STATUS_GLYPHS = {
9
+ [SubAgentStatus.SUB_AGENT_IN_PROGRESS]: { glyph: "⟳", color: "cyan" },
10
+ [SubAgentStatus.SUB_AGENT_COMPLETED]: { glyph: "✓", color: "green" },
11
+ [SubAgentStatus.SUB_AGENT_FAILED]: { glyph: "✗", color: "red" },
12
+ [SubAgentStatus.SUB_AGENT_PENDING]: { glyph: "○", color: "gray" },
13
+ [SubAgentStatus.SUB_AGENT_CANCELLED]: { glyph: "⊘", color: "yellow" },
14
+ };
15
+ function statusDisplay(status) {
16
+ return STATUS_GLYPHS[status] ?? { glyph: "·", color: "gray" };
17
+ }
18
+ function formatDuration(startedAt, completedAt) {
19
+ if (!startedAt)
20
+ return null;
21
+ const start = new Date(startedAt).getTime();
22
+ const end = completedAt ? new Date(completedAt).getTime() : Date.now();
23
+ const ms = end - start;
24
+ if (ms < 1000)
25
+ return `${ms}ms`;
26
+ const s = Math.round(ms / 1000);
27
+ if (s < 60)
28
+ return `${s}s`;
29
+ return `${Math.floor(s / 60)}m ${s % 60}s`;
30
+ }
31
+ /**
32
+ * Renders a sub-agent execution as a collapsible block in the terminal.
33
+ *
34
+ * Shows a summary line with status glyph, name/subject, and duration.
35
+ * When expanded, renders the sub-agent's internal message thread using
36
+ * the same MessageEntry and ToolCallGroup components as the main thread.
37
+ */
38
+ export function SubAgentBlock({ subAgent, defaultExpanded = false, isFocused = false, }) {
39
+ const [expanded, setExpanded] = useState(defaultExpanded);
40
+ useInput((input, key) => {
41
+ if (key.return || input === " ") {
42
+ setExpanded((e) => !e);
43
+ }
44
+ }, { isActive: isFocused });
45
+ const { glyph, color } = statusDisplay(subAgent.status);
46
+ const label = subAgent.subject || subAgent.name || "Sub-agent";
47
+ const duration = formatDuration(subAgent.startedAt, subAgent.completedAt);
48
+ return (_jsxs(Box, { flexDirection: "column", paddingLeft: 2, children: [_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: color, children: glyph }), _jsx(Text, { bold: true, color: "magenta", children: "\u21B3" }), _jsx(Text, { bold: true, children: label }), duration && _jsxs(Text, { dimColor: true, children: ["(", duration, ")"] }), _jsx(Text, { dimColor: true, children: expanded ? "▾" : "▸" })] }), expanded && (_jsxs(Box, { flexDirection: "column", paddingLeft: 3, marginTop: 1, children: [subAgent.input && (_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { dimColor: true, italic: true, wrap: "truncate-end", children: ["Task: ", subAgent.input.length > 120
49
+ ? subAgent.input.slice(0, 120) + "…"
50
+ : subAgent.input] }) })), renderSubAgentMessages(subAgent), subAgent.error && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "red", children: ["Error: ", subAgent.error] }) })), subAgent.output && subAgent.status === SubAgentStatus.SUB_AGENT_COMPLETED && (_jsxs(Box, { marginTop: 1, children: [_jsx(Text, { dimColor: true, children: "Result: " }), _jsx(Text, { wrap: "truncate-end", children: subAgent.output.length > 200
51
+ ? subAgent.output.slice(0, 200) + "…"
52
+ : subAgent.output })] }))] }))] }));
53
+ }
54
+ function renderSubAgentMessages(subAgent) {
55
+ const messages = subAgent.messages ?? [];
56
+ if (messages.length === 0)
57
+ return null;
58
+ const elements = [];
59
+ for (let i = 0; i < messages.length; i++) {
60
+ const msg = messages[i];
61
+ if (msg.type === MessageType.MESSAGE_TOOL)
62
+ continue;
63
+ const isEmptyAi = msg.type === MessageType.MESSAGE_AI && !msg.content.trim();
64
+ if (!isEmptyAi) {
65
+ elements.push(_jsx(Box, { marginBottom: 1, children: _jsx(MessageEntry, { message: msg }) }, `sub-m${i}`));
66
+ }
67
+ if (msg.type === MessageType.MESSAGE_AI && msg.toolCalls.length > 0) {
68
+ elements.push(_jsx(Box, { marginBottom: 1, children: _jsx(ToolCallGroup, { toolCalls: msg.toolCalls }) }, `sub-m${i}-tc`));
69
+ }
70
+ }
71
+ return _jsx(_Fragment, { children: elements });
72
+ }
73
+ //# sourceMappingURL=SubAgentBlock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SubAgentBlock.js","sourceRoot":"","sources":["../../src/components/SubAgentBlock.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { TodoItem } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/todo_pb";
2
+ /** Props for {@link TodoList}. */
3
+ export interface TodoListProps {
4
+ /** Map of todo item IDs to their current state, as provided by the execution status. */
5
+ readonly todos: {
6
+ readonly [key: string]: TodoItem;
7
+ };
8
+ }
9
+ /**
10
+ * Renders a sorted checklist of todo items in the terminal.
11
+ *
12
+ * Items are sorted by activity: in-progress first, then pending,
13
+ * completed, and cancelled. Terminal equivalent of the web SDK's
14
+ * TodoList component.
15
+ */
16
+ export declare function TodoList({ todos }: TodoListProps): import("react/jsx-runtime").JSX.Element | null;
17
+ //# sourceMappingURL=TodoList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TodoList.d.ts","sourceRoot":"","sources":["../../src/components/TodoList.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8DAA8D,CAAC;AAG7F,kCAAkC;AAClC,MAAM,WAAW,aAAa;IAC5B,wFAAwF;IACxF,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,QAAQ,CAAA;KAAE,CAAC;CACtD;AAgBD;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,EAAE,aAAa,kDA0ChD"}
@@ -0,0 +1,43 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useMemo } from "react";
3
+ import { Box, Text } from "ink";
4
+ import { TodoStatus } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
5
+ const STATUS_SORT_ORDER = new Map([
6
+ [TodoStatus.TODO_IN_PROGRESS, 0],
7
+ [TodoStatus.TODO_PENDING, 1],
8
+ [TodoStatus.TODO_COMPLETED, 2],
9
+ [TodoStatus.TODO_CANCELLED, 3],
10
+ ]);
11
+ const STATUS_DISPLAY = {
12
+ [TodoStatus.TODO_PENDING]: { glyph: "○", color: "gray" },
13
+ [TodoStatus.TODO_IN_PROGRESS]: { glyph: "●", color: "cyan" },
14
+ [TodoStatus.TODO_COMPLETED]: { glyph: "✓", color: "green" },
15
+ [TodoStatus.TODO_CANCELLED]: { glyph: "⊘", color: "gray" },
16
+ };
17
+ /**
18
+ * Renders a sorted checklist of todo items in the terminal.
19
+ *
20
+ * Items are sorted by activity: in-progress first, then pending,
21
+ * completed, and cancelled. Terminal equivalent of the web SDK's
22
+ * TodoList component.
23
+ */
24
+ export function TodoList({ todos }) {
25
+ const sortedTodos = useMemo(() => {
26
+ const items = Object.values(todos);
27
+ if (items.length === 0)
28
+ return [];
29
+ return items
30
+ .slice()
31
+ .sort((a, b) => (STATUS_SORT_ORDER.get(a.status) ?? 4) -
32
+ (STATUS_SORT_ORDER.get(b.status) ?? 4));
33
+ }, [todos]);
34
+ if (sortedTodos.length === 0)
35
+ return null;
36
+ const completed = sortedTodos.filter((t) => t.status === TodoStatus.TODO_COMPLETED).length;
37
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { gap: 1, marginBottom: 1, children: [_jsx(Text, { dimColor: true, bold: true, children: "Tasks" }), _jsxs(Text, { dimColor: true, children: ["(", completed, "/", sortedTodos.length, ")"] })] }), sortedTodos.map((item) => {
38
+ const display = STATUS_DISPLAY[item.status] ?? { glyph: "·", color: "gray" };
39
+ const isCancelled = item.status === TodoStatus.TODO_CANCELLED;
40
+ return (_jsxs(Box, { gap: 1, paddingLeft: 1, children: [_jsx(Text, { color: display.color, children: display.glyph }), _jsx(Text, { dimColor: isCancelled, strikethrough: isCancelled, children: item.content })] }, item.id));
41
+ })] }));
42
+ }
43
+ //# sourceMappingURL=TodoList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TodoList.js","sourceRoot":"","sources":["../../src/components/TodoList.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAEhC,OAAO,EAAE,UAAU,EAAE,MAAM,8DAA8D,CAAC;AAQ1F,MAAM,iBAAiB,GAAoC,IAAI,GAAG,CAAC;IACjE,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC,CAAC;IAChC,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC,CAAC;IAC5B,CAAC,UAAU,CAAC,cAAc,EAAE,CAAC,CAAC;IAC9B,CAAC,UAAU,CAAC,cAAc,EAAE,CAAC,CAAC;CAC/B,CAAC,CAAC;AAEH,MAAM,cAAc,GAAqD;IACvE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE;IACxD,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE;IAC5D,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE;IAC3D,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE;CAC3D,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,QAAQ,CAAC,EAAE,KAAK,EAAiB;IAC/C,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE;QAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAClC,OAAO,KAAK;aACT,KAAK,EAAE;aACP,IAAI,CACH,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACP,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACtC,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CACzC,CAAC;IACN,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAEZ,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAE1C,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,CAClC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,cAAc,CAC9C,CAAC,MAAM,CAAC;IAET,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACzB,MAAC,GAAG,IAAC,GAAG,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,aAC1B,KAAC,IAAI,IAAC,QAAQ,QAAC,IAAI,4BAAa,EAChC,MAAC,IAAI,IAAC,QAAQ,wBAAG,SAAS,OAAG,WAAW,CAAC,MAAM,SAAS,IACpD,EACL,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;gBACxB,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;gBAC7E,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,cAAc,CAAC;gBAC9D,OAAO,CACL,MAAC,GAAG,IAAe,GAAG,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,aACvC,KAAC,IAAI,IAAC,KAAK,EAAE,OAAO,CAAC,KAAK,YAAG,OAAO,CAAC,KAAK,GAAQ,EAClD,KAAC,IAAI,IACH,QAAQ,EAAE,WAAW,EACrB,aAAa,EAAE,WAAW,YAEzB,IAAI,CAAC,OAAO,GACR,KAPC,IAAI,CAAC,EAAE,CAQX,CACP,CAAC;YACJ,CAAC,CAAC,IACE,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { ToolCall } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/message_pb";
2
+ /** Props for {@link ToolCallGroup}. */
3
+ export interface ToolCallGroupProps {
4
+ /** Tool calls in this group, ordered by invocation time. */
5
+ readonly toolCalls: readonly ToolCall[];
6
+ /** Whether this group is currently focused for keyboard interaction. */
7
+ readonly isFocused?: boolean;
8
+ /** Whether to start in expanded mode (driven by Ctrl+O global toggle). */
9
+ readonly defaultExpanded?: boolean;
10
+ }
11
+ /**
12
+ * Renders a collapsible group of tool calls with an aggregate status.
13
+ *
14
+ * When collapsed, shows a summary line with tool count and status.
15
+ * When expanded, renders each tool call via {@link ToolCallItem}.
16
+ *
17
+ * Press Enter or Space to toggle expansion when `isFocused` is true.
18
+ */
19
+ export declare function ToolCallGroup({ toolCalls, isFocused, defaultExpanded, }: ToolCallGroupProps): import("react/jsx-runtime").JSX.Element;
20
+ //# sourceMappingURL=ToolCallGroup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolCallGroup.d.ts","sourceRoot":"","sources":["../../src/components/ToolCallGroup.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iEAAiE,CAAC;AAIhG,uCAAuC;AACvC,MAAM,WAAW,kBAAkB;IACjC,4DAA4D;IAC5D,QAAQ,CAAC,SAAS,EAAE,SAAS,QAAQ,EAAE,CAAC;IACxC,wEAAwE;IACxE,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,0EAA0E;IAC1E,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;CACpC;AA8BD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,EAC5B,SAAS,EACT,SAAiB,EACjB,eAAuB,GACxB,EAAE,kBAAkB,2CAmCpB"}