@stigmer/react 3.1.12 → 3.1.14

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 (63) hide show
  1. package/agent/AgentDetailView.d.ts +11 -3
  2. package/agent/AgentDetailView.d.ts.map +1 -1
  3. package/agent/AgentDetailView.js +22 -17
  4. package/agent/AgentDetailView.js.map +1 -1
  5. package/index.d.ts +2 -2
  6. package/index.d.ts.map +1 -1
  7. package/index.js +2 -2
  8. package/index.js.map +1 -1
  9. package/package.json +4 -4
  10. package/sharing/AgentShareList.d.ts +44 -0
  11. package/sharing/AgentShareList.d.ts.map +1 -0
  12. package/sharing/AgentShareList.js +149 -0
  13. package/sharing/AgentShareList.js.map +1 -0
  14. package/sharing/ShareAgentDialog.d.ts +38 -15
  15. package/sharing/ShareAgentDialog.d.ts.map +1 -1
  16. package/sharing/ShareAgentDialog.js +135 -57
  17. package/sharing/ShareAgentDialog.js.map +1 -1
  18. package/sharing/index.d.ts +10 -6
  19. package/sharing/index.d.ts.map +1 -1
  20. package/sharing/index.js +5 -3
  21. package/sharing/index.js.map +1 -1
  22. package/sharing/useAgentShares.d.ts +42 -0
  23. package/sharing/useAgentShares.d.ts.map +1 -0
  24. package/sharing/useAgentShares.js +38 -0
  25. package/sharing/useAgentShares.js.map +1 -0
  26. package/sharing/useCanCreateAgentShare.d.ts +43 -0
  27. package/sharing/useCanCreateAgentShare.d.ts.map +1 -0
  28. package/sharing/useCanCreateAgentShare.js +44 -0
  29. package/sharing/useCanCreateAgentShare.js.map +1 -0
  30. package/sharing/useDeleteAgentShare.d.ts +42 -0
  31. package/sharing/useDeleteAgentShare.d.ts.map +1 -0
  32. package/sharing/useDeleteAgentShare.js +45 -0
  33. package/sharing/useDeleteAgentShare.js.map +1 -0
  34. package/sharing/useSaveAgentShare.d.ts +45 -14
  35. package/sharing/useSaveAgentShare.d.ts.map +1 -1
  36. package/sharing/useSaveAgentShare.js +59 -19
  37. package/sharing/useSaveAgentShare.js.map +1 -1
  38. package/src/agent/AgentDetailView.tsx +37 -20
  39. package/src/index.ts +11 -6
  40. package/src/sharing/AgentShareList.tsx +507 -0
  41. package/src/sharing/ShareAgentDialog.tsx +325 -95
  42. package/src/sharing/__tests__/AgentShareList.test.tsx +388 -0
  43. package/src/sharing/__tests__/ShareAgentDialog.test.tsx +333 -286
  44. package/src/sharing/__tests__/{useAgentShare.test.tsx → useAgentShares.test.tsx} +47 -51
  45. package/src/sharing/__tests__/useCanCreateAgentShare.test.tsx +190 -0
  46. package/src/sharing/__tests__/useSaveAgentShare.test.tsx +48 -0
  47. package/src/sharing/index.ts +10 -7
  48. package/src/sharing/useAgentShares.ts +68 -0
  49. package/src/sharing/useCanCreateAgentShare.ts +74 -0
  50. package/src/sharing/useDeleteAgentShare.ts +73 -0
  51. package/src/sharing/useSaveAgentShare.ts +77 -19
  52. package/styles.css +1 -1
  53. package/sharing/useAgentShare.d.ts +0 -43
  54. package/sharing/useAgentShare.d.ts.map +0 -1
  55. package/sharing/useAgentShare.js +0 -54
  56. package/sharing/useAgentShare.js.map +0 -1
  57. package/sharing/useShareAgent.d.ts +0 -69
  58. package/sharing/useShareAgent.d.ts.map +0 -1
  59. package/sharing/useShareAgent.js +0 -42
  60. package/sharing/useShareAgent.js.map +0 -1
  61. package/src/sharing/__tests__/useShareAgent.test.tsx +0 -131
  62. package/src/sharing/useAgentShare.ts +0 -91
  63. package/src/sharing/useShareAgent.tsx +0 -107
