@agentproto/secrets 1.2.1 → 1.3.0
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.
|
@@ -169,6 +169,33 @@ var mastracodeRecipe = defineProvisionRecipe({
|
|
|
169
169
|
}
|
|
170
170
|
]
|
|
171
171
|
});
|
|
172
|
+
var jcodeRecipe = defineProvisionRecipe({
|
|
173
|
+
id: "jcode",
|
|
174
|
+
description: "jcode's Claude Max and ChatGPT subscription OAuth access tokens, read from the CLI's own auth stores (written by `jcode login`).",
|
|
175
|
+
label: "jcode (Claude/ChatGPT subscription)",
|
|
176
|
+
methods: [
|
|
177
|
+
{
|
|
178
|
+
id: "anthropic-oauth",
|
|
179
|
+
source: [
|
|
180
|
+
{ file: "~/.jcode/auth.json", jsonPath: "anthropic_accounts.0.access" },
|
|
181
|
+
{ file: "~/.jcode/auth.json", jsonPath: "anthropic.access" }
|
|
182
|
+
]
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
id: "openai-oauth",
|
|
186
|
+
source: {
|
|
187
|
+
file: "~/.jcode/openai-auth.json",
|
|
188
|
+
jsonPath: "openai_accounts.0.access_token"
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
]
|
|
192
|
+
});
|
|
193
|
+
var mastracodeInprocessRecipe = defineProvisionRecipe({
|
|
194
|
+
id: "mastracode-inprocess",
|
|
195
|
+
description: "mastracode's Claude Pro/Max and ChatGPT subscription OAuth access tokens, read from the CLI's own auth store, for the in-process mastracode adapter.",
|
|
196
|
+
label: "mastracode in-process (Claude/ChatGPT subscription)",
|
|
197
|
+
methods: mastracodeRecipe.methods
|
|
198
|
+
});
|
|
172
199
|
var geminiRecipe = defineProvisionRecipe({
|
|
173
200
|
id: "gemini",
|
|
174
201
|
description: "Google Gemini CLI OAuth access token, read from the local CLI's credential cache.",
|
|
@@ -188,7 +215,9 @@ var BUILTIN_RECIPES = [
|
|
|
188
215
|
codexRecipe,
|
|
189
216
|
geminiRecipe,
|
|
190
217
|
opencodeRecipe,
|
|
191
|
-
mastracodeRecipe
|
|
218
|
+
mastracodeRecipe,
|
|
219
|
+
jcodeRecipe,
|
|
220
|
+
mastracodeInprocessRecipe
|
|
192
221
|
];
|
|
193
222
|
|
|
194
223
|
// src/provision/recipe/registry.ts
|
|
@@ -278,5 +307,5 @@ async function resolveKeychain(source) {
|
|
|
278
307
|
}
|
|
279
308
|
|
|
280
309
|
export { BUILTIN_RECIPES, claudeCodeOauthRecipe, codexRecipe, credentialSourceSpecSchema, defineProvisionRecipe, geminiRecipe, getRecipe, listRecipeIds, listRecipes, parseRecipeManifest, parseRecipeManifestRaw, provisionRecipeFrontmatterSchema, recipeMethodSchema, registerRecipe, resolveRecipeMethod, resolveSourceSpec };
|
|
281
|
-
//# sourceMappingURL=chunk-
|
|
282
|
-
//# sourceMappingURL=chunk-
|
|
310
|
+
//# sourceMappingURL=chunk-MYW7DD7E.mjs.map
|
|
311
|
+
//# sourceMappingURL=chunk-MYW7DD7E.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/provision/recipe/schema.ts","../src/provision/recipe/define-recipe.ts","../src/provision/recipe/manifest.ts","../src/provision/recipe/builtins.ts","../src/provision/recipe/registry.ts","../src/provision/recipe/resolve.ts"],"names":[],"mappings":"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","file":"chunk-MYW7DD7E.mjs","sourcesContent":["/**\n * Provision-recipe frontmatter / literal zod schema.\n *\n * Single source of truth for both authoring paths: `defineProvisionRecipe`\n * (TS literal) and `parseRecipeManifest` (.md) run this same schema, so a\n * malformed literal and a malformed manifest fail identically — mirrors how\n * `secretsFrontmatterSchema` backs both `defineSecrets` and\n * `parseSecretsManifest`.\n *\n * Hand-written rather than scaffold-aip-generated: a recipe is not yet a\n * numbered-AIP artifact. Promote to a generated schema if it gets its own spec.\n */\n\nimport { z } from \"zod\"\n\n/** Exactly one of file / env / keychain / prompt. `value` is explicitly\n * forbidden — a recipe carries locations, never secrets. */\nexport const credentialSourceSpecSchema = z\n .union([\n z\n .object({\n file: z.string().min(1),\n jsonPath: z.string().min(1).optional(),\n })\n .strict(),\n z.object({ env: z.string().min(1) }).strict(),\n z\n .object({\n keychain: z.string().min(1),\n account: z.string().min(1).optional(),\n jsonPath: z.string().min(1).optional(),\n })\n .strict(),\n z.object({ prompt: z.string().min(1) }).strict(),\n ])\n .describe(\n \"Where a method's credential is read on the origin machine: a file (optionally a JSON field), an env var, the macOS Keychain, or an interactive prompt. Never a literal value.\",\n )\n\n/** A method's source: a single spec or an ordered fallback chain (first that\n * resolves wins). */\nexport const methodSourceSchema = z.union([\n credentialSourceSpecSchema,\n z.array(credentialSourceSpecSchema).min(1),\n])\n\nexport const recipeMethodSchema = z\n .object({\n id: z.string().min(1),\n label: z.string().min(1).optional(),\n source: methodSourceSchema,\n })\n .strict()\n\nexport const provisionRecipeFrontmatterSchema = z\n .object({\n id: z.string().min(2).max(80),\n description: z.string().min(1).max(2000),\n methods: z.array(recipeMethodSchema).min(1),\n label: z.string().min(1).optional(),\n })\n .strict()\n .describe(\n \"A credential-provision recipe: for one provider, the installable flavors (methods) and where each flavor's credential lives locally. Holds locations, never values.\",\n )\n\nexport type ProvisionRecipeFrontmatter = z.infer<\n typeof provisionRecipeFrontmatterSchema\n>\n","/**\n * `defineProvisionRecipe` — the TS-literal authoring path for a recipe.\n *\n * Built on `createDoctype` so a recipe gets the same cross-AIP invariants as\n * every other doctype: id-pattern check, ≤2000-char description, frozen handle,\n * canonical \"defineProvisionRecipe (AIP-19): …\" error prefix. Field-level\n * validation runs the shared zod from `./schema.ts`, so a malformed literal\n * fails with the same diagnostic as a malformed `.md`.\n */\n\nimport { createDoctype } from \"@agentproto/define-doctype\"\nimport { provisionRecipeFrontmatterSchema } from \"./schema.js\"\nimport type {\n ProvisionRecipe,\n ProvisionRecipeDefinition,\n} from \"./types.js\"\n\nexport const defineProvisionRecipe = createDoctype<\n ProvisionRecipeDefinition,\n ProvisionRecipe\n>({\n aip: 19,\n name: \"provisionRecipe\",\n validate(def) {\n const result = provisionRecipeFrontmatterSchema.safeParse(def)\n if (!result.success) {\n throw new Error(\n `defineProvisionRecipe (AIP-19): ${result.error.issues\n .map((i) => `${i.path.join(\".\")}: ${i.message}`)\n .join(\"; \")}`,\n )\n }\n },\n build(def) {\n return {\n ...def,\n methods: def.methods.map((m) => Object.freeze({ ...m })) as ProvisionRecipe[\"methods\"],\n }\n },\n})\n","/**\n * `.md` authoring path for a provision recipe — parse a frontmatter manifest\n * into a frozen handle. Mirrors `parseSecretsManifest`: gray-matter splits the\n * frontmatter, the shared zod validates it, `defineProvisionRecipe` builds the\n * handle so the `.md` and TS-literal paths converge on one validated shape.\n *\n * The package ships its builtin recipes as TS literals (they bundle with zero\n * fs); this parser is for a HOST that reads its own external `.md` recipes and\n * registers them — the extension seam.\n */\n\nimport matter from \"gray-matter\"\nimport {\n provisionRecipeFrontmatterSchema,\n type ProvisionRecipeFrontmatter,\n} from \"./schema.js\"\nimport { defineProvisionRecipe } from \"./define-recipe.js\"\nimport type { ProvisionRecipe, ProvisionRecipeDefinition } from \"./types.js\"\n\nexport interface ProvisionRecipeManifest {\n frontmatter: ProvisionRecipeFrontmatter\n body: string\n}\n\nexport function parseRecipeManifestRaw(\n source: string,\n): ProvisionRecipeManifest {\n const parsed = matter(source)\n if (Object.keys(parsed.data).length === 0) {\n throw new Error(\"parseRecipeManifest: missing or empty frontmatter\")\n }\n const result = provisionRecipeFrontmatterSchema.safeParse(parsed.data)\n if (!result.success) {\n throw new Error(\n `parseRecipeManifest: invalid frontmatter — ${result.error.issues\n .map((i) => `${i.path.join(\".\")}: ${i.message}`)\n .join(\"; \")}`,\n )\n }\n return { frontmatter: result.data, body: parsed.content }\n}\n\n/** Parse a recipe `.md` straight to a frozen handle (frontmatter →\n * `defineProvisionRecipe`). */\nexport function parseRecipeManifest(source: string): ProvisionRecipe {\n const { frontmatter } = parseRecipeManifestRaw(source)\n return defineProvisionRecipe(\n frontmatter as unknown as ProvisionRecipeDefinition,\n )\n}\n","/**\n * Builtin provision recipes — the credential providers the flow knows out of\n * the box. Shipped as TS literals (not `.md`) so they bundle into the tsup\n * output with zero filesystem read at runtime. A host adds more by parsing its\n * own `.md` with `parseRecipeManifest` and `registerRecipe`-ing the result.\n *\n * Each recipe describes the credential's PUBLIC local convention for that CLI\n * (where it writes its token) — no vendor's private infra, no values.\n */\n\nimport { defineProvisionRecipe } from \"./define-recipe.js\"\nimport type { ProvisionRecipe } from \"./types.js\"\n\n/** Claude Code subscription OAuth token. macOS stores it in the login Keychain;\n * Linux writes it to ~/.claude/.credentials.json. Try the Keychain first, fall\n * back to the file, so one recipe spans both. */\nexport const claudeCodeOauthRecipe = defineProvisionRecipe({\n id: \"claude-code-oauth\",\n description:\n \"Claude Code subscription OAuth access token, read from the macOS Keychain or the local CLI's credential file.\",\n label: \"Claude Code (subscription)\",\n methods: [\n {\n id: \"subscription-token\",\n source: [\n {\n keychain: \"Claude Code-credentials\",\n jsonPath: \"claudeAiOauth.accessToken\",\n },\n {\n file: \"~/.claude/.credentials.json\",\n jsonPath: \"claudeAiOauth.accessToken\",\n },\n ],\n },\n ],\n})\n\n/** Codex CLI — two flavors: the subscription OAuth token, or a raw API key. */\nexport const codexRecipe = defineProvisionRecipe({\n id: \"codex\",\n description:\n \"OpenAI Codex CLI credential — either the subscription OAuth access token from the local auth file, or an API key from the environment.\",\n label: \"Codex\",\n methods: [\n {\n id: \"oauth-subscription\",\n label: \"Codex (subscription)\",\n source: { file: \"~/.codex/auth.json\", jsonPath: \"tokens.access_token\" },\n },\n {\n id: \"api-key\",\n label: \"Codex (API key)\",\n source: { env: \"OPENAI_API_KEY\" },\n },\n ],\n})\n\n/** opencode — Anthropic (Claude Pro/Max) OAuth login stored by the CLI's own\n * `opencode auth login` flow. opencode keeps its auth store under the XDG\n * data dir on every platform (macOS included — verified live). The entry\n * shape is `{anthropic: {type: \"oauth\", access, refresh, expires}}`.\n *\n * `openai-oauth` covers opencode's separate \"ChatGPT Pro/Plus\" OAuth login\n * (`opencode auth login` → select provider \"openai\", browser or headless\n * device-code flow against auth.openai.com). Reverse-engineered from the\n * shipped binary (`~/.opencode/bin/opencode`, no OSS source for this build\n * available to read directly): the plugin registers its two OAuth methods\n * under `integrationID: R.ID.make(\"openai\")`, and the generic provider-login\n * handler (`Cli.providers.login` → `Cli.providers.pluginAuth`) writes the\n * credential via `Auth.set(provider.id, {type:\"oauth\", access, refresh,\n * expires, ...})` where `provider.id` is the SAME \"openai\" id the user\n * selected — there is no separate \"chatgpt\" key. This mirrors exactly how\n * the already-verified `anthropic` entry is keyed by provider id, so the\n * ChatGPT login lands at `openai.access` in the same auth.json. */\nexport const opencodeRecipe = defineProvisionRecipe({\n id: \"opencode\",\n description:\n \"opencode's Claude Pro/Max and ChatGPT Pro/Plus subscription OAuth access tokens, read from the CLI's own auth store (written by `opencode auth login`).\",\n label: \"opencode (Claude/ChatGPT subscription)\",\n methods: [\n {\n id: \"anthropic-oauth\",\n source: {\n file: \"~/.local/share/opencode/auth.json\",\n jsonPath: \"anthropic.access\",\n },\n },\n {\n id: \"openai-oauth\",\n source: {\n file: \"~/.local/share/opencode/auth.json\",\n jsonPath: \"openai.access\",\n },\n },\n ],\n})\n\n/** mastracode — two independent OAuth logins from the TUI's own `/login`\n * flow. mastracode's app-data dir is platform-dependent (`getAppDataDir()`\n * in its source: Application Support on macOS, XDG data dir elsewhere).\n *\n * `anthropic-oauth`: Claude Pro/Max login, entry shape `{anthropic:\n * {type: \"oauth\", access, refresh, expires}}` — verified against a live\n * login.\n *\n * `openai-oauth`: ChatGPT login via mastracode's `openaiCodexOAuthProvider`,\n * stored under the DISTINCT key `openai-codex` (not `openai` — mastracode's\n * own naming, unrelated to opencode's), entry shape `{\"openai-codex\":\n * {type: \"oauth\", access, refresh, expires, accountId}}` — also verified\n * against a live login on this machine. */\nexport const mastracodeRecipe = defineProvisionRecipe({\n id: \"mastracode\",\n description:\n \"mastracode's Claude Pro/Max and ChatGPT subscription OAuth access tokens, read from the CLI's own auth store (written by its /login flow).\",\n label: \"mastracode (Claude/ChatGPT subscription)\",\n methods: [\n {\n id: \"anthropic-oauth\",\n source: [\n {\n file: \"~/Library/Application Support/mastracode/auth.json\",\n jsonPath: \"anthropic.access\",\n },\n {\n file: \"~/.local/share/mastracode/auth.json\",\n jsonPath: \"anthropic.access\",\n },\n ],\n },\n {\n id: \"openai-oauth\",\n source: [\n {\n file: \"~/Library/Application Support/mastracode/auth.json\",\n jsonPath: \"openai-codex.access\",\n },\n {\n file: \"~/.local/share/mastracode/auth.json\",\n jsonPath: \"openai-codex.access\",\n },\n ],\n },\n ],\n})\n\n/** jcode — two independent OAuth logins from `jcode login --provider claude`\n * (Claude Max) and `jcode login --provider openai` (ChatGPT/Codex). Both\n * files live under `~/.jcode` on every platform (`jcode_dir()`), and are\n * multi-account stores — the check only needs the first account to carry a\n * token (`jcode auth status` is the authority on which one is active).\n * Layouts read from upstream source (`crates/jcode-base/src/auth/claude.rs`,\n * `codex.rs`) and `docs/AUTH_CREDENTIAL_SOURCES.md`: `auth.json` is\n * `{anthropic_accounts: [{label, access, refresh, expires}]}` (legacy\n * single-account `{anthropic: {access}}` still read), `openai-auth.json` is\n * `{openai_accounts: [{label, access_token, refresh_token}]}`. NOT verified\n * against a live login. The API-key routes (`anthropic-api`, `openai-api`)\n * are separate providers and never appear in these files. */\nexport const jcodeRecipe = defineProvisionRecipe({\n id: \"jcode\",\n description:\n \"jcode's Claude Max and ChatGPT subscription OAuth access tokens, read from the CLI's own auth stores (written by `jcode login`).\",\n label: \"jcode (Claude/ChatGPT subscription)\",\n methods: [\n {\n id: \"anthropic-oauth\",\n source: [\n { file: \"~/.jcode/auth.json\", jsonPath: \"anthropic_accounts.0.access\" },\n { file: \"~/.jcode/auth.json\", jsonPath: \"anthropic.access\" },\n ],\n },\n {\n id: \"openai-oauth\",\n source: {\n file: \"~/.jcode/openai-auth.json\",\n jsonPath: \"openai_accounts.0.access_token\",\n },\n },\n ],\n})\n\n/** mastracode-inprocess — the in-process arm of the same Mastra Code CLI. The\n * `external` login check resolves a recipe by ADAPTER id, so the in-process\n * adapter needs its own id; it reads the very same mastracode `/login` auth\n * store (and the same two methods), so the methods are shared, not copied. */\nexport const mastracodeInprocessRecipe = defineProvisionRecipe({\n id: \"mastracode-inprocess\",\n description:\n \"mastracode's Claude Pro/Max and ChatGPT subscription OAuth access tokens, read from the CLI's own auth store, for the in-process mastracode adapter.\",\n label: \"mastracode in-process (Claude/ChatGPT subscription)\",\n methods: mastracodeRecipe.methods,\n})\n\n/** Gemini CLI OAuth token written by the local CLI. */\nexport const geminiRecipe = defineProvisionRecipe({\n id: \"gemini\",\n description:\n \"Google Gemini CLI OAuth access token, read from the local CLI's credential cache.\",\n label: \"Gemini\",\n methods: [\n {\n id: \"oauth-token\",\n source: {\n file: \"~/.gemini/oauth_creds.json\",\n jsonPath: \"access_token\",\n },\n },\n ],\n})\n\nexport const BUILTIN_RECIPES: readonly ProvisionRecipe[] = [\n claudeCodeOauthRecipe,\n codexRecipe,\n geminiRecipe,\n opencodeRecipe,\n mastracodeRecipe,\n jcodeRecipe,\n mastracodeInprocessRecipe,\n]\n","/**\n * Provision-recipe registry — id → recipe lookup, pre-seeded with the builtins.\n *\n * Mirrors the host-side OAuth-provider registry shape: a module-level Map a\n * caller resolves by id at provision time, plus a `registerRecipe` seam so a\n * host can add recipes parsed from its own `.md` (`parseRecipeManifest`)\n * without editing this package. Re-registering an id overrides it — last write\n * wins, so a host can shadow a builtin.\n */\n\nimport { BUILTIN_RECIPES } from \"./builtins.js\"\nimport type { ProvisionRecipe, RecipeMethod } from \"./types.js\"\n\nconst _registry = new Map<string, ProvisionRecipe>()\nfor (const r of BUILTIN_RECIPES) _registry.set(r.id, r)\n\nexport function registerRecipe(recipe: ProvisionRecipe): void {\n _registry.set(recipe.id, recipe)\n}\n\nexport function getRecipe(id: string): ProvisionRecipe | undefined {\n return _registry.get(id)\n}\n\nexport function listRecipes(): ProvisionRecipe[] {\n return [..._registry.values()]\n}\n\nexport function listRecipeIds(): string[] {\n return [..._registry.keys()]\n}\n\n/**\n * Resolve a recipe + one of its methods. `methodId` selects among the recipe's\n * flavors; omitted picks the first (default). Throws a caller-friendly error\n * naming the available methods when the id is unknown or ambiguous.\n */\nexport function resolveRecipeMethod(\n id: string,\n methodId?: string,\n): { recipe: ProvisionRecipe; method: RecipeMethod } {\n const recipe = getRecipe(id)\n if (!recipe) {\n throw new Error(\n `unknown provider '${id}' — known: ${listRecipeIds().join(\", \") || \"(none)\"}`,\n )\n }\n if (!methodId) {\n return { recipe, method: recipe.methods[0] }\n }\n const method = recipe.methods.find((m) => m.id === methodId)\n if (!method) {\n throw new Error(\n `provider '${id}' has no method '${methodId}' — methods: ${recipe.methods\n .map((m) => m.id)\n .join(\", \")}`,\n )\n }\n return { recipe, method }\n}\n","/**\n * Resolve a recipe method's source to plaintext.\n *\n * A source is a single `CredentialSourceSpec` or an ordered fallback chain\n * (array) — the first that resolves wins, so one recipe spans platforms\n * (macOS Keychain → file). Bridges onto `resolveCredential` (file / env), the\n * macOS `security` Keychain, and an injected prompt impl (interactive, e.g. a\n * website password for a remote browser). The prompt impl is INJECTED — no\n * hard TTY dependency at import, same discipline as `fetchImpl` on\n * `httpTarget`. The result is sensitive: seal it immediately, never print it.\n */\n\nimport { resolveCredential, extractJsonPath } from \"../index.js\"\nimport type { CredentialSourceSpec } from \"./types.js\"\n\nexport interface ResolveSourceOptions {\n /** Asked for a `{ prompt }` source. Receives the prompt text, returns the\n * entered value. Required only when a method uses a prompt source. */\n promptImpl?: (prompt: string) => Promise<string>\n}\n\nexport async function resolveSourceSpec(\n source: CredentialSourceSpec | CredentialSourceSpec[],\n opts: ResolveSourceOptions = {},\n): Promise<string> {\n const chain = Array.isArray(source) ? source : [source]\n const errors: string[] = []\n for (const spec of chain) {\n try {\n return await resolveOne(spec, opts)\n } catch (err) {\n errors.push(err instanceof Error ? err.message : String(err))\n }\n }\n throw new Error(`no credential source resolved (${errors.join(\"; \")})`)\n}\n\nasync function resolveOne(\n source: CredentialSourceSpec,\n opts: ResolveSourceOptions,\n): Promise<string> {\n if (\"env\" in source) {\n return resolveCredential({ fromEnv: source.env })\n }\n if (\"file\" in source) {\n return resolveCredential({\n fromFile: source.file,\n ...(source.jsonPath ? { jsonPath: source.jsonPath } : {}),\n })\n }\n if (\"keychain\" in source) {\n return resolveKeychain(source)\n }\n // prompt\n if (!opts.promptImpl) {\n throw new Error(\n `credential source needs an interactive prompt but no promptImpl was provided`,\n )\n }\n const value = await opts.promptImpl(source.prompt)\n if (!value) throw new Error(\"prompt returned an empty credential\")\n return value\n}\n\nasync function resolveKeychain(source: {\n keychain: string\n account?: string\n jsonPath?: string\n}): Promise<string> {\n if (process.platform !== \"darwin\") {\n throw new Error(\"keychain source is macOS-only\")\n }\n const { execFileSync } = await import(\"node:child_process\")\n const args = [\"find-generic-password\", \"-w\", \"-s\", source.keychain]\n if (source.account) args.push(\"-a\", source.account)\n let raw: string\n try {\n raw = execFileSync(\"security\", args, { encoding: \"utf8\" }).trim()\n } catch {\n throw new Error(`keychain item '${source.keychain}' not found`)\n }\n if (!raw) throw new Error(`keychain item '${source.keychain}' is empty`)\n return source.jsonPath ? extractJsonPath(raw, source.jsonPath) : raw\n}\n"]}
|
package/dist/cli.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { listRecipeIds, resolveRecipeMethod, resolveSourceSpec } from './chunk-
|
|
1
|
+
import { listRecipeIds, resolveRecipeMethod, resolveSourceSpec } from './chunk-MYW7DD7E.mjs';
|
|
2
2
|
import { httpTarget, provisionSealed, resolveCredential } from './chunk-7V6U6DII.mjs';
|
|
3
3
|
import { unseal, seal, generateSealKeyPair, sealKeyId } from './chunk-PCFPJ47T.mjs';
|
|
4
4
|
import './chunk-5HUHYBPR.mjs';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { BUILTIN_RECIPES, claudeCodeOauthRecipe, codexRecipe, credentialSourceSpecSchema, defineProvisionRecipe, geminiRecipe, getRecipe, listRecipeIds, listRecipes, parseRecipeManifest, parseRecipeManifestRaw, provisionRecipeFrontmatterSchema, recipeMethodSchema, registerRecipe, resolveRecipeMethod, resolveSourceSpec } from '../../chunk-
|
|
1
|
+
export { BUILTIN_RECIPES, claudeCodeOauthRecipe, codexRecipe, credentialSourceSpecSchema, defineProvisionRecipe, geminiRecipe, getRecipe, listRecipeIds, listRecipes, parseRecipeManifest, parseRecipeManifestRaw, provisionRecipeFrontmatterSchema, recipeMethodSchema, registerRecipe, resolveRecipeMethod, resolveSourceSpec } from '../../chunk-MYW7DD7E.mjs';
|
|
2
2
|
import '../../chunk-7V6U6DII.mjs';
|
|
3
3
|
import '../../chunk-PCFPJ47T.mjs';
|
|
4
4
|
import '../../chunk-5HUHYBPR.mjs';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentproto/secrets",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "@agentproto/secrets — AIP-19 SECRETS.md reference implementation. A workspace-level manifest format for declaring secret slugs, their purpose, access grants, and audit metadata — without ever storing the values themselves. Hosts resolve slugs against a real vault at reveal time.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agentproto",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/provision/recipe/schema.ts","../src/provision/recipe/define-recipe.ts","../src/provision/recipe/manifest.ts","../src/provision/recipe/builtins.ts","../src/provision/recipe/registry.ts","../src/provision/recipe/resolve.ts"],"names":[],"mappings":"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","file":"chunk-2FHFW2AU.mjs","sourcesContent":["/**\n * Provision-recipe frontmatter / literal zod schema.\n *\n * Single source of truth for both authoring paths: `defineProvisionRecipe`\n * (TS literal) and `parseRecipeManifest` (.md) run this same schema, so a\n * malformed literal and a malformed manifest fail identically — mirrors how\n * `secretsFrontmatterSchema` backs both `defineSecrets` and\n * `parseSecretsManifest`.\n *\n * Hand-written rather than scaffold-aip-generated: a recipe is not yet a\n * numbered-AIP artifact. Promote to a generated schema if it gets its own spec.\n */\n\nimport { z } from \"zod\"\n\n/** Exactly one of file / env / keychain / prompt. `value` is explicitly\n * forbidden — a recipe carries locations, never secrets. */\nexport const credentialSourceSpecSchema = z\n .union([\n z\n .object({\n file: z.string().min(1),\n jsonPath: z.string().min(1).optional(),\n })\n .strict(),\n z.object({ env: z.string().min(1) }).strict(),\n z\n .object({\n keychain: z.string().min(1),\n account: z.string().min(1).optional(),\n jsonPath: z.string().min(1).optional(),\n })\n .strict(),\n z.object({ prompt: z.string().min(1) }).strict(),\n ])\n .describe(\n \"Where a method's credential is read on the origin machine: a file (optionally a JSON field), an env var, the macOS Keychain, or an interactive prompt. Never a literal value.\",\n )\n\n/** A method's source: a single spec or an ordered fallback chain (first that\n * resolves wins). */\nexport const methodSourceSchema = z.union([\n credentialSourceSpecSchema,\n z.array(credentialSourceSpecSchema).min(1),\n])\n\nexport const recipeMethodSchema = z\n .object({\n id: z.string().min(1),\n label: z.string().min(1).optional(),\n source: methodSourceSchema,\n })\n .strict()\n\nexport const provisionRecipeFrontmatterSchema = z\n .object({\n id: z.string().min(2).max(80),\n description: z.string().min(1).max(2000),\n methods: z.array(recipeMethodSchema).min(1),\n label: z.string().min(1).optional(),\n })\n .strict()\n .describe(\n \"A credential-provision recipe: for one provider, the installable flavors (methods) and where each flavor's credential lives locally. Holds locations, never values.\",\n )\n\nexport type ProvisionRecipeFrontmatter = z.infer<\n typeof provisionRecipeFrontmatterSchema\n>\n","/**\n * `defineProvisionRecipe` — the TS-literal authoring path for a recipe.\n *\n * Built on `createDoctype` so a recipe gets the same cross-AIP invariants as\n * every other doctype: id-pattern check, ≤2000-char description, frozen handle,\n * canonical \"defineProvisionRecipe (AIP-19): …\" error prefix. Field-level\n * validation runs the shared zod from `./schema.ts`, so a malformed literal\n * fails with the same diagnostic as a malformed `.md`.\n */\n\nimport { createDoctype } from \"@agentproto/define-doctype\"\nimport { provisionRecipeFrontmatterSchema } from \"./schema.js\"\nimport type {\n ProvisionRecipe,\n ProvisionRecipeDefinition,\n} from \"./types.js\"\n\nexport const defineProvisionRecipe = createDoctype<\n ProvisionRecipeDefinition,\n ProvisionRecipe\n>({\n aip: 19,\n name: \"provisionRecipe\",\n validate(def) {\n const result = provisionRecipeFrontmatterSchema.safeParse(def)\n if (!result.success) {\n throw new Error(\n `defineProvisionRecipe (AIP-19): ${result.error.issues\n .map((i) => `${i.path.join(\".\")}: ${i.message}`)\n .join(\"; \")}`,\n )\n }\n },\n build(def) {\n return {\n ...def,\n methods: def.methods.map((m) => Object.freeze({ ...m })) as ProvisionRecipe[\"methods\"],\n }\n },\n})\n","/**\n * `.md` authoring path for a provision recipe — parse a frontmatter manifest\n * into a frozen handle. Mirrors `parseSecretsManifest`: gray-matter splits the\n * frontmatter, the shared zod validates it, `defineProvisionRecipe` builds the\n * handle so the `.md` and TS-literal paths converge on one validated shape.\n *\n * The package ships its builtin recipes as TS literals (they bundle with zero\n * fs); this parser is for a HOST that reads its own external `.md` recipes and\n * registers them — the extension seam.\n */\n\nimport matter from \"gray-matter\"\nimport {\n provisionRecipeFrontmatterSchema,\n type ProvisionRecipeFrontmatter,\n} from \"./schema.js\"\nimport { defineProvisionRecipe } from \"./define-recipe.js\"\nimport type { ProvisionRecipe, ProvisionRecipeDefinition } from \"./types.js\"\n\nexport interface ProvisionRecipeManifest {\n frontmatter: ProvisionRecipeFrontmatter\n body: string\n}\n\nexport function parseRecipeManifestRaw(\n source: string,\n): ProvisionRecipeManifest {\n const parsed = matter(source)\n if (Object.keys(parsed.data).length === 0) {\n throw new Error(\"parseRecipeManifest: missing or empty frontmatter\")\n }\n const result = provisionRecipeFrontmatterSchema.safeParse(parsed.data)\n if (!result.success) {\n throw new Error(\n `parseRecipeManifest: invalid frontmatter — ${result.error.issues\n .map((i) => `${i.path.join(\".\")}: ${i.message}`)\n .join(\"; \")}`,\n )\n }\n return { frontmatter: result.data, body: parsed.content }\n}\n\n/** Parse a recipe `.md` straight to a frozen handle (frontmatter →\n * `defineProvisionRecipe`). */\nexport function parseRecipeManifest(source: string): ProvisionRecipe {\n const { frontmatter } = parseRecipeManifestRaw(source)\n return defineProvisionRecipe(\n frontmatter as unknown as ProvisionRecipeDefinition,\n )\n}\n","/**\n * Builtin provision recipes — the credential providers the flow knows out of\n * the box. Shipped as TS literals (not `.md`) so they bundle into the tsup\n * output with zero filesystem read at runtime. A host adds more by parsing its\n * own `.md` with `parseRecipeManifest` and `registerRecipe`-ing the result.\n *\n * Each recipe describes the credential's PUBLIC local convention for that CLI\n * (where it writes its token) — no vendor's private infra, no values.\n */\n\nimport { defineProvisionRecipe } from \"./define-recipe.js\"\nimport type { ProvisionRecipe } from \"./types.js\"\n\n/** Claude Code subscription OAuth token. macOS stores it in the login Keychain;\n * Linux writes it to ~/.claude/.credentials.json. Try the Keychain first, fall\n * back to the file, so one recipe spans both. */\nexport const claudeCodeOauthRecipe = defineProvisionRecipe({\n id: \"claude-code-oauth\",\n description:\n \"Claude Code subscription OAuth access token, read from the macOS Keychain or the local CLI's credential file.\",\n label: \"Claude Code (subscription)\",\n methods: [\n {\n id: \"subscription-token\",\n source: [\n {\n keychain: \"Claude Code-credentials\",\n jsonPath: \"claudeAiOauth.accessToken\",\n },\n {\n file: \"~/.claude/.credentials.json\",\n jsonPath: \"claudeAiOauth.accessToken\",\n },\n ],\n },\n ],\n})\n\n/** Codex CLI — two flavors: the subscription OAuth token, or a raw API key. */\nexport const codexRecipe = defineProvisionRecipe({\n id: \"codex\",\n description:\n \"OpenAI Codex CLI credential — either the subscription OAuth access token from the local auth file, or an API key from the environment.\",\n label: \"Codex\",\n methods: [\n {\n id: \"oauth-subscription\",\n label: \"Codex (subscription)\",\n source: { file: \"~/.codex/auth.json\", jsonPath: \"tokens.access_token\" },\n },\n {\n id: \"api-key\",\n label: \"Codex (API key)\",\n source: { env: \"OPENAI_API_KEY\" },\n },\n ],\n})\n\n/** opencode — Anthropic (Claude Pro/Max) OAuth login stored by the CLI's own\n * `opencode auth login` flow. opencode keeps its auth store under the XDG\n * data dir on every platform (macOS included — verified live). The entry\n * shape is `{anthropic: {type: \"oauth\", access, refresh, expires}}`.\n *\n * `openai-oauth` covers opencode's separate \"ChatGPT Pro/Plus\" OAuth login\n * (`opencode auth login` → select provider \"openai\", browser or headless\n * device-code flow against auth.openai.com). Reverse-engineered from the\n * shipped binary (`~/.opencode/bin/opencode`, no OSS source for this build\n * available to read directly): the plugin registers its two OAuth methods\n * under `integrationID: R.ID.make(\"openai\")`, and the generic provider-login\n * handler (`Cli.providers.login` → `Cli.providers.pluginAuth`) writes the\n * credential via `Auth.set(provider.id, {type:\"oauth\", access, refresh,\n * expires, ...})` where `provider.id` is the SAME \"openai\" id the user\n * selected — there is no separate \"chatgpt\" key. This mirrors exactly how\n * the already-verified `anthropic` entry is keyed by provider id, so the\n * ChatGPT login lands at `openai.access` in the same auth.json. */\nexport const opencodeRecipe = defineProvisionRecipe({\n id: \"opencode\",\n description:\n \"opencode's Claude Pro/Max and ChatGPT Pro/Plus subscription OAuth access tokens, read from the CLI's own auth store (written by `opencode auth login`).\",\n label: \"opencode (Claude/ChatGPT subscription)\",\n methods: [\n {\n id: \"anthropic-oauth\",\n source: {\n file: \"~/.local/share/opencode/auth.json\",\n jsonPath: \"anthropic.access\",\n },\n },\n {\n id: \"openai-oauth\",\n source: {\n file: \"~/.local/share/opencode/auth.json\",\n jsonPath: \"openai.access\",\n },\n },\n ],\n})\n\n/** mastracode — two independent OAuth logins from the TUI's own `/login`\n * flow. mastracode's app-data dir is platform-dependent (`getAppDataDir()`\n * in its source: Application Support on macOS, XDG data dir elsewhere).\n *\n * `anthropic-oauth`: Claude Pro/Max login, entry shape `{anthropic:\n * {type: \"oauth\", access, refresh, expires}}` — verified against a live\n * login.\n *\n * `openai-oauth`: ChatGPT login via mastracode's `openaiCodexOAuthProvider`,\n * stored under the DISTINCT key `openai-codex` (not `openai` — mastracode's\n * own naming, unrelated to opencode's), entry shape `{\"openai-codex\":\n * {type: \"oauth\", access, refresh, expires, accountId}}` — also verified\n * against a live login on this machine. */\nexport const mastracodeRecipe = defineProvisionRecipe({\n id: \"mastracode\",\n description:\n \"mastracode's Claude Pro/Max and ChatGPT subscription OAuth access tokens, read from the CLI's own auth store (written by its /login flow).\",\n label: \"mastracode (Claude/ChatGPT subscription)\",\n methods: [\n {\n id: \"anthropic-oauth\",\n source: [\n {\n file: \"~/Library/Application Support/mastracode/auth.json\",\n jsonPath: \"anthropic.access\",\n },\n {\n file: \"~/.local/share/mastracode/auth.json\",\n jsonPath: \"anthropic.access\",\n },\n ],\n },\n {\n id: \"openai-oauth\",\n source: [\n {\n file: \"~/Library/Application Support/mastracode/auth.json\",\n jsonPath: \"openai-codex.access\",\n },\n {\n file: \"~/.local/share/mastracode/auth.json\",\n jsonPath: \"openai-codex.access\",\n },\n ],\n },\n ],\n})\n\n/** Gemini CLI OAuth token written by the local CLI. */\nexport const geminiRecipe = defineProvisionRecipe({\n id: \"gemini\",\n description:\n \"Google Gemini CLI OAuth access token, read from the local CLI's credential cache.\",\n label: \"Gemini\",\n methods: [\n {\n id: \"oauth-token\",\n source: {\n file: \"~/.gemini/oauth_creds.json\",\n jsonPath: \"access_token\",\n },\n },\n ],\n})\n\nexport const BUILTIN_RECIPES: readonly ProvisionRecipe[] = [\n claudeCodeOauthRecipe,\n codexRecipe,\n geminiRecipe,\n opencodeRecipe,\n mastracodeRecipe,\n]\n","/**\n * Provision-recipe registry — id → recipe lookup, pre-seeded with the builtins.\n *\n * Mirrors the host-side OAuth-provider registry shape: a module-level Map a\n * caller resolves by id at provision time, plus a `registerRecipe` seam so a\n * host can add recipes parsed from its own `.md` (`parseRecipeManifest`)\n * without editing this package. Re-registering an id overrides it — last write\n * wins, so a host can shadow a builtin.\n */\n\nimport { BUILTIN_RECIPES } from \"./builtins.js\"\nimport type { ProvisionRecipe, RecipeMethod } from \"./types.js\"\n\nconst _registry = new Map<string, ProvisionRecipe>()\nfor (const r of BUILTIN_RECIPES) _registry.set(r.id, r)\n\nexport function registerRecipe(recipe: ProvisionRecipe): void {\n _registry.set(recipe.id, recipe)\n}\n\nexport function getRecipe(id: string): ProvisionRecipe | undefined {\n return _registry.get(id)\n}\n\nexport function listRecipes(): ProvisionRecipe[] {\n return [..._registry.values()]\n}\n\nexport function listRecipeIds(): string[] {\n return [..._registry.keys()]\n}\n\n/**\n * Resolve a recipe + one of its methods. `methodId` selects among the recipe's\n * flavors; omitted picks the first (default). Throws a caller-friendly error\n * naming the available methods when the id is unknown or ambiguous.\n */\nexport function resolveRecipeMethod(\n id: string,\n methodId?: string,\n): { recipe: ProvisionRecipe; method: RecipeMethod } {\n const recipe = getRecipe(id)\n if (!recipe) {\n throw new Error(\n `unknown provider '${id}' — known: ${listRecipeIds().join(\", \") || \"(none)\"}`,\n )\n }\n if (!methodId) {\n return { recipe, method: recipe.methods[0] }\n }\n const method = recipe.methods.find((m) => m.id === methodId)\n if (!method) {\n throw new Error(\n `provider '${id}' has no method '${methodId}' — methods: ${recipe.methods\n .map((m) => m.id)\n .join(\", \")}`,\n )\n }\n return { recipe, method }\n}\n","/**\n * Resolve a recipe method's source to plaintext.\n *\n * A source is a single `CredentialSourceSpec` or an ordered fallback chain\n * (array) — the first that resolves wins, so one recipe spans platforms\n * (macOS Keychain → file). Bridges onto `resolveCredential` (file / env), the\n * macOS `security` Keychain, and an injected prompt impl (interactive, e.g. a\n * website password for a remote browser). The prompt impl is INJECTED — no\n * hard TTY dependency at import, same discipline as `fetchImpl` on\n * `httpTarget`. The result is sensitive: seal it immediately, never print it.\n */\n\nimport { resolveCredential, extractJsonPath } from \"../index.js\"\nimport type { CredentialSourceSpec } from \"./types.js\"\n\nexport interface ResolveSourceOptions {\n /** Asked for a `{ prompt }` source. Receives the prompt text, returns the\n * entered value. Required only when a method uses a prompt source. */\n promptImpl?: (prompt: string) => Promise<string>\n}\n\nexport async function resolveSourceSpec(\n source: CredentialSourceSpec | CredentialSourceSpec[],\n opts: ResolveSourceOptions = {},\n): Promise<string> {\n const chain = Array.isArray(source) ? source : [source]\n const errors: string[] = []\n for (const spec of chain) {\n try {\n return await resolveOne(spec, opts)\n } catch (err) {\n errors.push(err instanceof Error ? err.message : String(err))\n }\n }\n throw new Error(`no credential source resolved (${errors.join(\"; \")})`)\n}\n\nasync function resolveOne(\n source: CredentialSourceSpec,\n opts: ResolveSourceOptions,\n): Promise<string> {\n if (\"env\" in source) {\n return resolveCredential({ fromEnv: source.env })\n }\n if (\"file\" in source) {\n return resolveCredential({\n fromFile: source.file,\n ...(source.jsonPath ? { jsonPath: source.jsonPath } : {}),\n })\n }\n if (\"keychain\" in source) {\n return resolveKeychain(source)\n }\n // prompt\n if (!opts.promptImpl) {\n throw new Error(\n `credential source needs an interactive prompt but no promptImpl was provided`,\n )\n }\n const value = await opts.promptImpl(source.prompt)\n if (!value) throw new Error(\"prompt returned an empty credential\")\n return value\n}\n\nasync function resolveKeychain(source: {\n keychain: string\n account?: string\n jsonPath?: string\n}): Promise<string> {\n if (process.platform !== \"darwin\") {\n throw new Error(\"keychain source is macOS-only\")\n }\n const { execFileSync } = await import(\"node:child_process\")\n const args = [\"find-generic-password\", \"-w\", \"-s\", source.keychain]\n if (source.account) args.push(\"-a\", source.account)\n let raw: string\n try {\n raw = execFileSync(\"security\", args, { encoding: \"utf8\" }).trim()\n } catch {\n throw new Error(`keychain item '${source.keychain}' not found`)\n }\n if (!raw) throw new Error(`keychain item '${source.keychain}' is empty`)\n return source.jsonPath ? extractJsonPath(raw, source.jsonPath) : raw\n}\n"]}
|