@stigmer/react 3.1.4 → 3.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/execution/FileReviewContext.d.ts +15 -1
- package/execution/FileReviewContext.d.ts.map +1 -1
- package/execution/FileReviewContext.js +20 -1
- package/execution/FileReviewContext.js.map +1 -1
- package/execution/MessageThread.d.ts +65 -2
- package/execution/MessageThread.d.ts.map +1 -1
- package/execution/MessageThread.js +42 -23
- package/execution/MessageThread.js.map +1 -1
- package/execution/TodoCard.d.ts +8 -0
- package/execution/TodoCard.d.ts.map +1 -1
- package/execution/TodoCard.js +6 -4
- package/execution/TodoCard.js.map +1 -1
- package/execution/TodoList.d.ts +20 -1
- package/execution/TodoList.d.ts.map +1 -1
- package/execution/TodoList.js +9 -6
- package/execution/TodoList.js.map +1 -1
- package/execution/ToolCallDetail.d.ts +3 -2
- package/execution/ToolCallDetail.d.ts.map +1 -1
- package/execution/ToolCallDetail.js +49 -16
- package/execution/ToolCallDetail.js.map +1 -1
- package/execution/file-review-status.d.ts +15 -0
- package/execution/file-review-status.d.ts.map +1 -1
- package/execution/file-review-status.js +22 -0
- package/execution/file-review-status.js.map +1 -1
- package/execution/index.d.ts +5 -5
- package/execution/index.d.ts.map +1 -1
- package/execution/index.js +3 -3
- package/execution/index.js.map +1 -1
- package/github/useGitHubFileReader.d.ts +4 -2
- package/github/useGitHubFileReader.d.ts.map +1 -1
- package/github/useGitHubFileReader.js +16 -3
- package/github/useGitHubFileReader.js.map +1 -1
- package/github/useGitHubTreeLister.d.ts +2 -1
- package/github/useGitHubTreeLister.d.ts.map +1 -1
- package/github/useGitHubTreeLister.js +7 -3
- package/github/useGitHubTreeLister.js.map +1 -1
- package/index.d.ts +3 -3
- package/index.d.ts.map +1 -1
- package/index.js +3 -3
- package/index.js.map +1 -1
- package/internal/VirtualizedThread.d.ts +3 -2
- package/internal/VirtualizedThread.d.ts.map +1 -1
- package/internal/VirtualizedThread.js +3 -2
- package/internal/VirtualizedThread.js.map +1 -1
- package/package.json +4 -4
- package/session/SessionViewer.d.ts +11 -1
- package/session/SessionViewer.d.ts.map +1 -1
- package/session/SessionViewer.js +12 -5
- package/session/SessionViewer.js.map +1 -1
- package/session/index.d.ts +1 -0
- package/session/index.d.ts.map +1 -1
- package/session/index.js +1 -0
- package/session/index.js.map +1 -1
- package/session/useWorkspaceReadRefs.d.ts +45 -0
- package/session/useWorkspaceReadRefs.d.ts.map +1 -0
- package/session/useWorkspaceReadRefs.js +104 -0
- package/session/useWorkspaceReadRefs.js.map +1 -0
- package/src/execution/FileReviewContext.ts +27 -1
- package/src/execution/MessageThread.tsx +110 -22
- package/src/execution/TodoCard.tsx +20 -4
- package/src/execution/TodoList.tsx +26 -4
- package/src/execution/ToolCallDetail.tsx +69 -16
- package/src/execution/__tests__/ToolCallDetail.test.tsx +188 -2
- package/src/execution/__tests__/file-review-status.test.ts +47 -0
- package/src/execution/__tests__/message-thread-slots.test.tsx +463 -0
- package/src/execution/file-review-status.ts +24 -0
- package/src/execution/index.ts +13 -3
- package/src/github/__tests__/useGitHubFileReader.test.ts +35 -2
- package/src/github/__tests__/useGitHubTreeLister.test.ts +14 -0
- package/src/github/useGitHubFileReader.ts +19 -6
- package/src/github/useGitHubTreeLister.ts +7 -3
- package/src/index.ts +4 -0
- package/src/internal/VirtualizedThread.tsx +5 -1
- package/src/session/SessionViewer.tsx +27 -2
- package/src/session/__tests__/useWorkspaceReadRefs.test.ts +245 -0
- package/src/session/index.ts +2 -0
- package/src/session/useWorkspaceReadRefs.ts +118 -0
- package/src/workspace/FileViewer.tsx +144 -38
- package/src/workspace/WorkspaceFileReader.ts +21 -0
- package/src/workspace/__tests__/FileViewer.test.tsx +138 -3
- package/src/workspace/__tests__/useWorkspaceFileContent.test.tsx +20 -0
- package/src/workspace/__tests__/workspaceListingCache.test.ts +114 -0
- package/src/workspace/index.ts +4 -1
- package/src/workspace/useWorkspaceEntries.ts +11 -0
- package/src/workspace/useWorkspaceFileContent.ts +4 -1
- package/src/workspace/useWorkspaceFileSearch.ts +8 -3
- package/src/workspace/useWorkspaceFiles.ts +3 -2
- package/src/workspace/workspaceListingCache.ts +21 -7
- package/styles.css +1 -1
- package/workspace/FileViewer.d.ts +1 -1
- package/workspace/FileViewer.d.ts.map +1 -1
- package/workspace/FileViewer.js +55 -5
- package/workspace/FileViewer.js.map +1 -1
- package/workspace/WorkspaceFileReader.d.ts +17 -0
- package/workspace/WorkspaceFileReader.d.ts.map +1 -1
- package/workspace/WorkspaceFileReader.js +18 -0
- package/workspace/WorkspaceFileReader.js.map +1 -1
- package/workspace/index.d.ts +1 -1
- package/workspace/index.d.ts.map +1 -1
- package/workspace/index.js +1 -1
- package/workspace/index.js.map +1 -1
- package/workspace/useWorkspaceEntries.d.ts +11 -0
- package/workspace/useWorkspaceEntries.d.ts.map +1 -1
- package/workspace/useWorkspaceEntries.js.map +1 -1
- package/workspace/useWorkspaceFileContent.d.ts.map +1 -1
- package/workspace/useWorkspaceFileContent.js +4 -1
- package/workspace/useWorkspaceFileContent.js.map +1 -1
- package/workspace/useWorkspaceFileSearch.d.ts.map +1 -1
- package/workspace/useWorkspaceFileSearch.js +8 -3
- package/workspace/useWorkspaceFileSearch.js.map +1 -1
- package/workspace/useWorkspaceFiles.d.ts +2 -1
- package/workspace/useWorkspaceFiles.d.ts.map +1 -1
- package/workspace/useWorkspaceFiles.js +3 -2
- package/workspace/useWorkspaceFiles.js.map +1 -1
- package/workspace/workspaceListingCache.d.ts +1 -1
- package/workspace/workspaceListingCache.d.ts.map +1 -1
- package/workspace/workspaceListingCache.js +20 -7
- package/workspace/workspaceListingCache.js.map +1 -1
package/session/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/session/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/session/index.ts"],"names":[],"mappings":"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"}
|
package/session/index.js
CHANGED
|
@@ -7,6 +7,7 @@ export { useSessionExecutions } from "./useSessionExecutions.js";
|
|
|
7
7
|
export { useSessionConversation } from "./useSessionConversation.js";
|
|
8
8
|
export { useSessionArtifacts, artifactKey } from "./useSessionArtifacts.js";
|
|
9
9
|
export { useSessionWriteBacks } from "./useSessionWriteBacks.js";
|
|
10
|
+
export { useWorkspaceReadRefs } from "./useWorkspaceReadRefs.js";
|
|
10
11
|
export { useSessionFileChanges } from "./useSessionFileChanges.js";
|
|
11
12
|
export { useSessionUsage } from "./useSessionUsage.js";
|
|
12
13
|
export { useAgentRefFromSession } from "./useAgentRefFromSession.js";
|
package/session/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/session/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAMzF,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAQzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGzD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAG7C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAMrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAGjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAMrE,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAM5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAMjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAGnE,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAMvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAGrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAM3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAM7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAG3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAG7D,OAAO,EACL,cAAc,EACd,cAAc,EACd,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAMpB,OAAO,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAGpF,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAMzD,wDAAwD;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,oEAAoE;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGzD,6EAA6E;AAC7E,uEAAuE;AACvE,4CAA4C;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAMvD,wEAAwE;AACxE,oEAAoE;AACpE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAG/D,8EAA8E;AAC9E,yDAAyD;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,OAAO,EACL,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAE5B,yEAAyE;AACzE,iFAAiF;AACjF,OAAO,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAKpE,0EAA0E;AAC1E,qCAAqC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAM7C,oDAAoD;AACpD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/session/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAMzF,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAQzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGzD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAG7C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAMrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAGjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAMrE,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAM5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAMjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAGnE,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAMvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAGrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAM3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAM7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAG3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAG7D,OAAO,EACL,cAAc,EACd,cAAc,EACd,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAMpB,OAAO,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAGpF,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAMzD,wDAAwD;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,oEAAoE;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGzD,6EAA6E;AAC7E,uEAAuE;AACvE,4CAA4C;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAMvD,wEAAwE;AACxE,oEAAoE;AACpE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAG/D,8EAA8E;AAC9E,yDAAyD;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,OAAO,EACL,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAE5B,yEAAyE;AACzE,iFAAiF;AACjF,OAAO,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAKpE,0EAA0E;AAC1E,qCAAqC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAM7C,oDAAoD;AACpD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { AgentExecution } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
|
|
2
|
+
import type { WorkspaceEntry } from "../workspace/useWorkspaceEntries.js";
|
|
3
|
+
/**
|
|
4
|
+
* Pure derivation hook that projects the session's workspace write-backs onto
|
|
5
|
+
* its workspace entries as per-entry read refs.
|
|
6
|
+
*
|
|
7
|
+
* The agent's file changes land on a write-back branch (`stigmer/<id>`), not
|
|
8
|
+
* the branch the session was configured with — so read-side surfaces (file
|
|
9
|
+
* viewer, tree listing, name search) pointed at the configured branch would
|
|
10
|
+
* 404 on agent-created files and silently show stale content for modified
|
|
11
|
+
* ones. This hook returns the entries with `readRef` set to the latest
|
|
12
|
+
* write-back commit SHA, which those surfaces resolve in preference to
|
|
13
|
+
* `gitBranch`. A commit SHA (not the branch name) so reads are immutable-ref
|
|
14
|
+
* exact, immune to branch eventual-consistency.
|
|
15
|
+
*
|
|
16
|
+
* **Ref selection:** the latest write-back with a non-empty `commitSha` wins
|
|
17
|
+
* per workspace entry, across all executions in chronological order. FAILED
|
|
18
|
+
* write-back records carry no SHA and never regress the ref.
|
|
19
|
+
*
|
|
20
|
+
* **Entry matching** mirrors the runner's `WriteBackCoordinator.resolveEntry`:
|
|
21
|
+
* single-entry sessions provision with an empty `workspaceEntryName`, so when
|
|
22
|
+
* the session has exactly one git entry every write-back applies to it;
|
|
23
|
+
* multi-entry sessions match strictly by name.
|
|
24
|
+
*
|
|
25
|
+
* **Reference stability (DD-010):** the decorated array is memoized on the
|
|
26
|
+
* entries array and a value signature of the derived refs — streaming frames
|
|
27
|
+
* that don't change any write-back SHA return the identical array, so
|
|
28
|
+
* downstream listing/content effects never churn.
|
|
29
|
+
*
|
|
30
|
+
* @param executions - All executions for the session, in chronological order
|
|
31
|
+
* (same input contract as {@link useSessionWriteBacks}).
|
|
32
|
+
* @param entries - The session's workspace entries. Returned as-is (same
|
|
33
|
+
* reference) when no entry derives a ref.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```tsx
|
|
37
|
+
* const surfaceEntries = useWorkspaceReadRefs(flow.allExecutions, flow.workspace.entries);
|
|
38
|
+
* <WorkspaceSurface entries={surfaceEntries} ... />
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @see useSessionWriteBacks — the write-back list this projection derives from
|
|
42
|
+
* @see WorkspaceEntry.readRef — the field this hook populates
|
|
43
|
+
*/
|
|
44
|
+
export declare function useWorkspaceReadRefs(executions: readonly AgentExecution[], entries: readonly WorkspaceEntry[]): readonly WorkspaceEntry[];
|
|
45
|
+
//# sourceMappingURL=useWorkspaceReadRefs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useWorkspaceReadRefs.d.ts","sourceRoot":"","sources":["../../src/session/useWorkspaceReadRefs.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6DAA6D,CAAC;AAClG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AAE1E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,SAAS,cAAc,EAAE,EACrC,OAAO,EAAE,SAAS,cAAc,EAAE,GACjC,SAAS,cAAc,EAAE,CA0B3B"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useMemo } from "react";
|
|
3
|
+
/**
|
|
4
|
+
* Pure derivation hook that projects the session's workspace write-backs onto
|
|
5
|
+
* its workspace entries as per-entry read refs.
|
|
6
|
+
*
|
|
7
|
+
* The agent's file changes land on a write-back branch (`stigmer/<id>`), not
|
|
8
|
+
* the branch the session was configured with — so read-side surfaces (file
|
|
9
|
+
* viewer, tree listing, name search) pointed at the configured branch would
|
|
10
|
+
* 404 on agent-created files and silently show stale content for modified
|
|
11
|
+
* ones. This hook returns the entries with `readRef` set to the latest
|
|
12
|
+
* write-back commit SHA, which those surfaces resolve in preference to
|
|
13
|
+
* `gitBranch`. A commit SHA (not the branch name) so reads are immutable-ref
|
|
14
|
+
* exact, immune to branch eventual-consistency.
|
|
15
|
+
*
|
|
16
|
+
* **Ref selection:** the latest write-back with a non-empty `commitSha` wins
|
|
17
|
+
* per workspace entry, across all executions in chronological order. FAILED
|
|
18
|
+
* write-back records carry no SHA and never regress the ref.
|
|
19
|
+
*
|
|
20
|
+
* **Entry matching** mirrors the runner's `WriteBackCoordinator.resolveEntry`:
|
|
21
|
+
* single-entry sessions provision with an empty `workspaceEntryName`, so when
|
|
22
|
+
* the session has exactly one git entry every write-back applies to it;
|
|
23
|
+
* multi-entry sessions match strictly by name.
|
|
24
|
+
*
|
|
25
|
+
* **Reference stability (DD-010):** the decorated array is memoized on the
|
|
26
|
+
* entries array and a value signature of the derived refs — streaming frames
|
|
27
|
+
* that don't change any write-back SHA return the identical array, so
|
|
28
|
+
* downstream listing/content effects never churn.
|
|
29
|
+
*
|
|
30
|
+
* @param executions - All executions for the session, in chronological order
|
|
31
|
+
* (same input contract as {@link useSessionWriteBacks}).
|
|
32
|
+
* @param entries - The session's workspace entries. Returned as-is (same
|
|
33
|
+
* reference) when no entry derives a ref.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```tsx
|
|
37
|
+
* const surfaceEntries = useWorkspaceReadRefs(flow.allExecutions, flow.workspace.entries);
|
|
38
|
+
* <WorkspaceSurface entries={surfaceEntries} ... />
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @see useSessionWriteBacks — the write-back list this projection derives from
|
|
42
|
+
* @see WorkspaceEntry.readRef — the field this hook populates
|
|
43
|
+
*/
|
|
44
|
+
export function useWorkspaceReadRefs(executions, entries) {
|
|
45
|
+
// Cheap per-render pass; memoizing on `executions` would defeat the point —
|
|
46
|
+
// its identity changes every streaming frame while the SHAs rarely do. The
|
|
47
|
+
// signature collapses those frames into a stable memo key.
|
|
48
|
+
const refByName = collectLatestShas(executions);
|
|
49
|
+
const signature = [...refByName]
|
|
50
|
+
.map(([name, sha]) => `${name}\u0001${sha}`)
|
|
51
|
+
.join("\u0000");
|
|
52
|
+
return useMemo(() => {
|
|
53
|
+
if (refByName.size === 0)
|
|
54
|
+
return entries;
|
|
55
|
+
const gitEntries = entries.filter((entry) => entry.type === "git");
|
|
56
|
+
let decorated = false;
|
|
57
|
+
const next = entries.map((entry) => {
|
|
58
|
+
const readRef = resolveReadRef(entry, gitEntries.length, refByName);
|
|
59
|
+
if (!readRef || readRef === entry.readRef)
|
|
60
|
+
return entry;
|
|
61
|
+
decorated = true;
|
|
62
|
+
return { ...entry, readRef };
|
|
63
|
+
});
|
|
64
|
+
return decorated ? next : entries;
|
|
65
|
+
// `signature` is the value-equality key for `refByName` (rebuilt each
|
|
66
|
+
// render); the map itself must stay out of the deps.
|
|
67
|
+
}, [entries, signature]);
|
|
68
|
+
}
|
|
69
|
+
/** Latest non-empty write-back commit SHA per workspace entry name. */
|
|
70
|
+
function collectLatestShas(executions) {
|
|
71
|
+
const refByName = new Map();
|
|
72
|
+
for (const execution of executions) {
|
|
73
|
+
for (const wb of execution.status?.workspaceWriteBacks ?? []) {
|
|
74
|
+
if (wb.commitSha)
|
|
75
|
+
refByName.set(wb.workspaceEntryName, wb.commitSha);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return refByName;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* The write-back SHA for one entry, honoring the runner's single-entry
|
|
82
|
+
* convention: with exactly one git entry, any write-back applies to it
|
|
83
|
+
* (single-entry sessions write back under an empty entry name).
|
|
84
|
+
*/
|
|
85
|
+
function resolveReadRef(entry, gitEntryCount, refByName) {
|
|
86
|
+
if (entry.type !== "git")
|
|
87
|
+
return undefined;
|
|
88
|
+
const byName = refByName.get(entry.name);
|
|
89
|
+
if (byName)
|
|
90
|
+
return byName;
|
|
91
|
+
if (gitEntryCount === 1) {
|
|
92
|
+
// Single-entry sessions write back under an empty entry name; a lone
|
|
93
|
+
// unambiguous name is equally safe to claim. Anything else (multiple
|
|
94
|
+
// names against one entry) is malformed status data — decorate nothing
|
|
95
|
+
// rather than guess.
|
|
96
|
+
const unnamed = refByName.get("");
|
|
97
|
+
if (unnamed)
|
|
98
|
+
return unnamed;
|
|
99
|
+
if (refByName.size === 1)
|
|
100
|
+
return refByName.values().next().value;
|
|
101
|
+
}
|
|
102
|
+
return undefined;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=useWorkspaceReadRefs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useWorkspaceReadRefs.js","sourceRoot":"","sources":["../../src/session/useWorkspaceReadRefs.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAIhC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,MAAM,UAAU,oBAAoB,CAClC,UAAqC,EACrC,OAAkC;IAElC,4EAA4E;IAC5E,2EAA2E;IAC3E,2DAA2D;IAC3D,MAAM,SAAS,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAChD,MAAM,SAAS,GAAG,CAAC,GAAG,SAAS,CAAC;SAC7B,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,SAAS,GAAG,EAAE,CAAC;SAC3C,IAAI,CAAC,QAAQ,CAAC,CAAC;IAElB,OAAO,OAAO,CAAC,GAAG,EAAE;QAClB,IAAI,SAAS,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO,OAAO,CAAC;QAEzC,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC;QACnE,IAAI,SAAS,GAAG,KAAK,CAAC;QAEtB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YACjC,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,EAAE,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;YACpE,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,KAAK,CAAC,OAAO;gBAAE,OAAO,KAAK,CAAC;YACxD,SAAS,GAAG,IAAI,CAAC;YACjB,OAAO,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,OAAO,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;QAClC,sEAAsE;QACtE,qDAAqD;IACvD,CAAC,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;AAC3B,CAAC;AAED,uEAAuE;AACvE,SAAS,iBAAiB,CACxB,UAAqC;IAErC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC5C,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,KAAK,MAAM,EAAE,IAAI,SAAS,CAAC,MAAM,EAAE,mBAAmB,IAAI,EAAE,EAAE,CAAC;YAC7D,IAAI,EAAE,CAAC,SAAS;gBAAE,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACH,SAAS,cAAc,CACrB,KAAqB,EACrB,aAAqB,EACrB,SAAsC;IAEtC,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK;QAAE,OAAO,SAAS,CAAC;IAE3C,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACzC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,IAAI,aAAa,KAAK,CAAC,EAAE,CAAC;QACxB,qEAAqE;QACrE,qEAAqE;QACrE,uEAAuE;QACvE,qBAAqB;QACrB,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClC,IAAI,OAAO;YAAE,OAAO,OAAO,CAAC;QAC5B,IAAI,SAAS,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;IACnE,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { createContext, useContext } from "react";
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
CapturedFileChange,
|
|
4
|
+
FileChangeSet,
|
|
5
|
+
} from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/filereview_pb";
|
|
3
6
|
import {
|
|
7
|
+
fileReviewRowChange,
|
|
4
8
|
fileReviewRowState,
|
|
5
9
|
type FileReviewRowState,
|
|
6
10
|
} from "./file-review-status.js";
|
|
@@ -51,3 +55,25 @@ export function useFileReviewRowState(
|
|
|
51
55
|
if (!fileChangeSetId) return null;
|
|
52
56
|
return fileReviewRowState(changeSetsById.get(fileChangeSetId), rowPath);
|
|
53
57
|
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* The captured change a stamped tool row should render as its inline diff, or
|
|
61
|
+
* `null` to keep the row's own content view (unstamped row, unknown set, path
|
|
62
|
+
* miss, or a non-reviewable change — see {@link fileReviewRowChange} for the
|
|
63
|
+
* honest-degradation rules).
|
|
64
|
+
*
|
|
65
|
+
* The diff sibling of {@link useFileReviewRowState}: both read the same
|
|
66
|
+
* context entry through the same path matcher, so a row's badge and its diff
|
|
67
|
+
* always describe the same captured artifact.
|
|
68
|
+
*
|
|
69
|
+
* @param fileChangeSetId The row's `ToolCall.file_change_set_id` (may be "").
|
|
70
|
+
* @param rowPath The row's file path (the presenter's primary arg).
|
|
71
|
+
*/
|
|
72
|
+
export function useFileReviewRowChange(
|
|
73
|
+
fileChangeSetId: string,
|
|
74
|
+
rowPath: string | null,
|
|
75
|
+
): CapturedFileChange | null {
|
|
76
|
+
const { changeSetsById } = useContext(FileReviewContext);
|
|
77
|
+
if (!fileChangeSetId) return null;
|
|
78
|
+
return fileReviewRowChange(changeSetsById.get(fileChangeSetId), rowPath);
|
|
79
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { lazy, memo, Suspense, useCallback, useMemo, useState } from "react";
|
|
3
|
+
import { lazy, memo, Suspense, useCallback, useMemo, useState, type ComponentType } from "react";
|
|
4
4
|
import { create } from "@bufbuild/protobuf";
|
|
5
5
|
import type { AgentExecution } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
|
|
6
6
|
import type { AgentMessage, ToolCall } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/message_pb";
|
|
@@ -21,18 +21,19 @@ import type { WorkspaceEntry } from "@stigmer/protos/ai/stigmer/agentic/session/
|
|
|
21
21
|
import { displayFileChangeSets } from "@stigmer/sdk";
|
|
22
22
|
import { cn } from "@stigmer/theme";
|
|
23
23
|
import { isTerminalPhase } from "./execution-phases.js";
|
|
24
|
-
import { MessageEntry } from "./MessageEntry.js";
|
|
24
|
+
import { MessageEntry, type MessageEntryProps } from "./MessageEntry.js";
|
|
25
25
|
import { ToolCallGroup } from "./ToolCallGroup.js";
|
|
26
26
|
import { SubAgentSection } from "./SubAgentSection.js";
|
|
27
27
|
import { ExecutionPhaseBadge } from "./ExecutionPhaseBadge.js";
|
|
28
|
-
import { SetupProgress } from "./SetupProgress.js";
|
|
29
|
-
import { ApprovalCard } from "./ApprovalCard.js";
|
|
28
|
+
import { SetupProgress, type SetupProgressProps } from "./SetupProgress.js";
|
|
29
|
+
import { ApprovalCard, type ApprovalCardProps } from "./ApprovalCard.js";
|
|
30
30
|
import { FileReviewCard } from "./FileReviewCard.js";
|
|
31
31
|
import { SummarizationCard } from "./SummarizationCard.js";
|
|
32
|
-
import { PlanCompletionCard } from "./PlanCompletionCard.js";
|
|
33
|
-
import { PlanArtifactCard } from "./PlanArtifactCard.js";
|
|
34
|
-
import { PlanStreamingCard } from "./PlanStreamingCard.js";
|
|
35
|
-
import { TodoCard } from "./TodoCard.js";
|
|
32
|
+
import { PlanCompletionCard, type PlanCompletionCardProps } from "./PlanCompletionCard.js";
|
|
33
|
+
import { PlanArtifactCard, type PlanArtifactCardProps } from "./PlanArtifactCard.js";
|
|
34
|
+
import { PlanStreamingCard, type PlanStreamingCardProps } from "./PlanStreamingCard.js";
|
|
35
|
+
import { TodoCard, type TodoCardProps } from "./TodoCard.js";
|
|
36
|
+
import type { TodoRowProps } from "./TodoList.js";
|
|
36
37
|
import { findPlanArtifact } from "../library/detect-plan-artifact.js";
|
|
37
38
|
import { findStreamingPlan } from "../library/detect-streaming-plan.js";
|
|
38
39
|
import type { SummarizationEventView } from "./useContextWindow.js";
|
|
@@ -63,6 +64,49 @@ const EMPTY_APPROVALS: readonly PendingApproval[] = [];
|
|
|
63
64
|
const EMPTY_SUBMITTING_IDS: ReadonlySet<string> = new Set();
|
|
64
65
|
const EMPTY_APPROVAL_ERRORS: ReadonlyMap<string, Error> = new Map();
|
|
65
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Component overrides for the chrome {@link MessageThread} renders — the
|
|
69
|
+
* adaptation surface for hosts whose design system needs different
|
|
70
|
+
* *structure*, not just different `--stgm-*` token values (stigmer#187).
|
|
71
|
+
*
|
|
72
|
+
* Each slot is keyed by the built-in component it replaces and receives
|
|
73
|
+
* exactly that component's exported props interface, so an override can
|
|
74
|
+
* always delegate to the built-in for the cases it does not customize
|
|
75
|
+
* (e.g. a `MessageEntry` slot that restyles `MESSAGE_HUMAN` bubbles and
|
|
76
|
+
* renders the default `MessageEntry` for everything else).
|
|
77
|
+
*
|
|
78
|
+
* Define slot components at module level (or memoize them). The thread's
|
|
79
|
+
* rows rely on `React.memo` + structural sharing to skip re-renders during
|
|
80
|
+
* streaming (DD-009/DD-010); a slot component recreated on every host
|
|
81
|
+
* render defeats that for its rows.
|
|
82
|
+
*/
|
|
83
|
+
export interface MessageThreadSlots {
|
|
84
|
+
/**
|
|
85
|
+
* All message bubbles — human, assistant, thinking, and system entries.
|
|
86
|
+
* Also wraps the failed-send bubble (the inline Retry chrome around it
|
|
87
|
+
* stays built-in).
|
|
88
|
+
*/
|
|
89
|
+
readonly MessageEntry?: ComponentType<MessageEntryProps>;
|
|
90
|
+
/** The HITL tool-approval gate card. */
|
|
91
|
+
readonly ApprovalCard?: ComponentType<ApprovalCardProps>;
|
|
92
|
+
/** The collapsible in-thread to-dos card. */
|
|
93
|
+
readonly TodoCard?: ComponentType<TodoCardProps>;
|
|
94
|
+
/**
|
|
95
|
+
* One to-do row inside the built-in {@link TodoCard}'s list. Ignored
|
|
96
|
+
* when `TodoCard` is also overridden (the replacement receives it via
|
|
97
|
+
* {@link TodoCardProps.TodoRow} and may forward or ignore it).
|
|
98
|
+
*/
|
|
99
|
+
readonly TodoRow?: ComponentType<TodoRowProps>;
|
|
100
|
+
/** Completed Plan turn that published a plan artifact. */
|
|
101
|
+
readonly PlanArtifactCard?: ComponentType<PlanArtifactCardProps>;
|
|
102
|
+
/** Completed Plan turn without an artifact — the bare Implement CTA. */
|
|
103
|
+
readonly PlanCompletionCard?: ComponentType<PlanCompletionCardProps>;
|
|
104
|
+
/** Live stand-in card while a Plan turn is writing its document. */
|
|
105
|
+
readonly PlanStreamingCard?: ComponentType<PlanStreamingCardProps>;
|
|
106
|
+
/** Pre-first-token setup / "Thinking…" indicator. */
|
|
107
|
+
readonly SetupProgress?: ComponentType<SetupProgressProps>;
|
|
108
|
+
}
|
|
109
|
+
|
|
66
110
|
/** Props for {@link MessageThread}. */
|
|
67
111
|
export interface MessageThreadProps {
|
|
68
112
|
/** Completed executions in chronological order. */
|
|
@@ -261,6 +305,12 @@ export interface MessageThreadProps {
|
|
|
261
305
|
* existing consumers see no layout change.
|
|
262
306
|
*/
|
|
263
307
|
readonly contentColumn?: ThreadContentColumn;
|
|
308
|
+
/**
|
|
309
|
+
* Component overrides for the thread's chrome — see
|
|
310
|
+
* {@link MessageThreadSlots}. Omitted slots render the built-ins;
|
|
311
|
+
* omitting the prop entirely changes nothing (DD-011).
|
|
312
|
+
*/
|
|
313
|
+
readonly slots?: MessageThreadSlots;
|
|
264
314
|
}
|
|
265
315
|
|
|
266
316
|
/** Reading-column alignment for {@link MessageThread} content. */
|
|
@@ -1020,6 +1070,7 @@ export function MessageThread({
|
|
|
1020
1070
|
planActionsDisabled,
|
|
1021
1071
|
planBuildPending,
|
|
1022
1072
|
contentColumn,
|
|
1073
|
+
slots,
|
|
1023
1074
|
}: MessageThreadProps) {
|
|
1024
1075
|
useRenderTracer("MessageThread", { executions, activeStreamExecution });
|
|
1025
1076
|
|
|
@@ -1124,6 +1175,7 @@ export function MessageThread({
|
|
|
1124
1175
|
onRetrySend={onRetrySend}
|
|
1125
1176
|
onRetryExecution={onRetryExecution}
|
|
1126
1177
|
onEditMessage={onEditMessage}
|
|
1178
|
+
slots={slots}
|
|
1127
1179
|
/>
|
|
1128
1180
|
</Suspense>
|
|
1129
1181
|
</div>
|
|
@@ -1152,6 +1204,7 @@ export function MessageThread({
|
|
|
1152
1204
|
onRetrySend={onRetrySend}
|
|
1153
1205
|
onRetryExecution={onRetryExecution}
|
|
1154
1206
|
onEditMessage={onEditMessage}
|
|
1207
|
+
slots={slots}
|
|
1155
1208
|
/>
|
|
1156
1209
|
);
|
|
1157
1210
|
}
|
|
@@ -1186,6 +1239,7 @@ interface NonVirtualizedThreadProps {
|
|
|
1186
1239
|
readonly onRetrySend?: () => void;
|
|
1187
1240
|
readonly onRetryExecution?: (message: string) => void;
|
|
1188
1241
|
readonly onEditMessage?: (text: string) => void;
|
|
1242
|
+
readonly slots?: MessageThreadSlots;
|
|
1189
1243
|
}
|
|
1190
1244
|
|
|
1191
1245
|
function NonVirtualizedThread({
|
|
@@ -1209,6 +1263,7 @@ function NonVirtualizedThread({
|
|
|
1209
1263
|
onRetrySend,
|
|
1210
1264
|
onRetryExecution,
|
|
1211
1265
|
onEditMessage,
|
|
1266
|
+
slots,
|
|
1212
1267
|
}: NonVirtualizedThreadProps) {
|
|
1213
1268
|
const { scrollRef, sentinelRef, contentRef, isFollowing, jumpToLatest } =
|
|
1214
1269
|
useAutoScroll();
|
|
@@ -1252,6 +1307,7 @@ function NonVirtualizedThread({
|
|
|
1252
1307
|
onRetrySend={onRetrySend}
|
|
1253
1308
|
onRetryExecution={onRetryExecution}
|
|
1254
1309
|
onEditMessage={onEditMessage}
|
|
1310
|
+
slots={slots}
|
|
1255
1311
|
/>
|
|
1256
1312
|
</ThreadItemWrapper>
|
|
1257
1313
|
))}
|
|
@@ -1307,6 +1363,7 @@ export interface ThreadItemRendererProps {
|
|
|
1307
1363
|
readonly onRetrySend?: () => void;
|
|
1308
1364
|
readonly onRetryExecution?: (message: string) => void;
|
|
1309
1365
|
readonly onEditMessage?: (text: string) => void;
|
|
1366
|
+
readonly slots?: MessageThreadSlots;
|
|
1310
1367
|
}
|
|
1311
1368
|
|
|
1312
1369
|
/**
|
|
@@ -1314,6 +1371,11 @@ export interface ThreadItemRendererProps {
|
|
|
1314
1371
|
* the non-virtualized `items.map()` path and the virtualized
|
|
1315
1372
|
* `Virtuoso.itemContent` callback.
|
|
1316
1373
|
*
|
|
1374
|
+
* Slot resolution happens here, per case, as `slots?.X ?? X` — no merged
|
|
1375
|
+
* defaults object, no allocation, and the memoized row wrappers below
|
|
1376
|
+
* (`ApprovalCardRow`, `FileReviewRecordRow`) keep their DD-010 callback
|
|
1377
|
+
* stabilization around whichever component renders inside them.
|
|
1378
|
+
*
|
|
1317
1379
|
* Does not receive a `key` prop — the caller is responsible for
|
|
1318
1380
|
* keying (either via `items.map` or `computeItemKey`).
|
|
1319
1381
|
*
|
|
@@ -1334,16 +1396,22 @@ export function ThreadItemRenderer({
|
|
|
1334
1396
|
onRetrySend,
|
|
1335
1397
|
onRetryExecution,
|
|
1336
1398
|
onEditMessage,
|
|
1399
|
+
slots,
|
|
1337
1400
|
}: ThreadItemRendererProps) {
|
|
1338
1401
|
switch (item.kind) {
|
|
1339
|
-
case "message":
|
|
1402
|
+
case "message": {
|
|
1403
|
+
const Entry = slots?.MessageEntry ?? MessageEntry;
|
|
1340
1404
|
if (item.isFailed) {
|
|
1341
1405
|
return (
|
|
1342
|
-
<FailedUserMessage
|
|
1406
|
+
<FailedUserMessage
|
|
1407
|
+
message={item.message}
|
|
1408
|
+
onRetry={onRetrySend}
|
|
1409
|
+
MessageEntryComponent={Entry}
|
|
1410
|
+
/>
|
|
1343
1411
|
);
|
|
1344
1412
|
}
|
|
1345
1413
|
return (
|
|
1346
|
-
<
|
|
1414
|
+
<Entry
|
|
1347
1415
|
message={item.message}
|
|
1348
1416
|
className={item.isPending ? "opacity-70" : undefined}
|
|
1349
1417
|
isPlanDocument={item.isPlanDocument}
|
|
@@ -1355,6 +1423,7 @@ export function ThreadItemRenderer({
|
|
|
1355
1423
|
}
|
|
1356
1424
|
/>
|
|
1357
1425
|
);
|
|
1426
|
+
}
|
|
1358
1427
|
case "tool-group":
|
|
1359
1428
|
return (
|
|
1360
1429
|
<ToolCallGroup
|
|
@@ -1392,30 +1461,37 @@ export function ThreadItemRenderer({
|
|
|
1392
1461
|
onApprovalSubmit={onApprovalSubmit!}
|
|
1393
1462
|
isSubmitting={submittingApprovalIds?.has(item.pendingApproval.toolCallId) ?? false}
|
|
1394
1463
|
error={approvalErrors?.get(item.pendingApproval.toolCallId) ?? null}
|
|
1464
|
+
ApprovalCardComponent={slots?.ApprovalCard ?? ApprovalCard}
|
|
1395
1465
|
/>
|
|
1396
1466
|
);
|
|
1397
1467
|
case "file-review-record":
|
|
1398
1468
|
return <FileReviewRecordRow fileChangeSet={item.fileChangeSet} />;
|
|
1399
|
-
case "setup-progress":
|
|
1469
|
+
case "setup-progress": {
|
|
1470
|
+
const Setup = slots?.SetupProgress ?? SetupProgress;
|
|
1400
1471
|
return (
|
|
1401
|
-
<
|
|
1472
|
+
<Setup
|
|
1402
1473
|
workspaceEntries={item.workspaceEntries}
|
|
1403
1474
|
serverPhase={item.serverPhase}
|
|
1404
1475
|
isAwaitingResponse={item.isAwaitingResponse}
|
|
1405
1476
|
/>
|
|
1406
1477
|
);
|
|
1478
|
+
}
|
|
1407
1479
|
case "context-compacted":
|
|
1408
1480
|
return <SummarizationCard event={item.event} />;
|
|
1409
|
-
case "todos":
|
|
1410
|
-
|
|
1411
|
-
|
|
1481
|
+
case "todos": {
|
|
1482
|
+
const Todos = slots?.TodoCard ?? TodoCard;
|
|
1483
|
+
return <Todos todos={item.todos} className="mx-4" TodoRow={slots?.TodoRow} />;
|
|
1484
|
+
}
|
|
1485
|
+
case "plan-completion": {
|
|
1412
1486
|
// When the plan was published as an artifact, show the richer reviewable
|
|
1413
1487
|
// card (preview / copy / download / implement). Otherwise fall back to the
|
|
1414
1488
|
// bare Implement CTA (older executions, or a plan that failed to publish).
|
|
1415
1489
|
// Only the latest plan receives the build action — a superseded plan's
|
|
1416
1490
|
// card is review-only, so a stale plan can never be implemented from it.
|
|
1491
|
+
const Artifact = slots?.PlanArtifactCard ?? PlanArtifactCard;
|
|
1492
|
+
const Completion = slots?.PlanCompletionCard ?? PlanCompletionCard;
|
|
1417
1493
|
return item.planArtifact && item.executionId ? (
|
|
1418
|
-
<
|
|
1494
|
+
<Artifact
|
|
1419
1495
|
executionId={item.executionId}
|
|
1420
1496
|
artifact={item.planArtifact}
|
|
1421
1497
|
title={item.planTitle}
|
|
@@ -1432,17 +1508,19 @@ export function ThreadItemRenderer({
|
|
|
1432
1508
|
buildPending={planBuildPending}
|
|
1433
1509
|
/>
|
|
1434
1510
|
) : (
|
|
1435
|
-
<
|
|
1511
|
+
<Completion
|
|
1436
1512
|
onImplement={item.isLatestPlan ? onBuildFromPlan : undefined}
|
|
1437
1513
|
disabled={planActionsDisabled}
|
|
1438
1514
|
/>
|
|
1439
1515
|
);
|
|
1440
|
-
|
|
1516
|
+
}
|
|
1517
|
+
case "plan-writing": {
|
|
1441
1518
|
// The live stand-in for a plan the active turn is writing. Emitted only
|
|
1442
1519
|
// when onOpenPlan is wired (see buildThreadItems' collapseStreamingPlan
|
|
1443
1520
|
// gate), so the action is always available in practice.
|
|
1521
|
+
const Streaming = slots?.PlanStreamingCard ?? PlanStreamingCard;
|
|
1444
1522
|
return (
|
|
1445
|
-
<
|
|
1523
|
+
<Streaming
|
|
1446
1524
|
title={item.planTitle}
|
|
1447
1525
|
sizeBytes={item.planSize}
|
|
1448
1526
|
onOpenPlan={
|
|
@@ -1450,6 +1528,7 @@ export function ThreadItemRenderer({
|
|
|
1450
1528
|
}
|
|
1451
1529
|
/>
|
|
1452
1530
|
);
|
|
1531
|
+
}
|
|
1453
1532
|
}
|
|
1454
1533
|
}
|
|
1455
1534
|
|
|
@@ -1462,17 +1541,22 @@ export function ThreadItemRenderer({
|
|
|
1462
1541
|
* (so the typed text is never lost) with an inline, actionable error beneath
|
|
1463
1542
|
* it. The error copy is intentionally short — the full reason is surfaced by
|
|
1464
1543
|
* the consumer's send-error banner; this is the in-thread "Retry" affordance.
|
|
1544
|
+
*
|
|
1545
|
+
* The bubble renders through the caller-resolved MessageEntry slot so an
|
|
1546
|
+
* overridden bubble style also applies to failed sends.
|
|
1465
1547
|
*/
|
|
1466
1548
|
function FailedUserMessage({
|
|
1467
1549
|
message,
|
|
1468
1550
|
onRetry,
|
|
1551
|
+
MessageEntryComponent,
|
|
1469
1552
|
}: {
|
|
1470
1553
|
message: AgentMessage;
|
|
1471
1554
|
onRetry?: () => void;
|
|
1555
|
+
MessageEntryComponent: ComponentType<MessageEntryProps>;
|
|
1472
1556
|
}) {
|
|
1473
1557
|
return (
|
|
1474
1558
|
<div className="flex flex-col gap-1">
|
|
1475
|
-
<
|
|
1559
|
+
<MessageEntryComponent message={message} />
|
|
1476
1560
|
<div
|
|
1477
1561
|
role="alert"
|
|
1478
1562
|
className="mx-4 flex items-center gap-2 text-xs text-destructive"
|
|
@@ -1587,6 +1671,9 @@ interface ApprovalCardRowProps {
|
|
|
1587
1671
|
// This gate's last failed decision, or null — a stable ref from the
|
|
1588
1672
|
// approvalErrors map, so the row re-renders only when its error appears/clears.
|
|
1589
1673
|
readonly error?: Error | null;
|
|
1674
|
+
// The (possibly slotted) card component. The row's callback stabilization
|
|
1675
|
+
// wraps whichever card renders, so a slot override keeps the memo behavior.
|
|
1676
|
+
readonly ApprovalCardComponent: ComponentType<ApprovalCardProps>;
|
|
1590
1677
|
}
|
|
1591
1678
|
|
|
1592
1679
|
const ApprovalCardRow = memo(function ApprovalCardRow({
|
|
@@ -1594,6 +1681,7 @@ const ApprovalCardRow = memo(function ApprovalCardRow({
|
|
|
1594
1681
|
onApprovalSubmit,
|
|
1595
1682
|
isSubmitting,
|
|
1596
1683
|
error = null,
|
|
1684
|
+
ApprovalCardComponent,
|
|
1597
1685
|
}: ApprovalCardRowProps) {
|
|
1598
1686
|
const handleSubmit = useCallback(
|
|
1599
1687
|
(action: ApprovalAction, comment?: string) => {
|
|
@@ -1603,7 +1691,7 @@ const ApprovalCardRow = memo(function ApprovalCardRow({
|
|
|
1603
1691
|
);
|
|
1604
1692
|
|
|
1605
1693
|
return (
|
|
1606
|
-
<
|
|
1694
|
+
<ApprovalCardComponent
|
|
1607
1695
|
pendingApproval={pendingApproval}
|
|
1608
1696
|
onSubmit={handleSubmit}
|
|
1609
1697
|
isSubmitting={isSubmitting}
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { memo, useMemo } from "react";
|
|
3
|
+
import { memo, useMemo, type ComponentType } from "react";
|
|
4
4
|
import type { TodoItem } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/todo_pb";
|
|
5
5
|
import { TodoStatus } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
6
6
|
import { cn } from "@stigmer/theme";
|
|
7
7
|
import { useRenderTracer } from "../internal/dev/index.js";
|
|
8
8
|
import { useAutoDisclosure } from "../internal/useAutoDisclosure.js";
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
TodoList,
|
|
11
|
+
findActiveTodo,
|
|
12
|
+
todoCompletionSummary,
|
|
13
|
+
type TodoRowProps,
|
|
14
|
+
} from "./TodoList.js";
|
|
10
15
|
|
|
11
16
|
/** Props for {@link TodoCard}. */
|
|
12
17
|
export interface TodoCardProps {
|
|
@@ -18,6 +23,12 @@ export interface TodoCardProps {
|
|
|
18
23
|
readonly todos: { readonly [key: string]: TodoItem };
|
|
19
24
|
/** Additional CSS class names for the root container. */
|
|
20
25
|
readonly className?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Replacement row component, forwarded to the inner {@link TodoList}.
|
|
28
|
+
* Lets a host restyle individual rows while keeping the card's
|
|
29
|
+
* collapse/progress chrome. Defaults to the built-in {@link TodoRow}.
|
|
30
|
+
*/
|
|
31
|
+
readonly TodoRow?: ComponentType<TodoRowProps>;
|
|
21
32
|
}
|
|
22
33
|
|
|
23
34
|
/**
|
|
@@ -52,6 +63,7 @@ export interface TodoCardProps {
|
|
|
52
63
|
export const TodoCard = memo(function TodoCard({
|
|
53
64
|
todos,
|
|
54
65
|
className,
|
|
66
|
+
TodoRow,
|
|
55
67
|
}: TodoCardProps) {
|
|
56
68
|
useRenderTracer("TodoCard", { todos });
|
|
57
69
|
|
|
@@ -121,7 +133,7 @@ export const TodoCard = memo(function TodoCard({
|
|
|
121
133
|
|
|
122
134
|
{expanded && (
|
|
123
135
|
<div className="border-t border-border-muted px-2.5 py-2">
|
|
124
|
-
<TodoList todos={todos} />
|
|
136
|
+
<TodoList todos={todos} TodoRow={TodoRow} />
|
|
125
137
|
</div>
|
|
126
138
|
)}
|
|
127
139
|
</div>
|
|
@@ -139,7 +151,11 @@ export function todoCardPropsEqual(
|
|
|
139
151
|
prev: Readonly<TodoCardProps>,
|
|
140
152
|
next: Readonly<TodoCardProps>,
|
|
141
153
|
): boolean {
|
|
142
|
-
return
|
|
154
|
+
return (
|
|
155
|
+
prev.todos === next.todos &&
|
|
156
|
+
prev.className === next.className &&
|
|
157
|
+
prev.TodoRow === next.TodoRow
|
|
158
|
+
);
|
|
143
159
|
}
|
|
144
160
|
|
|
145
161
|
// ---------------------------------------------------------------------------
|