@stigmer/react 3.0.6 → 3.0.7-dev.20260611143057

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 (94) hide show
  1. package/agent-instance/AgentInstanceDetailPanel.d.ts.map +1 -1
  2. package/agent-instance/AgentInstanceDetailPanel.js +2 -9
  3. package/agent-instance/AgentInstanceDetailPanel.js.map +1 -1
  4. package/agent-instance/AgentInstanceList.d.ts.map +1 -1
  5. package/agent-instance/AgentInstanceList.js +2 -9
  6. package/agent-instance/AgentInstanceList.js.map +1 -1
  7. package/agent-instance/CreateAgentInstanceDialog.d.ts.map +1 -1
  8. package/agent-instance/CreateAgentInstanceDialog.js +1 -1
  9. package/agent-instance/CreateAgentInstanceDialog.js.map +1 -1
  10. package/composer/SessionComposer.d.ts +14 -0
  11. package/composer/SessionComposer.d.ts.map +1 -1
  12. package/composer/SessionComposer.js +15 -9
  13. package/composer/SessionComposer.js.map +1 -1
  14. package/index.d.ts +1 -1
  15. package/index.d.ts.map +1 -1
  16. package/index.js.map +1 -1
  17. package/library/InstanceVisibilitySelector.d.ts +23 -9
  18. package/library/InstanceVisibilitySelector.d.ts.map +1 -1
  19. package/library/InstanceVisibilitySelector.js +14 -9
  20. package/library/InstanceVisibilitySelector.js.map +1 -1
  21. package/library/VisibilityOptionRow.d.ts +52 -0
  22. package/library/VisibilityOptionRow.d.ts.map +1 -0
  23. package/library/VisibilityOptionRow.js +92 -0
  24. package/library/VisibilityOptionRow.js.map +1 -0
  25. package/library/VisibilitySelector.d.ts +47 -24
  26. package/library/VisibilitySelector.d.ts.map +1 -1
  27. package/library/VisibilitySelector.js +137 -115
  28. package/library/VisibilitySelector.js.map +1 -1
  29. package/library/visibilityLevels.d.ts +25 -3
  30. package/library/visibilityLevels.d.ts.map +1 -1
  31. package/library/visibilityLevels.js +8 -2
  32. package/library/visibilityLevels.js.map +1 -1
  33. package/package.json +4 -4
  34. package/session/NewSessionViewer.d.ts +32 -1
  35. package/session/NewSessionViewer.d.ts.map +1 -1
  36. package/session/NewSessionViewer.js +20 -9
  37. package/session/NewSessionViewer.js.map +1 -1
  38. package/session/SessionViewer.d.ts +24 -1
  39. package/session/SessionViewer.d.ts.map +1 -1
  40. package/session/SessionViewer.js +18 -12
  41. package/session/SessionViewer.js.map +1 -1
  42. package/session/audience.d.ts +21 -0
  43. package/session/audience.d.ts.map +1 -0
  44. package/session/audience.js +2 -0
  45. package/session/audience.js.map +1 -0
  46. package/session/index.d.ts +2 -0
  47. package/session/index.d.ts.map +1 -1
  48. package/session/index.js.map +1 -1
  49. package/session/runtime-env.d.ts +47 -0
  50. package/session/runtime-env.d.ts.map +1 -0
  51. package/session/runtime-env.js +20 -0
  52. package/session/runtime-env.js.map +1 -0
  53. package/session/useNewSessionFlow.d.ts +25 -0
  54. package/session/useNewSessionFlow.d.ts.map +1 -1
  55. package/session/useNewSessionFlow.js +20 -8
  56. package/session/useNewSessionFlow.js.map +1 -1
  57. package/session/useSessionPageFlow.d.ts +27 -2
  58. package/session/useSessionPageFlow.d.ts.map +1 -1
  59. package/session/useSessionPageFlow.js +34 -13
  60. package/session/useSessionPageFlow.js.map +1 -1
  61. package/src/agent-instance/AgentInstanceDetailPanel.tsx +7 -27
  62. package/src/agent-instance/AgentInstanceList.tsx +7 -27
  63. package/src/agent-instance/CreateAgentInstanceDialog.tsx +1 -0
  64. package/src/composer/SessionComposer.tsx +30 -8
  65. package/src/composer/__tests__/SessionComposer-lockAgent.test.tsx +150 -0
  66. package/src/index.ts +2 -0
  67. package/src/library/InstanceVisibilitySelector.tsx +27 -9
  68. package/src/library/VisibilityOptionRow.tsx +244 -0
  69. package/src/library/VisibilitySelector.tsx +303 -260
  70. package/src/library/__tests__/VisibilitySelector.test.tsx +256 -0
  71. package/src/library/visibilityLevels.ts +35 -5
  72. package/src/session/NewSessionViewer.tsx +61 -12
  73. package/src/session/SessionViewer.tsx +51 -15
  74. package/src/session/__tests__/audienceWiring.test.tsx +274 -0
  75. package/src/session/__tests__/useNewSessionFlow.test.tsx +122 -0
  76. package/src/session/__tests__/useSessionPageFlow.runtimeEnv.test.tsx +170 -0
  77. package/src/session/audience.ts +20 -0
  78. package/src/session/index.ts +3 -0
  79. package/src/session/runtime-env.ts +57 -0
  80. package/src/session/useNewSessionFlow.ts +44 -9
  81. package/src/session/useSessionPageFlow.ts +65 -17
  82. package/src/workflow/instance/CreateWorkflowInstanceDialog.tsx +1 -0
  83. package/src/workflow/instance/WorkflowInstanceDetailPanel.tsx +7 -27
  84. package/src/workflow/instance/WorkflowInstanceList.tsx +7 -27
  85. package/styles.css +1 -1
  86. package/workflow/instance/CreateWorkflowInstanceDialog.d.ts.map +1 -1
  87. package/workflow/instance/CreateWorkflowInstanceDialog.js +1 -1
  88. package/workflow/instance/CreateWorkflowInstanceDialog.js.map +1 -1
  89. package/workflow/instance/WorkflowInstanceDetailPanel.d.ts.map +1 -1
  90. package/workflow/instance/WorkflowInstanceDetailPanel.js +2 -9
  91. package/workflow/instance/WorkflowInstanceDetailPanel.js.map +1 -1
  92. package/workflow/instance/WorkflowInstanceList.d.ts.map +1 -1
  93. package/workflow/instance/WorkflowInstanceList.js +2 -9
  94. package/workflow/instance/WorkflowInstanceList.js.map +1 -1
