@stigmer/react 3.1.7 → 3.1.9

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 (206) hide show
  1. package/agent/AgentDetailView.d.ts +9 -1
  2. package/agent/AgentDetailView.d.ts.map +1 -1
  3. package/agent/AgentDetailView.js +15 -4
  4. package/agent/AgentDetailView.js.map +1 -1
  5. package/environment/EnvironmentListPanel.d.ts.map +1 -1
  6. package/environment/EnvironmentListPanel.js +11 -3
  7. package/environment/EnvironmentListPanel.js.map +1 -1
  8. package/environment/EnvironmentPicker.d.ts +17 -1
  9. package/environment/EnvironmentPicker.d.ts.map +1 -1
  10. package/environment/EnvironmentPicker.js +3 -2
  11. package/environment/EnvironmentPicker.js.map +1 -1
  12. package/environment/EnvironmentVariableEditor.d.ts.map +1 -1
  13. package/environment/EnvironmentVariableEditor.js +9 -3
  14. package/environment/EnvironmentVariableEditor.js.map +1 -1
  15. package/environment/index.d.ts +1 -0
  16. package/environment/index.d.ts.map +1 -1
  17. package/environment/index.js +1 -0
  18. package/environment/index.js.map +1 -1
  19. package/environment/shareRestriction.d.ts +13 -0
  20. package/environment/shareRestriction.d.ts.map +1 -0
  21. package/environment/shareRestriction.js +15 -0
  22. package/environment/shareRestriction.js.map +1 -0
  23. package/execution/ToolCallItem.d.ts.map +1 -1
  24. package/execution/ToolCallItem.js +12 -0
  25. package/execution/ToolCallItem.js.map +1 -1
  26. package/execution/ToolRunGroup.js +4 -0
  27. package/execution/ToolRunGroup.js.map +1 -1
  28. package/execution/WriteBackCard.d.ts +14 -5
  29. package/execution/WriteBackCard.d.ts.map +1 -1
  30. package/execution/WriteBackCard.js +103 -32
  31. package/execution/WriteBackCard.js.map +1 -1
  32. package/execution/WriteBacksWidget.d.ts +1 -1
  33. package/execution/WriteBacksWidget.js +2 -2
  34. package/execution/WriteBacksWidget.js.map +1 -1
  35. package/execution/index.d.ts +2 -0
  36. package/execution/index.d.ts.map +1 -1
  37. package/execution/index.js +1 -0
  38. package/execution/index.js.map +1 -1
  39. package/execution/write-back-utils.d.ts +57 -0
  40. package/execution/write-back-utils.d.ts.map +1 -0
  41. package/execution/write-back-utils.js +81 -0
  42. package/execution/write-back-utils.js.map +1 -0
  43. package/index.d.ts +6 -2
  44. package/index.d.ts.map +1 -1
  45. package/index.js +6 -1
  46. package/index.js.map +1 -1
  47. package/internal/dev/dom-counter.d.ts.map +1 -1
  48. package/internal/dev/dom-counter.js +2 -2
  49. package/internal/dev/dom-counter.js.map +1 -1
  50. package/internal/dev/enabled.d.ts +7 -0
  51. package/internal/dev/enabled.d.ts.map +1 -0
  52. package/internal/dev/enabled.js +38 -0
  53. package/internal/dev/enabled.js.map +1 -0
  54. package/internal/dev/profiler-wrapper.d.ts +3 -3
  55. package/internal/dev/profiler-wrapper.d.ts.map +1 -1
  56. package/internal/dev/profiler-wrapper.js +5 -5
  57. package/internal/dev/profiler-wrapper.js.map +1 -1
  58. package/internal/dev/use-key-stability.d.ts.map +1 -1
  59. package/internal/dev/use-key-stability.js +2 -2
  60. package/internal/dev/use-key-stability.js.map +1 -1
  61. package/internal/dev/use-render-tracer.d.ts +2 -2
  62. package/internal/dev/use-render-tracer.d.ts.map +1 -1
  63. package/internal/dev/use-render-tracer.js +4 -4
  64. package/internal/dev/use-render-tracer.js.map +1 -1
  65. package/internal/dev/use-stream-rate.d.ts +2 -1
  66. package/internal/dev/use-stream-rate.d.ts.map +1 -1
  67. package/internal/dev/use-stream-rate.js +4 -3
  68. package/internal/dev/use-stream-rate.js.map +1 -1
  69. package/library/ResourceVisibilityControl.d.ts +3 -0
  70. package/library/ResourceVisibilityControl.d.ts.map +1 -1
  71. package/library/ResourceVisibilityControl.js +22 -8
  72. package/library/ResourceVisibilityControl.js.map +1 -1
  73. package/library/useUpdateVisibility.d.ts +5 -3
  74. package/library/useUpdateVisibility.d.ts.map +1 -1
  75. package/library/useUpdateVisibility.js +7 -2
  76. package/library/useUpdateVisibility.js.map +1 -1
  77. package/library/visibilityLevels.d.ts +17 -0
  78. package/library/visibilityLevels.d.ts.map +1 -1
  79. package/library/visibilityLevels.js +32 -0
  80. package/library/visibilityLevels.js.map +1 -1
  81. package/package.json +4 -4
  82. package/session/NewSessionViewer.d.ts +11 -1
  83. package/session/NewSessionViewer.d.ts.map +1 -1
  84. package/session/NewSessionViewer.js +28 -8
  85. package/session/NewSessionViewer.js.map +1 -1
  86. package/session/SessionViewer.d.ts +9 -2
  87. package/session/SessionViewer.d.ts.map +1 -1
  88. package/session/SessionViewer.js +26 -12
  89. package/session/SessionViewer.js.map +1 -1
  90. package/session/audience.d.ts +12 -4
  91. package/session/audience.d.ts.map +1 -1
  92. package/session/facets/ChangesTab.d.ts.map +1 -1
  93. package/session/facets/ChangesTab.js +3 -1
  94. package/session/facets/ChangesTab.js.map +1 -1
  95. package/session/useNewSessionFlow.d.ts +12 -0
  96. package/session/useNewSessionFlow.d.ts.map +1 -1
  97. package/session/useNewSessionFlow.js +13 -1
  98. package/session/useNewSessionFlow.js.map +1 -1
  99. package/session/useSessionPageFlow.d.ts +13 -0
  100. package/session/useSessionPageFlow.d.ts.map +1 -1
  101. package/session/useSessionPageFlow.js +7 -2
  102. package/session/useSessionPageFlow.js.map +1 -1
  103. package/sharing/ShareAgentDialog.d.ts +57 -0
  104. package/sharing/ShareAgentDialog.d.ts.map +1 -0
  105. package/sharing/ShareAgentDialog.js +478 -0
  106. package/sharing/ShareAgentDialog.js.map +1 -0
  107. package/sharing/SharedAgentChat.d.ts +84 -0
  108. package/sharing/SharedAgentChat.d.ts.map +1 -0
  109. package/sharing/SharedAgentChat.js +80 -0
  110. package/sharing/SharedAgentChat.js.map +1 -0
  111. package/sharing/index.d.ts +18 -0
  112. package/sharing/index.d.ts.map +1 -0
  113. package/sharing/index.js +12 -0
  114. package/sharing/index.js.map +1 -0
  115. package/sharing/useAgentShare.d.ts +43 -0
  116. package/sharing/useAgentShare.d.ts.map +1 -0
  117. package/sharing/useAgentShare.js +54 -0
  118. package/sharing/useAgentShare.js.map +1 -0
  119. package/sharing/useRotateShareLink.d.ts +45 -0
  120. package/sharing/useRotateShareLink.d.ts.map +1 -0
  121. package/sharing/useRotateShareLink.js +58 -0
  122. package/sharing/useRotateShareLink.js.map +1 -0
  123. package/sharing/useSaveAgentShare.d.ts +105 -0
  124. package/sharing/useSaveAgentShare.d.ts.map +1 -0
  125. package/sharing/useSaveAgentShare.js +97 -0
  126. package/sharing/useSaveAgentShare.js.map +1 -0
  127. package/sharing/useShareAgent.d.ts +69 -0
  128. package/sharing/useShareAgent.d.ts.map +1 -0
  129. package/sharing/useShareAgent.js +42 -0
  130. package/sharing/useShareAgent.js.map +1 -0
  131. package/sharing/useShareToolReadiness.d.ts +52 -0
  132. package/sharing/useShareToolReadiness.d.ts.map +1 -0
  133. package/sharing/useShareToolReadiness.js +89 -0
  134. package/sharing/useShareToolReadiness.js.map +1 -0
  135. package/sharing/useSharedAgentProfile.d.ts +85 -0
  136. package/sharing/useSharedAgentProfile.d.ts.map +1 -0
  137. package/sharing/useSharedAgentProfile.js +73 -0
  138. package/sharing/useSharedAgentProfile.js.map +1 -0
  139. package/src/agent/AgentDetailView.tsx +28 -3
  140. package/src/environment/EnvironmentListPanel.tsx +47 -18
  141. package/src/environment/EnvironmentPicker.tsx +23 -2
  142. package/src/environment/EnvironmentVariableEditor.tsx +27 -17
  143. package/src/environment/__tests__/shareRestriction.test.ts +35 -0
  144. package/src/environment/index.ts +5 -0
  145. package/src/environment/shareRestriction.ts +22 -0
  146. package/src/execution/ToolCallItem.tsx +19 -1
  147. package/src/execution/ToolRunGroup.tsx +4 -0
  148. package/src/execution/WriteBackCard.tsx +285 -88
  149. package/src/execution/WriteBacksWidget.tsx +5 -5
  150. package/src/execution/__tests__/ToolCallItem.test.tsx +51 -0
  151. package/src/execution/__tests__/ToolRunGroup.test.tsx +22 -0
  152. package/src/execution/__tests__/WriteBackCard.test.tsx +64 -10
  153. package/src/execution/__tests__/write-back-utils.test.ts +135 -0
  154. package/src/execution/index.ts +7 -0
  155. package/src/execution/write-back-utils.ts +107 -0
  156. package/src/index.ts +38 -0
  157. package/src/internal/dev/__tests__/use-key-stability.test.ts +4 -0
  158. package/src/internal/dev/__tests__/use-render-tracer.test.ts +4 -0
  159. package/src/internal/dev/dom-counter.ts +2 -3
  160. package/src/internal/dev/enabled.ts +39 -0
  161. package/src/internal/dev/profiler-wrapper.tsx +5 -6
  162. package/src/internal/dev/use-key-stability.ts +2 -3
  163. package/src/internal/dev/use-render-tracer.ts +4 -5
  164. package/src/internal/dev/use-stream-rate.ts +4 -4
  165. package/src/library/ResourceVisibilityControl.tsx +23 -7
  166. package/src/library/__tests__/visibilityLevels.test.ts +33 -0
  167. package/src/library/useUpdateVisibility.ts +9 -3
  168. package/src/library/visibilityLevels.ts +36 -0
  169. package/src/session/NewSessionViewer.tsx +67 -31
  170. package/src/session/SessionViewer.tsx +67 -36
  171. package/src/session/__tests__/audienceWiring.test.tsx +99 -0
  172. package/src/session/__tests__/useNewSessionFlow.test.tsx +75 -1
  173. package/src/session/__tests__/useSessionPageFlow.guest.test.tsx +112 -0
  174. package/src/session/audience.ts +12 -4
  175. package/src/session/facets/ChangesTab.tsx +6 -4
  176. package/src/session/useNewSessionFlow.ts +26 -1
  177. package/src/session/useSessionPageFlow.ts +24 -2
  178. package/src/sharing/ShareAgentDialog.tsx +1489 -0
  179. package/src/sharing/SharedAgentChat.tsx +283 -0
  180. package/src/sharing/__tests__/ShareAgentDialog.test.tsx +926 -0
  181. package/src/sharing/__tests__/SharedAgentChat.test.tsx +222 -0
  182. package/src/sharing/__tests__/useAgentShare.test.tsx +149 -0
  183. package/src/sharing/__tests__/useRotateShareLink.test.tsx +96 -0
  184. package/src/sharing/__tests__/useSaveAgentShare.test.tsx +241 -0
  185. package/src/sharing/__tests__/useShareAgent.test.tsx +131 -0
  186. package/src/sharing/__tests__/useShareToolReadiness.test.tsx +219 -0
  187. package/src/sharing/__tests__/useSharedAgentProfile.test.tsx +201 -0
  188. package/src/sharing/index.ts +32 -0
  189. package/src/sharing/useAgentShare.ts +91 -0
  190. package/src/sharing/useRotateShareLink.ts +81 -0
  191. package/src/sharing/useSaveAgentShare.ts +186 -0
  192. package/src/sharing/useShareAgent.tsx +107 -0
  193. package/src/sharing/useShareToolReadiness.ts +131 -0
  194. package/src/sharing/useSharedAgentProfile.ts +132 -0
  195. package/src/switch/Switch.tsx +97 -0
  196. package/src/switch/__tests__/Switch.test.tsx +107 -0
  197. package/src/switch/index.ts +2 -0
  198. package/styles.css +1 -1
  199. package/switch/Switch.d.ts +47 -0
  200. package/switch/Switch.d.ts.map +1 -0
  201. package/switch/Switch.js +41 -0
  202. package/switch/Switch.js.map +1 -0
  203. package/switch/index.d.ts +3 -0
  204. package/switch/index.d.ts.map +1 -0
  205. package/switch/index.js +2 -0
  206. package/switch/index.js.map +1 -0