@@ -76,6 +76,48 @@ function sharingAudienceToProto(audience: SharingAudience): AgentShareAudience {
76
76
  : AgentShareAudience.public;
77
77
  }
78
78
 
79
+ /**
80
+ * Projects a share into the editable {@link AgentShareDraft} — the
81
+ * single constructor for the full-spec drafts every save requires.
82
+ * `null` (no share yet) seeds the same defaults the server would apply
83
+ * on first create.
84
+ *
85
+ * Shared by the Share dialog (draft seeding) and the share list's
86
+ * pause/resume toggle, so a toggle rebuilds the complete spec with only
87
+ * `enabled` flipped and can never wipe origins, messages, or credential
88
+ * bindings — the fails-closed posture {@link AgentShareDraft} exists to
89
+ * enforce.
90
+ */
91
+ export function draftFromShare(share: AgentShare | null): AgentShareDraft {
92
+ const spec = share?.spec;
93
+ return {
94
+ enabled: spec?.enabled ?? false,
95
+ audience: sharingAudienceFromProto(spec?.audience),
96
+ allowedOrigins: spec?.allowedOrigins ?? [],
97
+ messages: {
98
+ rateLimited: spec?.messages?.rateLimited ?? "",
99
+ unavailable: spec?.messages?.unavailable ?? "",
100
+ conversationEnded: spec?.messages?.conversationEnded ?? "",
101
+ },
102
+ environmentRefs: (spec?.environmentRefs ?? []).map((ref) => ({
103
+ org: ref.org,
104
+ slug: ref.slug,
105
+ })),
106
+ };
107
+ }
108
+
109
+ /**
110
+ * Identity for a share being created: its display name and URL slug in
111
+ * the sharing org's namespace. Only consulted when `current` is `null`
112
+ * — an existing share's identity is immutable (decision 011 D2).
113
+ */
114
+ export interface AgentShareCreateIdentity {
115
+ /** Display name for the new share. */
116
+ readonly name: string;
117
+ /** URL slug for the new share — appears in `/chat/<org>/<slug>`. */
118
+ readonly slug: string;
119
+ }
120
+
79
121
  /** Return value of {@link useSaveAgentShare}. */
