@stigmer/react 0.0.51 → 0.0.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/deployment-mode.d.ts +35 -0
  2. package/deployment-mode.d.ts.map +1 -0
  3. package/deployment-mode.js +41 -0
  4. package/deployment-mode.js.map +1 -0
  5. package/execution/ApprovalCard.d.ts +8 -6
  6. package/execution/ApprovalCard.d.ts.map +1 -1
  7. package/execution/ApprovalCard.js +34 -96
  8. package/execution/ApprovalCard.js.map +1 -1
  9. package/execution/McpToolDetail.d.ts +48 -0
  10. package/execution/McpToolDetail.d.ts.map +1 -0
  11. package/execution/McpToolDetail.js +159 -0
  12. package/execution/McpToolDetail.js.map +1 -0
  13. package/execution/ToolArgsView.d.ts +41 -0
  14. package/execution/ToolArgsView.d.ts.map +1 -0
  15. package/execution/ToolArgsView.js +132 -0
  16. package/execution/ToolArgsView.js.map +1 -0
  17. package/execution/ToolCallDetail.d.ts +11 -4
  18. package/execution/ToolCallDetail.d.ts.map +1 -1
  19. package/execution/ToolCallDetail.js +30 -101
  20. package/execution/ToolCallDetail.js.map +1 -1
  21. package/execution/ToolCallGroup.d.ts.map +1 -1
  22. package/execution/ToolCallGroup.js +3 -2
  23. package/execution/ToolCallGroup.js.map +1 -1
  24. package/execution/ToolCallItem.d.ts +2 -0
  25. package/execution/ToolCallItem.d.ts.map +1 -1
  26. package/execution/ToolCallItem.js +6 -2
  27. package/execution/ToolCallItem.js.map +1 -1
  28. package/execution/index.d.ts +7 -1
  29. package/execution/index.d.ts.map +1 -1
  30. package/execution/index.js +4 -1
  31. package/execution/index.js.map +1 -1
  32. package/execution/tool-categories.d.ts +35 -8
  33. package/execution/tool-categories.d.ts.map +1 -1
  34. package/execution/tool-categories.js +76 -10
  35. package/execution/tool-categories.js.map +1 -1
  36. package/execution/tool-rendering-primitives.d.ts +61 -0
  37. package/execution/tool-rendering-primitives.d.ts.map +1 -0
  38. package/execution/tool-rendering-primitives.js +106 -0
  39. package/execution/tool-rendering-primitives.js.map +1 -0
  40. package/index.d.ts +5 -2
  41. package/index.d.ts.map +1 -1
  42. package/index.js +5 -1
  43. package/index.js.map +1 -1
  44. package/internal/CloudFeatureNotice.d.ts +19 -0
  45. package/internal/CloudFeatureNotice.d.ts.map +1 -0
  46. package/internal/CloudFeatureNotice.js +21 -0
  47. package/internal/CloudFeatureNotice.js.map +1 -0
  48. package/mcp-server/McpServerDetailView.d.ts +15 -1
  49. package/mcp-server/McpServerDetailView.d.ts.map +1 -1
  50. package/mcp-server/McpServerDetailView.js +11 -3
  51. package/mcp-server/McpServerDetailView.js.map +1 -1
  52. package/package.json +4 -4
  53. package/provider.d.ts +14 -2
  54. package/provider.d.ts.map +1 -1
  55. package/provider.js +3 -2
  56. package/provider.js.map +1 -1
  57. package/src/deployment-mode.ts +46 -0
  58. package/src/execution/ApprovalCard.tsx +130 -283
  59. package/src/execution/McpToolDetail.tsx +283 -0
  60. package/src/execution/ToolArgsView.tsx +277 -0
  61. package/src/execution/ToolCallDetail.tsx +51 -219
  62. package/src/execution/ToolCallGroup.tsx +3 -2
  63. package/src/execution/ToolCallItem.tsx +14 -2
  64. package/src/execution/index.ts +25 -0
  65. package/src/execution/tool-categories.ts +89 -9
  66. package/src/execution/tool-rendering-primitives.tsx +253 -0
  67. package/src/index.ts +13 -0
  68. package/src/internal/CloudFeatureNotice.tsx +60 -0
  69. package/src/mcp-server/McpServerDetailView.tsx +24 -2
  70. package/src/provider.tsx +18 -2
  71. package/styles.css +1 -1
