@stigmer/react 0.0.39 → 0.0.41

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 (104) hide show
  1. package/agent/AgentDetailView.d.ts +14 -3
  2. package/agent/AgentDetailView.d.ts.map +1 -1
  3. package/agent/AgentDetailView.js +8 -7
  4. package/agent/AgentDetailView.js.map +1 -1
  5. package/agent/agentSetupReducer.d.ts +1 -0
  6. package/agent/agentSetupReducer.d.ts.map +1 -1
  7. package/agent/agentSetupReducer.js +11 -0
  8. package/agent/agentSetupReducer.js.map +1 -1
  9. package/agent/useAgentSetup.d.ts.map +1 -1
  10. package/agent/useAgentSetup.js +41 -6
  11. package/agent/useAgentSetup.js.map +1 -1
  12. package/api-key/ApiKeyCreatedAlert.d.ts +33 -0
  13. package/api-key/ApiKeyCreatedAlert.d.ts.map +1 -0
  14. package/api-key/ApiKeyCreatedAlert.js +61 -0
  15. package/api-key/ApiKeyCreatedAlert.js.map +1 -0
  16. package/api-key/ApiKeyListPanel.d.ts +30 -0
  17. package/api-key/ApiKeyListPanel.d.ts.map +1 -0
  18. package/api-key/ApiKeyListPanel.js +126 -0
  19. package/api-key/ApiKeyListPanel.js.map +1 -0
  20. package/api-key/CreateApiKeyForm.d.ts +35 -0
  21. package/api-key/CreateApiKeyForm.d.ts.map +1 -0
  22. package/api-key/CreateApiKeyForm.js +81 -0
  23. package/api-key/CreateApiKeyForm.js.map +1 -0
  24. package/api-key/index.d.ts +13 -0
  25. package/api-key/index.d.ts.map +1 -0
  26. package/api-key/index.js +7 -0
  27. package/api-key/index.js.map +1 -0
  28. package/api-key/useApiKeyList.d.ts +28 -0
  29. package/api-key/useApiKeyList.d.ts.map +1 -0
  30. package/api-key/useApiKeyList.js +52 -0
  31. package/api-key/useApiKeyList.js.map +1 -0
  32. package/api-key/useCreateApiKey.d.ts +40 -0
  33. package/api-key/useCreateApiKey.d.ts.map +1 -0
  34. package/api-key/useCreateApiKey.js +56 -0
  35. package/api-key/useCreateApiKey.js.map +1 -0
  36. package/api-key/useDeleteApiKey.d.ts +26 -0
  37. package/api-key/useDeleteApiKey.d.ts.map +1 -0
  38. package/api-key/useDeleteApiKey.js +43 -0
  39. package/api-key/useDeleteApiKey.js.map +1 -0
  40. package/composer/SessionComposer.d.ts.map +1 -1
  41. package/composer/SessionComposer.js +12 -0
  42. package/composer/SessionComposer.js.map +1 -1
  43. package/index.d.ts +5 -3
  44. package/index.d.ts.map +1 -1
  45. package/index.js +5 -3
  46. package/index.js.map +1 -1
  47. package/library/VisibilityToggle.d.ts +41 -0
  48. package/library/VisibilityToggle.d.ts.map +1 -0
  49. package/library/VisibilityToggle.js +80 -0
  50. package/library/VisibilityToggle.js.map +1 -0
  51. package/library/index.d.ts +4 -0
  52. package/library/index.d.ts.map +1 -1
  53. package/library/index.js +2 -0
  54. package/library/index.js.map +1 -1
  55. package/library/useUpdateVisibility.d.ts +40 -0
  56. package/library/useUpdateVisibility.d.ts.map +1 -0
  57. package/library/useUpdateVisibility.js +67 -0
  58. package/library/useUpdateVisibility.js.map +1 -0
  59. package/mcp-server/McpServerDetailView.d.ts +12 -1
  60. package/mcp-server/McpServerDetailView.d.ts.map +1 -1
  61. package/mcp-server/McpServerDetailView.js +6 -5
  62. package/mcp-server/McpServerDetailView.js.map +1 -1
  63. package/package.json +4 -4
  64. package/search/useResourceCount.d.ts +2 -2
  65. package/search/useResourceCount.js +2 -2
  66. package/search/useResourceCount.js.map +1 -1
  67. package/search/useResourceList.d.ts +8 -3
  68. package/search/useResourceList.d.ts.map +1 -1
  69. package/search/useResourceList.js +2 -2
  70. package/search/useResourceList.js.map +1 -1
  71. package/session/index.d.ts +1 -0
  72. package/session/index.d.ts.map +1 -1
  73. package/session/index.js +2 -0
  74. package/session/index.js.map +1 -1
  75. package/session/useCreateSession.d.ts +1 -1
  76. package/session/useCreateSession.d.ts.map +1 -1
  77. package/session/useCreateSession.js +2 -1
  78. package/session/useCreateSession.js.map +1 -1
  79. package/skill/SkillDetailView.d.ts +12 -1
  80. package/skill/SkillDetailView.d.ts.map +1 -1
  81. package/skill/SkillDetailView.js +6 -5
  82. package/skill/SkillDetailView.js.map +1 -1
  83. package/src/agent/AgentDetailView.tsx +34 -8
  84. package/src/agent/agentSetupReducer.ts +12 -0
  85. package/src/agent/useAgentSetup.ts +69 -19
  86. package/src/api-key/ApiKeyCreatedAlert.tsx +184 -0
  87. package/src/api-key/ApiKeyListPanel.tsx +359 -0
  88. package/src/api-key/CreateApiKeyForm.tsx +250 -0
  89. package/src/api-key/index.ts +12 -0
  90. package/src/api-key/useApiKeyList.ts +68 -0
  91. package/src/api-key/useCreateApiKey.ts +71 -0
  92. package/src/api-key/useDeleteApiKey.ts +57 -0
  93. package/src/composer/SessionComposer.tsx +13 -0
  94. package/src/index.ts +26 -1
  95. package/src/library/VisibilityToggle.tsx +205 -0
  96. package/src/library/index.ts +9 -0
  97. package/src/library/useUpdateVisibility.ts +94 -0
  98. package/src/mcp-server/McpServerDetailView.tsx +32 -6
  99. package/src/search/useResourceCount.ts +4 -4
  100. package/src/search/useResourceList.ts +10 -5
  101. package/src/session/index.ts +3 -0
  102. package/src/session/useCreateSession.ts +6 -5
  103. package/src/skill/SkillDetailView.tsx +32 -6
  104. package/styles.css +1 -1
