@stigmer/react 3.1.2 → 3.1.4
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 +37 -5
- package/composer/SessionComposer.d.ts.map +1 -1
- package/composer/SessionComposer.js +13 -5
- 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 +9 -9
- package/execution/ArtifactPreviewModal.d.ts.map +1 -1
- package/execution/ArtifactPreviewModal.js +18 -145
- 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/FileChangeProgressBar.d.ts +47 -0
- package/execution/FileChangeProgressBar.d.ts.map +1 -0
- package/execution/FileChangeProgressBar.js +49 -0
- package/execution/FileChangeProgressBar.js.map +1 -0
- package/execution/FileChangesView.d.ts.map +1 -1
- package/execution/FileChangesView.js +19 -4
- package/execution/FileChangesView.js.map +1 -1
- package/execution/FileReviewAtoms.d.ts +27 -0
- package/execution/FileReviewAtoms.d.ts.map +1 -0
- package/execution/FileReviewAtoms.js +64 -0
- package/execution/FileReviewAtoms.js.map +1 -0
- package/execution/FileReviewCard.d.ts +2 -2
- package/execution/FileReviewCard.d.ts.map +1 -1
- package/execution/FileReviewCard.js +32 -62
- package/execution/FileReviewCard.js.map +1 -1
- package/execution/MessageEntry.d.ts +0 -9
- package/execution/MessageEntry.d.ts.map +1 -1
- package/execution/MessageEntry.js +1 -11
- package/execution/MessageEntry.js.map +1 -1
- package/execution/MessageThread.d.ts +3 -4
- package/execution/MessageThread.d.ts.map +1 -1
- package/execution/MessageThread.js +25 -11
- package/execution/MessageThread.js.map +1 -1
- package/execution/PlanArtifactCard.d.ts +16 -10
- package/execution/PlanArtifactCard.d.ts.map +1 -1
- package/execution/PlanArtifactCard.js +31 -7
- package/execution/PlanArtifactCard.js.map +1 -1
- package/execution/PlanCompletionCard.d.ts +4 -4
- package/execution/PlanCompletionCard.d.ts.map +1 -1
- package/execution/PlanCompletionCard.js +4 -4
- package/execution/PlanCompletionCard.js.map +1 -1
- package/execution/PlanStreamingCard.d.ts +7 -2
- package/execution/PlanStreamingCard.d.ts.map +1 -1
- package/execution/PlanStreamingCard.js +11 -6
- package/execution/PlanStreamingCard.js.map +1 -1
- package/execution/index.d.ts +12 -2
- package/execution/index.d.ts.map +1 -1
- package/execution/index.js +6 -1
- package/execution/index.js.map +1 -1
- package/execution/use-build-from-plan-hotkey.d.ts +1 -1
- package/execution/use-build-from-plan-hotkey.js +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/useArtifactCopy.d.ts +51 -0
- package/execution/useArtifactCopy.d.ts.map +1 -0
- package/execution/useArtifactCopy.js +75 -0
- package/execution/useArtifactCopy.js.map +1 -0
- package/execution/useArtifactDownload.d.ts.map +1 -1
- package/execution/useArtifactDownload.js +17 -5
- package/execution/useArtifactDownload.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 +16 -3
- package/execution/useCreateAgentExecution.d.ts.map +1 -1
- package/execution/useCreateAgentExecution.js +1 -0
- package/execution/useCreateAgentExecution.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/file-tree/FileTreeNode.d.ts.map +1 -1
- package/internal/file-tree/FileTreeNode.js +2 -2
- package/internal/file-tree/FileTreeNode.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/library/detect-plan-artifact.d.ts +27 -9
- package/library/detect-plan-artifact.d.ts.map +1 -1
- package/library/detect-plan-artifact.js +26 -6
- package/library/detect-plan-artifact.js.map +1 -1
- package/library/index.d.ts +1 -1
- package/library/index.d.ts.map +1 -1
- package/library/index.js +1 -1
- package/library/index.js.map +1 -1
- package/package.json +5 -4
- package/session/PlanEditor.js +1 -1
- package/session/PlanEditor.js.map +1 -1
- package/session/SessionViewer.d.ts.map +1 -1
- package/session/SessionViewer.js +122 -30
- 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 +2 -1
- package/session/index.d.ts.map +1 -1
- package/session/index.js +4 -1
- package/session/index.js.map +1 -1
- package/session/plan-document.d.ts +14 -2
- package/session/plan-document.d.ts.map +1 -1
- package/session/plan-document.js +14 -3
- package/session/plan-document.js.map +1 -1
- package/session/usePlanDraft.d.ts +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 +26 -3
- package/session/useSessionConversation.d.ts.map +1 -1
- package/session/useSessionConversation.js +51 -6
- 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/src/composer/SessionComposer.tsx +76 -7
- 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 +49 -415
- package/src/execution/ArtifactRow.tsx +165 -0
- package/src/execution/ArtifactsWidget.tsx +24 -33
- package/src/execution/FileChangeProgressBar.tsx +121 -0
- package/src/execution/FileChangesView.tsx +18 -4
- package/src/execution/FileReviewAtoms.tsx +89 -0
- package/src/execution/FileReviewCard.tsx +57 -90
- package/src/execution/MessageEntry.tsx +0 -62
- package/src/execution/MessageThread.tsx +29 -15
- package/src/execution/PlanArtifactCard.tsx +130 -52
- package/src/execution/PlanCompletionCard.tsx +5 -5
- package/src/execution/PlanStreamingCard.tsx +15 -11
- package/src/execution/__tests__/ArtifactContentBody.test.tsx +131 -0
- package/src/execution/__tests__/ArtifactDocument.test.tsx +100 -0
- package/src/execution/__tests__/ArtifactPreviewModal.test.tsx +6 -6
- package/src/execution/__tests__/ArtifactRow.test.tsx +139 -0
- package/src/execution/__tests__/ArtifactsWidget.test.tsx +78 -0
- package/src/execution/__tests__/FileChangeProgressBar.test.tsx +125 -0
- package/src/execution/__tests__/FileReviewCard.test.tsx +66 -7
- package/src/execution/__tests__/MessageThread.test.tsx +1 -1
- package/src/execution/__tests__/PlanArtifactCard.test.tsx +52 -18
- package/src/execution/__tests__/PlanCompletionCard.test.tsx +2 -2
- package/src/execution/__tests__/PlanStreamingCard.test.tsx +11 -4
- package/src/execution/__tests__/buildThreadItems-plan-completion.test.ts +104 -8
- package/src/execution/__tests__/message-entry.test.tsx +56 -39
- package/src/execution/__tests__/useArtifactCopy.test.tsx +90 -0
- package/src/execution/__tests__/useArtifactDownload.test.tsx +2 -0
- package/src/execution/__tests__/useArtifactInspection.test.tsx +151 -0
- package/src/execution/__tests__/useCreateAgentExecution.test.tsx +35 -0
- package/src/execution/index.ts +20 -2
- package/src/execution/use-build-from-plan-hotkey.ts +1 -1
- package/src/execution/useArtifactContent.ts +7 -0
- package/src/execution/useArtifactCopy.ts +109 -0
- package/src/execution/useArtifactDownload.ts +17 -5
- package/src/execution/useArtifactInspection.ts +252 -0
- package/src/execution/useCreateAgentExecution.ts +17 -3
- package/src/index.ts +17 -2
- package/src/internal/MermaidDiagram.tsx +164 -0
- 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/file-tree/FileTreeNode.tsx +13 -2
- 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/library/__tests__/detect-plan-artifact.test.ts +21 -0
- package/src/library/detect-plan-artifact.ts +32 -10
- package/src/library/index.ts +2 -0
- package/src/session/PlanEditor.tsx +1 -1
- package/src/session/SessionViewer.tsx +227 -51
- package/src/session/__tests__/PlanEditor.test.tsx +4 -4
- package/src/session/__tests__/PlanStreamingDocument.test.tsx +1 -1
- package/src/session/__tests__/SessionViewer-artifactTabs.test.tsx +210 -0
- package/src/session/__tests__/SessionViewer-editResubmit.test.tsx +233 -0
- package/src/session/__tests__/SessionViewer-fileReviewDock.test.tsx +57 -0
- package/src/session/__tests__/useSessionArtifacts.test.ts +57 -0
- package/src/session/__tests__/useSessionConversation.test.tsx +216 -1
- package/src/session/__tests__/useSessionPanel.test.ts +70 -1
- 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 +5 -1
- package/src/session/plan-document.ts +14 -3
- package/src/session/usePlanDraft.ts +1 -1
- package/src/session/useSessionArtifacts.ts +16 -5
- package/src/session/useSessionConversation.ts +80 -10
- package/src/session/useSessionPageFlow.ts +1 -0
- package/src/session/useSessionPanel.ts +41 -0
- package/src/session/useSessionRailViews.tsx +21 -1
- package/src/workspace/EditorTabs.tsx +38 -9
- package/src/workspace/ExplorerTree.tsx +10 -4
- package/src/workspace/FileViewer.tsx +27 -6
- package/src/workspace/WorkspaceContentSearch.tsx +44 -20
- package/src/workspace/WorkspaceEditor.tsx +19 -16
- package/src/workspace/WorkspaceFileSearch.tsx +51 -28
- package/src/workspace/WorkspaceSurface.tsx +106 -48
- package/src/workspace/__tests__/EditorTabs.test.tsx +4 -2
- package/src/workspace/__tests__/ExplorerTree.test.tsx +52 -0
- package/src/workspace/__tests__/FileViewer.test.tsx +18 -0
- package/src/workspace/__tests__/WorkspaceContentSearch.test.tsx +38 -5
- package/src/workspace/__tests__/WorkspaceEditor-initialPanel.test.tsx +19 -0
- package/src/workspace/__tests__/WorkspaceFileSearch.test.tsx +27 -6
- package/src/workspace/__tests__/WorkspaceSurface.test.tsx +70 -0
- package/src/workspace/__tests__/a11y/harness.tsx +140 -0
- package/src/workspace/__tests__/a11y/mock-capabilities.ts +138 -0
- package/src/workspace/__tests__/a11y/workspace-editor.a11y.test.tsx +65 -0
- package/src/workspace/__tests__/a11y/workspace-explorer-search.a11y.test.tsx +112 -0
- package/src/workspace/__tests__/a11y/workspace-viewer-tabs.a11y.test.tsx +69 -0
- package/styles.css +1 -1
- package/workspace/EditorTabs.d.ts +21 -3
- package/workspace/EditorTabs.d.ts.map +1 -1
- package/workspace/EditorTabs.js +18 -6
- package/workspace/EditorTabs.js.map +1 -1
- package/workspace/ExplorerTree.js +8 -4
- package/workspace/ExplorerTree.js.map +1 -1
- package/workspace/FileViewer.d.ts.map +1 -1
- package/workspace/FileViewer.js +19 -8
- package/workspace/FileViewer.js.map +1 -1
- package/workspace/WorkspaceContentSearch.d.ts.map +1 -1
- package/workspace/WorkspaceContentSearch.js +23 -2
- package/workspace/WorkspaceContentSearch.js.map +1 -1
- package/workspace/WorkspaceEditor.d.ts.map +1 -1
- package/workspace/WorkspaceEditor.js +8 -10
- package/workspace/WorkspaceEditor.js.map +1 -1
- package/workspace/WorkspaceFileSearch.d.ts.map +1 -1
- package/workspace/WorkspaceFileSearch.js +23 -3
- package/workspace/WorkspaceFileSearch.js.map +1 -1
- package/workspace/WorkspaceSurface.d.ts.map +1 -1
- package/workspace/WorkspaceSurface.js +54 -18
- package/workspace/WorkspaceSurface.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
|
@@ -1,22 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { useCallback, useEffect, useRef
|
|
3
|
+
import { useCallback, useEffect, useRef } from "react";
|
|
4
4
|
import type { ExecutionArtifact } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/artifact_pb";
|
|
5
|
-
import { ExecutionArtifactKind } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
6
5
|
import { cn } from "@stigmer/theme";
|
|
7
|
-
import { useArtifactContent } from "./useArtifactContent.js";
|
|
8
6
|
import { useArtifactDownload } from "./useArtifactDownload.js";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import type {
|
|
14
|
-
import {
|
|
15
|
-
useApplyResource,
|
|
16
|
-
type ApplyResourceResult,
|
|
17
|
-
} from "../library/useApplyResource.js";
|
|
18
|
-
|
|
19
|
-
const COPIED_FEEDBACK_MS = 2000;
|
|
7
|
+
import { formatArtifactSize } from "./artifact-utils.js";
|
|
8
|
+
import { ArtifactContentBody } from "./ArtifactContentBody.js";
|
|
9
|
+
import { ArtifactApplyButton } from "./ArtifactApplyButton.js";
|
|
10
|
+
import { useArtifactInspection } from "./useArtifactInspection.js";
|
|
11
|
+
import type { ApplyResourceResult } from "../library/useApplyResource.js";
|
|
20
12
|
|
|
21
13
|
// ---------------------------------------------------------------------------
|
|
22
14
|
// ArtifactPreviewContent — standalone content component
|
|
@@ -47,10 +39,10 @@ export interface ArtifactPreviewContentProps {
|
|
|
47
39
|
*/
|
|
48
40
|
readonly onApplied?: (result: ApplyResourceResult) => void;
|
|
49
41
|
/**
|
|
50
|
-
* Optional plan-build action. When provided, a "Build
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
42
|
+
* Optional plan-build action. When provided, a "Build" primary button
|
|
43
|
+
* appears in the action bar (used for plan artifacts: turn the plan into
|
|
44
|
+
* an Agent run). Clicking it calls `onImplement` then closes the modal.
|
|
45
|
+
* Omit for non-actionable artifacts.
|
|
54
46
|
*/
|
|
55
47
|
readonly onImplement?: () => void;
|
|
56
48
|
/** Additional CSS classes for the root container. */
|
|
@@ -66,7 +58,7 @@ export interface ArtifactPreviewContentProps {
|
|
|
66
58
|
* it inside a `<dialog>`, modal, sheet, overlay, or inline context as
|
|
67
59
|
* needed.
|
|
68
60
|
*
|
|
69
|
-
* Orchestrates the
|
|
61
|
+
* Orchestrates the shared detection pipeline (see {@link useArtifactInspection}):
|
|
70
62
|
*
|
|
71
63
|
* - **FILE artifacts**: Fetches text content via {@link useArtifactContent},
|
|
72
64
|
* renders via {@link ArtifactContentRenderer} (markdown, YAML, JSON, or
|
|
@@ -96,7 +88,7 @@ export interface ArtifactPreviewContentProps {
|
|
|
96
88
|
* ```
|
|
97
89
|
*
|
|
98
90
|
* @see {@link ArtifactPreviewModal} — wraps this component in a native `<dialog>`
|
|
99
|
-
* @see {@link
|
|
91
|
+
* @see {@link ArtifactRow} — dense list row that triggers preview via `onOpen`
|
|
100
92
|
* @see {@link useArtifactContent} — content-fetching hook (headless alternative)
|
|
101
93
|
* @see {@link useDetectStigmerResource} — YAML resource detection (headless)
|
|
102
94
|
* @see {@link useDetectSkillPackage} — skill package detection (headless)
|
|
@@ -112,176 +104,56 @@ export function ArtifactPreviewContent({
|
|
|
112
104
|
onImplement,
|
|
113
105
|
className,
|
|
114
106
|
}: ArtifactPreviewContentProps) {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
// Detection orchestration
|
|
120
|
-
// ---------------------------------------------------------------------------
|
|
121
|
-
|
|
122
|
-
const {
|
|
123
|
-
content,
|
|
124
|
-
contentType,
|
|
125
|
-
isTruncated,
|
|
126
|
-
isLoading: isContentLoading,
|
|
127
|
-
error: contentError,
|
|
128
|
-
} = useArtifactContent(
|
|
129
|
-
canFetchContent ? executionId : null,
|
|
130
|
-
canFetchContent ? artifact.storageKey : null,
|
|
131
|
-
undefined,
|
|
132
|
-
artifact.contentHash || undefined,
|
|
133
|
-
);
|
|
134
|
-
|
|
135
|
-
const yamlDetection = useDetectStigmerResource(
|
|
136
|
-
canFetchContent ? content : null,
|
|
137
|
-
);
|
|
138
|
-
|
|
139
|
-
const { detection: skillDetection, isLoading: isSkillLoading } =
|
|
140
|
-
useDetectSkillPackage(
|
|
141
|
-
isDirectory ? artifact : null,
|
|
142
|
-
isDirectory ? executionId : null,
|
|
143
|
-
);
|
|
144
|
-
|
|
145
|
-
// ---------------------------------------------------------------------------
|
|
146
|
-
// Derived detection state
|
|
147
|
-
// ---------------------------------------------------------------------------
|
|
148
|
-
|
|
149
|
-
const isDetected = yamlDetection.detected || skillDetection.detected;
|
|
150
|
-
const isDetecting =
|
|
151
|
-
(canFetchContent && isContentLoading) || (isDirectory && isSkillLoading);
|
|
152
|
-
|
|
153
|
-
let detectionLabel: string | null = null;
|
|
154
|
-
if (yamlDetection.detected) {
|
|
155
|
-
detectionLabel = `${yamlDetection.displayName} detected`;
|
|
156
|
-
} else if (skillDetection.detected) {
|
|
157
|
-
const count = skillDetection.fileCount;
|
|
158
|
-
detectionLabel = `Skill \u00B7 ${count} ${count === 1 ? "file" : "files"}`;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// ---------------------------------------------------------------------------
|
|
162
|
-
// Apply state
|
|
163
|
-
// ---------------------------------------------------------------------------
|
|
164
|
-
|
|
165
|
-
const {
|
|
166
|
-
applyYamlResource,
|
|
167
|
-
pushSkillPackage,
|
|
168
|
-
isApplying,
|
|
169
|
-
error: applyError,
|
|
170
|
-
clearError,
|
|
171
|
-
} = useApplyResource();
|
|
172
|
-
|
|
173
|
-
const [applyResult, setApplyResult] = useState<ApplyResourceResult | null>(
|
|
174
|
-
null,
|
|
175
|
-
);
|
|
176
|
-
|
|
177
|
-
const handleApply = useCallback(async () => {
|
|
178
|
-
clearError();
|
|
179
|
-
try {
|
|
180
|
-
let result: ApplyResourceResult;
|
|
181
|
-
if (yamlDetection.detected && content) {
|
|
182
|
-
result = await applyYamlResource(content, org);
|
|
183
|
-
} else if (skillDetection.detected) {
|
|
184
|
-
result = await pushSkillPackage({
|
|
185
|
-
org,
|
|
186
|
-
executionId,
|
|
187
|
-
storageKey: artifact.storageKey,
|
|
188
|
-
});
|
|
189
|
-
} else {
|
|
190
|
-
return;
|
|
191
|
-
}
|
|
192
|
-
setApplyResult(result);
|
|
193
|
-
onApplied?.(result);
|
|
194
|
-
} catch {
|
|
195
|
-
// error state managed by useApplyResource
|
|
196
|
-
}
|
|
197
|
-
}, [
|
|
198
|
-
yamlDetection.detected,
|
|
199
|
-
skillDetection.detected,
|
|
200
|
-
content,
|
|
201
|
-
org,
|
|
202
|
-
executionId,
|
|
203
|
-
artifact.storageKey,
|
|
204
|
-
applyYamlResource,
|
|
205
|
-
pushSkillPackage,
|
|
206
|
-
clearError,
|
|
107
|
+
// The whole inspect-and-act pipeline (content, detection, apply/push, copy)
|
|
108
|
+
// lives in one headless hook, shared with the editor-area ArtifactDocument so
|
|
109
|
+
// the two surfaces can never drift.
|
|
110
|
+
const inspection = useArtifactInspection(artifact, executionId, org, {
|
|
207
111
|
onApplied,
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
//
|
|
211
|
-
//
|
|
212
|
-
//
|
|
213
|
-
|
|
214
|
-
const [copied, setCopied] = useState(false);
|
|
215
|
-
|
|
216
|
-
const handleCopy = useCallback(() => {
|
|
217
|
-
if (!content) return;
|
|
218
|
-
navigator.clipboard.writeText(content).then(() => {
|
|
219
|
-
setCopied(true);
|
|
220
|
-
setTimeout(() => setCopied(false), COPIED_FEEDBACK_MS);
|
|
221
|
-
});
|
|
222
|
-
}, [content]);
|
|
223
|
-
|
|
224
|
-
let ctaLabel: string | null = null;
|
|
225
|
-
if (yamlDetection.detected) {
|
|
226
|
-
ctaLabel = `Apply to ${org}`;
|
|
227
|
-
} else if (skillDetection.detected) {
|
|
228
|
-
ctaLabel = `Push Skill to ${org}`;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// "Build from plan" runs the plan; closing the modal lets the host's submit
|
|
232
|
-
// pipeline take over (switch to Agent + send). Single combined handler keeps
|
|
233
|
-
// the caller's contract simple ("just give me onImplement").
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// "Build" runs the plan; closing the modal lets the host's submit pipeline
|
|
115
|
+
// take over (switch to Agent + send). Single combined handler keeps the
|
|
116
|
+
// caller's contract simple ("just give me onImplement").
|
|
234
117
|
const handleImplement = useCallback(() => {
|
|
235
118
|
onImplement?.();
|
|
236
119
|
onClose();
|
|
237
120
|
}, [onImplement, onClose]);
|
|
238
121
|
|
|
239
|
-
// ---------------------------------------------------------------------------
|
|
240
|
-
// Render
|
|
241
|
-
// ---------------------------------------------------------------------------
|
|
242
|
-
|
|
243
122
|
return (
|
|
244
123
|
<div className={cn("flex max-h-[80vh] flex-col", className)}>
|
|
245
124
|
<ContentHeader
|
|
246
125
|
artifact={artifact}
|
|
247
|
-
isDirectory={isDirectory}
|
|
248
|
-
detectionLabel={detectionLabel}
|
|
249
|
-
isDetecting={isDetecting}
|
|
126
|
+
isDirectory={inspection.isDirectory}
|
|
127
|
+
detectionLabel={inspection.detectionLabel}
|
|
128
|
+
isDetecting={inspection.isDetecting}
|
|
250
129
|
onClose={onClose}
|
|
251
130
|
/>
|
|
252
131
|
|
|
253
|
-
<
|
|
254
|
-
{
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
contentType={contentType}
|
|
264
|
-
isLoading={isContentLoading}
|
|
265
|
-
error={contentError}
|
|
266
|
-
isTruncated={isTruncated}
|
|
267
|
-
/>
|
|
268
|
-
)}
|
|
269
|
-
</div>
|
|
132
|
+
<ArtifactContentBody
|
|
133
|
+
artifact={artifact}
|
|
134
|
+
content={inspection.content}
|
|
135
|
+
contentType={inspection.contentType}
|
|
136
|
+
isLoading={inspection.isLoading}
|
|
137
|
+
error={inspection.error}
|
|
138
|
+
isTruncated={inspection.isTruncated}
|
|
139
|
+
skillDetection={inspection.skillDetection}
|
|
140
|
+
className="min-h-0 flex-1 overflow-y-auto border-t border-border"
|
|
141
|
+
/>
|
|
270
142
|
|
|
271
143
|
<ActionBar
|
|
272
144
|
artifact={artifact}
|
|
273
145
|
executionId={executionId}
|
|
274
|
-
isDirectory={isDirectory}
|
|
275
|
-
hasContent={content !== null}
|
|
276
|
-
copied={copied}
|
|
277
|
-
onCopy={
|
|
278
|
-
isDetected={isDetected}
|
|
279
|
-
ctaLabel={ctaLabel}
|
|
146
|
+
isDirectory={inspection.isDirectory}
|
|
147
|
+
hasContent={inspection.content !== null}
|
|
148
|
+
copied={inspection.copied}
|
|
149
|
+
onCopy={inspection.copy}
|
|
150
|
+
isDetected={inspection.isDetected}
|
|
151
|
+
ctaLabel={inspection.ctaLabel}
|
|
280
152
|
isTerminal={isTerminal}
|
|
281
|
-
isApplying={isApplying}
|
|
282
|
-
applyResult={applyResult}
|
|
283
|
-
applyError={applyError}
|
|
284
|
-
onApply={
|
|
153
|
+
isApplying={inspection.isApplying}
|
|
154
|
+
applyResult={inspection.applyResult}
|
|
155
|
+
applyError={inspection.applyError}
|
|
156
|
+
onApply={inspection.apply}
|
|
285
157
|
onImplement={onImplement ? handleImplement : undefined}
|
|
286
158
|
/>
|
|
287
159
|
|
|
@@ -291,7 +163,7 @@ export function ArtifactPreviewContent({
|
|
|
291
163
|
aria-atomic="true"
|
|
292
164
|
className="sr-only"
|
|
293
165
|
>
|
|
294
|
-
{copied && "Content copied to clipboard"}
|
|
166
|
+
{inspection.copied && "Content copied to clipboard"}
|
|
295
167
|
</div>
|
|
296
168
|
</div>
|
|
297
169
|
);
|
|
@@ -329,7 +201,7 @@ export interface ArtifactPreviewModalProps {
|
|
|
329
201
|
readonly onApplied?: (result: ApplyResourceResult) => void;
|
|
330
202
|
/**
|
|
331
203
|
* Optional plan-build action (see {@link ArtifactPreviewContentProps.onImplement}).
|
|
332
|
-
* When provided, a "Build
|
|
204
|
+
* When provided, a "Build" primary button appears; clicking it calls
|
|
333
205
|
* `onImplement` then closes the modal.
|
|
334
206
|
*/
|
|
335
207
|
readonly onImplement?: () => void;
|
|
@@ -368,7 +240,7 @@ export interface ArtifactPreviewModalProps {
|
|
|
368
240
|
* ```
|
|
369
241
|
*
|
|
370
242
|
* @see {@link ArtifactPreviewContent} — the content component (use directly for non-dialog contexts)
|
|
371
|
-
* @see {@link
|
|
243
|
+
* @see {@link ArtifactRow} — dense list row that triggers preview via `onOpen`
|
|
372
244
|
*/
|
|
373
245
|
export function ArtifactPreviewModal({
|
|
374
246
|
artifact,
|
|
@@ -496,128 +368,6 @@ function ContentHeader({
|
|
|
496
368
|
);
|
|
497
369
|
}
|
|
498
370
|
|
|
499
|
-
// ---------------------------------------------------------------------------
|
|
500
|
-
// FileContentStateView (internal — loading/error/empty states + renderer)
|
|
501
|
-
// ---------------------------------------------------------------------------
|
|
502
|
-
|
|
503
|
-
const SKELETON_LINE_WIDTHS = [85, 72, 90, 65, 78, 88, 70, 82] as const;
|
|
504
|
-
|
|
505
|
-
function FileContentStateView({
|
|
506
|
-
artifact,
|
|
507
|
-
content,
|
|
508
|
-
contentType,
|
|
509
|
-
isLoading,
|
|
510
|
-
error,
|
|
511
|
-
isTruncated,
|
|
512
|
-
}: {
|
|
513
|
-
readonly artifact: ExecutionArtifact;
|
|
514
|
-
readonly content: string | null;
|
|
515
|
-
readonly contentType: string | null;
|
|
516
|
-
readonly isLoading: boolean;
|
|
517
|
-
readonly error: Error | null;
|
|
518
|
-
readonly isTruncated: boolean;
|
|
519
|
-
}) {
|
|
520
|
-
if (isLoading) {
|
|
521
|
-
return (
|
|
522
|
-
<div className="space-y-2 p-4" aria-busy="true" aria-label="Loading content">
|
|
523
|
-
{SKELETON_LINE_WIDTHS.map((width, i) => (
|
|
524
|
-
<div
|
|
525
|
-
key={i}
|
|
526
|
-
className="h-4 animate-pulse rounded bg-muted"
|
|
527
|
-
style={{ width: `${width}%` }}
|
|
528
|
-
aria-hidden="true"
|
|
529
|
-
/>
|
|
530
|
-
))}
|
|
531
|
-
</div>
|
|
532
|
-
);
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
if (error) {
|
|
536
|
-
return (
|
|
537
|
-
<div className="flex flex-col items-center justify-center gap-2 p-8 text-center">
|
|
538
|
-
<ErrorAlertIcon />
|
|
539
|
-
<p className="text-sm text-destructive">{error.message}</p>
|
|
540
|
-
</div>
|
|
541
|
-
);
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
if (content === null) {
|
|
545
|
-
return (
|
|
546
|
-
<div className="p-8 text-center text-sm text-muted-foreground">
|
|
547
|
-
Content not available for preview.
|
|
548
|
-
</div>
|
|
549
|
-
);
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
return (
|
|
553
|
-
<ArtifactContentRenderer
|
|
554
|
-
content={content}
|
|
555
|
-
fileName={artifact.name}
|
|
556
|
-
contentType={contentType}
|
|
557
|
-
isTruncated={isTruncated}
|
|
558
|
-
/>
|
|
559
|
-
);
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
// ---------------------------------------------------------------------------
|
|
563
|
-
// DirectoryContentView (internal)
|
|
564
|
-
// ---------------------------------------------------------------------------
|
|
565
|
-
|
|
566
|
-
function DirectoryContentView({
|
|
567
|
-
artifact,
|
|
568
|
-
skillDetection,
|
|
569
|
-
}: {
|
|
570
|
-
readonly artifact: ExecutionArtifact;
|
|
571
|
-
readonly skillDetection: SkillPackageDetection;
|
|
572
|
-
}) {
|
|
573
|
-
const entries = artifact.entries;
|
|
574
|
-
|
|
575
|
-
return (
|
|
576
|
-
<div className="p-4">
|
|
577
|
-
{skillDetection.detected && (
|
|
578
|
-
<div className="mb-4 rounded-md bg-primary-subtle p-3">
|
|
579
|
-
<p className="text-sm font-medium text-foreground">
|
|
580
|
-
{skillDetection.skillName}
|
|
581
|
-
</p>
|
|
582
|
-
{skillDetection.skillDescription && (
|
|
583
|
-
<p className="mt-1 text-xs text-muted-foreground">
|
|
584
|
-
{skillDetection.skillDescription}
|
|
585
|
-
</p>
|
|
586
|
-
)}
|
|
587
|
-
</div>
|
|
588
|
-
)}
|
|
589
|
-
|
|
590
|
-
{entries.length > 0 ? (
|
|
591
|
-
<div>
|
|
592
|
-
<h3 className="mb-2 text-xs font-medium text-muted-foreground">
|
|
593
|
-
Files ({entries.length})
|
|
594
|
-
</h3>
|
|
595
|
-
<ul className="space-y-0.5" role="list">
|
|
596
|
-
{entries.map((entry) => (
|
|
597
|
-
<li
|
|
598
|
-
key={entry}
|
|
599
|
-
className="flex items-center gap-2 rounded-sm px-2 py-1 font-mono text-xs text-foreground"
|
|
600
|
-
>
|
|
601
|
-
<EntryIcon name={entry} />
|
|
602
|
-
<span className="min-w-0 truncate">{entry}</span>
|
|
603
|
-
</li>
|
|
604
|
-
))}
|
|
605
|
-
</ul>
|
|
606
|
-
</div>
|
|
607
|
-
) : (
|
|
608
|
-
<p className="text-sm text-muted-foreground">
|
|
609
|
-
File listing not available.
|
|
610
|
-
</p>
|
|
611
|
-
)}
|
|
612
|
-
</div>
|
|
613
|
-
);
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
function EntryIcon({ name }: { readonly name: string }) {
|
|
617
|
-
if (name.endsWith("/")) return <FolderSmallIcon />;
|
|
618
|
-
return <FileSmallIcon />;
|
|
619
|
-
}
|
|
620
|
-
|
|
621
371
|
// ---------------------------------------------------------------------------
|
|
622
372
|
// ActionBar (internal)
|
|
623
373
|
// ---------------------------------------------------------------------------
|
|
@@ -701,7 +451,7 @@ function ActionBar({
|
|
|
701
451
|
)}
|
|
702
452
|
>
|
|
703
453
|
<ImplementIcon />
|
|
704
|
-
Build
|
|
454
|
+
Build
|
|
705
455
|
</button>
|
|
706
456
|
)}
|
|
707
457
|
{applyResult ? (
|
|
@@ -727,7 +477,7 @@ function ActionBar({
|
|
|
727
477
|
</span>
|
|
728
478
|
) : isDetected && ctaLabel ? (
|
|
729
479
|
<span data-cursor-target="apply-resource-button">
|
|
730
|
-
<
|
|
480
|
+
<ArtifactApplyButton
|
|
731
481
|
label={ctaLabel}
|
|
732
482
|
isTerminal={isTerminal}
|
|
733
483
|
isApplying={isApplying}
|
|
@@ -740,46 +490,6 @@ function ActionBar({
|
|
|
740
490
|
);
|
|
741
491
|
}
|
|
742
492
|
|
|
743
|
-
function ApplyButton({
|
|
744
|
-
label,
|
|
745
|
-
isTerminal,
|
|
746
|
-
isApplying,
|
|
747
|
-
onApply,
|
|
748
|
-
}: {
|
|
749
|
-
readonly label: string;
|
|
750
|
-
readonly isTerminal: boolean;
|
|
751
|
-
readonly isApplying: boolean;
|
|
752
|
-
readonly onApply: () => void;
|
|
753
|
-
}) {
|
|
754
|
-
const canApply = isTerminal && !isApplying;
|
|
755
|
-
|
|
756
|
-
return (
|
|
757
|
-
<button
|
|
758
|
-
type="button"
|
|
759
|
-
onClick={canApply ? onApply : undefined}
|
|
760
|
-
disabled={!canApply}
|
|
761
|
-
aria-busy={isApplying}
|
|
762
|
-
className={cn(
|
|
763
|
-
"rounded-md px-4 py-1.5 text-xs font-medium transition-colors",
|
|
764
|
-
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
765
|
-
"disabled:cursor-not-allowed",
|
|
766
|
-
canApply
|
|
767
|
-
? "bg-primary text-primary-foreground hover:bg-primary-hover"
|
|
768
|
-
: "bg-muted text-muted-foreground",
|
|
769
|
-
)}
|
|
770
|
-
>
|
|
771
|
-
{isApplying ? (
|
|
772
|
-
<span className="inline-flex items-center gap-1.5">
|
|
773
|
-
<SpinnerIcon />
|
|
774
|
-
Applying{"\u2026"}
|
|
775
|
-
</span>
|
|
776
|
-
) : (
|
|
777
|
-
label
|
|
778
|
-
)}
|
|
779
|
-
</button>
|
|
780
|
-
);
|
|
781
|
-
}
|
|
782
|
-
|
|
783
493
|
// ---------------------------------------------------------------------------
|
|
784
494
|
// Inline SVG icons (SDK pattern: no external icon dependency)
|
|
785
495
|
// ---------------------------------------------------------------------------
|
|
@@ -840,45 +550,6 @@ function FolderIcon() {
|
|
|
840
550
|
);
|
|
841
551
|
}
|
|
842
552
|
|
|
843
|
-
function FileSmallIcon() {
|
|
844
|
-
return (
|
|
845
|
-
<svg
|
|
846
|
-
width="12"
|
|
847
|
-
height="12"
|
|
848
|
-
viewBox="0 0 14 14"
|
|
849
|
-
fill="none"
|
|
850
|
-
stroke="currentColor"
|
|
851
|
-
strokeWidth="1.5"
|
|
852
|
-
strokeLinecap="round"
|
|
853
|
-
strokeLinejoin="round"
|
|
854
|
-
className="shrink-0 text-muted-foreground"
|
|
855
|
-
aria-hidden="true"
|
|
856
|
-
>
|
|
857
|
-
<path d="M8 1H4C3.45 1 3 1.45 3 2V12C3 12.55 3.45 13 4 13H10C10.55 13 11 12.55 11 12V4L8 1Z" />
|
|
858
|
-
<path d="M8 1V4H11" />
|
|
859
|
-
</svg>
|
|
860
|
-
);
|
|
861
|
-
}
|
|
862
|
-
|
|
863
|
-
function FolderSmallIcon() {
|
|
864
|
-
return (
|
|
865
|
-
<svg
|
|
866
|
-
width="12"
|
|
867
|
-
height="12"
|
|
868
|
-
viewBox="0 0 14 14"
|
|
869
|
-
fill="none"
|
|
870
|
-
stroke="currentColor"
|
|
871
|
-
strokeWidth="1.5"
|
|
872
|
-
strokeLinecap="round"
|
|
873
|
-
strokeLinejoin="round"
|
|
874
|
-
className="shrink-0 text-muted-foreground"
|
|
875
|
-
aria-hidden="true"
|
|
876
|
-
>
|
|
877
|
-
<path d="M13 11C13 11.55 12.55 12 12 12H2C1.45 12 1 11.55 1 11V3C1 2.45 1.45 2 2 2H5L7 4H12C12.55 4 13 4.45 13 5V11Z" />
|
|
878
|
-
</svg>
|
|
879
|
-
);
|
|
880
|
-
}
|
|
881
|
-
|
|
882
553
|
function CopyIcon() {
|
|
883
554
|
return (
|
|
884
555
|
<svg
|
|
@@ -958,40 +629,3 @@ function CheckIcon() {
|
|
|
958
629
|
);
|
|
959
630
|
}
|
|
960
631
|
|
|
961
|
-
function SpinnerIcon() {
|
|
962
|
-
return (
|
|
963
|
-
<svg
|
|
964
|
-
width="12"
|
|
965
|
-
height="12"
|
|
966
|
-
viewBox="0 0 12 12"
|
|
967
|
-
fill="none"
|
|
968
|
-
stroke="currentColor"
|
|
969
|
-
strokeWidth="1.5"
|
|
970
|
-
className="shrink-0 animate-spin"
|
|
971
|
-
aria-hidden="true"
|
|
972
|
-
>
|
|
973
|
-
<path d="M6 1.5A4.5 4.5 0 1 1 1.5 6" strokeLinecap="round" />
|
|
974
|
-
</svg>
|
|
975
|
-
);
|
|
976
|
-
}
|
|
977
|
-
|
|
978
|
-
function ErrorAlertIcon() {
|
|
979
|
-
return (
|
|
980
|
-
<svg
|
|
981
|
-
width="16"
|
|
982
|
-
height="16"
|
|
983
|
-
viewBox="0 0 16 16"
|
|
984
|
-
fill="none"
|
|
985
|
-
stroke="currentColor"
|
|
986
|
-
strokeWidth="1.5"
|
|
987
|
-
strokeLinecap="round"
|
|
988
|
-
strokeLinejoin="round"
|
|
989
|
-
className="text-destructive"
|
|
990
|
-
aria-hidden="true"
|
|
991
|
-
>
|
|
992
|
-
<circle cx="8" cy="8" r="6.5" />
|
|
993
|
-
<path d="M8 5.5V8.5" />
|
|
994
|
-
<circle cx="8" cy="11" r="0.5" fill="currentColor" stroke="none" />
|
|
995
|
-
</svg>
|
|
996
|
-
);
|
|
997
|
-
}
|