@@ -0,0 +1,253 @@
1
+ "use client";
2
+
3
+ import { useState } from "react";
4
+ import { cn } from "@stigmer/theme";
5
+
6
+ /**
7
+ * Shared truncation threshold for all collapsible tool rendering
8
+ * primitives. Applied consistently across detail views and approval
9
+ * card previews.
10
+ */
11
+ export const TRUNCATION_LINE_LIMIT = 10;
12
+
13
+ // ---------------------------------------------------------------------------
14
+ // CollapsibleCode — labeled code block with line-based truncation
15
+ // ---------------------------------------------------------------------------
16
+
17
+ export interface CollapsibleCodeProps {
18
+ readonly label: string;
19
+ readonly content: string;
20
+ readonly className?: string;
21
+ }
22
+
23
+ /**
24
+ * A labeled `<pre>` block with automatic line-based truncation and
25
+ * an expand/collapse toggle.
26
+ *
27
+ * Used for tool arguments, file content previews, and result blocks
28
+ * across both the detail view and the approval card.
29
+ */
30
+ export function CollapsibleCode({ label, content, className }: CollapsibleCodeProps) {
31
+ const lines = content.split("\n");
32
+ const needsTruncation = lines.length > TRUNCATION_LINE_LIMIT;
33
+ const [isExpanded, setIsExpanded] = useState(false);
34
+
35
+ const displayContent =
36
+ needsTruncation && !isExpanded
37
+ ? lines.slice(0, TRUNCATION_LINE_LIMIT).join("\n") + "\n\u2026"
38
+ : content;
39
+
40
+ return (
41
+ <div className={cn("space-y-1", className)}>
42
+ <span className="font-medium text-muted-foreground">{label}</span>
43
+ <pre className="max-h-80 overflow-auto whitespace-pre-wrap break-words rounded-md border border-border bg-muted/40 p-2 font-mono text-foreground">
44
+ {displayContent}
45
+ </pre>
46
+ {needsTruncation && (
47
+ <button
48
+ type="button"
49
+ onClick={() => setIsExpanded((v) => !v)}
50
+ className="text-xs font-medium text-primary transition-colors hover:text-primary/80"
51
+ >
52
+ {isExpanded ? "Show less" : `Show all ${lines.length} lines`}
53
+ </button>
54
+ )}
55
+ </div>
56
+ );
57
+ }
58
+
59
+ // ---------------------------------------------------------------------------
60
+ // CollapsiblePre — raw pre with line-based truncation (no label/border)
61
+ // ---------------------------------------------------------------------------
62
+
63
+ export interface CollapsiblePreProps {
64
+ readonly content: string;
65
+ readonly className?: string;
66
+ }
67
+
68
+ /**
69
+ * A bare `<pre>` element with line-based truncation. Unlike
70
+ * {@link CollapsibleCode}, this has no label, border, or background
71
+ * — the caller controls container styling via `className`.
72
+ *
73
+ * Pass container styles (border, background, max-height) through
74
+ * `className` when rendering standalone; omit when the parent
75
+ * already provides a styled container (e.g. terminal blocks).
76
+ */
77
+ export function CollapsiblePre({ content, className }: CollapsiblePreProps) {
78
+ const lines = content.split("\n");
79
+ const needsTruncation = lines.length > TRUNCATION_LINE_LIMIT;
80
+ const [isExpanded, setIsExpanded] = useState(false);
81
+
82
+ const displayContent =
83
+ needsTruncation && !isExpanded
84
+ ? lines.slice(0, TRUNCATION_LINE_LIMIT).join("\n") + "\n\u2026"
85
+ : content;
86
+
87
+ return (
88
+ <>
89
+ <pre className={cn("whitespace-pre-wrap break-words font-mono", className)}>
90
+ {displayContent}
91
+ </pre>
92
+ {needsTruncation && (
93
+ <button
94
+ type="button"
95
+ onClick={() => setIsExpanded((v) => !v)}
96
+ className="mt-1 text-xs font-medium text-primary transition-colors hover:text-primary/80"
97
+ >
98
+ {isExpanded ? "Show less" : `Show all ${lines.length} lines`}
99
+ </button>
100
+ )}
101
+ </>
102
+ );
103
+ }
104
+
105
+ // ---------------------------------------------------------------------------
106
+ // CollapsibleJsonBlock — chevron-toggled JSON section
107
+ // ---------------------------------------------------------------------------
108
+
109
+ export interface CollapsibleJsonBlockProps {
110
+ readonly label: string;
111
+ readonly content: string;
112
+ }
113
+
114
+ /**
115
+ * A collapsible JSON section with a chevron toggle. Initially
116
+ * collapsed, showing the label and line count. Useful for complex
117
+ * (non-scalar) tool arguments.
118
+ */
119
+ export function CollapsibleJsonBlock({ label, content }: CollapsibleJsonBlockProps) {
120
+ const [isExpanded, setIsExpanded] = useState(false);
121
+ const lines = content.split("\n");
122
+ const isLong = lines.length > 3;
123
+
124
+ return (
125
+ <div className="space-y-1">
126
+ <button
127
+ type="button"
128
+ onClick={() => setIsExpanded((v) => !v)}
129
+ className="flex items-center gap-1 font-medium text-muted-foreground transition-colors hover:text-foreground"
130
+ >
131
+ <svg
132
+ width="8"
133
+ height="8"
134
+ viewBox="0 0 8 8"
135
+ fill="none"
136
+ stroke="currentColor"
137
+ strokeWidth="1.5"
138
+ strokeLinecap="round"
139
+ strokeLinejoin="round"
140
+ className={cn(
141
+ "shrink-0 transition-transform duration-150",
142
+ isExpanded && "rotate-90",
143
+ )}
144
+ aria-hidden="true"
145
+ >
146
+ <path d="M2 1L6 4L2 7" />
147
+ </svg>
148
+ {label}
149
+ {!isExpanded && isLong && (
150
+ <span className="font-normal text-muted-foreground/60">
151
+ ({lines.length} lines)
152
+ </span>
153
+ )}
154
+ </button>
155
+ {isExpanded && (
156
+ <pre className="max-h-80 overflow-auto whitespace-pre-wrap break-words rounded-md border border-border bg-muted/40 p-2 font-mono text-foreground">
157
+ {content}
158
+ </pre>
159
+ )}
160
+ </div>
161
+ );
162
+ }
163
+
164
+ // ---------------------------------------------------------------------------
165
+ // Inline SVG icons
166
+ // ---------------------------------------------------------------------------
167
+
168
+ /** Small document icon for file path displays (10x10). */
169
+ export function FilePathIcon() {
170
+ return (
171
+ <svg
172
+ width="10"
173
+ height="10"
174
+ viewBox="0 0 12 12"
175
+ fill="none"
176
+ stroke="currentColor"
177
+ strokeWidth="1.2"
178
+ strokeLinecap="round"
179
+ strokeLinejoin="round"
180
+ className="shrink-0 text-muted-foreground"
181
+ aria-hidden="true"
182
+ >
183
+ <path d="M7 1H3C2.45 1 2 1.45 2 2V10C2 10.55 2.45 11 3 11H9C9.55 11 10 10.55 10 10V4L7 1Z" />
184
+ <path d="M7 1V4H10" />
185
+ </svg>
186
+ );
187
+ }
188
+
189
+ /** MCP server node/link icon (10x10). */
190
+ export function McpServerIcon() {
191
+ return (
192
+ <svg
193
+ width="10"
194
+ height="10"
195
+ viewBox="0 0 12 12"
196
+ fill="none"
197
+ stroke="currentColor"
198
+ strokeWidth="1.2"
199
+ strokeLinecap="round"
200
+ strokeLinejoin="round"
201
+ className="shrink-0"
202
+ aria-hidden="true"
203
+ >
204
+ <circle cx="6" cy="3" r="1.5" />
205
+ <circle cx="6" cy="9" r="1.5" />
206
+ <path d="M6 4.5V7.5" />
207
+ <path d="M3 6H4.5" />
208
+ <path d="M7.5 6H9" />
209
+ </svg>
210
+ );
211
+ }
212
+
213
+ // ---------------------------------------------------------------------------
214
+ // Shared utilities
215
+ // ---------------------------------------------------------------------------
216
+
217
+ /** Safely serialise an object to pretty JSON. */
218
+ export function formatJson(obj: unknown): string {
219
+ try {
220
+ return JSON.stringify(obj, null, 2);
221
+ } catch {
222
+ return String(obj);
223
+ }
224
+ }
225
+
226
+ /** Pretty-print a result string if it's valid JSON, otherwise return as-is. */
227
+ export function formatResult(result: string): string {
228
+ try {
229
+ const parsed = JSON.parse(result);
230
+ return JSON.stringify(parsed, null, 2);
231
+ } catch {
232
+ return result;
233
+ }
234
+ }
235
+
236
+ /** Detect scalar values (string, number, boolean). */
237
+ export function isScalar(value: unknown): value is string | number | boolean {
238
+ const t = typeof value;
239
+ return t === "string" || t === "number" || t === "boolean";
240
+ }
241
+
242
+ /**
243
+ * Title-case a snake_case or camelCase argument key for display.
244
+ *
245
+ * @example
246
+ * humanizeArgKey("mcp_server_slug") // "Mcp Server Slug"
247
+ */
248
+ export function humanizeArgKey(key: string): string {
249
+ return key
250
+ .replace(/([a-z])([A-Z])/g, "$1 $2")
251
+ .replace(/[_-]+/g, " ")
252
+ .replace(/\b[a-z]/g, (c) => c.toUpperCase());
253
+ }
package/src/index.ts CHANGED
@@ -5,6 +5,11 @@ export { StigmerContext } from "./context";
5
5
  // Hooks