@@ -0,0 +1,250 @@
1
+ "use client";
2
+
3
+ import { useCallback, useState, type FormEvent } from "react";
4
+ import { cn } from "@stigmer/theme";
5
+ import { getUserMessage } from "@stigmer/sdk";
6
+ import type { ApiKey } from "@stigmer/protos/ai/stigmer/iam/apikey/v1/api_pb";
7
+ import { useCreateApiKey } from "./useCreateApiKey";
8
+
9
+ // ---------------------------------------------------------------------------
10
+ // Public API
11
+ // ---------------------------------------------------------------------------
12
+
13
+ export interface CreateApiKeyFormProps {
14
+ /** Organization slug used as the `org` field when creating the key. */
15
+ readonly org: string;
16
+ /**
17
+ * Fired with the newly created API key after successful creation.
18
+ * The `spec.keyHash` field of the returned key contains the raw
19
+ * key value — available only at this moment.
20
+ */
21
+ readonly onCreated?: (apiKey: ApiKey) => void;
22
+ /** Fired when the user cancels creation. */
23
+ readonly onCancel?: () => void;
24
+ readonly className?: string;
25
+ }
26
+
27
+ type ExpiryOption = "30" | "60" | "90" | "never";
28
+
29
+ /**
30
+ * Compact form for creating a new API key.
31
+ *
32
+ * Collects a **name** (required) and an **expiry** choice (30 / 60 /
33
+ * 90 days or never), then creates the key via {@link useCreateApiKey}.
34
+ * On success it fires `onCreated` with the full {@link ApiKey}
35
+ * response, which includes the raw key in `spec.keyHash`.
36
+ *
37
+ * All visual properties flow through `--stgm-*` design tokens.
38
+ *
39
+ * @example
40
+ * ```tsx
41
+ * <CreateApiKeyForm
42
+ * org="acme"
43
+ * onCreated={(key) => setRevealedKey(key)}
44
+ * onCancel={() => setShowForm(false)}
45
+ * />
46
+ * ```
47
+ */
48
+ export function CreateApiKeyForm({
49
+ org,
50
+ onCreated,
51
+ onCancel,
52
+ className,
53
+ }: CreateApiKeyFormProps) {
54
+ const { create, isCreating, error, clearError } = useCreateApiKey();
55
+
56
+ const [name, setName] = useState("");
57
+ const [expiry, setExpiry] = useState<ExpiryOption>("never");
58
+
59
+ const trimmedName = name.trim();
60
+ const canSubmit = trimmedName !== "" && !isCreating;
61
+
62
+ const handleSubmit = useCallback(
63
+ async (e: FormEvent) => {
64
+ e.preventDefault();
65
+ if (!canSubmit) return;
66
+
67
+ clearError();
68
+ try {
69
+ const apiKey = await create({
70
+ name: trimmedName,
71
+ org,
72
+ ...(expiry === "never"
73
+ ? { neverExpires: true }
74
+ : { expiresAt: daysFromNow(Number(expiry)) }),
75
+ });
76
+ onCreated?.(apiKey);
77
+ } catch {
78
+ // error state is managed by useCreateApiKey
79
+ }
80
+ },
81
+ [canSubmit, trimmedName, org, expiry, create, clearError, onCreated],
82
+ );
83
+
84
+ return (
85
+ <form onSubmit={handleSubmit} className={cn("space-y-3", className)}>
86
+ <div className="space-y-3">
87
+ {/* Name */}
88
+ <div className="space-y-1">
89
+ <label
90
+ htmlFor="stgm-new-apikey-name"
91
+ className="text-xs font-medium text-foreground"
92
+ >
93
+ Name
94
+ </label>
95
+ <input
96
+ id="stgm-new-apikey-name"
97
+ type="text"
98
+ value={name}
99
+ onChange={(e) => setName(e.target.value)}
100
+ placeholder="e.g. ci-deploy-key"
101
+ disabled={isCreating}
102
+ autoFocus
103
+ required
104
+ className={cn(
105
+ "w-full rounded-md border border-input bg-background px-2.5 py-1.5 text-xs text-foreground",
106
+ "placeholder:text-muted-foreground",
107
+ "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
108
+ "disabled:pointer-events-none disabled:opacity-50",
109
+ )}
110
+ />
111
+ </div>
112
+
113
+ {/* Expiry */}
114
+ <fieldset className="space-y-1.5">
115
+ <legend className="text-xs font-medium text-foreground">
116
+ Expiration
117
+ </legend>
118
+ <div className="flex flex-wrap gap-2">
119
+ {EXPIRY_OPTIONS.map(({ value, label }) => (
120
+ <ExpiryRadio
121
+ key={value}
122
+ value={value}
123
+ label={label}
124
+ checked={expiry === value}
125
+ disabled={isCreating}
126
+ onChange={setExpiry}
127
+ />
128
+ ))}
129
+ </div>
130
+ </fieldset>
131
+ </div>
132
+
133
+ {error && (
134
+ <p className="text-destructive text-[0.65rem]" role="alert">
135
+ {getUserMessage(error)}
136
+ </p>
137
+ )}
138
+
139
+ <div className="flex items-center gap-2">
140
+ <button
141
+ type="submit"
142
+ disabled={!canSubmit}
143
+ className={cn(
144
+ "inline-flex items-center gap-1.5 rounded-md px-3 py-1.5 text-xs font-medium",
145
+ "bg-primary text-primary-foreground hover:bg-primary/90",
146
+ "disabled:pointer-events-none disabled:opacity-40",
147
+ )}
148
+ >
149
+ {isCreating && <SpinnerIcon />}
150
+ Create API key
151
+ </button>
152
+
153
+ {onCancel && (
154
+ <button
155
+ type="button"
156
+ onClick={onCancel}
157
+ disabled={isCreating}
158
+ className={cn(
159
+ "rounded-md px-3 py-1.5 text-xs",
160
+ "text-muted-foreground hover:text-foreground hover:bg-accent/50",
161
+ "disabled:pointer-events-none disabled:opacity-50",
162
+ )}
163
+ >
164
+ Cancel
165
+ </button>
166
+ )}
167
+ </div>
168
+ </form>
169
+ );
170
+ }
171
+
172
+ // ---------------------------------------------------------------------------
173
+ // Expiry helpers
174
+ // ---------------------------------------------------------------------------
175
+
176
+ const EXPIRY_OPTIONS: { value: ExpiryOption; label: string }[] = [
177
+ { value: "30", label: "30 days" },
178
+ { value: "60", label: "60 days" },
179
+ { value: "90", label: "90 days" },
180
+ { value: "never", label: "Never" },
181
+ ];
182
+
183
+ function daysFromNow(days: number): Date {
184
+ const date = new Date();
185
+ date.setDate(date.getDate() + days);
186
+ return date;
187
+ }
188
+
189
+ // ---------------------------------------------------------------------------
190
+ // ExpiryRadio (internal)
191
+ // ---------------------------------------------------------------------------
192
+
193
+ function ExpiryRadio({
194
+ value,
195
+ label,
196
+ checked,
197
+ disabled,
198
+ onChange,
199
+ }: {
200
+ value: ExpiryOption;
201
+ label: string;
202
+ checked: boolean;
203
+ disabled: boolean;
204
+ onChange: (v: ExpiryOption) => void;
205
+ }) {
206
+ return (
207
+ <label
208
+ className={cn(
209
+ "inline-flex cursor-pointer items-center rounded-md border px-2.5 py-1 text-xs transition-colors",
210
+ checked
211
+ ? "border-primary bg-primary-subtle text-primary font-medium"
212
+ : "border-input bg-background text-muted-foreground hover:border-border hover:text-foreground",
213
+ disabled && "pointer-events-none opacity-50",
214
+ )}
215
+ >
216
+ <input
217
+ type="radio"
218
+ name="stgm-apikey-expiry"
219
+ value={value}
220
+ checked={checked}
221
+ disabled={disabled}
222
+ onChange={() => onChange(value)}
223
+ className="sr-only"
224
+ />
225
+ {label}
226
+ </label>
227
+ );
228
+ }
229
+
230
+ // ---------------------------------------------------------------------------
231
+ // Icons
232
+ // ---------------------------------------------------------------------------
233
+
234
+ function SpinnerIcon() {
235
+ return (
236
+ <svg
237
+ width="12"
238
+ height="12"
239
+ viewBox="0 0 16 16"
240
+ fill="none"
241
+ stroke="currentColor"
242
+ strokeWidth="2"
243
+ strokeLinecap="round"
244
+ className="animate-spin"
245
+ aria-hidden="true"
246
+ >
247
+ <path d="M8 2a6 6 0 1 0 6 6" />
248
+ </svg>
249
+ );
250
+ }
@@ -0,0 +1,12 @@
1
+ export { useApiKeyList } from "./useApiKeyList";
2
+ export type { UseApiKeyListReturn } from "./useApiKeyList";
3
+ export { useCreateApiKey } from "./useCreateApiKey";
4
+ export type { UseCreateApiKeyReturn } from "./useCreateApiKey";
5
+ export { useDeleteApiKey } from "./useDeleteApiKey";
6
+ export type { UseDeleteApiKeyReturn } from "./useDeleteApiKey";
7
+ export { ApiKeyListPanel } from "./ApiKeyListPanel";
8
+ export type { ApiKeyListPanelProps } from "./ApiKeyListPanel";
9
+ export { CreateApiKeyForm } from "./CreateApiKeyForm";
10
+ export type { CreateApiKeyFormProps } from "./CreateApiKeyForm";
11
+ export { ApiKeyCreatedAlert } from "./ApiKeyCreatedAlert";
12
+ export type { ApiKeyCreatedAlertProps } from "./ApiKeyCreatedAlert";
@@ -0,0 +1,68 @@
1
+ "use client";
2
+
3
+ import { useCallback, useEffect, useState } from "react";
4
+ import type { ApiKey } from "@stigmer/protos/ai/stigmer/iam/apikey/v1/api_pb";
5
+ import { useStigmer } from "../hooks";
6
+ import { toError } from "../internal/toError";
7
+
8
+ export interface UseApiKeyListReturn {
9
+ readonly apiKeys: readonly ApiKey[];
10
+ readonly isLoading: boolean;
11
+ readonly error: Error | null;
12
+ readonly refetch: () => void;
13
+ }
14
+
15
+ /**
16
+ * Data hook that fetches all {@link ApiKey} entries for the
17
+ * authenticated identity.
18
+ *
19
+ * API keys are identity-scoped — the server returns every key owned
20
+ * by the identity in the auth header, regardless of organization.
21
+ * Call `refetch()` to re-query after mutations (create / delete).
22
+ *
23
+ * The raw key value is never returned by `findAll` — only the
24
+ * `fingerprint` (last 6 characters) is available for display.
25
+ *
26
+ * @example
27
+ * ```tsx
28
+ * const { apiKeys, isLoading, error, refetch } = useApiKeyList();
29
+ *
30
+ * if (isLoading) return <Spinner />;
31
+ * apiKeys.map((k) => k.metadata?.name);
32
+ * ```
33
+ */
34
+ export function useApiKeyList(): UseApiKeyListReturn {
35
+ const stigmer = useStigmer();
36
+ const [apiKeys, setApiKeys] = useState<ApiKey[]>([]);
37
+ const [isLoading, setIsLoading] = useState(true);
38
+ const [error, setError] = useState<Error | null>(null);
39
+ const [fetchKey, setFetchKey] = useState(0);
40
+
41
+ const refetch = useCallback(() => setFetchKey((k) => k + 1), []);
42
+
43
+ useEffect(() => {
44
+ const cancelled = { current: false };
45
+
46
+ setIsLoading(true);
47
+ setError(null);
48
+
49
+ stigmer.apiKey.findAll().then(
50
+ (result) => {
51
+ if (cancelled.current) return;
52
+ setApiKeys([...result.entries]);
53
+ setIsLoading(false);
54
+ },
55
+ (err) => {
56
+ if (cancelled.current) return;
57
+ setError(toError(err));
58
+ setIsLoading(false);
59
+ },
60
+ );
61
+
62
+ return () => {
63
+ cancelled.current = true;
64
+ };
65
+ }, [stigmer, fetchKey]);
66
+
67
+ return { apiKeys, isLoading, error, refetch };
68
+ }
@@ -0,0 +1,71 @@
1
+ "use client";
2
+
3
+ import { useCallback, useState } from "react";
4
+ import type { ApiKeyInput } from "@stigmer/sdk";
5
+ import type { ApiKey } from "@stigmer/protos/ai/stigmer/iam/apikey/v1/api_pb";
6
+ import { useStigmer } from "../hooks";
7
+ import { toError } from "../internal/toError";
8
+
9
+ export interface UseCreateApiKeyReturn {
10
+ readonly create: (input: ApiKeyInput) => Promise<ApiKey>;
11
+ readonly isCreating: boolean;
12
+ readonly error: Error | null;
13
+ readonly clearError: () => void;
14
+ }
15
+
16
+ /**
17
+ * Behavior hook that wraps `apiKey.create()` with loading and error
18
+ * state.
19
+ *
20
+ * Creates an API key resource. The caller provides an
21
+ * {@link ApiKeyInput} with `name`, `org`, and optionally `expiresAt`
22
+ * or `neverExpires`.
23
+ *
24
+ * **Critical**: The returned {@link ApiKey} is the *only* time the
25
+ * raw key value is available — it is returned in `spec.keyHash` of
26
+ * the create response. After creation the server stores only the
27
+ * hash; subsequent queries return an empty `keyHash` and only the
28
+ * `fingerprint` (last 6 characters) for display.
29
+ *
30
+ * Callers must capture the raw key from the resolved promise and
31
+ * present it to the user immediately (e.g. via
32
+ * {@link ApiKeyCreatedAlert}).
33
+ *
34
+ * @example
35
+ * ```tsx
36
+ * const { create, isCreating, error } = useCreateApiKey();
37
+ *
38
+ * const apiKey = await create({
39
+ * name: "ci-deploy-key",
40
+ * org: "acme",
41
+ * neverExpires: true,
42
+ * });
43
+ * // apiKey.spec?.keyHash contains the raw key — show it once
44
+ * ```
45
+ */
46
+ export function useCreateApiKey(): UseCreateApiKeyReturn {
47
+ const stigmer = useStigmer();
48
+ const [isCreating, setIsCreating] = useState(false);
49
+ const [error, setError] = useState<Error | null>(null);
50
+
51
+ const clearError = useCallback(() => setError(null), []);
52
+
53
+ const create = useCallback(
54
+ async (input: ApiKeyInput): Promise<ApiKey> => {
55
+ setIsCreating(true);
56
+ setError(null);
57
+
58
+ try {
59
+ return await stigmer.apiKey.create(input);
60
+ } catch (err) {
61
+ setError(toError(err));
62
+ throw err;
63
+ } finally {
64
+ setIsCreating(false);
65
+ }
66
+ },
67
+ [stigmer],
68
+ );
69
+
70
+ return { create, isCreating, error, clearError };
71
+ }
@@ -0,0 +1,57 @@
1
+ "use client";
2
+
3
+ import { useCallback, useState } from "react";
4
+ import type { ApiKey } from "@stigmer/protos/ai/stigmer/iam/apikey/v1/api_pb";
5
+ import { useStigmer } from "../hooks";
6
+ import { toError } from "../internal/toError";
7
+
8
+ export interface UseDeleteApiKeyReturn {
9
+ readonly deleteKey: (id: string) => Promise<ApiKey>;
10
+ readonly isDeleting: boolean;
11
+ readonly error: Error | null;
12
+ readonly clearError: () => void;
13
+ }
14
+
15
+ /**
16
+ * Behavior hook that wraps `apiKey.delete()` with loading and error
17
+ * state.
18
+ *
19
+ * Deletes an API key by its resource ID. Returns the deleted
20
+ * {@link ApiKey} on success so callers can confirm which key was
21
+ * removed. The deletion is permanent — the key can no longer be
22
+ * used for authentication.
23
+ *
24
+ * @example
25
+ * ```tsx
26
+ * const { deleteKey, isDeleting, error } = useDeleteApiKey();
27
+ *
28
+ * await deleteKey("key-id-abc123");
29
+ * refetch(); // refresh the list after deletion
30
+ * ```
31
+ */
32
+ export function useDeleteApiKey(): UseDeleteApiKeyReturn {
33
+ const stigmer = useStigmer();
34
+ const [isDeleting, setIsDeleting] = useState(false);
35
+ const [error, setError] = useState<Error | null>(null);
36
+
37
+ const clearError = useCallback(() => setError(null), []);
38
+
39
+ const deleteKey = useCallback(
40
+ async (id: string): Promise<ApiKey> => {
41
+ setIsDeleting(true);
42
+ setError(null);
43
+
44
+ try {
45
+ return await stigmer.apiKey.delete(id);
46
+ } catch (err) {
47
+ setError(toError(err));
48
+ throw err;
49
+ } finally {
50
+ setIsDeleting(false);
51
+ }
52
+ },
53
+ [stigmer],
54
+ );
55
+
56
+ return { deleteKey, isDeleting, error, clearError };
57
+ }
@@ -400,6 +400,19 @@ export function SessionComposer({
400
400
  pool.availableKeys,
401
401
  );
402
402
 
403
+ // ---------------------------------------------------------------------------
404
+ // Pool-resolve notification — when POOL_RESOLVE transitions agentSetup to
405
+ // "ready" reactively (via the useEffect inside useAgentSetup), the
406
+ // imperative callbacks (handleAgentSelect, handleEnvSubmit) are not
407
+ // involved, so onAgentResolutionChange would never fire. This effect
408
+ // bridges that gap so the parent always knows the current resolution.
409
+ // ---------------------------------------------------------------------------
410
+
411
+ useEffect(() => {
412
+ if (agentSetup.state.status !== "ready") return;
413
+ onAgentResolutionChange?.(agentSetup.state.resolution);
414
+ }, [agentSetup.state, onAgentResolutionChange]);
415
+
403
416
  // ---------------------------------------------------------------------------
404
417
  // Attachments — file upload state machine
405
418
  // ---------------------------------------------------------------------------
package/src/index.ts CHANGED
@@ -49,6 +49,8 @@ export {
49
49
  useSessionConversation,
50
50
  useAgentRefFromSession,
51
51
  groupSessionsByTime,
52
+ PENDING_SUBJECT,
53
+ resolvedSubject,
52
54
  } from "./session";
53
55
  export type {
54
56
  CreateSessionInput,
@@ -323,11 +325,29 @@ export type {
323
325
  CreateOrganizationFormProps,
324
326
  } from "./organization";
325
327
 
328
+ // API Key — data hooks, behavior hooks, and styled components for API key lifecycle
329
+ export {
330
+ useApiKeyList,
331
+ useCreateApiKey,
332
+ useDeleteApiKey,
333
+ ApiKeyListPanel,
334
+ CreateApiKeyForm,
335
+ ApiKeyCreatedAlert,
336
+ } from "./api-key";
337
+ export type {
338
+ UseApiKeyListReturn,
339
+ UseCreateApiKeyReturn,
340
+ UseDeleteApiKeyReturn,
341
+ ApiKeyListPanelProps,
342
+ CreateApiKeyFormProps,
343
+ ApiKeyCreatedAlertProps,
344
+ } from "./api-key";
345
+
326
346
  // Error — structured error display with classification, retry, and contextual guidance
327
347
  export { ErrorMessage, SecretFlowErrorGuide, isSecretFlowError } from "./error";
328
348
  export type { ErrorMessageProps, SecretFlowErrorGuideProps } from "./error";
329
349
 
330
- // Library — cross-resource UI components, resource detection, apply flow, and browsing
350
+ // Library — cross-resource UI components, resource detection, apply flow, browsing, and visibility management
331
351
  export {
332
352
  ScopeToggle,
333
353
  ResourceListView,
@@ -341,6 +361,8 @@ export {
341
361
  serializeAgentYaml,
342
362
  serializeMcpServerYaml,
343
363
  useApplyResource,
364
+ VisibilityToggle,
365
+ useUpdateVisibility,
344
366
  } from "./library";
345
367
  export type {
346
368
  ScopeToggleProps,
@@ -355,6 +377,9 @@ export type {
355
377
  UseApplyResourceReturn,
356
378
  ApplyResourceResult,
357
379
  PushSkillParams,
380
+ VisibilityToggleProps,
381
+ VisibilityResourceKind,
382
+ UseUpdateVisibilityReturn,
358
383
  } from "./library";
359
384
 
360
385
  // Agent Instance — data hooks, list hook, personal convenience hook, and behavior hook