@stigmer/ink 3.1.1 → 3.1.3

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 (45) hide show
  1. package/app/SessionView.d.ts.map +1 -1
  2. package/app/SessionView.js +12 -1
  3. package/app/SessionView.js.map +1 -1
  4. package/components/FileChangeProgressBar.d.ts +46 -0
  5. package/components/FileChangeProgressBar.d.ts.map +1 -0
  6. package/components/FileChangeProgressBar.js +55 -0
  7. package/components/FileChangeProgressBar.js.map +1 -0
  8. package/components/FileReviewPrompt.d.ts +43 -0
  9. package/components/FileReviewPrompt.d.ts.map +1 -0
  10. package/components/FileReviewPrompt.js +172 -0
  11. package/components/FileReviewPrompt.js.map +1 -0
  12. package/components/FileReviewRecord.d.ts +18 -0
  13. package/components/FileReviewRecord.d.ts.map +1 -0
  14. package/components/FileReviewRecord.js +32 -0
  15. package/components/FileReviewRecord.js.map +1 -0
  16. package/components/MessageThread.d.ts +19 -7
  17. package/components/MessageThread.d.ts.map +1 -1
  18. package/components/MessageThread.js +145 -77
  19. package/components/MessageThread.js.map +1 -1
  20. package/components/ToolCallGroup.d.ts.map +1 -1
  21. package/components/ToolCallGroup.js +42 -2
  22. package/components/ToolCallGroup.js.map +1 -1
  23. package/components/ToolCallItem.d.ts.map +1 -1
  24. package/components/ToolCallItem.js +16 -1
  25. package/components/ToolCallItem.js.map +1 -1
  26. package/file-review.d.ts +48 -0
  27. package/file-review.d.ts.map +1 -0
  28. package/file-review.js +113 -0
  29. package/file-review.js.map +1 -0
  30. package/index.d.ts +4 -0
  31. package/index.d.ts.map +1 -1
  32. package/index.js +5 -0
  33. package/index.js.map +1 -1
  34. package/package.json +4 -4
  35. package/src/__tests__/file-change-progress.test.tsx +295 -0
  36. package/src/__tests__/file-review.test.tsx +496 -0
  37. package/src/app/SessionView.tsx +51 -3
  38. package/src/components/FileChangeProgressBar.tsx +122 -0
  39. package/src/components/FileReviewPrompt.tsx +328 -0
  40. package/src/components/FileReviewRecord.tsx +63 -0
  41. package/src/components/MessageThread.tsx +199 -96
  42. package/src/components/ToolCallGroup.tsx +50 -1
  43. package/src/components/ToolCallItem.tsx +25 -0
  44. package/src/file-review.ts +135 -0
  45. package/src/index.ts +17 -0
@@ -1 +1 @@
1
- {"version":3,"file":"SessionView.d.ts","sourceRoot":"","sources":["../../src/app/SessionView.tsx"],"names":[],"mappings":"AAUA,2DAA2D;AAC3D,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,MAAM,CAAC;AAE/C,qCAAqC;AACrC,MAAM,WAAW,gBAAgB;IAC/B,6CAA6C;IAC7C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,2DAA2D;IAC3D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB;;;;;;;;;OASG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,eAAe,CAAC;CACjC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,gBAAgB,2CA2IrE"}
1
+ {"version":3,"file":"SessionView.d.ts","sourceRoot":"","sources":["../../src/app/SessionView.tsx"],"names":[],"mappings":"AAYA,2DAA2D;AAC3D,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,MAAM,CAAC;AAE/C,qCAAqC;AACrC,MAAM,WAAW,gBAAgB;IAC/B,6CAA6C;IAC7C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,2DAA2D;IAC3D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB;;;;;;;;;OASG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,eAAe,CAAC;CACjC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,gBAAgB,2CAyLrE"}
@@ -8,6 +8,8 @@ import { TodoList } from "../components/TodoList.js";
8
8
  import { FollowUpInput } from "../components/FollowUpInput.js";
9
9
  import { UsageWidget } from "../components/UsageWidget.js";
10
10
  import { ExecutionProgress } from "../components/ExecutionProgress.js";
