@rafads/plugin-onepassword 1.5.38

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.
package/README.md ADDED
@@ -0,0 +1,79 @@
1
+ # @rafads/plugin-onepassword
2
+
3
+ [1Password](https://1password.com) integration for the executor. Provides a secret source that resolves values from a 1Password vault, backed by either the desktop app (connect.sock) or a service account token.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ bun add @rafads/sdk @rafads/plugin-onepassword
9
+ # or
10
+ npm install @rafads/sdk @rafads/plugin-onepassword
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```ts
16
+ import { createExecutor } from "@rafads/sdk";
17
+ import { onepasswordPlugin } from "@rafads/plugin-onepassword";
18
+
19
+ const executor = await createExecutor({
20
+ onElicitation: "accept-all",
21
+ plugins: [onepasswordPlugin()] as const,
22
+ });
23
+
24
+ // Point the plugin at your account
25
+ await executor.onepassword.configure({
26
+ auth: { kind: "desktop-app", accountName: "my-account" },
27
+ vaultId: "my-vault-id",
28
+ name: "Personal",
29
+ });
30
+
31
+ // Inspect connection / list vaults
32
+ const status = await executor.onepassword.status();
33
+ const vaults = await executor.onepassword.listVaults({
34
+ kind: "desktop-app",
35
+ accountName: "my-account",
36
+ });
37
+ ```
38
+
39
+ For CI and headless environments, use a service-account token instead of the desktop app. Store the token through the executor's secret store first, then reference it by id:
40
+
41
+ ```ts
42
+ import { createExecutor } from "@rafads/sdk";
43
+ import { onepasswordPlugin } from "@rafads/plugin-onepassword";
44
+ import { fileSecretsPlugin } from "@rafads/plugin-file-secrets";
45
+
46
+ const executor = await createExecutor({
47
+ onElicitation: "accept-all",
48
+ plugins: [fileSecretsPlugin(), onepasswordPlugin()] as const,
49
+ });
50
+
51
+ await executor.secrets.set({
52
+ id: "op-token",
53
+ name: "1Password service account",
54
+ value: process.env.OP_SERVICE_ACCOUNT_TOKEN!,
55
+ scope: executor.scopes[0]!.id,
56
+ });
57
+
58
+ await executor.onepassword.configure({
59
+ auth: { kind: "service-account", tokenSecretId: "op-token" },
60
+ vaultId: "my-vault-id",
61
+ name: "CI",
62
+ });
63
+ ```
64
+
65
+ ## Using with Effect
66
+
67
+ If you're building on `@rafads/sdk/core` (the raw Effect entry), import this plugin from its `/core` subpath instead — it returns the Effect-shaped plugin with `Effect.Effect<...>`-returning methods rather than promisified wrappers:
68
+
69
+ ```ts
70
+ import { onepasswordPlugin } from "@rafads/plugin-onepassword/core";
71
+ ```
72
+
73
+ ## Status
74
+
75
+ Pre-`1.0`. APIs may still change between beta releases. Part of the [executor monorepo](https://github.com/UsefulSoftwareCo/executor).
76
+
77
+ ## License
78
+
79
+ MIT
@@ -0,0 +1,401 @@
1
+ import {
2
+ ConnectionStatus,
3
+ OnePasswordConfig,
4
+ OnePasswordError,
5
+ RedactedOnePasswordConfig,
6
+ Vault
7
+ } from "./chunk-OYHEG6OK.js";
8
+
9
+ // src/react/OnePasswordSettings.tsx
10
+ import { useState } from "react";
11
+ import { useAtomSet, useAtomValue } from "@effect/atom-react";
12
+ import * as Exit from "effect/Exit";
13
+ import * as AsyncResult from "effect/unstable/reactivity/AsyncResult";
14
+ import { Button } from "@rafads/react/components/button";
15
+ import { Input } from "@rafads/react/components/input";
16
+ import { Label } from "@rafads/react/components/label";
17
+ import {
18
+ Select,
19
+ SelectContent,
20
+ SelectItem,
21
+ SelectTrigger,
22
+ SelectValue
23
+ } from "@rafads/react/components/select";
24
+ import {
25
+ Dialog,
26
+ DialogContent,
27
+ DialogHeader,
28
+ DialogTitle,
29
+ DialogDescription,
30
+ DialogFooter,
31
+ DialogClose
32
+ } from "@rafads/react/components/dialog";
33
+ import {
34
+ CardStackEntry,
35
+ CardStackEntryActions,
36
+ CardStackEntryContent,
37
+ CardStackEntryDescription
38
+ } from "@rafads/react/components/card-stack";
39
+
40
+ // src/react/atoms.ts
41
+ import { ReactivityKey } from "@rafads/react/api/reactivity-keys";
42
+
43
+ // src/react/client.ts
44
+ import { createPluginAtomClient } from "@rafads/sdk/client";
45
+ import {
46
+ getExecutorOrganizationHeaders,
47
+ getExecutorApiBaseUrl,
48
+ getExecutorServerAuthorizationHeader
49
+ } from "@rafads/react/api/server-connection";
50
+
51
+ // src/api/group.ts
52
+ import { HttpApiEndpoint, HttpApiGroup } from "effect/unstable/httpapi";
53
+ import { Schema } from "effect";
54
+ import { InternalError } from "@rafads/sdk/shared";
55
+ var ConfigurePayload = OnePasswordConfig;
56
+ var ListVaultsParams = Schema.Struct({
57
+ authKind: Schema.Literals(["desktop-app", "service-account"]),
58
+ account: Schema.String
59
+ });
60
+ var ListVaultsResponse = Schema.Struct({
61
+ vaults: Schema.Array(Vault)
62
+ });
63
+ var GetConfigResponse = Schema.NullOr(RedactedOnePasswordConfig);
64
+ var OnePasswordGroup = HttpApiGroup.make("onepassword").add(
65
+ HttpApiEndpoint.get("getConfig", "/onepassword/config", {
66
+ success: GetConfigResponse,
67
+ error: [InternalError, OnePasswordError]
68
+ })
69
+ ).add(
70
+ HttpApiEndpoint.put("configure", "/onepassword/config", {
71
+ payload: ConfigurePayload,
72
+ success: Schema.Void,
73
+ error: [InternalError, OnePasswordError]
74
+ })
75
+ ).add(
76
+ HttpApiEndpoint.delete("removeConfig", "/onepassword/config", {
77
+ success: Schema.Void,
78
+ error: [InternalError, OnePasswordError]
79
+ })
80
+ ).add(
81
+ HttpApiEndpoint.get("status", "/onepassword/status", {
82
+ success: ConnectionStatus,
83
+ error: [InternalError, OnePasswordError]
84
+ })
85
+ ).add(
86
+ HttpApiEndpoint.get("listVaults", "/onepassword/vaults", {
87
+ query: ListVaultsParams,
88
+ success: ListVaultsResponse,
89
+ error: [InternalError, OnePasswordError]
90
+ })
91
+ );
92
+
93
+ // src/react/client.ts
94
+ var OnePasswordClient = createPluginAtomClient(OnePasswordGroup, {
95
+ baseUrl: getExecutorApiBaseUrl,
96
+ authorizationHeader: getExecutorServerAuthorizationHeader,
97
+ headers: getExecutorOrganizationHeaders
98
+ });
99
+
100
+ // src/react/atoms.ts
101
+ var onepasswordWriteKeys = [ReactivityKey.providers];
102
+ var onepasswordConfigAtom = OnePasswordClient.query("onepassword", "getConfig", {
103
+ timeToLive: "30 seconds",
104
+ reactivityKeys: [ReactivityKey.providers]
105
+ });
106
+ var onepasswordStatusAtom = OnePasswordClient.query("onepassword", "status", {
107
+ timeToLive: "15 seconds",
108
+ reactivityKeys: [ReactivityKey.providers]
109
+ });
110
+ var onepasswordVaultsAtom = (authKind, account) => OnePasswordClient.query("onepassword", "listVaults", {
111
+ query: { authKind, account },
112
+ timeToLive: "30 seconds",
113
+ reactivityKeys: [ReactivityKey.providers]
114
+ });
115
+ var configureOnePassword = OnePasswordClient.mutation("onepassword", "configure");
116
+ var removeOnePasswordConfig = OnePasswordClient.mutation("onepassword", "removeConfig");
117
+
118
+ // src/react/OnePasswordSettings.tsx
119
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
120
+ var VAULT_LIST_ERROR_FALLBACK = "Failed to list vaults";
121
+ var formatVaultListError = (error) => {
122
+ const message = error.message.trim();
123
+ return message ? `${VAULT_LIST_ERROR_FALLBACK}: ${message}` : VAULT_LIST_ERROR_FALLBACK;
124
+ };
125
+ function VaultPicker(props) {
126
+ const account = props.accountName.trim();
127
+ const vaultsResult = useAtomValue(onepasswordVaultsAtom(props.authKind, account));
128
+ const { vaults, isLoading, error } = AsyncResult.matchWithError(
129
+ vaultsResult,
130
+ {
131
+ onInitial: () => ({
132
+ vaults: [],
133
+ isLoading: true,
134
+ error: null
135
+ }),
136
+ onError: (queryError) => ({
137
+ vaults: [],
138
+ isLoading: false,
139
+ error: formatVaultListError(queryError)
140
+ }),
141
+ onDefect: () => ({
142
+ vaults: [],
143
+ isLoading: false,
144
+ error: VAULT_LIST_ERROR_FALLBACK
145
+ }),
146
+ onSuccess: ({ value }) => {
147
+ const v = value.vaults;
148
+ const defaultVault = v[0];
149
+ if (defaultVault && (!props.vaultId || v.length === 1 && props.vaultId !== defaultVault.id)) {
150
+ queueMicrotask(() => props.onVaultSelect(defaultVault.id, defaultVault.name));
151
+ }
152
+ return { vaults: [...v], isLoading: false, error: null };
153
+ }
154
+ }
155
+ );
156
+ if (!account) {
157
+ return /* @__PURE__ */ jsx("p", { className: "text-[11px] text-muted-foreground/50 py-1", children: "Enter account details to load vaults." });
158
+ }
159
+ const singleVault = vaults.length === 1 ? vaults[0] : null;
160
+ return /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
161
+ singleVault ? /* @__PURE__ */ jsx("div", { className: "flex h-9 items-center rounded-md border border-input bg-muted/30 px-3 text-[13px] text-foreground", children: /* @__PURE__ */ jsx("span", { className: "truncate", children: singleVault.name }) }) : /* @__PURE__ */ jsxs(
162
+ Select,
163
+ {
164
+ disabled: isLoading || vaults.length === 0,
165
+ value: props.vaultId,
166
+ onValueChange: (id) => {
167
+ const v = vaults.find((vault) => vault.id === id);
168
+ if (v) props.onVaultSelect(v.id, v.name);
169
+ },
170
+ children: [
171
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "h-9 text-[13px]", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: isLoading ? "Loading\u2026" : "Select a vault" }) }),
172
+ /* @__PURE__ */ jsx(SelectContent, { children: vaults.map((v) => /* @__PURE__ */ jsx(SelectItem, { value: v.id, children: v.name }, v.id)) })
173
+ ]
174
+ }
175
+ ),
176
+ error && /* @__PURE__ */ jsx("div", { className: "rounded-md border border-destructive/20 bg-destructive/5 px-2.5 py-1.5", children: /* @__PURE__ */ jsx("p", { className: "text-[11px] text-destructive leading-relaxed whitespace-pre-line", children: error }) })
177
+ ] });
178
+ }
179
+ function ConfigDialog(props) {
180
+ const isEdit = !!props.initial;
181
+ const [authKind, setAuthKind] = useState(
182
+ props.initial?.authKind ?? "desktop-app"
183
+ );
184
+ const [accountName, setAccountName] = useState(props.initial?.accountName ?? "my.1password.com");
185
+ const [vaultId, setVaultId] = useState(props.initial?.vaultId ?? "");
186
+ const [vaultName, setVaultName] = useState(props.initial?.name ?? "");
187
+ const [saving, setSaving] = useState(false);
188
+ const [error, setError] = useState(null);
189
+ const doConfigure = useAtomSet(configureOnePassword, { mode: "promiseExit" });
190
+ const reset = () => {
191
+ if (!isEdit) {
192
+ setAuthKind("desktop-app");
193
+ setAccountName("my.1password.com");
194
+ setVaultId("");
195
+ setVaultName("");
196
+ }
197
+ setError(null);
198
+ setSaving(false);
199
+ };
200
+ const handleSave = async () => {
201
+ if (!accountName.trim() || !vaultId.trim()) return;
202
+ setSaving(true);
203
+ setError(null);
204
+ const auth = authKind === "desktop-app" ? { kind: "desktop-app", accountName: accountName.trim() } : { kind: "service-account", token: accountName.trim() };
205
+ const exit = await doConfigure({
206
+ payload: {
207
+ auth,
208
+ vaultId: vaultId.trim(),
209
+ name: vaultName.trim() || "1Password"
210
+ },
211
+ reactivityKeys: onepasswordWriteKeys
212
+ });
213
+ if (Exit.isFailure(exit)) {
214
+ setError("Failed to save configuration");
215
+ setSaving(false);
216
+ return;
217
+ }
218
+ props.onOpenChange(false);
219
+ reset();
220
+ };
221
+ return /* @__PURE__ */ jsx(
222
+ Dialog,
223
+ {
224
+ open: props.open,
225
+ onOpenChange: (v) => {
226
+ if (!v) reset();
227
+ props.onOpenChange(v);
228
+ },
229
+ children: /* @__PURE__ */ jsxs(DialogContent, { className: "sm:max-w-[420px]", children: [
230
+ /* @__PURE__ */ jsxs(DialogHeader, { children: [
231
+ /* @__PURE__ */ jsx(DialogTitle, { className: "font-display text-xl", children: isEdit ? "Edit 1Password" : "Connect 1Password" }),
232
+ /* @__PURE__ */ jsx(DialogDescription, { className: "text-[13px] leading-relaxed", children: "Link a vault to resolve secrets via the 1Password desktop app or a service account." })
233
+ ] }),
234
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-5 py-3", children: [
235
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-1.5", children: [
236
+ /* @__PURE__ */ jsx(Label, { className: "text-[11px] font-medium uppercase tracking-[0.08em] text-muted-foreground", children: "Auth method" }),
237
+ /* @__PURE__ */ jsxs(
238
+ Select,
239
+ {
240
+ value: authKind,
241
+ onValueChange: (v) => setAuthKind(v),
242
+ children: [
243
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "h-9 text-[13px]", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
244
+ /* @__PURE__ */ jsxs(SelectContent, { children: [
245
+ /* @__PURE__ */ jsx(SelectItem, { value: "desktop-app", children: "Desktop App (biometric)" }),
246
+ /* @__PURE__ */ jsx(SelectItem, { value: "service-account", children: "Service Account" })
247
+ ] })
248
+ ]
249
+ }
250
+ )
251
+ ] }),
252
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-1.5", children: [
253
+ /* @__PURE__ */ jsx(Label, { className: "text-[11px] font-medium uppercase tracking-[0.08em] text-muted-foreground", children: authKind === "desktop-app" ? "Account domain" : "Service account token" }),
254
+ /* @__PURE__ */ jsx(
255
+ Input,
256
+ {
257
+ placeholder: authKind === "desktop-app" ? "my.1password.com" : "ops_...",
258
+ value: accountName,
259
+ onChange: (e) => setAccountName(e.target.value),
260
+ className: "font-mono text-[13px] h-9"
261
+ }
262
+ ),
263
+ /* @__PURE__ */ jsx("p", { className: "text-[11px] text-muted-foreground/60 leading-relaxed", children: authKind === "desktop-app" ? "Requires the 1Password desktop app with biometric unlock." : "The token is stored in this provider's owner-scoped config and never surfaced again." })
264
+ ] }),
265
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-1.5", children: [
266
+ /* @__PURE__ */ jsx(Label, { className: "text-[11px] font-medium uppercase tracking-[0.08em] text-muted-foreground", children: "Vault" }),
267
+ /* @__PURE__ */ jsx(
268
+ VaultPicker,
269
+ {
270
+ authKind,
271
+ accountName,
272
+ vaultId,
273
+ onVaultSelect: (id, name) => {
274
+ setVaultId(id);
275
+ setVaultName(name);
276
+ }
277
+ }
278
+ )
279
+ ] }),
280
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-1.5", children: [
281
+ /* @__PURE__ */ jsx(Label, { className: "text-[11px] font-medium uppercase tracking-[0.08em] text-muted-foreground", children: "Display name" }),
282
+ /* @__PURE__ */ jsx(
283
+ Input,
284
+ {
285
+ placeholder: "1Password",
286
+ value: vaultName,
287
+ onChange: (e) => setVaultName(e.target.value),
288
+ className: "text-[13px] h-9"
289
+ }
290
+ )
291
+ ] }),
292
+ error && /* @__PURE__ */ jsx("div", { className: "rounded-md border border-destructive/20 bg-destructive/5 px-3 py-2", children: /* @__PURE__ */ jsx("p", { className: "text-[12px] text-destructive whitespace-pre-line", children: error }) })
293
+ ] }),
294
+ /* @__PURE__ */ jsxs(DialogFooter, { children: [
295
+ /* @__PURE__ */ jsx(DialogClose, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", children: "Cancel" }) }),
296
+ /* @__PURE__ */ jsx(
297
+ Button,
298
+ {
299
+ size: "sm",
300
+ onClick: handleSave,
301
+ disabled: !accountName.trim() || !vaultId.trim() || saving,
302
+ children: saving ? "Saving\u2026" : isEdit ? "Update" : "Connect"
303
+ }
304
+ )
305
+ ] })
306
+ ] })
307
+ }
308
+ );
309
+ }
310
+ function OnePasswordSettings() {
311
+ const [configOpen, setConfigOpen] = useState(false);
312
+ const configResult = useAtomValue(onepasswordConfigAtom);
313
+ const doRemove = useAtomSet(removeOnePasswordConfig, { mode: "promiseExit" });
314
+ const handleRemove = async () => {
315
+ await doRemove({ reactivityKeys: onepasswordWriteKeys });
316
+ };
317
+ const config = AsyncResult.match(
318
+ configResult,
319
+ {
320
+ onInitial: () => null,
321
+ onFailure: () => null,
322
+ onSuccess: ({ value }) => value
323
+ }
324
+ );
325
+ const isLoading = AsyncResult.match(
326
+ configResult,
327
+ {
328
+ onInitial: () => true,
329
+ onFailure: () => false,
330
+ onSuccess: () => false
331
+ }
332
+ );
333
+ const isError = AsyncResult.match(
334
+ configResult,
335
+ {
336
+ onInitial: () => false,
337
+ onFailure: () => true,
338
+ onSuccess: () => false
339
+ }
340
+ );
341
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
342
+ /* @__PURE__ */ jsxs(CardStackEntry, { children: [
343
+ /* @__PURE__ */ jsx(CardStackEntryContent, { children: isLoading ? /* @__PURE__ */ jsx(CardStackEntryDescription, { children: "Loading\u2026" }) : isError ? /* @__PURE__ */ jsx(CardStackEntryDescription, { className: "text-destructive", children: "Failed to load configuration" }) : config ? /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[auto_1fr] gap-x-6 gap-y-1 text-[12px]", children: [
344
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground/60", children: "Auth" }),
345
+ /* @__PURE__ */ jsx("span", { className: "font-mono text-foreground/80 truncate", children: config.auth.kind === "desktop-app" ? config.auth.accountName : "service-account" }),
346
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground/60", children: "Vault" }),
347
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2 min-w-0", children: /* @__PURE__ */ jsx("span", { className: "text-foreground/80 truncate", children: config.name }) })
348
+ ] }) : /* @__PURE__ */ jsx(CardStackEntryDescription, { children: "Resolve secrets from your 1Password vault." }) }),
349
+ /* @__PURE__ */ jsx(CardStackEntryActions, { children: config ? /* @__PURE__ */ jsxs(Fragment, { children: [
350
+ /* @__PURE__ */ jsx(
351
+ Button,
352
+ {
353
+ variant: "ghost",
354
+ size: "sm",
355
+ className: "h-7 px-2.5 text-[12px]",
356
+ onClick: () => setConfigOpen(true),
357
+ children: "Edit"
358
+ }
359
+ ),
360
+ /* @__PURE__ */ jsx(
361
+ Button,
362
+ {
363
+ variant: "ghost",
364
+ size: "sm",
365
+ className: "h-7 px-2.5 text-[12px] text-destructive/70 hover:text-destructive",
366
+ onClick: handleRemove,
367
+ children: "Disconnect"
368
+ }
369
+ )
370
+ ] }) : !isLoading && !isError && /* @__PURE__ */ jsx(
371
+ Button,
372
+ {
373
+ variant: "link",
374
+ size: "sm",
375
+ className: "h-7 px-0 text-[12px] shrink-0",
376
+ onClick: () => setConfigOpen(true),
377
+ children: "Add 1Password"
378
+ }
379
+ ) })
380
+ ] }),
381
+ configOpen && /* @__PURE__ */ jsx(
382
+ ConfigDialog,
383
+ {
384
+ open: configOpen,
385
+ onOpenChange: setConfigOpen,
386
+ initial: config ? {
387
+ authKind: config.auth.kind,
388
+ // Service-account tokens are never surfaced (redacted); the
389
+ // user re-enters the token when editing that auth method.
390
+ accountName: config.auth.kind === "desktop-app" ? config.auth.accountName : "",
391
+ vaultId: config.vaultId,
392
+ name: config.name
393
+ } : void 0
394
+ }
395
+ )
396
+ ] });
397
+ }
398
+ export {
399
+ OnePasswordSettings as default
400
+ };
401
+ //# sourceMappingURL=OnePasswordSettings-YYVXN2JL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/react/OnePasswordSettings.tsx","../src/react/atoms.ts","../src/react/client.ts","../src/api/group.ts"],"sourcesContent":["import { useState } from \"react\";\nimport { useAtomSet, useAtomValue } from \"@effect/atom-react\";\nimport * as Exit from \"effect/Exit\";\nimport * as AsyncResult from \"effect/unstable/reactivity/AsyncResult\";\nimport { Button } from \"@rafads/react/components/button\";\nimport { Input } from \"@rafads/react/components/input\";\nimport { Label } from \"@rafads/react/components/label\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@rafads/react/components/select\";\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogDescription,\n DialogFooter,\n DialogClose,\n} from \"@rafads/react/components/dialog\";\nimport {\n CardStackEntry,\n CardStackEntryActions,\n CardStackEntryContent,\n CardStackEntryDescription,\n} from \"@rafads/react/components/card-stack\";\n\nimport {\n onepasswordConfigAtom,\n onepasswordVaultsAtom,\n configureOnePassword,\n removeOnePasswordConfig,\n onepasswordWriteKeys,\n} from \"./atoms\";\nimport type { RedactedOnePasswordConfig } from \"../sdk/types\";\n\n// ---------------------------------------------------------------------------\n// Vault picker\n// ---------------------------------------------------------------------------\n\nconst VAULT_LIST_ERROR_FALLBACK = \"Failed to list vaults\";\n\nconst formatVaultListError = (error: Error): string => {\n // oxlint-disable-next-line executor/no-unknown-error-message -- boundary: OnePasswordError carries a typed `message`\n const message = error.message.trim();\n return message ? `${VAULT_LIST_ERROR_FALLBACK}: ${message}` : VAULT_LIST_ERROR_FALLBACK;\n};\n\nfunction VaultPicker(props: {\n authKind: \"desktop-app\" | \"service-account\";\n accountName: string;\n vaultId: string;\n onVaultSelect: (id: string, name: string) => void;\n}) {\n const account = props.accountName.trim();\n const vaultsResult = useAtomValue(onepasswordVaultsAtom(props.authKind, account));\n\n const { vaults, isLoading, error } = AsyncResult.matchWithError(\n vaultsResult as AsyncResult.AsyncResult<\n { vaults: ReadonlyArray<{ id: string; name: string }> },\n Error\n >,\n {\n onInitial: () => ({\n vaults: [] as { id: string; name: string }[],\n isLoading: true,\n error: null,\n }),\n onError: (queryError) => ({\n vaults: [] as { id: string; name: string }[],\n isLoading: false,\n error: formatVaultListError(queryError),\n }),\n onDefect: () => ({\n vaults: [] as { id: string; name: string }[],\n isLoading: false,\n error: VAULT_LIST_ERROR_FALLBACK,\n }),\n onSuccess: ({ value }) => {\n const v = value.vaults;\n const defaultVault = v[0];\n if (\n defaultVault &&\n (!props.vaultId || (v.length === 1 && props.vaultId !== defaultVault.id))\n ) {\n queueMicrotask(() => props.onVaultSelect(defaultVault.id, defaultVault.name));\n }\n return { vaults: [...v], isLoading: false, error: null };\n },\n },\n );\n\n if (!account) {\n return (\n <p className=\"text-[11px] text-muted-foreground/50 py-1\">\n Enter account details to load vaults.\n </p>\n );\n }\n\n const singleVault = vaults.length === 1 ? vaults[0] : null;\n\n return (\n <div className=\"grid gap-2\">\n {singleVault ? (\n <div className=\"flex h-9 items-center rounded-md border border-input bg-muted/30 px-3 text-[13px] text-foreground\">\n <span className=\"truncate\">{singleVault.name}</span>\n </div>\n ) : (\n <Select\n disabled={isLoading || vaults.length === 0}\n value={props.vaultId}\n onValueChange={(id) => {\n const v = vaults.find((vault) => vault.id === id);\n if (v) props.onVaultSelect(v.id, v.name);\n }}\n >\n <SelectTrigger className=\"h-9 text-[13px]\">\n <SelectValue placeholder={isLoading ? \"Loading…\" : \"Select a vault\"} />\n </SelectTrigger>\n <SelectContent>\n {vaults.map((v) => (\n <SelectItem key={v.id} value={v.id}>\n {v.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n {error && (\n <div className=\"rounded-md border border-destructive/20 bg-destructive/5 px-2.5 py-1.5\">\n <p className=\"text-[11px] text-destructive leading-relaxed whitespace-pre-line\">\n {error}\n </p>\n </div>\n )}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Config dialog\n// ---------------------------------------------------------------------------\n\nfunction ConfigDialog(props: {\n open: boolean;\n onOpenChange: (v: boolean) => void;\n initial?: {\n authKind: string;\n accountName: string;\n vaultId: string;\n name: string;\n };\n}) {\n const isEdit = !!props.initial;\n const [authKind, setAuthKind] = useState<\"desktop-app\" | \"service-account\">(\n (props.initial?.authKind as \"desktop-app\" | \"service-account\") ?? \"desktop-app\",\n );\n const [accountName, setAccountName] = useState(props.initial?.accountName ?? \"my.1password.com\");\n const [vaultId, setVaultId] = useState(props.initial?.vaultId ?? \"\");\n const [vaultName, setVaultName] = useState(props.initial?.name ?? \"\");\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const doConfigure = useAtomSet(configureOnePassword, { mode: \"promiseExit\" });\n\n const reset = () => {\n if (!isEdit) {\n setAuthKind(\"desktop-app\");\n setAccountName(\"my.1password.com\");\n setVaultId(\"\");\n setVaultName(\"\");\n }\n setError(null);\n setSaving(false);\n };\n\n const handleSave = async () => {\n if (!accountName.trim() || !vaultId.trim()) return;\n setSaving(true);\n setError(null);\n\n const auth =\n authKind === \"desktop-app\"\n ? { kind: \"desktop-app\" as const, accountName: accountName.trim() }\n : { kind: \"service-account\" as const, token: accountName.trim() };\n\n const exit = await doConfigure({\n payload: {\n auth,\n vaultId: vaultId.trim(),\n name: vaultName.trim() || \"1Password\",\n },\n reactivityKeys: onepasswordWriteKeys,\n });\n if (Exit.isFailure(exit)) {\n setError(\"Failed to save configuration\");\n setSaving(false);\n return;\n }\n\n props.onOpenChange(false);\n reset();\n };\n\n return (\n <Dialog\n open={props.open}\n onOpenChange={(v) => {\n if (!v) reset();\n props.onOpenChange(v);\n }}\n >\n <DialogContent className=\"sm:max-w-[420px]\">\n <DialogHeader>\n <DialogTitle className=\"font-display text-xl\">\n {isEdit ? \"Edit 1Password\" : \"Connect 1Password\"}\n </DialogTitle>\n <DialogDescription className=\"text-[13px] leading-relaxed\">\n Link a vault to resolve secrets via the 1Password desktop app or a service account.\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"grid gap-5 py-3\">\n {/* Auth method */}\n <div className=\"grid gap-1.5\">\n <Label className=\"text-[11px] font-medium uppercase tracking-[0.08em] text-muted-foreground\">\n Auth method\n </Label>\n <Select\n value={authKind}\n onValueChange={(v) => setAuthKind(v as \"desktop-app\" | \"service-account\")}\n >\n <SelectTrigger className=\"h-9 text-[13px]\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"desktop-app\">Desktop App (biometric)</SelectItem>\n <SelectItem value=\"service-account\">Service Account</SelectItem>\n </SelectContent>\n </Select>\n </div>\n\n {/* Account / token */}\n <div className=\"grid gap-1.5\">\n <Label className=\"text-[11px] font-medium uppercase tracking-[0.08em] text-muted-foreground\">\n {authKind === \"desktop-app\" ? \"Account domain\" : \"Service account token\"}\n </Label>\n <Input\n placeholder={authKind === \"desktop-app\" ? \"my.1password.com\" : \"ops_...\"}\n value={accountName}\n onChange={(e) => setAccountName((e.target as HTMLInputElement).value)}\n className=\"font-mono text-[13px] h-9\"\n />\n <p className=\"text-[11px] text-muted-foreground/60 leading-relaxed\">\n {authKind === \"desktop-app\"\n ? \"Requires the 1Password desktop app with biometric unlock.\"\n : \"The token is stored in this provider's owner-scoped config and never surfaced again.\"}\n </p>\n </div>\n\n {/* Vault */}\n <div className=\"grid gap-1.5\">\n <Label className=\"text-[11px] font-medium uppercase tracking-[0.08em] text-muted-foreground\">\n Vault\n </Label>\n <VaultPicker\n authKind={authKind}\n accountName={accountName}\n vaultId={vaultId}\n onVaultSelect={(id, name) => {\n setVaultId(id);\n setVaultName(name);\n }}\n />\n </div>\n\n {/* Display name */}\n <div className=\"grid gap-1.5\">\n <Label className=\"text-[11px] font-medium uppercase tracking-[0.08em] text-muted-foreground\">\n Display name\n </Label>\n <Input\n placeholder=\"1Password\"\n value={vaultName}\n onChange={(e) => setVaultName((e.target as HTMLInputElement).value)}\n className=\"text-[13px] h-9\"\n />\n </div>\n\n {error && (\n <div className=\"rounded-md border border-destructive/20 bg-destructive/5 px-3 py-2\">\n <p className=\"text-[12px] text-destructive whitespace-pre-line\">{error}</p>\n </div>\n )}\n </div>\n\n <DialogFooter>\n <DialogClose asChild>\n <Button variant=\"ghost\" size=\"sm\">\n Cancel\n </Button>\n </DialogClose>\n <Button\n size=\"sm\"\n onClick={handleSave}\n disabled={!accountName.trim() || !vaultId.trim() || saving}\n >\n {saving ? \"Saving…\" : isEdit ? \"Update\" : \"Connect\"}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Settings card\n// ---------------------------------------------------------------------------\n\nexport default function OnePasswordSettings() {\n const [configOpen, setConfigOpen] = useState(false);\n const configResult = useAtomValue(onepasswordConfigAtom);\n const doRemove = useAtomSet(removeOnePasswordConfig, { mode: \"promiseExit\" });\n\n const handleRemove = async () => {\n await doRemove({ reactivityKeys: onepasswordWriteKeys });\n };\n\n const config: RedactedOnePasswordConfig | null = AsyncResult.match(\n configResult as AsyncResult.AsyncResult<RedactedOnePasswordConfig | null, unknown>,\n {\n onInitial: () => null,\n onFailure: () => null,\n onSuccess: ({ value }) => value,\n },\n );\n const isLoading = AsyncResult.match(\n configResult as AsyncResult.AsyncResult<RedactedOnePasswordConfig | null, unknown>,\n {\n onInitial: () => true,\n onFailure: () => false,\n onSuccess: () => false,\n },\n );\n const isError = AsyncResult.match(\n configResult as AsyncResult.AsyncResult<RedactedOnePasswordConfig | null, unknown>,\n {\n onInitial: () => false,\n onFailure: () => true,\n onSuccess: () => false,\n },\n );\n\n return (\n <>\n <CardStackEntry>\n <CardStackEntryContent>\n {isLoading ? (\n <CardStackEntryDescription>Loading…</CardStackEntryDescription>\n ) : isError ? (\n <CardStackEntryDescription className=\"text-destructive\">\n Failed to load configuration\n </CardStackEntryDescription>\n ) : config ? (\n <div className=\"grid grid-cols-[auto_1fr] gap-x-6 gap-y-1 text-[12px]\">\n <span className=\"text-muted-foreground/60\">Auth</span>\n <span className=\"font-mono text-foreground/80 truncate\">\n {config.auth.kind === \"desktop-app\" ? config.auth.accountName : \"service-account\"}\n </span>\n <span className=\"text-muted-foreground/60\">Vault</span>\n <div className=\"flex items-center gap-2 min-w-0\">\n <span className=\"text-foreground/80 truncate\">{config.name}</span>\n </div>\n </div>\n ) : (\n <CardStackEntryDescription>\n Resolve secrets from your 1Password vault.\n </CardStackEntryDescription>\n )}\n </CardStackEntryContent>\n <CardStackEntryActions>\n {config ? (\n <>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 px-2.5 text-[12px]\"\n onClick={() => setConfigOpen(true)}\n >\n Edit\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 px-2.5 text-[12px] text-destructive/70 hover:text-destructive\"\n onClick={handleRemove}\n >\n Disconnect\n </Button>\n </>\n ) : (\n !isLoading &&\n !isError && (\n <Button\n variant=\"link\"\n size=\"sm\"\n className=\"h-7 px-0 text-[12px] shrink-0\"\n onClick={() => setConfigOpen(true)}\n >\n Add 1Password\n </Button>\n )\n )}\n </CardStackEntryActions>\n </CardStackEntry>\n\n {configOpen && (\n <ConfigDialog\n open={configOpen}\n onOpenChange={setConfigOpen}\n initial={\n config\n ? {\n authKind: config.auth.kind,\n // Service-account tokens are never surfaced (redacted); the\n // user re-enters the token when editing that auth method.\n accountName: config.auth.kind === \"desktop-app\" ? config.auth.accountName : \"\",\n vaultId: config.vaultId,\n name: config.name,\n }\n : undefined\n }\n />\n )}\n </>\n );\n}\n","import { ReactivityKey } from \"@rafads/react/api/reactivity-keys\";\nimport { OnePasswordClient } from \"./client\";\n\n// 1Password is a CredentialProvider in v2 — its owner-scoped config lives in\n// the `providers` reactivity family (the v1 `secrets` key is gone).\nexport const onepasswordWriteKeys = [ReactivityKey.providers] as const;\n\n// ---------------------------------------------------------------------------\n// Query atoms\n//\n// v2: the 1Password config is a single owner-partitioned binding the server\n// derives from the executor's owner — there are no owner path params here; the\n// server reads the acting owner from the executor binding.\n// ---------------------------------------------------------------------------\n\nexport const onepasswordConfigAtom = OnePasswordClient.query(\"onepassword\", \"getConfig\", {\n timeToLive: \"30 seconds\",\n reactivityKeys: [ReactivityKey.providers],\n});\n\nexport const onepasswordStatusAtom = OnePasswordClient.query(\"onepassword\", \"status\", {\n timeToLive: \"15 seconds\",\n reactivityKeys: [ReactivityKey.providers],\n});\n\n// ---------------------------------------------------------------------------\n// Query atoms — vaults\n// ---------------------------------------------------------------------------\n\nexport const onepasswordVaultsAtom = (\n authKind: \"desktop-app\" | \"service-account\",\n account: string,\n) =>\n OnePasswordClient.query(\"onepassword\", \"listVaults\", {\n query: { authKind, account },\n timeToLive: \"30 seconds\",\n reactivityKeys: [ReactivityKey.providers],\n });\n\n// ---------------------------------------------------------------------------\n// Mutation atoms\n// ---------------------------------------------------------------------------\n\nexport const configureOnePassword = OnePasswordClient.mutation(\"onepassword\", \"configure\");\n\nexport const removeOnePasswordConfig = OnePasswordClient.mutation(\"onepassword\", \"removeConfig\");\n","import { createPluginAtomClient } from \"@rafads/sdk/client\";\nimport {\n getExecutorOrganizationHeaders,\n getExecutorApiBaseUrl,\n getExecutorServerAuthorizationHeader,\n} from \"@rafads/react/api/server-connection\";\nimport { OnePasswordGroup } from \"../api/group\";\n\nexport const OnePasswordClient = createPluginAtomClient(OnePasswordGroup, {\n baseUrl: getExecutorApiBaseUrl,\n authorizationHeader: getExecutorServerAuthorizationHeader,\n headers: getExecutorOrganizationHeaders,\n});\n","import { HttpApiEndpoint, HttpApiGroup } from \"effect/unstable/httpapi\";\nimport { Schema } from \"effect\";\nimport { InternalError } from \"@rafads/sdk/shared\";\n\nimport { OnePasswordError } from \"../sdk/errors\";\nimport {\n OnePasswordConfig,\n RedactedOnePasswordConfig,\n Vault,\n ConnectionStatus,\n} from \"../sdk/types\";\n\n// ---------------------------------------------------------------------------\n// Payloads\n//\n// v2: config is a single per-owner binding the extension derives from the\n// executor's owner binding — there are no scope segments in the path. The\n// configure payload carries the full config (including the service-account\n// token); reads return the redacted projection so the token never leaves the\n// plugin.\n// ---------------------------------------------------------------------------\n\nconst ConfigurePayload = OnePasswordConfig;\n\nconst ListVaultsParams = Schema.Struct({\n authKind: Schema.Literals([\"desktop-app\", \"service-account\"]),\n account: Schema.String,\n});\n\n// ---------------------------------------------------------------------------\n// Responses\n// ---------------------------------------------------------------------------\n\nconst ListVaultsResponse = Schema.Struct({\n vaults: Schema.Array(Vault),\n});\n\nconst GetConfigResponse = Schema.NullOr(RedactedOnePasswordConfig);\n\n// ---------------------------------------------------------------------------\n// Group\n//\n// Plugin SDK errors (OnePasswordError) are declared once per endpoint via the\n// `error` field — the error carries its own 502 status via `HttpApiSchema`\n// annotations in errors.ts.\n//\n// `InternalError` is the shared opaque 500 schema translated at the HTTP edge\n// by `withCapture`. Storage failures on `ctx.storage` flow through as\n// `StorageFailure` in the typed channel and are captured + downgraded to\n// `InternalError({ traceId })` at Layer composition.\n// ---------------------------------------------------------------------------\n\nexport const OnePasswordGroup = HttpApiGroup.make(\"onepassword\")\n .add(\n HttpApiEndpoint.get(\"getConfig\", \"/onepassword/config\", {\n success: GetConfigResponse,\n error: [InternalError, OnePasswordError],\n }),\n )\n .add(\n HttpApiEndpoint.put(\"configure\", \"/onepassword/config\", {\n payload: ConfigurePayload,\n success: Schema.Void,\n error: [InternalError, OnePasswordError],\n }),\n )\n .add(\n HttpApiEndpoint.delete(\"removeConfig\", \"/onepassword/config\", {\n success: Schema.Void,\n error: [InternalError, OnePasswordError],\n }),\n )\n .add(\n HttpApiEndpoint.get(\"status\", \"/onepassword/status\", {\n success: ConnectionStatus,\n error: [InternalError, OnePasswordError],\n }),\n )\n .add(\n HttpApiEndpoint.get(\"listVaults\", \"/onepassword/vaults\", {\n query: ListVaultsParams,\n success: ListVaultsResponse,\n error: [InternalError, OnePasswordError],\n }),\n );\n"],"mappings":"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","names":[]}
@@ -0,0 +1,36 @@
1
+ import { HttpApiEndpoint, HttpApiGroup } from "effect/unstable/httpapi";
2
+ import { Schema } from "effect";
3
+ import { InternalError } from "@rafads/sdk/shared";
4
+ import { OnePasswordError } from "../sdk/errors";
5
+ export declare const OnePasswordGroup: HttpApiGroup.HttpApiGroup<"onepassword", HttpApiEndpoint.HttpApiEndpoint<"getConfig", "GET", "/onepassword/config", HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.Json<Schema.NullOr<Schema.Struct<{
6
+ readonly auth: Schema.Union<readonly [Schema.Struct<{
7
+ readonly kind: Schema.Literal<"desktop-app">;
8
+ readonly accountName: Schema.String;
9
+ }>, Schema.Struct<{
10
+ readonly kind: Schema.Literal<"service-account">;
11
+ }>]>;
12
+ readonly vaultId: Schema.String;
13
+ readonly name: Schema.String;
14
+ }>>>, HttpApiEndpoint.Json<typeof InternalError | typeof OnePasswordError>, never, never> | HttpApiEndpoint.HttpApiEndpoint<"configure", "PUT", "/onepassword/config", HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.Json<Schema.Struct<{
15
+ readonly auth: Schema.Union<readonly [Schema.Struct<{
16
+ readonly kind: Schema.Literal<"desktop-app">;
17
+ readonly accountName: Schema.String;
18
+ }>, Schema.Struct<{
19
+ readonly kind: Schema.Literal<"service-account">;
20
+ readonly token: Schema.String;
21
+ }>]>;
22
+ readonly vaultId: Schema.String;
23
+ readonly name: Schema.String;
24
+ }>>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.Json<Schema.Void>, HttpApiEndpoint.Json<typeof InternalError | typeof OnePasswordError>, never, never> | HttpApiEndpoint.HttpApiEndpoint<"removeConfig", "DELETE", "/onepassword/config", HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.Json<never>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.Json<Schema.Void>, HttpApiEndpoint.Json<typeof InternalError | typeof OnePasswordError>, never, never> | HttpApiEndpoint.HttpApiEndpoint<"status", "GET", "/onepassword/status", HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.Json<Schema.Struct<{
25
+ readonly connected: Schema.Boolean;
26
+ readonly vaultName: Schema.optional<Schema.String>;
27
+ readonly error: Schema.optional<Schema.String>;
28
+ }>>, HttpApiEndpoint.Json<typeof InternalError | typeof OnePasswordError>, never, never> | HttpApiEndpoint.HttpApiEndpoint<"listVaults", "GET", "/onepassword/vaults", HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.StringTree<Schema.Struct<{
29
+ readonly authKind: Schema.Literals<readonly ["desktop-app", "service-account"]>;
30
+ readonly account: Schema.String;
31
+ }>>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.Json<Schema.Struct<{
32
+ readonly vaults: Schema.$Array<Schema.Struct<{
33
+ readonly id: Schema.String;
34
+ readonly name: Schema.String;
35
+ }>>;
36
+ }>>, HttpApiEndpoint.Json<typeof InternalError | typeof OnePasswordError>, never, never>, false>;
@@ -0,0 +1,20 @@
1
+ import { Context, Effect } from "effect";
2
+ declare const OnePasswordExtensionService_base: Context.ServiceClass<OnePasswordExtensionService, "OnePasswordExtensionService", {
3
+ configure: (config: import("../promise").OnePasswordConfig) => Effect.Effect<void, import("@rafads/sdk").StorageError, never>;
4
+ getConfig: () => Effect.Effect<import("../sdk").RedactedOnePasswordConfig | null, import("@rafads/sdk").StorageError | import("../promise").OnePasswordError>;
5
+ removeConfig: () => Effect.Effect<void, import("@rafads/sdk").StorageError, never>;
6
+ status: () => Effect.Effect<{
7
+ readonly connected: boolean;
8
+ readonly error?: string | undefined;
9
+ readonly vaultName?: string | undefined;
10
+ }, import("@rafads/sdk").StorageError | import("../promise").OnePasswordError, never>;
11
+ listVaults: (auth: import("../promise").OnePasswordAuth) => Effect.Effect<{
12
+ readonly id: string;
13
+ readonly name: string;
14
+ }[], import("../promise").OnePasswordError, never>;
15
+ resolve: (uri: string) => Effect.Effect<string, import("@rafads/sdk").StorageError | import("../promise").OnePasswordError, never>;
16
+ }>;
17
+ export declare class OnePasswordExtensionService extends OnePasswordExtensionService_base {
18
+ }
19
+ export declare const OnePasswordHandlers: import("effect/Layer").Layer<import("effect/unstable/httpapi/HttpApiGroup").ApiGroup<"executor", "onepassword">, never, import("effect/unstable/http/HttpRouter").Request<"Requires", OnePasswordExtensionService>>;
20
+ export {};