@stigmer/react 3.1.13 → 3.1.15

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 (139) hide show
  1. package/agent/AgentDetailView.d.ts +9 -9
  2. package/agent/AgentDetailView.d.ts.map +1 -1
  3. package/agent/AgentDetailView.js +23 -31
  4. package/agent/AgentDetailView.js.map +1 -1
  5. package/agent-instance/AgentInstanceEmptyState.d.ts +4 -1
  6. package/agent-instance/AgentInstanceEmptyState.d.ts.map +1 -1
  7. package/agent-instance/AgentInstanceEmptyState.js +12 -5
  8. package/agent-instance/AgentInstanceEmptyState.js.map +1 -1
  9. package/agent-instance/AgentInstanceList.d.ts +13 -2
  10. package/agent-instance/AgentInstanceList.d.ts.map +1 -1
  11. package/agent-instance/AgentInstanceList.js +8 -4
  12. package/agent-instance/AgentInstanceList.js.map +1 -1
  13. package/agent-instance/useAgentInstances.d.ts +10 -3
  14. package/agent-instance/useAgentInstances.d.ts.map +1 -1
  15. package/agent-instance/useAgentInstances.js +12 -4
  16. package/agent-instance/useAgentInstances.js.map +1 -1
  17. package/button/Button.d.ts +54 -0
  18. package/button/Button.d.ts.map +1 -0
  19. package/button/Button.js +42 -0
  20. package/button/Button.js.map +1 -0
  21. package/button/index.d.ts +3 -0
  22. package/button/index.d.ts.map +1 -0
  23. package/button/index.js +2 -0
  24. package/button/index.js.map +1 -0
  25. package/empty-state/EmptyState.d.ts.map +1 -1
  26. package/empty-state/EmptyState.js +8 -3
  27. package/empty-state/EmptyState.js.map +1 -1
  28. package/empty-state/types.d.ts +2 -0
  29. package/empty-state/types.d.ts.map +1 -1
  30. package/execution/index.d.ts +1 -1
  31. package/execution/index.d.ts.map +1 -1
  32. package/execution/index.js.map +1 -1
  33. package/execution/useCreateAgentExecution.d.ts +81 -9
  34. package/execution/useCreateAgentExecution.d.ts.map +1 -1
  35. package/execution/useCreateAgentExecution.js +42 -4
  36. package/execution/useCreateAgentExecution.js.map +1 -1
  37. package/index.d.ts +5 -3
  38. package/index.d.ts.map +1 -1
  39. package/index.js +4 -2
  40. package/index.js.map +1 -1
  41. package/package.json +4 -4
  42. package/session/useNewSessionFlow.d.ts +6 -3
  43. package/session/useNewSessionFlow.d.ts.map +1 -1
  44. package/session/useNewSessionFlow.js +34 -35
  45. package/session/useNewSessionFlow.js.map +1 -1
  46. package/sharing/AgentShareList.d.ts +46 -0
  47. package/sharing/AgentShareList.d.ts.map +1 -0
  48. package/sharing/AgentShareList.js +159 -0
  49. package/sharing/AgentShareList.js.map +1 -0
  50. package/sharing/ShareAgentDialog.d.ts +38 -25
  51. package/sharing/ShareAgentDialog.d.ts.map +1 -1
  52. package/sharing/ShareAgentDialog.js +131 -62
  53. package/sharing/ShareAgentDialog.js.map +1 -1
  54. package/sharing/index.d.ts +10 -8
  55. package/sharing/index.d.ts.map +1 -1
  56. package/sharing/index.js +5 -4
  57. package/sharing/index.js.map +1 -1
  58. package/sharing/useAgentShares.d.ts +48 -0
  59. package/sharing/useAgentShares.d.ts.map +1 -0
  60. package/sharing/useAgentShares.js +44 -0
  61. package/sharing/useAgentShares.js.map +1 -0
  62. package/sharing/useCanCreateAgentShare.d.ts +43 -0
  63. package/sharing/useCanCreateAgentShare.d.ts.map +1 -0
  64. package/sharing/useCanCreateAgentShare.js +44 -0
  65. package/sharing/useCanCreateAgentShare.js.map +1 -0
  66. package/sharing/useDeleteAgentShare.d.ts +42 -0
  67. package/sharing/useDeleteAgentShare.d.ts.map +1 -0
  68. package/sharing/useDeleteAgentShare.js +45 -0
  69. package/sharing/useDeleteAgentShare.js.map +1 -0
  70. package/sharing/useSaveAgentShare.d.ts +43 -18
  71. package/sharing/useSaveAgentShare.d.ts.map +1 -1
  72. package/sharing/useSaveAgentShare.js +55 -22
  73. package/sharing/useSaveAgentShare.js.map +1 -1
  74. package/src/agent/AgentDetailView.tsx +37 -43
  75. package/src/agent-instance/AgentInstanceEmptyState.tsx +24 -43
  76. package/src/agent-instance/AgentInstanceList.tsx +29 -16
  77. package/src/agent-instance/__tests__/agent-instance-hooks.test.tsx +19 -0
  78. package/src/agent-instance/useAgentInstances.ts +12 -3
  79. package/src/button/Button.tsx +104 -0
  80. package/src/button/__tests__/Button.test.tsx +82 -0
  81. package/src/button/index.ts +2 -0
  82. package/src/empty-state/EmptyState.tsx +8 -10
  83. package/src/empty-state/types.ts +2 -0
  84. package/src/execution/__tests__/useCreateAgentExecution.test.tsx +92 -0
  85. package/src/execution/index.ts +2 -0
  86. package/src/execution/useCreateAgentExecution.ts +116 -10
  87. package/src/index.ts +17 -9
  88. package/src/session/__tests__/useNewSessionFlow.test.tsx +121 -52
  89. package/src/session/useNewSessionFlow.ts +38 -37
  90. package/src/sharing/AgentShareList.tsx +502 -0
  91. package/src/sharing/ShareAgentDialog.tsx +310 -112
  92. package/src/sharing/__tests__/AgentShareList.test.tsx +388 -0
  93. package/src/sharing/__tests__/ShareAgentDialog.test.tsx +311 -312
  94. package/src/sharing/__tests__/useAgentShares.test.tsx +186 -0
  95. package/src/sharing/__tests__/useCanCreateAgentShare.test.tsx +190 -0
  96. package/src/sharing/index.ts +10 -12
  97. package/src/sharing/useAgentShares.ts +74 -0
  98. package/src/sharing/useCanCreateAgentShare.ts +74 -0
  99. package/src/sharing/useDeleteAgentShare.ts +73 -0
  100. package/src/sharing/useSaveAgentShare.ts +73 -23
  101. package/src/workflow/WorkflowDetailView.tsx +9 -0
  102. package/src/workflow/instance/WorkflowInstanceEmptyState.tsx +24 -43
  103. package/src/workflow/instance/WorkflowInstanceList.tsx +29 -16
  104. package/src/workflow/useWorkflowInstances.ts +10 -3
  105. package/styles.css +1 -1
  106. package/workflow/WorkflowDetailView.d.ts +8 -1
  107. package/workflow/WorkflowDetailView.d.ts.map +1 -1
  108. package/workflow/WorkflowDetailView.js +2 -2
  109. package/workflow/WorkflowDetailView.js.map +1 -1
  110. package/workflow/instance/WorkflowInstanceEmptyState.d.ts +4 -1
  111. package/workflow/instance/WorkflowInstanceEmptyState.d.ts.map +1 -1
  112. package/workflow/instance/WorkflowInstanceEmptyState.js +12 -5
  113. package/workflow/instance/WorkflowInstanceEmptyState.js.map +1 -1
  114. package/workflow/instance/WorkflowInstanceList.d.ts +13 -2
  115. package/workflow/instance/WorkflowInstanceList.d.ts.map +1 -1
  116. package/workflow/instance/WorkflowInstanceList.js +8 -4
  117. package/workflow/instance/WorkflowInstanceList.js.map +1 -1
  118. package/workflow/useWorkflowInstances.d.ts +8 -3
  119. package/workflow/useWorkflowInstances.d.ts.map +1 -1
  120. package/workflow/useWorkflowInstances.js +10 -4
  121. package/workflow/useWorkflowInstances.js.map +1 -1
  122. package/sharing/useAgentShare.d.ts +0 -49
  123. package/sharing/useAgentShare.d.ts.map +0 -1
  124. package/sharing/useAgentShare.js +0 -64
  125. package/sharing/useAgentShare.js.map +0 -1
  126. package/sharing/useCreateExternalShareLink.d.ts +0 -90
  127. package/sharing/useCreateExternalShareLink.d.ts.map +0 -1
  128. package/sharing/useCreateExternalShareLink.js +0 -65
  129. package/sharing/useCreateExternalShareLink.js.map +0 -1
  130. package/sharing/useShareAgent.d.ts +0 -69
  131. package/sharing/useShareAgent.d.ts.map +0 -1
  132. package/sharing/useShareAgent.js +0 -42
  133. package/sharing/useShareAgent.js.map +0 -1
  134. package/src/sharing/__tests__/useAgentShare.test.tsx +0 -210
  135. package/src/sharing/__tests__/useCreateExternalShareLink.test.tsx +0 -194
  136. package/src/sharing/__tests__/useShareAgent.test.tsx +0 -131
  137. package/src/sharing/useAgentShare.ts +0 -105
  138. package/src/sharing/useCreateExternalShareLink.tsx +0 -141
  139. package/src/sharing/useShareAgent.tsx +0 -107