11
+ import { FileChangeProgressBar } from "../components/FileChangeProgressBar.js";
12
+ import { FileReviewPrompt } from "../components/FileReviewPrompt.js";
11
13
  /**
12
14
  * Full-featured session conversation view for the terminal.
13
15
  *
@@ -59,7 +61,16 @@ export function SessionView({ sessionId, org, mode }) {
59
61
  ];
60
62
  const activeTodos = conv.activeStreamExecution?.status?.todos;
61
63
  const subject = resolvedSubject(conv.session?.spec?.subject);
62
- return (_jsxs(Box, { flexDirection: "column", children: [subject && subject !== PENDING_SUBJECT && (_jsx(Box, { paddingLeft: 1, marginBottom: 1, children: _jsx(Text, { dimColor: true, bold: true, children: subject }) })), conv.isConnecting && (_jsxs(Box, { gap: 1, paddingLeft: 1, children: [_jsx(Text, { color: "cyan", children: _jsx(Spinner, { type: "dots" }) }), _jsx(Text, { dimColor: true, children: "Connecting to stream..." })] })), conv.isReconnecting && (_jsxs(Box, { gap: 1, paddingLeft: 1, children: [_jsx(Text, { color: "yellow", children: _jsx(Spinner, { type: "dots" }) }), _jsx(Text, { dimColor: true, children: "Reconnecting..." })] })), conv.streamError && (_jsxs(Box, { flexDirection: "column", paddingLeft: 1, marginBottom: 1, children: [_jsx(Text, { color: "yellow", bold: true, children: "Stream disconnected" }), _jsx(Text, { color: "red", dimColor: true, children: conv.streamError.message })] })), conv.activePhase != null && conv.activePhase !== 0 && (_jsx(ExecutionProgress, { phase: conv.activePhase })), _jsx(MessageThread, { executions: conv.completedExecutions, activeStreamExecution: conv.activeStreamExecution, pendingUserMessage: conv.pendingUserMessage, onApprovalSubmit: conv.submitApproval, submittingApprovalIds: conv.submittingApprovalIds, expandToolCalls: expandTools }), activeTodos && Object.keys(activeTodos).length > 0 && (_jsx(Box, { marginTop: 1, paddingLeft: 1, children: _jsx(TodoList, { todos: activeTodos }) })), conv.approvalError && (_jsx(Box, { paddingLeft: 1, children: _jsxs(Text, { color: "red", children: ["Approval error: ", conv.approvalError.message] }) })), conv.sendError && (_jsx(Box, { paddingLeft: 1, children: _jsxs(Text, { color: "red", children: ["Send error: ", conv.sendError.message] }) })), _jsx(UsageWidget, { executions: allExecutions }), conv.canSendFollowUp && (_jsx(Box, { paddingLeft: 1, children: _jsx(Text, { color: activeMode === "plan" ? "yellow" : "cyan", dimColor: true, children: activeMode === "plan"
64
+ return (_jsxs(Box, { flexDirection: "column", children: [subject && subject !== PENDING_SUBJECT && (_jsx(Box, { paddingLeft: 1, marginBottom: 1, children: _jsx(Text, { dimColor: true, bold: true, children: subject }) })), conv.isConnecting && (_jsxs(Box, { gap: 1, paddingLeft: 1, children: [_jsx(Text, { color: "cyan", children: _jsx(Spinner, { type: "dots" }) }), _jsx(Text, { dimColor: true, children: "Connecting to stream..." })] })), conv.isReconnecting && (_jsxs(Box, { gap: 1, paddingLeft: 1, children: [_jsx(Text, { color: "yellow", children: _jsx(Spinner, { type: "dots" }) }), _jsx(Text, { dimColor: true, children: "Reconnecting..." })] })), conv.streamError && (_jsxs(Box, { flexDirection: "column", paddingLeft: 1, marginBottom: 1, children: [_jsx(Text, { color: "yellow", bold: true, children: "Stream disconnected" }), _jsx(Text, { color: "red", dimColor: true, children: conv.streamError.message })] })), conv.activePhase != null &&
65
+ conv.activePhase !== 0 &&
66
+ conv.fileChangeSets.length === 0 && (
67
+ // Suppressed while a set awaits review: there is no execution phase
68
+ // for review (it lives on FileChangeSet.status), so the phase would
69
+ // otherwise read as an active "Running" spinner while the agent is
70
+ // idle awaiting the reviewer — the FileReviewPrompt is the honest cue.
71
+ _jsx(ExecutionProgress, { phase: conv.activePhase })), _jsx(MessageThread, { executions: conv.completedExecutions, activeStreamExecution: conv.activeStreamExecution, pendingUserMessage: conv.pendingUserMessage, onApprovalSubmit: conv.submitApproval, submittingApprovalIds: conv.submittingApprovalIds, expandToolCalls: expandTools, showFileReviewRecords: true }), activeTodos && Object.keys(activeTodos).length > 0 && (_jsx(Box, { marginTop: 1, paddingLeft: 1, children: _jsx(TodoList, { todos: activeTodos }) })), conv.approvalError && (_jsx(Box, { paddingLeft: 1, children: _jsxs(Text, { color: "red", children: ["Approval error: ", conv.approvalError.message] }) })), conv.sendError && (_jsx(Box, { paddingLeft: 1, children: _jsxs(Text, { color: "red", children: ["Send error: ", conv.sendError.message] }) })), _jsx(UsageWidget, { executions: allExecutions }), _jsx(FileChangeProgressBar, { progress: conv.fileChangeProgress, expanded: expandTools }), conv.fileChangeSets.length > 0 && (_jsxs(Box, { flexDirection: "column", children: [_jsx(FileReviewPrompt, { changeSet: conv.fileChangeSets[0], onSubmit: conv.submitFileDecision, submittingDecisionKeys: conv.submittingFileDecisionKeys, decisionErrors: conv.fileDecisionErrors,
72
+ // Single active decision surface: yield to a pending tool approval.
73
+ isActive: conv.pendingApprovals.length === 0 }), conv.fileChangeSets.length > 1 && (_jsx(Box, { paddingLeft: 2, children: _jsxs(Text, { dimColor: true, children: [conv.fileChangeSets.length - 1, " more awaiting review"] }) }))] })), conv.fileReviewError && (_jsx(Box, { paddingLeft: 1, children: _jsxs(Text, { color: "red", children: ["File review error: ", conv.fileReviewError.message] }) })), conv.canSendFollowUp && (_jsx(Box, { paddingLeft: 1, children: _jsx(Text, { color: activeMode === "plan" ? "yellow" : "cyan", dimColor: true, children: activeMode === "plan"
63
74
  ? "Plan mode — read-only analysis, no file mutations"
64
75
  : "Agent mode — full tool access" }) })), _jsx(FollowUpInput, { onSubmit: (message) => conv.sendFollowUp(message, { interactionMode: activeMode }), isSubmitting: conv.isSending, disabled: !conv.canSendFollowUp, mode: activeMode })] }));
65
76
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SessionView.js","sourceRoot":"","sources":["../../src/app/SessionView.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SessionView.js","sourceRoot":"","sources":["../../src/app/SessionView.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import type { FileChangeProgress } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/filereview_pb";
2
+ /** Props for {@link FileChangeProgressBar}. */
3
+ export interface FileChangeProgressBarProps {
4
+ /**
5
+ * The transient mid-run progress snapshot for the active turn (DD-32). Feed
6
+ * this from `useSessionConversation().fileChangeProgress`. Renders nothing when
7
+ * undefined or when no files have changed yet — the server clears it once the
8
+ * turn's change set leaves CAPTURING, so the strip disappears exactly when the
9
+ * decision surface (`FileReviewPrompt`) takes over.
10
+ */
11
+ readonly progress: FileChangeProgress | undefined;
12
+ /**
13
+ * Whether to reveal the per-file list. The compact one-line summary always
14
+ * shows; the list is progressive disclosure. `SessionView` binds this to its
15
+ * existing Ctrl+O "expand" toggle so no new keybinding is introduced. Defaults
16
+ * to `false`.
17
+ */
18
+ readonly expanded?: boolean;
19
+ }
20
+ /**
21
+ * The terminal analogue of the web's non-interactive "N files changing…" strip
22
+ * (`@stigmer/react` `FileChangeProgressBar`), for a turn that is still running.
23
+ *
24
+ * WHY IT EXISTS. The transcript streams per-edit tool rows, but a change made by
25
+ * a shell command (a `sed`, a build step) has no tool row, and there is no
26
+ * running net-of-many-edits rollup until the turn ends. This strip fills that
27
+ * gap: a compact, non-interactive count of the workspace delta accumulating
28
+ * during the turn, sitting where the `FileReviewPrompt` will later appear. The
29
+ * two are mutually exclusive per turn (progress shows while CAPTURING; the prompt
30
+ * once AWAITING_REVIEW), so the strip hands off cleanly to the prompt.
31
+ *
32
+ * NEVER A DECISION SURFACE. Progress is non-authoritative and carries no file
33
+ * bodies — it is never reviewable or decidable, and it owns no keyboard input.
34
+ * The reviewed diff is the turn-boundary candidate (`FileReviewPrompt`). A
35
+ * secret-like path is surfaced by name with its counts withheld (zeroed), so the
36
+ * `+N −M` stat renders nothing for it. The quiet/dim register (no border)
37
+ * distinguishes it from the loud, bordered decision prompt.
38
+ *
39
+ * @example
40
+ * ```tsx
41
+ * const conv = useSessionConversation(sessionId, org);
42
+ * <FileChangeProgressBar progress={conv.fileChangeProgress} expanded={expandTools} />
43
+ * ```
44
+ */
45
+ export declare function FileChangeProgressBar({ progress, expanded, }: FileChangeProgressBarProps): import("react/jsx-runtime").JSX.Element | null;
46
+ //# sourceMappingURL=FileChangeProgressBar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileChangeProgressBar.d.ts","sourceRoot":"","sources":["../../src/components/FileChangeProgressBar.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oEAAoE,CAAC;AAG7G,+CAA+C;AAC/C,MAAM,WAAW,0BAA0B;IACzC;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,GAAG,SAAS,CAAC;IAClD;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,QAAQ,EACR,QAAgB,GACjB,EAAE,0BAA0B,kDA0C5B"}
@@ -0,0 +1,55 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ import { kindLetter, progressEntryDisplayPath } from "../file-review.js";
4
+ /**
5
+ * The terminal analogue of the web's non-interactive "N files changing…" strip
6
+ * (`@stigmer/react` `FileChangeProgressBar`), for a turn that is still running.
7
+ *
8
+ * WHY IT EXISTS. The transcript streams per-edit tool rows, but a change made by
9
+ * a shell command (a `sed`, a build step) has no tool row, and there is no
10
+ * running net-of-many-edits rollup until the turn ends. This strip fills that
11
+ * gap: a compact, non-interactive count of the workspace delta accumulating
12
+ * during the turn, sitting where the `FileReviewPrompt` will later appear. The
13
+ * two are mutually exclusive per turn (progress shows while CAPTURING; the prompt
14
+ * once AWAITING_REVIEW), so the strip hands off cleanly to the prompt.
15
+ *
16
+ * NEVER A DECISION SURFACE. Progress is non-authoritative and carries no file
17
+ * bodies — it is never reviewable or decidable, and it owns no keyboard input.
18
+ * The reviewed diff is the turn-boundary candidate (`FileReviewPrompt`). A
19
+ * secret-like path is surfaced by name with its counts withheld (zeroed), so the
20
+ * `+N −M` stat renders nothing for it. The quiet/dim register (no border)
21
+ * distinguishes it from the loud, bordered decision prompt.
22
+ *
23
+ * @example
24
+ * ```tsx
25
+ * const conv = useSessionConversation(sessionId, org);
26
+ * <FileChangeProgressBar progress={conv.fileChangeProgress} expanded={expandTools} />
27
+ * ```
28
+ */
29
+ export function FileChangeProgressBar({ progress, expanded = false, }) {
30
+ if (!progress || progress.filesChanged === 0)
31
+ return null;
32
+ const { filesChanged, linesAdded, linesRemoved, entries } = progress;
33
+ const hiddenCount = filesChanged - entries.length;
34
+ return (_jsxs(Box, { flexDirection: "column", paddingLeft: 1, children: [_jsxs(Box, { gap: 1, children: [_jsx(Text, { dimColor: true, children: "\u270E" }), _jsxs(Text, { dimColor: true, children: [filesChanged, " file", filesChanged === 1 ? "" : "s", " changing\u2026"] }), _jsx(LineStats, { linesAdded: linesAdded, linesRemoved: linesRemoved })] }), expanded && (_jsxs(Box, { flexDirection: "column", paddingLeft: 2, children: [entries.map((entry, idx) => {
35
+ const path = progressEntryDisplayPath(entry);
36
+ return (_jsxs(Box, { gap: 1, children: [_jsx(Text, { dimColor: true, children: kindLetter(entry.kind) }), _jsx(Text, { dimColor: true, wrap: "truncate-end", children: path }), _jsx(LineStats, { linesAdded: entry.linesAdded, linesRemoved: entry.linesRemoved })] }, `${path}-${idx}`));
37
+ }), hiddenCount > 0 && (_jsx(Box, { children: _jsxs(Text, { dimColor: true, children: ["\u2026 and ", hiddenCount, " more"] }) }))] }))] }));
38
+ }
39
+ /**
40
+ * The `+N −M` stat for one file (or the whole turn), in the diff colour
41
+ * vocabulary. Renders nothing when both counts are zero — the honest signal that
42
+ * no count exists (binary or secret-withheld changes) — rather than a misleading
43
+ * `+0 -0`, matching the web `FileLineStats` contract.
44
+ *
45
+ * Kept module-local: this is the only consumer today. When `FileReviewPrompt`
46
+ * and `FileReviewRecord` gain `+N −M` (the deferred "CLI +N −M parity"
47
+ * follow-up), lift this into a shared ink atom (the analogue of `sdk/react`'s
48
+ * `FileReviewAtoms`) so the three surfaces cannot drift — do not copy it.
49
+ */
50
+ function LineStats({ linesAdded, linesRemoved, }) {
51
+ if (linesAdded === 0 && linesRemoved === 0)
52
+ return null;
53
+ return (_jsxs(Text, { children: [_jsxs(Text, { color: "green", children: ["+", linesAdded] }), _jsxs(Text, { color: "red", children: [" -", linesRemoved] })] }));
54
+ }
55
+ //# sourceMappingURL=FileChangeProgressBar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileChangeProgressBar.js","sourceRoot":"","sources":["../../src/components/FileChangeProgressBar.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAEhC,OAAO,EAAE,UAAU,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAqBzE;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,qBAAqB,CAAC,EACpC,QAAQ,EACR,QAAQ,GAAG,KAAK,GACW;IAC3B,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,YAAY,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAE1D,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC;IACrE,MAAM,WAAW,GAAG,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAElD,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,WAAW,EAAE,CAAC,aACxC,MAAC,GAAG,IAAC,GAAG,EAAE,CAAC,aACT,KAAC,IAAI,IAAC,QAAQ,6BAAS,EACvB,MAAC,IAAI,IAAC,QAAQ,mBACX,YAAY,WAAO,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,uBAC5C,EACP,KAAC,SAAS,IAAC,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,GAAI,IAC7D,EAEL,QAAQ,IAAI,CACX,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,WAAW,EAAE,CAAC,aACvC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;wBAC1B,MAAM,IAAI,GAAG,wBAAwB,CAAC,KAAK,CAAC,CAAC;wBAC7C,OAAO,CACL,MAAC,GAAG,IAAwB,GAAG,EAAE,CAAC,aAChC,KAAC,IAAI,IAAC,QAAQ,kBAAE,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,GAAQ,EAC9C,KAAC,IAAI,IAAC,QAAQ,QAAC,IAAI,EAAC,cAAc,YAC/B,IAAI,GACA,EACP,KAAC,SAAS,IACR,UAAU,EAAE,KAAK,CAAC,UAAU,EAC5B,YAAY,EAAE,KAAK,CAAC,YAAY,GAChC,KARM,GAAG,IAAI,IAAI,GAAG,EAAE,CASpB,CACP,CAAC;oBACJ,CAAC,CAAC,EACD,WAAW,GAAG,CAAC,IAAI,CAClB,KAAC,GAAG,cACF,MAAC,IAAI,IAAC,QAAQ,kCAAQ,WAAW,aAAa,GAC1C,CACP,IACG,CACP,IACG,CACP,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAS,SAAS,CAAC,EACjB,UAAU,EACV,YAAY,GAIb;IACC,IAAI,UAAU,KAAK,CAAC,IAAI,YAAY,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACxD,OAAO,CACL,MAAC,IAAI,eACH,MAAC,IAAI,IAAC,KAAK,EAAC,OAAO,kBAAG,UAAU,IAAQ,EACxC,MAAC,IAAI,IAAC,KAAK,EAAC,KAAK,mBAAI,YAAY,IAAQ,IACpC,CACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,43 @@
1
+ import type { FileChangeSet } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/filereview_pb";
2
+ import { FileDecisionAction } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
3
+ import { type FileDecisionOptions } from "@stigmer/react";
4
+ /** Props for {@link FileReviewPrompt}. */
5
+ export interface FileReviewPromptProps {
6
+ /** The AWAITING_REVIEW change set this prompt decides. */
7
+ readonly changeSet: FileChangeSet;
8
+ /**
9
+ * Submit a decision for this set (or one file within it). Bound to the active
10
+ * execution by the caller; the terminal analogue of the web dock's
11
+ * `submitFileDecision`.
12
+ */
13
+ readonly onSubmit: (changeSetId: string, action: FileDecisionAction, options?: FileDecisionOptions) => void;
14
+ /** Keys (via `fileDecisionKey`) currently being submitted — drives busy state. */
15
+ readonly submittingDecisionKeys?: ReadonlySet<string>;
16
+ /** Per-decision failures, keyed via `fileDecisionKey`. */
17
+ readonly decisionErrors?: ReadonlyMap<string, Error>;
18
+ /**
19
+ * Whether this prompt owns the keyboard. False renders a read-only view (no
20
+ * `useInput`) so exactly one decision surface is interactive at a time.
21
+ * Defaults to `true`.
22
+ */
23
+ readonly isActive?: boolean;
24
+ }
25
+ /**
26
+ * The terminal file-review decision surface — the linear-log analogue of the
27
+ * web's composer-docked `FileReviewDock`/`FileReviewCard`.
28
+ *
29
+ * Renders `N files awaiting review` and, gated by `changeSetReviewability`:
30
+ * bulk Approve/Keep all + Reject all (a complete set is approvable as-is; a
31
+ * binary-only set is kept with an acknowledgement; a blocked set can only be
32
+ * rejected in bulk), plus a per-file mode (`f`) for keeping/discarding each file
33
+ * — the only way to resolve a blocked or mixed set, since the server refuses a
34
+ * whole-set approve unless every file is complete. Decisions carry the same
35
+ * digests (`aggregate_digest` / `file_digest`) and `acknowledge_unreviewable`
36
+ * semantics as the web; no decision-model change.
37
+ *
38
+ * Keyboard: `a` approve/keep all · `r` reject all · `f` per-file mode; in
39
+ * per-file mode ↑/↓ move, `k` keep, `d` discard, `esc` back. Input is gated by
40
+ * `isActive` so only one decision surface owns the keyboard at a time.
41
+ */
42
+ export declare function FileReviewPrompt({ changeSet, onSubmit, submittingDecisionKeys, decisionErrors, isActive, }: FileReviewPromptProps): import("react/jsx-runtime").JSX.Element;
43
+ //# sourceMappingURL=FileReviewPrompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileReviewPrompt.d.ts","sourceRoot":"","sources":["../../src/components/FileReviewPrompt.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,aAAa,EACd,MAAM,oEAAoE,CAAC;AAC5E,OAAO,EACL,kBAAkB,EAEnB,MAAM,8DAA8D,CAAC;AACtE,OAAO,EAKL,KAAK,mBAAmB,EACzB,MAAM,gBAAgB,CAAC;AAGxB,0CAA0C;AAC1C,MAAM,WAAW,qBAAqB;IACpC,0DAA0D;IAC1D,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;IAClC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,CACjB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,kBAAkB,EAC1B,OAAO,CAAC,EAAE,mBAAmB,KAC1B,IAAI,CAAC;IACV,kFAAkF;IAClF,QAAQ,CAAC,sBAAsB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACtD,0DAA0D;IAC1D,QAAQ,CAAC,cAAc,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACrD;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AA2BD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,SAAS,EACT,QAAQ,EACR,sBAAsB,EACtB,cAAc,EACd,QAAe,GAChB,EAAE,qBAAqB,2CAmLvB"}
@@ -0,0 +1,172 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { useMemo, useState } from "react";
3
+ import { Box, Text, useInput } from "ink";
4
+ import { FileDecisionAction, FileDecisionScope, } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
5
+ import { changeSetReviewability, fileReviewability, deriveEffectiveVerdicts, } from "@stigmer/react";
6
+ import { blockReasonNote, changeDisplayPath, kindLetter } from "../file-review.js";
7
+ /**
8
+ * The bulk approve/reject verb labels for a set, mirroring the web card's
9
+ * `bulkLabels`: "Keep" for a binary-only set (its bytes are applied as-is),
10
+ * "Approve" otherwise; "remaining" when some files are already decided.
11
+ */
12
+ function bulkLabels(total, decided, binaryOnly) {
13
+ const verb = binaryOnly ? "Keep" : "Approve";
14
+ if (total <= 1)
15
+ return { approve: verb, reject: "Reject" };
16
+ if (decided > 0 && decided < total) {
17
+ return { approve: `${verb} remaining`, reject: "Reject remaining" };
18
+ }
19
+ return { approve: `${verb} all`, reject: "Reject all" };
20
+ }
21
+ /**
22
+ * The terminal file-review decision surface — the linear-log analogue of the
23
+ * web's composer-docked `FileReviewDock`/`FileReviewCard`.
24
+ *
25
+ * Renders `N files awaiting review` and, gated by `changeSetReviewability`:
26
+ * bulk Approve/Keep all + Reject all (a complete set is approvable as-is; a
27
+ * binary-only set is kept with an acknowledgement; a blocked set can only be
28
+ * rejected in bulk), plus a per-file mode (`f`) for keeping/discarding each file
29
+ * — the only way to resolve a blocked or mixed set, since the server refuses a
30
+ * whole-set approve unless every file is complete. Decisions carry the same
31
+ * digests (`aggregate_digest` / `file_digest`) and `acknowledge_unreviewable`
32
+ * semantics as the web; no decision-model change.
33
+ *
34
+ * Keyboard: `a` approve/keep all · `r` reject all · `f` per-file mode; in
35
+ * per-file mode ↑/↓ move, `k` keep, `d` discard, `esc` back. Input is gated by
36
+ * `isActive` so only one decision surface owns the keyboard at a time.
37
+ */
38
+ export function FileReviewPrompt({ changeSet, onSubmit, submittingDecisionKeys, decisionErrors, isActive = true, }) {
39
+ const [perFile, setPerFile] = useState(false);
40
+ const [selectedIndex, setSelectedIndex] = useState(0);
41
+ const changes = changeSet.changes;
42
+ const total = changes.length;
43
+ const reviewability = changeSetReviewability(changeSet);
44
+ const binaryOnly = reviewability === "binary-only";
45
+ const canBulkApprove = reviewability !== "blocked";
46
+ const verdicts = useMemo(() => deriveEffectiveVerdicts(changeSet), [changeSet]);
47
+ const decidedCount = useMemo(() => {
48
+ let n = 0;
49
+ for (const c of changes)
50
+ if (verdicts.has(c.id))
51
+ n++;
52
+ return n;
53
+ }, [changes, verdicts]);
54
+ const labels = bulkLabels(total, decidedCount, binaryOnly);
55
+ // Busy while any decision for THIS set is in flight (whole-set key or any
56
+ // per-file key). Blocks input to avoid a double-submit mid-request.
57
+ const busy = useMemo(() => {
58
+ if (!submittingDecisionKeys)
59
+ return false;
60
+ for (const key of submittingDecisionKeys) {
61
+ if (key === changeSet.id || key.startsWith(`${changeSet.id}:`))
62
+ return true;
63
+ }
64
+ return false;
65
+ }, [submittingDecisionKeys, changeSet.id]);
66
+ const errorText = useMemo(() => {
67
+ if (!decisionErrors)
68
+ return null;
69
+ for (const [key, err] of decisionErrors) {
70
+ if (key === changeSet.id || key.startsWith(`${changeSet.id}:`)) {
71
+ return err.message;
72
+ }
73
+ }
74
+ return null;
75
+ }, [decisionErrors, changeSet.id]);
76
+ const submitBulk = (action) => {
77
+ onSubmit(changeSet.id, action, {
78
+ scope: FileDecisionScope.CHANGE_SET,
79
+ expectedDigest: changeSet.aggregateDigest,
80
+ acknowledgeUnreviewable: action === FileDecisionAction.APPROVE && binaryOnly,
81
+ });
82
+ };
83
+ const submitFile = (change, action) => {
84
+ onSubmit(changeSet.id, action, {
85
+ scope: FileDecisionScope.FILE,
86
+ fileChangeId: change.id,
87
+ expectedDigest: change.fileDigest,
88
+ acknowledgeUnreviewable: action === FileDecisionAction.APPROVE &&
89
+ fileReviewability(change).kind === "binary",
90
+ });
91
+ };
92
+ // Rebuilt each render (cheap; 2-3 options) so the `run` closures always bind
93
+ // the current `changeSet`/`onSubmit` — a memo keyed on the labels would hold
94
+ // a stale submit closure when the set updates without changing its labels.
95
+ const bulkOptions = [];
96
+ if (canBulkApprove) {
97
+ bulkOptions.push({
98
+ label: labels.approve,
99
+ shortcut: "a",
100
+ color: "green",
101
+ run: () => submitBulk(FileDecisionAction.APPROVE),
102
+ });
103
+ }
104
+ bulkOptions.push({
105
+ label: labels.reject,
106
+ shortcut: "r",
107
+ color: "red",
108
+ run: () => submitBulk(FileDecisionAction.REJECT),
109
+ });
110
+ bulkOptions.push({
111
+ label: "Review files",
112
+ shortcut: "f",
113
+ color: "cyan",
114
+ run: () => {
115
+ setSelectedIndex(0);
116
+ setPerFile(true);
117
+ },
118
+ });
119
+ useInput((input, key) => {
120
+ if (busy)
121
+ return;
122
+ if (perFile) {
123
+ if (key.escape) {
124
+ setPerFile(false);
125
+ return;
126
+ }
127
+ if (key.upArrow) {
128
+ setSelectedIndex((i) => (i > 0 ? i - 1 : total - 1));
129
+ return;
130
+ }
131
+ if (key.downArrow) {
132
+ setSelectedIndex((i) => (i < total - 1 ? i + 1 : 0));
133
+ return;
134
+ }
135
+ const change = changes[selectedIndex];
136
+ if (!change)
137
+ return;
138
+ if (input === "k") {
139
+ // Keep is refused for a file with no reviewable/keepable bytes.
140
+ if (fileReviewability(change).kind !== "unavailable") {
141
+ submitFile(change, FileDecisionAction.APPROVE);
142
+ }
143
+ }
144
+ else if (input === "d") {
145
+ submitFile(change, FileDecisionAction.REJECT);
146
+ }
147
+ return;
148
+ }
149
+ // Bulk mode.
150
+ const match = bulkOptions.find((o) => o.shortcut === input.toLowerCase());
151
+ if (match)
152
+ match.run();
153
+ }, { isActive: isActive && !busy });
154
+ return (_jsxs(Box, { flexDirection: "column", paddingLeft: 2, paddingTop: 1, paddingBottom: 1, borderStyle: "round", borderColor: "cyan", children: [_jsx(Box, { gap: 1, children: _jsxs(Text, { color: "cyan", bold: true, children: ["\u270E ", total, " file", total === 1 ? "" : "s", " awaiting review"] }) }), perFile ? (_jsx(PerFileList, { changes: changes, verdicts: verdicts, selectedIndex: selectedIndex, interactive: isActive && !busy })) : (_jsx(Box, { gap: 2, marginTop: 1, paddingLeft: 2, children: bulkOptions.map((opt) => (_jsxs(Text, { color: opt.color, children: ["[", opt.shortcut, "] ", opt.label] }, opt.shortcut))) })), busy && (_jsx(Box, { paddingLeft: 2, marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Submitting..." }) })), errorText && (_jsx(Box, { paddingLeft: 2, marginTop: 1, children: _jsxs(Text, { color: "red", children: ["Decision failed: ", errorText] }) })), !isActive && !perFile && (_jsx(Box, { paddingLeft: 2, marginTop: 1, children: _jsx(Text, { dimColor: true, italic: true, children: "Resolve the pending approval first" }) }))] }));
155
+ }
156
+ /** The per-file review list: kind letter, path, verdict/keepability, and a hint. */
157
+ function PerFileList({ changes, verdicts, selectedIndex, interactive, }) {
158
+ return (_jsxs(Box, { flexDirection: "column", marginTop: 1, paddingLeft: 2, children: [changes.map((change, idx) => {
159
+ const selected = idx === selectedIndex;
160
+ const verdict = verdicts.get(change.id);
161
+ const note = blockReasonNote(change);
162
+ const decided = verdict === FileDecisionAction.APPROVE
163
+ ? "kept"
164
+ : verdict === FileDecisionAction.REJECT
165
+ ? "discarded"
166
+ : null;
167
+ return (_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: selected ? "cyan" : undefined, children: selected ? "▸" : " " }), _jsx(Text, { dimColor: true, children: kindLetter(change.kind) }), _jsx(Text, { color: selected ? "cyan" : undefined, bold: selected, wrap: "truncate-end", children: changeDisplayPath(change) }), decided && _jsxs(Text, { dimColor: true, children: ["(", decided, ")"] }), !decided && note && _jsxs(Text, { color: "yellow", children: ["\u2014 ", note] })] }, change.id));
168
+ }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: interactive
169
+ ? "↑/↓ move · [k] keep · [d] discard · [esc] back"
170
+ : "read-only" }) })] }));
171
+ }
172
+ //# sourceMappingURL=FileReviewPrompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileReviewPrompt.js","sourceRoot":"","sources":["../../src/components/FileReviewPrompt.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { FileChangeSet } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/filereview_pb";
2
+ /** Props for {@link FileReviewRecord}. */
3
+ export interface FileReviewRecordProps {
4
+ /** A settled (decided / reconciled / failed) change set to record. */
5
+ readonly fileChangeSet: FileChangeSet;
6
+ }
7
+ /**
8
+ * A read-only, append-only record of a SETTLED file-review change set — the
9
+ * terminal analogue of the web's in-thread `FileReviewRecordRow` (DD-27 D2).
10
+ *
11
+ * Its primary job is the no-stamped-row case: a set changed only via shell
12
+ * commands stamps no edit rows, so the per-row badges leave no trace and this
13
+ * record is the only evidence of what was reviewed and decided. Sets with
14
+ * stamped rows already carry their outcome on the (frozen) row badges; this
15
+ * record complements them with a one-line summary and file list.
16
+ */
17
+ export declare function FileReviewRecord({ fileChangeSet }: FileReviewRecordProps): import("react/jsx-runtime").JSX.Element;
18
+ //# sourceMappingURL=FileReviewRecord.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileReviewRecord.d.ts","sourceRoot":"","sources":["../../src/components/FileReviewRecord.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oEAAoE,CAAC;AAYxG,0CAA0C;AAC1C,MAAM,WAAW,qBAAqB;IACpC,sEAAsE;IACtE,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;CACvC;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,aAAa,EAAE,EAAE,qBAAqB,2CAgCxE"}
@@ -0,0 +1,32 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ import { FileChangeSetStatus, FileDecisionAction, } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
4
+ import { deriveEffectiveVerdicts } from "@stigmer/react";
5
+ import { changeDisplayPath, kindLetter, settledSummary, } from "../file-review.js";
6
+ /**
7
+ * A read-only, append-only record of a SETTLED file-review change set — the
8
+ * terminal analogue of the web's in-thread `FileReviewRecordRow` (DD-27 D2).
9
+ *
10
+ * Its primary job is the no-stamped-row case: a set changed only via shell
11
+ * commands stamps no edit rows, so the per-row badges leave no trace and this
12
+ * record is the only evidence of what was reviewed and decided. Sets with
13
+ * stamped rows already carry their outcome on the (frozen) row badges; this
14
+ * record complements them with a one-line summary and file list.
15
+ */
16
+ export function FileReviewRecord({ fileChangeSet }) {
17
+ const failed = fileChangeSet.status === FileChangeSetStatus.FAILED;
18
+ const verdicts = deriveEffectiveVerdicts(fileChangeSet);
19
+ const summary = failed ? "review failed" : settledSummary(fileChangeSet);
20
+ return (_jsxs(Box, { flexDirection: "column", paddingLeft: 2, children: [_jsxs(Box, { gap: 1, children: [_jsx(Text, { dimColor: true, children: "\u270E" }), _jsxs(Text, { dimColor: true, children: ["File review \u2014 ", summary] })] }), fileChangeSet.changes.map((change) => {
21
+ const verdict = verdicts.get(change.id);
22
+ const label = failed
23
+ ? null
24
+ : verdict === FileDecisionAction.APPROVE
25
+ ? "kept"
26
+ : verdict === FileDecisionAction.REJECT
27
+ ? "discarded"
28
+ : "not reviewed";
29
+ return (_jsxs(Box, { paddingLeft: 2, gap: 1, children: [_jsx(Text, { dimColor: true, children: kindLetter(change.kind) }), _jsx(Text, { dimColor: true, wrap: "truncate-end", children: changeDisplayPath(change) }), label && _jsxs(Text, { dimColor: true, children: ["(", label, ")"] })] }, change.id));
30
+ })] }));
31
+ }
32
+ //# sourceMappingURL=FileReviewRecord.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileReviewRecord.js","sourceRoot":"","sources":["../../src/components/FileReviewRecord.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAEhC,OAAO,EACL,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,8DAA8D,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EACL,iBAAiB,EACjB,UAAU,EACV,cAAc,GACf,MAAM,mBAAmB,CAAC;AAQ3B;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAAE,aAAa,EAAyB;IACvE,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,KAAK,mBAAmB,CAAC,MAAM,CAAC;IACnE,MAAM,QAAQ,GAAG,uBAAuB,CAAC,aAAa,CAAC,CAAC;IACxD,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;IAEzE,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,WAAW,EAAE,CAAC,aACxC,MAAC,GAAG,IAAC,GAAG,EAAE,CAAC,aACT,KAAC,IAAI,IAAC,QAAQ,6BAAS,EACvB,MAAC,IAAI,IAAC,QAAQ,0CAAgB,OAAO,IAAQ,IACzC,EACL,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;gBACpC,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACxC,MAAM,KAAK,GAAG,MAAM;oBAClB,CAAC,CAAC,IAAI;oBACN,CAAC,CAAC,OAAO,KAAK,kBAAkB,CAAC,OAAO;wBACtC,CAAC,CAAC,MAAM;wBACR,CAAC,CAAC,OAAO,KAAK,kBAAkB,CAAC,MAAM;4BACrC,CAAC,CAAC,WAAW;4BACb,CAAC,CAAC,cAAc,CAAC;gBACvB,OAAO,CACL,MAAC,GAAG,IAAiB,WAAW,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,aACzC,KAAC,IAAI,IAAC,QAAQ,kBAAE,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,GAAQ,EAC/C,KAAC,IAAI,IAAC,QAAQ,QAAC,IAAI,EAAC,cAAc,YAC/B,iBAAiB,CAAC,MAAM,CAAC,GACrB,EACN,KAAK,IAAI,MAAC,IAAI,IAAC,QAAQ,wBAAG,KAAK,SAAS,KALjC,MAAM,CAAC,EAAE,CAMb,CACP,CAAC;YACJ,CAAC,CAAC,IACE,CACP,CAAC;AACJ,CAAC"}
@@ -14,18 +14,30 @@ export interface MessageThreadProps {
14
14
  readonly submittingApprovalIds?: ReadonlySet<string>;
15
15
  /** Whether tool call groups should be rendered in expanded mode. Toggled via Ctrl+O. */
16
16
  readonly expandToolCalls?: boolean;
17
+ /**
18
+ * Whether to render a read-only settled record for each decided/reconciled/
19
+ * failed change set (the terminal analogue of the web's in-thread record,
20
+ * DD-27 D2). Off by default so bare consumers stay minimal; `SessionView`
21
+ * opts in. Pending (AWAITING_REVIEW) sets are never records here — their
22
+ * decision surface is the docked `FileReviewPrompt`.
23
+ */
24
+ readonly showFileReviewRecords?: boolean;
17
25
  }