6
6
  export { useStigmer } from "./hooks";
7
7
 
8
+ // Deployment mode and resource availability
9
+ export { useDeploymentMode, useResourceAvailable } from "./deployment-mode";
10
+ export { type DeploymentMode, isResourceAvailable, ApiResourceKind } from "@stigmer/sdk";
11
+ export { CloudFeatureNotice, type CloudFeatureNoticeProps } from "./internal/CloudFeatureNotice";
12
+
8
13
  // Models — data hook, styled component, and registry data
9
14
  export {
10
15
  MODEL_REGISTRY,
@@ -81,7 +86,10 @@ export {
81
86
  ExecutionCostSummary,
82
87
  ToolCallGroup,
83
88
  ToolCallDetail,
89
+ McpToolDetail,
90
+ parseMcpResult,
84
91
  formatDuration,
92
+ humanizeToolName,
85
93
  ToolCallItem,
86
94
  SubAgentSection,
87
95
  MessageEntry,
@@ -92,6 +100,9 @@ export {
92
100
  ArtifactContentRenderer,
93
101
  ArtifactPreviewModal,
94
102
  ArtifactsWidget,
103
+ ToolArgsView,
104
+ McpArgsView,
105
+ McpMetadataRow,
95
106
  FilePathLink,
96
107
  FilePathContext,
97
108
  classifyPath,
@@ -121,6 +132,8 @@ export type {
121
132
  ExecutionCostSummaryProps,
122
133
  ToolCallGroupProps,
123
134
  ToolCallDetailProps,
135
+ McpToolDetailProps,
136
+ ToolArgsViewProps,
124
137
  ToolCallItemProps,
125
138
  SubAgentSectionProps,
126
139
  MessageEntryProps,
@@ -0,0 +1,60 @@
1
+ "use client";
2
+
3
+ import type { ReactNode } from "react";
4
+ import { cn } from "@stigmer/theme";
5
+
6
+ export interface CloudFeatureNoticeProps {
7
+ /** Explanation of why the feature is unavailable and what to do instead. */
8
+ readonly children: ReactNode;
9
+ readonly className?: string;
10
+ }
11
+
12
+ /**
13
+ * Subdued info notice displayed in place of cloud-only feature content
14
+ * when the connected Stigmer backend does not support the feature.
15
+ *
16
+ * Renders an inline box with an info icon and the provided message.
17
+ * The parent section provides its own heading and description — this
18
+ * component is purely the "why it's absent" explanation.
19
+ *
20
+ * All visual properties flow through `--stgm-*` design tokens.
21
+ * No Console-specific dependencies — safe for platform builder embedding.
22
+ */
23
+ export function CloudFeatureNotice({
24
+ children,
25
+ className,
26
+ }: CloudFeatureNoticeProps) {
27
+ return (
28
+ <div
29
+ role="status"
30
+ className={cn(
31
+ "bg-muted/50 text-muted-foreground flex items-start gap-2.5 rounded-lg border border-transparent px-4 py-3",
32
+ className,
33
+ )}
34
+ >
35
+ <InfoIcon className="mt-0.5 size-4 shrink-0" />
36
+ <p className="text-xs leading-relaxed">{children}</p>
37
+ </div>
38
+ );
39
+ }
40
+
41
+ function InfoIcon({ className }: { className?: string }) {
42
+ return (
43
+ <svg
44
+ width="16"
45
+ height="16"
46
+ viewBox="0 0 16 16"
47
+ fill="none"
48
+ stroke="currentColor"
49
+ strokeWidth="1.5"
50
+ strokeLinecap="round"
51
+ strokeLinejoin="round"
52
+ className={className}
53
+ aria-hidden="true"
54
+ >
55
+ <circle cx="8" cy="8" r="6.25" />
56
+ <path d="M8 7v4" />
57
+ <circle cx="8" cy="5" r="0.5" fill="currentColor" stroke="none" />
58
+ </svg>
59
+ );
60
+ }
@@ -46,6 +46,20 @@ export interface McpServerDetailViewProps {
46
46
  readonly onVisibilityChange?: (v: ApiResourceVisibility) => void;
47
47
  /** `true` while a visibility update RPC is in flight. */
48
48
  readonly isVisibilityPending?: boolean;
49
+ /**
50
+ * Called after the approval-policy generation session and execution
51
+ * have been created successfully.
52
+ *
53
+ * When provided, the component delegates post-trigger behavior to the
54
+ * consumer (e.g. navigating to a session page) instead of rendering
55
+ * the inline {@link ApprovalPolicyGeneratorPanel}.
56
+ *
57
+ * When omitted, the inline panel is shown as a fallback.
58
+ */
59
+ readonly onPolicySessionCreated?: (info: {
60
+ sessionId: string;
61
+ executionId: string;
62
+ }) => void;
49
63
  /** Additional CSS classes for the root container. */
50
64
  readonly className?: string;
51
65
  }
@@ -78,6 +92,7 @@ export function McpServerDetailView({
78
92
  onResourceLoad,
79
93
  onVisibilityChange,
80
94
  isVisibilityPending,
95
+ onPolicySessionCreated,
81
96
  className,
82
97
  }: McpServerDetailViewProps) {
83
98
  const { mcpServer, isLoading, error, refetch } = useMcpServer(org, slug);
@@ -149,11 +164,18 @@ export function McpServerDetailView({
149
164
  try {
150
165
  const yaml = serializeMcpServerYaml(mcpServer);
151
166
  const result = await policySession.trigger(yaml, org, slug);
152
- setPolicyPanelExecutionId(result.executionId);
167
+ if (onPolicySessionCreated) {
168
+ onPolicySessionCreated({
169
+ sessionId: result.sessionId,
170
+ executionId: result.executionId,
171
+ });
172
+ } else {
173
+ setPolicyPanelExecutionId(result.executionId);
174
+ }
153
175
  } catch {
154
176
  // error state is managed by the hook
155
177
  }
156
- }, [mcpServer, org, slug, policySession]);
178
+ }, [mcpServer, org, slug, policySession, onPolicySessionCreated]);
157
179
 
158
180
  const handlePolicyPanelComplete = useCallback(() => {
159
181
  refetch();
package/src/provider.tsx CHANGED
@@ -1,15 +1,28 @@
1
1
  "use client";
2
2
 
3
3
  import type { ReactNode } from "react";
4
- import type { Stigmer } from "@stigmer/sdk";
4
+ import type { Stigmer, DeploymentMode } from "@stigmer/sdk";
5
5
  import { cn, resolvePresetClass } from "@stigmer/theme";
6
6
  import type { ThemePresetId } from "@stigmer/theme";
7
7
  import { StigmerContext } from "./context";
8
+ import { DeploymentModeContext } from "./deployment-mode";
8
9
 
9
10
  export interface StigmerProviderProps {
10
11
  /** A configured {@link Stigmer} client instance. */
11
12
  readonly client: Stigmer;
12
13
  readonly children: ReactNode;
14
+ /**
15
+ * Deployment mode of the connected Stigmer backend.
16
+ *
17
+ * - `"local"` — local Go CLI server (OSS). Cloud-only resources
18
+ * (API keys, IAM, identity management) are unavailable.
19
+ * - `"cloud"` — Stigmer Cloud. All resources are available.
20
+ *
21
+ * Defaults to `"cloud"` so existing consumers see no change.
22
+ * The Stigmer Console derives this from the API URL hostname.
23
+ * Platform builders pass it based on their deployment context.
24
+ */
25
+ readonly deploymentMode?: DeploymentMode;
13
26
  /**
14
27
  * Built-in theme preset to apply.
15
28
  *
@@ -60,6 +73,7 @@ export interface StigmerProviderProps {
60
73
  export function StigmerProvider({
61
74
  client,
62
75
  children,
76
+ deploymentMode = "cloud",
63
77
  preset,
64
78
  className,
65
79
  }: StigmerProviderProps) {
@@ -67,7 +81,9 @@ export function StigmerProvider({
67
81
 
68
82
  return (
69
83
  <StigmerContext.Provider value={client}>
70
- <div className={cn("stgm", presetClass, className)}>{children}</div>
84
+ <DeploymentModeContext.Provider value={deploymentMode}>
85
+ <div className={cn("stgm", presetClass, className)}>{children}</div>
86
+ </DeploymentModeContext.Provider>
71
87
  </StigmerContext.Provider>
72
88
  );
73
89
  }