80
122
  export interface UseSaveAgentShareReturn {
81
123
  /**
@@ -83,12 +125,14 @@ export interface UseSaveAgentShareReturn {
83
125
  * persisted {@link AgentShare} — adopt it as the new baseline (its
84
126
  * `status.shareLinkToken` carries the live link token).
85
127
  *
86
- * `current` is the share being edited, or `null` when the agent has
87
- * never been shared the save then creates the canonical share.
128
+ * `current` is the share being edited, or `null` to create one
129
+ * named by `createIdentity` when given, else the server's defaults
130
+ * (the agent's own name and slug).
88
131
  */
89
132
  readonly save: (
90
133
  draft: AgentShareDraft,
91
134
  current: AgentShare | null,
135
+ createIdentity?: AgentShareCreateIdentity,
92
136
  ) => Promise<AgentShare | undefined>;
93
137
  /** `true` while the RPC is in flight. */
94
138
  readonly isPending: boolean;
@@ -97,35 +141,42 @@ export interface UseSaveAgentShareReturn {
97
141
  }
98
142
 
99
143
  /**
100
- * Behavior hook that persists an agent's canonical share configuration.
144
+ * Behavior hook that persists an agent share's configuration.
101
145
  *
102
146
  * Commits via `stigmer.agentShare.apply()` — an idempotent upsert keyed
103
147
  * on the share's `(org, slug)` identity — so one code path serves both
104
- * the first enable (creates the share; the server authorizes on the
105
- * referenced agent's `can_edit`) and every later edit. There is
106
- * deliberately no create/update branching: the share slug is unique per
107
- * org and defaults to the agent's slug, which makes apply-by-identity
108
- * exact, and the generated `AgentShareInput` carries no `metadata.id`
109
- * for an update to route by anyway.
148
+ * creation (the server authorizes on the referenced agent's `can_edit`)
149
+ * and every later edit. There is deliberately no create/update
150
+ * branching: the share slug is unique per org, which makes
151
+ * apply-by-identity exact, and the generated `AgentShareInput` carries
152
+ * no `metadata.id` for an update to route by anyway. A create that
153
+ * collides on `(org, slug)` rejects with an already-exists error rather
154
+ * than touching the existing share.
110
155
  *
111
156
  * Disabling is a save with `enabled: false` — a config-preserving pause
112
157
  * (decision 011 D1). Deleting the share is a separate, destructive
113
- * operation this hook does not perform.
158
+ * operation ({@link useDeleteAgentShare}).
159
+ *
160
+ * `shareOrg` selects which org owns a created share and defaults to the
161
+ * agent's own org. Pass the viewer's org to create a **cross-org
162
+ * share** (decision 013) — the server then authorizes on the public
163
+ * agent's `can_execute` plus `can_create_agent_share` in the sharing
164
+ * org, and bills that org.
114
165
  *
115
166
  * Pass `null` for `agent` to produce a stable no-op (useful while the
116
167
  * agent is still loading).
117
168
  *
118
169
  * @example
119
170
  * ```tsx
120
- * const { share } = useAgentShare(agent);
121
171
  * const { save, isPending } = useSaveAgentShare(agent);
122
172
  *
123
- * const persisted = await save({ ...draft, enabled: true }, share);
173
+ * const persisted = await save({ ...draftFromShare(share), enabled: true }, share);
124
174
  * // persisted.status.shareLinkToken is the live link token
125
175
  * ```
126
176
  */
127
177
  export function useSaveAgentShare(
128
178
  agent: Agent | null,
179
+ shareOrg?: string,
129
180
  ): UseSaveAgentShareReturn {
130
181
  const stigmer = useStigmer();
131
182
  const [isPending, setIsPending] = useState(false);
@@ -134,11 +185,13 @@ export function useSaveAgentShare(
134
185
  const agentOrg = agent?.metadata?.org ?? "";
135
186
  const agentSlug = agent?.metadata?.slug ?? "";
136
187
  const agentName = agent?.metadata?.name ?? "";
188
+ const resolvedShareOrg = shareOrg || agentOrg;
137
189
 
138
190
  const save = useCallback(
139
191
  async (
140
192
  draft: AgentShareDraft,
141
193
  current: AgentShare | null,
194
+ createIdentity?: AgentShareCreateIdentity,
142
195
  ): Promise<AgentShare | undefined> => {
143
196
  if (!agentOrg || !agentSlug) return undefined;
144
197
 
@@ -148,13 +201,18 @@ export function useSaveAgentShare(
148
201
  try {
149
202
  return await stigmer.agentShare.apply({
150
203
  // Identity: the existing share's org/slug when editing (a
151
- // manifest-created share may carry a non-default slug — apply
152
- // with the agent's slug would create a SECOND share), the
153
- // agent's when creating (the server's own D2 default, made
204
+ // share may carry a non-default slug — apply with the agent's
205
+ // slug would create a SECOND share); when creating, the
206
+ // sharing org + the caller-chosen identity, falling back to
207
+ // the agent's own slug/name (the server's D2 default, made
154
208
  // explicit).
155
- org: current?.metadata?.org || agentOrg,
156
- slug: current?.metadata?.slug || agentSlug,
157
- name: current?.metadata?.name || agentName || agentSlug,
209
+ org: current?.metadata?.org || resolvedShareOrg,
210
+ slug: current?.metadata?.slug || createIdentity?.slug || agentSlug,
211
+ name:
212
+ current?.metadata?.name ||
213
+ createIdentity?.name ||
214
+ agentName ||
215
+ agentSlug,
158
216
  agentRef: { org: agentOrg, slug: agentSlug },
159
217
  enabled: draft.enabled,
160
218
  // Written as the explicit enum value, never left unspecified —
@@ -179,7 +237,7 @@ export function useSaveAgentShare(
179
237
  setIsPending(false);
180
238
  }
181
239
  },
182
- [agentOrg, agentSlug, agentName, stigmer],
240
+ [agentOrg, agentSlug, agentName, resolvedShareOrg, stigmer],
183
241
  );
184
242
 
185
243
  return { save, isPending, error };