@@ -6,6 +6,7 @@ import type { SessionComposerSubmitContext, InteractionModeOption } from "../com
6
6
  import { type HarnessOption } from "../models/harness";
7
7
  import { type ExecutionTargetOption } from "./execution-target";
8
8
  import { type UseSessionConversationReturn } from "./useSessionConversation";
9
+ import { type RuntimeEnvProvider } from "./runtime-env";
9
10
  import { type UsePersistedModelReturn } from "./usePersistedModel";
10
11
  /** Options for {@link useSessionPageFlow}. */
11
12
  export interface UseSessionPageFlowOptions {
@@ -13,6 +14,18 @@ export interface UseSessionPageFlowOptions {
13
14
  readonly sessionId: string;
14
15
  /** Organization slug. */
15
16
  readonly org: string;
17
+ /**
18
+ * Supplies host-app environment variables for every follow-up
19
+ * execution. Evaluated once per follow-up, at send time, so
20
+ * short-lived credentials stay fresh.
21
+ *
22
+ * Host values win over composer-collected env on key collisions. If
23
+ * the provider throws, the follow-up is aborted before any optimistic
24
+ * UI or session mutation and the error surfaces via
25
+ * {@link UseSessionPageFlowReturn.submitError}. See
26
+ * {@link RuntimeEnvProvider}.
27
+ */
28
+ readonly getRuntimeEnv?: RuntimeEnvProvider;
16
29
  }
17
30
  /** Return value of {@link useSessionPageFlow}. */
18
31
  export interface UseSessionPageFlowReturn {
@@ -99,10 +112,22 @@ export interface UseSessionPageFlowReturn {
99
112
  readonly submitApproval: UseSessionConversationReturn["submitApproval"];
100
113
  /**
101
114
  * Submit a follow-up message. Handles agent override resolution
102
- * (if the user changed the agent mid-session) and delegates to
103
- * `conv.sendFollowUp` with all managed state.
115
+ * (if the user changed the agent mid-session), evaluates the host
116
+ * runtime-env provider, and delegates to `conv.sendFollowUp` with
117
+ * all managed state. Never rejects — pre-send failures land in
118
+ * {@link submitError}.
104
119
  */
105
120
  readonly handleSubmit: (message: string, model?: string, context?: SessionComposerSubmitContext) => Promise<void>;
121
+ /**
122
+ * Error from the most recent follow-up's pre-send work (agent
123
+ * override resolution, host runtime-env evaluation), or `null`.
124
+ *
125
+ * Distinct from `conv.sendError`, which covers the create-execution
126
+ * RPC itself. Kept as the raw `Error` so consumers can render
127
+ * contextual guidance (e.g. secret-flow errors). Cleared at the
128
+ * start of each submission.
129
+ */
130
+ readonly submitError: Error | null;
106
131
  /**
107
132
  * The most relevant execution for sidebar display — the active
108
133
  * streaming execution, or the last completed one.
@@ -1 +1 @@
1
- {"version":3,"file":"useSessionPageFlow.d.ts","sourceRoot":"","sources":["../../src/session/useSessionPageFlow.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useSessionPageFlow.d.ts","sourceRoot":"","sources":["../../src/session/useSessionPageFlow.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,7 @@ import { fromProtoHarness } from "../models/harness";
10
10
  import { Harness, ExecutionTarget } from "@stigmer/protos/ai/stigmer/agentic/session/v1/enum_pb";
11
11
  import { fromProtoExecutionTarget } from "./execution-target";
12
12
  import { useSessionConversation } from "./useSessionConversation";
13
+ import { resolveExecutionRuntimeEnv } from "./runtime-env";
13
14
  import { useAgentRefFromSession } from "./useAgentRefFromSession";
14
15
  import { usePersistedModel } from "./usePersistedModel";
15
16
  import { specMcpUsagesToInput, specSkillRefsToInput } from "./session-spec-converters";
@@ -60,7 +61,7 @@ const DAYTONA_WORKSPACE_ROOT = "/home/daytona/workspace";
60
61
  * ```
61
62
  */
62
63
  export function useSessionPageFlow(options) {
63
- const { sessionId, org } = options;
64
+ const { sessionId, org, getRuntimeEnv } = options;
64
65
  const stigmer = useStigmer();
65
66
  const conv = useSessionConversation(sessionId, org);
66
67
  const harness = fromProtoHarness(conv.session?.spec?.harness ?? Harness.UNSPECIFIED);
@@ -152,20 +153,39 @@ export function useSessionPageFlow(options) {
152
153
  // -------------------------------------------------------------------------
153
154
  // Follow-up submission with agent override
154
155
  // -------------------------------------------------------------------------
156
+ const [submitError, setSubmitError] = useState(null);
155
157
  const handleSubmit = useCallback(async (message, selectedModel, context) => {
158
+ setSubmitError(null);
159
+ // Pre-send work runs before conv.sendFollowUp so a failure here
160
+ // aborts cleanly: no optimistic pending message, no session
161
+ // mutation. The composer fires this handler without awaiting it,
162
+ // so a rejection would otherwise be an unhandled rejection —
163
+ // failures must land in submitError instead.
156
164
  let agentInstanceIdOverride;
157
- if (resolution) {
158
- if (resolution.mode === "saved" &&
159
- resolution.instanceId !== sessionInstanceId) {
160
- agentInstanceIdOverride = resolution.instanceId;
161
- }
162
- else if (resolution.mode === "direct" && agentRef) {
163
- const agent = await stigmer.agent.getByReference(agentRef);
164
- const defaultId = agent.status?.defaultInstanceId;
165
- if (defaultId && defaultId !== sessionInstanceId) {
166
- agentInstanceIdOverride = defaultId;
165
+ let runtimeEnv;
166
+ try {
167
+ if (resolution) {
168
+ if (resolution.mode === "saved" &&
169
+ resolution.instanceId !== sessionInstanceId) {
170
+ agentInstanceIdOverride = resolution.instanceId;
171
+ }
172
+ else if (resolution.mode === "direct" && agentRef) {
173
+ const agent = await stigmer.agent.getByReference(agentRef);
174
+ const defaultId = agent.status?.defaultInstanceId;
175
+ if (defaultId && defaultId !== sessionInstanceId) {
176
+ agentInstanceIdOverride = defaultId;
177
+ }
167
178
  }
168
179
  }
180
+ // Evaluated per follow-up so short-lived host credentials are
181
+ // current; host values win over composer-collected env.
182
+ runtimeEnv = getRuntimeEnv
183
+ ? await resolveExecutionRuntimeEnv(getRuntimeEnv, context?.runtimeEnv)
184
+ : context?.runtimeEnv;
185
+ }
186
+ catch (err) {
187
+ setSubmitError(err instanceof Error ? err : new Error(String(err)));
188
+ return;
169
189
  }
170
190
  conv.sendFollowUp(message, {
171
191
  agentInstanceId: agentInstanceIdOverride,
@@ -175,7 +195,7 @@ export function useSessionPageFlow(options) {
175
195
  : undefined,
176
196
  mcpServerUsages: mcpServerUsages.length > 0 ? mcpServerUsages : undefined,
177
197
  skillRefs: skillRefs.length > 0 ? skillRefs : undefined,
178
- runtimeEnv: context?.runtimeEnv,
198
+ runtimeEnv,
179
199
  attachments: context?.attachments,
180
200
  interactionMode: context?.interactionMode,
181
201
  // Sourced from the session-scoped preference set at the approval gate,
@@ -184,7 +204,7 @@ export function useSessionPageFlow(options) {
184
204
  workspaceFileRefs: context?.workspaceFileRefs,
185
205
  });
186
206
  sessionVariables.clear();
187
- }, [conv.sendFollowUp, modelId, workspace, mcpServerUsages, skillRefs, sessionVariables.clear, resolution, agentRef, sessionInstanceId, stigmer, autoApproveAll]);
207
+ }, [conv.sendFollowUp, modelId, workspace, mcpServerUsages, skillRefs, sessionVariables.clear, resolution, agentRef, sessionInstanceId, stigmer, autoApproveAll, getRuntimeEnv]);
188
208
  // -------------------------------------------------------------------------
189
209
  // Derived display state
190
210
  // -------------------------------------------------------------------------
@@ -224,6 +244,7 @@ export function useSessionPageFlow(options) {
224
244
  setAutoApproveAll,
225
245
  submitApproval,
226
246
  handleSubmit,
247
+ submitError,
227
248
  displayExecution,
228
249
  allExecutions,
229
250
  sandboxWorkspaceRoot,
@@ -1 +1 @@
1
- {"version":3,"file":"useSessionPageFlow.js","sourceRoot":"","sources":["../../src/session/useSessionPageFlow.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useSessionPageFlow.js","sourceRoot":"","sources":["../../src/session/useSessionPageFlow.ts"],"names":[],"mappings":"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"}
@@ -10,9 +10,7 @@ import type { ResourceRef } from "@stigmer/sdk";
10
10
  import { getUserMessage } from "@stigmer/sdk";
11
11
  import { useUpdateAgentInstance } from "./useUpdateAgentInstance";
12
12
  import { useDeleteAgentInstance } from "./useDeleteAgentInstance";
13
- import { useUpdateVisibility } from "../library/useUpdateVisibility";
14
- import { InstanceVisibilitySelector } from "../library/InstanceVisibilitySelector";
15
- import { visibilityLabel } from "../library/visibilityLevels";
13
+ import { ResourceVisibilityControl } from "../library/ResourceVisibilityControl";
16
14
  import { PermissionGate } from "../iam-policy/PermissionGate";
17
15
  import { SharePanel } from "../iam-policy/SharePanel";
18
16
  import { EnvironmentPicker } from "../environment/EnvironmentPicker";
@@ -56,7 +54,6 @@ export function AgentInstanceDetailPanel({
56
54
 
57
55
  const { update, isUpdating } = useUpdateAgentInstance();
58
56
  const { deleteInstance, isDeleting } = useDeleteAgentInstance();
59
- const { updateVisibility, isPending: isVisibilityPending } = useUpdateVisibility("agentInstance", id || null);
60
57
  const { environments } = useEnvironmentList(org);
61
58
 
62
59
  const [isEditingEnvs, setIsEditingEnvs] = useState(false);
@@ -65,14 +62,6 @@ export function AgentInstanceDetailPanel({
65
62
  const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
66
63
  const [deleteError, setDeleteError] = useState<Error | null>(null);
67
64
 
68
- const handleVisibilityChange = useCallback(
69
- async (v: ApiResourceVisibility) => {
70
- await updateVisibility(v);
71
- onUpdated?.();
72
- },
73
- [updateVisibility, onUpdated],
74
- );
75
-
76
65
  const handleStartEditEnvs = useCallback(() => {
77
66
  const currentRefs: ResourceRef[] = (spec?.environmentRefs ?? []).map((ref) => ({
78
67
  org: ref.org || org,
@@ -255,21 +244,12 @@ export function AgentInstanceDetailPanel({
255
244
  {/* Visibility */}
256
245
  <div className="px-4 py-3">
257
246
  <h4 className="text-xs font-medium text-muted-foreground mb-2">Visibility</h4>
258
- <PermissionGate
259
- resource={{ kind: "agent_instance", id }}
260
- relation="can_edit"
261
- fallback={
262
- <span className="text-sm text-foreground">
263
- {visibilityLabel(meta?.visibility ?? ApiResourceVisibility.visibility_private)}
264
- </span>
265
- }
266
- >
267
- <InstanceVisibilitySelector
268
- visibility={meta?.visibility ?? ApiResourceVisibility.visibility_private}
269
- onVisibilityChange={handleVisibilityChange}
270
- isPending={isVisibilityPending}
271
- />
272
- </PermissionGate>
247
+ <ResourceVisibilityControl
248
+ kind="agentInstance"
249
+ resourceId={id}
250
+ visibility={meta?.visibility ?? ApiResourceVisibility.visibility_private}
251
+ onChanged={onUpdated}
252
+ />
273
253
  </div>
274
254
 
275
255
  {/* Share Panel */}
@@ -6,9 +6,7 @@ import type { AgentInstance } from "@stigmer/protos/ai/stigmer/agentic/agentinst
6
6
  import { ApiResourceVisibility } from "@stigmer/protos/ai/stigmer/commons/apiresource/enum_pb";
7
7
  import { useAgentInstances } from "./useAgentInstances";
8
8
  import { useEnvironmentList } from "../environment/useEnvironmentList";
9
- import { useUpdateVisibility } from "../library/useUpdateVisibility";
10
- import { InstanceVisibilitySelector } from "../library/InstanceVisibilitySelector";
11
- import { visibilityLabel } from "../library/visibilityLevels";
9
+ import { ResourceVisibilityControl } from "../library/ResourceVisibilityControl";
12
10
  import { PermissionGate } from "../iam-policy/PermissionGate";
13
11
  import { AgentInstanceEmptyState } from "./AgentInstanceEmptyState";
14
12
 
@@ -176,18 +174,9 @@ function InstanceRow({
176
174
  const meta = instance.metadata;
177
175
  const id = meta?.id ?? "";
178
176
  const isPersonal = meta?.labels?.[PERSONAL_LABEL] === "true";
179
- const { updateVisibility, isPending } = useUpdateVisibility("agentInstance", id || null);
180
177
 
181
178
  const envRefs = instance.spec?.environmentRefs ?? [];
182
179
 
183
- const handleVisibilityChange = useCallback(
184
- async (v: ApiResourceVisibility) => {
185
- await updateVisibility(v);
186
- refetch();
187
- },
188
- [updateVisibility, refetch],
189
- );
190
-
191
180
  return (
192
181
  <tr
193
182
  className={cn(
@@ -246,21 +235,12 @@ function InstanceRow({
246
235
 
247
236
  <td className="px-4 py-2.5" onClick={(e) => e.stopPropagation()}>
248
237
  {id ? (
249
- <PermissionGate
250
- resource={{ kind: "agent_instance", id }}
251
- relation="can_edit"
252
- fallback={
253
- <span className="text-xs text-muted-foreground">
254
- {visibilityLabel(meta?.visibility ?? ApiResourceVisibility.visibility_private)}
255
- </span>
256
- }
257
- >
258
- <InstanceVisibilitySelector
259
- visibility={meta?.visibility ?? ApiResourceVisibility.visibility_private}
260
- onVisibilityChange={handleVisibilityChange}
261
- isPending={isPending}
262
- />
263
- </PermissionGate>
238
+ <ResourceVisibilityControl
239
+ kind="agentInstance"
240
+ resourceId={id}
241
+ visibility={meta?.visibility ?? ApiResourceVisibility.visibility_private}
242
+ onChanged={refetch}
243
+ />
264
244
  ) : (
265
245
  <span className="text-xs text-muted-foreground">{"\u2014"}</span>
266
246
  )}
@@ -203,6 +203,7 @@ export function CreateAgentInstanceDialog({
203
203
  <InstanceVisibilitySelector
204
204
  visibility={visibility}
205
205
  onVisibilityChange={setVisibility}
206
+ mode="create"
206
207
  disabled={isCreating}
207
208
  />
208
209
  </div>
@@ -309,6 +309,21 @@ export interface SessionComposerProps {
309
309
  */
310
310
  readonly isDefaultAgent?: boolean;
311
311
 
312
+ /**
313
+ * Lock the current agent: the Agent entry is removed from the
314
+ * Configure menu so the user cannot swap or deselect it.
315
+ *
316
+ * Locking does not unwire the agent machinery — `initialAgentRef`
317
+ * resolution still runs on mount, and when the agent requires
318
+ * credentials the environment form stays reachable in the Configure
319
+ * menu until setup completes (lock ≠ unwire). Pair with
320
+ * `initialAgentRef` to pin a pre-configured agent in end-user-facing
321
+ * embeds (see `SessionViewer` / `NewSessionViewer` `audience`).
322
+ *
323
+ * @default false
324
+ */
325
+ readonly lockAgent?: boolean;
326
+
312
327
  /**
313
328
  * Currently selected MCP server usages.
314
329
  * When `onMcpServerUsagesChange` is provided, a MCP server trigger
@@ -496,6 +511,7 @@ const SessionComposerInner = forwardRef<SessionComposerHandle, SessionComposerPr
496
511
  initialAgentRef,
497
512
  initialInstanceId,
498
513
  isDefaultAgent = false,
514
+ lockAgent = false,
499
515
  mcpServerUsages,
500
516
  onMcpServerUsagesChange,
501
517
  skillRefs,
@@ -1140,13 +1156,19 @@ const SessionComposerInner = forwardRef<SessionComposerHandle, SessionComposerPr
1140
1156
  (agentSetup.state.status === "needsEnvVars" ||
1141
1157
  agentSetup.state.status === "resolving" ||
1142
1158
  agentSetup.state.status === "submitting");
1143
- items.push({
1144
- id: "agent",
1145
- icon: <AgentIcon />,
1146
- label: "Agent",
1147
- count: agentRef || agentPending ? 1 : 0,
1148
- hasWarning: agentPending && agentSetup.state.status === "needsEnvVars",
1149
- });
1159
+ // A locked agent stays out of the menu unless setup is pending:
1160
+ // the env-collection form lives in this panel and must remain
1161
+ // reachable until the agent resolves (lock ≠ unwire). Once
1162
+ // resolved, the entry disappears and the agent cannot be swapped.
1163
+ if (!lockAgent || agentPending) {
1164
+ items.push({
1165
+ id: "agent",
1166
+ icon: <AgentIcon />,
1167
+ label: "Agent",
1168
+ count: agentRef || agentPending ? 1 : 0,
1169
+ hasWarning: agentPending && agentSetup.state.status === "needsEnvVars",
1170
+ });
1171
+ }
1150
1172
  }
1151
1173
  if (showMcp) {
1152
1174
  items.push({
@@ -1174,7 +1196,7 @@ const SessionComposerInner = forwardRef<SessionComposerHandle, SessionComposerPr
1174
1196
  });
1175
1197
  }
1176
1198
  return items;
1177
- }, [showAgent, agentRef, agentSetup.state, showMcp, mcpCount, mcpSetup.needsSetupCount, showSkills, skillCount, showSessionVars, sessionVarCount]);
1199
+ }, [showAgent, lockAgent, agentRef, agentSetup.state, showMcp, mcpCount, mcpSetup.needsSetupCount, showSkills, skillCount, showSessionVars, sessionVarCount]);
1178
1200
 
1179
1201
  const renderConfigPanel = useCallback(
1180
1202
  (panelId: string): React.ReactNode => {
@@ -0,0 +1,150 @@
1
+ import { describe, it, expect, vi, beforeAll, beforeEach, afterEach } from "vitest";
2
+ import { render, screen, cleanup, fireEvent } from "@testing-library/react";
3
+ import type { ReactNode } from "react";
4
+ import type { Stigmer } from "@stigmer/sdk";
5
+ import { StigmerContext } from "../../context";
6
+ import { ModelRegistryContext } from "../../models/ModelRegistryContext";
7
+
8
+ // Without a StigmerProvider the portal container is null, and Base UI's
9
+ // Portal renders nothing — pin it to document.body so the popover mounts.
10
+ vi.mock("../../portal-container", () => ({
11
+ useStigmerPortalContainer: () => document.body,
12
+ }));
13
+
14
+ // Controllable agent-setup state — lets these tests drive the lock × setup
15
+ // matrix directly instead of exercising the full resolution state machine
16
+ // (which is covered by useAgentSetup's own tests).
17
+ const mockAgentSetup = {
18
+ state: { status: "idle" } as Record<string, unknown>,
19
+ resolveAgent: vi.fn(),
20
+ resolveToInstance: vi.fn(),
21
+ submitEnvVars: vi.fn(),
22
+ reset: vi.fn(),
23
+ };
24
+ vi.mock("../../agent/useAgentSetup", () => ({
25
+ useAgentSetup: () => mockAgentSetup,
26
+ }));
27
+
28
+ import { SessionComposer } from "../SessionComposer";
29
+
30
+ // Base UI's Popover positioner observes its anchor; happy-dom lacks
31
+ // ResizeObserver, so provide a no-op shim.
32
+ beforeAll(() => {
33
+ if (!("ResizeObserver" in globalThis)) {
34
+ (globalThis as unknown as { ResizeObserver: unknown }).ResizeObserver =
35
+ class {
36
+ observe() {}
37
+ unobserve() {}
38
+ disconnect() {}
39
+ };
40
+ }
41
+ });
42
+
43
+ function createMinimalStigmerMock(): Stigmer {
44
+ return {
45
+ agentExecution: { uploadAttachment: vi.fn() },
46
+ environment: { getPersonal: vi.fn().mockResolvedValue(null) },
47
+ baseUrl: "http://localhost:8080",
48
+ getAuthCredential: vi.fn().mockResolvedValue("test-token"),
49
+ config: {
50
+ baseUrl: "http://localhost:8080",
51
+ getAccessToken: vi.fn().mockResolvedValue(""),
52
+ },
53
+ } as unknown as Stigmer;
54
+ }
55
+
56
+ function createWrapper(client: Stigmer) {
57
+ return function Wrapper({ children }: { children: ReactNode }) {
58
+ return (
59
+ <StigmerContext.Provider value={client}>
60
+ <ModelRegistryContext.Provider
61
+ value={{ models: [], isLoading: false, error: null, refetch: vi.fn() }}
62
+ >
63
+ {children}
64
+ </ModelRegistryContext.Provider>
65
+ </StigmerContext.Provider>
66
+ );
67
+ };
68
+ }
69
+
70
+ function renderComposer(
71
+ props?: Partial<React.ComponentProps<typeof SessionComposer>>,
72
+ ) {
73
+ const client = createMinimalStigmerMock();
74
+ return render(
75
+ <SessionComposer
76
+ onSubmit={vi.fn()}
77
+ org="acme"
78
+ agentRef={null}
79
+ onAgentRefChange={vi.fn()}
80
+ onSkillRefsChange={vi.fn()}
81
+ skillRefs={[]}
82
+ {...props}
83
+ />,
84
+ { wrapper: createWrapper(client) },
85
+ );
86
+ }
87
+
88
+ function openConfigureMenu() {
89
+ fireEvent.click(
90
+ screen.getByRole("button", { name: "Configure agent, tools, and skills" }),
91
+ );
92
+ }
93
+
94
+ beforeEach(() => {
95
+ mockAgentSetup.state = { status: "idle" };
96
+ });
97
+
98
+ afterEach(cleanup);
99
+
100
+ describe("SessionComposer — lockAgent", () => {
101
+ it("shows the Agent entry in the Configure menu by default", () => {
102
+ renderComposer();
103
+ openConfigureMenu();
104
+
105
+ expect(screen.getByRole("menuitem", { name: /Agent/ })).toBeTruthy();
106
+ });
107
+
108
+ it("hides the Agent entry when locked, leaving other entries intact", () => {
109
+ renderComposer({
110
+ lockAgent: true,
111
+ agentRef: { org: "acme", slug: "support-bot" },
112
+ });
113
+ openConfigureMenu();
114
+
115
+ expect(screen.queryByRole("menuitem", { name: /Agent/ })).toBeNull();
116
+ expect(screen.getByRole("menuitem", { name: /Skills/ })).toBeTruthy();
117
+ });
118
+
119
+ it("keeps the Agent entry reachable while a locked agent needs env vars", () => {
120
+ // A pinned agent that requires credentials: resolution is pending and
121
+ // the env form lives in the Configure > Agent panel — lock ≠ unwire.
122
+ mockAgentSetup.state = {
123
+ status: "needsEnvVars",
124
+ agentName: "Support Bot",
125
+ agentRef: { org: "acme", slug: "support-bot" },
126
+ missingVariables: [{ key: "API_KEY", isSecret: true }],
127
+ error: null,
128
+ };
129
+ renderComposer({ lockAgent: true });
130
+
131
+ // The composer surfaces the pending setup both as a warning banner...
132
+ expect(screen.getByText("Agent needs configuration before use")).toBeTruthy();
133
+
134
+ // ...and as a (warning-marked) Configure menu entry, despite the lock.
135
+ openConfigureMenu();
136
+ expect(screen.getByRole("menuitem", { name: /Agent/ })).toBeTruthy();
137
+ });
138
+
139
+ it("removes the Agent entry once the locked agent has resolved", () => {
140
+ mockAgentSetup.state = { status: "idle" };
141
+ renderComposer({
142
+ lockAgent: true,
143
+ agentRef: { org: "acme", slug: "support-bot" },
144
+ });
145
+
146
+ expect(screen.queryByText("Agent needs configuration before use")).toBeNull();
147
+ openConfigureMenu();
148
+ expect(screen.queryByRole("menuitem", { name: /Agent/ })).toBeNull();
149
+ });
150
+ });
package/src/index.ts CHANGED
@@ -150,6 +150,8 @@ export type {
150
150
  SearchResultGroup,
151
151
  SessionViewerProps,
152
152
  NewSessionViewerProps,
153
+ RuntimeEnvProvider,
154
+ SessionAudience,
153
155
  SessionInspectorProps,
154
156
  SessionInspectorTabId,
155
157
  UseSessionInspectorOptions,
@@ -1,7 +1,10 @@
1
1
  "use client";
2
2
 
3
3
  import type { ApiResourceVisibility } from "@stigmer/protos/ai/stigmer/commons/apiresource/enum_pb";
4
- import { VisibilitySelector } from "./VisibilitySelector";
4
+ import {
5
+ VisibilitySelector,
6
+ type VisibilitySelectorMode,
7
+ } from "./VisibilitySelector";
5
8
  import { INSTANCE_VISIBILITY_LEVELS } from "./visibilityLevels";
6
9
 
7
10
  /** Props for {@link InstanceVisibilitySelector}. */
@@ -9,10 +12,18 @@ export interface InstanceVisibilitySelectorProps {
9
12
  /** Current visibility of the instance. */
10
13
  readonly visibility: ApiResourceVisibility;
11
14
  /**
12
- * Called when the user confirms a visibility change.
13
- * Escalating visibility (to org or public) shows an inline confirmation.
15
+ * Called when the user selects (and, for escalations in `"manage"` mode,
16
+ * confirms) a visibility change. Escalating to Organization shows a light
17
+ * inline confirm; escalating to Public opens a blocking confirm dialog.
14
18
  */
15
19
  readonly onVisibilityChange: (v: ApiResourceVisibility) => void;
20
+ /**
21
+ * Presentation + confirmation mode, forwarded to {@link VisibilitySelector}.
22
+ * Use `"create"` when picking an initial value inside a create dialog
23
+ * (inline list, applies immediately); defaults to `"manage"` (popover with
24
+ * escalation confirmation) for live instances.
25
+ */
26
+ readonly mode?: VisibilitySelectorMode;
16
27
  /** Shows a spinner/disabled state while the RPC is in flight. */
17
28
  readonly isPending?: boolean;
18
29
  /** Disables all interaction (e.g., when the user lacks can_edit). */
@@ -31,23 +42,29 @@ export interface InstanceVisibilitySelectorProps {
31
42
  * members automatically see all executions via FGA inheritance (zero
32
43
  * per-execution tuples needed).
33
44
  *
45
+ * For live instances, prefer {@link ResourceVisibilityControl} (which adds
46
+ * the read-only {@link VisibilityBadge} fallback for non-editors). This thin
47
+ * preset is used directly when picking an initial value inside a create
48
+ * dialog, where `mode="create"` renders an inline list instead of a popover
49
+ * (a portaled popover would stack beneath a native `<dialog>`'s top layer).
50
+ *
34
51
  * @example
35
52
  * ```tsx
36
- * const { updateVisibility, isPending } = useUpdateVisibility(
37
- * "workflowInstance",
38
- * instance.metadata.id,
53
+ * const [visibility, setVisibility] = useState(
54
+ * ApiResourceVisibility.visibility_private,
39
55
  * );
40
56
  *
41
57
  * <InstanceVisibilitySelector
42
- * visibility={instance.metadata.visibility}
43
- * onVisibilityChange={updateVisibility}
44
- * isPending={isPending}
58
+ * mode="create"
59
+ * visibility={visibility}
60
+ * onVisibilityChange={setVisibility}
45
61
  * />
46
62
  * ```
47
63
  */
48
64
  export function InstanceVisibilitySelector({
49
65
  visibility,
50
66
  onVisibilityChange,
67
+ mode,
51
68
  isPending = false,
52
69
  disabled = false,
53
70
  className,
@@ -57,6 +74,7 @@ export function InstanceVisibilitySelector({
57
74
  visibility={visibility}
58
75
  options={INSTANCE_VISIBILITY_LEVELS}
59
76
  onVisibilityChange={onVisibilityChange}
77
+ mode={mode}
60
78
  isPending={isPending}
61
79
  disabled={disabled}
62
80
  ariaLabel="Instance visibility"