18
26
  /**
19
27
  * Renders a continuous conversation thread from one or more
20
28
  * `AgentExecution` snapshots in the terminal.
21
29
  *
22
- * Composes {@link MessageEntry}, {@link ToolCallGroup},
23
- * {@link ExecutionProgress}, and {@link ApprovalPrompt} into a
24
- * scrolling terminal log.
30
+ * Composes {@link MessageEntry}, {@link ToolCallGroup}, {@link SubAgentBlock},
31
+ * {@link ExecutionProgress}, {@link ApprovalPrompt}, and (for settled change
32
+ * sets) {@link FileReviewRecord} into a scrolling terminal log.
25
33
  *
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.
34
+ * Completed executions are rendered via Ink's `<Static>` component so they are
35
+ * written once and don't re-render, keeping terminal output efficient for long
36
+ * conversations. The active execution renders live so its file-review row
37
+ * badges transition (Pending review → Kept/Discarded) in place, then freeze
38
+ * into `<Static>` when the execution reaches a terminal phase. The thread is
39
+ * wrapped in a `FileReviewContext` provider so every {@link ToolCallItem}
40
+ * can badge its stamped edit rows.
29
41
  */
30
- export declare function MessageThread({ executions, activeStreamExecution, pendingUserMessage, onApprovalSubmit, submittingApprovalIds, expandToolCalls, }: MessageThreadProps): import("react/jsx-runtime").JSX.Element;
42
+ export declare function MessageThread({ executions, activeStreamExecution, pendingUserMessage, onApprovalSubmit, submittingApprovalIds, expandToolCalls, showFileReviewRecords, }: MessageThreadProps): import("react/jsx-runtime").JSX.Element;
31
43
  //# sourceMappingURL=MessageThread.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"MessageThread.d.ts","sourceRoot":"","sources":["../../src/components/MessageThread.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6DAA6D,CAAC;AASlG,OAAO,EACL,cAAc,EAIf,MAAM,8DAA8D,CAAC;AActE,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;IACnC;;;;;;OAMG;IACH,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;CAC1C;AAuMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,CAAC,EAC5B,UAAU,EACV,qBAAqB,EACrB,kBAAkB,EAClB,gBAAgB,EAChB,qBAAqB,EACrB,eAAuB,EACvB,qBAA6B,GAC9B,EAAE,kBAAkB,2CA+CpB"}