@@ -0,0 +1,159 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useCallback, useState } from "react";
4
+ import { cn } from "@stigmer/theme";
5
+ import { appendLinkToken, chatPath, getUserMessage, } from "@stigmer/sdk";
6
+ import { toast } from "../feedback/toast.js";
7
+ import { Button } from "../button/Button.js";
8
+ import { EmptyState } from "../empty-state/EmptyState.js";
9
+ import { PermissionGate } from "../iam-policy/PermissionGate.js";
10
+ import { ConfirmDialog } from "../resource-detail/ConfirmDialog.js";
11
+ import { useConfirmAction } from "../resource-detail/useConfirmAction.js";
12
+ import { useCopyResource } from "../resource-detail/useCopyResource.js";
13
+ import { ShareAgentDialog } from "./ShareAgentDialog.js";
14
+ import { useAgentShares } from "./useAgentShares.js";
15
+ import { useCanCreateAgentShare } from "./useCanCreateAgentShare.js";
16
+ import { useDeleteAgentShare } from "./useDeleteAgentShare.js";
17
+ import { useRotateShareLink } from "./useRotateShareLink.js";
18
+ import { draftFromShare, sharingAudienceFromProto, useSaveAgentShare, } from "./useSaveAgentShare.js";
19
+ /**
20
+ * Management surface for an agent's {@link AgentShare} channels — the
21
+ * agent analog of {@link AgentInstanceList}, rendered in the agent
22
+ * detail view's Shares tab.
23
+ *
24
+ * Lists the viewer's active org's channels of the agent: `viewerOrg`
25
+ * scopes the `getByAgent` call server-side, so a member of several orgs
26
+ * sees exactly the current org context's channels — never a merged list
27
+ * of every org's (decision 013 amendment). Per-row actions: copy link,
28
+ * edit, pause/resume, reset link, delete. Creation goes through the same
29
+ * {@link ShareAgentDialog} and always lands in the viewer's active org;
30
+ * the create bar mirrors the server's via
31
+ * {@link useCanCreateAgentShare}, so the button never appears to a user
32
+ * whose create would be refused.
33
+ *
34
+ * Self-contained: owns its dialog, its confirmation prompts, and its
35
+ * refetch-after-mutation — hosts render it with just the agent and the
36
+ * URL builder.
37
+ *
38
+ * This is an SDK component (DD-001) — embeddable by platform builders.
39
+ */
40
+ export function AgentShareList({ agent, viewerOrg, buildShareUrl, className, }) {
41
+ const agentId = agent.metadata?.id ?? "";
42
+ // Scope the list to the org whose context the viewer is in; when the
43
+ // host passes no viewerOrg the scope falls back to the agent's own org
44
+ // (the same-org owner flow), matching where creation would land.
45
+ const { shares, isLoading, error, refetch } = useAgentShares(agentId, viewerOrg || (agent.metadata?.org ?? ""));
46
+ const { allowed: canCreate, shareOrg } = useCanCreateAgentShare(agent, viewerOrg);
47
+ const { deleteShare } = useDeleteAgentShare();
48
+ const { confirmState, confirm, handleConfirm, handleCancel } = useConfirmAction();
49
+ // One dialog instance serves both flows: editing the chosen share, or
50
+ // creating a new one in the viewer's org.
51
+ const [editor, setEditor] = useState(null);
52
+ const handleDelete = useCallback(async (share) => {
53
+ const slug = share.metadata?.slug ?? "";
54
+ const confirmed = await confirm({
55
+ title: "Delete share?",
56
+ description: `The link /chat/${share.metadata?.org}/${slug} stops working ` +
57
+ "immediately — including for visitors mid-conversation — and its " +
58
+ "configuration (origins, messages, credential bindings) is gone. " +
59
+ "To stop serving while keeping the configuration, pause it instead.",
60
+ confirmLabel: "Delete",
61
+ variant: "destructive",
62
+ });
63
+ if (!confirmed)
64
+ return;
65
+ try {
66
+ await deleteShare(share.metadata?.id ?? "");
67
+ toast.success("Share deleted");
68
+ refetch();
69
+ }
70
+ catch (err) {
71
+ toast.error(getUserMessage(err));
72
+ }
73
+ }, [confirm, deleteShare, refetch]);
74
+ if (isLoading) {
75
+ return _jsx(LoadingSkeleton, {});
76
+ }
77
+ if (error) {
78
+ return (_jsx("div", { className: "py-8 text-center text-sm text-destructive", children: "Failed to load shares" }));
79
+ }
80
+ return (_jsxs("div", { className: cn("space-y-3", className), children: [shares.length === 0 ? (_jsx(ShareEmptyState, { canCreate: canCreate, onCreateClick: () => setEditor({ mode: "create" }) })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("h3", { className: "text-sm font-medium text-foreground", children: [shares.length, " ", shares.length === 1 ? "share" : "shares"] }), canCreate && (_jsx(Button, { variant: "outline", size: "xs", icon: _jsx(PlusIcon, {}), onClick: () => setEditor({ mode: "create" }), children: "Create share" }))] }), _jsx("div", { className: "overflow-hidden rounded-lg border border-border", children: _jsxs("table", { className: "w-full text-sm", children: [_jsx("thead", { children: _jsxs("tr", { className: "border-b border-border bg-muted-subtle", children: [_jsx("th", { className: "px-4 py-2 text-left font-medium text-muted-foreground", children: "Name" }), _jsx("th", { className: "px-4 py-2 text-left font-medium text-muted-foreground", children: "Link" }), _jsx("th", { className: "px-4 py-2 text-left font-medium text-muted-foreground", children: "Audience" }), _jsx("th", { className: "px-4 py-2 text-left font-medium text-muted-foreground", children: "Status" }), _jsx("th", { className: "px-4 py-2 text-right font-medium text-muted-foreground", children: "Actions" })] }) }), _jsx("tbody", { className: "divide-y divide-border", children: shares.map((share) => (_jsx(ShareRow, { share: share, agent: agent, buildShareUrl: buildShareUrl, onEditClick: (s) => setEditor({ mode: "edit", share: s }), onDeleteClick: handleDelete, refetch: refetch }, share.metadata?.id))) })] }) })] })), editor && (_jsx(ShareAgentDialog, { open: true, onOpenChange: (open) => {
81
+ if (!open)
82
+ setEditor(null);
83
+ }, agent: agent, share: editor.mode === "edit" ? editor.share : undefined, shareOrg: shareOrg, buildShareUrl: buildShareUrl, onSharingChanged: refetch })), _jsx(ConfirmDialog, { state: confirmState, onConfirm: handleConfirm, onCancel: handleCancel })] }));
84
+ }
85
+ function ShareRow({ share, agent, buildShareUrl, onEditClick, onDeleteClick, refetch, }) {
86
+ const meta = share.metadata;
87
+ const id = meta?.id ?? "";
88
+ const org = meta?.org ?? "";
89
+ const slug = meta?.slug ?? "";
90
+ const enabled = share.spec?.enabled ?? false;
91
+ const audience = sharingAudienceFromProto(share.spec?.audience);
92
+ const isCrossOrg = org !== (agent.metadata?.org ?? "");
93
+ const { copy } = useCopyResource();
94
+ const { save, isPending } = useSaveAgentShare(agent);
95
+ const { rotateShareLink, isPending: isRotating } = useRotateShareLink(id);
96
+ // The copyable URL carries the link token on public shares (org
97
+ // audience is gated by membership, not the token). The display stays
98
+ // the bare path — the token is a secret, not an address.
99
+ const displayPath = chatPath(org, slug);
100
+ const copyUrl = (() => {
101
+ const base = buildShareUrl ? buildShareUrl(org, slug) : displayPath;
102
+ return audience === "org"
103
+ ? base
104
+ : appendLinkToken(base, share.status?.shareLinkToken ?? "");
105
+ })();
106
+ const handleCopyLink = useCallback(() => {
107
+ void copy(copyUrl, "Link");
108
+ }, [copy, copyUrl]);
109
+ // Pause/resume is a full-spec save with only `enabled` flipped —
110
+ // draftFromShare guarantees a toggle can never wipe origins, messages,
111
+ // or credential bindings (the fails-closed posture the CLI shares).
112
+ const handleToggleEnabled = useCallback(async () => {
113
+ try {
114
+ await save({ ...draftFromShare(share), enabled: !enabled }, share);
115
+ toast.success(enabled ? "Share paused" : "Share resumed");
116
+ refetch();
117
+ }
118
+ catch (err) {
119
+ toast.error(getUserMessage(err));
120
+ }
121
+ }, [save, share, enabled, refetch]);
122
+ const handleResetLink = useCallback(async () => {
123
+ try {
124
+ await rotateShareLink();
125
+ toast.success("Link reset — the old link no longer works");
126
+ refetch();
127
+ }
128
+ catch (err) {
129
+ toast.error(getUserMessage(err));
130
+ }
131
+ }, [rotateShareLink, refetch]);
132
+ return (_jsxs("tr", { className: "cursor-pointer transition-colors hover:bg-accent-hover", onClick: () => onEditClick(share), children: [_jsx("td", { className: "px-4 py-2.5", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "font-medium text-foreground", children: meta?.name || slug || "\u2014" }), isCrossOrg && (_jsx("span", { className: cn("inline-flex items-center rounded-md px-1.5 py-0.5", "text-[0.6rem] font-medium uppercase tracking-wide", "bg-muted text-muted-foreground border border-border"), title: `This share lives in ${org}; the agent lives in ${agent.metadata?.org}`, children: "Cross-org" }))] }) }), _jsx("td", { className: "px-4 py-2.5", onClick: (e) => e.stopPropagation(), children: _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx("code", { className: "max-w-56 truncate font-mono text-xs text-muted-foreground", title: displayPath, children: displayPath }), _jsx("button", { type: "button", onClick: handleCopyLink, "aria-label": `Copy link for ${meta?.name || slug}`, className: cn("rounded p-1 text-muted-foreground", "hover:bg-accent-hover hover:text-foreground", "focus:outline-none focus:ring-1 focus:ring-ring"), children: _jsx(CopyIcon, {}) })] }) }), _jsx("td", { className: "px-4 py-2.5", children: _jsx("span", { className: "text-xs text-muted-foreground", children: audience === "org" ? "Org members" : "Public" }) }), _jsx("td", { className: "px-4 py-2.5", children: _jsxs("span", { className: cn("inline-flex items-center gap-1.5 text-xs", enabled ? "text-foreground" : "text-muted-foreground"), children: [_jsx("span", { "aria-hidden": "true", className: cn("size-1.5 rounded-full", enabled ? "bg-success" : "bg-muted-foreground") }), enabled ? "Active" : "Paused"] }) }), _jsx("td", { className: "px-4 py-2.5 text-right", onClick: (e) => e.stopPropagation(), children: _jsxs("div", { className: "flex items-center justify-end gap-1", children: [_jsxs(PermissionGate, { resource: { kind: "agent_share", id }, relation: "can_edit", children: [_jsx("button", { type: "button", onClick: () => onEditClick(share), className: cn("rounded px-2 py-1 text-xs font-medium", "text-foreground hover:bg-accent-hover", "focus:outline-none focus:ring-1 focus:ring-ring"), children: "Edit" }), _jsx("button", { type: "button", onClick: () => void handleToggleEnabled(), disabled: isPending, className: cn("rounded px-2 py-1 text-xs font-medium", "text-foreground hover:bg-accent-hover", "focus:outline-none focus:ring-1 focus:ring-ring", "disabled:pointer-events-none disabled:opacity-50"), children: enabled ? "Pause" : "Resume" }), audience === "public" && (_jsx("button", { type: "button", onClick: () => void handleResetLink(), disabled: isRotating, className: cn("rounded px-2 py-1 text-xs font-medium", "text-foreground hover:bg-accent-hover", "focus:outline-none focus:ring-1 focus:ring-ring", "disabled:pointer-events-none disabled:opacity-50"), children: isRotating ? "Resetting…" : "Reset link" }))] }), _jsx(PermissionGate, { resource: { kind: "agent_share", id }, relation: "can_delete", children: _jsx("button", { type: "button", onClick: () => onDeleteClick(share), className: cn("rounded px-2 py-1 text-xs font-medium", "text-destructive hover:bg-destructive-subtle", "focus:outline-none focus:ring-1 focus:ring-ring"), children: "Delete" }) })] }) })] }));
133
+ }
134
+ // ---------------------------------------------------------------------------
135
+ // Empty state
136
+ // ---------------------------------------------------------------------------
137
+ function ShareEmptyState({ canCreate, onCreateClick, }) {
138
+ return (_jsx(EmptyState, { variant: "first-use", icon: _jsx(ShareIcon, { className: "size-10" }), title: "No shares yet", description: "A share gives this agent a hosted chat link you can send or embed — " +
139
+ "each share is its own channel with its own audience, embed origins, " +
140
+ "and tool credentials.", action: canCreate
141
+ ? { label: "Create share", onClick: onCreateClick, icon: _jsx(PlusIcon, {}) }
142
+ : undefined }));
143
+ }
144
+ // ---------------------------------------------------------------------------
145
+ // Non-happy states + icons
146
+ // ---------------------------------------------------------------------------
147
+ function LoadingSkeleton() {
148
+ return (_jsx("div", { className: "space-y-2 py-4", children: [1, 2, 3].map((i) => (_jsx("div", { className: "h-12 animate-pulse rounded-md bg-muted-faint" }, i))) }));
149
+ }
150
+ function PlusIcon() {
151
+ return (_jsx("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", "aria-hidden": "true", children: _jsx("path", { d: "M6 2v8M2 6h8", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }) }));
152
+ }
153
+ function CopyIcon() {
154
+ return (_jsxs("svg", { width: "12", height: "12", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("rect", { x: "5.5", y: "5.5", width: "8", height: "8", rx: "1.5" }), _jsx("path", { d: "M10.5 5.5v-2a1 1 0 0 0-1-1h-6a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2" })] }));
155
+ }
156
+ function ShareIcon({ className }) {
157
+ return (_jsxs("svg", { className: className, viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("circle", { cx: "4", cy: "8", r: "2" }), _jsx("circle", { cx: "12", cy: "4", r: "2" }), _jsx("circle", { cx: "12", cy: "12", r: "2" }), _jsx("path", { d: "m5.8 7.1 4.4-2.2M5.8 8.9l4.4 2.2" })] }));
158
+ }
159
+ //# sourceMappingURL=AgentShareList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AgentShareList.js","sourceRoot":"","sources":["../../src/sharing/AgentShareList.tsx"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import type { Agent } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
2
+ import type { AgentShare } from "@stigmer/protos/ai/stigmer/agentic/agentshare/v1/api_pb";
2
3
  /** Props for {@link ShareAgentDialog}. */
