@stigmer/react 3.1.3 → 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/composer/SessionComposer.d.ts +31 -0
- package/composer/SessionComposer.d.ts.map +1 -1
- package/composer/SessionComposer.js +12 -4
- package/composer/SessionComposer.js.map +1 -1
- package/execution/ArtifactApplyButton.d.ts +25 -0
- package/execution/ArtifactApplyButton.d.ts.map +1 -0
- package/execution/ArtifactApplyButton.js +21 -0
- package/execution/ArtifactApplyButton.js.map +1 -0
- package/execution/ArtifactContentBody.d.ts +36 -0
- package/execution/ArtifactContentBody.d.ts.map +1 -0
- package/execution/ArtifactContentBody.js +62 -0
- package/execution/ArtifactContentBody.js.map +1 -0
- package/execution/ArtifactDocument.d.ts +48 -0
- package/execution/ArtifactDocument.d.ts.map +1 -0
- package/execution/ArtifactDocument.js +89 -0
- package/execution/ArtifactDocument.js.map +1 -0
- package/execution/ArtifactPreviewModal.d.ts +4 -4
- package/execution/ArtifactPreviewModal.d.ts.map +1 -1
- package/execution/ArtifactPreviewModal.js +15 -142
- package/execution/ArtifactPreviewModal.js.map +1 -1
- package/execution/ArtifactRow.d.ts +49 -0
- package/execution/ArtifactRow.d.ts.map +1 -0
- package/execution/ArtifactRow.js +56 -0
- package/execution/ArtifactRow.js.map +1 -0
- package/execution/ArtifactsWidget.d.ts +6 -9
- package/execution/ArtifactsWidget.d.ts.map +1 -1
- package/execution/ArtifactsWidget.js +15 -19
- package/execution/ArtifactsWidget.js.map +1 -1
- 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 +13 -7
- package/execution/index.d.ts.map +1 -1
- package/execution/index.js +7 -4
- package/execution/index.js.map +1 -1
- package/execution/useArtifactContent.d.ts +6 -1
- package/execution/useArtifactContent.d.ts.map +1 -1
- package/execution/useArtifactContent.js +7 -2
- package/execution/useArtifactContent.js.map +1 -1
- package/execution/useArtifactInspection.d.ts +85 -0
- package/execution/useArtifactInspection.d.ts.map +1 -0
- package/execution/useArtifactInspection.js +143 -0
- package/execution/useArtifactInspection.js.map +1 -0
- package/execution/useCreateAgentExecution.d.ts +11 -0
- package/execution/useCreateAgentExecution.d.ts.map +1 -1
- package/execution/useCreateAgentExecution.js +1 -0
- package/execution/useCreateAgentExecution.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 +4 -4
- package/index.d.ts.map +1 -1
- package/index.js +3 -3
- package/index.js.map +1 -1
- package/internal/MermaidDiagram.d.ts +47 -0
- package/internal/MermaidDiagram.d.ts.map +1 -0
- package/internal/MermaidDiagram.js +118 -0
- package/internal/MermaidDiagram.js.map +1 -0
- 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/internal/markdown-components.d.ts.map +1 -1
- package/internal/markdown-components.js +34 -0
- package/internal/markdown-components.js.map +1 -1
- package/internal/mermaid-loader.d.ts +26 -0
- package/internal/mermaid-loader.d.ts.map +1 -0
- package/internal/mermaid-loader.js +34 -0
- package/internal/mermaid-loader.js.map +1 -0
- package/internal/mermaid-theme-css.d.ts +41 -0
- package/internal/mermaid-theme-css.d.ts.map +1 -0
- package/internal/mermaid-theme-css.js +179 -0
- package/internal/mermaid-theme-css.js.map +1 -0
- package/internal/slug.d.ts +9 -5
- package/internal/slug.d.ts.map +1 -1
- package/internal/slug.js +10 -6
- package/internal/slug.js.map +1 -1
- package/package.json +5 -4
- package/session/SessionViewer.d.ts +11 -1
- package/session/SessionViewer.d.ts.map +1 -1
- package/session/SessionViewer.js +101 -21
- package/session/SessionViewer.js.map +1 -1
- package/session/artifact-document.d.ts +13 -0
- package/session/artifact-document.d.ts.map +1 -0
- package/session/artifact-document.js +22 -0
- package/session/artifact-document.js.map +1 -0
- package/session/facets/ArtifactsTab.d.ts +30 -4
- package/session/facets/ArtifactsTab.d.ts.map +1 -1
- package/session/facets/ArtifactsTab.js +32 -10
- package/session/facets/ArtifactsTab.js.map +1 -1
- package/session/index.d.ts +3 -1
- package/session/index.d.ts.map +1 -1
- package/session/index.js +5 -1
- package/session/index.js.map +1 -1
- package/session/useSessionArtifacts.d.ts +17 -0
- package/session/useSessionArtifacts.d.ts.map +1 -1
- package/session/useSessionArtifacts.js +16 -5
- package/session/useSessionArtifacts.js.map +1 -1
- package/session/useSessionConversation.d.ts +17 -1
- package/session/useSessionConversation.d.ts.map +1 -1
- package/session/useSessionConversation.js +32 -4
- package/session/useSessionConversation.js.map +1 -1
- package/session/useSessionPageFlow.d.ts.map +1 -1
- package/session/useSessionPageFlow.js +1 -0
- package/session/useSessionPageFlow.js.map +1 -1
- package/session/useSessionPanel.d.ts +20 -0
- package/session/useSessionPanel.d.ts.map +1 -1
- package/session/useSessionPanel.js +13 -0
- package/session/useSessionPanel.js.map +1 -1
- package/session/useSessionRailViews.d.ts +13 -1
- package/session/useSessionRailViews.d.ts.map +1 -1
- package/session/useSessionRailViews.js +5 -3
- package/session/useSessionRailViews.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/composer/SessionComposer.tsx +69 -1
- package/src/composer/__tests__/SessionComposer-editing.test.tsx +128 -0
- package/src/execution/ArtifactApplyButton.tsx +79 -0
- package/src/execution/ArtifactContentBody.tsx +255 -0
- package/src/execution/ArtifactDocument.tsx +344 -0
- package/src/execution/ArtifactPreviewModal.tsx +39 -405
- package/src/execution/ArtifactRow.tsx +165 -0
- package/src/execution/ArtifactsWidget.tsx +24 -33
- 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__/ArtifactContentBody.test.tsx +131 -0
- package/src/execution/__tests__/ArtifactDocument.test.tsx +100 -0
- package/src/execution/__tests__/ArtifactRow.test.tsx +139 -0
- package/src/execution/__tests__/ArtifactsWidget.test.tsx +78 -0
- 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-entry.test.tsx +50 -2
- package/src/execution/__tests__/message-thread-slots.test.tsx +463 -0
- package/src/execution/__tests__/useArtifactInspection.test.tsx +151 -0
- package/src/execution/__tests__/useCreateAgentExecution.test.tsx +35 -0
- package/src/execution/file-review-status.ts +24 -0
- package/src/execution/index.ts +27 -5
- package/src/execution/useArtifactContent.ts +7 -0
- package/src/execution/useArtifactInspection.ts +252 -0
- package/src/execution/useCreateAgentExecution.ts +12 -0
- 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 +15 -2
- package/src/internal/MermaidDiagram.tsx +164 -0
- package/src/internal/VirtualizedThread.tsx +5 -1
- package/src/internal/__tests__/a11y/mermaid-theme.a11y.test.tsx +122 -0
- package/src/internal/__tests__/markdown-components.test.tsx +93 -1
- package/src/internal/__tests__/mermaid-diagram.test.tsx +282 -0
- package/src/internal/markdown-components.tsx +36 -1
- package/src/internal/mermaid-loader.ts +44 -0
- package/src/internal/mermaid-theme-css.ts +178 -0
- package/src/internal/slug.ts +10 -6
- package/src/session/SessionViewer.tsx +204 -35
- package/src/session/__tests__/SessionViewer-artifactTabs.test.tsx +210 -0
- package/src/session/__tests__/SessionViewer-editResubmit.test.tsx +233 -0
- package/src/session/__tests__/useSessionArtifacts.test.ts +57 -0
- package/src/session/__tests__/useSessionConversation.test.tsx +172 -1
- package/src/session/__tests__/useSessionPanel.test.ts +70 -1
- package/src/session/__tests__/useWorkspaceReadRefs.test.ts +245 -0
- package/src/session/artifact-document.ts +23 -0
- package/src/session/facets/ArtifactsTab.tsx +66 -18
- package/src/session/facets/__tests__/ArtifactsTab.test.tsx +111 -47
- package/src/session/index.ts +7 -1
- package/src/session/useSessionArtifacts.ts +16 -5
- package/src/session/useSessionConversation.ts +48 -6
- package/src/session/useSessionPageFlow.ts +1 -0
- package/src/session/useSessionPanel.ts +41 -0
- package/src/session/useSessionRailViews.tsx +21 -1
- 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/execution/ArtifactCard.d.ts +0 -81
- package/execution/ArtifactCard.d.ts.map +0 -1
- package/execution/ArtifactCard.js +0 -130
- package/execution/ArtifactCard.js.map +0 -1
- package/src/execution/ArtifactCard.tsx +0 -320
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token-driven `themeCSS` for Mermaid diagram interiors.
|
|
3
|
+
*
|
|
4
|
+
* Mermaid's built-in `default`/`dark` themes color a diagram's SVG interior
|
|
5
|
+
* with a fixed palette that ignores the host's `--stgm-*` preset (Corporate,
|
|
6
|
+
* Fintech, ...). The obvious fix — feeding resolved tokens into Mermaid's
|
|
7
|
+
* `themeVariables` — is blocked: our tokens are authored in `oklch()`, and
|
|
8
|
+
* Mermaid's color engine (`khroma`) parses only hex/rgb/hsl/keyword, so it
|
|
9
|
+
* throws or NaNs on `oklch(...)`. (Mermaid also gates every `themeVariables`
|
|
10
|
+
* value through the allowlist `^[\d "#%(),.;A-Za-z]+$`, which excludes `-` and
|
|
11
|
+
* would blank any `var(--...)`.)
|
|
12
|
+
*
|
|
13
|
+
* Instead we hand Mermaid this CSS via `initialize({ themeCSS })`. Mermaid
|
|
14
|
+
* injects it into the diagram's own `<style>` block, scoped under the render
|
|
15
|
+
* id (`#stgm-mermaid-N`), *after* the theme palette it computes. Because every
|
|
16
|
+
* selector in that block is id-prefixed, our rules and the palette's rules sit
|
|
17
|
+
* at equal specificity, so ours win by source order — and `!important` makes
|
|
18
|
+
* that bulletproof against the few palette rules that are themselves important
|
|
19
|
+
* or inlined. Crucially, `themeCSS` never passes through khroma, so the
|
|
20
|
+
* `oklch()`-backed `var(--stgm-*)` references flow straight to the browser,
|
|
21
|
+
* which resolves them against the `.stgm` scope the SVG lives in. That is why
|
|
22
|
+
* interiors track the active preset *and* color mode live, with no JS color
|
|
23
|
+
* reading and no re-render on theme change.
|
|
24
|
+
*
|
|
25
|
+
* `initialize({ theme })` still selects the built-in `default`/`dark` theme as
|
|
26
|
+
* the base, so any element or diagram type we do not target here degrades to
|
|
27
|
+
* Mermaid's stock palette — never a blank or mis-colored diagram.
|
|
28
|
+
*
|
|
29
|
+
* Palette intent (subtle surfaces + brand accents — legibility over brand
|
|
30
|
+
* saturation): node/actor bodies sit on a muted surface with quiet
|
|
31
|
+
* token-colored borders and edges; labels use the standard foreground; the
|
|
32
|
+
* brand `--stgm-primary` is reserved for structural headers (subgraph/cluster
|
|
33
|
+
* titles, sequence loop/section titles, the sequence-number badge).
|
|
34
|
+
*
|
|
35
|
+
* Coverage is the two families agents emit overwhelmingly — flowchart and
|
|
36
|
+
* sequence — plus the shared marker/edge-label chrome. Both label render paths
|
|
37
|
+
* are handled: SVG `text`/`tspan` (via `fill`) and HTML labels inside
|
|
38
|
+
* `foreignObject` (via `color`).
|
|
39
|
+
*/
|
|
40
|
+
export const MERMAID_THEME_CSS = `
|
|
41
|
+
/* Shared: edge arrowheads / markers */
|
|
42
|
+
.marker {
|
|
43
|
+
fill: var(--stgm-border) !important;
|
|
44
|
+
stroke: var(--stgm-border) !important;
|
|
45
|
+
}
|
|
46
|
+
.marker.cross {
|
|
47
|
+
stroke: var(--stgm-border) !important;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/* Flowchart: node bodies */
|
|
51
|
+
.node rect,
|
|
52
|
+
.node circle,
|
|
53
|
+
.node ellipse,
|
|
54
|
+
.node polygon,
|
|
55
|
+
.node path {
|
|
56
|
+
fill: var(--stgm-muted) !important;
|
|
57
|
+
stroke: var(--stgm-border) !important;
|
|
58
|
+
}
|
|
59
|
+
.node .neo-node {
|
|
60
|
+
stroke: var(--stgm-border) !important;
|
|
61
|
+
}
|
|
62
|
+
.node .katex path {
|
|
63
|
+
fill: var(--stgm-foreground) !important;
|
|
64
|
+
stroke: var(--stgm-foreground) !important;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/* Flowchart: node labels (SVG text and HTML spans) */
|
|
68
|
+
.label {
|
|
69
|
+
color: var(--stgm-foreground) !important;
|
|
70
|
+
}
|
|
71
|
+
.label text,
|
|
72
|
+
.label span {
|
|
73
|
+
fill: var(--stgm-foreground) !important;
|
|
74
|
+
color: var(--stgm-foreground) !important;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/* Flowchart: edges */
|
|
78
|
+
.edgePath .path,
|
|
79
|
+
.flowchart-link {
|
|
80
|
+
stroke: var(--stgm-border) !important;
|
|
81
|
+
}
|
|
82
|
+
.arrowheadPath,
|
|
83
|
+
.root .anchor path {
|
|
84
|
+
fill: var(--stgm-border) !important;
|
|
85
|
+
stroke: var(--stgm-border) !important;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/* Flowchart: edge labels sit on the diagram surface for legibility */
|
|
89
|
+
.edgeLabel,
|
|
90
|
+
.edgeLabel p,
|
|
91
|
+
.edgeLabel rect,
|
|
92
|
+
.labelBkg {
|
|
93
|
+
background-color: var(--stgm-card) !important;
|
|
94
|
+
fill: var(--stgm-card) !important;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/* Flowchart: subgraph clusters — muted surface, brand-accent title */
|
|
98
|
+
.cluster rect {
|
|
99
|
+
fill: var(--stgm-muted-subtle) !important;
|
|
100
|
+
stroke: var(--stgm-border) !important;
|
|
101
|
+
}
|
|
102
|
+
.cluster-label text,
|
|
103
|
+
.cluster text {
|
|
104
|
+
fill: var(--stgm-primary) !important;
|
|
105
|
+
}
|
|
106
|
+
.cluster-label span,
|
|
107
|
+
.cluster span {
|
|
108
|
+
color: var(--stgm-primary) !important;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/* Sequence: actors and lifelines */
|
|
112
|
+
.actor {
|
|
113
|
+
fill: var(--stgm-muted) !important;
|
|
114
|
+
stroke: var(--stgm-border) !important;
|
|
115
|
+
}
|
|
116
|
+
text.actor > tspan {
|
|
117
|
+
fill: var(--stgm-foreground) !important;
|
|
118
|
+
}
|
|
119
|
+
.actor-line {
|
|
120
|
+
stroke: var(--stgm-border) !important;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/* Sequence: messages */
|
|
124
|
+
.messageLine0,
|
|
125
|
+
.messageLine1 {
|
|
126
|
+
stroke: var(--stgm-border) !important;
|
|
127
|
+
}
|
|
128
|
+
[id$="-arrowhead"] path,
|
|
129
|
+
[id$="-crosshead"] path {
|
|
130
|
+
fill: var(--stgm-border) !important;
|
|
131
|
+
stroke: var(--stgm-border) !important;
|
|
132
|
+
}
|
|
133
|
+
.messageText {
|
|
134
|
+
fill: var(--stgm-foreground) !important;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/* Sequence: number badge — brand accent with its paired foreground */
|
|
138
|
+
[id$="-sequencenumber"] {
|
|
139
|
+
fill: var(--stgm-primary) !important;
|
|
140
|
+
}
|
|
141
|
+
.sequenceNumber {
|
|
142
|
+
fill: var(--stgm-primary-foreground) !important;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/* Sequence: alt/opt/loop boxes and labels */
|
|
146
|
+
.labelBox {
|
|
147
|
+
fill: var(--stgm-muted-subtle) !important;
|
|
148
|
+
stroke: var(--stgm-border) !important;
|
|
149
|
+
}
|
|
150
|
+
.labelText,
|
|
151
|
+
.labelText > tspan {
|
|
152
|
+
fill: var(--stgm-foreground) !important;
|
|
153
|
+
}
|
|
154
|
+
.loopText,
|
|
155
|
+
.loopText > tspan,
|
|
156
|
+
.sectionTitle,
|
|
157
|
+
.sectionTitle > tspan {
|
|
158
|
+
fill: var(--stgm-primary) !important;
|
|
159
|
+
}
|
|
160
|
+
.loopLine {
|
|
161
|
+
stroke: var(--stgm-border) !important;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/* Sequence: notes and activations */
|
|
165
|
+
.note {
|
|
166
|
+
fill: var(--stgm-muted-subtle) !important;
|
|
167
|
+
stroke: var(--stgm-border) !important;
|
|
168
|
+
}
|
|
169
|
+
.noteText,
|
|
170
|
+
.noteText > tspan {
|
|
171
|
+
fill: var(--stgm-foreground) !important;
|
|
172
|
+
}
|
|
173
|
+
.activation0,
|
|
174
|
+
.activation1 {
|
|
175
|
+
fill: var(--stgm-muted) !important;
|
|
176
|
+
stroke: var(--stgm-border) !important;
|
|
177
|
+
}
|
|
178
|
+
`;
|
|
179
|
+
//# sourceMappingURL=mermaid-theme-css.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mermaid-theme-css.js","sourceRoot":"","sources":["../../src/internal/mermaid-theme-css.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0IhC,CAAC"}
|
package/internal/slug.d.ts
CHANGED
|
@@ -7,17 +7,21 @@
|
|
|
7
7
|
*
|
|
8
8
|
* Rules (applied in order):
|
|
9
9
|
* 1. Convert to lowercase
|
|
10
|
-
* 2. Replace spaces with hyphens
|
|
10
|
+
* 2. Replace spaces and dots (namespace separators) with hyphens
|
|
11
11
|
* 3. Strip everything except `a-z`, `0-9`, and `-`
|
|
12
12
|
* 4. Collapse consecutive hyphens into one
|
|
13
13
|
* 5. Trim leading / trailing hyphens
|
|
14
14
|
*
|
|
15
|
+
* Dots are treated as namespace separators (e.g. `platform.sara` → `platform-sara`),
|
|
16
|
+
* matching the backend generators, so namespace-scoped names stay readable.
|
|
17
|
+
*
|
|
15
18
|
* @example
|
|
16
19
|
* ```ts
|
|
17
|
-
* generateSlug("My Cool Agent")
|
|
18
|
-
* generateSlug("Acme Corp!")
|
|
19
|
-
* generateSlug(" --hello-- ")
|
|
20
|
-
* generateSlug("")
|
|
20
|
+
* generateSlug("My Cool Agent") // "my-cool-agent"
|
|
21
|
+
* generateSlug("Acme Corp!") // "acme-corp"
|
|
22
|
+
* generateSlug(" --hello-- ") // "hello"
|
|
23
|
+
* generateSlug("platform.planton-arch") // "platform-planton-arch"
|
|
24
|
+
* generateSlug("") // ""
|
|
21
25
|
* ```
|
|
22
26
|
*/
|
|
23
27
|
export declare function generateSlug(name: string): string;
|
package/internal/slug.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slug.d.ts","sourceRoot":"","sources":["../../src/internal/slug.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"slug.d.ts","sourceRoot":"","sources":["../../src/internal/slug.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOjD;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C"}
|
package/internal/slug.js
CHANGED
|
@@ -7,23 +7,27 @@
|
|
|
7
7
|
*
|
|
8
8
|
* Rules (applied in order):
|
|
9
9
|
* 1. Convert to lowercase
|
|
10
|
-
* 2. Replace spaces with hyphens
|
|
10
|
+
* 2. Replace spaces and dots (namespace separators) with hyphens
|
|
11
11
|
* 3. Strip everything except `a-z`, `0-9`, and `-`
|
|
12
12
|
* 4. Collapse consecutive hyphens into one
|
|
13
13
|
* 5. Trim leading / trailing hyphens
|
|
14
14
|
*
|
|
15
|
+
* Dots are treated as namespace separators (e.g. `platform.sara` → `platform-sara`),
|
|
16
|
+
* matching the backend generators, so namespace-scoped names stay readable.
|
|
17
|
+
*
|
|
15
18
|
* @example
|
|
16
19
|
* ```ts
|
|
17
|
-
* generateSlug("My Cool Agent")
|
|
18
|
-
* generateSlug("Acme Corp!")
|
|
19
|
-
* generateSlug(" --hello-- ")
|
|
20
|
-
* generateSlug("")
|
|
20
|
+
* generateSlug("My Cool Agent") // "my-cool-agent"
|
|
21
|
+
* generateSlug("Acme Corp!") // "acme-corp"
|
|
22
|
+
* generateSlug(" --hello-- ") // "hello"
|
|
23
|
+
* generateSlug("platform.planton-arch") // "platform-planton-arch"
|
|
24
|
+
* generateSlug("") // ""
|
|
21
25
|
* ```
|
|
22
26
|
*/
|
|
23
27
|
export function generateSlug(name) {
|
|
24
28
|
return name
|
|
25
29
|
.toLowerCase()
|
|
26
|
-
.replace(/ /g, "-")
|
|
30
|
+
.replace(/[ .]/g, "-")
|
|
27
31
|
.replace(/[^a-z0-9-]/g, "")
|
|
28
32
|
.replace(/-{2,}/g, "-")
|
|
29
33
|
.replace(/^-+|-+$/g, "");
|
package/internal/slug.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slug.js","sourceRoot":"","sources":["../../src/internal/slug.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"slug.js","sourceRoot":"","sources":["../../src/internal/slug.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,IAAI;SACR,WAAW,EAAE;SACb,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC;SACrB,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC;SAC1B,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AAC7B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,MAAM,CAAC,UAAU,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stigmer/react",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.5",
|
|
4
4
|
"description": "React provider and client hook for the Stigmer platform SDK",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@bufbuild/protovalidate": "^1.1.1",
|
|
39
39
|
"@dagrejs/dagre": "^1.1.4",
|
|
40
|
-
"@stigmer/theme": "3.1.
|
|
40
|
+
"@stigmer/theme": "3.1.5",
|
|
41
41
|
"diff": "^8.0.3",
|
|
42
42
|
"fflate": "^0.8.2",
|
|
43
43
|
"hast-util-to-jsx-runtime": "^2.3.6",
|
|
@@ -60,12 +60,13 @@
|
|
|
60
60
|
"@codemirror/state": "^6.0.0",
|
|
61
61
|
"@codemirror/view": "^6.0.0",
|
|
62
62
|
"@lezer/highlight": "^1.0.0",
|
|
63
|
-
"@stigmer/protos": "3.1.
|
|
64
|
-
"@stigmer/sdk": "3.1.
|
|
63
|
+
"@stigmer/protos": "3.1.5",
|
|
64
|
+
"@stigmer/sdk": "3.1.5",
|
|
65
65
|
"@tanstack/react-table": "^8.20.0",
|
|
66
66
|
"@xyflow/react": "^12.0.0",
|
|
67
67
|
"elkjs": "^0.9.0",
|
|
68
68
|
"lucide-react": ">=0.400.0",
|
|
69
|
+
"mermaid": "^11.0.0",
|
|
69
70
|
"react": "^19.0.0",
|
|
70
71
|
"react-dom": "^19.0.0",
|
|
71
72
|
"react-virtuoso": "^4.0.0",
|
|
@@ -4,6 +4,7 @@ import type { WorkspaceFileLister } from "../workspace/WorkspaceFileLister.js";
|
|
|
4
4
|
import type { WorkspaceFileReader } from "../workspace/WorkspaceFileReader.js";
|
|
5
5
|
import type { WorkspaceContentSearcher } from "../workspace/WorkspaceContentSearcher.js";
|
|
6
6
|
import type { ApplyResourceResult } from "../library/useApplyResource.js";
|
|
7
|
+
import { type MessageThreadSlots } from "../execution/MessageThread.js";
|
|
7
8
|
import type { RuntimeEnvProvider } from "./runtime-env.js";
|
|
8
9
|
import type { SessionAudience } from "./audience.js";
|
|
9
10
|
/** Props for {@link SessionViewer}. */
|
|
@@ -98,6 +99,15 @@ export interface SessionViewerProps {
|
|
|
98
99
|
readonly accessSlot?: ReactNode;
|
|
99
100
|
/** Called after a resource is applied from the Artifacts tab. */
|
|
100
101
|
readonly onApplied?: (result: ApplyResourceResult) => void;
|
|
102
|
+
/**
|
|
103
|
+
* Component overrides for the conversation thread's chrome (message
|
|
104
|
+
* bubbles, approval card, to-dos card, plan cards, thinking indicator) —
|
|
105
|
+
* forwarded to the inner {@link MessageThread}. See
|
|
106
|
+
* {@link MessageThreadSlots}. Define the object and its components at
|
|
107
|
+
* module level (or memoize) so thread rows keep their streaming
|
|
108
|
+
* re-render guarantees.
|
|
109
|
+
*/
|
|
110
|
+
readonly threadSlots?: MessageThreadSlots;
|
|
101
111
|
/** Additional CSS classes for the root container. */
|
|
102
112
|
readonly className?: string;
|
|
103
113
|
}
|
|
@@ -143,5 +153,5 @@ export interface SessionViewerProps {
|
|
|
143
153
|
* />
|
|
144
154
|
* ```
|
|
145
155
|
*/
|
|
146
|
-
export declare function SessionViewer({ sessionId, org, gitHubConnection, enableGitHub, enableLocal, onBrowseLocalFolder, workspaceFileLister, workspaceFileReader, workspaceContentSearcher, getRuntimeEnv, audience, headerActions, accessSlot, onApplied, className, }: SessionViewerProps): import("react/jsx-runtime").JSX.Element;
|
|
156
|
+
export declare function SessionViewer({ sessionId, org, gitHubConnection, enableGitHub, enableLocal, onBrowseLocalFolder, workspaceFileLister, workspaceFileReader, workspaceContentSearcher, getRuntimeEnv, audience, headerActions, accessSlot, onApplied, threadSlots, className, }: SessionViewerProps): import("react/jsx-runtime").JSX.Element;
|
|
147
157
|
//# sourceMappingURL=SessionViewer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SessionViewer.d.ts","sourceRoot":"","sources":["../../src/session/SessionViewer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA2D,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAQhG,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAClF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC/E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC/E,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,0CAA0C,CAAC;AAOzF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"SessionViewer.d.ts","sourceRoot":"","sources":["../../src/session/SessionViewer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA2D,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAQhG,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAClF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC/E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC/E,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,0CAA0C,CAAC;AAOzF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAM1E,OAAO,EAAiB,KAAK,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAqCvF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AA2ErD,uCAAuC;AACvC,MAAM,WAAW,kBAAkB;IACjC,sCAAsC;IACtC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,yBAAyB;IACzB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,yBAAyB,CAAC;IACtD;;;OAGG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAChC;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC5D;;;;OAIG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IACnD;;;;;OAKG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IACnD;;;;;;OAMG;IACH,QAAQ,CAAC,wBAAwB,CAAC,EAAE,wBAAwB,CAAC;IAC7D;;;;;;;OAOG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,kBAAkB,CAAC;IAC5C;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAC;IACpC;;;;OAIG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,CAAC;IACnC;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,CAAC;IAChC,iEAAiE;IACjE,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAC3D;;;;;;;OAOG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,kBAAkB,CAAC;IAC1C,qDAAqD;IACrD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,wBAAgB,aAAa,CAAC,EAC5B,SAAS,EACT,GAAG,EACH,gBAAgB,EAChB,YAAmB,EACnB,WAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,wBAAwB,EACxB,aAAa,EACb,QAAuB,EACvB,aAAa,EACb,UAAU,EACV,SAAS,EACT,WAAW,EACX,SAAS,GACV,EAAE,kBAAkB,2CA2TpB"}
|
package/session/SessionViewer.js
CHANGED
|
@@ -28,11 +28,14 @@ import { usePlanDraft, planDraftKey } from "./usePlanDraft.js";
|
|
|
28
28
|
import { PlanEditor } from "./PlanEditor.js";
|
|
29
29
|
import { PlanStreamingDocument } from "./PlanStreamingDocument.js";
|
|
30
30
|
import { PLAN_DOCUMENT_ENTRY_ID, PLAN_DOCUMENT_PATH } from "./plan-document.js";
|
|
31
|
+
import { ARTIFACT_DOCUMENT_ENTRY_ID } from "./artifact-document.js";
|
|
32
|
+
import { ArtifactDocument } from "../execution/ArtifactDocument.js";
|
|
31
33
|
import { useSessionRailViews } from "./useSessionRailViews.js";
|
|
32
34
|
import { useSessionPanel } from "./useSessionPanel.js";
|
|
33
35
|
import { SessionPanelChip } from "./SessionPanelChip.js";
|
|
34
36
|
import { useSessionWriteBacks } from "./useSessionWriteBacks.js";
|
|
35
|
-
import {
|
|
37
|
+
import { useWorkspaceReadRefs } from "./useWorkspaceReadRefs.js";
|
|
38
|
+
import { useSessionArtifacts, artifactKey, } from "./useSessionArtifacts.js";
|
|
36
39
|
import { ExecutionPhase } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
37
40
|
/**
|
|
38
41
|
* Where the approved plan mounts in the implement execution's workspace —
|
|
@@ -126,7 +129,7 @@ const CONVERSATION_COLUMN_CLASS = "mx-auto w-full max-w-3xl";
|
|
|
126
129
|
* />
|
|
127
130
|
* ```
|
|
128
131
|
*/
|
|
129
|
-
export function SessionViewer({ sessionId, org, gitHubConnection, enableGitHub = true, enableLocal = false, onBrowseLocalFolder, workspaceFileLister, workspaceFileReader, workspaceContentSearcher, getRuntimeEnv, audience = "integrator", headerActions, accessSlot, onApplied, className, }) {
|
|
132
|
+
export function SessionViewer({ sessionId, org, gitHubConnection, enableGitHub = true, enableLocal = false, onBrowseLocalFolder, workspaceFileLister, workspaceFileReader, workspaceContentSearcher, getRuntimeEnv, audience = "integrator", headerActions, accessSlot, onApplied, threadSlots, className, }) {
|
|
130
133
|
const flow = useSessionPageFlow({ sessionId, org, getRuntimeEnv });
|
|
131
134
|
const { conv } = flow;
|
|
132
135
|
const isEndUser = audience === "endUser";
|
|
@@ -271,6 +274,20 @@ export function SessionViewer({ sessionId, org, gitHubConnection, enableGitHub =
|
|
|
271
274
|
: executionId);
|
|
272
275
|
panel.openPlanDocument();
|
|
273
276
|
}, [sessionPlan, panel.openPlanDocument]);
|
|
277
|
+
// "Open artifact" (an Artifacts-facet row) → an editor-pane document tab.
|
|
278
|
+
// Writing the editors store re-renders only the panel subtree (which
|
|
279
|
+
// subscribes), never this streaming column. Plan artifacts are routed to the
|
|
280
|
+
// plan tab upstream (in ArtifactsTab), so they never reach here.
|
|
281
|
+
const handleOpenArtifact = useCallback((entry) => {
|
|
282
|
+
panel.openArtifact(entry.artifact);
|
|
283
|
+
}, [panel.openArtifact]);
|
|
284
|
+
// Double-click an artifact row → pin its tab (the leading single click already
|
|
285
|
+
// opened the preview via `handleOpenArtifact`). Mirrors the file tree's
|
|
286
|
+
// preview/pin split; plan artifacts are routed to the plan tab upstream (in
|
|
287
|
+
// ArtifactsTab) and never reach here.
|
|
288
|
+
const handleActivateArtifact = useCallback((entry) => {
|
|
289
|
+
panel.pinArtifact(entry.artifact);
|
|
290
|
+
}, [panel.pinArtifact]);
|
|
274
291
|
// Open a transcript tool-call file path in the panel's read-only editor.
|
|
275
292
|
// Resolves the (possibly absolute / subdir-prefixed) path to a
|
|
276
293
|
// repo/root-relative selection the editor can fetch; on a definite hit it
|
|
@@ -294,9 +311,9 @@ export function SessionViewer({ sessionId, org, gitHubConnection, enableGitHub =
|
|
|
294
311
|
if (!conv.session && !conv.isLoading) {
|
|
295
312
|
return _jsx(SessionStarting, {});
|
|
296
313
|
}
|
|
297
|
-
return (_jsxs("div", { className: cn("relative flex h-full w-full flex-col", className), children: [_jsxs("div", { className: "absolute top-2 right-6 z-10 flex items-center gap-2", children: [headerActions, _jsx(SessionPanelChip, { isOpen: panel.isOpen, onToggle: panel.isOpen ? panel.closePanel : panel.openPanel, badgeCount: writeBackCount + artifactCount })] }), _jsx(ThreadSelectionContext.Provider, { value: selectionStore, children: _jsx(ResizableSplit, { resizablePane: "primary", collapsedPane: panel.isOpen ? "none" : "secondary", defaultSize: 420, minSize: 320, maxSize: 640, storageKey: "stgm-session-chat-width", responsiveCollapse: panel.isOpen ? "primary" : "none", ariaLabel: "Resize chat panel", className: "min-h-0 flex-1", primary: _jsx(ConversationColumn, { flow: flow, modelId: modelId, setModelId: setModelId, interactionMode: interactionMode, setInteractionMode: setInteractionMode, composerRef: composerRef, org: org, gitHubConnection: gitHubConnection, enableGitHub: enableGitHub, enableLocal: enableLocal, onBrowseLocalFolder: onBrowseLocalFolder, onBuildFromPlan: handleBuildFromPlan, onOpenPlan: handleOpenPlan, isBuildingFromPlan: isBuildingFromPlan, planAttachFailed: planAttachFailed, onDismissPlanAttachFailed: () => setPlanAttachFailed(false), onFilePathClick: handleTranscriptFilePathClick, isEndUser: isEndUser }), secondary: panel.isOpen ? (_jsx(SessionPanelRegion, { flow: flow, org: org, panel: panel, accessSlot: accessSlot, onApplied: onApplied, onImplementPlan: handleBuildFromPlan, implementPlanDisabled: !conv.canSendFollowUp || isBuildingFromPlan, sessionPlan: sessionPlan, streamingPlan: streamingPlan, planDraft: planDraft, openPlanExecutionId: openPlanExecutionId, onOpenPlan: handleOpenPlan, enableLocal: enableLocal, onBrowseLocalFolder: onBrowseLocalFolder, workspaceFileLister: workspaceFileLister, workspaceFileReader: workspaceFileReader, workspaceContentSearcher: workspaceContentSearcher, isEndUser: isEndUser })) : null }) })] }));
|
|
314
|
+
return (_jsxs("div", { className: cn("relative flex h-full w-full flex-col", className), children: [_jsxs("div", { className: "absolute top-2 right-6 z-10 flex items-center gap-2", children: [headerActions, _jsx(SessionPanelChip, { isOpen: panel.isOpen, onToggle: panel.isOpen ? panel.closePanel : panel.openPanel, badgeCount: writeBackCount + artifactCount })] }), _jsx(ThreadSelectionContext.Provider, { value: selectionStore, children: _jsx(ResizableSplit, { resizablePane: "primary", collapsedPane: panel.isOpen ? "none" : "secondary", defaultSize: 420, minSize: 320, maxSize: 640, storageKey: "stgm-session-chat-width", responsiveCollapse: panel.isOpen ? "primary" : "none", ariaLabel: "Resize chat panel", className: "min-h-0 flex-1", primary: _jsx(ConversationColumn, { flow: flow, modelId: modelId, setModelId: setModelId, interactionMode: interactionMode, setInteractionMode: setInteractionMode, composerRef: composerRef, org: org, gitHubConnection: gitHubConnection, enableGitHub: enableGitHub, enableLocal: enableLocal, onBrowseLocalFolder: onBrowseLocalFolder, onBuildFromPlan: handleBuildFromPlan, onOpenPlan: handleOpenPlan, isBuildingFromPlan: isBuildingFromPlan, planAttachFailed: planAttachFailed, onDismissPlanAttachFailed: () => setPlanAttachFailed(false), onFilePathClick: handleTranscriptFilePathClick, isEndUser: isEndUser, threadSlots: threadSlots }), secondary: panel.isOpen ? (_jsx(SessionPanelRegion, { flow: flow, org: org, panel: panel, accessSlot: accessSlot, onApplied: onApplied, onImplementPlan: handleBuildFromPlan, implementPlanDisabled: !conv.canSendFollowUp || isBuildingFromPlan, sessionPlan: sessionPlan, streamingPlan: streamingPlan, planDraft: planDraft, openPlanExecutionId: openPlanExecutionId, onOpenPlan: handleOpenPlan, onOpenArtifact: handleOpenArtifact, onActivateArtifact: handleActivateArtifact, enableLocal: enableLocal, onBrowseLocalFolder: onBrowseLocalFolder, workspaceFileLister: workspaceFileLister, workspaceFileReader: workspaceFileReader, workspaceContentSearcher: workspaceContentSearcher, isEndUser: isEndUser })) : null }) })] }));
|
|
298
315
|
}
|
|
299
|
-
const ConversationColumn = memo(function ConversationColumn({ flow, modelId, setModelId, interactionMode, setInteractionMode, composerRef, org, gitHubConnection, enableGitHub, enableLocal, onBrowseLocalFolder, onBuildFromPlan, onOpenPlan, isBuildingFromPlan, planAttachFailed, onDismissPlanAttachFailed, onFilePathClick, isEndUser, }) {
|
|
316
|
+
const ConversationColumn = memo(function ConversationColumn({ flow, modelId, setModelId, interactionMode, setInteractionMode, composerRef, org, gitHubConnection, enableGitHub, enableLocal, onBrowseLocalFolder, onBuildFromPlan, onOpenPlan, isBuildingFromPlan, planAttachFailed, onDismissPlanAttachFailed, onFilePathClick, isEndUser, threadSlots, }) {
|
|
300
317
|
const { conv } = flow;
|
|
301
318
|
// Approval failures are NOT folded into this banner: they now surface in-card,
|
|
302
319
|
// beside the exact gate that failed (see MessageThread's approvalErrors →
|
|
@@ -314,16 +331,37 @@ const ConversationColumn = memo(function ConversationColumn({ flow, modelId, set
|
|
|
314
331
|
const handleStop = useCallback(() => {
|
|
315
332
|
void conv.stop();
|
|
316
333
|
}, [conv.stop]);
|
|
317
|
-
// Edit-and-resubmit: stop the in-flight turn
|
|
318
|
-
// the original text
|
|
319
|
-
//
|
|
320
|
-
//
|
|
321
|
-
//
|
|
334
|
+
// Edit-and-resubmit: stop the in-flight turn, pre-fill the composer with
|
|
335
|
+
// the original text, and remember which execution is being edited. The
|
|
336
|
+
// append-only execution log is never rewritten — submitting while editing
|
|
337
|
+
// creates a NEW execution that carries `supersedesExecutionId`, and the
|
|
338
|
+
// conversation read model hides the superseded turn so the edited message
|
|
339
|
+
// replaces the original in place (Cursor-style, stigmer/stigmer#181).
|
|
340
|
+
//
|
|
341
|
+
// The editing state is explicit (banner + cancel in the composer) so the
|
|
342
|
+
// supersede link only attaches when the user actually resubmits the edit.
|
|
343
|
+
// Cancelling drops the link — a subsequent unrelated message appends
|
|
344
|
+
// normally without hiding any history.
|
|
345
|
+
const [editingExecutionId, setEditingExecutionId] = useState(null);
|
|
346
|
+
const activeExecutionId = conv.activeStreamExecution?.metadata?.id ?? null;
|
|
322
347
|
const handleEditMessage = useCallback((text) => {
|
|
323
348
|
void conv.stop();
|
|
349
|
+
setEditingExecutionId(activeExecutionId);
|
|
324
350
|
composerRef.current?.setMessage(text);
|
|
325
351
|
composerRef.current?.focus();
|
|
326
|
-
}, [conv.stop, composerRef]);
|
|
352
|
+
}, [conv.stop, activeExecutionId, composerRef]);
|
|
353
|
+
const handleCancelEdit = useCallback(() => {
|
|
354
|
+
setEditingExecutionId(null);
|
|
355
|
+
composerRef.current?.setMessage("");
|
|
356
|
+
}, [composerRef]);
|
|
357
|
+
// Submit wrapper that attaches the supersede link while editing, then
|
|
358
|
+
// exits editing mode. Ordinary (non-editing) submits pass through as-is.
|
|
359
|
+
const handleComposerSubmit = useCallback((message, modelName, context) => {
|
|
360
|
+
void flow.handleSubmit(message, modelName, editingExecutionId
|
|
361
|
+
? { ...context, supersedesExecutionId: editingExecutionId }
|
|
362
|
+
: context);
|
|
363
|
+
setEditingExecutionId(null);
|
|
364
|
+
}, [flow.handleSubmit, editingExecutionId]);
|
|
327
365
|
// The composer-docked FileReviewDock sits OUTSIDE MessageThread, so the
|
|
328
366
|
// thread's own FilePathContext provider does not reach it. This provider
|
|
329
367
|
// gives the dock's file list the same path resolution and click routing
|
|
@@ -334,11 +372,14 @@ const ConversationColumn = memo(function ConversationColumn({ flow, modelId, set
|
|
|
334
372
|
workspaceEntries: conv.workspaceEntries ?? [],
|
|
335
373
|
onFilePathClick,
|
|
336
374
|
}), [conv.workspaceEntries, onFilePathClick]);
|
|
337
|
-
return (_jsxs("div", { className: "flex h-full min-w-0 flex-col", children: [_jsx(MessageThread, { executions: conv.completedExecutions, activeStreamExecution: conv.activeStreamExecution, pendingUserMessage: conv.pendingUserMessage, pendingMessageFailed: !!conv.sendError && !!conv.pendingUserMessage, onRetrySend: conv.retryLastSend, onRetryExecution: onRetryExecution, onApprovalSubmit: flow.submitApproval, submittingApprovalIds: conv.submittingApprovalIds, approvalErrors: conv.approvalErrors, showFileReviewRecords: true, onEditMessage: conv.isStoppable ? handleEditMessage : undefined, workspaceEntries: conv.workspaceEntries, onFilePathClick: onFilePathClick, sandboxWorkspaceRoot: flow.sandboxWorkspaceRoot, onBuildFromPlan: onBuildFromPlan, onOpenPlan: onOpenPlan, org: org, planActionsDisabled: !conv.canSendFollowUp || isBuildingFromPlan, planBuildPending: isBuildingFromPlan, contentColumn: "center", className: "flex-1" }), _jsxs("div", { className: CONVERSATION_COLUMN_CLASS, children: [planAttachFailed && (_jsx(PlanAttachFailedNotice, { onDismiss: onDismissPlanAttachFailed })), conv.isReconnecting && _jsx(ReconnectingIndicator, {}), conv.connectTimedOut && (_jsx(ConnectTimedOutBanner, { onRetry: conv.reconnectStream })), conv.isSlow && !conv.connectTimedOut && _jsx(SlowIndicator, {}), conv.streamError && (_jsx(StreamErrorBanner, { error: conv.streamError, onReconnect: conv.reconnectStream })), sendError && _jsx(SendErrorBanner, { error: sendError }), flow.autoApproveAll && (_jsx(AutoApproveIndicator, { onTurnOff: () => flow.setAutoApproveAll(false) })), _jsxs(FilePathContext.Provider, { value: dockFilePathCtx, children: [_jsx(FileChangeProgressBar, { progress: conv.fileChangeProgress }), _jsx(FileReviewDock, { changeSets: conv.fileChangeSets, onSubmit: conv.submitFileDecision, submittingDecisionKeys: conv.submittingFileDecisionKeys, decisionErrors: conv.fileDecisionErrors })] }), _jsx(SessionComposer, { ref: composerRef, onSubmit:
|
|
375
|
+
return (_jsxs("div", { className: "flex h-full min-w-0 flex-col", children: [_jsx(MessageThread, { executions: conv.completedExecutions, activeStreamExecution: conv.activeStreamExecution, pendingUserMessage: conv.pendingUserMessage, pendingMessageFailed: !!conv.sendError && !!conv.pendingUserMessage, onRetrySend: conv.retryLastSend, onRetryExecution: onRetryExecution, onApprovalSubmit: flow.submitApproval, submittingApprovalIds: conv.submittingApprovalIds, approvalErrors: conv.approvalErrors, showFileReviewRecords: true, onEditMessage: conv.isStoppable ? handleEditMessage : undefined, workspaceEntries: conv.workspaceEntries, onFilePathClick: onFilePathClick, sandboxWorkspaceRoot: flow.sandboxWorkspaceRoot, onBuildFromPlan: onBuildFromPlan, onOpenPlan: onOpenPlan, org: org, planActionsDisabled: !conv.canSendFollowUp || isBuildingFromPlan, planBuildPending: isBuildingFromPlan, contentColumn: "center", slots: threadSlots, className: "flex-1" }), _jsxs("div", { className: CONVERSATION_COLUMN_CLASS, children: [planAttachFailed && (_jsx(PlanAttachFailedNotice, { onDismiss: onDismissPlanAttachFailed })), conv.isReconnecting && _jsx(ReconnectingIndicator, {}), conv.connectTimedOut && (_jsx(ConnectTimedOutBanner, { onRetry: conv.reconnectStream })), conv.isSlow && !conv.connectTimedOut && _jsx(SlowIndicator, {}), conv.streamError && (_jsx(StreamErrorBanner, { error: conv.streamError, onReconnect: conv.reconnectStream })), sendError && _jsx(SendErrorBanner, { error: sendError }), flow.autoApproveAll && (_jsx(AutoApproveIndicator, { onTurnOff: () => flow.setAutoApproveAll(false) })), _jsxs(FilePathContext.Provider, { value: dockFilePathCtx, children: [_jsx(FileChangeProgressBar, { progress: conv.fileChangeProgress }), _jsx(FileReviewDock, { changeSets: conv.fileChangeSets, onSubmit: conv.submitFileDecision, submittingDecisionKeys: conv.submittingFileDecisionKeys, decisionErrors: conv.fileDecisionErrors })] }), _jsx(SessionComposer, { ref: composerRef, onSubmit: handleComposerSubmit, isSubmitting: conv.isSending, disabled: !conv.canSendFollowUp, onStop: conv.isStoppable ? handleStop : undefined, isStopping: conv.isStopping, isEditing: editingExecutionId != null, onCancelEdit: handleCancelEdit, org: org, harness: flow.harness, defaultModelId: modelId, onModelChange: setModelId, interactionMode: interactionMode, onInteractionModeChange: setInteractionMode, showInteractionModePicker: true, workspace: flow.workspace, gitHubConnection: gitHubConnection, enableGitHub: enableGitHub, enableLocal: enableLocal, onBrowseLocalFolder: onBrowseLocalFolder, agentRef: flow.agentRef, onAgentRefChange: flow.setAgentRef, onAgentResolutionChange: flow.setResolution, isDefaultAgent: flow.isDefaultAgent, lockAgent: isEndUser, mcpServerUsages: isEndUser ? undefined : flow.mcpServerUsages, onMcpServerUsagesChange: isEndUser ? undefined : flow.setMcpServerUsages, skillRefs: isEndUser ? undefined : flow.skillRefs, onSkillRefsChange: isEndUser ? undefined : flow.setSkillRefs, sessionVariables: isEndUser ? undefined : flow.sessionVariables, className: "px-4 py-3" })] })] }));
|
|
338
376
|
});
|
|
339
|
-
function SessionPanelRegion({ flow, org, panel, accessSlot, onApplied, onImplementPlan, implementPlanDisabled, sessionPlan, streamingPlan, planDraft, openPlanExecutionId, onOpenPlan, enableLocal, onBrowseLocalFolder, workspaceFileLister, workspaceFileReader, workspaceContentSearcher, isEndUser, }) {
|
|
377
|
+
function SessionPanelRegion({ flow, org, panel, accessSlot, onApplied, onImplementPlan, implementPlanDisabled, sessionPlan, streamingPlan, planDraft, openPlanExecutionId, onOpenPlan, onOpenArtifact, onActivateArtifact, enableLocal, onBrowseLocalFolder, workspaceFileLister, workspaceFileReader, workspaceContentSearcher, isEndUser, }) {
|
|
340
378
|
const selectedItem = useSelectedThreadItem();
|
|
341
379
|
const { editors, activeKey, activeFile, reveal } = useWorkspaceEditors(panel.editorsStore);
|
|
380
|
+
// Session artifacts, deduped by identity — the source both the Artifacts
|
|
381
|
+
// rail-view badge and the open artifact document tabs resolve against.
|
|
382
|
+
const { artifacts: sessionArtifacts } = useSessionArtifacts(flow.allExecutions);
|
|
342
383
|
// Honor a pending jump-to-line reveal only while it targets the active editor
|
|
343
384
|
// (an EditorReveal is structurally a RevealTarget). Switching tabs changes
|
|
344
385
|
// activeKey, so a stale reveal for another tab is naturally ignored.
|
|
@@ -379,14 +420,12 @@ function SessionPanelRegion({ flow, org, panel, accessSlot, onApplied, onImpleme
|
|
|
379
420
|
// tab and its turn then ended without publishing, with no earlier plan to
|
|
380
421
|
// fall back to.
|
|
381
422
|
const openPlanIsLatest = openPlan?.executionId === sessionPlan?.executionId;
|
|
382
|
-
const
|
|
383
|
-
return
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
},
|
|
389
|
-
];
|
|
423
|
+
const planVirtualDocument = useMemo(() => {
|
|
424
|
+
return {
|
|
425
|
+
entryId: PLAN_DOCUMENT_ENTRY_ID,
|
|
426
|
+
path: PLAN_DOCUMENT_PATH,
|
|
427
|
+
content: streamingPlan ? (_jsx(PlanStreamingDocument, { displayText: streamingPlan.displayText }, `streaming-${streamingPlan.executionId}`)) : openPlan ? (_jsx(PlanEditor, { plan: openPlan, draft: openPlanIsLatest ? planDraft : undefined, onBuildFromPlan: openPlanIsLatest ? onImplementPlan : undefined, buildDisabled: implementPlanDisabled, readOnly: !openPlanIsLatest }, planDraftKey(openPlan))) : (_jsx(PlanUnavailableNotice, {})),
|
|
428
|
+
};
|
|
390
429
|
}, [
|
|
391
430
|
streamingPlan,
|
|
392
431
|
openPlan,
|
|
@@ -395,6 +434,30 @@ function SessionPanelRegion({ flow, org, panel, accessSlot, onApplied, onImpleme
|
|
|
395
434
|
onImplementPlan,
|
|
396
435
|
implementPlanDisabled,
|
|
397
436
|
]);
|
|
437
|
+
// The open artifact document tabs (the artifact virtual-document FAMILY).
|
|
438
|
+
// Built in a SEPARATE memo from the plan doc so artifact-tab churn never
|
|
439
|
+
// recreates the plan doc (and vice versa). Bounded to what is actually open:
|
|
440
|
+
// one document per editor whose entry id is the artifact family's, resolved
|
|
441
|
+
// back to its `SessionArtifactEntry` by the same `artifactKey` used to open
|
|
442
|
+
// it (single source of truth for artifact identity). Only the ACTIVE doc's
|
|
443
|
+
// `content` is mounted by the surface, so building these elements is cheap;
|
|
444
|
+
// keying on `contentHash` remounts a tab whose artifact was overwritten by a
|
|
445
|
+
// later execution. A tab whose artifact no longer exists degrades to an
|
|
446
|
+
// honest notice rather than vanishing.
|
|
447
|
+
const artifactByKey = useMemo(() => new Map(sessionArtifacts.map((entry) => [artifactKey(entry.artifact), entry])), [sessionArtifacts]);
|
|
448
|
+
const artifactVirtualDocuments = useMemo(() => {
|
|
449
|
+
return editors
|
|
450
|
+
.filter((editor) => editor.entryId === ARTIFACT_DOCUMENT_ENTRY_ID)
|
|
451
|
+
.map((editor) => {
|
|
452
|
+
const entry = artifactByKey.get(editor.path);
|
|
453
|
+
return {
|
|
454
|
+
entryId: ARTIFACT_DOCUMENT_ENTRY_ID,
|
|
455
|
+
path: editor.path,
|
|
456
|
+
content: entry ? (_jsx(ArtifactDocument, { artifact: entry.artifact, executionId: entry.executionId, org: org, isTerminal: entry.isTerminal, onApplied: onApplied }, entry.artifact.contentHash || editor.path)) : (_jsx(ArtifactUnavailableNotice, {})),
|
|
457
|
+
};
|
|
458
|
+
});
|
|
459
|
+
}, [editors, artifactByKey, org, onApplied]);
|
|
460
|
+
const virtualDocuments = useMemo(() => [planVirtualDocument, ...artifactVirtualDocuments], [planVirtualDocument, artifactVirtualDocuments]);
|
|
398
461
|
const handleRemoveAgent = useCallback(() => {
|
|
399
462
|
flow.setAgentRef(null);
|
|
400
463
|
flow.setResolution(null);
|
|
@@ -440,6 +503,8 @@ function SessionPanelRegion({ flow, org, panel, accessSlot, onApplied, onImpleme
|
|
|
440
503
|
onApplied,
|
|
441
504
|
onImplementPlan,
|
|
442
505
|
onOpenPlan,
|
|
506
|
+
onOpenArtifact,
|
|
507
|
+
onActivateArtifact,
|
|
443
508
|
});
|
|
444
509
|
// Explorer-footer folder attach (desktop only — needs the native picker).
|
|
445
510
|
// Same wiring the retired Workspace tab used.
|
|
@@ -449,7 +514,13 @@ function SessionPanelRegion({ flow, org, panel, accessSlot, onApplied, onImpleme
|
|
|
449
514
|
if (path)
|
|
450
515
|
flow.workspace.addLocalPath(path);
|
|
451
516
|
}, [onBrowseLocalFolder, flow.workspace.addLocalPath]);
|
|
452
|
-
|
|
517
|
+
// Entries decorated with per-entry read refs (the latest write-back commit
|
|
518
|
+
// SHA), so the surface's read-side capabilities — file viewer, tree listing,
|
|
519
|
+
// name search — resolve at the ref the agent's changes actually live on. A
|
|
520
|
+
// read-side projection only: `flow.workspace.entries` stays undecorated for
|
|
521
|
+
// setup and session input.
|
|
522
|
+
const surfaceEntries = useWorkspaceReadRefs(flow.allExecutions, flow.workspace.entries);
|
|
523
|
+
return (_jsx(WorkspaceSurface, { entries: surfaceEntries, lister: workspaceFileLister, reader: workspaceFileReader, searcher: workspaceContentSearcher, view: panel.view, onViewChange: panel.setView, extraViews: railViews, virtualDocuments: virtualDocuments, onRemoveEntry: flow.workspace.remove, onAddLocalFolder: canAddLocalFolder ? handleAddLocalFolder : undefined, editors: editors, selectedFile: activeFile, onOpenFile: panel.openFile, onActivateEditor: panel.activateEditor, onPinEditor: panel.pinEditor, onCloseEditor: panel.closeEditor, onCollapse: panel.closePanel, change: openFileChange ?? undefined, reveal: activeReveal, className: "h-full" }));
|
|
453
524
|
}
|
|
454
525
|
// ---------------------------------------------------------------------------
|
|
455
526
|
// Local sub-components (error states)
|
|
@@ -479,6 +550,15 @@ function AutoApproveIndicator({ onTurnOff }) {
|
|
|
479
550
|
function PlanUnavailableNotice() {
|
|
480
551
|
return (_jsxs("div", { role: "status", className: "mx-auto flex w-full max-w-3xl flex-col items-center gap-1 px-4 py-8 text-center", children: [_jsx("p", { className: "text-xs font-medium text-foreground", children: "This turn ended before a plan was completed." }), _jsx("p", { className: "text-xs text-muted-foreground", children: "Any partial plan text remains in the conversation." })] }));
|
|
481
552
|
}
|
|
553
|
+
/**
|
|
554
|
+
* Shown in an artifact document tab whose artifact is no longer among the
|
|
555
|
+
* session's outputs (an edge only reachable if the executions backing the tab
|
|
556
|
+
* changed underneath it). The tab stays closable; the content is honest rather
|
|
557
|
+
* than blank.
|
|
558
|
+
*/
|
|
559
|
+
function ArtifactUnavailableNotice() {
|
|
560
|
+
return (_jsxs("div", { role: "status", className: "mx-auto flex w-full max-w-3xl flex-col items-center gap-1 px-4 py-8 text-center", children: [_jsx("p", { className: "text-xs font-medium text-foreground", children: "This artifact is no longer available." }), _jsx("p", { className: "text-xs text-muted-foreground", children: "It may have been replaced by a newer version of this session." })] }));
|
|
561
|
+
}
|
|
482
562
|
/**
|
|
483
563
|
* Non-blocking notice for a build that fell back to message-only implement
|
|
484
564
|
* (the approved plan.md could not be uploaded/attached). The build itself
|