@@ -16,6 +16,21 @@ export interface EnvironmentPickerProps {
16
16
  readonly onChange: (refs: ResourceRef[]) => void;
17
17
  /** Disable all interactions. */
18
18
  readonly disabled?: boolean;
19
+ /**
20
+ * Restrict which environments are offered in the dropdown. Already
21
+ * selected references remain listed (and removable) even when they no
22
+ * longer pass the filter — hiding them would strand the binding.
23
+ * When omitted, every environment in the org is offered (the default
24
+ * behavior of every existing caller).
25
+ *
26
+ * @example Only org-shared environments (guest-usable credentials):
27
+ * ```tsx
28
+ * filterEnvironment={(env) =>
29
+ * env.metadata?.visibility === ApiResourceVisibility.visibility_org
30
+ * }
31
+ * ```
32
+ */
33
+ readonly filterEnvironment?: (environment: Environment) => boolean;
19
34
  /** Additional CSS class names for the root container. */
20
35
  readonly className?: string;
21
36
  }
@@ -44,6 +59,7 @@ export function EnvironmentPicker({
44
59
  value,
45
60
  onChange,
46
61
  disabled = false,
62
+ filterEnvironment,
47
63
  className,
48
64
  }: EnvironmentPickerProps) {
49
65
  const { environments, isLoading } = useEnvironmentList(org);
@@ -55,8 +71,13 @@ export function EnvironmentPicker({
55
71
  );
56
72
 
57
73
  const availableEnvironments = useMemo(
58
- () => environments.filter((env) => !selectedSlugs.has(env.metadata?.slug ?? "")),
59
- [environments, selectedSlugs],
74
+ () =>
75
+ environments.filter(
76
+ (env) =>
77
+ !selectedSlugs.has(env.metadata?.slug ?? "") &&
78
+ (filterEnvironment?.(env) ?? true),
79
+ ),
80
+ [environments, selectedSlugs, filterEnvironment],
60
81
  );
61
82
 
62
83
  const handleAdd = useCallback(
@@ -12,6 +12,7 @@ import { getUserMessage, type EnvVarInput } from "@stigmer/sdk";
12
12
  import type { Environment } from "@stigmer/protos/ai/stigmer/agentic/environment/v1/api_pb";
13
13
  import { useStigmer } from "../hooks.js";
14
14
  import { toError } from "../internal/toError.js";
15
+ import { PermissionGate } from "../iam-policy/PermissionGate.js";
15
16
  import { useUpdateEnvironmentVariables } from "./useUpdateEnvironmentVariables.js";
16
17
  import { useRemoveEnvironmentVariables } from "./useRemoveEnvironmentVariables.js";
17
18
  import { useRevealSecretValue } from "./useRevealSecretValue.js";
@@ -438,24 +439,33 @@ function VariableRow({
438
439
  !readOnly && (
439
440
  <div className="flex shrink-0 items-center gap-0.5 opacity-0 transition-opacity group-hover:opacity-100 group-focus-within:opacity-100">
440
441
  {variable.isSecret && (
441
- <ActionButton
442
- onClick={toggleReveal}
443
- disabled={isRevealing}
444
- label={
445
- revealedValue !== null
446
- ? `Hide ${variable.key}`
447
- : `Reveal ${variable.key}`
448
- }
449
- variant="muted"
442
+ /* Secret reveal is creator-only (can_read_secrets) at every
443
+ visibility level — org sharing never widens it. Hide the
444
+ affordance for everyone else instead of offering a button
445
+ that is guaranteed to fail (error prevention). */
446
+ <PermissionGate
447
+ resource={{ kind: "environment", id: environmentId }}
448
+ relation="can_read_secrets"
450
449
  >
451
- {isRevealing ? (
452
- <SpinnerIcon />
453
- ) : revealedValue !== null ? (
454
- <EyeOffIcon />
455
- ) : (
456
- <EyeIcon />
457
- )}
458
- </ActionButton>
450
+ <ActionButton
451
+ onClick={toggleReveal}
452
+ disabled={isRevealing}
453
+ label={
454
+ revealedValue !== null
455
+ ? `Hide ${variable.key}`
456
+ : `Reveal ${variable.key}`
457
+ }
458
+ variant="muted"
459
+ >
460
+ {isRevealing ? (
461
+ <SpinnerIcon />
462
+ ) : revealedValue !== null ? (
463
+ <EyeOffIcon />
464
+ ) : (
465
+ <EyeIcon />
466
+ )}
467
+ </ActionButton>
468
+ </PermissionGate>
459
469
  )}
460
470
  <ActionButton
461
471
  onClick={startEdit}
@@ -0,0 +1,35 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { create } from "@bufbuild/protobuf";
3
+ import { EnvironmentSchema } from "@stigmer/protos/ai/stigmer/agentic/environment/v1/api_pb";
4
+ import { isShareRestrictedEnvironment } from "../shareRestriction";
5
+
6
+ function env(labels: Record<string, string>) {
7
+ return create(EnvironmentSchema, {
8
+ metadata: { id: "env_1", org: "acme", labels },
9
+ });
10
+ }
11
+
12
+ describe("isShareRestrictedEnvironment", () => {
13
+ it("restricts personal environments", () => {
14
+ expect(
15
+ isShareRestrictedEnvironment(env({ "stigmer.ai/personal": "true" })),
16
+ ).toBe(true);
17
+ });
18
+
19
+ it("restricts OAuth-managed environments", () => {
20
+ expect(
21
+ isShareRestrictedEnvironment(env({ "stigmer.ai/managed": "true" })),
22
+ ).toBe(true);
23
+ });
24
+
25
+ it("does not restrict ordinary environments", () => {
26
+ expect(isShareRestrictedEnvironment(env({}))).toBe(false);
27
+ expect(isShareRestrictedEnvironment(env({ team: "payments" }))).toBe(false);
28
+ });
29
+
30
+ it("only the literal 'true' value restricts", () => {
31
+ expect(
32
+ isShareRestrictedEnvironment(env({ "stigmer.ai/personal": "false" })),
33
+ ).toBe(false);
34
+ });
35
+ });
@@ -50,3 +50,8 @@ export {
50
50
  } from "./systemEnvVars.js";
51
51
  export { EnvironmentPicker } from "./EnvironmentPicker.js";
52
52
  export type { EnvironmentPickerProps } from "./EnvironmentPicker.js";
53
+ export {
54
+ PERSONAL_ENV_LABEL,
55
+ MANAGED_ENV_LABEL,
56
+ isShareRestrictedEnvironment,
57
+ } from "./shareRestriction.js";
@@ -0,0 +1,22 @@
1
+ import type { Environment } from "@stigmer/protos/ai/stigmer/agentic/environment/v1/api_pb";
2
+
3
+ /** Label marking a user's personal credential-fallback environment. */
4
+ export const PERSONAL_ENV_LABEL = "stigmer.ai/personal";
5
+
6
+ /** Label marking a system-managed environment holding per-user OAuth tokens. */
7
+ export const MANAGED_ENV_LABEL = "stigmer.ai/managed";
8
+
9
+ /**
10
+ * Whether an environment is share-restricted — personal and OAuth-managed
11
+ * environments must never carry org visibility, so surfaces hide the
12
+ * sharing control for them entirely (error prevention: the backend
13
+ * rejects the transition with FAILED_PRECONDITION in both editions).
14
+ */
15
+ export function isShareRestrictedEnvironment(
16
+ environment: Environment,
17
+ ): boolean {
18
+ const labels = environment.metadata?.labels ?? {};
19
+ return (
20
+ labels[PERSONAL_ENV_LABEL] === "true" || labels[MANAGED_ENV_LABEL] === "true"
21
+ );
22
+ }
@@ -454,7 +454,7 @@ const REVIEW_BADGE: Record<FileReviewRowState, ApprovalBadgeInfo> = {
454
454
  // Status mapping
455
455
  // ---------------------------------------------------------------------------
456
456
 
457
- type ItemStatus = "running" | "waiting" | "failed" | "completed" | "pending";
457
+ type ItemStatus = "running" | "waiting" | "failed" | "completed" | "pending" | "interrupted";
458
458
 
459
459
  function mapToolCallStatus(toolCall: ToolCall): ItemStatus {
460
460
  switch (toolCall.status) {
@@ -474,6 +474,12 @@ function mapToolCallStatus(toolCall: ToolCall): ItemStatus {
474
474
  case ToolCallStatus.TOOL_CALL_COMPLETED:
475
475
  case ToolCallStatus.TOOL_CALL_SKIPPED:
476
476
  return "completed";
477
+ // Platform-settled when the execution terminalized mid-call (issue #207).
478
+ // A settled, neutral state: not a spinner (nothing is running), not a
479
+ // failure (the tool never errored), not a grey pending dot (it will never
480
+ // start).
481
+ case ToolCallStatus.TOOL_CALL_INTERRUPTED:
482
+ return "interrupted";
477
483
  default:
478
484
  return "pending";
479
485
  }
@@ -485,6 +491,7 @@ const STATUS_COLOR: Record<ItemStatus, string> = {
485
491
  failed: "text-destructive",
486
492
  completed: "text-success",
487
493
  pending: "text-muted-foreground",
494
+ interrupted: "text-muted-foreground",
488
495
  };
489
496
 
490
497
  // ---------------------------------------------------------------------------
@@ -626,6 +633,7 @@ const STATUS_ICON: Record<ItemStatus, () => React.JSX.Element> = {
626
633
  failed: XCircleIcon,
627
634
  completed: CheckCircleIcon,
628
635
  pending: DotIcon,
636
+ interrupted: SlashCircleIcon,
629
637
  };
630
638
 
631
639
  function SpinnerIcon() {
@@ -671,6 +679,16 @@ function DotIcon() {
671
679
  );
672
680
  }
673
681
 
682
+ /** Slashed circle for an interrupted call — settled, neutral, visibly "cut short". */
683
+ function SlashCircleIcon() {
684
+ return (
685
+ <svg width="10" height="10" viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round">
686
+ <circle cx="6" cy="6" r="4.5" />
687
+ <path d="M2.8 9.2L9.2 2.8" />
688
+ </svg>
689
+ );
690
+ }
691
+
674
692
  function InspectIcon() {
675
693
  return (
676
694
  <svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
@@ -202,6 +202,10 @@ function deriveAggregateStatus(toolCalls: readonly ToolCall[]): AggregateStatus
202
202
  break;
203
203
  case ToolCallStatus.TOOL_CALL_COMPLETED:
204
204
  case ToolCallStatus.TOOL_CALL_SKIPPED:
205
+ // INTERRUPTED is terminal (platform-settled when the execution
206
+ // terminalized mid-call, issue #207): the chip must settle, not pin to
207
+ // "pending" forever.
208
+ case ToolCallStatus.TOOL_CALL_INTERRUPTED:
205
209
  break;
206
210
  default:
207
211
  allTerminal = false;