@stigmer/react 3.12.5 → 3.12.7
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/agent/AgentDetailView.js +2 -2
- package/agent/AgentDetailView.js.map +1 -1
- package/agent/index.d.ts +0 -1
- package/agent/index.d.ts.map +1 -1
- package/agent/index.js +0 -1
- package/agent/index.js.map +1 -1
- package/agent/useUpdateAgent.d.ts +3 -3
- package/agent/useUpdateAgent.js +3 -3
- package/agent-instance/AgentInstanceDetailPanel.d.ts.map +1 -1
- package/agent-instance/AgentInstanceDetailPanel.js +5 -7
- package/agent-instance/AgentInstanceDetailPanel.js.map +1 -1
- package/agent-instance/useUpdateAgentInstance.d.ts +1 -1
- package/agent-instance/useUpdateAgentInstance.js +1 -1
- package/channel/AgentChannelsPanel.d.ts.map +1 -1
- package/channel/AgentChannelsPanel.js +10 -5
- package/channel/AgentChannelsPanel.js.map +1 -1
- package/channel/ChannelRunConfigDialog.d.ts +51 -0
- package/channel/ChannelRunConfigDialog.d.ts.map +1 -0
- package/channel/ChannelRunConfigDialog.js +121 -0
- package/channel/ChannelRunConfigDialog.js.map +1 -0
- package/channel/index.d.ts +2 -0
- package/channel/index.d.ts.map +1 -1
- package/channel/index.js +1 -0
- package/channel/index.js.map +1 -1
- package/channel/useSaveAgentChannel.d.ts.map +1 -1
- package/channel/useSaveAgentChannel.js +6 -3
- package/channel/useSaveAgentChannel.js.map +1 -1
- package/channel-app/ChannelAppDetailPanel.js +9 -9
- package/channel-app/ChannelAppDetailPanel.js.map +1 -1
- package/composer/ComposerToolbar.d.ts +24 -1
- package/composer/ComposerToolbar.d.ts.map +1 -1
- package/composer/ComposerToolbar.js +7 -2
- package/composer/ComposerToolbar.js.map +1 -1
- package/composer/SessionComposer.d.ts +19 -0
- package/composer/SessionComposer.d.ts.map +1 -1
- package/composer/SessionComposer.js +24 -5
- package/composer/SessionComposer.js.map +1 -1
- package/composer/index.d.ts +1 -0
- package/composer/index.d.ts.map +1 -1
- package/composer/index.js.map +1 -1
- package/cursor-accounts/CursorAccountsConsole.d.ts.map +1 -1
- package/cursor-accounts/CursorAccountsConsole.js +12 -3
- package/cursor-accounts/CursorAccountsConsole.js.map +1 -1
- package/cursor-accounts/cursor-account-coverage.d.ts +30 -1
- package/cursor-accounts/cursor-account-coverage.d.ts.map +1 -1
- package/cursor-accounts/cursor-account-coverage.js +21 -0
- package/cursor-accounts/cursor-account-coverage.js.map +1 -1
- package/execution/MessageThread.d.ts.map +1 -1
- package/execution/MessageThread.js +8 -11
- package/execution/MessageThread.js.map +1 -1
- package/execution/useCreateAgentExecution.d.ts +15 -0
- package/execution/useCreateAgentExecution.d.ts.map +1 -1
- package/execution/useCreateAgentExecution.js +5 -0
- package/execution/useCreateAgentExecution.js.map +1 -1
- package/execution/useFileChangeContent.d.ts +2 -6
- package/execution/useFileChangeContent.d.ts.map +1 -1
- package/execution/useFileChangeContent.js +4 -12
- package/execution/useFileChangeContent.js.map +1 -1
- package/identity-account/AccountPreferencesPanel.d.ts +2 -1
- package/identity-account/AccountPreferencesPanel.d.ts.map +1 -1
- package/identity-account/AccountPreferencesPanel.js +33 -18
- package/identity-account/AccountPreferencesPanel.js.map +1 -1
- package/identity-provider/IdentityProviderDetailPanel.d.ts.map +1 -1
- package/identity-provider/IdentityProviderDetailPanel.js +16 -15
- package/identity-provider/IdentityProviderDetailPanel.js.map +1 -1
- package/index.d.ts +10 -7
- package/index.d.ts.map +1 -1
- package/index.js +8 -4
- package/index.js.map +1 -1
- package/internal/download.d.ts +8 -0
- package/internal/download.d.ts.map +1 -0
- package/internal/download.js +25 -0
- package/internal/download.js.map +1 -0
- package/library/useExportResource.d.ts.map +1 -1
- package/library/useExportResource.js +3 -17
- package/library/useExportResource.js.map +1 -1
- package/mcp-server/McpServerDetailView.js +2 -2
- package/mcp-server/McpServerDetailView.js.map +1 -1
- package/mcp-server/index.d.ts +0 -1
- package/mcp-server/index.d.ts.map +1 -1
- package/mcp-server/index.js +0 -1
- package/mcp-server/index.js.map +1 -1
- package/mcp-server/internal/definitionDrift.d.ts +14 -12
- package/mcp-server/internal/definitionDrift.d.ts.map +1 -1
- package/mcp-server/internal/definitionDrift.js +22 -19
- package/mcp-server/internal/definitionDrift.js.map +1 -1
- package/mcp-server/useUpdateMcpServer.d.ts +3 -3
- package/mcp-server/useUpdateMcpServer.js +3 -3
- package/memory/MemoryListPanel.d.ts +35 -0
- package/memory/MemoryListPanel.d.ts.map +1 -0
- package/memory/MemoryListPanel.js +141 -0
- package/memory/MemoryListPanel.js.map +1 -0
- package/memory/index.d.ts +8 -0
- package/memory/index.d.ts.map +1 -0
- package/memory/index.js +12 -0
- package/memory/index.js.map +1 -0
- package/memory/memoryGroups.d.ts +31 -0
- package/memory/memoryGroups.d.ts.map +1 -0
- package/memory/memoryGroups.js +52 -0
- package/memory/memoryGroups.js.map +1 -0
- package/memory/useConfirmMemory.d.ts +31 -0
- package/memory/useConfirmMemory.d.ts.map +1 -0
- package/memory/useConfirmMemory.js +43 -0
- package/memory/useConfirmMemory.js.map +1 -0
- package/memory/useDeleteMemory.d.ts +30 -0
- package/memory/useDeleteMemory.d.ts.map +1 -0
- package/memory/useDeleteMemory.js +42 -0
- package/memory/useDeleteMemory.js.map +1 -0
- package/memory/useMemories.d.ts +33 -0
- package/memory/useMemories.d.ts.map +1 -0
- package/memory/useMemories.js +42 -0
- package/memory/useMemories.js.map +1 -0
- package/memory/useRejectMemory.d.ts +34 -0
- package/memory/useRejectMemory.d.ts.map +1 -0
- package/memory/useRejectMemory.js +46 -0
- package/memory/useRejectMemory.js.map +1 -0
- package/memory/useUpdateMemoryContent.d.ts +32 -0
- package/memory/useUpdateMemoryContent.d.ts.map +1 -0
- package/memory/useUpdateMemoryContent.js +48 -0
- package/memory/useUpdateMemoryContent.js.map +1 -0
- package/models/ModelSelector.d.ts +33 -1
- package/models/ModelSelector.d.ts.map +1 -1
- package/models/ModelSelector.js +37 -4
- package/models/ModelSelector.js.map +1 -1
- package/models/index.d.ts +2 -0
- package/models/index.d.ts.map +1 -1
- package/models/index.js +1 -0
- package/models/index.js.map +1 -1
- package/models/registry.d.ts +16 -0
- package/models/registry.d.ts.map +1 -1
- package/models/registry.js +13 -0
- package/models/registry.js.map +1 -1
- package/models/thinking-mode.d.ts +27 -0
- package/models/thinking-mode.d.ts.map +1 -0
- package/models/thinking-mode.js +32 -0
- package/models/thinking-mode.js.map +1 -0
- package/oauth-app/OAuthAppDetailPanel.d.ts.map +1 -1
- package/oauth-app/OAuthAppDetailPanel.js +21 -20
- package/oauth-app/OAuthAppDetailPanel.js.map +1 -1
- package/package.json +4 -4
- package/platform-client/PlatformClientDetailPanel.d.ts.map +1 -1
- package/platform-client/PlatformClientDetailPanel.js +12 -13
- package/platform-client/PlatformClientDetailPanel.js.map +1 -1
- package/schedule/ScheduleDetailView.d.ts.map +1 -1
- package/schedule/ScheduleDetailView.js +21 -10
- package/schedule/ScheduleDetailView.js.map +1 -1
- package/schedule/ScheduleForm.d.ts.map +1 -1
- package/schedule/ScheduleForm.js +13 -3
- package/schedule/ScheduleForm.js.map +1 -1
- package/session/NewSessionViewer.d.ts.map +1 -1
- package/session/NewSessionViewer.js +9 -1
- package/session/NewSessionViewer.js.map +1 -1
- package/session/SessionViewer.d.ts +14 -1
- package/session/SessionViewer.d.ts.map +1 -1
- package/session/SessionViewer.js +21 -25
- package/session/SessionViewer.js.map +1 -1
- package/session/TranscriptExportMenu.d.ts +24 -0
- package/session/TranscriptExportMenu.d.ts.map +1 -0
- package/session/TranscriptExportMenu.js +26 -0
- package/session/TranscriptExportMenu.js.map +1 -0
- package/session/index.d.ts +4 -0
- package/session/index.d.ts.map +1 -1
- package/session/index.js +2 -0
- package/session/index.js.map +1 -1
- package/session/run-config.d.ts +9 -0
- package/session/run-config.d.ts.map +1 -1
- package/session/run-config.js +5 -0
- package/session/run-config.js.map +1 -1
- package/session/useExportTranscript.d.ts +44 -0
- package/session/useExportTranscript.d.ts.map +1 -0
- package/session/useExportTranscript.js +109 -0
- package/session/useExportTranscript.js.map +1 -0
- package/session/useNewSessionFlow.d.ts +11 -0
- package/session/useNewSessionFlow.d.ts.map +1 -1
- package/session/useNewSessionFlow.js +20 -6
- package/session/useNewSessionFlow.js.map +1 -1
- package/session/useSessionConversation.d.ts +12 -1
- package/session/useSessionConversation.d.ts.map +1 -1
- package/session/useSessionConversation.js +21 -42
- package/session/useSessionConversation.js.map +1 -1
- package/session/useSessionExecutions.d.ts +2 -14
- package/session/useSessionExecutions.d.ts.map +1 -1
- package/session/useSessionExecutions.js +4 -26
- package/session/useSessionExecutions.js.map +1 -1
- package/session/useSessionPageFlow.d.ts +23 -10
- package/session/useSessionPageFlow.d.ts.map +1 -1
- package/session/useSessionPageFlow.js +75 -19
- package/session/useSessionPageFlow.js.map +1 -1
- package/session/useUpdateSession.d.ts +18 -24
- package/session/useUpdateSession.d.ts.map +1 -1
- package/session/useUpdateSession.js +18 -24
- package/session/useUpdateSession.js.map +1 -1
- package/settings/MemorySection.d.ts +12 -0
- package/settings/MemorySection.d.ts.map +1 -0
- package/settings/MemorySection.js +21 -0
- package/settings/MemorySection.js.map +1 -0
- package/settings/index.d.ts +1 -0
- package/settings/index.d.ts.map +1 -1
- package/settings/index.js +1 -0
- package/settings/index.js.map +1 -1
- package/settings/settings-nav.d.ts.map +1 -1
- package/settings/settings-nav.js +2 -1
- package/settings/settings-nav.js.map +1 -1
- package/src/__tests__/public-api.test.ts +21 -0
- package/src/agent/AgentDetailView.tsx +2 -2
- package/src/agent/index.ts +0 -2
- package/src/agent/useUpdateAgent.ts +3 -3
- package/src/agent-instance/AgentInstanceDetailPanel.tsx +5 -7
- package/src/agent-instance/__tests__/AgentInstanceDetailPanel.test.tsx +75 -0
- package/src/agent-instance/useUpdateAgentInstance.ts +1 -1
- package/src/channel/AgentChannelsPanel.tsx +26 -1
- package/src/channel/ChannelRunConfigDialog.tsx +351 -0
- package/src/channel/__tests__/ChannelRunConfigDialog.test.tsx +210 -0
- package/src/channel/index.ts +2 -0
- package/src/channel/useSaveAgentChannel.ts +6 -3
- package/src/channel-app/ChannelAppDetailPanel.tsx +9 -9
- package/src/channel-app/__tests__/channelAppWhatsApp.test.tsx +2 -0
- package/src/channel-app/__tests__/channelAppWipeSafety.test.tsx +87 -0
- package/src/composer/ComposerToolbar.tsx +67 -0
- package/src/composer/SessionComposer.tsx +49 -3
- package/src/composer/__tests__/ComposerToolbar-autoApprove.test.tsx +80 -0
- package/src/composer/__tests__/SessionComposer-thinkingMode.test.tsx +176 -0
- package/src/composer/index.ts +1 -0
- package/src/cursor-accounts/CursorAccountsConsole.tsx +40 -5
- package/src/cursor-accounts/__tests__/CursorAccountsConsole.test.tsx +32 -0
- package/src/cursor-accounts/__tests__/cursor-account-coverage.test.ts +58 -1
- package/src/cursor-accounts/cursor-account-coverage.ts +55 -0
- package/src/execution/MessageThread.tsx +8 -11
- package/src/execution/useCreateAgentExecution.ts +19 -0
- package/src/execution/useFileChangeContent.ts +5 -12
- package/src/identity-account/AccountPreferencesPanel.tsx +154 -68
- package/src/identity-account/__tests__/AccountPreferencesPanel.test.tsx +36 -2
- package/src/identity-provider/IdentityProviderDetailPanel.tsx +18 -15
- package/src/identity-provider/__tests__/IdentityProviderDetailPanel.test.tsx +80 -0
- package/src/index.ts +36 -2
- package/src/internal/download.ts +29 -0
- package/src/library/useExportResource.ts +3 -19
- package/src/mcp-server/McpServerDetailView.tsx +2 -2
- package/src/mcp-server/index.ts +0 -2
- package/src/mcp-server/internal/definitionDrift.ts +22 -20
- package/src/mcp-server/useUpdateMcpServer.ts +3 -3
- package/src/memory/MemoryListPanel.tsx +532 -0
- package/src/memory/__tests__/MemoryListPanel.test.tsx +259 -0
- package/src/memory/__tests__/memoryHooks.test.tsx +220 -0
- package/src/memory/index.ts +19 -0
- package/src/memory/memoryGroups.ts +64 -0
- package/src/memory/useConfirmMemory.ts +62 -0
- package/src/memory/useDeleteMemory.ts +61 -0
- package/src/memory/useMemories.ts +66 -0
- package/src/memory/useRejectMemory.ts +65 -0
- package/src/memory/useUpdateMemoryContent.ts +67 -0
- package/src/models/ModelSelector.tsx +94 -1
- package/src/models/index.ts +2 -0
- package/src/models/registry.ts +29 -0
- package/src/models/thinking-mode.ts +48 -0
- package/src/oauth-app/OAuthAppDetailPanel.tsx +23 -21
- package/src/oauth-app/__tests__/OAuthAppDetailPanel.test.tsx +94 -0
- package/src/platform-client/PlatformClientDetailPanel.tsx +14 -13
- package/src/platform-client/__tests__/PlatformClientDetailPanel.test.tsx +82 -0
- package/src/schedule/ScheduleDetailView.tsx +29 -4
- package/src/schedule/ScheduleForm.tsx +14 -1
- package/src/session/NewSessionViewer.tsx +15 -1
- package/src/session/SessionViewer.tsx +48 -49
- package/src/session/TranscriptExportMenu.tsx +78 -0
- package/src/session/__tests__/SessionViewer-autoApproveToggle.test.tsx +178 -0
- package/src/session/__tests__/SessionViewer-transcriptExport.test.tsx +151 -0
- package/src/session/__tests__/TranscriptExportMenu.test.tsx +97 -0
- package/src/session/__tests__/useExportTranscript.test.tsx +187 -0
- package/src/session/__tests__/useNewSessionFlow.test.tsx +33 -0
- package/src/session/__tests__/useSessionPageFlow.autoApprove.test.tsx +176 -2
- package/src/session/index.ts +9 -0
- package/src/session/run-config.ts +16 -0
- package/src/session/useExportTranscript.ts +171 -0
- package/src/session/useNewSessionFlow.ts +34 -7
- package/src/session/useSessionConversation.ts +42 -56
- package/src/session/useSessionExecutions.ts +5 -26
- package/src/session/useSessionPageFlow.ts +98 -32
- package/src/session/useUpdateSession.ts +18 -24
- package/src/settings/MemorySection.tsx +45 -0
- package/src/settings/index.ts +1 -0
- package/src/settings/settings-nav.ts +2 -0
- package/src/usage/useExportCSV.ts +2 -14
- package/src/workflow/ApprovalFormBuilder.tsx +20 -5
- package/src/workflow/WorkflowDetailView.tsx +2 -2
- package/src/workflow/__tests__/WorkflowInstanceDetailPanel.test.tsx +83 -0
- package/src/workflow/index.ts +0 -2
- package/src/workflow/instance/WorkflowInstanceDetailPanel.tsx +6 -7
- package/src/workflow/useUpdateWorkflow.ts +3 -3
- package/styles.css +1 -1
- package/usage/useExportCSV.d.ts.map +1 -1
- package/usage/useExportCSV.js +2 -13
- package/usage/useExportCSV.js.map +1 -1
- package/workflow/ApprovalFormBuilder.d.ts.map +1 -1
- package/workflow/ApprovalFormBuilder.js +10 -8
- package/workflow/ApprovalFormBuilder.js.map +1 -1
- package/workflow/WorkflowDetailView.js +2 -2
- package/workflow/WorkflowDetailView.js.map +1 -1
- package/workflow/index.d.ts +0 -1
- package/workflow/index.d.ts.map +1 -1
- package/workflow/index.js +0 -1
- package/workflow/index.js.map +1 -1
- package/workflow/instance/WorkflowInstanceDetailPanel.d.ts.map +1 -1
- package/workflow/instance/WorkflowInstanceDetailPanel.js +6 -7
- package/workflow/instance/WorkflowInstanceDetailPanel.js.map +1 -1
- package/workflow/useUpdateWorkflow.d.ts +3 -3
- package/workflow/useUpdateWorkflow.js +3 -3
- package/agent/internal/agentToInput.d.ts +0 -15
- package/agent/internal/agentToInput.d.ts.map +0 -1
- package/agent/internal/agentToInput.js +0 -84
- package/agent/internal/agentToInput.js.map +0 -1
- package/mcp-server/internal/mcpServerToInput.d.ts +0 -12
- package/mcp-server/internal/mcpServerToInput.d.ts.map +0 -1
- package/mcp-server/internal/mcpServerToInput.js +0 -84
- package/mcp-server/internal/mcpServerToInput.js.map +0 -1
- package/session/session-spec-converters.d.ts +0 -24
- package/session/session-spec-converters.d.ts.map +0 -1
- package/session/session-spec-converters.js +0 -72
- package/session/session-spec-converters.js.map +0 -1
- package/src/agent/internal/__tests__/agentToInput.test.ts +0 -145
- package/src/agent/internal/agentToInput.ts +0 -102
- package/src/mcp-server/__tests__/mcpServerToInput.test.ts +0 -201
- package/src/mcp-server/internal/mcpServerToInput.ts +0 -98
- package/src/session/__tests__/session-spec-converters.test.ts +0 -183
- package/src/session/session-spec-converters.ts +0 -86
- package/src/workflow/internal/workflowToInput.ts +0 -96
- package/workflow/internal/workflowToInput.d.ts +0 -12
- package/workflow/internal/workflowToInput.d.ts.map +0 -1
- package/workflow/internal/workflowToInput.js +0 -73
- package/workflow/internal/workflowToInput.js.map +0 -1
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
type FormEvent,
|
|
5
|
+
type ReactNode,
|
|
6
|
+
useCallback,
|
|
7
|
+
useEffect,
|
|
8
|
+
useId,
|
|
9
|
+
useMemo,
|
|
10
|
+
useState,
|
|
11
|
+
} from "react";
|
|
4
12
|
import { cn } from "@stigmer/theme";
|
|
5
13
|
import { getUserMessage, toIdentityAccountUpdateInput } from "@stigmer/sdk";
|
|
6
14
|
import type { IdentityAccount } from "@stigmer/protos/ai/stigmer/iam/identityaccount/v1/api_pb";
|
|
@@ -23,7 +31,8 @@ export interface AccountPreferencesPanelProps {
|
|
|
23
31
|
|
|
24
32
|
/**
|
|
25
33
|
* Self-contained editor for the current user's declared preferences
|
|
26
|
-
* (`IdentityAccountSpec.preferences
|
|
34
|
+
* (`IdentityAccountSpec.preferences`): standing context plus the
|
|
35
|
+
* execution defaults (default harness and per-harness default models).
|
|
27
36
|
*
|
|
28
37
|
* The declared text is snapshotted into the user's own eligible agent
|
|
29
38
|
* executions and delivered to the agent as background context.
|
|
@@ -267,31 +276,60 @@ function AccountPreferencesForm({
|
|
|
267
276
|
</p>
|
|
268
277
|
</div>
|
|
269
278
|
|
|
270
|
-
<
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
label={`Default model — ${HARNESS_META.native.label}`}
|
|
282
|
-
value={defaultNativeModel}
|
|
283
|
-
onChange={setDefaultNativeModel}
|
|
279
|
+
<fieldset className="stg:space-y-2" disabled={isUpdating}>
|
|
280
|
+
<legend className="stg:text-xs stg:font-medium stg:text-foreground stg:mb-1">
|
|
281
|
+
Default harness
|
|
282
|
+
</legend>
|
|
283
|
+
<HarnessOptionRow
|
|
284
|
+
radioName={`${baseId}-default-harness`}
|
|
285
|
+
value=""
|
|
286
|
+
label="Platform default"
|
|
287
|
+
description="Stigmer picks the harness for new sessions."
|
|
288
|
+
checked={defaultHarness === ""}
|
|
289
|
+
onSelect={setDefaultHarness}
|
|
284
290
|
disabled={isUpdating}
|
|
285
291
|
/>
|
|
286
|
-
<
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
label={
|
|
290
|
-
|
|
291
|
-
|
|
292
|
+
<HarnessOptionRow
|
|
293
|
+
radioName={`${baseId}-default-harness`}
|
|
294
|
+
value="native"
|
|
295
|
+
label={HARNESS_META.native.label}
|
|
296
|
+
description={HARNESS_META.native.description}
|
|
297
|
+
checked={defaultHarness === "native"}
|
|
298
|
+
onSelect={setDefaultHarness}
|
|
292
299
|
disabled={isUpdating}
|
|
293
|
-
|
|
294
|
-
|
|
300
|
+
>
|
|
301
|
+
<DefaultModelSelect
|
|
302
|
+
id={`${baseId}-default-native-model`}
|
|
303
|
+
harness="native"
|
|
304
|
+
label="Default model"
|
|
305
|
+
value={defaultNativeModel}
|
|
306
|
+
onChange={setDefaultNativeModel}
|
|
307
|
+
disabled={isUpdating}
|
|
308
|
+
/>
|
|
309
|
+
</HarnessOptionRow>
|
|
310
|
+
<HarnessOptionRow
|
|
311
|
+
radioName={`${baseId}-default-harness`}
|
|
312
|
+
value="cursor"
|
|
313
|
+
label={HARNESS_META.cursor.label}
|
|
314
|
+
description={HARNESS_META.cursor.description}
|
|
315
|
+
checked={defaultHarness === "cursor"}
|
|
316
|
+
onSelect={setDefaultHarness}
|
|
317
|
+
disabled={isUpdating}
|
|
318
|
+
>
|
|
319
|
+
<DefaultModelSelect
|
|
320
|
+
id={`${baseId}-default-cursor-model`}
|
|
321
|
+
harness="cursor"
|
|
322
|
+
label="Default model"
|
|
323
|
+
value={defaultCursorModel}
|
|
324
|
+
onChange={setDefaultCursorModel}
|
|
325
|
+
disabled={isUpdating}
|
|
326
|
+
/>
|
|
327
|
+
</HarnessOptionRow>
|
|
328
|
+
<p className="stg:text-[0.65rem] stg:text-muted-foreground">
|
|
329
|
+
Each harness's default model applies whenever a session runs
|
|
330
|
+
on that harness — even when it isn't your default.
|
|
331
|
+
</p>
|
|
332
|
+
</fieldset>
|
|
295
333
|
</div>
|
|
296
334
|
|
|
297
335
|
{updateError && (
|
|
@@ -332,60 +370,104 @@ function AccountPreferencesForm({
|
|
|
332
370
|
}
|
|
333
371
|
|
|
334
372
|
/**
|
|
335
|
-
*
|
|
336
|
-
*
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
*
|
|
342
|
-
*
|
|
373
|
+
* One selectable default-harness choice, presented as a bordered row
|
|
374
|
+
* (the `VisibilityOptionRow` presentation shape): radio + label +
|
|
375
|
+
* one-line description, with the harness's own controls nested below.
|
|
376
|
+
*
|
|
377
|
+
* The rows for shipped harnesses embed that harness's default-model
|
|
378
|
+
* select as `children` — the pairing IS the information architecture:
|
|
379
|
+
* a harness and its model default belong to each other, and each model
|
|
380
|
+
* default applies whenever a session runs on that harness, independent
|
|
381
|
+
* of which harness is the default. The non-selected harness's select
|
|
382
|
+
* therefore stays interactive (visually secondary, never disabled).
|
|
383
|
+
*
|
|
384
|
+
* The nested controls live OUTSIDE the radio's `<label>` on purpose:
|
|
385
|
+
* a `<select>` inside the label would toggle the radio on every
|
|
386
|
+
* interaction with it.
|
|
387
|
+
*
|
|
388
|
+
* The shipped-harness rows must stay in lockstep with the proto's
|
|
389
|
+
* `default_harness` in-list validation (`["native", "cursor"]`) — each
|
|
390
|
+
* shipped harness binds to its own proto model field, so a new harness
|
|
391
|
+
* adds a field, a row, and a validation entry together.
|
|
343
392
|
*/
|
|
344
|
-
function
|
|
345
|
-
|
|
393
|
+
function HarnessOptionRow({
|
|
394
|
+
radioName,
|
|
346
395
|
value,
|
|
347
|
-
|
|
396
|
+
label,
|
|
397
|
+
description,
|
|
398
|
+
checked,
|
|
399
|
+
onSelect,
|
|
348
400
|
disabled,
|
|
401
|
+
children,
|
|
349
402
|
}: {
|
|
350
|
-
readonly
|
|
403
|
+
readonly radioName: string;
|
|
351
404
|
readonly value: string;
|
|
352
|
-
readonly
|
|
405
|
+
readonly label: string;
|
|
406
|
+
readonly description: string;
|
|
407
|
+
readonly checked: boolean;
|
|
408
|
+
readonly onSelect: (value: string) => void;
|
|
353
409
|
readonly disabled: boolean;
|
|
410
|
+
readonly children?: ReactNode;
|
|
354
411
|
}) {
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
412
|
+
// The radio's accessible name is the title alone (aria-labelledby), with
|
|
413
|
+
// the description attached as aria-describedby — the wrapping label keeps
|
|
414
|
+
// the whole text block clickable without bloating the announced name.
|
|
415
|
+
const titleId = `${radioName}-${value || "platform"}-title`;
|
|
416
|
+
const descriptionId = `${radioName}-${value || "platform"}-description`;
|
|
360
417
|
|
|
361
418
|
return (
|
|
362
|
-
<
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
419
|
+
<div
|
|
420
|
+
className={cn(
|
|
421
|
+
"stg:rounded-md stg:border stg:px-3 stg:py-2.5 stg:transition-colors",
|
|
422
|
+
checked
|
|
423
|
+
? "stg:border-primary stg:bg-accent"
|
|
424
|
+
: "stg:border-input stg:hover:bg-accent-hover",
|
|
425
|
+
disabled && "stg:opacity-50",
|
|
426
|
+
)}
|
|
427
|
+
>
|
|
428
|
+
<label
|
|
429
|
+
className={cn(
|
|
430
|
+
"stg:flex stg:cursor-pointer stg:items-start stg:gap-2",
|
|
431
|
+
disabled && "stg:cursor-default",
|
|
432
|
+
)}
|
|
433
|
+
>
|
|
434
|
+
<input
|
|
435
|
+
type="radio"
|
|
436
|
+
name={radioName}
|
|
437
|
+
value={value}
|
|
438
|
+
checked={checked}
|
|
439
|
+
onChange={() => onSelect(value)}
|
|
440
|
+
disabled={disabled}
|
|
441
|
+
aria-labelledby={titleId}
|
|
442
|
+
aria-describedby={descriptionId}
|
|
443
|
+
className="stg:mt-0.5 stg:accent-primary stg:focus-visible:outline-none stg:focus-visible:ring-1 stg:focus-visible:ring-ring"
|
|
444
|
+
/>
|
|
445
|
+
<span className="stg:min-w-0 stg:flex-1">
|
|
446
|
+
<span
|
|
447
|
+
id={titleId}
|
|
448
|
+
className="stg:block stg:text-xs stg:font-medium stg:text-foreground"
|
|
374
449
|
>
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
450
|
+
{label}
|
|
451
|
+
</span>
|
|
452
|
+
<span
|
|
453
|
+
id={descriptionId}
|
|
454
|
+
className="stg:block stg:text-[0.65rem] stg:leading-snug stg:text-muted-foreground"
|
|
455
|
+
>
|
|
456
|
+
{description}
|
|
457
|
+
</span>
|
|
458
|
+
</span>
|
|
459
|
+
</label>
|
|
460
|
+
{children && (
|
|
461
|
+
<div
|
|
462
|
+
className={cn(
|
|
463
|
+
"stg:mt-2 stg:pl-6 stg:transition-opacity",
|
|
464
|
+
!checked && "stg:opacity-70",
|
|
465
|
+
)}
|
|
466
|
+
>
|
|
467
|
+
{children}
|
|
468
|
+
</div>
|
|
469
|
+
)}
|
|
470
|
+
</div>
|
|
389
471
|
);
|
|
390
472
|
}
|
|
391
473
|
|
|
@@ -426,6 +508,10 @@ function DefaultModelSelect({
|
|
|
426
508
|
id={id}
|
|
427
509
|
value={value}
|
|
428
510
|
onChange={(e) => onChange(e.target.value)}
|
|
511
|
+
// Both harness rows show the same visible label; the accessible
|
|
512
|
+
// name stays unique per control by qualifying it with the harness
|
|
513
|
+
// (WCAG label-in-name: the visible text remains a prefix).
|
|
514
|
+
aria-label={`${label} — ${HARNESS_META[harness].label}`}
|
|
429
515
|
disabled={disabled || isLoading}
|
|
430
516
|
className={cn(
|
|
431
517
|
"stg:w-full stg:rounded-md stg:border stg:border-input stg:bg-background stg:px-2.5 stg:py-1.5 stg:text-xs stg:text-foreground",
|
|
@@ -107,7 +107,10 @@ describe("AccountPreferencesPanel", () => {
|
|
|
107
107
|
// Fields this form never renders must round-trip untouched.
|
|
108
108
|
expect(input.idpId).toBe("auth0|abc");
|
|
109
109
|
expect(input.email).toBe("ada@acme.example");
|
|
110
|
-
// The update pipeline addresses the
|
|
110
|
+
// The update pipeline addresses id-first — the id is REQUIRED here:
|
|
111
|
+
// identity accounts are org-less, so the org+slug fallback can never
|
|
112
|
+
// match one (the save-path bug this pin guards against).
|
|
113
|
+
expect(input.id).toBe("ia-1");
|
|
111
114
|
expect(input.org).toBe("acme");
|
|
112
115
|
expect(input.slug).toBe("ada");
|
|
113
116
|
});
|
|
@@ -149,7 +152,7 @@ describe("AccountPreferencesPanel", () => {
|
|
|
149
152
|
},
|
|
150
153
|
});
|
|
151
154
|
|
|
152
|
-
it("renders the harness
|
|
155
|
+
it("renders the harness option rows and registry-fed model selects", async () => {
|
|
153
156
|
renderPanel(createMockStigmer());
|
|
154
157
|
await findSyncedField("Keep answers terse.");
|
|
155
158
|
|
|
@@ -160,6 +163,37 @@ describe("AccountPreferencesPanel", () => {
|
|
|
160
163
|
expect(screen.getByLabelText("Default model — Cursor")).toBeTruthy();
|
|
161
164
|
});
|
|
162
165
|
|
|
166
|
+
it("pairs each harness row with its description (the row IS the context)", async () => {
|
|
167
|
+
renderPanel(createMockStigmer());
|
|
168
|
+
await findSyncedField("Keep answers terse.");
|
|
169
|
+
|
|
170
|
+
// Row subtitles come from HARNESS_META — the single source of harness
|
|
171
|
+
// display copy — plus the platform-default explainer.
|
|
172
|
+
expect(screen.getByText("Stigmer picks the harness for new sessions.")).toBeTruthy();
|
|
173
|
+
expect(screen.getByText("Stigmer's native agent runtime")).toBeTruthy();
|
|
174
|
+
expect(screen.getByText("Cursor IDE agent with codebase indexing")).toBeTruthy();
|
|
175
|
+
// The radios' accessible descriptions are wired via aria-describedby.
|
|
176
|
+
expect(
|
|
177
|
+
screen.getByRole("radio", { name: "Stigmer" }).getAttribute("aria-describedby"),
|
|
178
|
+
).toBeTruthy();
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it("keeps the non-selected harness's model select editable (per-harness models are independent of the default harness)", async () => {
|
|
182
|
+
renderPanel(createMockStigmer({ whoAmI: vi.fn(async () => ACCOUNT_WITH_DEFAULTS) }));
|
|
183
|
+
await findSyncedField("Keep answers terse.");
|
|
184
|
+
|
|
185
|
+
// Default harness is cursor, yet the Stigmer model stays settable:
|
|
186
|
+
// the launcher applies the model of the session's ACTIVE harness, so
|
|
187
|
+
// hiding or disabling it would remove a real capability.
|
|
188
|
+
await waitFor(() => {
|
|
189
|
+
expect(screen.getByRole("radio", { name: "Cursor" })).toHaveProperty("checked", true);
|
|
190
|
+
});
|
|
191
|
+
const nativeSelect = screen.getByLabelText("Default model — Stigmer") as HTMLSelectElement;
|
|
192
|
+
expect(nativeSelect.disabled).toBe(false);
|
|
193
|
+
fireEvent.change(nativeSelect, { target: { value: "claude-sonnet-4.6" } });
|
|
194
|
+
expect(nativeSelect.value).toBe("claude-sonnet-4.6");
|
|
195
|
+
});
|
|
196
|
+
|
|
163
197
|
it("reflects the saved defaults in the form", async () => {
|
|
164
198
|
renderPanel(createMockStigmer({ whoAmI: vi.fn(async () => ACCOUNT_WITH_DEFAULTS) }));
|
|
165
199
|
await findSyncedField("Keep answers terse.");
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { type FormEvent, useCallback, useId, useRef, useState } from "react";
|
|
4
4
|
import { cn } from "@stigmer/theme";
|
|
5
5
|
import { UNSTYLED_FIELDSET } from "../internal/element-resets.js";
|
|
6
|
-
import { getUserMessage } from "@stigmer/sdk";
|
|
6
|
+
import { getUserMessage, toIdentityProviderUpdateInput } from "@stigmer/sdk";
|
|
7
7
|
import type { IdentityProvider } from "@stigmer/protos/ai/stigmer/iam/identityprovider/v1/api_pb";
|
|
8
8
|
import { IamRole } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
|
|
9
9
|
import { timestampDate, type Timestamp } from "@bufbuild/protobuf/wkt";
|
|
@@ -132,10 +132,13 @@ export function IdentityProviderDetailPanel({
|
|
|
132
132
|
e.preventDefault();
|
|
133
133
|
clearError();
|
|
134
134
|
try {
|
|
135
|
+
// Full-spec-replace safety: spread the complete mapped input and
|
|
136
|
+
// override only the edited fields, so unlisted spec fields (e.g.
|
|
137
|
+
// rate_limit_budget) survive the save. Fields the form clears
|
|
138
|
+
// (SSO providers have no JIT settings) are set to undefined
|
|
139
|
+
// explicitly — omitting them would carry the stale mapped value.
|
|
135
140
|
const updated = await update({
|
|
136
|
-
|
|
137
|
-
slug: meta?.slug,
|
|
138
|
-
org: meta?.org ?? "",
|
|
141
|
+
...toIdentityProviderUpdateInput(identityProvider),
|
|
139
142
|
displayName: displayName.trim(),
|
|
140
143
|
jwksUri: jwksUri.trim(),
|
|
141
144
|
allowedIssuers: issuers
|
|
@@ -146,16 +149,16 @@ export function IdentityProviderDetailPanel({
|
|
|
146
149
|
userinfoEndpoint: userinfoEndpoint.trim() || undefined,
|
|
147
150
|
isSsoProvider: isSso,
|
|
148
151
|
oidcClientId: isSso ? oidcClientId.trim() : undefined,
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
autoGrantRole
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
152
|
+
autoProvisionAccounts: !isSso && autoProvision ? true : undefined,
|
|
153
|
+
autoGrantOnOrg: !isSso && autoGrant ? true : undefined,
|
|
154
|
+
autoGrantRole:
|
|
155
|
+
!isSso && autoGrant && autoGrantRole !== IamRole.iam_role_unspecified
|
|
156
|
+
? autoGrantRole
|
|
157
|
+
: undefined,
|
|
158
|
+
tenantOrgClaim:
|
|
159
|
+
!isSso && autoGrant && tenantOrgClaim.trim()
|
|
160
|
+
? tenantOrgClaim.trim()
|
|
161
|
+
: undefined,
|
|
159
162
|
});
|
|
160
163
|
setMode("view");
|
|
161
164
|
onUpdated?.(updated);
|
|
@@ -164,7 +167,7 @@ export function IdentityProviderDetailPanel({
|
|
|
164
167
|
}
|
|
165
168
|
},
|
|
166
169
|
[
|
|
167
|
-
|
|
170
|
+
identityProvider, displayName, jwksUri, issuers, audience,
|
|
168
171
|
userinfoEndpoint, isSso, oidcClientId, autoProvision, autoGrant,
|
|
169
172
|
autoGrantRole, tenantOrgClaim, update, clearError, onUpdated,
|
|
170
173
|
],
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { describe, it, expect, vi, afterEach } from "vitest";
|
|
2
|
+
import { cleanup, fireEvent, render, screen, waitFor } from "@testing-library/react";
|
|
3
|
+
import { create } from "@bufbuild/protobuf";
|
|
4
|
+
import {
|
|
5
|
+
IdentityProviderSchema,
|
|
6
|
+
type IdentityProvider,
|
|
7
|
+
} from "@stigmer/protos/ai/stigmer/iam/identityprovider/v1/api_pb";
|
|
8
|
+
import { IamRole } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
|
|
9
|
+
import type { IdentityProviderInput } from "@stigmer/sdk";
|
|
10
|
+
import { StigmerContext } from "../../context";
|
|
11
|
+
import { IdentityProviderDetailPanel } from "../IdentityProviderDetailPanel";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Regression suite for the full-spec-replace wipe bug: before the
|
|
15
|
+
* generated-mapper migration, this panel hand-built its update input and
|
|
16
|
+
* NEVER sent `rate_limit_budget` — editing any IdP field zeroed the
|
|
17
|
+
* provider's rate limit. The panel must spread
|
|
18
|
+
* `toIdentityProviderUpdateInput` and override only what it edits.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
const IDP: IdentityProvider = create(IdentityProviderSchema, {
|
|
22
|
+
metadata: {
|
|
23
|
+
id: "idp-1",
|
|
24
|
+
name: "Acme Okta",
|
|
25
|
+
slug: "acme-okta",
|
|
26
|
+
org: "acme",
|
|
27
|
+
},
|
|
28
|
+
spec: {
|
|
29
|
+
displayName: "Acme Okta",
|
|
30
|
+
jwksUri: "https://acme.okta.example/jwks",
|
|
31
|
+
allowedIssuers: ["https://acme.okta.example"],
|
|
32
|
+
expectedAudience: "stigmer",
|
|
33
|
+
rateLimitBudget: 120,
|
|
34
|
+
isSsoProvider: false,
|
|
35
|
+
autoProvisionAccounts: true,
|
|
36
|
+
autoGrantOnOrg: true,
|
|
37
|
+
autoGrantRole: IamRole.admin,
|
|
38
|
+
tenantOrgClaim: "org_slug",
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
function renderPanel(update: ReturnType<typeof vi.fn>) {
|
|
43
|
+
const client = {
|
|
44
|
+
identityProvider: { update },
|
|
45
|
+
} as never;
|
|
46
|
+
return render(
|
|
47
|
+
<StigmerContext.Provider value={client}>
|
|
48
|
+
<IdentityProviderDetailPanel identityProvider={IDP} />
|
|
49
|
+
</StigmerContext.Provider>,
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
afterEach(cleanup);
|
|
54
|
+
|
|
55
|
+
describe("IdentityProviderDetailPanel save payload", () => {
|
|
56
|
+
it("round-trips rate_limit_budget on a display-name edit (the wipe bug)", async () => {
|
|
57
|
+
const update = vi.fn(async (_input: IdentityProviderInput) => IDP);
|
|
58
|
+
renderPanel(update);
|
|
59
|
+
|
|
60
|
+
fireEvent.click(screen.getByRole("button", { name: "Edit" }));
|
|
61
|
+
const displayName = await screen.findByLabelText("Display name");
|
|
62
|
+
fireEvent.change(displayName, { target: { value: "Acme Okta (renamed)" } });
|
|
63
|
+
fireEvent.click(screen.getByRole("button", { name: "Save changes" }));
|
|
64
|
+
|
|
65
|
+
await waitFor(() => expect(update).toHaveBeenCalledTimes(1));
|
|
66
|
+
const input = update.mock.calls[0]![0];
|
|
67
|
+
|
|
68
|
+
// The wipe-bug guard: the form does not render the rate limit, yet it
|
|
69
|
+
// must survive the save.
|
|
70
|
+
expect(input.rateLimitBudget).toBe(120);
|
|
71
|
+
// The edited field.
|
|
72
|
+
expect(input.displayName).toBe("Acme Okta (renamed)");
|
|
73
|
+
// JIT settings round-trip from the edit state.
|
|
74
|
+
expect(input.autoGrantRole).toBe(IamRole.admin);
|
|
75
|
+
expect(input.tenantOrgClaim).toBe("org_slug");
|
|
76
|
+
// Addressing fields.
|
|
77
|
+
expect(input.org).toBe("acme");
|
|
78
|
+
expect(input.slug).toBe("acme-okta");
|
|
79
|
+
});
|
|
80
|
+
});
|
package/src/index.ts
CHANGED
|
@@ -139,6 +139,8 @@ export {
|
|
|
139
139
|
useSessionList,
|
|
140
140
|
useSessionExecutions,
|
|
141
141
|
useSessionConversation,
|
|
142
|
+
useExportTranscript,
|
|
143
|
+
TranscriptExportMenu,
|
|
142
144
|
useSessionArtifacts,
|
|
143
145
|
artifactKey,
|
|
144
146
|
useSessionWriteBacks,
|
|
@@ -189,6 +191,9 @@ export type {
|
|
|
189
191
|
UseSessionExecutionsReturn,
|
|
190
192
|
SendFollowUpOptions,
|
|
191
193
|
UseSessionConversationReturn,
|
|
194
|
+
UseExportTranscriptOptions,
|
|
195
|
+
UseExportTranscriptReturn,
|
|
196
|
+
TranscriptExportMenuProps,
|
|
192
197
|
SessionArtifactEntry,
|
|
193
198
|
UseSessionArtifactsReturn,
|
|
194
199
|
SessionWriteBackEntry,
|
|
@@ -222,6 +227,11 @@ export type {
|
|
|
222
227
|
RuntimeEnvProvider,
|
|
223
228
|
SessionAudience,
|
|
224
229
|
SessionPanelMode,
|
|
230
|
+
// The #664 pinning seam's contract type: SessionViewer/NewSessionViewer/
|
|
231
|
+
// useNewSessionFlow all accept it, and the docs name it — embedders must
|
|
232
|
+
// be able to import it from the root (oss#802; the exports map exposes no
|
|
233
|
+
// ./session subpath on purpose).
|
|
234
|
+
SessionRunConfig,
|
|
225
235
|
SetupTabProps,
|
|
226
236
|
SetupTabMutationCallbacks,
|
|
227
237
|
} from "./session/index.js";
|
|
@@ -541,6 +551,7 @@ export type {
|
|
|
541
551
|
SessionComposerHandle,
|
|
542
552
|
SessionComposerProps,
|
|
543
553
|
SessionComposerSubmitContext,
|
|
554
|
+
ComposerAutoApproveProps,
|
|
544
555
|
InteractionModePickerProps,
|
|
545
556
|
InteractionModeOption,
|
|
546
557
|
} from "./composer/index.js";
|
|
@@ -567,7 +578,6 @@ export {
|
|
|
567
578
|
McpToolSelector,
|
|
568
579
|
useCreateMcpServer,
|
|
569
580
|
useUpdateMcpServer,
|
|
570
|
-
mcpServerToInput,
|
|
571
581
|
toServerKey,
|
|
572
582
|
IdentityTransportStep,
|
|
573
583
|
EnvironmentAuthStep,
|
|
@@ -696,7 +706,6 @@ export {
|
|
|
696
706
|
useDefaultAgent,
|
|
697
707
|
useCreateAgent,
|
|
698
708
|
useUpdateAgent,
|
|
699
|
-
agentToInput,
|
|
700
709
|
AgentCreationWizard,
|
|
701
710
|
} from "./agent/index.js";
|
|
702
711
|
export type {
|
|
@@ -853,6 +862,28 @@ export type {
|
|
|
853
862
|
AccountPreferencesPanelProps,
|
|
854
863
|
} from "./identity-account/index.js";
|
|
855
864
|
|
|
865
|
+
// Memory — agent-proposed, user-confirmed facts: data hook, decision
|
|
866
|
+
// hooks (confirm/reject/delete/edit), grouping helpers, and the list panel
|
|
867
|
+
export {
|
|
868
|
+
useMemories,
|
|
869
|
+
useConfirmMemory,
|
|
870
|
+
useRejectMemory,
|
|
871
|
+
useDeleteMemory,
|
|
872
|
+
useUpdateMemoryContent,
|
|
873
|
+
groupMemoriesByLifecycle,
|
|
874
|
+
formatMemoryProvenance,
|
|
875
|
+
MemoryListPanel,
|
|
876
|
+
} from "./memory/index.js";
|
|
877
|
+
export type {
|
|
878
|
+
UseMemoriesReturn,
|
|
879
|
+
UseConfirmMemoryReturn,
|
|
880
|
+
UseRejectMemoryReturn,
|
|
881
|
+
UseDeleteMemoryReturn,
|
|
882
|
+
UseUpdateMemoryContentReturn,
|
|
883
|
+
MemoryGroups,
|
|
884
|
+
MemoryListPanelProps,
|
|
885
|
+
} from "./memory/index.js";
|
|
886
|
+
|
|
856
887
|
// IAM Policy — data hooks, behavior hooks, headless hook, and styled components for access management
|
|
857
888
|
export {
|
|
858
889
|
useGrantableRoles,
|
|
@@ -1080,6 +1111,7 @@ export { MembersSection } from "./settings/index.js";
|
|
|
1080
1111
|
export { OrgProfileSection } from "./settings/index.js";
|
|
1081
1112
|
export { OrgPreferencesSection } from "./settings/index.js";
|
|
1082
1113
|
export { AccountPreferencesSection } from "./settings/index.js";
|
|
1114
|
+
export { MemorySection } from "./settings/index.js";
|
|
1083
1115
|
export { EnvironmentsSection } from "./settings/index.js";
|
|
1084
1116
|
export { InvitationsSection } from "./settings/index.js";
|
|
1085
1117
|
export { IdentityProvidersSection } from "./settings/index.js";
|
|
@@ -1311,6 +1343,7 @@ export {
|
|
|
1311
1343
|
ConnectSlackDialog,
|
|
1312
1344
|
ConnectWhatsAppDialog,
|
|
1313
1345
|
ChannelCredentialsDialog,
|
|
1346
|
+
ChannelRunConfigDialog,
|
|
1314
1347
|
ChannelToolCredentials,
|
|
1315
1348
|
ChannelConversationsDialog,
|
|
1316
1349
|
ChannelTemplatesDialog,
|
|
@@ -1334,6 +1367,7 @@ export type {
|
|
|
1334
1367
|
ConnectSlackDialogProps,
|
|
1335
1368
|
ConnectWhatsAppDialogProps,
|
|
1336
1369
|
ChannelCredentialsDialogProps,
|
|
1370
|
+
ChannelRunConfigDialogProps,
|
|
1337
1371
|
ChannelToolCredentialsProps,
|
|
1338
1372
|
ChannelConversationsDialogProps,
|
|
1339
1373
|
ChannelTemplatesDialogProps,
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Client-side file download via Blob + object URL + anchor click.
|
|
2
|
+
//
|
|
3
|
+
// The one home of this routine — useExportResource, useExportCSV, and
|
|
4
|
+
// useExportTranscript all download through it. The pattern is proven inside
|
|
5
|
+
// the desktop (Tauri) webview as well as browsers, so SDK components can rely
|
|
6
|
+
// on it without a per-host seam.
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Triggers a browser download of `content` as a UTF-8 text file.
|
|
10
|
+
*
|
|
11
|
+
* @param mimeType - Bare MIME type (e.g. `"text/markdown"`); the UTF-8
|
|
12
|
+
* charset is appended here so callers cannot drift on it.
|
|
13
|
+
*/
|
|
14
|
+
export function downloadTextFile(
|
|
15
|
+
content: string,
|
|
16
|
+
filename: string,
|
|
17
|
+
mimeType: string,
|
|
18
|
+
): void {
|
|
19
|
+
const blob = new Blob([content], { type: `${mimeType};charset=utf-8;` });
|
|
20
|
+
const url = URL.createObjectURL(blob);
|
|
21
|
+
const link = document.createElement("a");
|
|
22
|
+
link.href = url;
|
|
23
|
+
link.download = filename;
|
|
24
|
+
link.style.display = "none";
|
|
25
|
+
document.body.appendChild(link);
|
|
26
|
+
link.click();
|
|
27
|
+
document.body.removeChild(link);
|
|
28
|
+
URL.revokeObjectURL(url);
|
|
29
|
+
}
|
|
@@ -8,6 +8,7 @@ import type { Schedule } from "@stigmer/protos/ai/stigmer/agentic/schedule/v1/ap
|
|
|
8
8
|
import type { Workflow } from "@stigmer/protos/ai/stigmer/agentic/workflow/v1/api_pb";
|
|
9
9
|
import { serializeManifest } from "@stigmer/sdk";
|
|
10
10
|
import { toast } from "../feedback/toast.js";
|
|
11
|
+
import { downloadTextFile } from "../internal/download.js";
|
|
11
12
|
import { useCopyFeedback } from "../internal/useCopyFeedback.js";
|
|
12
13
|
import { serializeWorkflowYaml } from "../workflow/serialize-workflow-yaml.js";
|
|
13
14
|
|
|
@@ -121,12 +122,12 @@ export function useExportResource({
|
|
|
121
122
|
|
|
122
123
|
const downloadYaml = useCallback(() => {
|
|
123
124
|
if (!yaml) return;
|
|
124
|
-
|
|
125
|
+
downloadTextFile(yaml, `${slug}.yaml`, "text/yaml");
|
|
125
126
|
}, [yaml, slug]);
|
|
126
127
|
|
|
127
128
|
const downloadJson = useCallback(() => {
|
|
128
129
|
if (!json) return;
|
|
129
|
-
|
|
130
|
+
downloadTextFile(json, `${slug}.json`, "application/json");
|
|
130
131
|
}, [json, slug]);
|
|
131
132
|
|
|
132
133
|
return useMemo(
|
|
@@ -134,20 +135,3 @@ export function useExportResource({
|
|
|
134
135
|
[copyYaml, copyJson, downloadYaml, downloadJson, yaml, json],
|
|
135
136
|
);
|
|
136
137
|
}
|
|
137
|
-
|
|
138
|
-
// ---------------------------------------------------------------------------
|
|
139
|
-
// File download
|
|
140
|
-
// ---------------------------------------------------------------------------
|
|
141
|
-
|
|
142
|
-
function downloadFile(content: string, filename: string, mimeType: string): void {
|
|
143
|
-
const blob = new Blob([content], { type: `${mimeType};charset=utf-8;` });
|
|
144
|
-
const url = URL.createObjectURL(blob);
|
|
145
|
-
const link = document.createElement("a");
|
|
146
|
-
link.href = url;
|
|
147
|
-
link.download = filename;
|
|
148
|
-
link.style.display = "none";
|
|
149
|
-
document.body.appendChild(link);
|
|
150
|
-
link.click();
|
|
151
|
-
document.body.removeChild(link);
|
|
152
|
-
URL.revokeObjectURL(url);
|
|
153
|
-
}
|
|
@@ -16,7 +16,7 @@ import type { EnvVarDeclaration } from "@stigmer/protos/ai/stigmer/agentic/envir
|
|
|
16
16
|
import { useMcpServer } from "./useMcpServer.js";
|
|
17
17
|
import type { UseMcpServerReturn } from "./useMcpServer.js";
|
|
18
18
|
import { useUpdateMcpServer } from "./useUpdateMcpServer.js";
|
|
19
|
-
import {
|
|
19
|
+
import { toMcpServerUpdateInput } from "@stigmer/sdk";
|
|
20
20
|
import { useMcpServerConnect } from "./useMcpServerConnect.js";
|
|
21
21
|
import { useMcpServerCredentials } from "./useMcpServerCredentials.js";
|
|
22
22
|
import {
|
|
@@ -214,7 +214,7 @@ export function McpServerDetailView({
|
|
|
214
214
|
value: import("@stigmer/sdk").McpServerInput[K],
|
|
215
215
|
): Promise<boolean> => {
|
|
216
216
|
if (!mcpServer) return false;
|
|
217
|
-
const input =
|
|
217
|
+
const input = toMcpServerUpdateInput(mcpServer);
|
|
218
218
|
(input as unknown as Record<string, unknown>)[field] = value;
|
|
219
219
|
try {
|
|
220
220
|
const updated = await updateMcpServer(input);
|