3
4
  export interface ShareAgentDialogProps {
4
5
  /** Whether the dialog is open. */
@@ -7,6 +8,24 @@ export interface ShareAgentDialogProps {
7
8
  readonly onOpenChange: (open: boolean) => void;
8
9
  /** The agent whose sharing is managed. */
9
10
  readonly agent: Agent;
11
+ /**
12
+ * The exact share to edit. When omitted, the dialog opens in **create
13
+ * mode**: a name/slug step creates a new share in `shareOrg`, then the
14
+ * dialog becomes its editor. The share's identity is immutable once
15
+ * created (decision 011 D2) — edit mode never renames.
16
+ */
17
+ readonly share?: AgentShare | null;
18
+ /**
19
+ * The org that owns (and pays for) a share created by this dialog.
20
+ * Defaults to the agent's own org — the owner's channel. Pass the
21
+ * viewer's org to create a **cross-org share** of another org's
22
+ * marketplace-public agent (decision 013): the share, its billing,
23
+ * its credentials, and its hosted URL all belong to this org, while
24
+ * the agent stays live in its own. Cross-org shares are
25
+ * public-audience only, so the audience selector is hidden in that
26
+ * mode. Ignored in edit mode — an existing share knows its org.
27
+ */
28
+ readonly shareOrg?: string;
10
29
  /**
11
30
  * Builds the absolute public chat URL for the shared agent. The host
12
31
  * application owns URL construction (its configured public origin may
@@ -16,19 +35,9 @@ export interface ShareAgentDialogProps {
16
35
  readonly buildShareUrl?: (org: string, slug: string) => string;
17
36
  /**
18
37
  * Called after any sharing change is persisted. Hosts typically pass
19
- * the agent data hook's `refetch`.
38
+ * the share list's `refetch`.
20
39
  */
21
40
  readonly onSharingChanged?: () => void;
22
- /**
23
- * The org that owns (and pays for) the share. Defaults to the agent's
24
- * own org — the owner's channel. Pass the viewer's org to manage a
25
- * **cross-org share** of another org's marketplace-public agent
26
- * (decision 013): the share, its billing, its credentials, and its
27
- * hosted URL all belong to this org, while the agent stays live in its
28
- * own. Cross-org shares are public-audience only, so the audience
29
- * selector is hidden in that mode.
30
- */
31
- readonly shareOrg?: string;
32
41
  /**
33
42
  * When `false`, renders as an in-flow open dialog instead of a
34
43
  * top-layer modal — no `showModal()`, no backdrop, no focus trap.
@@ -39,29 +48,33 @@ export interface ShareAgentDialogProps {
39
48
  readonly modal?: boolean;
40
49
  }
41
50
  /**
42
- * The Share dialog for an agent: toggle sharing, copy the hosted chat
43
- * link, copy an embeddable snippet, manage allowed embed origins, bind
44
- * tool credentials for visitors, customize visitor refusal messages,
45
- * and discover the PlatformClient SDK path.
51
+ * The Share dialog for one agent share: create it (name/slug step), then
52
+ * toggle serving, copy the hosted chat link, copy an embeddable snippet,
53
+ * manage allowed embed origins, bind tool credentials for visitors,
54
+ * customize visitor refusal messages, and discover the PlatformClient
55
+ * SDK path.
46
56
  *
47
57
  * Sharing is a distinct consent from marketplace visibility: visibility
48
58
  * governs who can *read* the blueprint; sharing governs who can *chat*
49
- * with the running agent — billed to the owning org. The dialog states
50
- * who pays next to the toggle so enabling sharing never surprises.
59
+ * with the running agent — billed to the org that owns the share. The
60
+ * dialog states who pays before creation and next to the toggle, so
61
+ * sharing never surprises.
51
62
  *
52
- * Sharing lives in its own **AgentShare resource** (decision 011), so
53
- * the dialog loads the agent's canonical share when it opens and every
54
- * save is an idempotent `apply` of the complete configuration — the
55
- * first enable creates the share, later edits update it, one code path
56
- * (see {@link useSaveAgentShare}). The local draft is refreshed from
57
- * every returned share, so the dialog never drifts from the server.
63
+ * Sharing lives in its own **AgentShare resource** (decision 011), and
64
+ * an agent can carry N shares each its own channel with its own URL,
65
+ * audience, origins, credentials, and link token (D3). The dialog edits
66
+ * exactly the share it is given; it never resolves "the" share of an
67
+ * agent. Every save is an idempotent `apply` of the complete
68
+ * configuration ({@link useSaveAgentShare}), and the local draft is
69
+ * refreshed from every returned share, so the dialog never drifts from
70
+ * the server.
58
71
  *
59
72
  * Built on the native `<dialog>` element for focus trapping and escape
60
73
  * handling, matching the SDK's modal convention ({@link ManageAccessDialog}).
61
74
  * All visual properties flow through `--stgm-*` design tokens.
62
75
  *
63
- * Most hosts mount it via {@link useShareAgent} (a kebab-menu action).
76
+ * Most hosts mount it via {@link AgentShareList} (the Shares tab).
64
77
  * Render it directly only when you own the open-state.
65
78
  */
66
- export declare function ShareAgentDialog({ open, onOpenChange, agent, buildShareUrl, onSharingChanged, shareOrg, modal, }: ShareAgentDialogProps): import("react/jsx-runtime").JSX.Element;
79
+ export declare function ShareAgentDialog({ open, onOpenChange, agent, share, shareOrg, buildShareUrl, onSharingChanged, modal, }: ShareAgentDialogProps): import("react/jsx-runtime").JSX.Element;
67
80
  //# sourceMappingURL=ShareAgentDialog.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ShareAgentDialog.d.ts","sourceRoot":"","sources":["../../src/sharing/ShareAgentDialog.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oDAAoD,CAAC;AAkChF,0CAA0C;AAC1C,MAAM,WAAW,qBAAqB;IACpC,kCAAkC;IAClC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,mDAAmD;IACnD,QAAQ,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C,0CAA0C;IAC1C,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC/D;;;OAGG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IACvC;;;;;;;;OAQG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,YAAY,EACZ,KAAK,EACL,aAAa,EACb,gBAAgB,EAChB,QAAQ,EACR,KAAY,GACb,EAAE,qBAAqB,2CAiDvB"}
1
+ {"version":3,"file":"ShareAgentDialog.d.ts","sourceRoot":"","sources":["../../src/sharing/ShareAgentDialog.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oDAAoD,CAAC;AAChF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yDAAyD,CAAC;AAmC1F,0CAA0C;AAC1C,MAAM,WAAW,qBAAqB;IACpC,kCAAkC;IAClC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,mDAAmD;IACnD,QAAQ,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C,0CAA0C;IAC1C,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IACnC;;;;;;;;;OASG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC/D;;;OAGG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IACvC;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,YAAY,EACZ,KAAK,EACL,KAAK,EACL,QAAQ,EACR,aAAa,EACb,gBAAgB,EAChB,KAAY,GACb,EAAE,qBAAqB,2CAkDvB"}
@@ -2,8 +2,10 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { useCallback, useMemo, useRef, useState } from "react";
4
4
  import { cn } from "@stigmer/theme";
5
- import { MAX_ALLOWED_ORIGINS, appendLinkToken, buildEmbedSnippet, chatPath, getUserMessage, validateOrigin, } from "@stigmer/sdk";
5
+ import { MAX_ALLOWED_ORIGINS, StigmerError, appendLinkToken, buildEmbedSnippet, chatPath, getUserMessage, validateOrigin, } from "@stigmer/sdk";
6
+ import { create as createMessage } from "@bufbuild/protobuf";
6
7
  import { ApiResourceVisibility } from "@stigmer/protos/ai/stigmer/commons/apiresource/enum_pb";
8
+ import { ApiResourceMetadataSchema } from "@stigmer/protos/ai/stigmer/commons/apiresource/metadata_pb";
7
9
  import { Switch } from "../switch/Switch.js";
8
10
  import { Tabs } from "../tabs/Tabs.js";
9
11
  import { toast } from "../feedback/toast.js";
@@ -12,8 +14,9 @@ import { useDeploymentMode } from "../deployment-mode.js";
12
14
  import { useBillingAccount } from "../billing/useBillingAccount.js";
13
15
  import { formatCreditBalance } from "../billing/format.js";
14
16
  import { EnvironmentPicker } from "../environment/EnvironmentPicker.js";
15
- import { useAgentShare } from "./useAgentShare.js";
16
- import { sharingAudienceFromProto, useSaveAgentShare, } from "./useSaveAgentShare.js";
17
+ import { generateSlug } from "../internal/slug.js";
18
+ import { getFieldError, validateMessage } from "../internal/validate.js";
19
+ import { draftFromShare, useSaveAgentShare, } from "./useSaveAgentShare.js";
17
20
  import { useRotateShareLink } from "./useRotateShareLink.js";
18
21
  import { useShareToolReadiness } from "./useShareToolReadiness.js";
19
22
  /** Maximum length of each visitor message (proto: `string.max_len = 300`). */
@@ -25,31 +28,35 @@ const SHARE_TABS = [
25
28
  ];
26
29
  const PLATFORM_CLIENT_DOCS_URL = "https://docs.stigmer.ai/guides/authentication/platform-client/overview";
27
30
  /**
28
- * The Share dialog for an agent: toggle sharing, copy the hosted chat
29
- * link, copy an embeddable snippet, manage allowed embed origins, bind
30
- * tool credentials for visitors, customize visitor refusal messages,
31
- * and discover the PlatformClient SDK path.
31
+ * The Share dialog for one agent share: create it (name/slug step), then
32
+ * toggle serving, copy the hosted chat link, copy an embeddable snippet,
33
+ * manage allowed embed origins, bind tool credentials for visitors,
34
+ * customize visitor refusal messages, and discover the PlatformClient
35
+ * SDK path.
32
36
  *
33
37
  * Sharing is a distinct consent from marketplace visibility: visibility
34
38
  * governs who can *read* the blueprint; sharing governs who can *chat*
35
- * with the running agent — billed to the owning org. The dialog states
36
- * who pays next to the toggle so enabling sharing never surprises.
39
+ * with the running agent — billed to the org that owns the share. The
40
+ * dialog states who pays before creation and next to the toggle, so
41
+ * sharing never surprises.
37
42
  *
38
- * Sharing lives in its own **AgentShare resource** (decision 011), so
39
- * the dialog loads the agent's canonical share when it opens and every
40
- * save is an idempotent `apply` of the complete configuration — the
41
- * first enable creates the share, later edits update it, one code path
42
- * (see {@link useSaveAgentShare}). The local draft is refreshed from
43
- * every returned share, so the dialog never drifts from the server.
43
+ * Sharing lives in its own **AgentShare resource** (decision 011), and
44
+ * an agent can carry N shares each its own channel with its own URL,
45
+ * audience, origins, credentials, and link token (D3). The dialog edits
46
+ * exactly the share it is given; it never resolves "the" share of an
47
+ * agent. Every save is an idempotent `apply` of the complete
48
+ * configuration ({@link useSaveAgentShare}), and the local draft is
49
+ * refreshed from every returned share, so the dialog never drifts from
50
+ * the server.
44
51
  *
45
52
  * Built on the native `<dialog>` element for focus trapping and escape
46
53
  * handling, matching the SDK's modal convention ({@link ManageAccessDialog}).
47
54
  * All visual properties flow through `--stgm-*` design tokens.
48
55
  *
49
- * Most hosts mount it via {@link useShareAgent} (a kebab-menu action).
56
+ * Most hosts mount it via {@link AgentShareList} (the Shares tab).
50
57
  * Render it directly only when you own the open-state.
51
58
  */
52
- export function ShareAgentDialog({ open, onOpenChange, agent, buildShareUrl, onSharingChanged, shareOrg, modal = true, }) {
59
+ export function ShareAgentDialog({ open, onOpenChange, agent, share, shareOrg, buildShareUrl, onSharingChanged, modal = true, }) {
53
60
  const dialogRef = useRef(null);
54
61
  const handleClose = useCallback(() => {
55
62
  dialogRef.current?.close();
@@ -72,68 +79,130 @@ export function ShareAgentDialog({ open, onOpenChange, agent, buildShareUrl, onS
72
79
  dialogRef.current.close();
73
80
  }
74
81
  }
75
- return (_jsx("dialog", { ref: dialogRef, open: modal ? undefined : open, onClose: handleClose, className: cn("w-full max-w-lg rounded-xl border border-border bg-popover p-0 shadow-xl", modal ? "fixed inset-0 m-auto backdrop:bg-black/50" : "relative"), "aria-labelledby": "share-agent-title", children: open && (_jsx(ShareAgentDialogBody, { agent: agent, buildShareUrl: buildShareUrl, onSharingChanged: onSharingChanged, shareOrg: shareOrg, onClose: handleClose })) }));
82
+ return (_jsx("dialog", { ref: dialogRef, open: modal ? undefined : open, onClose: handleClose, className: cn("w-full max-w-lg rounded-xl border border-border bg-popover p-0 shadow-xl", modal ? "fixed inset-0 m-auto backdrop:bg-black/50" : "relative"), "aria-labelledby": "share-agent-title", children: open && (_jsx(ShareAgentDialogBody, { agent: agent, share: share ?? null, shareOrg: shareOrg, buildShareUrl: buildShareUrl, onSharingChanged: onSharingChanged, onClose: handleClose })) }));
76
83
  }
77
84
  // ---------------------------------------------------------------------------
78
- // Dialog body — resolves the canonical share, then hands off to the form
85
+ // Dialog body — create step or editor, depending on the share it was given
79
86
  // ---------------------------------------------------------------------------
80
87
  /**
81
- * Loads the agent's canonical share and mounts the form once resolved.
82
- * The split keeps the form's draft seeding synchronous (`useState`
83
- * initializer from the loaded share)no hydrate-on-effect, no window
84
- * where the switch shows a state the server never had.
88
+ * Renders the create step (no share yet) or the editor (share in hand).
89
+ * A share persisted by the create step is adopted locally, so one dialog
90
+ * session flows create edit without remounting and the editor's
91
+ * draft seeding stays synchronous (`useState` initializer from the
92
+ * share): no hydrate-on-effect, no window where the switch shows a state
93
+ * the server never had.
85
94
  */
86
- function ShareAgentDialogBody({ agent, buildShareUrl, onSharingChanged, shareOrg, onClose, }) {
87
- const { share, isLoading, error, refetch } = useAgentShare(agent, shareOrg);
88
- const isCrossOrg = !!shareOrg && shareOrg !== (agent.metadata?.org ?? "");
89
- return (_jsxs("div", { className: "flex flex-col", children: [_jsxs("div", { className: "flex items-start justify-between border-b border-border px-6 py-4", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("h2", { id: "share-agent-title", className: "text-base font-semibold text-foreground", children: "Share" }), _jsx("p", { className: "mt-0.5 truncate text-xs text-muted-foreground", children: isCrossOrg
95
+ function ShareAgentDialogBody({ agent, share, shareOrg, buildShareUrl, onSharingChanged, onClose, }) {
96
+ const [created, setCreated] = useState(null);
97
+ const activeShare = share ?? created;
98
+ const isCreating = activeShare === null;
99
+ const resolvedShareOrg = activeShare?.metadata?.org || shareOrg || (agent.metadata?.org ?? "");
100
+ const isCrossOrg = resolvedShareOrg !== (agent.metadata?.org ?? "");
101
+ return (_jsxs("div", { className: "flex flex-col", children: [_jsxs("div", { className: "flex items-start justify-between border-b border-border px-6 py-4", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("h2", { id: "share-agent-title", className: "text-base font-semibold text-foreground", children: isCreating ? "Create share" : "Share" }), _jsx("p", { className: "mt-0.5 truncate text-xs text-muted-foreground", children: isCrossOrg
90
102
  ? `${agent.metadata?.org}/${agent.metadata?.slug}`
91
- : agent.metadata?.name || agent.metadata?.slug })] }), _jsx("button", { type: "button", onClick: onClose, "aria-label": "Close", className: cn("rounded-md p-1 text-muted-foreground", "hover:text-foreground hover:bg-accent-hover", "focus:outline-none focus:ring-2 focus:ring-ring"), children: _jsx(CloseIcon, {}) })] }), isLoading ? (_jsxs("div", { className: "px-6 py-10 text-center", "aria-busy": "true", "aria-label": "Loading sharing settings", children: [_jsx("div", { className: "mx-auto h-4 w-2/3 animate-pulse rounded bg-muted" }), _jsx("div", { className: "mx-auto mt-2 h-3 w-1/2 animate-pulse rounded bg-muted" })] })) : error ? (_jsxs("div", { className: "px-6 py-8 text-center", role: "alert", children: [_jsx("p", { className: "text-sm text-foreground", children: "Couldn't load this agent's sharing settings." }), _jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: getUserMessage(error) }), _jsx("button", { type: "button", onClick: refetch, className: cn("mt-3 rounded-md px-3 py-1.5 text-xs font-medium", "border border-border text-foreground hover:bg-accent-hover", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"), children: "Try again" })] })) : (_jsx(ShareAgentForm, { agent: agent, initialShare: share, buildShareUrl: buildShareUrl, onSharingChanged: onSharingChanged, shareOrg: shareOrg })), _jsx("div", { className: "flex items-center justify-end border-t border-border px-6 py-3", children: _jsx("button", { type: "button", onClick: onClose, className: cn("rounded-md px-3 py-1.5 text-sm font-medium", "bg-primary text-primary-foreground hover:bg-primary-hover", "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2"), children: "Done" }) })] }));
103
+ : agent.metadata?.name || agent.metadata?.slug })] }), _jsx("button", { type: "button", onClick: onClose, "aria-label": "Close", className: cn("rounded-md p-1 text-muted-foreground", "hover:text-foreground hover:bg-accent-hover", "focus:outline-none focus:ring-2 focus:ring-ring"), children: _jsx(CloseIcon, {}) })] }), isCreating ? (_jsx(CreateShareForm, { agent: agent, shareOrg: resolvedShareOrg, onCreated: (persisted) => {
104
+ setCreated(persisted);
105
+ onSharingChanged?.();
106
+ } })) : (_jsx(ShareAgentForm, { agent: agent, initialShare: activeShare, buildShareUrl: buildShareUrl, onSharingChanged: onSharingChanged })), _jsx("div", { className: "flex items-center justify-end border-t border-border px-6 py-3", children: _jsx("button", { type: "button", onClick: onClose, className: cn("rounded-md px-3 py-1.5 text-sm font-medium", isCreating
107
+ ? "border border-border text-foreground hover:bg-accent-hover"
108
+ : "bg-primary text-primary-foreground hover:bg-primary-hover", "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2"), children: isCreating ? "Cancel" : "Done" }) })] }));
92
109
  }
93
110
  // ---------------------------------------------------------------------------
94
- // Formowns the share draft for the session
111
+ // Create step — the new share's identity and cost, before any channel exists
95
112
  // ---------------------------------------------------------------------------
96
113
  /**
97
- * The dialog's editable projection of a share. `null` (never shared)
98
- * seeds the same defaults the server would apply on first create, so
99
- * the form needs no "no share yet" special case beyond the disabled
100
- * copy fields that `enabled: false` already produces.
114
+ * Names the new share and creates it live (`enabled: true`, public
115
+ * audience the server's own defaults). Identity is set here because it
116
+ * is immutable afterward (decision 011 D2): the slug becomes the hosted
117
+ * URL `/chat/<org>/<slug>` in the sharing org's namespace.
118
+ *
119
+ * The slug auto-derives from the name until the user edits it (the
120
+ * {@link CreateOrganizationForm} pattern), validated by the same
121
+ * protovalidate rules the server enforces. An `(org, slug)` collision —
122
+ * the server's ALREADY_EXISTS — surfaces inline on the slug field with a
123
+ * pick-another-slug remedy instead of a generic failure toast.
101
124
  */
102
- function draftFromShare(share) {
103
- const spec = share?.spec;
104
- return {
105
- enabled: spec?.enabled ?? false,
106
- audience: sharingAudienceFromProto(spec?.audience),
107
- allowedOrigins: spec?.allowedOrigins ?? [],
108
- messages: {
109
- rateLimited: spec?.messages?.rateLimited ?? "",
110
- unavailable: spec?.messages?.unavailable ?? "",
111
- conversationEnded: spec?.messages?.conversationEnded ?? "",
112
- },
113
- environmentRefs: (spec?.environmentRefs ?? []).map((ref) => ({
114
- org: ref.org,
115
- slug: ref.slug,
116
- })),
117
- };
125
+ function CreateShareForm({ agent, shareOrg, onCreated, }) {
126
+ const agentName = agent.metadata?.name || (agent.metadata?.slug ?? "");
127
+ const isCrossOrg = shareOrg !== (agent.metadata?.org ?? "");
128
+ const [name, setName] = useState(agentName);
129
+ const [slug, setSlug] = useState(agent.metadata?.slug ?? "");
130
+ // Once the user manually edits the slug field, stop auto-deriving.
131
+ const slugTouchedRef = useRef(false);
132
+ // A server-side (org, slug) collision pins to the slug field until the
133
+ // slug changes — the remedy is picking another slug.
134
+ const [collisionError, setCollisionError] = useState(null);
135
+ const [submitError, setSubmitError] = useState(null);
136
+ const { save, isPending } = useSaveAgentShare(agent, shareOrg);
137
+ const trimmedName = name.trim();
138
+ const violations = slug.length > 0 || trimmedName.length > 0
139
+ ? validateMessage(ApiResourceMetadataSchema, createMessage(ApiResourceMetadataSchema, {
140
+ ...(slug.length > 0 && { slug }),
141
+ ...(trimmedName.length > 0 && { name: trimmedName }),
142
+ }))
143
+ : [];
144
+ const slugError = collisionError ?? (slug.length > 0 ? getFieldError(violations, "slug") : null);
145
+ const nameError = trimmedName.length > 0 ? getFieldError(violations, "name") : null;
146
+ const canSubmit = trimmedName !== "" && slug.length > 0 && slugError === null &&
147
+ nameError === null && !isPending;
148
+ const handleNameChange = useCallback((value) => {
149
+ setName(value);
150
+ if (!slugTouchedRef.current) {
151
+ setSlug(generateSlug(value.trim()));
152
+ setCollisionError(null);
153
+ }
154
+ }, []);
155
+ const handleSlugChange = useCallback((value) => {
156
+ slugTouchedRef.current = true;
157
+ setSlug(value);
158
+ setCollisionError(null);
159
+ }, []);
160
+ const handleSubmit = useCallback(async (e) => {
161
+ e.preventDefault();
162
+ if (!canSubmit)
163
+ return;
164
+ setSubmitError(null);
165
+ try {
166
+ const persisted = await save(
167
+ // The server's create defaults, made explicit: live from the
168
+ // start (the user's one intent-click is "share it"), public
169
+ // audience, nothing else configured yet.
170
+ { ...draftFromShare(null), enabled: true }, null, { name: trimmedName, slug });
171
+ if (persisted) {
172
+ toast.success("Share created — the link is live");
173
+ onCreated(persisted);
174
+ }
175
+ }
176
+ catch (err) {
177
+ if (err instanceof StigmerError && err.code === "already-exists") {
178
+ setCollisionError(`"${slug}" is already used by another share or resource in ${shareOrg} — pick a different slug`);
179
+ }
180
+ else {
181
+ // e.g. the cross-org FAILED_PRECONDITION naming non-public
182
+ // dependencies (decision 013 D5) — show the server's words.
183
+ setSubmitError(getUserMessage(err));
184
+ }
185
+ }
186
+ }, [canSubmit, save, trimmedName, slug, shareOrg, onCreated]);
187
+ return (_jsxs("form", { onSubmit: handleSubmit, className: "flex flex-col gap-4 px-6 py-4", children: [_jsxs("p", { className: "text-xs text-muted-foreground", children: ["A share is its own channel to this agent: a hosted chat link with its own audience, embed origins, tool credentials, and visitor messages.", " ", isCrossOrg && (_jsxs(_Fragment, { children: ["This one lives in your organization", " ", _jsx("span", { className: "font-medium", children: shareOrg }), " while the agent stays in ", _jsx("span", { className: "font-medium", children: agent.metadata?.org }), " ", "\u2014 updates to the agent apply live.", " "] })), "Visitors chat on ", _jsx("span", { className: "font-medium", children: shareOrg }), "'s credits."] }), _jsxs("div", { className: "space-y-1", children: [_jsx("label", { htmlFor: "stgm-new-share-name", className: "text-xs font-medium text-foreground", children: "Name" }), _jsx("input", { id: "stgm-new-share-name", type: "text", value: name, onChange: (e) => handleNameChange(e.target.value), disabled: isPending, required: true, maxLength: 63, className: cn("w-full rounded-md border bg-input-bg px-2.5 py-1.5 text-xs text-foreground", "placeholder:text-muted-foreground", "focus:outline-none focus:ring-2 focus:ring-ring", "disabled:pointer-events-none disabled:opacity-50", nameError ? "border-destructive" : "border-border") }), nameError ? (_jsx("p", { className: "text-[0.65rem] text-destructive", role: "alert", children: nameError })) : (_jsx("p", { className: "text-[0.65rem] text-muted-foreground", children: "A display name for this share \u2014 e.g. the site or campaign it serves." }))] }), _jsxs("div", { className: "space-y-1", children: [_jsx("label", { htmlFor: "stgm-new-share-slug", className: "text-xs font-medium text-foreground", children: "Slug" }), _jsx("input", { id: "stgm-new-share-slug", type: "text", value: slug, onChange: (e) => handleSlugChange(e.target.value), disabled: isPending, required: true, className: cn("w-full rounded-md border bg-input-bg px-2.5 py-1.5 font-mono text-xs text-foreground", "placeholder:text-muted-foreground", "focus:outline-none focus:ring-2 focus:ring-ring", "disabled:pointer-events-none disabled:opacity-50", slugError ? "border-destructive" : "border-border") }), slugError ? (_jsx("p", { className: "text-[0.65rem] text-destructive", role: "alert", children: slugError })) : (_jsxs("p", { className: "text-[0.65rem] text-muted-foreground", children: ["Becomes the share's address:", " ", _jsxs("code", { className: "font-mono", children: ["/chat/", shareOrg, "/", slug || "…"] }), ". Can't be changed later."] }))] }), submitError && (_jsx("p", { className: "text-xs text-destructive", role: "alert", children: submitError })), _jsx("div", { className: "flex items-center justify-end", children: _jsx("button", { type: "submit", disabled: !canSubmit, className: cn("rounded-md px-3 py-1.5 text-sm font-medium", "bg-primary text-primary-foreground hover:bg-primary-hover", "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", "disabled:pointer-events-none disabled:opacity-50"), children: isPending ? "Creating…" : "Create share" }) })] }));
118
188
  }
119
- function ShareAgentForm({ agent, initialShare, buildShareUrl, onSharingChanged, shareOrg, }) {
189
+ // ---------------------------------------------------------------------------
190
+ // Form — owns the share draft for the session
191
+ // ---------------------------------------------------------------------------
192
+ function ShareAgentForm({ agent, initialShare, buildShareUrl, onSharingChanged, }) {
120
193
  const agentName = agent.metadata?.name || (agent.metadata?.slug ?? "");
121
194
  // The latest server share is the single baseline: the draft, the link
122
- // token, and the share id for rotation all derive from it. `null`
123
- // until the first save creates the share.
195
+ // token, and the share id for rotation all derive from it.
124
196
  const [share, setShare] = useState(initialShare);
125
197
  const [draft, setDraft] = useState(() => draftFromShare(initialShare));
126
198
  const [activeTab, setActiveTab] = useState("link");
127
- const { save, isPending } = useSaveAgentShare(agent, shareOrg);
128
- const { rotateShareLink, isPending: isRotating } = useRotateShareLink(share?.metadata?.id ?? null);
129
- // The share's own org/slug form the hosted URL. Before the first save
130
- // the sharing org + the agent's slug stand in — exactly the identity
131
- // the server will assign on create (D2: share slug defaults to the
132
- // agent's; the org is the channel owner's, which for a cross-org share
133
- // is the viewer's org, not the agent's — decision 013).
134
- const org = share?.metadata?.org || shareOrg || (agent.metadata?.org ?? "");
135
- const slug = share?.metadata?.slug || (agent.metadata?.slug ?? "");
136
- const linkToken = share?.status?.shareLinkToken ?? "";
199
+ const { save, isPending } = useSaveAgentShare(agent);
200
+ const { rotateShareLink, isPending: isRotating } = useRotateShareLink(share.metadata?.id ?? null);
201
+ // The share's own org/slug are the hosted URL for a cross-org share
202
+ // (decision 013) that org is the sharing org's, not the agent's.
203
+ const org = share.metadata?.org ?? "";
204
+ const slug = share.metadata?.slug ?? "";
205
+ const linkToken = share.status?.shareLinkToken ?? "";
137
206
  // Cross-org shares are public-audience only (decision 013 D3) — the
138
207
  // audience selector disappears rather than offering a choice the
139
208
  // server would refuse.