| import type { ToolAnnotation } from "./route-types.js"; | ||
| /** Reserved top-level command names a generated domain may never take (spec S1). */ | ||
| export declare const RESERVED_TOP_LEVEL_NAMES: ReadonlySet<string>; | ||
| /** Reserved global flags a generated per-tool flag may never collide with (spec S1). */ | ||
| export declare const RESERVED_FLAGS: ReadonlySet<string>; | ||
| export declare const TOOL_ANNOTATIONS: Readonly<Record<string, ToolAnnotation>>; |
| // The baked-in Annotation Table (spec 051 S1), keyed by tool name. Everything | ||
| // the CLI needs beyond the four `tools/list` wire fields lives here: the | ||
| // command path, the client-side scope for the precheck, the list `itemsKey`, | ||
| // single-read flip props, windowed-text/paginationless markers, and the | ||
| // `manage_organization` discriminator split. Encoded as plain data so both the | ||
| // build-time codegen and (later) a runtime path can import it. | ||
| // | ||
| // `scope` is the UNPREFIXED form from `route-types.ts`; the scope precheck | ||
| // prefixes it with `stella:` before comparing against the decoded token. | ||
| /** Reserved top-level command names a generated domain may never take (spec S1). */ | ||
| export const RESERVED_TOP_LEVEL_NAMES = new Set([ | ||
| "auth", | ||
| "tools", | ||
| "reference", | ||
| "help", | ||
| "version", | ||
| "completion", | ||
| "config", | ||
| ]); | ||
| /** Reserved global flags a generated per-tool flag may never collide with (spec S1). */ | ||
| export const RESERVED_FLAGS = new Set([ | ||
| "--output", | ||
| "--json", | ||
| "--table", | ||
| "--input", | ||
| "--yes", | ||
| "-y", | ||
| "--all", | ||
| "--cursor", | ||
| "--limit", | ||
| "--org", | ||
| "--no-keychain", | ||
| "--server", | ||
| "--help", | ||
| "-h", | ||
| "--version", | ||
| ]); | ||
| export const TOOL_ANNOTATIONS = { | ||
| // --- compat shims: excluded from the tree entirely (spec S1) --- | ||
| search: { command: ["search"], excluded: true, scope: "search" }, | ||
| fetch: { command: ["fetch"], excluded: true, scope: "read" }, | ||
| // --- matter domain --- | ||
| save_matter: { command: ["matter", "save"], scope: "matters_write" }, | ||
| delete_matter: { command: ["matter", "delete"], scope: "matters_write" }, | ||
| list_matters: { | ||
| command: ["matter", "list"], | ||
| scope: "read", | ||
| itemsKey: "matters", | ||
| singleReadWhen: "matter_id", | ||
| }, | ||
| link_matter_contact: { | ||
| command: ["matter", "link-contact"], | ||
| scope: "matters_write", | ||
| }, | ||
| // --- contact domain --- | ||
| save_contact: { command: ["contact", "save"], scope: "matters_write" }, | ||
| delete_contact: { command: ["contact", "delete"], scope: "matters_write" }, | ||
| read_contact: { command: ["contact", "read"], scope: "read" }, | ||
| lookup_business_registry: { | ||
| command: ["contact", "lookup-registry"], | ||
| scope: "read", | ||
| }, | ||
| // --- task domain --- | ||
| list_tasks: { | ||
| command: ["task", "list"], | ||
| scope: "read", | ||
| itemsKey: "tasks", | ||
| singleReadWhen: "task_id", | ||
| }, | ||
| save_task: { command: ["task", "save"], scope: "matters_write" }, | ||
| // --- document domain --- | ||
| list_documents: { | ||
| command: ["document", "list"], | ||
| scope: "read", | ||
| itemsKey: "documents", | ||
| }, | ||
| read_document: { command: ["document", "read"], scope: "read" }, | ||
| save_document: { command: ["document", "save"], scope: "documents_write" }, | ||
| delete_document: { | ||
| command: ["document", "delete"], | ||
| scope: "documents_write", | ||
| }, | ||
| list_properties: { | ||
| command: ["document", "properties", "list"], | ||
| scope: "read", | ||
| itemsKey: "properties", | ||
| }, | ||
| set_field_value: { | ||
| command: ["document", "field", "set"], | ||
| scope: "documents_write", | ||
| }, | ||
| // --- knowledge domain --- | ||
| list_clauses: { | ||
| command: ["clause", "list"], | ||
| scope: "read", | ||
| // Registry payload key is `clauses` (spec table says `items`; registry wins). | ||
| itemsKey: "clauses", | ||
| singleReadWhen: "clause_id", | ||
| }, | ||
| save_clause: { command: ["clause", "save"], scope: "knowledge_write" }, | ||
| delete_clause: { command: ["clause", "delete"], scope: "knowledge_write" }, | ||
| list_playbooks: { | ||
| command: ["playbook", "list"], | ||
| scope: "read", | ||
| itemsKey: "items", | ||
| singleReadWhen: "playbook_id", | ||
| }, | ||
| run_playbook: { command: ["playbook", "run"], scope: "knowledge_write" }, | ||
| // --- cross-matter search / read --- | ||
| search_across_matters: { | ||
| command: ["search", "matters"], | ||
| scope: "search", | ||
| itemsKey: "hits", | ||
| }, | ||
| read_content_across_matters: { | ||
| command: ["search", "read"], | ||
| scope: "read", | ||
| windowedText: true, | ||
| }, | ||
| search_case_law: { | ||
| command: ["case-law", "search"], | ||
| scope: "search", | ||
| itemsKey: "results", | ||
| }, | ||
| read_case_law_decision: { | ||
| command: ["case-law", "read"], | ||
| scope: "read", | ||
| windowedText: true, | ||
| }, | ||
| // --- organization onboarding --- | ||
| set_practice_jurisdictions: { | ||
| command: ["organization", "set-jurisdictions"], | ||
| scope: "onboarding", | ||
| }, | ||
| // --- templates --- | ||
| list_templates: { | ||
| command: ["template", "list"], | ||
| scope: "templates", | ||
| itemsKey: "templates", | ||
| paginationless: true, | ||
| singleReadWhen: "template_id", | ||
| }, | ||
| fill_template: { command: ["template", "fill"], scope: "templates" }, | ||
| save_template: { command: ["template", "save"], scope: "templates" }, | ||
| // --- billing --- | ||
| list_time_entries: { | ||
| command: ["time-entry", "list"], | ||
| scope: "read", | ||
| itemsKey: "entries", | ||
| singleReadWhen: "time_entry_id", | ||
| }, | ||
| save_time_entry: { | ||
| command: ["time-entry", "save"], | ||
| scope: "billing_write", | ||
| }, | ||
| delete_time_entry: { | ||
| command: ["time-entry", "delete"], | ||
| scope: "billing_write", | ||
| }, | ||
| resolve_rate: { command: ["rate", "resolve"], scope: "read" }, | ||
| list_invoices: { | ||
| command: ["invoice", "list"], | ||
| scope: "read", | ||
| itemsKey: "invoices", | ||
| singleReadWhen: "invoice_id", | ||
| }, | ||
| get_usage: { command: ["usage", "get"], scope: "read" }, | ||
| // --- research / admin --- | ||
| search_legislation: { | ||
| command: ["legislation", "search"], | ||
| scope: "read", | ||
| // Multi-shape payload (list vs single block vs related); the search-mode | ||
| // list array key is `items`. Read-mode responses render as single objects. | ||
| itemsKey: "items", | ||
| }, | ||
| list_audit_log: { | ||
| command: ["audit-log", "list"], | ||
| scope: "admin_read", | ||
| itemsKey: "items", | ||
| }, | ||
| manage_organization: { | ||
| command: ["organization"], | ||
| scope: "admin_write", | ||
| discriminator: { | ||
| prop: "action", | ||
| subcommands: { | ||
| add_member: { | ||
| command: "add-member", | ||
| include: ["matter_id", "user_id"], | ||
| required: ["matter_id", "user_id"], | ||
| }, | ||
| remove_member: { | ||
| command: "remove-member", | ||
| include: ["matter_id", "user_id"], | ||
| required: ["matter_id", "user_id"], | ||
| destructive: true, | ||
| }, | ||
| update_org_settings: { | ||
| command: "update-settings", | ||
| include: [ | ||
| "matter_number_pattern", | ||
| "matter_number_padding", | ||
| "prompt_caching_enabled", | ||
| ], | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| }; | ||
| //# sourceMappingURL=annotations.js.map |
| {"version":3,"file":"annotations.js","sourceRoot":"","sources":["../src/annotations.ts"],"names":[],"mappings":"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"} |
| export declare const openInBrowser: (url: string) => Promise<boolean>; |
| // Best-effort system-browser launch. Never throws: the printed URL is always | ||
| // the fallback (see `login.ts`), so a failure here is not fatal. Uses | ||
| // `node:child_process` `spawn` so the published CLI runs under plain Node. | ||
| import { spawn } from "node:child_process"; | ||
| const OPEN_TIMEOUT_MS = 5000; | ||
| const openCommandFor = (platform) => { | ||
| if (platform === "darwin") { | ||
| return ["open"]; | ||
| } | ||
| if (platform === "win32") { | ||
| return ["cmd", "/c", "start", ""]; | ||
| } | ||
| return ["xdg-open"]; | ||
| }; | ||
| export const openInBrowser = async (url) => { | ||
| const command = openCommandFor(process.platform); | ||
| if (!command) { | ||
| return false; | ||
| } | ||
| // `command` always has at least one element (see `openCommandFor`); append | ||
| // the URL as the final argument, matching the old `[...command, url]` spawn. | ||
| const [file, ...args] = [...command, url]; | ||
| // Detached + `stdio: "ignore"` decouples the launched browser from the CLI | ||
| // (the old `Bun.spawn` ignored all three streams too); a bound `error` | ||
| // handler keeps an async spawn failure (ENOENT) from throwing on the emitter. | ||
| const child = spawn(file, args, { detached: true, stdio: "ignore" }); | ||
| // Mirror the old logic: succeed on a zero exit code, fail on a spawn error, | ||
| // and bound the wait so a hung opener can never stall the CLI. Each executor | ||
| // resolves exactly once; `Promise.race` takes whichever settles first. | ||
| let timer; | ||
| const exited = new Promise((resolve) => { | ||
| child.on("exit", (code) => resolve(code === 0)); | ||
| }); | ||
| const errored = new Promise((resolve) => { | ||
| child.on("error", () => resolve(false)); | ||
| }); | ||
| const timedOut = new Promise((resolve) => { | ||
| timer = setTimeout(() => resolve(false), OPEN_TIMEOUT_MS); | ||
| }); | ||
| try { | ||
| return await Promise.race([exited, errored, timedOut]); | ||
| } | ||
| finally { | ||
| clearTimeout(timer); | ||
| } | ||
| }; | ||
| //# sourceMappingURL=browser-open.js.map |
| {"version":3,"file":"browser-open.js","sourceRoot":"","sources":["../../src/auth/browser-open.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,sEAAsE;AACtE,2EAA2E;AAE3E,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,MAAM,eAAe,GAAG,IAAI,CAAC;AAE7B,MAAM,cAAc,GAAG,CACrB,QAAyB,EACM,EAAE;IACjC,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1B,OAAO,CAAC,MAAM,CAAC,CAAC;IAClB,CAAC;IACD,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,CAAC,UAAU,CAAC,CAAC;AACtB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAAE,GAAW,EAAoB,EAAE;IACnE,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,KAAK,CAAC;IACf,CAAC;IAED,2EAA2E;IAC3E,6EAA6E;IAC7E,MAAM,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,EAAE,GAAG,CAAC,CAAC;IAE1C,2EAA2E;IAC3E,uEAAuE;IACvE,8EAA8E;IAC9E,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IAErE,4EAA4E;IAC5E,6EAA6E;IAC7E,uEAAuE;IACvE,IAAI,KAAgD,CAAC;IACrD,MAAM,MAAM,GAAG,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,EAAE;QAC9C,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,EAAE;QAC/C,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,EAAE;QAChD,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,eAAe,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;IACzD,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;AACH,CAAC,CAAC"} |
| import { defaultConfigDir, resolveConfigDir } from "./config-dir.js"; | ||
| import type { ConfigPathOverrides } from "./config-dir.js"; | ||
| export { defaultConfigDir, resolveConfigDir }; | ||
| export type { ConfigPathOverrides }; | ||
| export type CliConfig = { | ||
| readonly version: 1; | ||
| readonly defaultServerUrl?: string | undefined; | ||
| readonly oauthClients: Readonly<Record<string, { | ||
| readonly clientId: string; | ||
| readonly registeredAt: number; | ||
| }>>; | ||
| }; | ||
| export declare const configFilePath: (configDir: string) => string; | ||
| export declare const readCliConfig: (configDir: string) => Promise<CliConfig>; | ||
| export declare const writeCliConfig: (configDir: string, config: CliConfig) => Promise<void>; | ||
| export declare const setDefaultServerUrl: (configDir: string, serverUrl: string) => Promise<void>; | ||
| export declare const getRegisteredClientId: (configDir: string, serverUrl: string) => Promise<string | undefined>; | ||
| export declare const setRegisteredClientId: (configDir: string, serverUrl: string, clientId: string) => Promise<void>; |
| // Non-secret CLI configuration: the default server origin and, per server, | ||
| // the dynamically-registered OAuth client id (a public client id is not a | ||
| // secret; there is no client_secret for `token_endpoint_auth_method: "none"` | ||
| // clients). Stored separately from `credential-store.ts`'s file, which holds | ||
| // tokens and is mode 0600. | ||
| import { Result } from "better-result"; | ||
| import { mkdir, readFile, writeFile } from "node:fs/promises"; | ||
| import path from "node:path"; | ||
| import * as v from "valibot"; | ||
| import { defaultConfigDir, resolveConfigDir } from "./config-dir.js"; | ||
| export { defaultConfigDir, resolveConfigDir }; | ||
| const oauthClientEntrySchema = v.strictObject({ | ||
| clientId: v.string(), | ||
| registeredAt: v.number(), | ||
| }); | ||
| const cliConfigSchema = v.strictObject({ | ||
| version: v.literal(1), | ||
| defaultServerUrl: v.optional(v.string()), | ||
| oauthClients: v.record(v.string(), oauthClientEntrySchema), | ||
| }); | ||
| const EMPTY_CONFIG = { oauthClients: {}, version: 1 }; | ||
| export const configFilePath = (configDir) => path.join(configDir, "config.json"); | ||
| export const readCliConfig = async (configDir) => { | ||
| // A missing, corrupt, or empty config file must degrade to defaults, not | ||
| // crash every CLI invocation at context construction. | ||
| const raw = await Result.tryPromise(async () => await readFile(configFilePath(configDir), "utf-8")); | ||
| if (Result.isError(raw)) { | ||
| return EMPTY_CONFIG; | ||
| } | ||
| const parsedJson = Result.try(() => JSON.parse(raw.value)); | ||
| if (Result.isError(parsedJson)) { | ||
| return EMPTY_CONFIG; | ||
| } | ||
| const parsed = v.safeParse(cliConfigSchema, parsedJson.value); | ||
| return parsed.success ? parsed.output : EMPTY_CONFIG; | ||
| }; | ||
| export const writeCliConfig = async (configDir, config) => { | ||
| // `Bun.write` created the parent directory implicitly; `node:fs` `writeFile` | ||
| // does not. Mirror `credential-store.ts`'s 0700 config dir (both files live | ||
| // in the same `~/.config/stella` directory). | ||
| await mkdir(configDir, { mode: 0o700, recursive: true }); | ||
| await writeFile(configFilePath(configDir), `${JSON.stringify(config, null, 2)}\n`); | ||
| }; | ||
| export const setDefaultServerUrl = async (configDir, serverUrl) => { | ||
| const config = await readCliConfig(configDir); | ||
| await writeCliConfig(configDir, { ...config, defaultServerUrl: serverUrl }); | ||
| }; | ||
| export const getRegisteredClientId = async (configDir, serverUrl) => { | ||
| const config = await readCliConfig(configDir); | ||
| return config.oauthClients[serverUrl]?.clientId; | ||
| }; | ||
| export const setRegisteredClientId = async (configDir, serverUrl, clientId) => { | ||
| const config = await readCliConfig(configDir); | ||
| await writeCliConfig(configDir, { | ||
| ...config, | ||
| oauthClients: { | ||
| ...config.oauthClients, | ||
| [serverUrl]: { clientId, registeredAt: Date.now() }, | ||
| }, | ||
| }); | ||
| }; | ||
| //# sourceMappingURL=cli-config.js.map |
| {"version":3,"file":"cli-config.js","sourceRoot":"","sources":["../../src/auth/cli-config.ts"],"names":[],"mappings":"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"} |
| export type ConfigPathOverrides = { | ||
| readonly xdgConfigHome?: string | undefined; | ||
| readonly homeDir: string; | ||
| }; | ||
| /** `$XDG_CONFIG_HOME/stella` or `~/.config/stella`, per the XDG base dir spec. */ | ||
| export declare const resolveConfigDir: (overrides: ConfigPathOverrides) => string; | ||
| export declare const defaultConfigDir: () => string; |
| // Shared `~/.config/stella` (XDG) directory resolution, used by both | ||
| // `cli-config.ts` (non-secret config) and `credential-store.ts` (secrets). | ||
| import os from "node:os"; | ||
| import path from "node:path"; | ||
| import { XDG_CONFIG_HOME } from "../env.js"; | ||
| /** `$XDG_CONFIG_HOME/stella` or `~/.config/stella`, per the XDG base dir spec. */ | ||
| export const resolveConfigDir = (overrides) => { | ||
| const base = overrides.xdgConfigHome && overrides.xdgConfigHome.length > 0 | ||
| ? overrides.xdgConfigHome | ||
| : path.join(overrides.homeDir, ".config"); | ||
| return path.join(base, "stella"); | ||
| }; | ||
| export const defaultConfigDir = () => resolveConfigDir({ | ||
| homeDir: os.homedir(), | ||
| xdgConfigHome: XDG_CONFIG_HOME, | ||
| }); | ||
| //# sourceMappingURL=config-dir.js.map |
| {"version":3,"file":"config-dir.js","sourceRoot":"","sources":["../../src/auth/config-dir.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,2EAA2E;AAE3E,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAO5C,kFAAkF;AAClF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,SAA8B,EAAU,EAAE;IACzE,MAAM,IAAI,GACR,SAAS,CAAC,aAAa,IAAI,SAAS,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC;QAC3D,CAAC,CAAC,SAAS,CAAC,aAAa;QACzB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAC9C,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AACnC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAW,EAAE,CAC3C,gBAAgB,CAAC;IACf,OAAO,EAAE,EAAE,CAAC,OAAO,EAAE;IACrB,aAAa,EAAE,eAAe;CAC/B,CAAC,CAAC"} |
| /** | ||
| * The OAuth resource (`RFC 8707`) the CLI requests. Passing `resource` at the | ||
| * token endpoint is what makes better-auth's oauth-provider mint a JWT-format | ||
| * access token (see `checkResource`/`isJwtAccessToken` in | ||
| * `@better-auth/oauth-provider`); without it the server returns an opaque | ||
| * token that the CLI cannot decode for `stella auth whoami`. | ||
| */ | ||
| export declare const getMcpResourceUrl: (serverUrl: string) => string; | ||
| /** | ||
| * Candidate RFC 8414 authorization-server-metadata paths, tried in order. | ||
| * The first is the spec's root-issuer convention; the second matches | ||
| * better-auth's actual (default `/api/auth`) mount point, which is what | ||
| * stella's own server uses today. Self-hosted forks that change | ||
| * `advanced.basePath` are covered as long as they keep one of these two | ||
| * shapes; forks using a third convention are a follow-up, not a Phase 2 gap. | ||
| */ | ||
| export declare const AUTHORIZATION_SERVER_METADATA_PATHS: readonly ["/.well-known/oauth-authorization-server", "/api/auth/.well-known/oauth-authorization-server"]; | ||
| /** | ||
| * Loopback redirect URI registered with the OAuth client. Deliberately has no | ||
| * port: better-auth's redirect-uri matcher (`isLoopbackIP` in | ||
| * `@better-auth/core/utils/host`) only compares hostname/pathname/protocol/ | ||
| * search for loopback hosts, never the port (RFC 8252 S7.3). Registering a | ||
| * portless URI once lets every login reuse the same client registration with | ||
| * a fresh ephemeral port each run. | ||
| */ | ||
| export declare const LOOPBACK_REDIRECT_PATH = "/callback"; | ||
| export declare const LOOPBACK_REDIRECT_URI: string; | ||
| /** Default scopes requested when `stella auth login` is run without `--scopes`. */ | ||
| export declare const CLI_DEFAULT_SCOPES: readonly ["openid", "profile", "email", "stella:read", "stella:search"]; | ||
| /** Every OAuth scope `stella auth login --scopes` is documented to accept. */ | ||
| export declare const CLI_KNOWN_SCOPES: readonly ["openid", "profile", "email", "stella:search", "stella:read", "stella:templates", "stella:documents_write", "stella:matters_write", "stella:knowledge_write", "stella:billing_write", "stella:admin_read", "stella:admin_write", "stella:onboarding", "stella:skills", "stella:external_mcps"]; | ||
| export declare const CLIENT_NAME = "stella-cli"; | ||
| /** `--server` resolution: env var name, checked between the flag and the config file. */ | ||
| export declare const SERVER_URL_ENV_VAR = "STELLA_SERVER_URL"; | ||
| /** How long the CLI waits for the browser round-trip before giving up. */ | ||
| export declare const LOGIN_TIMEOUT_MS: number; | ||
| /** Network timeout for every discovery/registration/token request the CLI makes. */ | ||
| export declare const AUTH_FETCH_TIMEOUT_MS = 10000; |
| // Shared literal constants for the `stella auth` flow (spec 051 Phase 2). | ||
| // | ||
| // Several of these intentionally duplicate values owned by `apps/api` | ||
| // (`apps/api/src/mcp/constants.ts`, `apps/api/src/lib/auth.ts`). `packages/cli` | ||
| // cannot import from `apps/api` (apps depend on packages, never the reverse), | ||
| // and the MCP tool registry does not yet expose these as data the CLI could | ||
| // fetch at runtime. This is the same hand-duplication already accepted for | ||
| // `ToolScope` in `../route-types.ts`; keep both sides in sync by hand until a | ||
| // shared package exists. | ||
| /** Mirrors `apps/api/src/mcp/constants.ts`'s `MCP_HTTP_PATH`. */ | ||
| const MCP_HTTP_PATH = "/mcp"; | ||
| /** | ||
| * The OAuth resource (`RFC 8707`) the CLI requests. Passing `resource` at the | ||
| * token endpoint is what makes better-auth's oauth-provider mint a JWT-format | ||
| * access token (see `checkResource`/`isJwtAccessToken` in | ||
| * `@better-auth/oauth-provider`); without it the server returns an opaque | ||
| * token that the CLI cannot decode for `stella auth whoami`. | ||
| */ | ||
| export const getMcpResourceUrl = (serverUrl) => new URL(MCP_HTTP_PATH, serverUrl).toString(); | ||
| /** | ||
| * Candidate RFC 8414 authorization-server-metadata paths, tried in order. | ||
| * The first is the spec's root-issuer convention; the second matches | ||
| * better-auth's actual (default `/api/auth`) mount point, which is what | ||
| * stella's own server uses today. Self-hosted forks that change | ||
| * `advanced.basePath` are covered as long as they keep one of these two | ||
| * shapes; forks using a third convention are a follow-up, not a Phase 2 gap. | ||
| */ | ||
| export const AUTHORIZATION_SERVER_METADATA_PATHS = [ | ||
| "/.well-known/oauth-authorization-server", | ||
| "/api/auth/.well-known/oauth-authorization-server", | ||
| ]; | ||
| /** | ||
| * Loopback redirect URI registered with the OAuth client. Deliberately has no | ||
| * port: better-auth's redirect-uri matcher (`isLoopbackIP` in | ||
| * `@better-auth/core/utils/host`) only compares hostname/pathname/protocol/ | ||
| * search for loopback hosts, never the port (RFC 8252 S7.3). Registering a | ||
| * portless URI once lets every login reuse the same client registration with | ||
| * a fresh ephemeral port each run. | ||
| */ | ||
| export const LOOPBACK_REDIRECT_PATH = "/callback"; | ||
| export const LOOPBACK_REDIRECT_URI = `http://127.0.0.1${LOOPBACK_REDIRECT_PATH}`; | ||
| /** Default scopes requested when `stella auth login` is run without `--scopes`. */ | ||
| export const CLI_DEFAULT_SCOPES = [ | ||
| "openid", | ||
| "profile", | ||
| "email", | ||
| "stella:read", | ||
| "stella:search", | ||
| ]; | ||
| /** Every OAuth scope `stella auth login --scopes` is documented to accept. */ | ||
| export const CLI_KNOWN_SCOPES = [ | ||
| "openid", | ||
| "profile", | ||
| "email", | ||
| "stella:search", | ||
| "stella:read", | ||
| "stella:templates", | ||
| "stella:documents_write", | ||
| "stella:matters_write", | ||
| "stella:knowledge_write", | ||
| "stella:billing_write", | ||
| "stella:admin_read", | ||
| "stella:admin_write", | ||
| "stella:onboarding", | ||
| "stella:skills", | ||
| "stella:external_mcps", | ||
| ]; | ||
| export const CLIENT_NAME = "stella-cli"; | ||
| /** `--server` resolution: env var name, checked between the flag and the config file. */ | ||
| export const SERVER_URL_ENV_VAR = "STELLA_SERVER_URL"; | ||
| /** How long the CLI waits for the browser round-trip before giving up. */ | ||
| export const LOGIN_TIMEOUT_MS = 5 * 60 * 1000; | ||
| /** Network timeout for every discovery/registration/token request the CLI makes. */ | ||
| export const AUTH_FETCH_TIMEOUT_MS = 10_000; | ||
| //# sourceMappingURL=constants.js.map |
| {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/auth/constants.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,EAAE;AACF,sEAAsE;AACtE,gFAAgF;AAChF,8EAA8E;AAC9E,4EAA4E;AAC5E,2EAA2E;AAC3E,8EAA8E;AAC9E,yBAAyB;AAEzB,iEAAiE;AACjE,MAAM,aAAa,GAAG,MAAM,CAAC;AAE7B;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,SAAiB,EAAU,EAAE,CAC7D,IAAI,GAAG,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC;AAE/C;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,mCAAmC,GAAG;IACjD,yCAAyC;IACzC,kDAAkD;CAC1C,CAAC;AAEX;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,WAAW,CAAC;AAClD,MAAM,CAAC,MAAM,qBAAqB,GAAW,mBAAmB,sBAAsB,EAAE,CAAC;AAEzF,mFAAmF;AACnF,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,QAAQ;IACR,SAAS;IACT,OAAO;IACP,aAAa;IACb,eAAe;CACP,CAAC;AAEX,8EAA8E;AAC9E,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,QAAQ;IACR,SAAS;IACT,OAAO;IACP,eAAe;IACf,aAAa;IACb,kBAAkB;IAClB,wBAAwB;IACxB,sBAAsB;IACtB,wBAAwB;IACxB,sBAAsB;IACtB,mBAAmB;IACnB,oBAAoB;IACpB,mBAAmB;IACnB,eAAe;IACf,sBAAsB;CACd,CAAC;AAEX,MAAM,CAAC,MAAM,WAAW,GAAG,YAAY,CAAC;AAExC,yFAAyF;AACzF,MAAM,CAAC,MAAM,kBAAkB,GAAG,mBAAmB,CAAC;AAEtD,0EAA0E;AAC1E,MAAM,CAAC,MAAM,gBAAgB,GAAW,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAEtD,oFAAoF;AACpF,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC"} |
| import { defaultConfigDir, resolveConfigDir } from "./config-dir.js"; | ||
| import type { ConfigPathOverrides } from "./config-dir.js"; | ||
| export { defaultConfigDir, resolveConfigDir }; | ||
| export type { ConfigPathOverrides }; | ||
| export type StoredCredential = { | ||
| readonly serverUrl: string; | ||
| readonly orgId: string; | ||
| /** | ||
| * Best-effort label the user passed via `--org` at login time. Not | ||
| * cryptographically verified against the token (see `login.ts` for why: | ||
| * the server has no cheap org-slug-lookup endpoint and org selection | ||
| * happens entirely in the browser). Purely a display/lookup convenience. | ||
| */ | ||
| readonly orgLabel?: string | undefined; | ||
| readonly clientId: string; | ||
| readonly accessToken: string; | ||
| readonly refreshToken?: string | undefined; | ||
| readonly scope: string; | ||
| readonly tokenType: string; | ||
| readonly expiresAt: number; | ||
| readonly createdAt: number; | ||
| readonly updatedAt: number; | ||
| }; | ||
| export type CredentialFile = { | ||
| readonly version: 1; | ||
| /** serverUrl -> orgId, the org used when a command targets a server without an explicit `--org`. */ | ||
| readonly defaultOrgByServer: Readonly<Record<string, string>>; | ||
| readonly credentials: readonly StoredCredential[]; | ||
| }; | ||
| export declare const credentialsFilePath: (configDir: string) => string; | ||
| export declare const readCredentialFile: (configDir: string) => Promise<CredentialFile>; | ||
| export declare const writeCredentialFile: (configDir: string, file: CredentialFile) => Promise<void>; | ||
| export declare const findCredentialByOrgId: (file: CredentialFile, serverUrl: string, orgId: string) => StoredCredential | undefined; | ||
| /** Matches on org id first, then the unverified `orgLabel`. */ | ||
| export declare const findCredentialByOrgHint: (file: CredentialFile, serverUrl: string, orgHint: string) => StoredCredential | undefined; | ||
| export declare const findDefaultCredential: (file: CredentialFile, serverUrl: string) => StoredCredential | undefined; | ||
| export declare const listCredentialsForServer: (file: CredentialFile, serverUrl: string) => readonly StoredCredential[]; | ||
| /** Inserts or replaces the (serverUrl, orgId) credential; sets it as the server's default if none was set. */ | ||
| export declare const upsertCredential: (file: CredentialFile, credential: StoredCredential) => CredentialFile; | ||
| export declare const removeCredential: (file: CredentialFile, serverUrl: string, orgId: string) => CredentialFile; | ||
| export declare const setDefaultOrg: (file: CredentialFile, serverUrl: string, orgId: string) => CredentialFile; |
| // Token storage. | ||
| // | ||
| // OS keychain is the target end state (see the design brief and | ||
| // `apps/desktop/src-tauri/src/keychain.rs`'s policy precedent), but wiring a | ||
| // native keyring binding is real native-dependency surface (napi-rs | ||
| // prebuilds, per-platform CI, etc.) that this phase deliberately does not | ||
| // pull in without a separate flag-and-discuss. The XDG file is the only | ||
| // backend today; `--no-keychain` (see `../commands/login.ts`) is accepted | ||
| // and threaded through for forward compatibility but is currently a no-op, | ||
| // since there is nothing else to fall back from yet. | ||
| // | ||
| // One credential per (serverUrl, orgId) pair, mode 0600, analogous to the | ||
| // `aws`/`gh` multi-profile credential file pattern. | ||
| import { Result } from "better-result"; | ||
| import { chmod, mkdir, readFile, writeFile } from "node:fs/promises"; | ||
| import path from "node:path"; | ||
| import * as v from "valibot"; | ||
| import { defaultConfigDir, resolveConfigDir } from "./config-dir.js"; | ||
| export { defaultConfigDir, resolveConfigDir }; | ||
| const CREDENTIALS_FILE_MODE = 0o600; | ||
| const storedCredentialSchema = v.strictObject({ | ||
| serverUrl: v.string(), | ||
| orgId: v.string(), | ||
| orgLabel: v.optional(v.string()), | ||
| clientId: v.string(), | ||
| accessToken: v.string(), | ||
| refreshToken: v.optional(v.string()), | ||
| scope: v.string(), | ||
| tokenType: v.string(), | ||
| expiresAt: v.number(), | ||
| createdAt: v.number(), | ||
| updatedAt: v.number(), | ||
| }); | ||
| const credentialFileSchema = v.strictObject({ | ||
| version: v.literal(1), | ||
| defaultOrgByServer: v.record(v.string(), v.string()), | ||
| credentials: v.array(storedCredentialSchema), | ||
| }); | ||
| const EMPTY_FILE = { | ||
| credentials: [], | ||
| defaultOrgByServer: {}, | ||
| version: 1, | ||
| }; | ||
| export const credentialsFilePath = (configDir) => path.join(configDir, "credentials.json"); | ||
| export const readCredentialFile = async (configDir) => { | ||
| const filePath = credentialsFilePath(configDir); | ||
| const raw = await Result.tryPromise(async () => await readFile(filePath, "utf-8")); | ||
| if (Result.isError(raw)) { | ||
| return EMPTY_FILE; | ||
| } | ||
| const parsedJson = Result.try(() => JSON.parse(raw.value)); | ||
| if (Result.isError(parsedJson)) { | ||
| return EMPTY_FILE; | ||
| } | ||
| const parsed = v.safeParse(credentialFileSchema, parsedJson.value); | ||
| return parsed.success ? parsed.output : EMPTY_FILE; | ||
| }; | ||
| export const writeCredentialFile = async (configDir, file) => { | ||
| const filePath = credentialsFilePath(configDir); | ||
| await mkdir(configDir, { mode: 0o700, recursive: true }); | ||
| await writeFile(filePath, `${JSON.stringify(file, null, 2)}\n`, { | ||
| mode: CREDENTIALS_FILE_MODE, | ||
| }); | ||
| // `writeFile`'s `mode` option only applies when the file is created; force | ||
| // it on every write so a pre-existing looser-permission file gets fixed. | ||
| await chmod(filePath, CREDENTIALS_FILE_MODE); | ||
| }; | ||
| const credentialKey = (serverUrl, orgId) => `${serverUrl}::${orgId}`; | ||
| export const findCredentialByOrgId = (file, serverUrl, orgId) => file.credentials.find((credential) => credentialKey(credential.serverUrl, credential.orgId) === | ||
| credentialKey(serverUrl, orgId)); | ||
| /** Matches on org id first, then the unverified `orgLabel`. */ | ||
| export const findCredentialByOrgHint = (file, serverUrl, orgHint) => file.credentials.find((credential) => credential.serverUrl === serverUrl && | ||
| (credential.orgId === orgHint || credential.orgLabel === orgHint)); | ||
| export const findDefaultCredential = (file, serverUrl) => { | ||
| const defaultOrgId = file.defaultOrgByServer[serverUrl]; | ||
| if (defaultOrgId) { | ||
| return findCredentialByOrgId(file, serverUrl, defaultOrgId); | ||
| } | ||
| return file.credentials.find((credential) => credential.serverUrl === serverUrl); | ||
| }; | ||
| export const listCredentialsForServer = (file, serverUrl) => file.credentials.filter((credential) => credential.serverUrl === serverUrl); | ||
| /** Inserts or replaces the (serverUrl, orgId) credential; sets it as the server's default if none was set. */ | ||
| export const upsertCredential = (file, credential) => { | ||
| const withoutExisting = file.credentials.filter((existing) => credentialKey(existing.serverUrl, existing.orgId) !== | ||
| credentialKey(credential.serverUrl, credential.orgId)); | ||
| const defaultOrgByServer = file.defaultOrgByServer[credential.serverUrl] | ||
| ? file.defaultOrgByServer | ||
| : { ...file.defaultOrgByServer, [credential.serverUrl]: credential.orgId }; | ||
| return { | ||
| ...file, | ||
| credentials: [...withoutExisting, credential], | ||
| defaultOrgByServer, | ||
| }; | ||
| }; | ||
| export const removeCredential = (file, serverUrl, orgId) => { | ||
| const credentials = file.credentials.filter((existing) => credentialKey(existing.serverUrl, existing.orgId) !== | ||
| credentialKey(serverUrl, orgId)); | ||
| if (file.defaultOrgByServer[serverUrl] !== orgId) { | ||
| return { ...file, credentials }; | ||
| } | ||
| // The removed credential was the server's default; drop it and, if | ||
| // another credential remains for that server, promote it in one step | ||
| // (destructuring-omit instead of `delete`, per repo convention). | ||
| const { [serverUrl]: _removedDefault, ...remainingDefaults } = file.defaultOrgByServer; | ||
| const nextDefault = credentials.find((c) => c.serverUrl === serverUrl); | ||
| const defaultOrgByServer = nextDefault | ||
| ? { ...remainingDefaults, [serverUrl]: nextDefault.orgId } | ||
| : remainingDefaults; | ||
| return { ...file, credentials, defaultOrgByServer }; | ||
| }; | ||
| export const setDefaultOrg = (file, serverUrl, orgId) => ({ | ||
| ...file, | ||
| defaultOrgByServer: { ...file.defaultOrgByServer, [serverUrl]: orgId }, | ||
| }); | ||
| //# sourceMappingURL=credential-store.js.map |
| {"version":3,"file":"credential-store.js","sourceRoot":"","sources":["../../src/auth/credential-store.ts"],"names":[],"mappings":"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"} |
| import { Result } from "better-result"; | ||
| import type { CredentialFile, StoredCredential } from "./credential-store.js"; | ||
| import type { CliAuthError } from "./errors.js"; | ||
| import type { AuthorizationServerMetadata } from "./oauth-metadata.js"; | ||
| export type EnsureFreshCredentialInput = { | ||
| readonly configDir: string; | ||
| readonly credential: StoredCredential; | ||
| readonly credentialFile: CredentialFile; | ||
| readonly metadata: AuthorizationServerMetadata; | ||
| readonly now?: number; | ||
| }; | ||
| /** | ||
| * Returns a credential guaranteed usable "now" (with `REFRESH_SKEW_MS` of | ||
| * slack), refreshing and persisting it first if it is expired or about to | ||
| * expire. Errors when the credential is expired and either has no refresh | ||
| * token or the refresh call itself fails — both cases mean the caller must | ||
| * fall back to `stella auth login`. | ||
| */ | ||
| export declare const ensureFreshCredential: (input: EnsureFreshCredentialInput) => Promise<Result<StoredCredential, CliAuthError>>; |
| // Token refresh state machine: called proactively (context/whoami resolution) | ||
| // and reactively (a future Phase 3+ HTTP client on a 401) to keep a stored | ||
| // credential usable without forcing a full re-login. | ||
| // | ||
| // Today's server config issues no refresh tokens at all (the oauthProvider's | ||
| // `scopes` list has no `offline_access`, which is what | ||
| // `@better-auth/oauth-provider` gates refresh-token issuance on — see | ||
| // `packages/cli/src/auth/login.ts`'s module comment and the design brief). | ||
| // This function is still exercised end-to-end against a mocked provider | ||
| // (see `ensure-fresh-credential.test.ts`) so it is ready the moment that | ||
| // scope is added server-side; until then every credential this CLI stores | ||
| // simply has no `refreshToken` and expires after `ACCESS_TOKEN_EXPIRES_IN`. | ||
| import { Result } from "better-result"; | ||
| import { getMcpResourceUrl } from "./constants.js"; | ||
| import { upsertCredential, writeCredentialFile } from "./credential-store.js"; | ||
| import { NoRefreshTokenError } from "./errors.js"; | ||
| import { refreshAccessToken } from "./token-exchange.js"; | ||
| /** How much of a credential's remaining lifetime triggers a proactive refresh. */ | ||
| const REFRESH_SKEW_MS = 30_000; | ||
| /** | ||
| * Returns a credential guaranteed usable "now" (with `REFRESH_SKEW_MS` of | ||
| * slack), refreshing and persisting it first if it is expired or about to | ||
| * expire. Errors when the credential is expired and either has no refresh | ||
| * token or the refresh call itself fails — both cases mean the caller must | ||
| * fall back to `stella auth login`. | ||
| */ | ||
| export const ensureFreshCredential = async (input) => { | ||
| const now = input.now ?? Date.now(); | ||
| if (input.credential.expiresAt - REFRESH_SKEW_MS > now) { | ||
| return Result.ok(input.credential); | ||
| } | ||
| if (!input.credential.refreshToken) { | ||
| return Result.err(new NoRefreshTokenError({ | ||
| message: "The stored access token has expired and no refresh token is available. Run `stella auth login` again.", | ||
| })); | ||
| } | ||
| const refreshed = await refreshAccessToken({ | ||
| clientId: input.credential.clientId, | ||
| metadata: input.metadata, | ||
| refreshToken: input.credential.refreshToken, | ||
| resource: getMcpResourceUrl(input.credential.serverUrl), | ||
| }); | ||
| if (Result.isError(refreshed)) { | ||
| return Result.err(refreshed.error); | ||
| } | ||
| const updated = { | ||
| ...input.credential, | ||
| accessToken: refreshed.value.access_token, | ||
| expiresAt: now + refreshed.value.expires_in * 1000, | ||
| refreshToken: refreshed.value.refresh_token ?? input.credential.refreshToken, | ||
| scope: refreshed.value.scope ?? input.credential.scope, | ||
| updatedAt: now, | ||
| }; | ||
| await writeCredentialFile(input.configDir, upsertCredential(input.credentialFile, updated)); | ||
| return Result.ok(updated); | ||
| }; | ||
| //# sourceMappingURL=ensure-fresh-credential.js.map |
| {"version":3,"file":"ensure-fresh-credential.js","sourceRoot":"","sources":["../../src/auth/ensure-fresh-credential.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,2EAA2E;AAC3E,qDAAqD;AACrD,EAAE;AACF,6EAA6E;AAC7E,uDAAuD;AACvD,sEAAsE;AACtE,2EAA2E;AAC3E,wEAAwE;AACxE,yEAAyE;AACzE,0EAA0E;AAC1E,4EAA4E;AAE5E,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE9E,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGlD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzD,kFAAkF;AAClF,MAAM,eAAe,GAAG,MAAM,CAAC;AAU/B;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,EACxC,KAAiC,EACgB,EAAE;IACnD,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;IACpC,IAAI,KAAK,CAAC,UAAU,CAAC,SAAS,GAAG,eAAe,GAAG,GAAG,EAAE,CAAC;QACvD,OAAO,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACrC,CAAC;IAED,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC;QACnC,OAAO,MAAM,CAAC,GAAG,CACf,IAAI,mBAAmB,CAAC;YACtB,OAAO,EACL,uGAAuG;SAC1G,CAAC,CACH,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,kBAAkB,CAAC;QACzC,QAAQ,EAAE,KAAK,CAAC,UAAU,CAAC,QAAQ;QACnC,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,YAAY,EAAE,KAAK,CAAC,UAAU,CAAC,YAAY;QAC3C,QAAQ,EAAE,iBAAiB,CAAC,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC;KACxD,CAAC,CAAC;IACH,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,OAAO,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC;IAED,MAAM,OAAO,GAAqB;QAChC,GAAG,KAAK,CAAC,UAAU;QACnB,WAAW,EAAE,SAAS,CAAC,KAAK,CAAC,YAAY;QACzC,SAAS,EAAE,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI;QAClD,YAAY,EACV,SAAS,CAAC,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,UAAU,CAAC,YAAY;QAChE,KAAK,EAAE,SAAS,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,UAAU,CAAC,KAAK;QACtD,SAAS,EAAE,GAAG;KACf,CAAC;IAEF,MAAM,mBAAmB,CACvB,KAAK,CAAC,SAAS,EACf,gBAAgB,CAAC,KAAK,CAAC,cAAc,EAAE,OAAO,CAAC,CAChD,CAAC;IAEF,OAAO,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;AAC5B,CAAC,CAAC"} |
| export declare class CliBaseError<Tag extends string> extends Error { | ||
| readonly name: Tag; | ||
| readonly _tag: Tag; | ||
| constructor(tag: Tag, message: string); | ||
| } | ||
| export declare class OAuthMetadataError extends CliBaseError<"OAuthMetadataError"> { | ||
| readonly name = "OAuthMetadataError"; | ||
| readonly serverUrl: string; | ||
| readonly cause?: unknown; | ||
| constructor(props: { | ||
| message: string; | ||
| serverUrl: string; | ||
| cause?: unknown; | ||
| }); | ||
| } | ||
| export declare class ClientRegistrationError extends CliBaseError<"ClientRegistrationError"> { | ||
| readonly name = "ClientRegistrationError"; | ||
| readonly cause?: unknown; | ||
| constructor(props: { | ||
| message: string; | ||
| cause?: unknown; | ||
| }); | ||
| } | ||
| export declare class TokenExchangeError extends CliBaseError<"TokenExchangeError"> { | ||
| readonly name = "TokenExchangeError"; | ||
| readonly oauthError?: string | undefined; | ||
| readonly cause?: unknown; | ||
| constructor(props: { | ||
| message: string; | ||
| oauthError?: string | undefined; | ||
| cause?: unknown; | ||
| }); | ||
| } | ||
| export declare class TokenRefreshError extends CliBaseError<"TokenRefreshError"> { | ||
| readonly name = "TokenRefreshError"; | ||
| readonly oauthError?: string | undefined; | ||
| readonly cause?: unknown; | ||
| constructor(props: { | ||
| message: string; | ||
| oauthError?: string | undefined; | ||
| cause?: unknown; | ||
| }); | ||
| } | ||
| export declare class LoopbackTimeoutError extends CliBaseError<"LoopbackTimeoutError"> { | ||
| readonly name = "LoopbackTimeoutError"; | ||
| constructor(props: { | ||
| message: string; | ||
| }); | ||
| } | ||
| export declare class LoopbackCallbackError extends CliBaseError<"LoopbackCallbackError"> { | ||
| readonly name = "LoopbackCallbackError"; | ||
| readonly oauthError: string; | ||
| readonly oauthErrorDescription?: string | undefined; | ||
| constructor(props: { | ||
| message: string; | ||
| oauthError: string; | ||
| oauthErrorDescription?: string | undefined; | ||
| }); | ||
| } | ||
| export declare class ManualCallbackParseError extends CliBaseError<"ManualCallbackParseError"> { | ||
| readonly name = "ManualCallbackParseError"; | ||
| constructor(props: { | ||
| message: string; | ||
| }); | ||
| } | ||
| export declare class ServerUrlNotConfiguredError extends CliBaseError<"ServerUrlNotConfiguredError"> { | ||
| readonly name = "ServerUrlNotConfiguredError"; | ||
| constructor(props: { | ||
| message: string; | ||
| }); | ||
| } | ||
| export declare class CredentialNotFoundError extends CliBaseError<"CredentialNotFoundError"> { | ||
| readonly name = "CredentialNotFoundError"; | ||
| readonly serverUrl: string; | ||
| readonly org?: string | undefined; | ||
| constructor(props: { | ||
| message: string; | ||
| serverUrl: string; | ||
| org?: string | undefined; | ||
| }); | ||
| } | ||
| export declare class MissingOrgClaimError extends CliBaseError<"MissingOrgClaimError"> { | ||
| readonly name = "MissingOrgClaimError"; | ||
| readonly serverUrl: string; | ||
| constructor(props: { | ||
| message: string; | ||
| serverUrl: string; | ||
| }); | ||
| } | ||
| export declare class NoRefreshTokenError extends CliBaseError<"NoRefreshTokenError"> { | ||
| readonly name = "NoRefreshTokenError"; | ||
| constructor(props: { | ||
| message: string; | ||
| }); | ||
| } | ||
| export type CliAuthError = OAuthMetadataError | ClientRegistrationError | TokenExchangeError | TokenRefreshError | LoopbackTimeoutError | LoopbackCallbackError | ManualCallbackParseError | ServerUrlNotConfiguredError | CredentialNotFoundError | MissingOrgClaimError | NoRefreshTokenError; |
| // Tagged errors for the `stella auth` flow (see AGENTS.md "Error Handling": | ||
| // tagged errors over bare `Error`, one `message: string` field on every one). | ||
| // | ||
| // Hand-rolled rather than `better-result`'s `TaggedError(tag)<Props>()` | ||
| // factory: that factory's `class Foo extends TaggedError("Foo")<Props>() {}` | ||
| // shape requires a call expression in the `extends` clause, which | ||
| // `isolatedDeclarations` (this package builds with it — see | ||
| // `cli-config.ts`) rejects outright (`TS9021`). `CliBaseError<Tag>` below | ||
| // gives the same discriminated-union/`_tag` shape without a factory call. | ||
| // Every subclass also declares its own literal `name` field (oxlint's | ||
| // `unicorn/custom-error-definition` checks each class individually, not | ||
| // through inheritance). | ||
| export class CliBaseError extends Error { | ||
| name; | ||
| _tag; | ||
| constructor(tag, message) { | ||
| super(message); | ||
| // eslint-disable-next-line unicorn/custom-error-definition -- generic base, never instantiated directly; every concrete subclass sets its own literal `name` too | ||
| this.name = tag; | ||
| this._tag = tag; | ||
| } | ||
| } | ||
| export class OAuthMetadataError extends CliBaseError { | ||
| name = "OAuthMetadataError"; | ||
| serverUrl; | ||
| cause; | ||
| constructor(props) { | ||
| super("OAuthMetadataError", props.message); | ||
| this.serverUrl = props.serverUrl; | ||
| this.cause = props.cause; | ||
| } | ||
| } | ||
| export class ClientRegistrationError extends CliBaseError { | ||
| name = "ClientRegistrationError"; | ||
| cause; | ||
| constructor(props) { | ||
| super("ClientRegistrationError", props.message); | ||
| this.cause = props.cause; | ||
| } | ||
| } | ||
| export class TokenExchangeError extends CliBaseError { | ||
| name = "TokenExchangeError"; | ||
| oauthError; | ||
| cause; | ||
| constructor(props) { | ||
| super("TokenExchangeError", props.message); | ||
| this.oauthError = props.oauthError; | ||
| this.cause = props.cause; | ||
| } | ||
| } | ||
| export class TokenRefreshError extends CliBaseError { | ||
| name = "TokenRefreshError"; | ||
| oauthError; | ||
| cause; | ||
| constructor(props) { | ||
| super("TokenRefreshError", props.message); | ||
| this.oauthError = props.oauthError; | ||
| this.cause = props.cause; | ||
| } | ||
| } | ||
| export class LoopbackTimeoutError extends CliBaseError { | ||
| name = "LoopbackTimeoutError"; | ||
| constructor(props) { | ||
| super("LoopbackTimeoutError", props.message); | ||
| } | ||
| } | ||
| export class LoopbackCallbackError extends CliBaseError { | ||
| name = "LoopbackCallbackError"; | ||
| oauthError; | ||
| oauthErrorDescription; | ||
| constructor(props) { | ||
| super("LoopbackCallbackError", props.message); | ||
| this.oauthError = props.oauthError; | ||
| this.oauthErrorDescription = props.oauthErrorDescription; | ||
| } | ||
| } | ||
| export class ManualCallbackParseError extends CliBaseError { | ||
| name = "ManualCallbackParseError"; | ||
| constructor(props) { | ||
| super("ManualCallbackParseError", props.message); | ||
| } | ||
| } | ||
| export class ServerUrlNotConfiguredError extends CliBaseError { | ||
| name = "ServerUrlNotConfiguredError"; | ||
| constructor(props) { | ||
| super("ServerUrlNotConfiguredError", props.message); | ||
| } | ||
| } | ||
| export class CredentialNotFoundError extends CliBaseError { | ||
| name = "CredentialNotFoundError"; | ||
| serverUrl; | ||
| org; | ||
| constructor(props) { | ||
| super("CredentialNotFoundError", props.message); | ||
| this.serverUrl = props.serverUrl; | ||
| this.org = props.org; | ||
| } | ||
| } | ||
| export class MissingOrgClaimError extends CliBaseError { | ||
| name = "MissingOrgClaimError"; | ||
| serverUrl; | ||
| constructor(props) { | ||
| super("MissingOrgClaimError", props.message); | ||
| this.serverUrl = props.serverUrl; | ||
| } | ||
| } | ||
| export class NoRefreshTokenError extends CliBaseError { | ||
| name = "NoRefreshTokenError"; | ||
| constructor(props) { | ||
| super("NoRefreshTokenError", props.message); | ||
| } | ||
| } | ||
| //# sourceMappingURL=errors.js.map |
| {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/auth/errors.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,8EAA8E;AAC9E,EAAE;AACF,wEAAwE;AACxE,6EAA6E;AAC7E,kEAAkE;AAClE,4DAA4D;AAC5D,0EAA0E;AAC1E,0EAA0E;AAC1E,sEAAsE;AACtE,wEAAwE;AACxE,wBAAwB;AAExB,MAAM,OAAO,YAAiC,SAAQ,KAAK;IACvC,IAAI,CAAM;IACnB,IAAI,CAAM;IAEnB,YAAY,GAAQ,EAAE,OAAe;QACnC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,iKAAiK;QACjK,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;QAChB,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;IAClB,CAAC;CACF;AAED,MAAM,OAAO,kBAAmB,SAAQ,YAAkC;IACtD,IAAI,GAAG,oBAAoB,CAAC;IACrC,SAAS,CAAS;IACT,KAAK,CAAW;IAElC,YAAY,KAA8D;QACxE,KAAK,CAAC,oBAAoB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAC3C,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;QACjC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAC3B,CAAC;CACF;AAED,MAAM,OAAO,uBAAwB,SAAQ,YAAuC;IAChE,IAAI,GAAG,yBAAyB,CAAC;IACjC,KAAK,CAAW;IAElC,YAAY,KAA2C;QACrD,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAChD,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAC3B,CAAC;CACF;AAED,MAAM,OAAO,kBAAmB,SAAQ,YAAkC;IACtD,IAAI,GAAG,oBAAoB,CAAC;IACrC,UAAU,CAAsB;IACvB,KAAK,CAAW;IAElC,YAAY,KAIX;QACC,KAAK,CAAC,oBAAoB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAC3C,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;QACnC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAC3B,CAAC;CACF;AAED,MAAM,OAAO,iBAAkB,SAAQ,YAAiC;IACpD,IAAI,GAAG,mBAAmB,CAAC;IACpC,UAAU,CAAsB;IACvB,KAAK,CAAW;IAElC,YAAY,KAIX;QACC,KAAK,CAAC,mBAAmB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAC1C,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;QACnC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAC3B,CAAC;CACF;AAED,MAAM,OAAO,oBAAqB,SAAQ,YAAoC;IAC1D,IAAI,GAAG,sBAAsB,CAAC;IAEhD,YAAY,KAA0B;QACpC,KAAK,CAAC,sBAAsB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/C,CAAC;CACF;AAED,MAAM,OAAO,qBAAsB,SAAQ,YAAqC;IAC5D,IAAI,GAAG,uBAAuB,CAAC;IACxC,UAAU,CAAS;IACnB,qBAAqB,CAAsB;IAEpD,YAAY,KAIX;QACC,KAAK,CAAC,uBAAuB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9C,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;QACnC,IAAI,CAAC,qBAAqB,GAAG,KAAK,CAAC,qBAAqB,CAAC;IAC3D,CAAC;CACF;AAED,MAAM,OAAO,wBAAyB,SAAQ,YAAwC;IAClE,IAAI,GAAG,0BAA0B,CAAC;IAEpD,YAAY,KAA0B;QACpC,KAAK,CAAC,0BAA0B,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IACnD,CAAC;CACF;AAED,MAAM,OAAO,2BAA4B,SAAQ,YAA2C;IACxE,IAAI,GAAG,6BAA6B,CAAC;IAEvD,YAAY,KAA0B;QACpC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IACtD,CAAC;CACF;AAED,MAAM,OAAO,uBAAwB,SAAQ,YAAuC;IAChE,IAAI,GAAG,yBAAyB,CAAC;IAC1C,SAAS,CAAS;IAClB,GAAG,CAAsB;IAElC,YAAY,KAIX;QACC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAChD,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;QACjC,IAAI,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;IACvB,CAAC;CACF;AAED,MAAM,OAAO,oBAAqB,SAAQ,YAAoC;IAC1D,IAAI,GAAG,sBAAsB,CAAC;IACvC,SAAS,CAAS;IAE3B,YAAY,KAA6C;QACvD,KAAK,CAAC,sBAAsB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7C,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;IACnC,CAAC;CACF;AAED,MAAM,OAAO,mBAAoB,SAAQ,YAAmC;IACxD,IAAI,GAAG,qBAAqB,CAAC;IAE/C,YAAY,KAA0B;QACpC,KAAK,CAAC,qBAAqB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IAC9C,CAAC;CACF"} |
| export type AccessTokenClaims = { | ||
| readonly sub: string; | ||
| readonly org_id?: string | undefined; | ||
| readonly scope?: string | undefined; | ||
| readonly exp: number; | ||
| readonly iat?: number | undefined; | ||
| readonly aud?: string | readonly string[] | undefined; | ||
| }; | ||
| /** | ||
| * Decodes a JWT's payload segment without verifying its signature. Returns | ||
| * `undefined` for opaque (non-JWT) tokens or malformed payloads. | ||
| */ | ||
| export declare const decodeAccessTokenClaims: (accessToken: string) => AccessTokenClaims | undefined; |
| // Local (unverified) decode of the access token for `stella auth whoami`. | ||
| // | ||
| // The provider only mints a JWT-format access token when the CLI requests a | ||
| // `resource` at the token endpoint (see `constants.ts#getMcpResourceUrl`); | ||
| // its authenticity was already established by receiving it directly from the | ||
| // token endpoint over TLS, so `whoami` decodes locally rather than making a | ||
| // server round trip, per the design brief. There is no cheap endpoint to | ||
| // resolve `org_id` back to an org slug/name (`/oauth2/userinfo` only returns | ||
| // `sub`/`email`/`name`/`picture`), so `whoami` reports the id verbatim. | ||
| import { Result } from "better-result"; | ||
| import * as v from "valibot"; | ||
| const accessTokenClaimsSchema = v.strictObject({ | ||
| sub: v.string(), | ||
| org_id: v.optional(v.string()), | ||
| scope: v.optional(v.string()), | ||
| exp: v.number(), | ||
| iat: v.optional(v.number()), | ||
| aud: v.optional(v.union([v.string(), v.array(v.string())])), | ||
| }); | ||
| /** | ||
| * Decodes a JWT's payload segment without verifying its signature. Returns | ||
| * `undefined` for opaque (non-JWT) tokens or malformed payloads. | ||
| */ | ||
| export const decodeAccessTokenClaims = (accessToken) => { | ||
| const segments = accessToken.split("."); | ||
| const payloadSegment = segments.length === 3 ? segments.at(1) : undefined; | ||
| if (!payloadSegment) { | ||
| return undefined; | ||
| } | ||
| const decoded = Result.try(() => JSON.parse(Buffer.from(payloadSegment, "base64url").toString("utf-8"))); | ||
| if (Result.isError(decoded)) { | ||
| return undefined; | ||
| } | ||
| const parsed = v.safeParse(accessTokenClaimsSchema, decoded.value); | ||
| return parsed.success ? parsed.output : undefined; | ||
| }; | ||
| //# sourceMappingURL=jwt.js.map |
| {"version":3,"file":"jwt.js","sourceRoot":"","sources":["../../src/auth/jwt.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,EAAE;AACF,4EAA4E;AAC5E,2EAA2E;AAC3E,6EAA6E;AAC7E,4EAA4E;AAC5E,yEAAyE;AACzE,6EAA6E;AAC7E,wEAAwE;AAExE,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAa7B,MAAM,uBAAuB,GAAG,CAAC,CAAC,YAAY,CAAC;IAC7C,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;IACf,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC9B,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC7B,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;IACf,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC3B,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;CAC5D,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CACrC,WAAmB,EACY,EAAE;IACjC,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC1E,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,GAAY,EAAE,CACvC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CACvE,CAAC;IACF,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,CAAC,uBAAuB,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IACnE,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AACpD,CAAC,CAAC"} |
| import { Result } from "better-result"; | ||
| import type { CliAuthError } from "./errors.js"; | ||
| export type LoginOptions = { | ||
| readonly configDir: string; | ||
| readonly orgHint: string | undefined; | ||
| readonly registrationScopes: readonly string[]; | ||
| readonly requestedScopes: readonly string[]; | ||
| readonly serverFlag: string | undefined; | ||
| }; | ||
| export type LoginSuccess = { | ||
| readonly serverUrl: string; | ||
| readonly orgId: string; | ||
| readonly grantedScopes: string; | ||
| readonly expiresAt: number; | ||
| readonly hasRefreshToken: boolean; | ||
| }; | ||
| export declare const login: (process: NodeJS.Process, options: LoginOptions) => Promise<Result<LoginSuccess, CliAuthError>>; |
| // Orchestrates `stella auth login`: PKCE authorization-code flow against | ||
| // stella's own oauthProvider, with a loopback listener as the primary | ||
| // transport and a manual URL/code paste as the fallback for headless | ||
| // environments (see module comments in `loopback-listener.ts` and | ||
| // `manual-callback.ts`). | ||
| import { Result } from "better-result"; | ||
| import { createInterface } from "node:readline/promises"; | ||
| import { openInBrowser } from "./browser-open.js"; | ||
| import { getRegisteredClientId, setRegisteredClientId } from "./cli-config.js"; | ||
| import { getMcpResourceUrl, LOGIN_TIMEOUT_MS, LOOPBACK_REDIRECT_URI, } from "./constants.js"; | ||
| import { readCredentialFile, setDefaultOrg, upsertCredential, writeCredentialFile, } from "./credential-store.js"; | ||
| import { MissingOrgClaimError } from "./errors.js"; | ||
| import { decodeAccessTokenClaims } from "./jwt.js"; | ||
| import { startLoopbackListener, toLoopbackCallbackError, } from "./loopback-listener.js"; | ||
| import { parseManualCallbackInput } from "./manual-callback.js"; | ||
| import { registerLoopbackClient } from "./oauth-client-registration.js"; | ||
| import { discoverAuthorizationServerMetadata } from "./oauth-metadata.js"; | ||
| import { createOAuthState, createPkcePair } from "./pkce.js"; | ||
| import { resolveServerUrl } from "./server-resolution.js"; | ||
| import { exchangeAuthorizationCode } from "./token-exchange.js"; | ||
| const buildIo = (process) => ({ | ||
| print: (line) => { | ||
| process.stdout.write(`${line}\n`); | ||
| }, | ||
| promptLine: async (question) => { | ||
| const rl = createInterface({ | ||
| input: process.stdin, | ||
| output: process.stdout, | ||
| }); | ||
| try { | ||
| return await rl.question(question); | ||
| } | ||
| finally { | ||
| rl.close(); | ||
| } | ||
| }, | ||
| }); | ||
| const buildAuthorizeUrl = (input) => { | ||
| const url = new URL(input.authorizationEndpoint); | ||
| url.searchParams.set("response_type", "code"); | ||
| url.searchParams.set("client_id", input.clientId); | ||
| url.searchParams.set("redirect_uri", input.redirectUri); | ||
| url.searchParams.set("code_challenge", input.codeChallenge); | ||
| url.searchParams.set("code_challenge_method", "S256"); | ||
| url.searchParams.set("state", input.state); | ||
| if (input.scopes.length > 0) { | ||
| url.searchParams.set("scope", input.scopes.join(" ")); | ||
| } | ||
| return url.toString(); | ||
| }; | ||
| /** Gets the cached loopback client id for `serverUrl`, registering one if none exists yet. */ | ||
| const getOrRegisterClient = async (configDir, serverUrl, metadata, registrationScopes) => { | ||
| const cached = await getRegisteredClientId(configDir, serverUrl); | ||
| if (cached) { | ||
| return Result.ok(cached); | ||
| } | ||
| const registered = await registerLoopbackClient(metadata, registrationScopes); | ||
| if (Result.isError(registered)) { | ||
| return registered; | ||
| } | ||
| await setRegisteredClientId(configDir, serverUrl, registered.value); | ||
| return Result.ok(registered.value); | ||
| }; | ||
| const isLoopbackCallback = (value) => "kind" in value; | ||
| const awaitManualCode = async (io, redirectUri, expectedState) => { | ||
| const pasted = await io.promptLine("Paste the redirected URL or code: "); | ||
| const parsed = parseManualCallbackInput(pasted); | ||
| if (Result.isError(parsed)) { | ||
| return Result.err(parsed.error); | ||
| } | ||
| if (parsed.value.state && parsed.value.state !== expectedState) { | ||
| return Result.err(toLoopbackCallbackError({ error: "invalid_state", kind: "error" })); | ||
| } | ||
| return Result.ok({ code: parsed.value.code, redirectUri }); | ||
| }; | ||
| /** | ||
| * Waits for the loopback callback, falling back to manual paste if the | ||
| * listener never fires. `redirectUri` must be whichever URI was actually | ||
| * used to build the authorize request (the listener's port-specific one, or | ||
| * the portless default when no listener could be started) — the token | ||
| * endpoint later requires an exact match (RFC 6749 S4.1.3). | ||
| */ | ||
| const awaitAuthorizationCode = async (io, authorizeUrl, redirectUri, listener, expectedState) => { | ||
| io.print("Opening the stella sign-in page in your browser:"); | ||
| io.print(` ${authorizeUrl}`); | ||
| void openInBrowser(authorizeUrl); | ||
| if (!listener) { | ||
| io.print("Could not start a local listener; complete sign-in in any browser, then paste the redirected URL (or just the code) below."); | ||
| return awaitManualCode(io, redirectUri, expectedState); | ||
| } | ||
| const result = await listener.waitForCallback(LOGIN_TIMEOUT_MS); | ||
| listener.close(); | ||
| if (!isLoopbackCallback(result)) { | ||
| // Timed out waiting locally: the browser most likely isn't reachable | ||
| // from this machine (SSH/remote dev/agent sandbox). Fall back to manual. | ||
| io.print("Timed out waiting for the browser. If you're running headless, complete sign-in in any browser, then paste the redirected URL (or just the code) below."); | ||
| return awaitManualCode(io, redirectUri, expectedState); | ||
| } | ||
| if (result.kind === "error") { | ||
| return Result.err(toLoopbackCallbackError(result)); | ||
| } | ||
| if (result.state !== expectedState) { | ||
| return Result.err(toLoopbackCallbackError({ error: "invalid_state", kind: "error" })); | ||
| } | ||
| return Result.ok({ code: result.code, redirectUri }); | ||
| }; | ||
| // Sequential steps with different Ok types chained via `Result.gen` + | ||
| // `yield* Result.await(...)` (see AGENTS.md's Error Handling conventions): | ||
| // this avoids re-wrapping every intermediate error result by hand. | ||
| export const login = async (process, options) => await Result.gen(async function* loginGen() { | ||
| const io = buildIo(process); | ||
| const serverUrl = yield* Result.await(resolveServerUrl(options.configDir, options.serverFlag)); | ||
| const metadata = yield* Result.await(discoverAuthorizationServerMetadata(serverUrl)); | ||
| const clientId = yield* Result.await(getOrRegisterClient(options.configDir, serverUrl, metadata, options.registrationScopes)); | ||
| const { codeChallenge, codeVerifier } = createPkcePair(); | ||
| const state = createOAuthState(); | ||
| if (options.orgHint) { | ||
| io.print(`If prompted to select an organization in the browser, choose: ${options.orgHint} (the CLI cannot preselect it for you; org selection happens in the browser UI).`); | ||
| } | ||
| // Start the listener before building the authorize URL: the redirect_uri | ||
| // sent to the authorization server must be whichever one the browser | ||
| // will actually be redirected back to (the listener's ephemeral port, or | ||
| // the portless default if binding failed), and it must stay identical | ||
| // through to the token exchange. | ||
| const listener = await startLoopbackListener(); | ||
| const redirectUri = listener?.redirectUri ?? LOOPBACK_REDIRECT_URI; | ||
| const authorizeUrl = buildAuthorizeUrl({ | ||
| authorizationEndpoint: metadata.authorization_endpoint, | ||
| clientId, | ||
| codeChallenge, | ||
| redirectUri, | ||
| scopes: options.requestedScopes, | ||
| state, | ||
| }); | ||
| const callback = yield* Result.await(awaitAuthorizationCode(io, authorizeUrl, redirectUri, listener, state)); | ||
| const token = yield* Result.await(exchangeAuthorizationCode({ | ||
| clientId, | ||
| code: callback.code, | ||
| codeVerifier, | ||
| metadata, | ||
| redirectUri: callback.redirectUri, | ||
| resource: getMcpResourceUrl(serverUrl), | ||
| })); | ||
| const claims = decodeAccessTokenClaims(token.access_token); | ||
| if (!claims?.org_id) { | ||
| return Result.err(new MissingOrgClaimError({ | ||
| message: "The access token has no org_id claim, so the CLI cannot tell which organization was granted. Re-run `stella auth login` and make sure an organization is active when you reach the consent screen.", | ||
| serverUrl, | ||
| })); | ||
| } | ||
| const now = Date.now(); | ||
| const credential = { | ||
| accessToken: token.access_token, | ||
| clientId, | ||
| createdAt: now, | ||
| expiresAt: now + token.expires_in * 1000, | ||
| orgId: claims.org_id, | ||
| ...(options.orgHint ? { orgLabel: options.orgHint } : {}), | ||
| refreshToken: token.refresh_token, | ||
| scope: token.scope ?? options.requestedScopes.join(" "), | ||
| serverUrl, | ||
| tokenType: token.token_type, | ||
| updatedAt: now, | ||
| }; | ||
| const existingFile = await readCredentialFile(options.configDir); | ||
| const withCredential = upsertCredential(existingFile, credential); | ||
| const withDefaultOrg = setDefaultOrg(withCredential, serverUrl, credential.orgId); | ||
| await writeCredentialFile(options.configDir, withDefaultOrg); | ||
| return Result.ok({ | ||
| expiresAt: credential.expiresAt, | ||
| grantedScopes: credential.scope, | ||
| hasRefreshToken: Boolean(credential.refreshToken), | ||
| orgId: credential.orgId, | ||
| serverUrl, | ||
| }); | ||
| }); | ||
| //# sourceMappingURL=login.js.map |
| {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/auth/login.ts"],"names":[],"mappings":"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"} |
| import { LoopbackCallbackError, LoopbackTimeoutError } from "./errors.js"; | ||
| export type LoopbackCallback = { | ||
| readonly kind: "success"; | ||
| readonly code: string; | ||
| readonly state: string; | ||
| } | { | ||
| readonly kind: "error"; | ||
| readonly error: string; | ||
| readonly errorDescription?: string; | ||
| readonly state?: string; | ||
| }; | ||
| export type LoopbackListener = { | ||
| readonly port: number; | ||
| readonly redirectUri: string; | ||
| readonly waitForCallback: (timeoutMs: number) => Promise<LoopbackCallback | LoopbackTimeoutError>; | ||
| readonly close: () => void; | ||
| }; | ||
| /** | ||
| * Starts the loopback HTTP listener. Resolves to `undefined` if binding fails | ||
| * (sandboxed/offline environments) so callers can fall back to the manual | ||
| * paste flow instead of crashing. Async because `node:http`'s `listen` reports | ||
| * its OS-assigned port on the `listening` event, not synchronously. | ||
| */ | ||
| export declare const startLoopbackListener: () => Promise<LoopbackListener | undefined>; | ||
| /** Converts a listener callback into the `TaggedError` shape the login flow expects. */ | ||
| export declare const toLoopbackCallbackError: (callback: Extract<LoopbackCallback, { | ||
| kind: "error"; | ||
| }>) => LoopbackCallbackError; |
| // Ephemeral 127.0.0.1 listener for the loopback redirect (RFC 8252). | ||
| // | ||
| // Binds port 0 (OS-assigned) so concurrent logins and busy dev machines never | ||
| // collide. The registered client's redirect_uri has no port (see | ||
| // `constants.ts#LOOPBACK_REDIRECT_URI`); better-auth's loopback exemption | ||
| // matches on hostname/pathname/protocol/search only, so any ephemeral port | ||
| // still satisfies the registered redirect_uri. | ||
| import { createServer } from "node:http"; | ||
| import { LOOPBACK_REDIRECT_PATH } from "./constants.js"; | ||
| import { LoopbackCallbackError, LoopbackTimeoutError } from "./errors.js"; | ||
| const renderCallbackPage = (ok) => `<!doctype html><html><head><meta charset="utf-8"><title>stella CLI</title></head>` + | ||
| `<body><p>${ok ? "Signed in. You can close this tab and return to the terminal." : "Sign-in failed. Return to the terminal for details."}</p></body></html>`; | ||
| const raceWithTimeout = async (received, timeoutMs) => { | ||
| let timer; | ||
| const timeout = new Promise((resolve) => { | ||
| timer = setTimeout(() => { | ||
| resolve(new LoopbackTimeoutError({ | ||
| message: `Timed out after ${Math.round(timeoutMs / 1000)}s waiting for the browser sign-in to complete.`, | ||
| })); | ||
| }, timeoutMs); | ||
| }); | ||
| try { | ||
| return await Promise.race([received, timeout]); | ||
| } | ||
| finally { | ||
| if (timer) { | ||
| clearTimeout(timer); | ||
| } | ||
| } | ||
| }; | ||
| /** | ||
| * Starts the loopback HTTP listener. Resolves to `undefined` if binding fails | ||
| * (sandboxed/offline environments) so callers can fall back to the manual | ||
| * paste flow instead of crashing. Async because `node:http`'s `listen` reports | ||
| * its OS-assigned port on the `listening` event, not synchronously. | ||
| */ | ||
| export const startLoopbackListener = async () => { | ||
| let deliver; | ||
| const received = new Promise((resolve) => { | ||
| deliver = resolve; | ||
| }); | ||
| const server = createServer((request, response) => { | ||
| // `request.url` is the path+query only; rebuild a full URL against the | ||
| // fixed loopback host to parse the query string. | ||
| const url = new URL(request.url ?? "/", "http://127.0.0.1"); | ||
| if (url.pathname !== LOOPBACK_REDIRECT_PATH) { | ||
| response.writeHead(404); | ||
| response.end("Not found"); | ||
| return; | ||
| } | ||
| const error = url.searchParams.get("error"); | ||
| if (error) { | ||
| const errorDescription = url.searchParams.get("error_description"); | ||
| const state = url.searchParams.get("state"); | ||
| deliver?.({ | ||
| error, | ||
| kind: "error", | ||
| ...(errorDescription ? { errorDescription } : {}), | ||
| ...(state ? { state } : {}), | ||
| }); | ||
| response.writeHead(200, { "Content-Type": "text/html" }); | ||
| response.end(renderCallbackPage(false)); | ||
| return; | ||
| } | ||
| const code = url.searchParams.get("code"); | ||
| const state = url.searchParams.get("state"); | ||
| if (!code || !state) { | ||
| response.writeHead(400); | ||
| response.end("Missing code or state"); | ||
| return; | ||
| } | ||
| deliver?.({ code, kind: "success", state }); | ||
| response.writeHead(200, { "Content-Type": "text/html" }); | ||
| response.end(renderCallbackPage(true)); | ||
| }); | ||
| const listenerPort = await new Promise((resolve) => { | ||
| // A pre-`listening` bind error (EADDRINUSE, EACCES, sandbox) resolves to | ||
| // `undefined`; the same handler stays attached afterward so a later socket | ||
| // error is absorbed rather than thrown as an uncaught `error` event. | ||
| server.on("error", () => resolve(undefined)); | ||
| server.listen(0, "127.0.0.1", () => { | ||
| const address = server.address(); | ||
| resolve(address !== null && typeof address === "object" | ||
| ? address.port | ||
| : undefined); | ||
| }); | ||
| }); | ||
| if (listenerPort === undefined) { | ||
| server.close(); | ||
| return undefined; | ||
| } | ||
| return { | ||
| // The CLI just needs the port freed and no more callbacks delivered; | ||
| // `closeAllConnections` drops any lingering keep-alive socket so the | ||
| // event loop can exit, then `close` stops accepting new connections. | ||
| close: () => { | ||
| server.closeAllConnections(); | ||
| server.close(); | ||
| }, | ||
| port: listenerPort, | ||
| redirectUri: `http://127.0.0.1:${listenerPort}${LOOPBACK_REDIRECT_PATH}`, | ||
| waitForCallback: async (timeoutMs) => await raceWithTimeout(received, timeoutMs), | ||
| }; | ||
| }; | ||
| /** Converts a listener callback into the `TaggedError` shape the login flow expects. */ | ||
| export const toLoopbackCallbackError = (callback) => new LoopbackCallbackError({ | ||
| message: callback.error === "set_organization" | ||
| ? "Your account needs an active organization before granting stella CLI access. Complete organization setup in the browser (create or select one), then re-run `stella auth login`." | ||
| : (callback.errorDescription ?? callback.error), | ||
| oauthError: callback.error, | ||
| oauthErrorDescription: callback.errorDescription, | ||
| }); | ||
| //# sourceMappingURL=loopback-listener.js.map |
| {"version":3,"file":"loopback-listener.js","sourceRoot":"","sources":["../../src/auth/loopback-listener.ts"],"names":[],"mappings":"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"} |
| import { Result } from "better-result"; | ||
| import type { CliAuthError } from "./errors.js"; | ||
| import type { AccessTokenClaims } from "./jwt.js"; | ||
| export type WhoamiInfo = { | ||
| readonly serverUrl: string; | ||
| readonly orgId: string; | ||
| readonly orgLabel: string | undefined; | ||
| readonly scope: string; | ||
| readonly expiresAt: number; | ||
| readonly isExpired: boolean; | ||
| readonly hasRefreshToken: boolean; | ||
| readonly claims: AccessTokenClaims | undefined; | ||
| }; | ||
| export declare const whoami: (configDir: string, serverUrl: string, orgHint: string | undefined) => Promise<Result<WhoamiInfo, CliAuthError>>; | ||
| export declare const logout: (configDir: string, serverUrl: string, orgHint: string | undefined) => Promise<Result<{ | ||
| orgId: string; | ||
| }, CliAuthError>>; | ||
| export declare const switchOrg: (configDir: string, serverUrl: string, orgHint: string) => Promise<Result<{ | ||
| orgId: string; | ||
| }, CliAuthError>>; |
| // `stella auth whoami` / `logout` / `switch`: read-mostly operations against | ||
| // the credential store, resolved for whichever server is currently active. | ||
| import { Result } from "better-result"; | ||
| import { findCredentialByOrgHint, findDefaultCredential, listCredentialsForServer, readCredentialFile, removeCredential, setDefaultOrg, writeCredentialFile, } from "./credential-store.js"; | ||
| import { CredentialNotFoundError } from "./errors.js"; | ||
| import { decodeAccessTokenClaims } from "./jwt.js"; | ||
| const resolveCredential = async (configDir, serverUrl, orgHint) => { | ||
| const file = await readCredentialFile(configDir); | ||
| const allForServer = listCredentialsForServer(file, serverUrl); | ||
| const credential = orgHint | ||
| ? findCredentialByOrgHint(file, serverUrl, orgHint) | ||
| : findDefaultCredential(file, serverUrl); | ||
| if (!credential) { | ||
| const guidance = orgHint && allForServer.length > 0 | ||
| ? `Not signed in to "${orgHint}" on ${serverUrl}. Known orgs here: ${allForServer.map((c) => c.orgLabel ?? c.orgId).join(", ")}.` | ||
| : `Not signed in to ${serverUrl}. Run \`stella auth login\`${orgHint ? ` --org ${orgHint}` : ""}.`; | ||
| return Result.err(new CredentialNotFoundError({ | ||
| message: guidance, | ||
| org: orgHint, | ||
| serverUrl, | ||
| })); | ||
| } | ||
| return Result.ok({ allForServer, credential }); | ||
| }; | ||
| export const whoami = async (configDir, serverUrl, orgHint) => { | ||
| const resolved = await resolveCredential(configDir, serverUrl, orgHint); | ||
| if (Result.isError(resolved)) { | ||
| return Result.err(resolved.error); | ||
| } | ||
| const { credential } = resolved.value; | ||
| return Result.ok({ | ||
| claims: decodeAccessTokenClaims(credential.accessToken), | ||
| expiresAt: credential.expiresAt, | ||
| hasRefreshToken: Boolean(credential.refreshToken), | ||
| isExpired: credential.expiresAt <= Date.now(), | ||
| orgId: credential.orgId, | ||
| orgLabel: credential.orgLabel, | ||
| scope: credential.scope, | ||
| serverUrl: credential.serverUrl, | ||
| }); | ||
| }; | ||
| export const logout = async (configDir, serverUrl, orgHint) => { | ||
| const file = await readCredentialFile(configDir); | ||
| const allForServer = listCredentialsForServer(file, serverUrl); | ||
| if (allForServer.length === 0) { | ||
| return Result.err(new CredentialNotFoundError({ | ||
| message: `Not signed in to ${serverUrl}.`, | ||
| serverUrl, | ||
| })); | ||
| } | ||
| let target; | ||
| if (orgHint) { | ||
| target = findCredentialByOrgHint(file, serverUrl, orgHint); | ||
| } | ||
| else if (allForServer.length === 1) { | ||
| target = allForServer.at(0); | ||
| } | ||
| if (!target) { | ||
| return Result.err(new CredentialNotFoundError({ | ||
| message: `Multiple organizations are signed in on ${serverUrl} (${allForServer.map((c) => c.orgLabel ?? c.orgId).join(", ")}); pass --org to pick one.`, | ||
| serverUrl, | ||
| })); | ||
| } | ||
| await writeCredentialFile(configDir, removeCredential(file, serverUrl, target.orgId)); | ||
| return Result.ok({ orgId: target.orgId }); | ||
| }; | ||
| export const switchOrg = async (configDir, serverUrl, orgHint) => { | ||
| const file = await readCredentialFile(configDir); | ||
| const target = findCredentialByOrgHint(file, serverUrl, orgHint); | ||
| if (!target) { | ||
| const allForServer = listCredentialsForServer(file, serverUrl); | ||
| const known = allForServer.map((c) => c.orgLabel ?? c.orgId).join(", "); | ||
| return Result.err(new CredentialNotFoundError({ | ||
| message: `Not signed in to "${orgHint}" on ${serverUrl}.${known ? ` Known orgs here: ${known}.` : ""} Run \`stella auth login --org ${orgHint}\` first.`, | ||
| org: orgHint, | ||
| serverUrl, | ||
| })); | ||
| } | ||
| await writeCredentialFile(configDir, setDefaultOrg(file, serverUrl, target.orgId)); | ||
| return Result.ok({ orgId: target.orgId }); | ||
| }; | ||
| //# sourceMappingURL=manage.js.map |
| {"version":3,"file":"manage.js","sourceRoot":"","sources":["../../src/auth/manage.ts"],"names":[],"mappings":"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"} |
| import { Result } from "better-result"; | ||
| import { ManualCallbackParseError } from "./errors.js"; | ||
| export type ParsedManualCallback = { | ||
| readonly code: string; | ||
| /** `undefined` when the user pasted a bare code and no state could be checked. */ | ||
| readonly state: string | undefined; | ||
| }; | ||
| /** | ||
| * Parses manual-paste input. Accepts a full redirect URL (`http://127.0.0.1/ | ||
| * callback?code=...&state=...`) or a bare authorization code. | ||
| */ | ||
| export declare const parseManualCallbackInput: (input: string) => Result<ParsedManualCallback, ManualCallbackParseError>; |
| // Headless fallback: the user completes the OAuth flow in any browser (not | ||
| // necessarily one reachable from the CLI's machine) and pastes back either | ||
| // the full redirected URL or the bare `code` value. | ||
| import { Result } from "better-result"; | ||
| import { ManualCallbackParseError } from "./errors.js"; | ||
| /** | ||
| * Parses manual-paste input. Accepts a full redirect URL (`http://127.0.0.1/ | ||
| * callback?code=...&state=...`) or a bare authorization code. | ||
| */ | ||
| export const parseManualCallbackInput = (input) => { | ||
| const trimmed = input.trim(); | ||
| if (trimmed.length === 0) { | ||
| return Result.err(new ManualCallbackParseError({ message: "No input provided" })); | ||
| } | ||
| if (!trimmed.includes("://")) { | ||
| return Result.ok({ code: trimmed, state: undefined }); | ||
| } | ||
| const parsedUrl = Result.try(() => new URL(trimmed)); | ||
| if (Result.isError(parsedUrl)) { | ||
| return Result.err(new ManualCallbackParseError({ | ||
| message: `Could not parse "${trimmed}" as a URL or a bare authorization code`, | ||
| })); | ||
| } | ||
| const error = parsedUrl.value.searchParams.get("error"); | ||
| if (error) { | ||
| const description = parsedUrl.value.searchParams.get("error_description"); | ||
| return Result.err(new ManualCallbackParseError({ | ||
| message: description ?? error, | ||
| })); | ||
| } | ||
| const code = parsedUrl.value.searchParams.get("code"); | ||
| if (!code) { | ||
| return Result.err(new ManualCallbackParseError({ | ||
| message: "The pasted URL has no `code` query parameter", | ||
| })); | ||
| } | ||
| return Result.ok({ | ||
| code, | ||
| state: parsedUrl.value.searchParams.get("state") ?? undefined, | ||
| }); | ||
| }; | ||
| //# sourceMappingURL=manual-callback.js.map |
| {"version":3,"file":"manual-callback.js","sourceRoot":"","sources":["../../src/auth/manual-callback.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,2EAA2E;AAC3E,oDAAoD;AAEpD,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEvC,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAQvD;;;GAGG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CACtC,KAAa,EAC2C,EAAE;IAC1D,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,MAAM,CAAC,GAAG,CACf,IAAI,wBAAwB,CAAC,EAAE,OAAO,EAAE,mBAAmB,EAAE,CAAC,CAC/D,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,MAAM,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IACxD,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IACrD,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,OAAO,MAAM,CAAC,GAAG,CACf,IAAI,wBAAwB,CAAC;YAC3B,OAAO,EAAE,oBAAoB,OAAO,yCAAyC;SAC9E,CAAC,CACH,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACxD,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,WAAW,GAAG,SAAS,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;QAC1E,OAAO,MAAM,CAAC,GAAG,CACf,IAAI,wBAAwB,CAAC;YAC3B,OAAO,EAAE,WAAW,IAAI,KAAK;SAC9B,CAAC,CACH,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACtD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,MAAM,CAAC,GAAG,CACf,IAAI,wBAAwB,CAAC;YAC3B,OAAO,EAAE,8CAA8C;SACxD,CAAC,CACH,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC,EAAE,CAAC;QACf,IAAI;QACJ,KAAK,EAAE,SAAS,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,SAAS;KAC9D,CAAC,CAAC;AACL,CAAC,CAAC"} |
| import { Result } from "better-result"; | ||
| import { ClientRegistrationError } from "./errors.js"; | ||
| import type { AuthorizationServerMetadata } from "./oauth-metadata.js"; | ||
| /** Registers a fresh public loopback client with the requested scopes. */ | ||
| export declare const registerLoopbackClient: (metadata: AuthorizationServerMetadata, scopes: readonly string[]) => Promise<Result<string, ClientRegistrationError>>; |
| // Dynamic client registration (RFC 7591) against a `registration_endpoint` | ||
| // better-auth's oauth-provider exposes with `allowDynamicClientRegistration` | ||
| // and `allowUnauthenticatedClientRegistration` both enabled (see | ||
| // `apps/api/src/lib/auth.ts`). Unauthenticated registration always resolves | ||
| // to a public client (`token_endpoint_auth_method: "none"`) server-side | ||
| // regardless of what the request asks for, so the CLI's request body is | ||
| // mostly documentation of intent. | ||
| import { Result } from "better-result"; | ||
| import * as v from "valibot"; | ||
| import { AUTH_FETCH_TIMEOUT_MS, CLIENT_NAME, LOOPBACK_REDIRECT_URI, } from "./constants.js"; | ||
| import { ClientRegistrationError } from "./errors.js"; | ||
| const registrationResponseSchema = v.looseObject({ | ||
| client_id: v.string(), | ||
| }); | ||
| /** Registers a fresh public loopback client with the requested scopes. */ | ||
| export const registerLoopbackClient = async (metadata, scopes) => { | ||
| if (!metadata.registration_endpoint) { | ||
| return Result.err(new ClientRegistrationError({ | ||
| message: "The server does not advertise a registration_endpoint (allowDynamicClientRegistration is off). A pre-registered loopback client id would need to be configured out of band; this is a server-side gap, not something the CLI can work around.", | ||
| })); | ||
| } | ||
| const body = { | ||
| client_name: CLIENT_NAME, | ||
| grant_types: ["authorization_code", "refresh_token"], | ||
| redirect_uris: [LOOPBACK_REDIRECT_URI], | ||
| response_types: ["code"], | ||
| scope: scopes.join(" "), | ||
| token_endpoint_auth_method: "none", | ||
| type: "native", | ||
| }; | ||
| return await Result.tryPromise({ | ||
| catch: (cause) => cause instanceof ClientRegistrationError | ||
| ? cause | ||
| : new ClientRegistrationError({ | ||
| cause, | ||
| message: "Failed to register the stella CLI as an OAuth client", | ||
| }), | ||
| try: async () => { | ||
| const response = await fetch(metadata.registration_endpoint ?? "", { | ||
| body: JSON.stringify(body), | ||
| headers: { "Content-Type": "application/json" }, | ||
| method: "POST", | ||
| signal: AbortSignal.timeout(AUTH_FETCH_TIMEOUT_MS), | ||
| }); | ||
| if (!response.ok) { | ||
| const text = await response.text(); | ||
| throw new ClientRegistrationError({ | ||
| message: `registration_endpoint responded ${response.status}: ${text}`, | ||
| }); | ||
| } | ||
| const json = await response.json(); | ||
| const parsed = v.parse(registrationResponseSchema, json); | ||
| return parsed.client_id; | ||
| }, | ||
| }); | ||
| }; | ||
| //# sourceMappingURL=oauth-client-registration.js.map |
| {"version":3,"file":"oauth-client-registration.js","sourceRoot":"","sources":["../../src/auth/oauth-client-registration.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,6EAA6E;AAC7E,iEAAiE;AACjE,4EAA4E;AAC5E,wEAAwE;AACxE,wEAAwE;AACxE,kCAAkC;AAElC,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAE7B,OAAO,EACL,qBAAqB,EACrB,WAAW,EACX,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAGtD,MAAM,0BAA0B,GAAG,CAAC,CAAC,WAAW,CAAC;IAC/C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;CACtB,CAAC,CAAC;AAEH,0EAA0E;AAC1E,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,EACzC,QAAqC,EACrC,MAAyB,EACyB,EAAE;IACpD,IAAI,CAAC,QAAQ,CAAC,qBAAqB,EAAE,CAAC;QACpC,OAAO,MAAM,CAAC,GAAG,CACf,IAAI,uBAAuB,CAAC;YAC1B,OAAO,EACL,+OAA+O;SAClP,CAAC,CACH,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG;QACX,WAAW,EAAE,WAAW;QACxB,WAAW,EAAE,CAAC,oBAAoB,EAAE,eAAe,CAAC;QACpD,aAAa,EAAE,CAAC,qBAAqB,CAAC;QACtC,cAAc,EAAE,CAAC,MAAM,CAAC;QACxB,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;QACvB,0BAA0B,EAAE,MAAM;QAClC,IAAI,EAAE,QAAQ;KACf,CAAC;IAEF,OAAO,MAAM,MAAM,CAAC,UAAU,CAAC;QAC7B,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CACf,KAAK,YAAY,uBAAuB;YACtC,CAAC,CAAC,KAAK;YACP,CAAC,CAAC,IAAI,uBAAuB,CAAC;gBAC1B,KAAK;gBACL,OAAO,EAAE,sDAAsD;aAChE,CAAC;QACR,GAAG,EAAE,KAAK,IAAI,EAAE;YACd,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,qBAAqB,IAAI,EAAE,EAAE;gBACjE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAC1B,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,MAAM,EAAE,MAAM;gBACd,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,qBAAqB,CAAC;aACnD,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACnC,MAAM,IAAI,uBAAuB,CAAC;oBAChC,OAAO,EAAE,mCAAmC,QAAQ,CAAC,MAAM,KAAK,IAAI,EAAE;iBACvE,CAAC,CAAC;YACL,CAAC;YAED,MAAM,IAAI,GAAY,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YAC5C,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,0BAA0B,EAAE,IAAI,CAAC,CAAC;YACzD,OAAO,MAAM,CAAC,SAAS,CAAC;QAC1B,CAAC;KACF,CAAC,CAAC;AACL,CAAC,CAAC"} |
| import { Result } from "better-result"; | ||
| import { OAuthMetadataError } from "./errors.js"; | ||
| export type AuthorizationServerMetadata = { | ||
| readonly issuer: string; | ||
| readonly authorization_endpoint: string; | ||
| readonly token_endpoint: string; | ||
| readonly registration_endpoint?: string | undefined; | ||
| readonly code_challenge_methods_supported?: readonly string[] | undefined; | ||
| readonly scopes_supported?: readonly string[] | undefined; | ||
| readonly token_endpoint_auth_methods_supported?: readonly string[] | undefined; | ||
| }; | ||
| /** | ||
| * Discovers the OAuth authorization-server metadata for `serverUrl` by | ||
| * trying both the RFC 8414 root-issuer path and better-auth's actual mount | ||
| * path (see `AUTHORIZATION_SERVER_METADATA_PATHS`), in order. The two | ||
| * candidates are unrolled explicitly (not looped) so the second request | ||
| * only ever fires once the first has definitively failed. | ||
| */ | ||
| export declare const discoverAuthorizationServerMetadata: (serverUrl: string) => Promise<Result<AuthorizationServerMetadata, OAuthMetadataError>>; |
| // RFC 8414 authorization-server-metadata discovery. | ||
| import { Result } from "better-result"; | ||
| import * as v from "valibot"; | ||
| import { AUTH_FETCH_TIMEOUT_MS, AUTHORIZATION_SERVER_METADATA_PATHS, } from "./constants.js"; | ||
| import { OAuthMetadataError } from "./errors.js"; | ||
| const authorizationServerMetadataSchema = v.strictObject({ | ||
| issuer: v.pipe(v.string(), v.url()), | ||
| authorization_endpoint: v.pipe(v.string(), v.url()), | ||
| token_endpoint: v.pipe(v.string(), v.url()), | ||
| registration_endpoint: v.optional(v.pipe(v.string(), v.url())), | ||
| code_challenge_methods_supported: v.optional(v.array(v.string())), | ||
| scopes_supported: v.optional(v.array(v.string())), | ||
| token_endpoint_auth_methods_supported: v.optional(v.array(v.string())), | ||
| }); | ||
| const fetchCandidate = async (url) => { | ||
| const attempt = await Result.tryPromise(async () => { | ||
| const response = await fetch(url, { | ||
| headers: { Accept: "application/json" }, | ||
| signal: AbortSignal.timeout(AUTH_FETCH_TIMEOUT_MS), | ||
| }); | ||
| return response.ok ? await response.json() : undefined; | ||
| }); | ||
| if (Result.isError(attempt) || attempt.value === undefined) { | ||
| return undefined; | ||
| } | ||
| const parsed = v.safeParse(authorizationServerMetadataSchema, attempt.value); | ||
| return parsed.success ? parsed.output : undefined; | ||
| }; | ||
| /** | ||
| * Discovers the OAuth authorization-server metadata for `serverUrl` by | ||
| * trying both the RFC 8414 root-issuer path and better-auth's actual mount | ||
| * path (see `AUTHORIZATION_SERVER_METADATA_PATHS`), in order. The two | ||
| * candidates are unrolled explicitly (not looped) so the second request | ||
| * only ever fires once the first has definitively failed. | ||
| */ | ||
| export const discoverAuthorizationServerMetadata = async (serverUrl) => { | ||
| const origin = serverUrl.replace(/\/$/u, ""); | ||
| const [rootPath, mountedPath] = AUTHORIZATION_SERVER_METADATA_PATHS; | ||
| const found = (await fetchCandidate(`${origin}${rootPath}`)) ?? | ||
| (await fetchCandidate(`${origin}${mountedPath}`)); | ||
| if (found) { | ||
| return Result.ok(found); | ||
| } | ||
| return Result.err(new OAuthMetadataError({ | ||
| message: `Could not discover OAuth authorization server metadata at ${serverUrl}. Pass --server pointing at the stella API origin (not the web app), and confirm the server exposes ${AUTHORIZATION_SERVER_METADATA_PATHS.join(" or ")}.`, | ||
| serverUrl, | ||
| })); | ||
| }; | ||
| //# sourceMappingURL=oauth-metadata.js.map |
| {"version":3,"file":"oauth-metadata.js","sourceRoot":"","sources":["../../src/auth/oauth-metadata.ts"],"names":[],"mappings":"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"} |
| export type PkcePair = { | ||
| readonly codeVerifier: string; | ||
| readonly codeChallenge: string; | ||
| }; | ||
| /** Generates a fresh PKCE verifier/challenge pair (S256). */ | ||
| export declare const createPkcePair: () => PkcePair; | ||
| /** Derives the S256 code challenge for a given verifier (exported for tests/vectors). */ | ||
| export declare const generateCodeChallenge: (codeVerifier: string) => string; | ||
| /** Generates a random `state` parameter used to bind the callback to this login attempt. */ | ||
| export declare const createOAuthState: () => string; |
| // PKCE (RFC 7636) helpers for the loopback authorization-code flow. | ||
| // | ||
| // Mirrors the existing repo convention for PKCE generation | ||
| // (`apps/api/src/handlers/mcp-connectors/oauth.ts`'s `createPkce`): random | ||
| // bytes via Web Crypto, S256 challenge via `node:crypto` `createHash` so the | ||
| // published CLI runs under plain Node (Bun executes `node:*` natively). | ||
| import { createHash } from "node:crypto"; | ||
| const VERIFIER_BYTES = 32; | ||
| const STATE_BYTES = 32; | ||
| const randomBase64Url = (byteLength) => { | ||
| const bytes = new Uint8Array(byteLength); | ||
| crypto.getRandomValues(bytes); | ||
| return Buffer.from(bytes).toString("base64url"); | ||
| }; | ||
| /** Generates a fresh PKCE verifier/challenge pair (S256). */ | ||
| export const createPkcePair = () => { | ||
| const codeVerifier = randomBase64Url(VERIFIER_BYTES); | ||
| const codeChallenge = generateCodeChallenge(codeVerifier); | ||
| return { codeChallenge, codeVerifier }; | ||
| }; | ||
| /** Derives the S256 code challenge for a given verifier (exported for tests/vectors). */ | ||
| export const generateCodeChallenge = (codeVerifier) => createHash("sha256").update(codeVerifier).digest("base64url"); | ||
| /** Generates a random `state` parameter used to bind the callback to this login attempt. */ | ||
| export const createOAuthState = () => randomBase64Url(STATE_BYTES); | ||
| //# sourceMappingURL=pkce.js.map |
| {"version":3,"file":"pkce.js","sourceRoot":"","sources":["../../src/auth/pkce.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,EAAE;AACF,2DAA2D;AAC3D,2EAA2E;AAC3E,6EAA6E;AAC7E,wEAAwE;AAExE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,cAAc,GAAG,EAAE,CAAC;AAC1B,MAAM,WAAW,GAAG,EAAE,CAAC;AAEvB,MAAM,eAAe,GAAG,CAAC,UAAkB,EAAU,EAAE;IACrD,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC;IACzC,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAC9B,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AAClD,CAAC,CAAC;AAOF,6DAA6D;AAC7D,MAAM,CAAC,MAAM,cAAc,GAAG,GAAa,EAAE;IAC3C,MAAM,YAAY,GAAG,eAAe,CAAC,cAAc,CAAC,CAAC;IACrD,MAAM,aAAa,GAAG,qBAAqB,CAAC,YAAY,CAAC,CAAC;IAC1D,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,CAAC;AACzC,CAAC,CAAC;AAEF,yFAAyF;AACzF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,YAAoB,EAAU,EAAE,CACpE,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;AAEhE,4FAA4F;AAC5F,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAW,EAAE,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC"} |
| import { Result } from "better-result"; | ||
| import { CliBaseError } from "./errors.js"; | ||
| declare class InvalidScopeInputError extends CliBaseError<"InvalidScopeInputError"> { | ||
| readonly name = "InvalidScopeInputError"; | ||
| constructor(message: string); | ||
| } | ||
| export declare const parseScopesFlag: (input: string) => Result<readonly string[], InvalidScopeInputError>; | ||
| export { InvalidScopeInputError }; |
| // `--scopes` parsing. Validity of individual scope names is ultimately the | ||
| // server's call (`opts.scopes` in `oauthProvider`, see the design brief's | ||
| // "let a feature-disabled call fail with the server's actual error" | ||
| // principle applied to scopes): this only rejects obviously-malformed input | ||
| // (empty, containing whitespace) before it reaches a URL query string. | ||
| import { Result } from "better-result"; | ||
| import * as v from "valibot"; | ||
| import { CliBaseError } from "./errors.js"; | ||
| class InvalidScopeInputError extends CliBaseError { | ||
| name = "InvalidScopeInputError"; | ||
| constructor(message) { | ||
| super("InvalidScopeInputError", message); | ||
| } | ||
| } | ||
| const scopeTokenSchema = v.pipe(v.string(), v.trim(), v.minLength(1), v.regex(/^\S+$/u, "Scope names cannot contain whitespace")); | ||
| export const parseScopesFlag = (input) => { | ||
| const tokens = input | ||
| .split(",") | ||
| .map((token) => token.trim()) | ||
| .filter((token) => token.length > 0); | ||
| if (tokens.length === 0) { | ||
| return Result.err(new InvalidScopeInputError("--scopes was empty")); | ||
| } | ||
| const parsed = v.safeParse(v.array(scopeTokenSchema), tokens); | ||
| if (!parsed.success) { | ||
| return Result.err(new InvalidScopeInputError(`Invalid --scopes value: ${parsed.issues.map((issue) => issue.message).join("; ")}`)); | ||
| } | ||
| return Result.ok(parsed.output); | ||
| }; | ||
| export { InvalidScopeInputError }; | ||
| //# sourceMappingURL=scopes.js.map |
| {"version":3,"file":"scopes.js","sourceRoot":"","sources":["../../src/auth/scopes.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,0EAA0E;AAC1E,oEAAoE;AACpE,4EAA4E;AAC5E,uEAAuE;AAEvE,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAE7B,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,sBAAuB,SAAQ,YAAsC;IACvD,IAAI,GAAG,wBAAwB,CAAC;IAElD,YAAY,OAAe;QACzB,KAAK,CAAC,wBAAwB,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;CACF;AAED,MAAM,gBAAgB,GAAG,CAAC,CAAC,IAAI,CAC7B,CAAC,CAAC,MAAM,EAAE,EACV,CAAC,CAAC,IAAI,EAAE,EACR,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EACd,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,uCAAuC,CAAC,CAC3D,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,KAAa,EACsC,EAAE;IACrD,MAAM,MAAM,GAAG,KAAK;SACjB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;SAC5B,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACvC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,MAAM,CAAC,GAAG,CAAC,IAAI,sBAAsB,CAAC,oBAAoB,CAAC,CAAC,CAAC;IACtE,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC,CAAC;IAC9D,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,MAAM,CAAC,GAAG,CACf,IAAI,sBAAsB,CACxB,2BAA2B,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACpF,CACF,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAClC,CAAC,CAAC;AAEF,OAAO,EAAE,sBAAsB,EAAE,CAAC"} |
| import { Result } from "better-result"; | ||
| import { ServerUrlNotConfiguredError } from "./errors.js"; | ||
| export declare const resolveServerUrl: (configDir: string, flagValue: string | undefined) => Promise<Result<string, ServerUrlNotConfiguredError>>; |
| // `--server` resolution: no hosted-SaaS URL is baked in (self-hosting is | ||
| // first-class; the CLI must not silently assume a build-time origin). | ||
| // Priority: `--server` flag > `STELLA_SERVER_URL` env var > the last server | ||
| // `stella auth login` succeeded against (`config.json#defaultServerUrl`). | ||
| import { Result } from "better-result"; | ||
| import { STELLA_SERVER_URL } from "../env.js"; | ||
| import { readCliConfig } from "./cli-config.js"; | ||
| import { SERVER_URL_ENV_VAR } from "./constants.js"; | ||
| import { ServerUrlNotConfiguredError } from "./errors.js"; | ||
| const normalizeServerUrl = (input) => input.replace(/\/$/u, ""); | ||
| export const resolveServerUrl = async (configDir, flagValue) => { | ||
| if (flagValue) { | ||
| return Result.ok(normalizeServerUrl(flagValue)); | ||
| } | ||
| if (STELLA_SERVER_URL) { | ||
| return Result.ok(normalizeServerUrl(STELLA_SERVER_URL)); | ||
| } | ||
| const config = await readCliConfig(configDir); | ||
| if (config.defaultServerUrl) { | ||
| return Result.ok(normalizeServerUrl(config.defaultServerUrl)); | ||
| } | ||
| return Result.err(new ServerUrlNotConfiguredError({ | ||
| message: `No server configured. Pass --server <url>, set ${SERVER_URL_ENV_VAR}, or run \`stella auth login --server <url>\` once to set the default.`, | ||
| })); | ||
| }; | ||
| //# sourceMappingURL=server-resolution.js.map |
| {"version":3,"file":"server-resolution.js","sourceRoot":"","sources":["../../src/auth/server-resolution.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,sEAAsE;AACtE,4EAA4E;AAC5E,0EAA0E;AAE1E,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAC;AAE1D,MAAM,kBAAkB,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAEhF,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EACnC,SAAiB,EACjB,SAA6B,EACyB,EAAE;IACxD,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,MAAM,CAAC,EAAE,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC;IAClD,CAAC;IAED,IAAI,iBAAiB,EAAE,CAAC;QACtB,OAAO,MAAM,CAAC,EAAE,CAAC,kBAAkB,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,SAAS,CAAC,CAAC;IAC9C,IAAI,MAAM,CAAC,gBAAgB,EAAE,CAAC;QAC5B,OAAO,MAAM,CAAC,EAAE,CAAC,kBAAkB,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAChE,CAAC;IAED,OAAO,MAAM,CAAC,GAAG,CACf,IAAI,2BAA2B,CAAC;QAC9B,OAAO,EAAE,kDAAkD,kBAAkB,wEAAwE;KACtJ,CAAC,CACH,CAAC;AACJ,CAAC,CAAC"} |
| import { Result } from "better-result"; | ||
| import { TokenExchangeError, TokenRefreshError } from "./errors.js"; | ||
| import type { AuthorizationServerMetadata } from "./oauth-metadata.js"; | ||
| export type TokenResponse = { | ||
| readonly access_token: string; | ||
| readonly expires_in: number; | ||
| readonly refresh_token?: string | undefined; | ||
| readonly scope?: string | undefined; | ||
| readonly token_type: string; | ||
| }; | ||
| export type ExchangeAuthorizationCodeInput = { | ||
| readonly metadata: AuthorizationServerMetadata; | ||
| readonly clientId: string; | ||
| readonly code: string; | ||
| readonly codeVerifier: string; | ||
| readonly redirectUri: string; | ||
| readonly resource: string; | ||
| }; | ||
| export declare const exchangeAuthorizationCode: ({ clientId, code, codeVerifier, metadata, redirectUri, resource, }: ExchangeAuthorizationCodeInput) => Promise<Result<TokenResponse, TokenExchangeError>>; | ||
| export type RefreshAccessTokenInput = { | ||
| readonly metadata: AuthorizationServerMetadata; | ||
| readonly clientId: string; | ||
| readonly refreshToken: string; | ||
| readonly resource: string; | ||
| }; | ||
| export declare const refreshAccessToken: ({ clientId, metadata, refreshToken, resource, }: RefreshAccessTokenInput) => Promise<Result<TokenResponse, TokenRefreshError>>; |
| // `/oauth2/token` grant handling: authorization_code exchange and | ||
| // refresh_token rotation. | ||
| import { Result } from "better-result"; | ||
| import * as v from "valibot"; | ||
| import { AUTH_FETCH_TIMEOUT_MS } from "./constants.js"; | ||
| import { TokenExchangeError, TokenRefreshError } from "./errors.js"; | ||
| const tokenResponseSchema = v.looseObject({ | ||
| access_token: v.string(), | ||
| expires_in: v.number(), | ||
| refresh_token: v.optional(v.string()), | ||
| scope: v.optional(v.string()), | ||
| token_type: v.string(), | ||
| }); | ||
| const oauthErrorBodySchema = v.looseObject({ | ||
| error: v.string(), | ||
| error_description: v.optional(v.string()), | ||
| }); | ||
| const describeTokenEndpointError = async (response) => { | ||
| const text = await response.text(); | ||
| const fallback = { | ||
| message: text.length > 0 ? text : `token endpoint responded ${response.status}`, | ||
| }; | ||
| const parsedJson = Result.try(() => JSON.parse(text)); | ||
| if (Result.isError(parsedJson)) { | ||
| return fallback; | ||
| } | ||
| const parsed = v.safeParse(oauthErrorBodySchema, parsedJson.value); | ||
| if (!parsed.success) { | ||
| return fallback; | ||
| } | ||
| return { | ||
| error: parsed.output.error, | ||
| message: parsed.output.error_description ?? parsed.output.error, | ||
| }; | ||
| }; | ||
| export const exchangeAuthorizationCode = async ({ clientId, code, codeVerifier, metadata, redirectUri, resource, }) => { | ||
| const body = new URLSearchParams({ | ||
| client_id: clientId, | ||
| code, | ||
| code_verifier: codeVerifier, | ||
| grant_type: "authorization_code", | ||
| redirect_uri: redirectUri, | ||
| resource, | ||
| }); | ||
| return await Result.tryPromise({ | ||
| catch: (cause) => cause instanceof TokenExchangeError | ||
| ? cause | ||
| : new TokenExchangeError({ | ||
| cause, | ||
| message: "Failed to exchange the authorization code for a token", | ||
| }), | ||
| try: async () => { | ||
| const response = await fetch(metadata.token_endpoint, { | ||
| body, | ||
| headers: { "Content-Type": "application/x-www-form-urlencoded" }, | ||
| method: "POST", | ||
| signal: AbortSignal.timeout(AUTH_FETCH_TIMEOUT_MS), | ||
| }); | ||
| if (!response.ok) { | ||
| const described = await describeTokenEndpointError(response); | ||
| throw new TokenExchangeError({ | ||
| message: described.message, | ||
| oauthError: described.error, | ||
| }); | ||
| } | ||
| return v.parse(tokenResponseSchema, await response.json()); | ||
| }, | ||
| }); | ||
| }; | ||
| export const refreshAccessToken = async ({ clientId, metadata, refreshToken, resource, }) => { | ||
| const body = new URLSearchParams({ | ||
| client_id: clientId, | ||
| grant_type: "refresh_token", | ||
| refresh_token: refreshToken, | ||
| resource, | ||
| }); | ||
| return await Result.tryPromise({ | ||
| catch: (cause) => cause instanceof TokenRefreshError | ||
| ? cause | ||
| : new TokenRefreshError({ | ||
| cause, | ||
| message: "Failed to refresh the access token", | ||
| }), | ||
| try: async () => { | ||
| const response = await fetch(metadata.token_endpoint, { | ||
| body, | ||
| headers: { "Content-Type": "application/x-www-form-urlencoded" }, | ||
| method: "POST", | ||
| signal: AbortSignal.timeout(AUTH_FETCH_TIMEOUT_MS), | ||
| }); | ||
| if (!response.ok) { | ||
| const described = await describeTokenEndpointError(response); | ||
| throw new TokenRefreshError({ | ||
| message: described.message, | ||
| oauthError: described.error, | ||
| }); | ||
| } | ||
| return v.parse(tokenResponseSchema, await response.json()); | ||
| }, | ||
| }); | ||
| }; | ||
| //# sourceMappingURL=token-exchange.js.map |
| {"version":3,"file":"token-exchange.js","sourceRoot":"","sources":["../../src/auth/token-exchange.ts"],"names":[],"mappings":"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"} |
| import type { Command, RouteMap } from "@stricli/core"; | ||
| import type { Context } from "./context.js"; | ||
| import type { ResourceNode } from "./resource-types.js"; | ||
| import type { RouteNode } from "./route-types.js"; | ||
| /** A stricli routing target: a leaf command or a nested route map. */ | ||
| type RoutingTarget = Command<Context> | RouteMap<Context>; | ||
| /** | ||
| * Fold a generated `RouteNode` (route) into stricli `RoutingTarget` children, | ||
| * ready to merge into the root route map's `routes`. | ||
| */ | ||
| export declare const buildGeneratedRoutes: (node: RouteNode) => Record<string, RoutingTarget>; | ||
| /** | ||
| * Fold a generated resource `ResourceNode` (route) into a single stricli | ||
| * `RouteMap` for the reserved `reference` top-level command (spec S5.4). | ||
| */ | ||
| export declare const buildResourceRoutes: (node: ResourceNode) => RouteMap<Context>; | ||
| export type { RouteMap }; |
| // Assembles a stricli `RoutingTarget` tree from a generated `RouteNode` (spec | ||
| // 051 S5.1). Each leaf becomes a `buildCommand` whose `func` delegates to the | ||
| // generic `runLeafCommand` executor; each route node becomes a `buildRouteMap`. | ||
| // stricli's own flag parsing is kept deliberately permissive (every value flag | ||
| // is an optional parsed string, booleans are optional): all validation and | ||
| // exit-code selection happen inside the executor, so `process.exitCode` is set | ||
| // precisely rather than defaulted by stricli. | ||
| import { buildCommand, buildRouteMap } from "@stricli/core"; | ||
| import { flagKey, RESERVED_FLAG_KEYS, runLeafCommand, } from "./run-leaf-command.js"; | ||
| import { runResourceCommand } from "./run-resource-command.js"; | ||
| const identity = (value) => value; | ||
| const parsedStringFlag = (brief) => ({ brief, kind: "parsed", optional: true, parse: identity }); | ||
| const variadicFlag = (brief) => ({ brief, kind: "parsed", variadic: true, parse: identity }); | ||
| const booleanFlag = (brief, withNegated) => ({ brief, kind: "boolean", optional: true, withNegated }); | ||
| const flagBrief = (spec) => { | ||
| const parts = [spec.required ? "(required)" : "(optional)", spec.kind]; | ||
| if (spec.enum) { | ||
| parts.push(`one of: ${spec.enum.join(", ")}`); | ||
| } | ||
| if (spec.min !== undefined || spec.max !== undefined) { | ||
| parts.push(`range ${spec.min ?? "-inf"}..${spec.max ?? "inf"}`); | ||
| } | ||
| if (spec.repeatable) { | ||
| parts.push("repeatable"); | ||
| } | ||
| return parts.join(" "); | ||
| }; | ||
| const hasLimitProp = (spec) => { | ||
| const properties = spec.inputSchema["properties"]; | ||
| if (typeof properties !== "object" || properties === null) { | ||
| return false; | ||
| } | ||
| return "limit" in properties; | ||
| }; | ||
| const buildLeafFlags = (spec) => { | ||
| const flags = {}; | ||
| for (const flagSpec of spec.flags) { | ||
| const key = flagKey(flagSpec); | ||
| const brief = flagBrief(flagSpec); | ||
| if (flagSpec.kind === "boolean") { | ||
| flags[key] = booleanFlag(brief, true); | ||
| continue; | ||
| } | ||
| if (flagSpec.repeatable) { | ||
| flags[key] = variadicFlag(brief); | ||
| continue; | ||
| } | ||
| flags[key] = parsedStringFlag(brief); | ||
| } | ||
| // Reserved global flags every command carries (spec S1/S3). | ||
| flags[RESERVED_FLAG_KEYS.input] = parsedStringFlag("Full tool-args JSON: '<json>' | - (stdin) | @file"); | ||
| flags[RESERVED_FLAG_KEYS.output] = parsedStringFlag("Output format: json | table"); | ||
| flags[RESERVED_FLAG_KEYS.json] = booleanFlag("Output JSON (= --output json)", false); | ||
| flags[RESERVED_FLAG_KEYS.table] = booleanFlag("Output a table (= --output table)", false); | ||
| if (spec.paginated) { | ||
| flags[RESERVED_FLAG_KEYS.cursor] = parsedStringFlag("Opaque pagination cursor from a previous page"); | ||
| flags[RESERVED_FLAG_KEYS.all] = booleanFlag("Follow cursors and return every page (bounded)", false); | ||
| if (hasLimitProp(spec)) { | ||
| flags[RESERVED_FLAG_KEYS.limit] = parsedStringFlag("Max items per page"); | ||
| } | ||
| } | ||
| if (spec.destructive) { | ||
| flags[RESERVED_FLAG_KEYS.yes] = booleanFlag("Skip the destructive-op confirmation prompt", false); | ||
| } | ||
| return flags; | ||
| }; | ||
| const leafBrief = (spec) => { | ||
| const inputHint = spec.inputOnly.length > 0 | ||
| ? ` (via --input only: ${spec.inputOnly.join(", ")})` | ||
| : ""; | ||
| return `Run the ${spec.toolName} tool${inputHint}`; | ||
| }; | ||
| const buildLeafCommand = (spec) => { | ||
| const flags = buildLeafFlags(spec); | ||
| const builderArgs = { | ||
| docs: { brief: leafBrief(spec) }, | ||
| parameters: { flags }, | ||
| func: async function func(parsedFlags) { | ||
| await runLeafCommand({ context: this, flags: parsedFlags, spec }); | ||
| }, | ||
| }; | ||
| // SAFETY: flags is assembled from FlagSpecs at build time, so the concrete | ||
| // FLAGS generic cannot be spelled out; every entry is a valid stricli flag | ||
| // parameter and the executor reads flags by name. | ||
| const typedArgs = | ||
| // eslint-disable-next-line no-unsafe-type-assertion -- see SAFETY comment above | ||
| builderArgs; | ||
| return buildCommand(typedArgs); | ||
| }; | ||
| const buildRouteNode = (node, brief) => { | ||
| if (node.kind === "leaf") { | ||
| return buildLeafCommand(node.spec); | ||
| } | ||
| const routes = {}; | ||
| for (const [name, child] of Object.entries(node.children)) { | ||
| routes[name] = buildRouteNode(child, `The ${name} command group`); | ||
| } | ||
| return buildRouteMap({ docs: { brief }, routes }); | ||
| }; | ||
| /** | ||
| * Fold a generated `RouteNode` (route) into stricli `RoutingTarget` children, | ||
| * ready to merge into the root route map's `routes`. | ||
| */ | ||
| export const buildGeneratedRoutes = (node) => { | ||
| if (node.kind !== "route") { | ||
| return {}; | ||
| } | ||
| const routes = {}; | ||
| for (const [name, child] of Object.entries(node.children)) { | ||
| routes[name] = buildRouteNode(child, `The ${name} command group`); | ||
| } | ||
| return routes; | ||
| }; | ||
| const outputOnlyFlags = () => ({ | ||
| [RESERVED_FLAG_KEYS.output]: parsedStringFlag("Output format: json | table"), | ||
| [RESERVED_FLAG_KEYS.json]: booleanFlag("Output JSON (= --output json)", false), | ||
| [RESERVED_FLAG_KEYS.table]: booleanFlag("Output a table (= --output table)", false), | ||
| }); | ||
| const resourceLeafBrief = (spec) => spec.kind === "list" | ||
| ? "List the static reference resources exposed by the stella server" | ||
| : `Read the ${spec.name} reference resource`; | ||
| const buildResourceLeaf = (spec) => { | ||
| const builderArgs = { | ||
| docs: { brief: resourceLeafBrief(spec) }, | ||
| parameters: { flags: outputOnlyFlags() }, | ||
| func: async function func(parsedFlags) { | ||
| await runResourceCommand({ context: this, flags: parsedFlags, spec }); | ||
| }, | ||
| }; | ||
| const typedArgs = | ||
| // eslint-disable-next-line no-unsafe-type-assertion -- see SAFETY comment on buildLeafCommand | ||
| builderArgs; | ||
| return buildCommand(typedArgs); | ||
| }; | ||
| const buildResourceNode = (node, brief) => { | ||
| if (node.kind === "leaf") { | ||
| return buildResourceLeaf(node.spec); | ||
| } | ||
| const routes = {}; | ||
| for (const [name, child] of Object.entries(node.children)) { | ||
| routes[name] = buildResourceNode(child, `The ${name} command group`); | ||
| } | ||
| return buildRouteMap({ docs: { brief }, routes }); | ||
| }; | ||
| /** | ||
| * Fold a generated resource `ResourceNode` (route) into a single stricli | ||
| * `RouteMap` for the reserved `reference` top-level command (spec S5.4). | ||
| */ | ||
| export const buildResourceRoutes = (node) => { | ||
| const routes = {}; | ||
| if (node.kind === "route") { | ||
| for (const [name, child] of Object.entries(node.children)) { | ||
| routes[name] = buildResourceNode(child, `The ${name} command group`); | ||
| } | ||
| } | ||
| return buildRouteMap({ | ||
| docs: { brief: "Read the server's static reference resources" }, | ||
| routes, | ||
| }); | ||
| }; | ||
| //# sourceMappingURL=build-cli-tree.js.map |
| {"version":3,"file":"build-cli-tree.js","sourceRoot":"","sources":["../src/build-cli-tree.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,8EAA8E;AAC9E,gFAAgF;AAChF,+EAA+E;AAC/E,2EAA2E;AAC3E,+EAA+E;AAC/E,8CAA8C;AAE9C,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAW5D,OAAO,EACL,OAAO,EACP,kBAAkB,EAClB,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAK/D,MAAM,QAAQ,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,KAAK,CAAC;AAElD,MAAM,gBAAgB,GAAG,CAAC,KAAa,EAAE,EAAE,CACzC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAU,CAAC;AAExE,MAAM,YAAY,GAAG,CAAC,KAAa,EAAE,EAAE,CACrC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAU,CAAC;AAExE,MAAM,WAAW,GAAG,CAAC,KAAa,EAAE,WAAoB,EAAE,EAAE,CAC1D,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,CAAU,CAAC;AAErE,MAAM,SAAS,GAAG,CAAC,IAAc,EAAU,EAAE;IAC3C,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACvE,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,KAAK,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChD,CAAC;IACD,IAAI,IAAI,CAAC,GAAG,KAAK,SAAS,IAAI,IAAI,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;QACrD,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,GAAG,IAAI,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,KAAK,EAAE,CAAC,CAAC;IAClE,CAAC;IACD,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QACpB,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,CAAC,IAAqB,EAAW,EAAE;IACtD,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;IAClD,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QAC1D,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,OAAO,IAAI,UAAU,CAAC;AAC/B,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CAAC,IAAqB,EAA2B,EAAE;IACxE,MAAM,KAAK,GAA4B,EAAE,CAAC;IAE1C,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QAClC,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC9B,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;QAClC,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAChC,KAAK,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YACtC,SAAS;QACX,CAAC;QACD,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;YACxB,KAAK,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YACjC,SAAS;QACX,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACvC,CAAC;IAED,4DAA4D;IAC5D,KAAK,CAAC,kBAAkB,CAAC,KAAK,CAAC,GAAG,gBAAgB,CAChD,mDAAmD,CACpD,CAAC;IACF,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,GAAG,gBAAgB,CACjD,6BAA6B,CAC9B,CAAC;IACF,KAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,WAAW,CAC1C,+BAA+B,EAC/B,KAAK,CACN,CAAC;IACF,KAAK,CAAC,kBAAkB,CAAC,KAAK,CAAC,GAAG,WAAW,CAC3C,mCAAmC,EACnC,KAAK,CACN,CAAC;IAEF,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,GAAG,gBAAgB,CACjD,+CAA+C,CAChD,CAAC;QACF,KAAK,CAAC,kBAAkB,CAAC,GAAG,CAAC,GAAG,WAAW,CACzC,gDAAgD,EAChD,KAAK,CACN,CAAC;QACF,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,KAAK,CAAC,kBAAkB,CAAC,KAAK,CAAC,GAAG,gBAAgB,CAAC,oBAAoB,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;IAED,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,KAAK,CAAC,kBAAkB,CAAC,GAAG,CAAC,GAAG,WAAW,CACzC,6CAA6C,EAC7C,KAAK,CACN,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF,MAAM,SAAS,GAAG,CAAC,IAAqB,EAAU,EAAE;IAClD,MAAM,SAAS,GACb,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC;QACvB,CAAC,CAAC,uBAAuB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;QACrD,CAAC,CAAC,EAAE,CAAC;IACT,OAAO,WAAW,IAAI,CAAC,QAAQ,QAAQ,SAAS,EAAE,CAAC;AACrD,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAAG,CAAC,IAAqB,EAAiB,EAAE;IAChE,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,WAAW,GAAG;QAClB,IAAI,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE;QAChC,UAAU,EAAE,EAAE,KAAK,EAAE;QACrB,IAAI,EAAE,KAAK,UAAU,IAAI,CAEvB,WAAoC;YAEpC,MAAM,cAAc,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;QACpE,CAAC;KACF,CAAC;IACF,2EAA2E;IAC3E,2EAA2E;IAC3E,kDAAkD;IAClD,MAAM,SAAS;IACb,gFAAgF;IAChF,WAAyE,CAAC;IAC5E,OAAO,YAAY,CAAC,SAAS,CAAC,CAAC;AACjC,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CAAC,IAAe,EAAE,KAAa,EAAiB,EAAE;IACvE,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACzB,OAAO,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC;IACD,MAAM,MAAM,GAAkC,EAAE,CAAC;IACjD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1D,MAAM,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,KAAK,EAAE,OAAO,IAAI,gBAAgB,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,aAAa,CAAC,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;AACpD,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,IAAe,EACgB,EAAE;IACjC,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC1B,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,MAAM,GAAkC,EAAE,CAAC;IACjD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1D,MAAM,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,KAAK,EAAE,OAAO,IAAI,gBAAgB,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,GAA4B,EAAE,CAAC,CAAC;IACtD,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,gBAAgB,CAAC,6BAA6B,CAAC;IAC5E,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,WAAW,CACpC,+BAA+B,EAC/B,KAAK,CACN;IACD,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,WAAW,CACrC,mCAAmC,EACnC,KAAK,CACN;CACF,CAAC,CAAC;AAEH,MAAM,iBAAiB,GAAG,CAAC,IAAsB,EAAU,EAAE,CAC3D,IAAI,CAAC,IAAI,KAAK,MAAM;IAClB,CAAC,CAAC,kEAAkE;IACpE,CAAC,CAAC,YAAY,IAAI,CAAC,IAAI,qBAAqB,CAAC;AAEjD,MAAM,iBAAiB,GAAG,CAAC,IAAsB,EAAiB,EAAE;IAClE,MAAM,WAAW,GAAG;QAClB,IAAI,EAAE,EAAE,KAAK,EAAE,iBAAiB,CAAC,IAAI,CAAC,EAAE;QACxC,UAAU,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,EAAE;QACxC,IAAI,EAAE,KAAK,UAAU,IAAI,CAEvB,WAAoC;YAEpC,MAAM,kBAAkB,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;QACxE,CAAC;KACF,CAAC;IACF,MAAM,SAAS;IACb,8FAA8F;IAC9F,WAAyE,CAAC;IAC5E,OAAO,YAAY,CAAC,SAAS,CAAC,CAAC;AACjC,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CACxB,IAAkB,EAClB,KAAa,EACE,EAAE;IACjB,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACzB,OAAO,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC;IACD,MAAM,MAAM,GAAkC,EAAE,CAAC;IACjD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1D,MAAM,CAAC,IAAI,CAAC,GAAG,iBAAiB,CAAC,KAAK,EAAE,OAAO,IAAI,gBAAgB,CAAC,CAAC;IACvE,CAAC;IACD,OAAO,aAAa,CAAC,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;AACpD,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,IAAkB,EAAqB,EAAE;IAC3E,MAAM,MAAM,GAAkC,EAAE,CAAC;IACjD,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC1B,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1D,MAAM,CAAC,IAAI,CAAC,GAAG,iBAAiB,CAAC,KAAK,EAAE,OAAO,IAAI,gBAAgB,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IACD,OAAO,aAAa,CAAC;QACnB,IAAI,EAAE,EAAE,KAAK,EAAE,8CAA8C,EAAE;QAC/D,MAAM;KACP,CAAC,CAAC;AACL,CAAC,CAAC"} |
| export declare const CLI_LATEST_HEADER = "x-stella-cli-latest"; | ||
| export declare const CLI_MINIMUM_HEADER = "x-stella-cli-minimum"; | ||
| /** -1 / 0 / 1 when both versions parse; `undefined` when either does not. */ | ||
| export declare const compareVersions: (a: string | undefined, b: string | undefined) => number | undefined; | ||
| /** What a nudge evaluation produced: an optional line + the version to remember. */ | ||
| export type VersionNudge = { | ||
| line?: string; | ||
| nudgeVersion?: string; | ||
| }; | ||
| /** | ||
| * Decide whether to nudge (spec 051 addendum). Priority: an explicit minimum the | ||
| * current version is below becomes an "unsupported" warning; otherwise a newer | ||
| * latest becomes an update hint. Anti-nag: if the target version equals the one | ||
| * last nudged, stay silent. Any unparsable/missing version yields no nudge. | ||
| */ | ||
| export declare const buildVersionNudge: ({ current, latest, minimum, lastNudged, }: { | ||
| current: string; | ||
| latest: string | undefined; | ||
| minimum: string | undefined; | ||
| lastNudged: string | undefined; | ||
| }) => VersionNudge; |
| // CLI update nudge (spec 051 addendum). The runtime `tools/list` fetch carries | ||
| // the server's advertised latest CLI version in a response header; if it is | ||
| // newer than the running CLI, we print exactly one stderr hint. This module is | ||
| // pure (no I/O): version parsing is Valibot-validated and any unparsable or | ||
| // missing input yields no nudge (fail-silent). The nudge never touches stdout | ||
| // or the exit code. | ||
| import * as v from "valibot"; | ||
| // Mirror of `apps/api/src/mcp/constants.ts` (no shared module between the API and | ||
| // the published CLI by design). Keep these header names in sync with that file. | ||
| export const CLI_LATEST_HEADER = "x-stella-cli-latest"; | ||
| export const CLI_MINIMUM_HEADER = "x-stella-cli-minimum"; | ||
| const SemVerSchema = v.pipe(v.string(), v.regex(/^\d+\.\d+\.\d+$/u)); | ||
| const parseVersion = (raw) => { | ||
| if (raw === undefined) { | ||
| return undefined; | ||
| } | ||
| const parsed = v.safeParse(SemVerSchema, raw); | ||
| if (!parsed.success) { | ||
| return undefined; | ||
| } | ||
| const parts = parsed.output.split("."); | ||
| return [Number(parts[0]), Number(parts[1]), Number(parts[2])]; | ||
| }; | ||
| /** -1 / 0 / 1 when both versions parse; `undefined` when either does not. */ | ||
| export const compareVersions = (a, b) => { | ||
| const left = parseVersion(a); | ||
| const right = parseVersion(b); | ||
| if (left === undefined || right === undefined) { | ||
| return undefined; | ||
| } | ||
| for (let index = 0; index < 3; index += 1) { | ||
| const delta = (left[index] ?? 0) - (right[index] ?? 0); | ||
| if (delta !== 0) { | ||
| return delta > 0 ? 1 : -1; | ||
| } | ||
| } | ||
| return 0; | ||
| }; | ||
| /** | ||
| * Decide whether to nudge (spec 051 addendum). Priority: an explicit minimum the | ||
| * current version is below becomes an "unsupported" warning; otherwise a newer | ||
| * latest becomes an update hint. Anti-nag: if the target version equals the one | ||
| * last nudged, stay silent. Any unparsable/missing version yields no nudge. | ||
| */ | ||
| export const buildVersionNudge = ({ current, latest, minimum, lastNudged, }) => { | ||
| if (compareVersions(current, minimum) === -1) { | ||
| // The comparison only returns -1 when `minimum` parsed, so it is defined. | ||
| const target = latest ?? minimum; | ||
| if (target === undefined || target === lastNudged) { | ||
| return {}; | ||
| } | ||
| return { | ||
| line: `stella ${current} is no longer supported (server requires >= ${minimum}); upgrade with: npm i -g @stll/cli`, | ||
| nudgeVersion: target, | ||
| }; | ||
| } | ||
| if (latest !== undefined && compareVersions(latest, current) === 1) { | ||
| if (latest === lastNudged) { | ||
| return {}; | ||
| } | ||
| return { | ||
| line: `stella ${current} -> ${latest} available; npm i -g @stll/cli`, | ||
| nudgeVersion: latest, | ||
| }; | ||
| } | ||
| return {}; | ||
| }; | ||
| //# sourceMappingURL=cli-version-nudge.js.map |
| {"version":3,"file":"cli-version-nudge.js","sourceRoot":"","sources":["../src/cli-version-nudge.ts"],"names":[],"mappings":"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"} |
| #!/usr/bin/env bun | ||
| export {}; |
+148
| #!/usr/bin/env node | ||
| // Application shell for the `stella` CLI (spec 051). Startup builds the command | ||
| // tree from the baked-in `generatedRouteMap` (instant, offline); the runtime | ||
| // path (S5.3) swaps in a validated cached-listings tree only when a fetched | ||
| // `tools/list` has diverged, and refreshes the per-origin cache behind the | ||
| // fail-closed trust boundary (S5.5). `stella auth *` (Phase 2) resolves its own | ||
| // server from flags and is the one moment the cache is force-refreshed. | ||
| import { buildApplication, buildCommand, buildRouteMap, run, } from "@stricli/core"; | ||
| import { Result } from "better-result"; | ||
| import packageJson from "../package.json" with { type: "json" }; | ||
| import { defaultConfigDir } from "./auth/cli-config.js"; | ||
| import { findDefaultCredential, readCredentialFile, } from "./auth/credential-store.js"; | ||
| import { resolveServerUrl } from "./auth/server-resolution.js"; | ||
| import { buildGeneratedRoutes, buildResourceRoutes } from "./build-cli-tree.js"; | ||
| import { authRoute } from "./commands/auth.js"; | ||
| import { HOME, XDG_CACHE_HOME } from "./env.js"; | ||
| import { generatedResourceTree } from "./generated/resource-tree.js"; | ||
| import { refreshRegistryCache, resolveCommandTree, } from "./registry-refresh.js"; | ||
| const collectLeafPaths = (node, path, lines) => { | ||
| if (node.kind === "leaf") { | ||
| lines.push(`${path.join(" ")}\t(${node.spec.toolName})`); | ||
| return; | ||
| } | ||
| for (const [name, child] of Object.entries(node.children)) { | ||
| collectLeafPaths(child, [...path, name], lines); | ||
| } | ||
| }; | ||
| const buildApp = (tree) => { | ||
| const toolsListCommand = buildCommand({ | ||
| docs: { | ||
| brief: "List the CLI commands generated from the stella MCP tool registry", | ||
| }, | ||
| func() { | ||
| const lines = []; | ||
| // Reflect the ACTIVE tree (the cached-listings tree when the server | ||
| // registry has diverged), so the divergence notice's pointer is honest. | ||
| collectLeafPaths(tree, [], lines); | ||
| this.process.stdout.write(`${lines.sort().join("\n")}\n`); | ||
| }, | ||
| parameters: {}, | ||
| }); | ||
| const toolsRoute = buildRouteMap({ | ||
| docs: { brief: "Inspect the generated command registry" }, | ||
| routes: { list: toolsListCommand }, | ||
| }); | ||
| const rootRoute = buildRouteMap({ | ||
| docs: { brief: "Stella command-line client" }, | ||
| routes: { | ||
| auth: authRoute, | ||
| tools: toolsRoute, | ||
| reference: buildResourceRoutes(generatedResourceTree), | ||
| ...buildGeneratedRoutes(tree), | ||
| }, | ||
| }); | ||
| return buildApplication(rootRoute, { | ||
| name: "stella", | ||
| // Renders (and accepts) multi-word flags as kebab-case, e.g. the | ||
| // `keychain` flag's auto-generated negation as `--no-keychain` rather | ||
| // than `--noKeychain` — matches the documented command surface and every | ||
| // other kebab-case CLI convention (gh, npm, docker). | ||
| scanner: { caseStyle: "allow-kebab-for-camel" }, | ||
| versionInfo: { currentVersion: packageJson.version }, | ||
| }); | ||
| }; | ||
| const resolvePreamble = async () => { | ||
| const configDir = defaultConfigDir(); | ||
| const serverUrlResult = await resolveServerUrl(configDir, undefined); | ||
| const serverUrl = Result.isOk(serverUrlResult) | ||
| ? serverUrlResult.value | ||
| : undefined; | ||
| const token = serverUrl | ||
| ? findDefaultCredential(await readCredentialFile(configDir), serverUrl) | ||
| ?.accessToken | ||
| : undefined; | ||
| return { configDir, serverUrl, token }; | ||
| }; | ||
| // SAFETY: Node's `process.exitCode` type allows an explicit `undefined` | ||
| // value (not just "absent"), which conflicts with stricli's own | ||
| // `StricliProcess.exitCode?: string | number | null` under this package's | ||
| // `exactOptionalPropertyTypes`. The real process object satisfies | ||
| // `StricliProcess` at runtime regardless (it has every field stricli reads | ||
| // or writes); this is a type-only mismatch between two independently-typed | ||
| // libraries, not an actual runtime risk. Passing the real `process` (rather | ||
| // than a constructed stand-in) matters: stricli sets `context.process.exitCode` | ||
| // on it directly, and that must land on the process that is actually exiting. | ||
| // eslint-disable-next-line no-unsafe-type-assertion -- see SAFETY comment above | ||
| const stricliProcess = process; | ||
| const main = async () => { | ||
| const argv = process.argv.slice(2); | ||
| const isAuthLogin = argv.at(0) === "auth" && argv.at(1) === "login"; | ||
| // A named slice of the env (read through `env.ts`) so the cache module never | ||
| // touches the full `ProcessEnv` (whose index signature would not narrow to | ||
| // `CacheEnv`). | ||
| const cacheEnv = { XDG_CACHE_HOME, HOME }; | ||
| const { configDir, serverUrl, token } = await resolvePreamble(); | ||
| // Keep an EXISTING per-origin cache current before building the tree; a | ||
| // missing cache stays offline-instant (seeded at `auth login` below). Any | ||
| // transport/trust failure warns and falls back to the baked-in tree (S5.5). | ||
| if (serverUrl !== undefined && token !== undefined && !isAuthLogin) { | ||
| const outcome = await refreshRegistryCache({ | ||
| serverOrigin: serverUrl, | ||
| token, | ||
| env: cacheEnv, | ||
| }); | ||
| if (outcome.status === "failed") { | ||
| process.stderr.write(`${outcome.warning}\n`); | ||
| } | ||
| else if (outcome.status === "refreshed" && outcome.nudge !== undefined) { | ||
| process.stderr.write(`${outcome.nudge}\n`); | ||
| } | ||
| } | ||
| // Startup always resolves against the baked-in tree unless a validated cache | ||
| // shows a non-empty delta, in which case build from the cached listings and | ||
| // surface the one-line divergence notice (spec S5.3). No network here. | ||
| const { tree, notice } = await resolveCommandTree({ | ||
| serverOrigin: serverUrl, | ||
| env: cacheEnv, | ||
| }); | ||
| if (notice !== undefined) { | ||
| process.stderr.write(notice); | ||
| } | ||
| await run(buildApp(tree), argv, { | ||
| forCommand: () => ({ configDir, process, serverUrl, token }), | ||
| process: stricliProcess, | ||
| }); | ||
| // Seed/refresh the cache right after a successful `auth login` (the one | ||
| // explicit-network moment), using the freshly stored credential. | ||
| if (isAuthLogin) { | ||
| const refreshed = await resolvePreamble(); | ||
| if (refreshed.serverUrl !== undefined && refreshed.token !== undefined) { | ||
| const outcome = await refreshRegistryCache({ | ||
| serverOrigin: refreshed.serverUrl, | ||
| token: refreshed.token, | ||
| env: cacheEnv, | ||
| force: true, | ||
| }); | ||
| if (outcome.status === "failed") { | ||
| process.stderr.write(`${outcome.warning}\n`); | ||
| } | ||
| else if (outcome.status === "refreshed" && | ||
| outcome.nudge !== undefined) { | ||
| process.stderr.write(`${outcome.nudge}\n`); | ||
| } | ||
| } | ||
| } | ||
| }; | ||
| void main(); | ||
| //# sourceMappingURL=cli.js.map |
| {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"} |
| #!/usr/bin/env bun | ||
| export {}; |
+121
| #!/usr/bin/env bun | ||
| // Build-time codegen (spec 051 S5.2, build-time call site). Reads the committed | ||
| // registry snapshot (produced by `apps/api/scripts/export-mcp-tool-registry.ts`, | ||
| // the only place the heavy registry imports resolve), runs the pure | ||
| // `generateRouteMap` with the baked-in Annotation Table, and writes the result | ||
| // to `generated/route-map.ts`. The snapshot keeps `@stll/cli` free of any | ||
| // `apps/api` import; the committed output means registry drift shows as a diff. | ||
| // | ||
| // Run via `bun run codegen` (which regenerates the snapshot first). | ||
| import { panic } from "better-result"; | ||
| import { readFile, writeFile } from "node:fs/promises"; | ||
| import * as v from "valibot"; | ||
| import packageJson from "../package.json" with { type: "json" }; | ||
| import { TOOL_ANNOTATIONS } from "./annotations.js"; | ||
| import { generateResourceTree } from "./generate-resource-tree.js"; | ||
| import { generateRouteMap } from "./generate-route-map.js"; | ||
| const snapshotUrl = new URL("generated/registry-snapshot.json", import.meta.url); | ||
| const outputUrl = new URL("generated/route-map.ts", import.meta.url); | ||
| const resourceSnapshotUrl = new URL("generated/resources-snapshot.json", import.meta.url); | ||
| const resourceOutputUrl = new URL("generated/resource-tree.ts", import.meta.url); | ||
| // Validate the snapshot into the four wire fields so the codegen input is typed | ||
| // (not `any` off `.json()`) and a malformed snapshot fails loudly. | ||
| const listingSchema = v.array(v.looseObject({ | ||
| name: v.string(), | ||
| description: v.string(), | ||
| inputSchema: v.record(v.string(), v.unknown()), | ||
| annotations: v.optional(v.looseObject({ | ||
| readOnlyHint: v.optional(v.boolean()), | ||
| destructiveHint: v.optional(v.boolean()), | ||
| })), | ||
| })); | ||
| const snapshot = v.safeParse(listingSchema, JSON.parse(await readFile(snapshotUrl, "utf-8"))); | ||
| if (!snapshot.success) { | ||
| panic("registry-snapshot.json does not match the expected listing shape"); | ||
| } | ||
| // Project the validated snapshot to the exact `RegistryToolListing` shape | ||
| // (dropping valibot's `| undefined` widening on optional annotation hints). | ||
| const listings = []; | ||
| for (const tool of snapshot.output) { | ||
| const annotations = {}; | ||
| if (tool.annotations?.readOnlyHint !== undefined) { | ||
| annotations.readOnlyHint = tool.annotations.readOnlyHint; | ||
| } | ||
| if (tool.annotations?.destructiveHint !== undefined) { | ||
| annotations.destructiveHint = tool.annotations.destructiveHint; | ||
| } | ||
| listings.push({ | ||
| name: tool.name, | ||
| description: tool.description, | ||
| inputSchema: tool.inputSchema, | ||
| ...(tool.annotations === undefined ? {} : { annotations }), | ||
| }); | ||
| } | ||
| const routeMap = generateRouteMap(listings, TOOL_ANNOTATIONS); | ||
| const header = `/* eslint-disable unicorn/numeric-separators-style -- generated JSON literals */ | ||
| // GENERATED by \`bun run codegen\` (spec 051 S5.2). Do not edit by hand. | ||
| // | ||
| // The committed route tree built from the MCP tool registry snapshot through | ||
| // \`generateRouteMap\`. Regenerate after any registry change; drift shows up here | ||
| // as a diff instead of a runtime surprise. | ||
| import type { RouteNode } from "../route-types.js"; | ||
| export const generatedRouteMap: RouteNode = `; | ||
| await writeFile(outputUrl, `${header}${JSON.stringify(routeMap, null, 2)};\n`); | ||
| process.stderr.write(`Wrote ${outputUrl.pathname}\n`); | ||
| // The resource tree (spec 051 S5.4) is generated the same way from its own | ||
| // snapshot so `reference list`/`reference show` can never drift from the | ||
| // server's static resources. | ||
| const resourceSchema = v.array(v.strictObject({ | ||
| uri: v.string(), | ||
| name: v.string(), | ||
| title: v.optional(v.string()), | ||
| description: v.optional(v.string()), | ||
| mimeType: v.optional(v.string()), | ||
| })); | ||
| const resourceSnapshot = v.safeParse(resourceSchema, JSON.parse(await readFile(resourceSnapshotUrl, "utf-8"))); | ||
| if (!resourceSnapshot.success) { | ||
| panic("resources-snapshot.json does not match the expected listing shape"); | ||
| } | ||
| // Project to the exact `ResourceListing` shape, dropping valibot's `| undefined` | ||
| // widening on the optional fields under `exactOptionalPropertyTypes`. | ||
| const resourceListings = []; | ||
| for (const resource of resourceSnapshot.output) { | ||
| const listing = { uri: resource.uri, name: resource.name }; | ||
| if (resource.title !== undefined) { | ||
| listing.title = resource.title; | ||
| } | ||
| if (resource.description !== undefined) { | ||
| listing.description = resource.description; | ||
| } | ||
| if (resource.mimeType !== undefined) { | ||
| listing.mimeType = resource.mimeType; | ||
| } | ||
| resourceListings.push(listing); | ||
| } | ||
| const resourceTree = generateResourceTree(resourceListings); | ||
| const resourceHeader = `// GENERATED by \`bun run codegen\` (spec 051 S5.4). Do not edit by hand. | ||
| // | ||
| // The committed resource tree built from the MCP \`resources/list\` snapshot | ||
| // through \`generateResourceTree\`. Regenerate after any resource change; drift | ||
| // shows up here as a diff instead of a runtime surprise. | ||
| import type { ResourceNode } from "../resource-types.js"; | ||
| export const generatedResourceTree: ResourceNode = `; | ||
| await writeFile(resourceOutputUrl, `${resourceHeader}${JSON.stringify(resourceTree, null, 2)};\n`); | ||
| process.stderr.write(`Wrote ${resourceOutputUrl.pathname}\n`); | ||
| // Bake the package version in at codegen time (spec 051 addendum: the CLI update | ||
| // nudge must not read package.json at runtime from dist). Regenerating after a | ||
| // version bump keeps this in lockstep with package.json. | ||
| const versionOutputUrl = new URL("generated/cli-version.ts", import.meta.url); | ||
| const versionHeader = `// GENERATED by \`bun run codegen\`. Do not edit by hand. | ||
| // | ||
| // The running CLI's own version, baked in at codegen time so the update nudge | ||
| // (spec 051 addendum) never reads package.json from the published dist. | ||
| export const CLI_VERSION = `; | ||
| await writeFile(versionOutputUrl, `${versionHeader}${JSON.stringify(packageJson.version)};\n`); | ||
| process.stderr.write(`Wrote ${versionOutputUrl.pathname}\n`); | ||
| //# sourceMappingURL=codegen.js.map |
| {"version":3,"file":"codegen.js","sourceRoot":"","sources":["../src/codegen.ts"],"names":[],"mappings":"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"} |
| import type { RouteMap } from "@stricli/core"; | ||
| import type { Context } from "../context.js"; | ||
| export declare const authRoute: RouteMap<Context>; |
| // `stella auth login|logout|whoami|switch` (spec 051 Phase 2). | ||
| import { buildCommand, buildRouteMap } from "@stricli/core"; | ||
| import { Result } from "better-result"; | ||
| import { CLI_DEFAULT_SCOPES, CLI_KNOWN_SCOPES } from "../auth/constants.js"; | ||
| import { login } from "../auth/login.js"; | ||
| import { logout, switchOrg, whoami } from "../auth/manage.js"; | ||
| import { parseScopesFlag } from "../auth/scopes.js"; | ||
| import { resolveServerUrl } from "../auth/server-resolution.js"; | ||
| const parseString = (input) => input; | ||
| const stringFlag = (brief) => ({ brief, kind: "parsed", optional: true, parse: parseString }); | ||
| const requiredStringFlag = (brief) => ({ brief, kind: "parsed", parse: parseString }); | ||
| const formatDate = (epochMs) => new Date(epochMs).toISOString(); | ||
| const loginCommand = buildCommand({ | ||
| docs: { | ||
| brief: "Sign in to a stella server via the browser (PKCE loopback flow)", | ||
| fullDescription: "Opens the stella sign-in page in your default browser and waits for the redirect on an ephemeral localhost port. If the browser can't reach this machine (SSH/remote/headless), paste the redirected URL or the bare authorization code back into the prompt instead.", | ||
| }, | ||
| func: async function func(flags) { | ||
| let requestedScopes = CLI_DEFAULT_SCOPES; | ||
| if (flags.scopes) { | ||
| const parsedScopes = parseScopesFlag(flags.scopes); | ||
| if (Result.isError(parsedScopes)) { | ||
| return new Error(parsedScopes.error.message); | ||
| } | ||
| requestedScopes = parsedScopes.value; | ||
| } | ||
| if (!flags.keychain) { | ||
| this.process.stdout.write("Note: --no-keychain has no effect yet; credentials are always stored at ~/.config/stella/credentials.json (mode 0600). OS keychain support is a follow-up.\n"); | ||
| } | ||
| const result = await login(this.process, { | ||
| configDir: this.configDir, | ||
| orgHint: flags.org, | ||
| registrationScopes: CLI_KNOWN_SCOPES, | ||
| requestedScopes, | ||
| serverFlag: flags.server, | ||
| }); | ||
| if (Result.isError(result)) { | ||
| return new Error(result.error.message); | ||
| } | ||
| const refreshNote = result.value.hasRefreshToken | ||
| ? "" | ||
| : "No refresh token was issued (the server has not enabled offline_access yet); re-run `stella auth login` once this token expires.\n"; | ||
| const lines = [ | ||
| `Signed in to ${result.value.serverUrl} (org ${result.value.orgId}).`, | ||
| `Granted scopes: ${result.value.grantedScopes}`, | ||
| `Access token expires: ${formatDate(result.value.expiresAt)}`, | ||
| ]; | ||
| this.process.stdout.write(`${lines.join("\n")}\n${refreshNote}`); | ||
| return undefined; | ||
| }, | ||
| parameters: { | ||
| flags: { | ||
| keychain: { | ||
| brief: "Use the OS keychain for storage (currently always falls back to the XDG credentials file; see --help)", | ||
| default: true, | ||
| kind: "boolean", | ||
| }, | ||
| org: stringFlag("Organization slug to select in the browser when prompted (label only, not enforced server-side; see --help)"), | ||
| scopes: stringFlag(`Comma-separated OAuth scopes to request (default: ${CLI_DEFAULT_SCOPES.join(",")})`), | ||
| server: stringFlag("Stella API origin to sign in to"), | ||
| }, | ||
| }, | ||
| }); | ||
| const whoamiCommand = buildCommand({ | ||
| docs: { brief: "Show the signed-in organization, scopes, and token expiry" }, | ||
| func: async function func(flags) { | ||
| const serverUrlResult = await resolveServerUrl(this.configDir, flags.server); | ||
| if (Result.isError(serverUrlResult)) { | ||
| return new Error(serverUrlResult.error.message); | ||
| } | ||
| const result = await whoami(this.configDir, serverUrlResult.value, flags.org); | ||
| if (Result.isError(result)) { | ||
| return new Error(result.error.message); | ||
| } | ||
| const info = result.value; | ||
| const lines = [ | ||
| `Server: ${info.serverUrl}`, | ||
| `Organization: ${info.orgLabel ? `${info.orgLabel} (${info.orgId})` : info.orgId}`, | ||
| `Scopes: ${info.scope}`, | ||
| `Expires: ${formatDate(info.expiresAt)}${info.isExpired ? " (expired)" : ""}`, | ||
| `Refresh token: ${info.hasRefreshToken ? "yes" : "no"}`, | ||
| ]; | ||
| if (info.claims?.sub) { | ||
| lines.push(`Subject: ${info.claims.sub}`); | ||
| } | ||
| this.process.stdout.write(`${lines.join("\n")}\n`); | ||
| return undefined; | ||
| }, | ||
| parameters: { | ||
| flags: { | ||
| org: stringFlag("Organization to inspect (default: this server's default org)"), | ||
| server: stringFlag("Stella API origin to inspect (default: resolved server)"), | ||
| }, | ||
| }, | ||
| }); | ||
| const logoutCommand = buildCommand({ | ||
| docs: { brief: "Remove a stored stella credential" }, | ||
| func: async function func(flags) { | ||
| const serverUrlResult = await resolveServerUrl(this.configDir, flags.server); | ||
| if (Result.isError(serverUrlResult)) { | ||
| return new Error(serverUrlResult.error.message); | ||
| } | ||
| const result = await logout(this.configDir, serverUrlResult.value, flags.org); | ||
| if (Result.isError(result)) { | ||
| return new Error(result.error.message); | ||
| } | ||
| this.process.stdout.write(`Signed out of ${serverUrlResult.value} (org ${result.value.orgId}).\n`); | ||
| return undefined; | ||
| }, | ||
| parameters: { | ||
| flags: { | ||
| org: stringFlag("Organization to sign out of (default: the only signed-in org)"), | ||
| server: stringFlag("Stella API origin to sign out of (default: resolved server)"), | ||
| }, | ||
| }, | ||
| }); | ||
| const switchCommand = buildCommand({ | ||
| docs: { | ||
| brief: "Switch the default organization for a server (no re-auth if already signed in)", | ||
| }, | ||
| func: async function func(flags) { | ||
| const serverUrlResult = await resolveServerUrl(this.configDir, flags.server); | ||
| if (Result.isError(serverUrlResult)) { | ||
| return new Error(serverUrlResult.error.message); | ||
| } | ||
| const result = await switchOrg(this.configDir, serverUrlResult.value, flags.org); | ||
| if (Result.isError(result)) { | ||
| return new Error(result.error.message); | ||
| } | ||
| this.process.stdout.write(`Default organization for ${serverUrlResult.value} is now ${result.value.orgId}.\n`); | ||
| return undefined; | ||
| }, | ||
| parameters: { | ||
| flags: { | ||
| org: requiredStringFlag("Organization to switch to"), | ||
| server: stringFlag("Stella API origin (default: resolved server)"), | ||
| }, | ||
| }, | ||
| }); | ||
| export const authRoute = buildRouteMap({ | ||
| docs: { brief: "Manage stella authentication" }, | ||
| routes: { | ||
| login: loginCommand, | ||
| logout: logoutCommand, | ||
| switch: switchCommand, | ||
| whoami: whoamiCommand, | ||
| }, | ||
| }); | ||
| //# sourceMappingURL=auth.js.map |
| {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"} |
| import type { CommandContext } from "@stricli/core"; | ||
| /** Context every generated (and hand-written) command receives. */ | ||
| export type Context = CommandContext & { | ||
| /** | ||
| * Real Node/Bun process, not just stricli's minimal `WritableStreams`: | ||
| * `stella auth login`'s manual-paste fallback needs `stdin`, and server | ||
| * resolution reads `env`. | ||
| */ | ||
| readonly process: NodeJS.Process; | ||
| /** `~/.config/stella` (or `$XDG_CONFIG_HOME/stella`), resolved once per invocation. */ | ||
| readonly configDir: string; | ||
| /** Resolved server origin (`--server`/env/config; see `auth/server-resolution.ts`), if any. */ | ||
| readonly serverUrl: string | undefined; | ||
| /** | ||
| * The default org's stored access token for `serverUrl`, if signed in. | ||
| * Not proactively refreshed here — a Phase 3+ HTTP client wrapper should | ||
| * call `auth/ensure-fresh-credential.ts` reactively on a 401, matching | ||
| * `stella auth whoami`'s "no extra server calls unless needed" stance. | ||
| */ | ||
| readonly token: string | undefined; | ||
| }; |
| // Shared stricli application context (spec 051 S5.1): a single `Context` type | ||
| // threaded through every command. Generated (Phase 3+) commands read | ||
| // `serverUrl`/`token` directly instead of re-resolving them; hand-written | ||
| // `stella auth` commands (this phase) resolve their own server/org from | ||
| // flags since they operate on a specific (possibly not-yet-configured) | ||
| // server rather than "the" current one. | ||
| export {}; | ||
| //# sourceMappingURL=context.js.map |
| {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,qEAAqE;AACrE,0EAA0E;AAC1E,wEAAwE;AACxE,uEAAuE;AACvE,wCAAwC"} |
| /** XDG base-directory override for `~/.config/stella`; see `auth/config-dir.ts`. */ | ||
| export declare const XDG_CONFIG_HOME: string | undefined; | ||
| /** Default `--server` origin when neither the flag nor a saved config exists; see `auth/server-resolution.ts`. */ | ||
| export declare const STELLA_SERVER_URL: string | undefined; | ||
| /** XDG cache base for the per-origin registry cache; see `registry-cache.ts`. */ | ||
| export declare const XDG_CACHE_HOME: string | undefined; | ||
| /** Home directory, the `~/.cache` fallback root for the registry cache. */ | ||
| export declare const HOME: string | undefined; |
+14
| // Centralizes every `process.env` read for `@stll/cli` (the | ||
| // `forbid-process-env-outside-env-ts` lint rule requires reads to live in an | ||
| // `env.ts`-named module; see `oxlint.config.ts`). Both variables are | ||
| // optional: the CLI never hard-requires an env var to start (self-hosting | ||
| // first-class — `--server`/`credentials.json` always work without either). | ||
| /** XDG base-directory override for `~/.config/stella`; see `auth/config-dir.ts`. */ | ||
| export const XDG_CONFIG_HOME = process.env["XDG_CONFIG_HOME"]; | ||
| /** Default `--server` origin when neither the flag nor a saved config exists; see `auth/server-resolution.ts`. */ | ||
| export const STELLA_SERVER_URL = process.env["STELLA_SERVER_URL"]; | ||
| /** XDG cache base for the per-origin registry cache; see `registry-cache.ts`. */ | ||
| export const XDG_CACHE_HOME = process.env["XDG_CACHE_HOME"]; | ||
| /** Home directory, the `~/.cache` fallback root for the registry cache. */ | ||
| export const HOME = process.env["HOME"]; | ||
| //# sourceMappingURL=env.js.map |
| {"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,6EAA6E;AAC7E,qEAAqE;AACrE,0EAA0E;AAC1E,2EAA2E;AAE3E,oFAAoF;AACpF,MAAM,CAAC,MAAM,eAAe,GAC1B,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;AAEjC,kHAAkH;AAClH,MAAM,CAAC,MAAM,iBAAiB,GAC5B,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;AAEnC,iFAAiF;AACjF,MAAM,CAAC,MAAM,cAAc,GAAuB,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;AAEhF,2EAA2E;AAC3E,MAAM,CAAC,MAAM,IAAI,GAAuB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC"} |
| import type { ResourceListing, ResourceNode } from "./resource-types.js"; | ||
| /** | ||
| * Fold a `resources/list` projection into a `reference` resource tree. `list` | ||
| * enumerates; each resource becomes a `show <name>` leaf keyed by its | ||
| * kebab-cased name. A duplicate resource name is a hard generation error. | ||
| */ | ||
| export declare const generateResourceTree: (resources: readonly ResourceListing[]) => ResourceNode; |
| // THE resource-tree generator (spec 051 S5.4), mirroring `generateRouteMap`: | ||
| // pure, deterministic, no I/O. Given a `resources/list` projection it emits a | ||
| // `reference` route with a `list` enumerator and one `show <name>` leaf per | ||
| // resource, so the tree is generated (never drifts) yet still fully offline. | ||
| // Both call sites (build-time codegen and the runtime path) share this function. | ||
| import { RouteGenerationError } from "./generate-route-map.js"; | ||
| /** snake_case, camelCase, or a `stella://` uri path segment -> kebab-case. */ | ||
| const kebabCase = (segment) => segment | ||
| .replace(/_/gu, "-") | ||
| .replace(/(?<lower>[a-z0-9])(?<upper>[A-Z])/gu, "$<lower>-$<upper>") | ||
| .toLowerCase(); | ||
| /** | ||
| * Fold a `resources/list` projection into a `reference` resource tree. `list` | ||
| * enumerates; each resource becomes a `show <name>` leaf keyed by its | ||
| * kebab-cased name. A duplicate resource name is a hard generation error. | ||
| */ | ||
| export const generateResourceTree = (resources) => { | ||
| const showChildren = {}; | ||
| for (const resource of resources) { | ||
| const key = kebabCase(resource.name); | ||
| if (showChildren[key] !== undefined) { | ||
| throw new RouteGenerationError(`Duplicate resource command 'reference show ${key}' (uri ${resource.uri})`); | ||
| } | ||
| showChildren[key] = { | ||
| kind: "leaf", | ||
| spec: { | ||
| kind: "show", | ||
| commandPath: ["reference", "show", key], | ||
| name: resource.name, | ||
| uri: resource.uri, | ||
| }, | ||
| }; | ||
| } | ||
| return { | ||
| kind: "route", | ||
| children: { | ||
| list: { | ||
| kind: "leaf", | ||
| spec: { kind: "list", commandPath: ["reference", "list"] }, | ||
| }, | ||
| show: { kind: "route", children: showChildren }, | ||
| }, | ||
| }; | ||
| }; | ||
| //# sourceMappingURL=generate-resource-tree.js.map |
| {"version":3,"file":"generate-resource-tree.js","sourceRoot":"","sources":["../src/generate-resource-tree.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,8EAA8E;AAC9E,4EAA4E;AAC5E,6EAA6E;AAC7E,iFAAiF;AAEjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAG/D,8EAA8E;AAC9E,MAAM,SAAS,GAAG,CAAC,OAAe,EAAU,EAAE,CAC5C,OAAO;KACJ,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;KACnB,OAAO,CAAC,qCAAqC,EAAE,mBAAmB,CAAC;KACnE,WAAW,EAAE,CAAC;AAEnB;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,SAAqC,EACvB,EAAE;IAChB,MAAM,YAAY,GAAiC,EAAE,CAAC;IAEtD,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,YAAY,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;YACpC,MAAM,IAAI,oBAAoB,CAC5B,8CAA8C,GAAG,UAAU,QAAQ,CAAC,GAAG,GAAG,CAC3E,CAAC;QACJ,CAAC;QACD,YAAY,CAAC,GAAG,CAAC,GAAG;YAClB,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE;gBACJ,IAAI,EAAE,MAAM;gBACZ,WAAW,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,CAAC;gBACvC,IAAI,EAAE,QAAQ,CAAC,IAAI;gBACnB,GAAG,EAAE,QAAQ,CAAC,GAAG;aAClB;SACF,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EAAE,OAAO;QACb,QAAQ,EAAE;YACR,IAAI,EAAE;gBACJ,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE;aAC3D;YACD,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE;SAChD;KACF,CAAC;AACJ,CAAC,CAAC"} |
| import { CliBaseError } from "./auth/errors.js"; | ||
| import type { RegistryToolListing, RouteNode, ToolAnnotation } from "./route-types.js"; | ||
| /** Hard codegen failure: a collision or reserved-name violation (spec S1). */ | ||
| export declare class RouteGenerationError extends CliBaseError<"RouteGenerationError"> { | ||
| readonly name = "RouteGenerationError"; | ||
| constructor(message: string); | ||
| } | ||
| /** | ||
| * THE generator. Deterministic and pure: same inputs -> byte-identical | ||
| * `RouteNode`. Excludes tools annotated `excluded`, splits required-enum | ||
| * discriminators into subcommands, maps every prop to a flag or `inputOnly` | ||
| * per spec S3, and fails hard on any reserved-name or kebab collision. | ||
| */ | ||
| export declare const generateRouteMap: (listings: readonly RegistryToolListing[], annotations: Readonly<Record<string, ToolAnnotation>>) => RouteNode; |
| // THE generator (spec 051 S5.2): JSON-Schema tool listings + the baked-in | ||
| // Annotation Table -> a stricli-ready `RouteNode` tree. Pure, deterministic, no | ||
| // I/O, no `Date.now()`/`Math.random()`. Called at build time by the codegen | ||
| // script and (later, out of scope here) at runtime with a validated | ||
| // `tools/list`; both call sites share this one function and the same | ||
| // annotations, so the trees are byte-identical. | ||
| import { RESERVED_FLAGS, RESERVED_TOP_LEVEL_NAMES } from "./annotations.js"; | ||
| import { CliBaseError } from "./auth/errors.js"; | ||
| /** Argument keys the pagination flags map onto, shared across every list tool. */ | ||
| const CURSOR_ARG = "cursor"; | ||
| const LIMIT_ARG = "limit"; | ||
| /** Prefixes that split an unknown tool name into `verb domain` (spec S1 rule 5). */ | ||
| const VERB_PREFIXES = new Set([ | ||
| "list", | ||
| "save", | ||
| "delete", | ||
| "read", | ||
| "get", | ||
| "search", | ||
| ]); | ||
| const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value); | ||
| /** Extract a `{ prop: schema }` map from a schema's `properties`, guarding shapes. */ | ||
| const propertyMap = (schema) => { | ||
| const raw = schema["properties"]; | ||
| if (!isRecord(raw)) { | ||
| return {}; | ||
| } | ||
| const out = {}; | ||
| for (const [key, value] of Object.entries(raw)) { | ||
| if (isRecord(value)) { | ||
| out[key] = value; | ||
| } | ||
| } | ||
| return out; | ||
| }; | ||
| /** Hard codegen failure: a collision or reserved-name violation (spec S1). */ | ||
| export class RouteGenerationError extends CliBaseError { | ||
| name = "RouteGenerationError"; | ||
| constructor(message) { | ||
| super("RouteGenerationError", message); | ||
| } | ||
| } | ||
| /** snake_case or camelCase segment -> kebab-case. */ | ||
| const kebabCase = (segment) => segment | ||
| .replace(/_/gu, "-") | ||
| .replace(/(?<lower>[a-z0-9])(?<upper>[A-Z])/gu, "$<lower>-$<upper>") | ||
| .toLowerCase(); | ||
| const schemaTypeList = (rawType) => { | ||
| if (Array.isArray(rawType)) { | ||
| return rawType.filter((t) => typeof t === "string"); | ||
| } | ||
| return typeof rawType === "string" ? [rawType] : []; | ||
| }; | ||
| const typeInfo = (schema) => { | ||
| const types = schemaTypeList(schema["type"]); | ||
| const nullable = types.includes("null"); | ||
| const base = types.find((t) => t !== "null"); | ||
| return { base, nullable }; | ||
| }; | ||
| const enumValues = (schema) => { | ||
| const values = schema["enum"]; | ||
| if (!Array.isArray(values)) { | ||
| return undefined; | ||
| } | ||
| return values.every((v) => typeof v === "string") | ||
| ? values | ||
| : undefined; | ||
| }; | ||
| /** Conditionally include `min`/`max` so an absent bound is omitted, not `undefined`. */ | ||
| const boundFields = (schema) => { | ||
| const minimum = schema["minimum"]; | ||
| const maximum = schema["maximum"]; | ||
| return { | ||
| ...(typeof minimum === "number" ? { min: minimum } : {}), | ||
| ...(typeof maximum === "number" ? { max: maximum } : {}), | ||
| }; | ||
| }; | ||
| const scalarFlagKind = (base) => { | ||
| if (base === "string") { | ||
| return "string"; | ||
| } | ||
| if (base === "integer") { | ||
| return "int"; | ||
| } | ||
| if (base === "number") { | ||
| return "number"; | ||
| } | ||
| if (base === "boolean") { | ||
| return "boolean"; | ||
| } | ||
| return undefined; | ||
| }; | ||
| const classifyArrayItems = (prop, items) => { | ||
| const { base } = typeInfo(items); | ||
| const itemEnum = enumValues(items); | ||
| if (itemEnum) { | ||
| return { | ||
| kind: "flag", | ||
| spec: { | ||
| flag: `--${kebabCase(prop)}`, | ||
| prop, | ||
| kind: "enum-array", | ||
| enum: itemEnum, | ||
| repeatable: true, | ||
| }, | ||
| }; | ||
| } | ||
| if (base === "string") { | ||
| return { | ||
| kind: "flag", | ||
| spec: { | ||
| flag: `--${kebabCase(prop)}`, | ||
| prop, | ||
| kind: "string-array", | ||
| repeatable: true, | ||
| }, | ||
| }; | ||
| } | ||
| if (base === "integer" || base === "number") { | ||
| return { | ||
| kind: "flag", | ||
| spec: { | ||
| flag: `--${kebabCase(prop)}`, | ||
| prop, | ||
| kind: "int-array", | ||
| repeatable: true, | ||
| }, | ||
| }; | ||
| } | ||
| // array-of-object (and anything else) -> --input only (spec S3). | ||
| return { kind: "input-only" }; | ||
| }; | ||
| const classifyObject = (prop, schema) => { | ||
| // Free map (additionalProperties: true) -> --input only (spec S3). | ||
| if (schema["additionalProperties"] === true) { | ||
| return { kind: "input-only" }; | ||
| } | ||
| if (!isRecord(schema["properties"])) { | ||
| return { kind: "input-only" }; | ||
| } | ||
| // Dot-path flags only for a depth-2 object all of whose children are scalars | ||
| // (spec S3). Any non-scalar child (nested object/array/untyped) pushes the | ||
| // whole subtree to --input rather than emitting half-generated flags. | ||
| const children = []; | ||
| for (const [childName, childSchema] of Object.entries(schema["properties"])) { | ||
| if (!isRecord(childSchema)) { | ||
| return { kind: "input-only" }; | ||
| } | ||
| const child = childSchema; | ||
| const childEnum = enumValues(child); | ||
| const { base } = typeInfo(child); | ||
| if (childEnum) { | ||
| children.push({ | ||
| flag: `--${kebabCase(prop)}.${kebabCase(childName)}`, | ||
| prop: `${prop}.${childName}`, | ||
| kind: "enum", | ||
| enum: childEnum, | ||
| repeatable: false, | ||
| }); | ||
| continue; | ||
| } | ||
| const scalar = scalarFlagKind(base ?? ""); | ||
| if (scalar === undefined) { | ||
| return { kind: "input-only" }; | ||
| } | ||
| children.push({ | ||
| flag: `--${kebabCase(prop)}.${kebabCase(childName)}`, | ||
| prop: `${prop}.${childName}`, | ||
| kind: scalar, | ||
| ...(scalar === "int" || scalar === "number" ? boundFields(child) : {}), | ||
| repeatable: false, | ||
| }); | ||
| } | ||
| return { kind: "dot-path", children }; | ||
| }; | ||
| const classifyProp = (prop, schema) => { | ||
| const { base, nullable } = typeInfo(schema); | ||
| const values = enumValues(schema); | ||
| if (values && base === "string") { | ||
| return { | ||
| kind: "flag", | ||
| spec: { | ||
| flag: `--${kebabCase(prop)}`, | ||
| prop, | ||
| kind: "enum", | ||
| enum: values, | ||
| repeatable: false, | ||
| }, | ||
| }; | ||
| } | ||
| if (base === "string") { | ||
| return { | ||
| kind: "flag", | ||
| spec: { | ||
| flag: `--${kebabCase(prop)}`, | ||
| prop, | ||
| kind: nullable ? "nullable-string" : "string", | ||
| repeatable: false, | ||
| }, | ||
| }; | ||
| } | ||
| if (base === "integer") { | ||
| return { | ||
| kind: "flag", | ||
| spec: { | ||
| flag: `--${kebabCase(prop)}`, | ||
| prop, | ||
| kind: "int", | ||
| ...boundFields(schema), | ||
| repeatable: false, | ||
| }, | ||
| }; | ||
| } | ||
| if (base === "number") { | ||
| return { | ||
| kind: "flag", | ||
| spec: { | ||
| flag: `--${kebabCase(prop)}`, | ||
| prop, | ||
| kind: "number", | ||
| ...boundFields(schema), | ||
| repeatable: false, | ||
| }, | ||
| }; | ||
| } | ||
| if (base === "boolean") { | ||
| return { | ||
| kind: "flag", | ||
| spec: { | ||
| flag: `--${kebabCase(prop)}`, | ||
| prop, | ||
| kind: "boolean", | ||
| repeatable: false, | ||
| }, | ||
| }; | ||
| } | ||
| if (base === "array") { | ||
| const items = schema["items"]; | ||
| if (!isRecord(items)) { | ||
| return { kind: "input-only" }; | ||
| } | ||
| return classifyArrayItems(prop, items); | ||
| } | ||
| if (base === "object") { | ||
| return classifyObject(prop, schema); | ||
| } | ||
| return { kind: "input-only" }; | ||
| }; | ||
| const resolvePaginationMode = (properties, annotation) => { | ||
| const cursor = properties[CURSOR_ARG]; | ||
| const limit = properties[LIMIT_ARG]; | ||
| const hasCursor = cursor !== undefined && typeInfo(cursor).base === "string"; | ||
| const hasLimit = limit !== undefined && typeInfo(limit).base === "integer"; | ||
| if (!hasCursor) { | ||
| return "none"; | ||
| } | ||
| // Windowed-text and paginationless tools page a cursor but expose no --limit. | ||
| if (annotation?.windowedText || annotation?.paginationless) { | ||
| return "cursor-only"; | ||
| } | ||
| return hasLimit ? "full" : "cursor-only"; | ||
| }; | ||
| const buildFlags = ({ properties, required, includeProps, skipProps, }) => { | ||
| const flags = []; | ||
| const inputOnly = []; | ||
| const seenFlags = new Set(); | ||
| const propNames = includeProps ?? Object.keys(properties).filter((p) => !skipProps.has(p)); | ||
| for (const prop of propNames) { | ||
| if (skipProps.has(prop)) { | ||
| continue; | ||
| } | ||
| const schema = properties[prop]; | ||
| if (schema === undefined) { | ||
| continue; | ||
| } | ||
| const classification = classifyProp(prop, schema); | ||
| if (classification.kind === "input-only") { | ||
| inputOnly.push(prop); | ||
| continue; | ||
| } | ||
| const isRequired = required.has(prop); | ||
| const candidates = classification.kind === "flag" | ||
| ? [classification.spec] | ||
| : classification.children; | ||
| for (const candidate of candidates) { | ||
| if (RESERVED_FLAGS.has(candidate.flag)) { | ||
| throw new RouteGenerationError(`Generated flag ${candidate.flag} (from prop ${candidate.prop}) collides with a reserved global flag`); | ||
| } | ||
| if (seenFlags.has(candidate.flag)) { | ||
| throw new RouteGenerationError(`Flag ${candidate.flag} is generated twice within one command; add a flagRename annotation`); | ||
| } | ||
| seenFlags.add(candidate.flag); | ||
| // A dot-path leaf is required only if the whole object prop is required | ||
| // AND the child schema itself is required; the CLI keeps this simple by | ||
| // treating dot-path leaves as optional (the server enforces sub-requiredness). | ||
| flags.push({ | ||
| ...candidate, | ||
| required: classification.kind === "flag" ? isRequired : false, | ||
| }); | ||
| } | ||
| } | ||
| return { flags, inputOnly }; | ||
| }; | ||
| const scopeOf = (annotation) => annotation.scope; | ||
| /** Split an unknown tool name into a `[domain, verb]` command path (spec S1 rule 5). */ | ||
| const heuristicCommandPath = (name) => { | ||
| const underscore = name.indexOf("_"); | ||
| if (underscore === -1) { | ||
| return [kebabCase(name)]; | ||
| } | ||
| const head = name.slice(0, underscore); | ||
| const rest = name.slice(underscore + 1); | ||
| if (VERB_PREFIXES.has(head)) { | ||
| return [kebabCase(rest), head]; | ||
| } | ||
| return [kebabCase(head), kebabCase(rest)]; | ||
| }; | ||
| const leafSpecsForTool = ({ listing, annotation, }) => { | ||
| const schema = listing.inputSchema; | ||
| const properties = propertyMap(schema); | ||
| const requiredList = Array.isArray(schema["required"]) | ||
| ? schema["required"].filter((r) => typeof r === "string") | ||
| : []; | ||
| const required = new Set(requiredList); | ||
| const destructiveHint = listing.annotations?.destructiveHint === true; | ||
| const command = annotation?.command ?? heuristicCommandPath(listing.name); | ||
| const scope = annotation ? scopeOf(annotation) : undefined; | ||
| const itemsKey = annotation?.itemsKey; | ||
| const windowedText = annotation?.windowedText === true; | ||
| const mode = resolvePaginationMode(properties, annotation); | ||
| const paginated = mode !== "none"; | ||
| const paginationSkip = new Set(); | ||
| if (mode === "full") { | ||
| paginationSkip.add(CURSOR_ARG); | ||
| paginationSkip.add(LIMIT_ARG); | ||
| } | ||
| else if (mode === "cursor-only") { | ||
| paginationSkip.add(CURSOR_ARG); | ||
| } | ||
| // Discriminator split (spec S2). An ANNOTATED tool splits only when its | ||
| // annotation explicitly marks a `discriminator` (so a plain required-enum | ||
| // filter such as `lookup_business_registry.registry` stays a normal flag). An | ||
| // UNKNOWN tool (runtime, no annotation) falls back to the safe-superset | ||
| // heuristic: split on its first required-enum prop. | ||
| const discriminatorProp = annotation | ||
| ? annotation.discriminator?.prop | ||
| : Object.keys(properties).find((prop) => { | ||
| const values = enumValues(properties[prop] ?? {}); | ||
| return values !== undefined && required.has(prop); | ||
| }); | ||
| if (discriminatorProp !== undefined) { | ||
| const propSchema = properties[discriminatorProp]; | ||
| const values = enumValues(propSchema ?? {}) ?? []; | ||
| const skipWithDiscriminator = new Set([ | ||
| ...paginationSkip, | ||
| discriminatorProp, | ||
| ]); | ||
| const baseRequired = new Set([...required].filter((r) => r !== discriminatorProp)); | ||
| const specs = []; | ||
| for (const value of values) { | ||
| const sub = annotation?.discriminator?.subcommands[value]; | ||
| const subCommandName = sub?.command ?? kebabCase(value); | ||
| const subRequired = new Set([...baseRequired, ...(sub?.required ?? [])]); | ||
| const { flags, inputOnly } = buildFlags({ | ||
| properties, | ||
| required: subRequired, | ||
| includeProps: sub?.include, | ||
| skipProps: skipWithDiscriminator, | ||
| }); | ||
| specs.push({ | ||
| commandPath: [...command, subCommandName], | ||
| toolName: listing.name, | ||
| discriminatorInject: { [discriminatorProp]: value }, | ||
| flags, | ||
| inputOnly, | ||
| paginated, | ||
| windowedText, | ||
| ...(itemsKey === undefined ? {} : { itemsKey }), | ||
| destructive: sub?.destructive === true || destructiveHint, | ||
| ...(scope === undefined ? {} : { scope }), | ||
| inputSchema: schema, | ||
| }); | ||
| } | ||
| return specs; | ||
| } | ||
| const { flags, inputOnly } = buildFlags({ | ||
| properties, | ||
| required, | ||
| includeProps: undefined, | ||
| skipProps: paginationSkip, | ||
| }); | ||
| return [ | ||
| { | ||
| commandPath: command, | ||
| toolName: listing.name, | ||
| flags, | ||
| inputOnly, | ||
| paginated, | ||
| windowedText, | ||
| ...(itemsKey === undefined ? {} : { itemsKey }), | ||
| destructive: destructiveHint, | ||
| ...(scope === undefined ? {} : { scope }), | ||
| inputSchema: schema, | ||
| }, | ||
| ]; | ||
| }; | ||
| const insertLeaf = (root, spec) => { | ||
| if (root.kind !== "route") { | ||
| throw new RouteGenerationError("Cannot insert into a leaf node"); | ||
| } | ||
| const path = spec.commandPath; | ||
| const top = path[0]; | ||
| if (top !== undefined && RESERVED_TOP_LEVEL_NAMES.has(top)) { | ||
| throw new RouteGenerationError(`Command domain '${top}' (tool ${spec.toolName}) collides with a reserved top-level name`); | ||
| } | ||
| let node = root; | ||
| for (let index = 0; index < path.length - 1; index += 1) { | ||
| const segment = path[index]; | ||
| if (segment === undefined) { | ||
| continue; | ||
| } | ||
| if (node.kind !== "route") { | ||
| throw new RouteGenerationError(`Command path ${path.join(" ")} passes through leaf '${segment}'`); | ||
| } | ||
| const existing = node.children[segment]; | ||
| if (existing === undefined) { | ||
| const created = { kind: "route", children: {} }; | ||
| node.children[segment] = created; | ||
| node = created; | ||
| continue; | ||
| } | ||
| node = existing; | ||
| } | ||
| const verb = path.at(-1); | ||
| if (verb === undefined) { | ||
| throw new RouteGenerationError(`Tool ${spec.toolName} produced an empty command path`); | ||
| } | ||
| if (node.kind !== "route") { | ||
| throw new RouteGenerationError(`Command path ${path.join(" ")} cannot attach under a leaf`); | ||
| } | ||
| if (node.children[verb] !== undefined) { | ||
| throw new RouteGenerationError(`Duplicate command '${path.join(" ")}' (tool ${spec.toolName})`); | ||
| } | ||
| node.children[verb] = { kind: "leaf", spec }; | ||
| }; | ||
| /** | ||
| * THE generator. Deterministic and pure: same inputs -> byte-identical | ||
| * `RouteNode`. Excludes tools annotated `excluded`, splits required-enum | ||
| * discriminators into subcommands, maps every prop to a flag or `inputOnly` | ||
| * per spec S3, and fails hard on any reserved-name or kebab collision. | ||
| */ | ||
| export const generateRouteMap = (listings, annotations) => { | ||
| const root = { kind: "route", children: {} }; | ||
| for (const listing of listings) { | ||
| const annotation = annotations[listing.name]; | ||
| if (annotation?.excluded === true) { | ||
| continue; | ||
| } | ||
| for (const spec of leafSpecsForTool({ listing, annotation })) { | ||
| insertLeaf(root, spec); | ||
| } | ||
| } | ||
| return root; | ||
| }; | ||
| //# sourceMappingURL=generate-route-map.js.map |
| {"version":3,"file":"generate-route-map.js","sourceRoot":"","sources":["../src/generate-route-map.ts"],"names":[],"mappings":"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"} |
| export declare const CLI_VERSION = "0.1.0"; |
| // GENERATED by `bun run codegen`. Do not edit by hand. | ||
| // | ||
| // The running CLI's own version, baked in at codegen time so the update nudge | ||
| // (spec 051 addendum) never reads package.json from the published dist. | ||
| export const CLI_VERSION = "0.1.0"; | ||
| //# sourceMappingURL=cli-version.js.map |
| {"version":3,"file":"cli-version.js","sourceRoot":"","sources":["../../src/generated/cli-version.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,EAAE;AACF,8EAA8E;AAC9E,wEAAwE;AAExE,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC"} |
Sorry, the diff of this file is too big to display
| import type { ResourceNode } from "../resource-types.js"; | ||
| export declare const generatedResourceTree: ResourceNode; |
| // GENERATED by `bun run codegen` (spec 051 S5.4). Do not edit by hand. | ||
| // | ||
| // The committed resource tree built from the MCP `resources/list` snapshot | ||
| // through `generateResourceTree`. Regenerate after any resource change; drift | ||
| // shows up here as a diff instead of a runtime surprise. | ||
| export const generatedResourceTree = { | ||
| kind: "route", | ||
| children: { | ||
| list: { | ||
| kind: "leaf", | ||
| spec: { | ||
| kind: "list", | ||
| commandPath: ["reference", "list"], | ||
| }, | ||
| }, | ||
| show: { | ||
| kind: "route", | ||
| children: { | ||
| "template-markers": { | ||
| kind: "leaf", | ||
| spec: { | ||
| kind: "show", | ||
| commandPath: ["reference", "show", "template-markers"], | ||
| name: "template-markers", | ||
| uri: "stella://reference/template-markers", | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| }; | ||
| //# sourceMappingURL=resource-tree.js.map |
| {"version":3,"file":"resource-tree.js","sourceRoot":"","sources":["../../src/generated/resource-tree.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,EAAE;AACF,2EAA2E;AAC3E,8EAA8E;AAC9E,yDAAyD;AAIzD,MAAM,CAAC,MAAM,qBAAqB,GAAiB;IACjD,IAAI,EAAE,OAAO;IACb,QAAQ,EAAE;QACR,IAAI,EAAE;YACJ,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE;gBACJ,IAAI,EAAE,MAAM;gBACZ,WAAW,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC;aACnC;SACF;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,OAAO;YACb,QAAQ,EAAE;gBACR,kBAAkB,EAAE;oBAClB,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE;wBACJ,IAAI,EAAE,MAAM;wBACZ,WAAW,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,kBAAkB,CAAC;wBACtD,IAAI,EAAE,kBAAkB;wBACxB,GAAG,EAAE,qCAAqC;qBAC3C;iBACF;aACF;SACF;KACF;CACF,CAAC"} |
| import type { RouteNode } from "../route-types.js"; | ||
| export declare const generatedRouteMap: RouteNode; |
Sorry, the diff of this file is too big to display
| {"version":3,"file":"route-map.js","sourceRoot":"","sources":["../../src/generated/route-map.ts"],"names":[],"mappings":"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AAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IAAI;oDACJ,IA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"} |
| type JsonSchema = Record<string, unknown>; | ||
| /** A validation outcome: valid, or the failing JSON path plus a message. */ | ||
| export type ValidationResult = { | ||
| valid: true; | ||
| } | { | ||
| valid: false; | ||
| path: string; | ||
| message: string; | ||
| }; | ||
| /** | ||
| * Validate `data` against a tool's `inputSchema` in interpreted mode. The root | ||
| * schema is always an object schema (`{ type: "object", properties }`). | ||
| */ | ||
| export declare const validateAgainstSchema: (schema: JsonSchema, data: unknown) => ValidationResult; | ||
| export {}; |
| // Interpreted JSON-Schema validator for the `--input` escape hatch (spec 051 | ||
| // S5.5 rule 1): it walks the schema and the data recursively, with NO | ||
| // `Function`/`eval`/dynamic code generation. Scoped to exactly the shapes the | ||
| // MCP prop builders emit (string, nullable-string, integer/number with | ||
| // min/max, enum, boolean, array + items, object + properties, free map). A | ||
| // hand-rolled walker is simpler and lighter than a general-purpose library for | ||
| // this closed shape set, and it structurally cannot run generated code. | ||
| const ok = { valid: true }; | ||
| const fail = (path, message) => ({ | ||
| valid: false, | ||
| path: path === "" ? "(root)" : path, | ||
| message, | ||
| }); | ||
| const schemaTypes = (schema) => { | ||
| const rawType = schema["type"]; | ||
| if (Array.isArray(rawType)) { | ||
| return rawType.filter((t) => typeof t === "string"); | ||
| } | ||
| return typeof rawType === "string" ? [rawType] : []; | ||
| }; | ||
| const isPlainObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value); | ||
| const enumValues = (schema) => Array.isArray(schema["enum"]) ? schema["enum"] : undefined; | ||
| const validateString = (schema, value, path) => { | ||
| const maxLength = schema["maxLength"]; | ||
| if (typeof maxLength === "number" && value.length > maxLength) { | ||
| return fail(path, `string longer than maxLength ${maxLength}`); | ||
| } | ||
| return ok; | ||
| }; | ||
| const validateNumber = (schema, value, path, integer) => { | ||
| if (integer && !Number.isInteger(value)) { | ||
| return fail(path, "expected an integer"); | ||
| } | ||
| const minimum = schema["minimum"]; | ||
| if (typeof minimum === "number" && value < minimum) { | ||
| return fail(path, `number below minimum ${minimum}`); | ||
| } | ||
| const maximum = schema["maximum"]; | ||
| if (typeof maximum === "number" && value > maximum) { | ||
| return fail(path, `number above maximum ${maximum}`); | ||
| } | ||
| return ok; | ||
| }; | ||
| const validateArray = (schema, value, path) => { | ||
| const minItems = schema["minItems"]; | ||
| if (typeof minItems === "number" && value.length < minItems) { | ||
| return fail(path, `array shorter than minItems ${minItems}`); | ||
| } | ||
| const maxItems = schema["maxItems"]; | ||
| if (typeof maxItems === "number" && value.length > maxItems) { | ||
| return fail(path, `array longer than maxItems ${maxItems}`); | ||
| } | ||
| const items = schema["items"]; | ||
| if (isPlainObject(items)) { | ||
| for (const [index, element] of value.entries()) { | ||
| const result = validateValue(items, element, `${path}[${index}]`); | ||
| if (!result.valid) { | ||
| return result; | ||
| } | ||
| } | ||
| } | ||
| return ok; | ||
| }; | ||
| const validateObject = (schema, value, path) => { | ||
| const properties = isPlainObject(schema["properties"]) | ||
| ? schema["properties"] | ||
| : {}; | ||
| const allowsAdditional = schema["additionalProperties"] === true; | ||
| const required = Array.isArray(schema["required"]) ? schema["required"] : []; | ||
| for (const key of required) { | ||
| if (typeof key === "string" && value[key] === undefined) { | ||
| return fail(path === "" ? key : `${path}.${key}`, "missing required property"); | ||
| } | ||
| } | ||
| for (const [key, child] of Object.entries(value)) { | ||
| const childSchema = properties[key]; | ||
| const childPath = path === "" ? key : `${path}.${key}`; | ||
| if (isPlainObject(childSchema)) { | ||
| const result = validateValue(childSchema, child, childPath); | ||
| if (!result.valid) { | ||
| return result; | ||
| } | ||
| continue; | ||
| } | ||
| if (!allowsAdditional && Object.keys(properties).length > 0) { | ||
| return fail(childPath, "unknown property"); | ||
| } | ||
| } | ||
| return ok; | ||
| }; | ||
| const validateValue = (schema, value, path) => { | ||
| const values = enumValues(schema); | ||
| if (values && !values.includes(value)) { | ||
| return fail(path, `value is not one of ${JSON.stringify(values)}`); | ||
| } | ||
| const types = schemaTypes(schema); | ||
| if (types.length === 0) { | ||
| // A schema with no `type` (e.g. set_field_value.content.value) accepts any | ||
| // JSON value; only its enum (checked above) constrains it. | ||
| return ok; | ||
| } | ||
| if (value === null) { | ||
| return types.includes("null") | ||
| ? ok | ||
| : fail(path, `null is not allowed (expected ${types.join("|")})`); | ||
| } | ||
| if (types.includes("string") && typeof value === "string") { | ||
| return validateString(schema, value, path); | ||
| } | ||
| if (types.includes("integer") && typeof value === "number") { | ||
| return validateNumber(schema, value, path, true); | ||
| } | ||
| if (types.includes("number") && typeof value === "number") { | ||
| return validateNumber(schema, value, path, false); | ||
| } | ||
| if (types.includes("boolean") && typeof value === "boolean") { | ||
| return ok; | ||
| } | ||
| if (types.includes("array") && Array.isArray(value)) { | ||
| return validateArray(schema, value, path); | ||
| } | ||
| if (types.includes("object") && isPlainObject(value)) { | ||
| return validateObject(schema, value, path); | ||
| } | ||
| return fail(path, `expected ${types.join("|")}`); | ||
| }; | ||
| /** | ||
| * Validate `data` against a tool's `inputSchema` in interpreted mode. The root | ||
| * schema is always an object schema (`{ type: "object", properties }`). | ||
| */ | ||
| export const validateAgainstSchema = (schema, data) => validateValue(schema, data, ""); | ||
| //# sourceMappingURL=json-schema-validate.js.map |
| {"version":3,"file":"json-schema-validate.js","sourceRoot":"","sources":["../src/json-schema-validate.ts"],"names":[],"mappings":"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"} |
| import { Result } from "better-result"; | ||
| import { CliBaseError } from "./auth/errors.js"; | ||
| /** One text content block of a `CallToolResult`. */ | ||
| export type ToolResultContent = { | ||
| type: string; | ||
| text: string; | ||
| }; | ||
| /** The `tools/call` result envelope (a success envelope even when isError). */ | ||
| export type CallToolResult = { | ||
| content: readonly ToolResultContent[]; | ||
| isError?: boolean; | ||
| }; | ||
| /** One tool as returned by `tools/list` (the four wire fields). */ | ||
| export type ListedTool = { | ||
| name: string; | ||
| description?: string; | ||
| inputSchema: Record<string, unknown>; | ||
| annotations?: { | ||
| readOnlyHint?: boolean; | ||
| destructiveHint?: boolean; | ||
| }; | ||
| }; | ||
| export type ListToolsResult = { | ||
| tools: readonly unknown[]; | ||
| }; | ||
| /** One `content` block of a `resources/read` result. */ | ||
| export type ResourceContent = { | ||
| uri?: string; | ||
| mimeType?: string; | ||
| text?: string; | ||
| }; | ||
| /** The `resources/read` result envelope. */ | ||
| export type ReadResourceResult = { | ||
| contents: readonly ResourceContent[]; | ||
| }; | ||
| /** | ||
| * A transport/HTTP/protocol failure. The three tiers (spec 051 S0/S4) are | ||
| * carried on `kind` so the exit-code mapping can distinguish them: | ||
| * - `transport`: fetch threw / timed out / body was not JSON | ||
| * - `http`: non-2xx HTTP status (401/403/404/5xx) | ||
| * - `rpc`: a JSON-RPC protocol error object (`error.code`) | ||
| * | ||
| * An application-level tool error (`isError: true`, HTTP 200) is NOT this: it | ||
| * comes back as a normal `CallToolResult` for the output layer to surface. | ||
| */ | ||
| export declare class McpClientError extends CliBaseError<"McpClientError"> { | ||
| readonly name = "McpClientError"; | ||
| readonly kind: "transport" | "http" | "rpc"; | ||
| readonly httpStatus?: number; | ||
| readonly rpcCode?: number; | ||
| constructor(props: { | ||
| message: string; | ||
| kind: "transport" | "http" | "rpc"; | ||
| httpStatus?: number; | ||
| rpcCode?: number; | ||
| }); | ||
| } | ||
| /** Invoke a tool via `tools/call`. `isError:true` results come back as success. */ | ||
| export declare const callTool: ({ serverUrl, token, name, args, }: { | ||
| serverUrl: string; | ||
| token: string; | ||
| name: string; | ||
| args: Record<string, unknown>; | ||
| }) => Promise<Result<CallToolResult, McpClientError>>; | ||
| /** Enumerate the server's tools via `tools/list`. */ | ||
| export declare const listTools: ({ serverUrl, token, }: { | ||
| serverUrl: string; | ||
| token: string; | ||
| }) => Promise<Result<ListToolsResult, McpClientError>>; | ||
| /** The raw `tools/list` body plus the CLI-version headers riding on it. */ | ||
| export type RawToolsList = { | ||
| rawBody: string; | ||
| cliLatest?: string; | ||
| cliMinimum?: string; | ||
| }; | ||
| /** | ||
| * Fetch the raw `tools/list` response body (spec S5.5). The runtime trust | ||
| * boundary hashes and validates the exact bytes the server returned, so this | ||
| * returns the unparsed text rather than a decoded envelope, plus the advertised | ||
| * CLI-version headers (spec 051 addendum) for the update nudge. | ||
| */ | ||
| export declare const fetchToolsListRaw: ({ serverUrl, token, }: { | ||
| serverUrl: string; | ||
| token: string; | ||
| }) => Promise<Result<RawToolsList, McpClientError>>; | ||
| /** Enumerate the server's static resources via `resources/list`. */ | ||
| export declare const listResources: ({ serverUrl, token, }: { | ||
| serverUrl: string; | ||
| token: string; | ||
| }) => Promise<Result<{ | ||
| resources: readonly unknown[]; | ||
| }, McpClientError>>; | ||
| /** Read one resource by URI via `resources/read`. */ | ||
| export declare const readResource: ({ serverUrl, token, uri, }: { | ||
| serverUrl: string; | ||
| token: string; | ||
| uri: string; | ||
| }) => Promise<Result<ReadResourceResult, McpClientError>>; |
| // Minimal hand-rolled JSON-RPC 2.0 client for the stella MCP endpoint (spec 051 | ||
| // S0). The server runs the SDK transport in stateless JSON mode | ||
| // (`enableJsonResponse: true`) with no `initialize` handshake required, so a | ||
| // bare `tools/call`/`tools/list` POST works. We do not depend on | ||
| // `@modelcontextprotocol/sdk`: the client only ever plumbs these two methods. | ||
| // | ||
| // The bearer token is NEVER logged or embedded in an error message. | ||
| import { Result } from "better-result"; | ||
| import { CliBaseError } from "./auth/errors.js"; | ||
| import { MCP_HTTP_PATH } from "./mcp-constants.js"; | ||
| // `tools/call` can drive a long server operation (e.g. fill_template), so it | ||
| // keeps a generous ceiling. The `tools/list` metadata fetch, by contrast, runs | ||
| // on the startup refresh path and is awaited before the command executes, so a | ||
| // tighter ceiling bounds how long an offline/slow client stalls before it falls | ||
| // back to the baked-in tree. | ||
| const REQUEST_TIMEOUT_MS = 30_000; | ||
| const LIST_REQUEST_TIMEOUT_MS = 10_000; | ||
| const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value); | ||
| /** | ||
| * A transport/HTTP/protocol failure. The three tiers (spec 051 S0/S4) are | ||
| * carried on `kind` so the exit-code mapping can distinguish them: | ||
| * - `transport`: fetch threw / timed out / body was not JSON | ||
| * - `http`: non-2xx HTTP status (401/403/404/5xx) | ||
| * - `rpc`: a JSON-RPC protocol error object (`error.code`) | ||
| * | ||
| * An application-level tool error (`isError: true`, HTTP 200) is NOT this: it | ||
| * comes back as a normal `CallToolResult` for the output layer to surface. | ||
| */ | ||
| export class McpClientError extends CliBaseError { | ||
| name = "McpClientError"; | ||
| kind; | ||
| httpStatus; | ||
| rpcCode; | ||
| constructor(props) { | ||
| super("McpClientError", props.message); | ||
| this.kind = props.kind; | ||
| if (props.httpStatus !== undefined) { | ||
| this.httpStatus = props.httpStatus; | ||
| } | ||
| if (props.rpcCode !== undefined) { | ||
| this.rpcCode = props.rpcCode; | ||
| } | ||
| } | ||
| } | ||
| const mcpUrl = (serverUrl) => new URL(MCP_HTTP_PATH, `${serverUrl.replace(/\/$/u, "")}/`).toString(); | ||
| const callRpc = async ({ serverUrl, token, method, params, }) => { | ||
| const body = { jsonrpc: "2.0", id: 1, method, params }; | ||
| const response = await Result.tryPromise({ | ||
| try: async () => await fetch(mcpUrl(serverUrl), { | ||
| method: "POST", | ||
| headers: { | ||
| "Content-Type": "application/json", | ||
| // Both required or the streamable-HTTP transport answers 406. | ||
| Accept: "application/json, text/event-stream", | ||
| Authorization: `Bearer ${token}`, | ||
| }, | ||
| body: JSON.stringify(body), | ||
| signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS), | ||
| }), | ||
| catch: (cause) => cause, | ||
| }); | ||
| if (Result.isError(response)) { | ||
| return Result.err(new McpClientError({ | ||
| kind: "transport", | ||
| message: `Request to the MCP server failed: ${response.error instanceof Error | ||
| ? response.error.message | ||
| : "network error"}`, | ||
| })); | ||
| } | ||
| const httpResponse = response.value; | ||
| const rawText = await Result.tryPromise({ | ||
| try: async () => await httpResponse.text(), | ||
| catch: (cause) => cause, | ||
| }); | ||
| const text = Result.isOk(rawText) ? rawText.value : ""; | ||
| if (!httpResponse.ok) { | ||
| return Result.err(new McpClientError({ | ||
| kind: "http", | ||
| httpStatus: httpResponse.status, | ||
| message: `MCP server returned HTTP ${httpResponse.status}${text ? `: ${text.slice(0, 500)}` : ""}`, | ||
| })); | ||
| } | ||
| const parsed = Result.try(() => JSON.parse(text)); | ||
| if (Result.isError(parsed)) { | ||
| return Result.err(new McpClientError({ | ||
| kind: "transport", | ||
| message: "MCP server returned a non-JSON response body", | ||
| })); | ||
| } | ||
| const envelope = parsed.value; | ||
| if (!isRecord(envelope)) { | ||
| return Result.err(new McpClientError({ | ||
| kind: "transport", | ||
| message: "MCP server returned an unexpected response envelope", | ||
| })); | ||
| } | ||
| const errorField = envelope["error"]; | ||
| if (isRecord(errorField)) { | ||
| const rawCode = errorField["code"]; | ||
| const code = typeof rawCode === "number" ? rawCode : undefined; | ||
| const rawMessage = errorField["message"]; | ||
| const message = typeof rawMessage === "string" ? rawMessage : "MCP protocol error"; | ||
| return Result.err(new McpClientError({ | ||
| kind: "rpc", | ||
| ...(code === undefined ? {} : { rpcCode: code }), | ||
| message, | ||
| })); | ||
| } | ||
| if (!("result" in envelope)) { | ||
| return Result.err(new McpClientError({ | ||
| kind: "transport", | ||
| message: "MCP response envelope had neither result nor error", | ||
| })); | ||
| } | ||
| return Result.ok(envelope["result"]); | ||
| }; | ||
| const isCallToolResult = (value) => typeof value === "object" && | ||
| value !== null && | ||
| "content" in value && | ||
| Array.isArray(value.content); | ||
| /** Invoke a tool via `tools/call`. `isError:true` results come back as success. */ | ||
| export const callTool = async ({ serverUrl, token, name, args, }) => { | ||
| const result = await callRpc({ | ||
| serverUrl, | ||
| token, | ||
| method: "tools/call", | ||
| params: { name, arguments: args }, | ||
| }); | ||
| if (Result.isError(result)) { | ||
| return Result.err(result.error); | ||
| } | ||
| if (!isCallToolResult(result.value)) { | ||
| return Result.err(new McpClientError({ | ||
| kind: "transport", | ||
| message: "tools/call returned an unexpected result shape", | ||
| })); | ||
| } | ||
| return Result.ok(result.value); | ||
| }; | ||
| /** Enumerate the server's tools via `tools/list`. */ | ||
| export const listTools = async ({ serverUrl, token, }) => { | ||
| const result = await callRpc({ | ||
| serverUrl, | ||
| token, | ||
| method: "tools/list", | ||
| params: {}, | ||
| }); | ||
| if (Result.isError(result)) { | ||
| return Result.err(result.error); | ||
| } | ||
| const value = result.value; | ||
| if (!isRecord(value) || !Array.isArray(value["tools"])) { | ||
| return Result.err(new McpClientError({ | ||
| kind: "transport", | ||
| message: "tools/list returned an unexpected result shape", | ||
| })); | ||
| } | ||
| return Result.ok({ tools: value["tools"] }); | ||
| }; | ||
| /** Header names carrying the advertised/minimum CLI version (spec 051 addendum). */ | ||
| const CLI_LATEST_HEADER = "x-stella-cli-latest"; | ||
| const CLI_MINIMUM_HEADER = "x-stella-cli-minimum"; | ||
| /** | ||
| * Fetch the raw `tools/list` response body (spec S5.5). The runtime trust | ||
| * boundary hashes and validates the exact bytes the server returned, so this | ||
| * returns the unparsed text rather than a decoded envelope, plus the advertised | ||
| * CLI-version headers (spec 051 addendum) for the update nudge. | ||
| */ | ||
| export const fetchToolsListRaw = async ({ serverUrl, token, }) => { | ||
| const body = { | ||
| jsonrpc: "2.0", | ||
| id: 1, | ||
| method: "tools/list", | ||
| params: {}, | ||
| }; | ||
| const response = await Result.tryPromise({ | ||
| try: async () => await fetch(mcpUrl(serverUrl), { | ||
| method: "POST", | ||
| headers: { | ||
| "Content-Type": "application/json", | ||
| Accept: "application/json, text/event-stream", | ||
| Authorization: `Bearer ${token}`, | ||
| }, | ||
| body: JSON.stringify(body), | ||
| signal: AbortSignal.timeout(LIST_REQUEST_TIMEOUT_MS), | ||
| }), | ||
| catch: (cause) => cause, | ||
| }); | ||
| if (Result.isError(response)) { | ||
| return Result.err(new McpClientError({ | ||
| kind: "transport", | ||
| message: `Request to the MCP server failed: ${response.error instanceof Error | ||
| ? response.error.message | ||
| : "network error"}`, | ||
| })); | ||
| } | ||
| const httpResponse = response.value; | ||
| const rawText = await Result.tryPromise({ | ||
| try: async () => await httpResponse.text(), | ||
| catch: (cause) => cause, | ||
| }); | ||
| const text = Result.isOk(rawText) ? rawText.value : ""; | ||
| if (!httpResponse.ok) { | ||
| return Result.err(new McpClientError({ | ||
| kind: "http", | ||
| httpStatus: httpResponse.status, | ||
| message: `MCP server returned HTTP ${httpResponse.status}`, | ||
| })); | ||
| } | ||
| const out = { rawBody: text }; | ||
| const cliLatest = httpResponse.headers.get(CLI_LATEST_HEADER); | ||
| if (cliLatest !== null) { | ||
| out.cliLatest = cliLatest; | ||
| } | ||
| const cliMinimum = httpResponse.headers.get(CLI_MINIMUM_HEADER); | ||
| if (cliMinimum !== null) { | ||
| out.cliMinimum = cliMinimum; | ||
| } | ||
| return Result.ok(out); | ||
| }; | ||
| /** Enumerate the server's static resources via `resources/list`. */ | ||
| export const listResources = async ({ serverUrl, token, }) => { | ||
| const result = await callRpc({ | ||
| serverUrl, | ||
| token, | ||
| method: "resources/list", | ||
| params: {}, | ||
| }); | ||
| if (Result.isError(result)) { | ||
| return Result.err(result.error); | ||
| } | ||
| const value = result.value; | ||
| if (!isRecord(value) || !Array.isArray(value["resources"])) { | ||
| return Result.err(new McpClientError({ | ||
| kind: "transport", | ||
| message: "resources/list returned an unexpected result shape", | ||
| })); | ||
| } | ||
| return Result.ok({ resources: value["resources"] }); | ||
| }; | ||
| /** Read one resource by URI via `resources/read`. */ | ||
| export const readResource = async ({ serverUrl, token, uri, }) => { | ||
| const result = await callRpc({ | ||
| serverUrl, | ||
| token, | ||
| method: "resources/read", | ||
| params: { uri }, | ||
| }); | ||
| if (Result.isError(result)) { | ||
| return Result.err(result.error); | ||
| } | ||
| const value = result.value; | ||
| if (!isRecord(value) || !Array.isArray(value["contents"])) { | ||
| return Result.err(new McpClientError({ | ||
| kind: "transport", | ||
| message: "resources/read returned an unexpected result shape", | ||
| })); | ||
| } | ||
| const contents = []; | ||
| for (const entry of value["contents"]) { | ||
| if (isRecord(entry)) { | ||
| const content = {}; | ||
| if (typeof entry["uri"] === "string") { | ||
| content.uri = entry["uri"]; | ||
| } | ||
| if (typeof entry["mimeType"] === "string") { | ||
| content.mimeType = entry["mimeType"]; | ||
| } | ||
| if (typeof entry["text"] === "string") { | ||
| content.text = entry["text"]; | ||
| } | ||
| contents.push(content); | ||
| } | ||
| } | ||
| return Result.ok({ contents }); | ||
| }; | ||
| //# sourceMappingURL=mcp-client.js.map |
| {"version":3,"file":"mcp-client.js","sourceRoot":"","sources":["../src/mcp-client.ts"],"names":[],"mappings":"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"} |
| /** The MCP JSON-RPC endpoint path, mirroring the server's `MCP_HTTP_PATH`. */ | ||
| export declare const MCP_HTTP_PATH = "/mcp"; | ||
| /** `--all` cursor-following ceilings (spec 051 S4). Bounded, moved client-side. */ | ||
| export declare const MAX_ALL_PAGES = 50; | ||
| export declare const MAX_ALL_ITEMS = 10000; | ||
| export declare const MAX_ALL_BYTES: number; | ||
| /** | ||
| * Machine codes a tool `isError` payload may carry to identify a disabled | ||
| * `FEATURE_*` gate (spec 051 S4, exit 5). `feature` is not on the wire and is | ||
| * per-org server state, so the CLI never gates a command client-side; it only | ||
| * upgrades the exit class from 4 to 5 when the server tags the failure with one | ||
| * of these codes. Until the server tags it, a feature error stays exit 4. | ||
| */ | ||
| export declare const FEATURE_DISABLED_ERROR_CODES: ReadonlySet<string>; | ||
| /** Exit-code classes (spec 051 S4), distinct per failure class. */ | ||
| export declare const EXIT_CODES: { | ||
| readonly ok: 0; | ||
| readonly unexpected: 1; | ||
| readonly validation: 2; | ||
| readonly auth: 3; | ||
| readonly server: 4; | ||
| readonly featureDisabled: 5; | ||
| readonly notFound: 6; | ||
| readonly aborted: 7; | ||
| }; | ||
| export type ExitCode = (typeof EXIT_CODES)[keyof typeof EXIT_CODES]; |
| // Shared constants for the domain-command runtime (spec 051). | ||
| /** The MCP JSON-RPC endpoint path, mirroring the server's `MCP_HTTP_PATH`. */ | ||
| export const MCP_HTTP_PATH = "/mcp"; | ||
| /** `--all` cursor-following ceilings (spec 051 S4). Bounded, moved client-side. */ | ||
| export const MAX_ALL_PAGES = 50; | ||
| export const MAX_ALL_ITEMS = 10_000; | ||
| export const MAX_ALL_BYTES = 32 * 1024 * 1024; | ||
| /** | ||
| * Machine codes a tool `isError` payload may carry to identify a disabled | ||
| * `FEATURE_*` gate (spec 051 S4, exit 5). `feature` is not on the wire and is | ||
| * per-org server state, so the CLI never gates a command client-side; it only | ||
| * upgrades the exit class from 4 to 5 when the server tags the failure with one | ||
| * of these codes. Until the server tags it, a feature error stays exit 4. | ||
| */ | ||
| export const FEATURE_DISABLED_ERROR_CODES = new Set([ | ||
| "feature_disabled", | ||
| "FEATURE_DISABLED", | ||
| ]); | ||
| /** Exit-code classes (spec 051 S4), distinct per failure class. */ | ||
| export const EXIT_CODES = { | ||
| ok: 0, | ||
| unexpected: 1, | ||
| validation: 2, | ||
| auth: 3, | ||
| server: 4, | ||
| featureDisabled: 5, | ||
| notFound: 6, | ||
| aborted: 7, | ||
| }; | ||
| //# sourceMappingURL=mcp-constants.js.map |
| {"version":3,"file":"mcp-constants.js","sourceRoot":"","sources":["../src/mcp-constants.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAE9D,8EAA8E;AAC9E,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC;AAEpC,mFAAmF;AACnF,MAAM,CAAC,MAAM,aAAa,GAAG,EAAE,CAAC;AAChC,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC;AACpC,MAAM,CAAC,MAAM,aAAa,GAAW,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAEtD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAwB,IAAI,GAAG,CAAC;IACvE,kBAAkB;IAClB,kBAAkB;CACnB,CAAC,CAAC;AAEH,mEAAmE;AACnE,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,EAAE,EAAE,CAAC;IACL,UAAU,EAAE,CAAC;IACb,UAAU,EAAE,CAAC;IACb,IAAI,EAAE,CAAC;IACP,MAAM,EAAE,CAAC;IACT,eAAe,EAAE,CAAC;IAClB,QAAQ,EAAE,CAAC;IACX,OAAO,EAAE,CAAC;CACF,CAAC"} |
| export type OutputFormat = "json" | "table"; | ||
| /** Reserved output flags read off a parsed command's flags. */ | ||
| export type OutputFlags = { | ||
| output?: OutputFormat | undefined; | ||
| json?: boolean | undefined; | ||
| table?: boolean | undefined; | ||
| }; | ||
| export declare const selectFormat: ({ flags, isTTY, }: { | ||
| flags: OutputFlags; | ||
| isTTY: boolean; | ||
| }) => OutputFormat; | ||
| /** The four mutually exclusive render shapes (spec S4). */ | ||
| export type RenderPlan = { | ||
| kind: "page"; | ||
| itemsKey: string; | ||
| items: readonly unknown[]; | ||
| payload: unknown; | ||
| nextCursor: string | null; | ||
| columns: readonly string[] | undefined; | ||
| } | { | ||
| kind: "single"; | ||
| payload: unknown; | ||
| } | { | ||
| kind: "windowed-text"; | ||
| text: string; | ||
| nextCursor: string | null; | ||
| } | { | ||
| kind: "raw-text"; | ||
| text: string; | ||
| }; | ||
| /** | ||
| * Choose the render shape for a parsed payload given the leaf's annotations and | ||
| * whether a single-read flip is active for this invocation (spec S4). | ||
| */ | ||
| export declare const buildRenderPlan: ({ payload, itemsKey, windowedText, singleReadActive, columns, }: { | ||
| payload: unknown; | ||
| itemsKey: string | undefined; | ||
| windowedText: boolean; | ||
| singleReadActive: boolean; | ||
| columns: readonly string[] | undefined; | ||
| }) => RenderPlan; | ||
| export type Writers = { | ||
| stdout: (text: string) => void; | ||
| stderr: (text: string) => void; | ||
| }; | ||
| /** Render a plan to stdout, emitting a `--cursor` resume hint on stderr. */ | ||
| export declare const renderResult: ({ plan, format, writers, allActive, }: { | ||
| plan: RenderPlan; | ||
| format: OutputFormat; | ||
| writers: Writers; | ||
| allActive: boolean; | ||
| }) => void; |
+135
| // Output layer (spec 051 S4). Every response is parsed as | ||
| // `JSON.parse(content[0].text)` upstream; here we pick the render shape as a | ||
| // discriminated union (page envelope / single object / windowed text / raw | ||
| // text) and render it as a table (default on a TTY) or pretty JSON (default off | ||
| // a TTY), honoring `--output`/`--json`/`--table`. `nextCursor` hints and `--all` | ||
| // truncation notices go to stderr so a piped JSON stdout stays clean. | ||
| export const selectFormat = ({ flags, isTTY, }) => { | ||
| if (flags.output !== undefined) { | ||
| return flags.output; | ||
| } | ||
| if (flags.json === true) { | ||
| return "json"; | ||
| } | ||
| if (flags.table === true) { | ||
| return "table"; | ||
| } | ||
| return isTTY ? "table" : "json"; | ||
| }; | ||
| const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value); | ||
| const asString = (value) => typeof value === "string" ? value : null; | ||
| const arrayAt = (payload, key) => { | ||
| if (!isRecord(payload)) { | ||
| return null; | ||
| } | ||
| const value = payload[key]; | ||
| return Array.isArray(value) ? value : null; | ||
| }; | ||
| const fieldOf = (payload, key) => isRecord(payload) ? payload[key] : undefined; | ||
| /** | ||
| * Choose the render shape for a parsed payload given the leaf's annotations and | ||
| * whether a single-read flip is active for this invocation (spec S4). | ||
| */ | ||
| export const buildRenderPlan = ({ payload, itemsKey, windowedText, singleReadActive, columns, }) => { | ||
| if (windowedText) { | ||
| return { | ||
| kind: "windowed-text", | ||
| text: asString(fieldOf(payload, "text")) ?? "", | ||
| nextCursor: asString(fieldOf(payload, "nextCursor")), | ||
| }; | ||
| } | ||
| if (!singleReadActive && itemsKey !== undefined) { | ||
| const items = arrayAt(payload, itemsKey); | ||
| if (items !== null) { | ||
| return { | ||
| kind: "page", | ||
| itemsKey, | ||
| items, | ||
| payload, | ||
| nextCursor: asString(fieldOf(payload, "nextCursor")), | ||
| columns, | ||
| }; | ||
| } | ||
| } | ||
| return { kind: "single", payload }; | ||
| }; | ||
| const formatCell = (value) => { | ||
| if (value === null || value === undefined) { | ||
| return ""; | ||
| } | ||
| if (typeof value === "string") { | ||
| return value; | ||
| } | ||
| if (typeof value === "number" || typeof value === "boolean") { | ||
| return String(value); | ||
| } | ||
| return JSON.stringify(value); | ||
| }; | ||
| const renderTable = ({ items, columns, }) => { | ||
| if (items.length === 0) { | ||
| return "(no results)"; | ||
| } | ||
| const first = items.at(0); | ||
| const cols = columns ?? (isRecord(first) ? Object.keys(first) : ["value"]); | ||
| const rows = items.map((item) => cols.map((col) => isRecord(item) ? formatCell(item[col]) : formatCell(item))); | ||
| const widths = cols.map((col, index) => Math.max(col.length, ...rows.map((row) => (row[index] ?? "").length))); | ||
| const pad = (cells) => cells | ||
| .map((cell, index) => cell.padEnd(widths[index] ?? cell.length)) | ||
| .join(" ") | ||
| .trimEnd(); | ||
| const header = pad(cols); | ||
| const separator = widths.map((width) => "-".repeat(width)).join(" "); | ||
| return [header, separator, ...rows.map(pad)].join("\n"); | ||
| }; | ||
| const renderKeyValue = (payload) => { | ||
| if (!isRecord(payload)) { | ||
| return formatCell(payload); | ||
| } | ||
| const keys = Object.keys(payload); | ||
| if (keys.length === 0) { | ||
| return "(empty)"; | ||
| } | ||
| const width = Math.max(...keys.map((key) => key.length)); | ||
| return keys | ||
| .map((key) => `${key.padEnd(width)} ${formatCell(payload[key])}`) | ||
| .join("\n"); | ||
| }; | ||
| /** Render a plan to stdout, emitting a `--cursor` resume hint on stderr. */ | ||
| export const renderResult = ({ plan, format, writers, allActive, }) => { | ||
| if (plan.kind === "raw-text") { | ||
| writers.stdout(plan.text.endsWith("\n") ? plan.text : `${plan.text}\n`); | ||
| return; | ||
| } | ||
| if (plan.kind === "windowed-text") { | ||
| if (format === "json") { | ||
| writers.stdout(`${JSON.stringify({ text: plan.text }, null, 2)}\n`); | ||
| } | ||
| else { | ||
| writers.stdout(plan.text.endsWith("\n") ? plan.text : `${plan.text}\n`); | ||
| } | ||
| if (!allActive && plan.nextCursor !== null) { | ||
| writers.stderr(`more: --cursor ${plan.nextCursor}\n`); | ||
| } | ||
| return; | ||
| } | ||
| if (plan.kind === "single") { | ||
| if (format === "json") { | ||
| writers.stdout(`${JSON.stringify(plan.payload, null, 2)}\n`); | ||
| } | ||
| else { | ||
| writers.stdout(`${renderKeyValue(plan.payload)}\n`); | ||
| } | ||
| return; | ||
| } | ||
| // page envelope | ||
| if (format === "json") { | ||
| writers.stdout(`${JSON.stringify(plan.payload, null, 2)}\n`); | ||
| } | ||
| else { | ||
| writers.stdout(`${renderTable({ items: plan.items, columns: plan.columns })}\n`); | ||
| } | ||
| if (!allActive && plan.nextCursor !== null) { | ||
| writers.stderr(`more: --cursor ${plan.nextCursor}\n`); | ||
| } | ||
| }; | ||
| //# sourceMappingURL=output.js.map |
| {"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"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"} |
| import type { RegistryToolListing } from "./route-types.js"; | ||
| export declare const CACHE_SCHEMA_VERSION = 2; | ||
| /** Default time-to-live before a cached listing is refetched (spec S5.3). */ | ||
| export declare const DEFAULT_TTL_SECONDS = 86400; | ||
| /** The delta of a fetched registry vs the baked-in tree (spec S5.3). */ | ||
| export type RegistryDelta = { | ||
| added: readonly string[]; | ||
| removed: readonly string[]; | ||
| changed: readonly string[]; | ||
| }; | ||
| /** The on-disk cache file shape (spec S5.3). */ | ||
| export type RegistryCacheFile = { | ||
| version: number; | ||
| serverOrigin: string; | ||
| fetchedAt: string; | ||
| ttlSeconds: number; | ||
| toolsListHash: string; | ||
| listings: readonly RegistryToolListing[]; | ||
| delta: RegistryDelta; | ||
| /** The latest CLI version we last nudged about (update-nudge anti-nag key). */ | ||
| lastNudgedVersion?: string; | ||
| }; | ||
| /** The environment slice the cache directory resolution needs. */ | ||
| export type CacheEnv = { | ||
| XDG_CACHE_HOME?: string | undefined; | ||
| HOME?: string | undefined; | ||
| }; | ||
| /** The `stella/registry` cache directory (XDG, `~/.cache` fallback; spec S5.3). */ | ||
| export declare const cacheDir: (env: CacheEnv) => string; | ||
| /** A stable sha256 hex of the server origin, used as the cache filename. */ | ||
| export declare const originHash: (serverOrigin: string) => string; | ||
| /** The cache file path for a given origin (one file per origin; spec S5.5 rule 5). */ | ||
| export declare const cachePathFor: (serverOrigin: string, env: CacheEnv) => string; | ||
| /** True when the cache is older than its TTL and should be refetched. */ | ||
| export declare const isCacheStale: (file: RegistryCacheFile, nowMs: number) => boolean; | ||
| /** True when a delta has no additions, removals, or changes. */ | ||
| export declare const isDeltaEmpty: (delta: RegistryDelta) => boolean; | ||
| /** | ||
| * Diff fetched listings against the baked-in listings (spec S5.3): a tool is | ||
| * `changed` when its `inputSchema` shape (which drives generated flags, incl. | ||
| * `required[]`) differs. Descriptions and annotations do not count as changes. | ||
| */ | ||
| export declare const computeDelta: (baked: readonly RegistryToolListing[], fetched: readonly RegistryToolListing[]) => RegistryDelta; | ||
| /** | ||
| * Read and shape-validate the cache file for an origin. A missing, corrupt, or | ||
| * wrong-version file returns `undefined` (the caller falls back to baked-in). | ||
| */ | ||
| export declare const readCacheFile: (filePath: string) => Promise<RegistryCacheFile | undefined>; | ||
| /** Write the cache file, creating the cache directory if needed. */ | ||
| export declare const writeCacheFile: (filePath: string, file: RegistryCacheFile) => Promise<void>; |
| // The per-origin XDG registry cache (spec 051 S5.3). One file per server origin | ||
| // under `$XDG_CACHE_HOME/stella/registry/<origin-hash>.json` (`~/.cache/...` | ||
| // fallback). The cache lets a `tools/list` fetched once (at `auth login` or on a | ||
| // TTL refresh) drive the command tree offline until it goes stale, and records | ||
| // the delta vs the baked-in tree so a divergence can be surfaced on stderr. | ||
| // | ||
| // This module is I/O-bounded (reads/writes the cache file); pure helpers | ||
| // (`computeDelta`, `isCacheStale`, `isDeltaEmpty`) are exported for the runtime | ||
| // path and its tests. It stores no secrets: only public tool listings. | ||
| import { Result } from "better-result"; | ||
| import { createHash } from "node:crypto"; | ||
| import { mkdir, readFile, writeFile } from "node:fs/promises"; | ||
| import path from "node:path"; | ||
| // Cache schema version; a bump invalidates every existing cache file. Bumped to | ||
| // 2 when `lastNudgedVersion` (the CLI update-nudge anti-nag key) was added. | ||
| export const CACHE_SCHEMA_VERSION = 2; | ||
| /** Default time-to-live before a cached listing is refetched (spec S5.3). */ | ||
| export const DEFAULT_TTL_SECONDS = 86_400; | ||
| const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value); | ||
| /** The `stella/registry` cache directory (XDG, `~/.cache` fallback; spec S5.3). */ | ||
| export const cacheDir = (env) => { | ||
| const base = env.XDG_CACHE_HOME && env.XDG_CACHE_HOME.length > 0 | ||
| ? env.XDG_CACHE_HOME | ||
| : path.join(env.HOME ?? ".", ".cache"); | ||
| return path.join(base, "stella", "registry"); | ||
| }; | ||
| /** A stable sha256 hex of the server origin, used as the cache filename. */ | ||
| export const originHash = (serverOrigin) => createHash("sha256").update(serverOrigin).digest("hex"); | ||
| /** The cache file path for a given origin (one file per origin; spec S5.5 rule 5). */ | ||
| export const cachePathFor = (serverOrigin, env) => path.join(cacheDir(env), `${originHash(serverOrigin)}.json`); | ||
| /** True when the cache is older than its TTL and should be refetched. */ | ||
| export const isCacheStale = (file, nowMs) => { | ||
| const fetchedAtMs = Date.parse(file.fetchedAt); | ||
| if (Number.isNaN(fetchedAtMs)) { | ||
| return true; | ||
| } | ||
| return nowMs - fetchedAtMs > file.ttlSeconds * 1000; | ||
| }; | ||
| /** True when a delta has no additions, removals, or changes. */ | ||
| export const isDeltaEmpty = (delta) => delta.added.length === 0 && | ||
| delta.removed.length === 0 && | ||
| delta.changed.length === 0; | ||
| /** Deterministic key-sorted stringify, so a re-ordered schema is not a "change". */ | ||
| const stableStringify = (value) => { | ||
| if (Array.isArray(value)) { | ||
| return `[${value.map(stableStringify).join(",")}]`; | ||
| } | ||
| if (isRecord(value)) { | ||
| const keys = Object.keys(value).sort(); | ||
| return `{${keys | ||
| .map((key) => `${JSON.stringify(key)}:${stableStringify(value[key])}`) | ||
| .join(",")}}`; | ||
| } | ||
| // `value` here is a parsed-JSON primitive (string/number/boolean/null), for | ||
| // which `JSON.stringify` is always defined. | ||
| return JSON.stringify(value); | ||
| }; | ||
| /** | ||
| * Diff fetched listings against the baked-in listings (spec S5.3): a tool is | ||
| * `changed` when its `inputSchema` shape (which drives generated flags, incl. | ||
| * `required[]`) differs. Descriptions and annotations do not count as changes. | ||
| */ | ||
| export const computeDelta = (baked, fetched) => { | ||
| const bakedByName = new Map(baked.map((tool) => [tool.name, tool])); | ||
| const fetchedByName = new Map(fetched.map((tool) => [tool.name, tool])); | ||
| const added = []; | ||
| const removed = []; | ||
| const changed = []; | ||
| for (const tool of fetched) { | ||
| if (!bakedByName.has(tool.name)) { | ||
| added.push(tool.name); | ||
| } | ||
| } | ||
| for (const tool of baked) { | ||
| if (!fetchedByName.has(tool.name)) { | ||
| removed.push(tool.name); | ||
| } | ||
| } | ||
| for (const tool of fetched) { | ||
| const bakedTool = bakedByName.get(tool.name); | ||
| if (bakedTool === undefined) { | ||
| continue; | ||
| } | ||
| if (stableStringify(bakedTool.inputSchema) !== | ||
| stableStringify(tool.inputSchema)) { | ||
| changed.push(tool.name); | ||
| } | ||
| } | ||
| return { added, removed, changed }; | ||
| }; | ||
| /** | ||
| * Re-shape the cached `listings` on read (defense in depth for a locally-tampered | ||
| * cache): keep only the wire fields, and drop the whole file if any entry is | ||
| * malformed so the caller falls back to the baked-in tree. | ||
| */ | ||
| const parseListings = (value) => { | ||
| if (!Array.isArray(value)) { | ||
| return undefined; | ||
| } | ||
| const listings = []; | ||
| for (const entry of value) { | ||
| if (!isRecord(entry) || | ||
| typeof entry["name"] !== "string" || | ||
| typeof entry["description"] !== "string" || | ||
| !isRecord(entry["inputSchema"])) { | ||
| return undefined; | ||
| } | ||
| const listing = { | ||
| name: entry["name"], | ||
| description: entry["description"], | ||
| inputSchema: entry["inputSchema"], | ||
| }; | ||
| const annotations = entry["annotations"]; | ||
| if (isRecord(annotations)) { | ||
| const hints = {}; | ||
| if (typeof annotations["readOnlyHint"] === "boolean") { | ||
| hints.readOnlyHint = annotations["readOnlyHint"]; | ||
| } | ||
| if (typeof annotations["destructiveHint"] === "boolean") { | ||
| hints.destructiveHint = annotations["destructiveHint"]; | ||
| } | ||
| listing.annotations = hints; | ||
| } | ||
| listings.push(listing); | ||
| } | ||
| return listings; | ||
| }; | ||
| const parseDelta = (value) => { | ||
| if (!isRecord(value)) { | ||
| return undefined; | ||
| } | ||
| const asStrings = (raw) => Array.isArray(raw) && raw.every((item) => typeof item === "string") | ||
| ? raw | ||
| : undefined; | ||
| const added = asStrings(value["added"]); | ||
| const removed = asStrings(value["removed"]); | ||
| const changed = asStrings(value["changed"]); | ||
| if (added === undefined || removed === undefined || changed === undefined) { | ||
| return undefined; | ||
| } | ||
| return { added, removed, changed }; | ||
| }; | ||
| /** | ||
| * Read and shape-validate the cache file for an origin. A missing, corrupt, or | ||
| * wrong-version file returns `undefined` (the caller falls back to baked-in). | ||
| */ | ||
| export const readCacheFile = async (filePath) => { | ||
| const parsed = await Result.tryPromise({ | ||
| try: async () => JSON.parse(await readFile(filePath, "utf-8")), | ||
| catch: (cause) => cause, | ||
| }); | ||
| if (Result.isError(parsed)) { | ||
| return undefined; | ||
| } | ||
| const value = parsed.value; | ||
| if (!isRecord(value) || value["version"] !== CACHE_SCHEMA_VERSION) { | ||
| return undefined; | ||
| } | ||
| const serverOrigin = value["serverOrigin"]; | ||
| const fetchedAt = value["fetchedAt"]; | ||
| const ttlSeconds = value["ttlSeconds"]; | ||
| const toolsListHash = value["toolsListHash"]; | ||
| const listings = parseListings(value["listings"]); | ||
| const delta = parseDelta(value["delta"]); | ||
| if (typeof serverOrigin !== "string" || | ||
| typeof fetchedAt !== "string" || | ||
| typeof ttlSeconds !== "number" || | ||
| typeof toolsListHash !== "string" || | ||
| listings === undefined || | ||
| delta === undefined) { | ||
| return undefined; | ||
| } | ||
| const lastNudgedVersion = value["lastNudgedVersion"]; | ||
| return { | ||
| version: CACHE_SCHEMA_VERSION, | ||
| serverOrigin, | ||
| fetchedAt, | ||
| ttlSeconds, | ||
| toolsListHash, | ||
| listings, | ||
| delta, | ||
| ...(typeof lastNudgedVersion === "string" ? { lastNudgedVersion } : {}), | ||
| }; | ||
| }; | ||
| /** Write the cache file, creating the cache directory if needed. */ | ||
| export const writeCacheFile = async (filePath, file) => { | ||
| // `Bun.write` created missing parent directories implicitly; `node:fs` | ||
| // `writeFile` does not, so mkdir the origin cache dir first (spec S5.3). | ||
| await mkdir(path.dirname(filePath), { recursive: true }); | ||
| await writeFile(filePath, `${JSON.stringify(file, null, 2)}\n`); | ||
| }; | ||
| //# sourceMappingURL=registry-cache.js.map |
| {"version":3,"file":"registry-cache.js","sourceRoot":"","sources":["../src/registry-cache.ts"],"names":[],"mappings":"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"} |
| import { Result } from "better-result"; | ||
| import { type McpClientError, type RawToolsList } from "./mcp-client.js"; | ||
| import { type CacheEnv } from "./registry-cache.js"; | ||
| import type { RegistryToolListing, RouteNode } from "./route-types.js"; | ||
| /** | ||
| * Pick the command tree for this invocation without any network (spec S5.3). | ||
| * The baked-in tree is the default; a valid same-origin cache with a non-empty | ||
| * delta builds from the cached listings and carries the one-line stderr notice | ||
| * for that divergence. The notice reflects a persistent state (the server tree | ||
| * differs from the built-in tree until the next refresh reconciles the cache), | ||
| * so it is emitted per invocation while divergent rather than suppressed after | ||
| * the first: this read path takes no network and writes no disk. Provenance is | ||
| * pinned: a cache whose `serverOrigin` differs is ignored (rule 5), and a | ||
| * cached tree that fails to build falls back to baked-in (rule 6). | ||
| */ | ||
| export declare const resolveCommandTree: ({ serverOrigin, env, }: { | ||
| serverOrigin: string | undefined; | ||
| env: CacheEnv; | ||
| }) => Promise<{ | ||
| tree: RouteNode; | ||
| notice?: string; | ||
| }>; | ||
| /** The outcome of a cache-refresh attempt (spec S5.3/S5.5 + addendum nudge). */ | ||
| export type RefreshOutcome = { | ||
| status: "skipped"; | ||
| reason: "no-cache" | "fresh"; | ||
| } | { | ||
| status: "failed"; | ||
| warning: string; | ||
| } | { | ||
| status: "refreshed"; | ||
| deltaEmpty: boolean; | ||
| nudge?: string; | ||
| }; | ||
| type FetchRaw = () => Promise<Result<RawToolsList, McpClientError>>; | ||
| /** | ||
| * Refresh the per-origin cache (spec S5.3). Force-refreshes on `auth login`; | ||
| * otherwise only refreshes an existing cache once it is stale (a missing cache | ||
| * stays offline-instant and is seeded at login). Fails closed on any transport | ||
| * or trust-boundary violation, keeping the baked-in tree (rule 6). | ||
| */ | ||
| export declare const refreshRegistryCache: ({ serverOrigin, token, env, now, force, ttlSeconds, currentVersion, fetchRaw, bakedListings, }: { | ||
| serverOrigin: string; | ||
| token: string; | ||
| env: CacheEnv; | ||
| now?: number; | ||
| force?: boolean; | ||
| ttlSeconds?: number; | ||
| currentVersion?: string; | ||
| fetchRaw?: FetchRaw; | ||
| bakedListings?: readonly RegistryToolListing[]; | ||
| }) => Promise<RefreshOutcome>; | ||
| export {}; |
| // The runtime-fetch call site (spec 051 S5.2 runtime + S5.3 + S5.5). Startup | ||
| // always uses the baked-in tree (instant, offline); this module keeps the | ||
| // per-origin cache current and, when a validated fetch diverges from the | ||
| // baked-in tree, lets the next command build from the cached listings. | ||
| // | ||
| // Two entry points: | ||
| // - `resolveCommandTree`: read-only, no network. Picks the baked-in tree, or | ||
| // the cached-listings tree when the cache shows a non-empty delta, and | ||
| // returns the one-line stderr notice for that case. | ||
| // - `refreshRegistryCache`: fetch `tools/list`, validate through the S5.5 | ||
| // trust boundary, diff vs baked-in, and write the cache. Fails closed: any | ||
| // transport/validation failure leaves the trusted baked-in tree in place. | ||
| // | ||
| // Both share the ONE pure `generateRouteMap` and the ONE baked-in Annotation | ||
| // Table, so unknown fetched tools get the same S1 heuristic defaults as the | ||
| // build-time path. | ||
| import { Result } from "better-result"; | ||
| import { readFile } from "node:fs/promises"; | ||
| import { TOOL_ANNOTATIONS } from "./annotations.js"; | ||
| import { buildVersionNudge } from "./cli-version-nudge.js"; | ||
| import { generateRouteMap } from "./generate-route-map.js"; | ||
| import { CLI_VERSION } from "./generated/cli-version.js"; | ||
| import { generatedRouteMap } from "./generated/route-map.js"; | ||
| import { fetchToolsListRaw, } from "./mcp-client.js"; | ||
| import { CACHE_SCHEMA_VERSION, cachePathFor, computeDelta, DEFAULT_TTL_SECONDS, isCacheStale, isDeltaEmpty, readCacheFile, writeCacheFile, } from "./registry-cache.js"; | ||
| import { validateFetchedToolsList } from "./registry-trust.js"; | ||
| const SNAPSHOT_URL = new URL("generated/registry-snapshot.json", import.meta.url); | ||
| const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value); | ||
| /** Load the baked-in listings (the committed snapshot) for the delta diff. */ | ||
| const loadBakedListings = async () => { | ||
| const parsed = await Result.tryPromise({ | ||
| try: async () => JSON.parse(await readFile(SNAPSHOT_URL, "utf-8")), | ||
| catch: (cause) => cause, | ||
| }); | ||
| if (Result.isError(parsed) || !Array.isArray(parsed.value)) { | ||
| return []; | ||
| } | ||
| const listings = []; | ||
| for (const entry of parsed.value) { | ||
| // The snapshot is committed, trusted data; project the diff-relevant fields | ||
| // (name identity + schema shape) with plain guards, no casts. | ||
| if (!isRecord(entry)) { | ||
| continue; | ||
| } | ||
| const name = entry["name"]; | ||
| const inputSchema = entry["inputSchema"]; | ||
| const description = entry["description"]; | ||
| if (typeof name === "string" && isRecord(inputSchema)) { | ||
| listings.push({ | ||
| name, | ||
| description: typeof description === "string" ? description : "", | ||
| inputSchema, | ||
| }); | ||
| } | ||
| } | ||
| return listings; | ||
| }; | ||
| /** The one-line stderr notice for a diverged registry (spec S5.3). */ | ||
| const divergenceNotice = (file) => `server registry differs (+${file.delta.added.length} −${file.delta.removed.length} ~${file.delta.changed.length}); see 'stella tools list'\n`; | ||
| /** | ||
| * Pick the command tree for this invocation without any network (spec S5.3). | ||
| * The baked-in tree is the default; a valid same-origin cache with a non-empty | ||
| * delta builds from the cached listings and carries the one-line stderr notice | ||
| * for that divergence. The notice reflects a persistent state (the server tree | ||
| * differs from the built-in tree until the next refresh reconciles the cache), | ||
| * so it is emitted per invocation while divergent rather than suppressed after | ||
| * the first: this read path takes no network and writes no disk. Provenance is | ||
| * pinned: a cache whose `serverOrigin` differs is ignored (rule 5), and a | ||
| * cached tree that fails to build falls back to baked-in (rule 6). | ||
| */ | ||
| export const resolveCommandTree = async ({ serverOrigin, env, }) => { | ||
| if (serverOrigin === undefined) { | ||
| return { tree: generatedRouteMap }; | ||
| } | ||
| const file = await readCacheFile(cachePathFor(serverOrigin, env)); | ||
| if (file === undefined || file.serverOrigin !== serverOrigin) { | ||
| return { tree: generatedRouteMap }; | ||
| } | ||
| if (isDeltaEmpty(file.delta)) { | ||
| return { tree: generatedRouteMap }; | ||
| } | ||
| const built = Result.try(() => generateRouteMap(file.listings, TOOL_ANNOTATIONS)); | ||
| if (Result.isError(built)) { | ||
| return { tree: generatedRouteMap }; | ||
| } | ||
| return { tree: built.value, notice: divergenceNotice(file) }; | ||
| }; | ||
| /** | ||
| * Refresh the per-origin cache (spec S5.3). Force-refreshes on `auth login`; | ||
| * otherwise only refreshes an existing cache once it is stale (a missing cache | ||
| * stays offline-instant and is seeded at login). Fails closed on any transport | ||
| * or trust-boundary violation, keeping the baked-in tree (rule 6). | ||
| */ | ||
| export const refreshRegistryCache = async ({ serverOrigin, token, env, now = Date.now(), force = false, ttlSeconds = DEFAULT_TTL_SECONDS, currentVersion = CLI_VERSION, fetchRaw, bakedListings, }) => { | ||
| const filePath = cachePathFor(serverOrigin, env); | ||
| const existing = await readCacheFile(filePath); | ||
| if (!force) { | ||
| if (existing === undefined) { | ||
| return { status: "skipped", reason: "no-cache" }; | ||
| } | ||
| if (!isCacheStale(existing, now)) { | ||
| return { status: "skipped", reason: "fresh" }; | ||
| } | ||
| } | ||
| const fetcher = fetchRaw ?? | ||
| (async () => await fetchToolsListRaw({ serverUrl: serverOrigin, token })); | ||
| const raw = await fetcher(); | ||
| if (Result.isError(raw)) { | ||
| return { | ||
| status: "failed", | ||
| warning: `registry refresh skipped: ${raw.error.message}`, | ||
| }; | ||
| } | ||
| const trust = validateFetchedToolsList(raw.value.rawBody); | ||
| if (!trust.ok) { | ||
| return { | ||
| status: "failed", | ||
| warning: `registry refresh rejected (using built-in commands): ${trust.violation}`, | ||
| }; | ||
| } | ||
| const baked = bakedListings ?? (await loadBakedListings()); | ||
| const delta = computeDelta(baked, trust.listings); | ||
| // CLI update nudge (spec 051 addendum): evaluate the advertised version headers | ||
| // against this build; anti-nag on the version last nudged for this origin. | ||
| const nudge = buildVersionNudge({ | ||
| current: currentVersion, | ||
| latest: raw.value.cliLatest, | ||
| minimum: raw.value.cliMinimum, | ||
| lastNudged: existing?.lastNudgedVersion, | ||
| }); | ||
| const lastNudgedVersion = nudge.nudgeVersion ?? existing?.lastNudgedVersion; | ||
| const file = { | ||
| version: CACHE_SCHEMA_VERSION, | ||
| serverOrigin, | ||
| fetchedAt: new Date(now).toISOString(), | ||
| ttlSeconds, | ||
| toolsListHash: trust.toolsListHash, | ||
| listings: trust.listings, | ||
| delta, | ||
| ...(lastNudgedVersion === undefined ? {} : { lastNudgedVersion }), | ||
| }; | ||
| await writeCacheFile(filePath, file); | ||
| return { | ||
| status: "refreshed", | ||
| deltaEmpty: isDeltaEmpty(delta), | ||
| ...(nudge.line === undefined ? {} : { nudge: nudge.line }), | ||
| }; | ||
| }; | ||
| //# sourceMappingURL=registry-refresh.js.map |
| {"version":3,"file":"registry-refresh.js","sourceRoot":"","sources":["../src/registry-refresh.ts"],"names":[],"mappings":"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"} |
| import type { RegistryToolListing } from "./route-types.js"; | ||
| /** Reject a whole fetched body larger than this (bytes). */ | ||
| export declare const MAX_LISTING_BYTES: number; | ||
| /** Reject a body advertising more tools than this. */ | ||
| export declare const MAX_TOOLS = 200; | ||
| /** Reject an `inputSchema` nested deeper than this (also catches `$ref` cycles). */ | ||
| export declare const MAX_SCHEMA_DEPTH = 8; | ||
| /** Reject a single tool whose serialized `inputSchema` exceeds this (bytes). */ | ||
| export declare const MAX_TOOL_SCHEMA_BYTES: number; | ||
| /** Reject an `enum` with more members than this. */ | ||
| export declare const MAX_ENUM = 300; | ||
| /** Reject a `properties` object with more keys than this. */ | ||
| export declare const MAX_PROPS = 100; | ||
| /** Tool names must match this (spec S5.5 rule 2). */ | ||
| export declare const TOOL_NAME_PATTERN: RegExp; | ||
| /** The success/failure result of validating a fetched tools/list body. */ | ||
| export type TrustResult = { | ||
| ok: true; | ||
| listings: RegistryToolListing[]; | ||
| toolsListHash: string; | ||
| } | { | ||
| ok: false; | ||
| violation: string; | ||
| }; | ||
| /** | ||
| * Validate a raw fetched `tools/list` body (spec S5.5). On success returns the | ||
| * projected `RegistryToolListing[]` plus the sha256 of the raw body; on any | ||
| * violation returns `{ ok: false }` so the caller falls back to the baked-in | ||
| * tree. Never throws. | ||
| */ | ||
| export declare const validateFetchedToolsList: (rawBody: string) => TrustResult; |
| // Trust boundary for runtime-fetched `tools/list` bodies (spec 051 S5.5). The | ||
| // runtime path turns a remote server's JSON into executable command | ||
| // definitions, so every fetched body is validated here before it can reach the | ||
| // pure `generateRouteMap`. Validation is INTERPRETED (a hand-rolled walker, no | ||
| // `Function`/`eval`/dynamic codegen; rule 1) and FAILS CLOSED (any violation is | ||
| // returned as a failure so the caller keeps the trusted baked-in tree; rule 6). | ||
| // | ||
| // The meta-schema (rule 2), the size/depth caps (rule 3), and the | ||
| // no-executable-content checks (rule 4) are enforced with the named constants | ||
| // below, exactly as the spec pins them. | ||
| import { Result } from "better-result"; | ||
| import { createHash } from "node:crypto"; | ||
| // --- Size / depth caps (spec S5.5 rule 3), named constants, not literals. --- | ||
| /** Reject a whole fetched body larger than this (bytes). */ | ||
| export const MAX_LISTING_BYTES = 1024 * 1024; // 1 MiB | ||
| /** Reject a body advertising more tools than this. */ | ||
| export const MAX_TOOLS = 200; | ||
| // Depth/enum caps bound recursion and abuse; they must clear the first-party | ||
| // registry with headroom (the `registry snapshot validates` test in | ||
| // registry-trust.test.ts fails closed if a shipped schema outgrows either cap). | ||
| // The deepest baked-in schema is `save_template` (depth 7); the largest enum is | ||
| // `set_practice_jurisdictions` (250). Both were raised from their spec S5.5 | ||
| // starting values (depth 6, enum 200) once the real registry exceeded them. | ||
| /** Reject an `inputSchema` nested deeper than this (also catches `$ref` cycles). */ | ||
| export const MAX_SCHEMA_DEPTH = 8; | ||
| /** Reject a single tool whose serialized `inputSchema` exceeds this (bytes). */ | ||
| export const MAX_TOOL_SCHEMA_BYTES = 64 * 1024; // 64 KiB | ||
| /** Reject an `enum` with more members than this. */ | ||
| export const MAX_ENUM = 300; | ||
| /** Reject a `properties` object with more keys than this. */ | ||
| export const MAX_PROPS = 100; | ||
| /** Tool names must match this (spec S5.5 rule 2). */ | ||
| export const TOOL_NAME_PATTERN = /^[a-z][a-z0-9_]{0,63}$/u; | ||
| /** The only annotation hints a fetched listing may carry (spec S5.5 rule 2). */ | ||
| const ALLOWED_ANNOTATION_KEYS = new Set([ | ||
| "readOnlyHint", | ||
| "destructiveHint", | ||
| ]); | ||
| const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value); | ||
| // A guard that narrows to `readonly unknown[]` (not `any[]`, which `Array.isArray` | ||
| // would introduce), keeping the walker fully typed. | ||
| const isUnknownArray = (value) => Array.isArray(value); | ||
| /** Pull the `tools` array from a tools/list body (bare, `{tools}`, or envelope). */ | ||
| const extractTools = (parsed) => { | ||
| if (isUnknownArray(parsed)) { | ||
| return parsed; | ||
| } | ||
| if (isRecord(parsed) && isUnknownArray(parsed["tools"])) { | ||
| return parsed["tools"]; | ||
| } | ||
| const result = isRecord(parsed) ? parsed["result"] : undefined; | ||
| if (isRecord(result) && isUnknownArray(result["tools"])) { | ||
| return result["tools"]; | ||
| } | ||
| return undefined; | ||
| }; | ||
| /** | ||
| * Walk one `inputSchema` subtree enforcing the depth/enum/props caps and the | ||
| * no-remote-`$ref` rule. Interpreted recursion with an explicit depth counter; | ||
| * the depth cap bounds resolution and catches any `$ref` cycle (rule 4). | ||
| * Returns a violation string, or `undefined` when the subtree is within bounds. | ||
| */ | ||
| const walkSchema = (schema, depth) => { | ||
| if (depth > MAX_SCHEMA_DEPTH) { | ||
| return `schema nested deeper than ${MAX_SCHEMA_DEPTH}`; | ||
| } | ||
| if (!isRecord(schema)) { | ||
| return undefined; | ||
| } | ||
| const ref = schema["$ref"]; | ||
| if (ref !== undefined && (typeof ref !== "string" || !ref.startsWith("#/"))) { | ||
| return "only local #/... $ref is allowed"; | ||
| } | ||
| const enumValues = schema["enum"]; | ||
| if (Array.isArray(enumValues) && enumValues.length > MAX_ENUM) { | ||
| return `enum larger than ${MAX_ENUM}`; | ||
| } | ||
| const properties = schema["properties"]; | ||
| if (isRecord(properties)) { | ||
| if (Object.keys(properties).length > MAX_PROPS) { | ||
| return `properties object larger than ${MAX_PROPS}`; | ||
| } | ||
| for (const child of Object.values(properties)) { | ||
| const violation = walkSchema(child, depth + 1); | ||
| if (violation !== undefined) { | ||
| return violation; | ||
| } | ||
| } | ||
| } | ||
| const items = schema["items"]; | ||
| if (Array.isArray(items)) { | ||
| for (const item of items) { | ||
| const violation = walkSchema(item, depth + 1); | ||
| if (violation !== undefined) { | ||
| return violation; | ||
| } | ||
| } | ||
| } | ||
| else if (isRecord(items)) { | ||
| const violation = walkSchema(items, depth + 1); | ||
| if (violation !== undefined) { | ||
| return violation; | ||
| } | ||
| } | ||
| const additional = schema["additionalProperties"]; | ||
| if (isRecord(additional)) { | ||
| return walkSchema(additional, depth + 1); | ||
| } | ||
| return undefined; | ||
| }; | ||
| /** Validate the `annotations` field to the two known boolean hints (rule 2). */ | ||
| const annotationsViolation = (annotations) => { | ||
| if (annotations === undefined) { | ||
| return undefined; | ||
| } | ||
| if (!isRecord(annotations)) { | ||
| return "annotations must be an object"; | ||
| } | ||
| for (const [key, value] of Object.entries(annotations)) { | ||
| if (!ALLOWED_ANNOTATION_KEYS.has(key)) { | ||
| return `annotations has an unknown key '${key}'`; | ||
| } | ||
| if (typeof value !== "boolean") { | ||
| return `annotations.${key} must be a boolean`; | ||
| } | ||
| } | ||
| return undefined; | ||
| }; | ||
| /** Project a validated entry to `RegistryToolListing`, keeping only wire fields. */ | ||
| const projectListing = (entry, name, description, inputSchema) => { | ||
| const rawAnnotations = entry["annotations"]; | ||
| if (!isRecord(rawAnnotations)) { | ||
| return { name, description, inputSchema }; | ||
| } | ||
| const annotations = {}; | ||
| if (typeof rawAnnotations["readOnlyHint"] === "boolean") { | ||
| annotations.readOnlyHint = rawAnnotations["readOnlyHint"]; | ||
| } | ||
| if (typeof rawAnnotations["destructiveHint"] === "boolean") { | ||
| annotations.destructiveHint = rawAnnotations["destructiveHint"]; | ||
| } | ||
| return { name, description, inputSchema, annotations }; | ||
| }; | ||
| /** Validate one entry against the meta-schema + per-tool caps (rules 2, 3, 4). */ | ||
| const validateEntry = (entry) => { | ||
| if (!isRecord(entry)) { | ||
| return { ok: false, violation: "tool entry is not an object" }; | ||
| } | ||
| const name = entry["name"]; | ||
| if (typeof name !== "string" || !TOOL_NAME_PATTERN.test(name)) { | ||
| return { ok: false, violation: `tool name is invalid: ${String(name)}` }; | ||
| } | ||
| const description = entry["description"]; | ||
| if (typeof description !== "string") { | ||
| return { | ||
| ok: false, | ||
| violation: `tool ${name} description must be a string`, | ||
| }; | ||
| } | ||
| const inputSchema = entry["inputSchema"]; | ||
| if (!isRecord(inputSchema)) { | ||
| return { | ||
| ok: false, | ||
| violation: `tool ${name} inputSchema must be an object`, | ||
| }; | ||
| } | ||
| if (inputSchema["type"] !== "object") { | ||
| return { | ||
| ok: false, | ||
| violation: `tool ${name} inputSchema.type must be "object"`, | ||
| }; | ||
| } | ||
| if (!isRecord(inputSchema["properties"])) { | ||
| return { | ||
| ok: false, | ||
| violation: `tool ${name} inputSchema.properties must be an object`, | ||
| }; | ||
| } | ||
| const schemaBytes = Buffer.byteLength(JSON.stringify(inputSchema)); | ||
| if (schemaBytes > MAX_TOOL_SCHEMA_BYTES) { | ||
| return { | ||
| ok: false, | ||
| violation: `tool ${name} inputSchema larger than ${MAX_TOOL_SCHEMA_BYTES} bytes`, | ||
| }; | ||
| } | ||
| const annotationViolation = annotationsViolation(entry["annotations"]); | ||
| if (annotationViolation !== undefined) { | ||
| return { ok: false, violation: `tool ${name}: ${annotationViolation}` }; | ||
| } | ||
| const schemaViolation = walkSchema(inputSchema, 1); | ||
| if (schemaViolation !== undefined) { | ||
| return { ok: false, violation: `tool ${name}: ${schemaViolation}` }; | ||
| } | ||
| return { | ||
| ok: true, | ||
| listing: projectListing(entry, name, description, inputSchema), | ||
| }; | ||
| }; | ||
| /** | ||
| * Validate a raw fetched `tools/list` body (spec S5.5). On success returns the | ||
| * projected `RegistryToolListing[]` plus the sha256 of the raw body; on any | ||
| * violation returns `{ ok: false }` so the caller falls back to the baked-in | ||
| * tree. Never throws. | ||
| */ | ||
| export const validateFetchedToolsList = (rawBody) => { | ||
| if (Buffer.byteLength(rawBody) > MAX_LISTING_BYTES) { | ||
| return { | ||
| ok: false, | ||
| violation: `body larger than ${MAX_LISTING_BYTES} bytes`, | ||
| }; | ||
| } | ||
| const parsed = Result.try(() => JSON.parse(rawBody)); | ||
| if (Result.isError(parsed)) { | ||
| return { ok: false, violation: "body is not valid JSON" }; | ||
| } | ||
| const tools = extractTools(parsed.value); | ||
| if (tools === undefined) { | ||
| return { ok: false, violation: "body has no tools array" }; | ||
| } | ||
| if (tools.length > MAX_TOOLS) { | ||
| return { ok: false, violation: `more than ${MAX_TOOLS} tools` }; | ||
| } | ||
| const listings = []; | ||
| for (const entry of tools) { | ||
| const validated = validateEntry(entry); | ||
| if (!validated.ok) { | ||
| return { ok: false, violation: validated.violation }; | ||
| } | ||
| listings.push(validated.listing); | ||
| } | ||
| const toolsListHash = createHash("sha256").update(rawBody).digest("hex"); | ||
| return { ok: true, listings, toolsListHash }; | ||
| }; | ||
| //# sourceMappingURL=registry-trust.js.map |
| {"version":3,"file":"registry-trust.js","sourceRoot":"","sources":["../src/registry-trust.ts"],"names":[],"mappings":"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"} |
| /** One resource as returned by `resources/list` (the wire fields the CLI uses). */ | ||
| export type ResourceListing = { | ||
| uri: string; | ||
| name: string; | ||
| title?: string; | ||
| description?: string; | ||
| mimeType?: string; | ||
| }; | ||
| /** | ||
| * A generated resource leaf: either the `list` enumerator or a per-resource | ||
| * `show` reader carrying the fixed URI it dispatches `resources/read` with. | ||
| */ | ||
| export type ResourceLeafSpec = { | ||
| kind: "list"; | ||
| commandPath: readonly string[]; | ||
| } | { | ||
| kind: "show"; | ||
| commandPath: readonly string[]; | ||
| name: string; | ||
| uri: string; | ||
| }; | ||
| /** stricli assembly for the resource tree, mirroring the tool `RouteNode`. */ | ||
| export type ResourceNode = { | ||
| kind: "leaf"; | ||
| spec: ResourceLeafSpec; | ||
| } | { | ||
| kind: "route"; | ||
| children: Record<string, ResourceNode>; | ||
| }; |
| // Data shapes for the MCP resources -> stricli route-map generator (spec 051 | ||
| // S5.4). Resources are a small parallel tree to the tool tree: `resources/list` | ||
| // projects to `reference list`, and each resource projects to a | ||
| // `reference show <name>` leaf that reads it via `resources/read`. Types only. | ||
| export {}; | ||
| //# sourceMappingURL=resource-types.js.map |
| {"version":3,"file":"resource-types.js","sourceRoot":"","sources":["../src/resource-types.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,gFAAgF;AAChF,gEAAgE;AAChE,+EAA+E"} |
| /** A JSON Schema fragment, as emitted by the MCP tool registry's prop builders. */ | ||
| export type JsonSchema = Record<string, unknown>; | ||
| /** The MCP scope strings a tool annotation can require (client-side precheck only). */ | ||
| export type ToolScope = "read" | "matters_write" | "documents_write" | "knowledge_write" | "search" | "onboarding" | "templates" | "billing_write" | "admin_read" | "admin_write"; | ||
| /** Wire fields from `tools/list` (build-time: projected from `DEFAULT_MCP_TOOL_DEFINITIONS`). */ | ||
| export type RegistryToolListing = { | ||
| name: string; | ||
| description: string; | ||
| inputSchema: JsonSchema; | ||
| annotations?: { | ||
| readOnlyHint?: boolean; | ||
| destructiveHint?: boolean; | ||
| }; | ||
| }; | ||
| /** One required-enum subcommand produced by a discriminator split (spec S2). */ | ||
| export type DiscriminatorSubcommand = { | ||
| command: string; | ||
| destructive?: true; | ||
| include?: readonly string[]; | ||
| required?: readonly string[]; | ||
| }; | ||
| /** Baked-in per-tool annotation (spec S1), keyed by tool name and merged with the listing. */ | ||
| export type ToolAnnotation = { | ||
| command: readonly string[]; | ||
| excluded?: true; | ||
| scope?: ToolScope; | ||
| itemsKey?: string; | ||
| singleReadWhen?: string; | ||
| columns?: readonly string[]; | ||
| windowedText?: true; | ||
| paginationless?: true; | ||
| inputOnly?: readonly string[]; | ||
| discriminator?: { | ||
| prop: string; | ||
| subcommands: Record<string, DiscriminatorSubcommand>; | ||
| }; | ||
| flagRename?: Record<string, string>; | ||
| }; | ||
| /** One generated CLI flag, derived from an `inputSchema` prop (spec S3). */ | ||
| export type FlagSpec = { | ||
| flag: string; | ||
| prop: string; | ||
| kind: "string" | "int" | "number" | "boolean" | "enum" | "nullable-string" | "string-array" | "int-array" | "enum-array"; | ||
| required: boolean; | ||
| enum?: readonly string[]; | ||
| min?: number; | ||
| max?: number; | ||
| repeatable: boolean; | ||
| default?: unknown; | ||
| }; | ||
| /** The generator's per-leaf output before handing to stricli's `buildCommand`. */ | ||
| export type LeafCommandSpec = { | ||
| commandPath: readonly string[]; | ||
| toolName: string; | ||
| discriminatorInject?: Record<string, string>; | ||
| flags: readonly FlagSpec[]; | ||
| inputOnly: readonly string[]; | ||
| paginated: boolean; | ||
| windowedText: boolean; | ||
| itemsKey?: string; | ||
| destructive: boolean; | ||
| scope?: ToolScope; | ||
| inputSchema: JsonSchema; | ||
| }; | ||
| /** stricli assembly: `LeafCommandSpec[]` folds into a nested route tree. */ | ||
| export type RouteNode = { | ||
| kind: "leaf"; | ||
| spec: LeafCommandSpec; | ||
| } | { | ||
| kind: "route"; | ||
| children: Record<string, RouteNode>; | ||
| }; |
| // Data shapes for the JSON-Schema -> stricli route-map generator. | ||
| // | ||
| // This module is types only (spec 051 S5.1). The generator itself | ||
| // (`generateRouteMap`), the annotation table (S1), and every domain command | ||
| // are out of scope for this phase; see `src/generated/route-map.ts` for the | ||
| // placeholder the real generator will replace. | ||
| export {}; | ||
| //# sourceMappingURL=route-types.js.map |
| {"version":3,"file":"route-types.js","sourceRoot":"","sources":["../src/route-types.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,EAAE;AACF,kEAAkE;AAClE,4EAA4E;AAC5E,4EAA4E;AAC5E,+CAA+C"} |
| import type { Context } from "./context.js"; | ||
| import { type OutputFormat, type Writers } from "./output.js"; | ||
| import type { FlagSpec, LeafCommandSpec } from "./route-types.js"; | ||
| /** stricli flag record key for a FlagSpec: snake/dot path -> camelCase identifier. */ | ||
| export declare const flagKey: (spec: Pick<FlagSpec, "prop">) => string; | ||
| /** Reserved global flag keys present on generated commands (spec S1/S3). */ | ||
| export declare const RESERVED_FLAG_KEYS: { | ||
| readonly input: "input"; | ||
| readonly output: "output"; | ||
| readonly json: "json"; | ||
| readonly table: "table"; | ||
| readonly cursor: "cursor"; | ||
| readonly limit: "limit"; | ||
| readonly all: "all"; | ||
| readonly yes: "yes"; | ||
| }; | ||
| type LeafFlags = Record<string, unknown>; | ||
| /** Bind a command's `Context` streams to the output layer's `Writers`. */ | ||
| export declare const writersFor: (context: Context) => Writers; | ||
| type ArgsResult = { | ||
| ok: true; | ||
| args: Record<string, unknown>; | ||
| } | { | ||
| ok: false; | ||
| message: string; | ||
| }; | ||
| /** Build the tool-args object from parsed value flags (spec S3). Exported for tests. */ | ||
| export declare const buildArgsFromFlags: (spec: LeafCommandSpec, flags: LeafFlags) => Promise<ArgsResult>; | ||
| /** Resolve the effective `OutputFormat` from the reserved output flags + TTY. */ | ||
| export declare const readOutputFormat: (flags: LeafFlags, context: Context) => OutputFormat; | ||
| /** Run one leaf command end to end. Sets `process.exitCode` per spec S4. */ | ||
| export declare const runLeafCommand: ({ context, flags, spec, }: { | ||
| context: Context; | ||
| flags: LeafFlags; | ||
| spec: LeafCommandSpec; | ||
| }) => Promise<void>; | ||
| export {}; |
| // The generic executor every generated leaf command dispatches through (spec 051 | ||
| // S3/S4). It builds the tool-args object from parsed flags (or the `--input` | ||
| // escape hatch), runs the client-side scope precheck, confirms destructive ops, | ||
| // calls the MCP endpoint (following cursors under `--all`, bounded by the | ||
| // ceilings), and renders the result. Exit codes are set on `process.exitCode` | ||
| // directly so stricli's `??=` never overrides them. | ||
| import { Result } from "better-result"; | ||
| import { readFile } from "node:fs/promises"; | ||
| import { createInterface } from "node:readline/promises"; | ||
| import { text as readStreamText } from "node:stream/consumers"; | ||
| import { decodeAccessTokenClaims } from "./auth/jwt.js"; | ||
| import { validateAgainstSchema } from "./json-schema-validate.js"; | ||
| import { callTool, } from "./mcp-client.js"; | ||
| import { EXIT_CODES, FEATURE_DISABLED_ERROR_CODES, MAX_ALL_BYTES, MAX_ALL_ITEMS, MAX_ALL_PAGES, } from "./mcp-constants.js"; | ||
| import { buildRenderPlan, renderResult, selectFormat, } from "./output.js"; | ||
| /** stricli flag record key for a FlagSpec: snake/dot path -> camelCase identifier. */ | ||
| export const flagKey = (spec) => spec.prop.replace(/[._](?<char>[a-z0-9])/gu, (_match, char) => char.toUpperCase()); | ||
| /** Reserved global flag keys present on generated commands (spec S1/S3). */ | ||
| export const RESERVED_FLAG_KEYS = { | ||
| input: "input", | ||
| output: "output", | ||
| json: "json", | ||
| table: "table", | ||
| cursor: "cursor", | ||
| limit: "limit", | ||
| all: "all", | ||
| yes: "yes", | ||
| }; | ||
| const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value); | ||
| const stringField = (value, key) => { | ||
| if (!isRecord(value)) { | ||
| return null; | ||
| } | ||
| const field = value[key]; | ||
| return typeof field === "string" ? field : null; | ||
| }; | ||
| const arrayField = (value, key) => { | ||
| if (!isRecord(value)) { | ||
| return []; | ||
| } | ||
| const field = value[key]; | ||
| return Array.isArray(field) ? field : []; | ||
| }; | ||
| /** Bind a command's `Context` streams to the output layer's `Writers`. */ | ||
| export const writersFor = (context) => ({ | ||
| stdout: (text) => { | ||
| context.process.stdout.write(text); | ||
| }, | ||
| stderr: (text) => { | ||
| context.process.stderr.write(text); | ||
| }, | ||
| }); | ||
| const setExit = (context, code) => { | ||
| context.process.exitCode = code; | ||
| }; | ||
| // Read all of stdin to a string (the `@-` / `--input -` escape hatch). Consumes | ||
| // `process.stdin` to EOF so the published CLI runs under plain Node. | ||
| const readAllStdin = async () => await readStreamText(process.stdin); | ||
| /** Apply gh-style `@file`/`@-`/`@@` sugar to a string flag value (spec S3). */ | ||
| const resolveStringValue = async (raw) => { | ||
| if (raw.startsWith("@@")) { | ||
| return Result.ok(raw.slice(1)); | ||
| } | ||
| if (raw === "@-") { | ||
| return Result.ok((await readAllStdin()).replace(/\n$/u, "")); | ||
| } | ||
| if (raw.startsWith("@")) { | ||
| const path = raw.slice(1); | ||
| const read = await Result.tryPromise({ | ||
| try: async () => await readFile(path, "utf-8"), | ||
| catch: (cause) => cause, | ||
| }); | ||
| if (Result.isError(read)) { | ||
| return Result.err(`could not read file ${path}`); | ||
| } | ||
| return Result.ok(read.value); | ||
| } | ||
| return Result.ok(raw); | ||
| }; | ||
| const setPath = (target, path, value) => { | ||
| const segments = path.split("."); | ||
| let node = target; | ||
| for (let index = 0; index < segments.length - 1; index += 1) { | ||
| const segment = segments[index] ?? ""; | ||
| const next = node[segment]; | ||
| if (isRecord(next)) { | ||
| node = next; | ||
| } | ||
| else { | ||
| const created = {}; | ||
| node[segment] = created; | ||
| node = created; | ||
| } | ||
| } | ||
| node[segments.at(-1) ?? path] = value; | ||
| }; | ||
| const parseBoundedInt = (spec, raw) => { | ||
| if (!/^-?\d+$/u.test(raw.trim())) { | ||
| return Result.err(`${spec.flag} expects an integer`); | ||
| } | ||
| const value = Number.parseInt(raw.trim(), 10); | ||
| if (spec.min !== undefined && value < spec.min) { | ||
| return Result.err(`${spec.flag} must be >= ${spec.min}`); | ||
| } | ||
| if (spec.max !== undefined && value > spec.max) { | ||
| return Result.err(`${spec.flag} must be <= ${spec.max}`); | ||
| } | ||
| return Result.ok(value); | ||
| }; | ||
| const parseBoundedNumber = (spec, raw) => { | ||
| const value = Number(raw.trim()); | ||
| if (!Number.isFinite(value)) { | ||
| return Result.err(`${spec.flag} expects a number`); | ||
| } | ||
| if (spec.min !== undefined && value < spec.min) { | ||
| return Result.err(`${spec.flag} must be >= ${spec.min}`); | ||
| } | ||
| if (spec.max !== undefined && value > spec.max) { | ||
| return Result.err(`${spec.flag} must be <= ${spec.max}`); | ||
| } | ||
| return Result.ok(value); | ||
| }; | ||
| /** stricli gives string values for scalar flags; guard against anything else. */ | ||
| const asFlagString = (value) => typeof value === "string" ? value : null; | ||
| const coerceArrayFlag = (flagSpec, value) => { | ||
| const raw = []; | ||
| for (const element of Array.isArray(value) ? value : []) { | ||
| const asString = asFlagString(element); | ||
| if (asString === null) { | ||
| return Result.err(`${flagSpec.flag} values must be strings`); | ||
| } | ||
| raw.push(asString); | ||
| } | ||
| if (flagSpec.kind === "string-array") { | ||
| return Result.ok(raw); | ||
| } | ||
| if (flagSpec.kind === "enum-array") { | ||
| for (const element of raw) { | ||
| if (flagSpec.enum && !flagSpec.enum.includes(element)) { | ||
| return Result.err(`${flagSpec.flag} values must each be one of ${flagSpec.enum.join(", ")}`); | ||
| } | ||
| } | ||
| return Result.ok(raw); | ||
| } | ||
| const ints = []; | ||
| for (const element of raw) { | ||
| const parsed = parseBoundedInt(flagSpec, element); | ||
| if (Result.isError(parsed)) { | ||
| return parsed; | ||
| } | ||
| ints.push(parsed.value); | ||
| } | ||
| return Result.ok(ints); | ||
| }; | ||
| /** Coerce one parsed flag value to its JSON tool-arg value (spec S3). */ | ||
| const coerceFlagValue = async (flagSpec, value) => { | ||
| if (flagSpec.kind === "boolean") { | ||
| return Result.ok(value === true); | ||
| } | ||
| if (flagSpec.kind === "string-array" || | ||
| flagSpec.kind === "enum-array" || | ||
| flagSpec.kind === "int-array") { | ||
| return coerceArrayFlag(flagSpec, value); | ||
| } | ||
| const raw = asFlagString(value); | ||
| if (raw === null) { | ||
| return Result.err(`${flagSpec.flag} expects a value`); | ||
| } | ||
| if (flagSpec.kind === "nullable-string") { | ||
| if (raw === "null") { | ||
| return Result.ok(null); | ||
| } | ||
| const resolved = await resolveStringValue(raw); | ||
| return resolved; | ||
| } | ||
| if (flagSpec.kind === "string") { | ||
| const resolved = await resolveStringValue(raw); | ||
| return resolved; | ||
| } | ||
| if (flagSpec.kind === "int") { | ||
| return parseBoundedInt(flagSpec, raw); | ||
| } | ||
| if (flagSpec.kind === "number") { | ||
| return parseBoundedNumber(flagSpec, raw); | ||
| } | ||
| // enum | ||
| if (flagSpec.enum && !flagSpec.enum.includes(raw)) { | ||
| return Result.err(`${flagSpec.flag} must be one of ${flagSpec.enum.join(", ")}`); | ||
| } | ||
| return Result.ok(raw); | ||
| }; | ||
| /** Build the tool-args object from parsed value flags (spec S3). Exported for tests. */ | ||
| export const buildArgsFromFlags = async (spec, flags) => { | ||
| const args = {}; | ||
| for (const flagSpec of spec.flags) { | ||
| const value = flags[flagKey(flagSpec)]; | ||
| if (value === undefined) { | ||
| continue; | ||
| } | ||
| // eslint-disable-next-line no-await-in-loop -- @file/@- reads must stay sequential | ||
| const coerced = await coerceFlagValue(flagSpec, value); | ||
| if (Result.isError(coerced)) { | ||
| return { ok: false, message: coerced.error }; | ||
| } | ||
| setPath(args, flagSpec.prop, coerced.value); | ||
| } | ||
| // Enforce required flags (spec S3): missing -> usage error (exit 2 upstream). | ||
| for (const flagSpec of spec.flags) { | ||
| if (flagSpec.required && flags[flagKey(flagSpec)] === undefined) { | ||
| return { ok: false, message: `missing required flag ${flagSpec.flag}` }; | ||
| } | ||
| } | ||
| return { ok: true, args }; | ||
| }; | ||
| const buildArgsFromInput = async ({ inputRaw, spec, writers, }) => { | ||
| let jsonText; | ||
| if (inputRaw === "-") { | ||
| jsonText = await readAllStdin(); | ||
| } | ||
| else if (inputRaw.startsWith("@")) { | ||
| const read = await Result.tryPromise({ | ||
| try: async () => await readFile(inputRaw.slice(1), "utf-8"), | ||
| catch: (cause) => cause, | ||
| }); | ||
| if (Result.isError(read)) { | ||
| writers.stderr(`--input could not read file ${inputRaw.slice(1)}\n`); | ||
| return undefined; | ||
| } | ||
| jsonText = read.value; | ||
| } | ||
| else { | ||
| jsonText = inputRaw; | ||
| } | ||
| const parsed = Result.try(() => JSON.parse(jsonText)); | ||
| if (Result.isError(parsed)) { | ||
| writers.stderr("--input is not valid JSON.\n"); | ||
| return undefined; | ||
| } | ||
| if (!isRecord(parsed.value)) { | ||
| writers.stderr("--input must be a JSON object.\n"); | ||
| return undefined; | ||
| } | ||
| const validation = validateAgainstSchema(spec.inputSchema, parsed.value); | ||
| if (!validation.valid) { | ||
| writers.stderr(`--input invalid at ${validation.path}: ${validation.message}\n`); | ||
| return undefined; | ||
| } | ||
| return parsed.value; | ||
| }; | ||
| const scopeGranted = ({ token, scope, }) => { | ||
| const claims = decodeAccessTokenClaims(token); | ||
| if (claims?.scope === undefined) { | ||
| // Opaque token or no scope claim: cannot verify locally, let the server rule. | ||
| return true; | ||
| } | ||
| return claims.scope.split(/\s+/u).includes(`stella:${scope}`); | ||
| }; | ||
| const confirmDestructive = async ({ context, flags, writers, label, }) => { | ||
| if (flags[RESERVED_FLAG_KEYS.yes] === true) { | ||
| return "proceed"; | ||
| } | ||
| if (!context.process.stdin.isTTY) { | ||
| writers.stderr("refusing destructive op without --yes on non-TTY\n"); | ||
| return "aborted"; | ||
| } | ||
| // A TTY confirmation must read a single line: `readAllStdin` waits for EOF, | ||
| // so `y`+Enter would never complete the prompt on a terminal. | ||
| const rl = createInterface({ | ||
| input: context.process.stdin, | ||
| output: context.process.stdout, | ||
| }); | ||
| const rawAnswer = await rl.question(`Run destructive command '${label}'? [y/N] `); | ||
| rl.close(); | ||
| const answer = rawAnswer.trim().toLowerCase(); | ||
| return answer === "y" || answer === "yes" ? "proceed" : "aborted"; | ||
| }; | ||
| const mapClientErrorExit = (error) => { | ||
| if (error.kind === "http") { | ||
| if (error.httpStatus === 401) { | ||
| return EXIT_CODES.auth; | ||
| } | ||
| if (error.httpStatus === 404) { | ||
| return EXIT_CODES.notFound; | ||
| } | ||
| return EXIT_CODES.server; | ||
| } | ||
| if (error.kind === "rpc") { | ||
| if (error.rpcCode === -32_602) { | ||
| return EXIT_CODES.validation; | ||
| } | ||
| if (error.rpcCode === -32_601) { | ||
| return EXIT_CODES.notFound; | ||
| } | ||
| return EXIT_CODES.server; | ||
| } | ||
| return EXIT_CODES.server; | ||
| }; | ||
| const parsePayload = (result) => { | ||
| const text = result.content.at(0)?.text ?? ""; | ||
| const parsed = Result.try(() => JSON.parse(text)); | ||
| return Result.isOk(parsed) ? parsed.value : undefined; | ||
| }; | ||
| /** | ||
| * Map a tool `isError` result to an exit class (spec 051 S4). A feature-disabled | ||
| * failure is exit 5 only when the server tags the error payload with a known | ||
| * machine code; a plain-text error (today's server) has no code and falls to | ||
| * exit 4. Text is never pattern-matched (it is locale-dependent server output). | ||
| */ | ||
| const classifyToolError = (payload) => { | ||
| if (!isRecord(payload)) { | ||
| return EXIT_CODES.server; | ||
| } | ||
| const code = stringField(payload, "code") ?? stringField(payload["error"], "code"); | ||
| if (code !== null && FEATURE_DISABLED_ERROR_CODES.has(code)) { | ||
| return EXIT_CODES.featureDisabled; | ||
| } | ||
| return EXIT_CODES.server; | ||
| }; | ||
| /** Resolve the effective `OutputFormat` from the reserved output flags + TTY. */ | ||
| export const readOutputFormat = (flags, context) => { | ||
| const output = flags[RESERVED_FLAG_KEYS.output]; | ||
| return selectFormat({ | ||
| flags: { | ||
| output: output === "json" || output === "table" ? output : undefined, | ||
| json: flags[RESERVED_FLAG_KEYS.json] === true, | ||
| table: flags[RESERVED_FLAG_KEYS.table] === true, | ||
| }, | ||
| isTTY: context.process.stdout.isTTY, | ||
| }); | ||
| }; | ||
| /** Follow `nextCursor` under `--all`, concatenating items/text within ceilings. */ | ||
| const followAll = async ({ spec, baseArgs, serverUrl, token, }) => { | ||
| const items = []; | ||
| let text = ""; | ||
| let firstPayload = {}; | ||
| let cursor = null; | ||
| let pages = 0; | ||
| let bytes = 0; | ||
| let truncated = false; | ||
| do { | ||
| const args = { ...baseArgs, ...(cursor === null ? {} : { cursor }) }; | ||
| // eslint-disable-next-line no-await-in-loop -- each page's cursor comes from the previous response | ||
| const call = await callTool({ | ||
| serverUrl, | ||
| token, | ||
| name: spec.toolName, | ||
| args, | ||
| }); | ||
| if (Result.isError(call)) { | ||
| return call; | ||
| } | ||
| const payload = parsePayload(call.value); | ||
| if (pages === 0 && isRecord(payload)) { | ||
| firstPayload = payload; | ||
| } | ||
| pages += 1; | ||
| if (spec.windowedText) { | ||
| const chunk = stringField(payload, "text") ?? ""; | ||
| bytes += Buffer.byteLength(chunk); | ||
| text += chunk; | ||
| } | ||
| else if (spec.itemsKey !== undefined) { | ||
| const pageItems = arrayField(payload, spec.itemsKey); | ||
| bytes += Buffer.byteLength(JSON.stringify(pageItems)); | ||
| items.push(...pageItems); | ||
| } | ||
| cursor = stringField(payload, "nextCursor"); | ||
| if (pages >= MAX_ALL_PAGES || | ||
| items.length >= MAX_ALL_ITEMS || | ||
| bytes >= MAX_ALL_BYTES) { | ||
| truncated = cursor !== null; | ||
| break; | ||
| } | ||
| } while (cursor !== null); | ||
| const mergedPayload = spec.windowedText | ||
| ? { text, nextCursor: null } | ||
| : { ...firstPayload, [spec.itemsKey ?? "items"]: items, nextCursor: null }; | ||
| return Result.ok({ | ||
| payload: mergedPayload, | ||
| truncated, | ||
| lastCursor: cursor, | ||
| count: spec.windowedText ? Buffer.byteLength(text) : items.length, | ||
| }); | ||
| }; | ||
| const renderCallResult = ({ context, spec, result, format, writers, }) => { | ||
| if (result.isError) { | ||
| writers.stderr(`${result.content.at(0)?.text ?? "Tool error"}\n`); | ||
| setExit(context, classifyToolError(parsePayload(result))); | ||
| return; | ||
| } | ||
| const payload = parsePayload(result); | ||
| if (payload === undefined) { | ||
| writers.stdout(`${result.content.at(0)?.text ?? ""}\n`); | ||
| return; | ||
| } | ||
| const plan = buildRenderPlan({ | ||
| payload, | ||
| itemsKey: spec.itemsKey, | ||
| windowedText: spec.windowedText, | ||
| singleReadActive: false, | ||
| columns: undefined, | ||
| }); | ||
| renderResult({ plan, format, writers, allActive: false }); | ||
| }; | ||
| /** Run one leaf command end to end. Sets `process.exitCode` per spec S4. */ | ||
| export const runLeafCommand = async ({ context, flags, spec, }) => { | ||
| const writers = writersFor(context); | ||
| const { serverUrl, token } = context; | ||
| if (serverUrl === undefined || token === undefined) { | ||
| writers.stderr("Not signed in. Run 'stella auth login' to authenticate.\n"); | ||
| setExit(context, EXIT_CODES.auth); | ||
| return; | ||
| } | ||
| const inputRaw = flags[RESERVED_FLAG_KEYS.input]; | ||
| let args; | ||
| if (typeof inputRaw === "string") { | ||
| const conflicting = spec.flags.some((flagSpec) => flags[flagKey(flagSpec)] !== undefined); | ||
| if (conflicting) { | ||
| writers.stderr("--input is exclusive with per-tool value flags.\n"); | ||
| setExit(context, EXIT_CODES.validation); | ||
| return; | ||
| } | ||
| const parsed = await buildArgsFromInput({ inputRaw, spec, writers }); | ||
| if (parsed === undefined) { | ||
| setExit(context, EXIT_CODES.validation); | ||
| return; | ||
| } | ||
| args = parsed; | ||
| } | ||
| else { | ||
| const built = await buildArgsFromFlags(spec, flags); | ||
| if (!built.ok) { | ||
| writers.stderr(`${built.message}\n`); | ||
| setExit(context, EXIT_CODES.validation); | ||
| return; | ||
| } | ||
| args = built.args; | ||
| } | ||
| if (spec.discriminatorInject !== undefined) { | ||
| args = { ...args, ...spec.discriminatorInject }; | ||
| } | ||
| // Client-side scope precheck (spec S3): fail before any server call. | ||
| if (spec.scope !== undefined && !scopeGranted({ token, scope: spec.scope })) { | ||
| writers.stderr(`Missing scope stella:${spec.scope}. Re-run 'stella auth login' to grant stella:${spec.scope}.\n`); | ||
| setExit(context, EXIT_CODES.auth); | ||
| return; | ||
| } | ||
| if (spec.destructive) { | ||
| const outcome = await confirmDestructive({ | ||
| context, | ||
| flags, | ||
| writers, | ||
| label: spec.commandPath.join(" "), | ||
| }); | ||
| if (outcome === "aborted") { | ||
| setExit(context, EXIT_CODES.aborted); | ||
| return; | ||
| } | ||
| } | ||
| // Windowed-text commands print raw document text by default; only an explicit | ||
| // --json / --output json switches them to a structured envelope (spec S4). | ||
| const explicitJson = flags[RESERVED_FLAG_KEYS.json] === true || | ||
| flags[RESERVED_FLAG_KEYS.output] === "json"; | ||
| const format = spec.windowedText && !explicitJson | ||
| ? "table" | ||
| : readOutputFormat(flags, context); | ||
| const allActive = spec.paginated && flags[RESERVED_FLAG_KEYS.all] === true; | ||
| // Reserved pagination flags map onto the tool's cursor/limit args (spec S3). | ||
| const cursorFlag = flags[RESERVED_FLAG_KEYS.cursor]; | ||
| const limitFlag = flags[RESERVED_FLAG_KEYS.limit]; | ||
| if (!allActive && typeof cursorFlag === "string") { | ||
| args["cursor"] = cursorFlag; | ||
| } | ||
| if (typeof limitFlag === "string" && /^-?\d+$/u.test(limitFlag.trim())) { | ||
| args["limit"] = Number.parseInt(limitFlag.trim(), 10); | ||
| } | ||
| if (allActive) { | ||
| const outcome = await followAll({ spec, baseArgs: args, serverUrl, token }); | ||
| if (Result.isError(outcome)) { | ||
| writers.stderr(`${outcome.error.message}\n`); | ||
| setExit(context, mapClientErrorExit(outcome.error)); | ||
| return; | ||
| } | ||
| const plan = buildRenderPlan({ | ||
| payload: outcome.value.payload, | ||
| itemsKey: spec.itemsKey, | ||
| windowedText: spec.windowedText, | ||
| singleReadActive: false, | ||
| columns: undefined, | ||
| }); | ||
| renderResult({ plan, format, writers, allActive: true }); | ||
| if (outcome.value.truncated) { | ||
| writers.stderr(`--all truncated at ${outcome.value.count} items/pages; resume with --cursor ${outcome.value.lastCursor}\n`); | ||
| } | ||
| return; | ||
| } | ||
| const call = await callTool({ serverUrl, token, name: spec.toolName, args }); | ||
| if (Result.isError(call)) { | ||
| writers.stderr(`${call.error.message}\n`); | ||
| setExit(context, mapClientErrorExit(call.error)); | ||
| return; | ||
| } | ||
| renderCallResult({ context, spec, result: call.value, format, writers }); | ||
| }; | ||
| //# sourceMappingURL=run-leaf-command.js.map |
| {"version":3,"file":"run-leaf-command.js","sourceRoot":"","sources":["../src/run-leaf-command.ts"],"names":[],"mappings":"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"} |
| import type { Context } from "./context.js"; | ||
| import type { ResourceLeafSpec } from "./resource-types.js"; | ||
| type LeafFlags = Record<string, unknown>; | ||
| /** Run one generated `reference` command end to end (spec 051 S5.4). */ | ||
| export declare const runResourceCommand: ({ context, flags, spec, }: { | ||
| context: Context; | ||
| flags: LeafFlags; | ||
| spec: ResourceLeafSpec; | ||
| }) => Promise<void>; | ||
| export {}; |
| // Executor for the generated `reference` resource commands (spec 051 S5.4). | ||
| // `reference list` enumerates `resources/list` as a table; `reference show | ||
| // <name>` reads the resource's fixed URI via `resources/read` and prints | ||
| // `contents[0].text`, honoring `--output`. Resources are public (no scope | ||
| // precheck); an unknown resource (server `resources/read` rejection) is exit 6. | ||
| import { Result } from "better-result"; | ||
| import { listResources, readResource, } from "./mcp-client.js"; | ||
| import { EXIT_CODES } from "./mcp-constants.js"; | ||
| import { renderResult } from "./output.js"; | ||
| import { readOutputFormat, RESERVED_FLAG_KEYS, writersFor, } from "./run-leaf-command.js"; | ||
| const REFERENCE_COLUMNS = ["name", "title", "mimeType"]; | ||
| /** Resources fail only with unknown-URI: any rpc/404 maps to not-found (spec S4). */ | ||
| const mapResourceErrorExit = (error) => { | ||
| if (error.kind === "rpc") { | ||
| return EXIT_CODES.notFound; | ||
| } | ||
| if (error.kind === "http") { | ||
| if (error.httpStatus === 401) { | ||
| return EXIT_CODES.auth; | ||
| } | ||
| if (error.httpStatus === 404) { | ||
| return EXIT_CODES.notFound; | ||
| } | ||
| return EXIT_CODES.server; | ||
| } | ||
| return EXIT_CODES.server; | ||
| }; | ||
| const runList = async ({ context, serverUrl, token, format, writers, }) => { | ||
| const result = await listResources({ serverUrl, token }); | ||
| if (Result.isError(result)) { | ||
| writers.stderr(`${result.error.message}\n`); | ||
| context.process.exitCode = mapResourceErrorExit(result.error); | ||
| return; | ||
| } | ||
| const items = result.value.resources; | ||
| renderResult({ | ||
| plan: { | ||
| kind: "page", | ||
| itemsKey: "resources", | ||
| items, | ||
| payload: { resources: items }, | ||
| nextCursor: null, | ||
| columns: REFERENCE_COLUMNS, | ||
| }, | ||
| format, | ||
| writers, | ||
| allActive: false, | ||
| }); | ||
| }; | ||
| const runShow = async ({ context, spec, serverUrl, token, format, writers, }) => { | ||
| const result = await readResource({ serverUrl, token, uri: spec.uri }); | ||
| if (Result.isError(result)) { | ||
| writers.stderr(`${result.error.message}\n`); | ||
| context.process.exitCode = mapResourceErrorExit(result.error); | ||
| return; | ||
| } | ||
| const text = result.value.contents.at(0)?.text ?? ""; | ||
| renderResult({ | ||
| plan: { kind: "windowed-text", text, nextCursor: null }, | ||
| format, | ||
| writers, | ||
| allActive: false, | ||
| }); | ||
| }; | ||
| /** Run one generated `reference` command end to end (spec 051 S5.4). */ | ||
| export const runResourceCommand = async ({ context, flags, spec, }) => { | ||
| const writers = writersFor(context); | ||
| const { serverUrl, token } = context; | ||
| if (serverUrl === undefined || token === undefined) { | ||
| writers.stderr("Not signed in. Run 'stella auth login' to authenticate.\n"); | ||
| context.process.exitCode = EXIT_CODES.auth; | ||
| return; | ||
| } | ||
| if (spec.kind === "list") { | ||
| await runList({ | ||
| context, | ||
| serverUrl, | ||
| token, | ||
| format: readOutputFormat(flags, context), | ||
| writers, | ||
| }); | ||
| return; | ||
| } | ||
| // `reference show` prints the resource text raw by default (like windowed-text | ||
| // tool output); only an explicit --json/--output json wraps it (spec S5.4). | ||
| const explicitJson = flags[RESERVED_FLAG_KEYS.json] === true || | ||
| flags[RESERVED_FLAG_KEYS.output] === "json"; | ||
| await runShow({ | ||
| context, | ||
| spec, | ||
| serverUrl, | ||
| token, | ||
| format: explicitJson ? "json" : "table", | ||
| writers, | ||
| }); | ||
| }; | ||
| //# sourceMappingURL=run-resource-command.js.map |
| {"version":3,"file":"run-resource-command.js","sourceRoot":"","sources":["../src/run-resource-command.ts"],"names":[],"mappings":"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"} |
+26
| # @stll/cli | ||
| The `stella` command-line client. | ||
| ## Install | ||
| ```sh | ||
| npm i -g @stll/cli | ||
| ``` | ||
| ## Usage | ||
| The command surface (`stella <resource> <action>`) is generated from the | ||
| Stella MCP tool registry, so it mirrors the tools exposed by a Stella server. | ||
| Run `stella --help` to list available commands. | ||
| Authenticate against a Stella server with: | ||
| ```sh | ||
| stella auth login | ||
| ``` | ||
| ## Links | ||
| - Repository: https://github.com/stella/stella/tree/main/packages/cli | ||
| - Issues: https://github.com/stella/stella/issues |
+61
-2
| { | ||
| "name": "@stll/cli", | ||
| "version": "0.0.1-placeholder.0", | ||
| "description": "Placeholder to bootstrap npm trusted publishing. The real package ships from https://github.com/stella/stella (packages/cli)." | ||
| "version": "0.1.0", | ||
| "description": "Stella command-line client", | ||
| "keywords": [ | ||
| "cli", | ||
| "legal", | ||
| "stella" | ||
| ], | ||
| "homepage": "https://github.com/stella/stella/tree/main/packages/cli", | ||
| "bugs": { | ||
| "url": "https://github.com/stella/stella/issues" | ||
| }, | ||
| "license": "Apache-2.0", | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "https://github.com/stella/stella.git", | ||
| "directory": "packages/cli" | ||
| }, | ||
| "bin": { | ||
| "stella": "./dist/cli.js" | ||
| }, | ||
| "files": [ | ||
| "dist", | ||
| "README.md" | ||
| ], | ||
| "type": "module", | ||
| "engines": { | ||
| "node": ">=20" | ||
| }, | ||
| "sideEffects": false, | ||
| "exports": { | ||
| ".": { | ||
| "types": "./dist/cli.d.ts", | ||
| "import": "./dist/cli.js" | ||
| } | ||
| }, | ||
| "publishConfig": { | ||
| "access": "public" | ||
| }, | ||
| "scripts": { | ||
| "clean": "git clean -xdf dist .cache .turbo node_modules", | ||
| "codegen": "cd ../../apps/api && bun scripts/export-mcp-tool-registry.ts && cd ../../packages/cli && bun run src/codegen.ts && oxfmt .", | ||
| "build": "rm -rf dist && tsgo -p tsconfig.build.json && cp src/generated/registry-snapshot.json dist/generated/registry-snapshot.json && printf '%s\\n' '#!/usr/bin/env node' > dist/cli.js.tmp && tail -n +2 dist/cli.js >> dist/cli.js.tmp && mv dist/cli.js.tmp dist/cli.js && chmod +x dist/cli.js", | ||
| "prepack": "bun run build", | ||
| "pack:dry-run": "bun pm pack --dry-run", | ||
| "test": "bun test src", | ||
| "typecheck": "tsgo --noEmit", | ||
| "lint": "cd ../.. && bun --bun oxlint -c oxlint.config.ts --report-unused-disable-directives-severity=error --deny-warnings --type-aware packages/cli", | ||
| "lint:fix": "cd ../.. && bun --bun oxlint -c oxlint.config.ts --type-aware --fix packages/cli", | ||
| "format": "oxfmt ." | ||
| }, | ||
| "dependencies": { | ||
| "@stricli/core": "^1.2.8", | ||
| "better-result": "2.9.2", | ||
| "valibot": "1.4.2" | ||
| }, | ||
| "devDependencies": { | ||
| "@stll/typescript-config": "0.0.0", | ||
| "@types/bun": "1.3.14" | ||
| }, | ||
| "main": "./dist/cli.js", | ||
| "types": "./dist/cli.d.ts" | ||
| } |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Network access
Supply chain riskThis module accesses the network.
Found 2 instances
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 4 instances
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Empty package
Supply chain riskPackage does not contain any code. It may be removed, is name squatting, or the result of a faulty package publish.
No README
QualityPackage does not have a README. This may indicate a failed publish or a low quality package.
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
No License Found
LicenseLicense information could not be found.
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
No website
QualityPackage does not have a website.
670772
322386.54%129
12800%0
-100%10488
Infinity%1
-50%1
-50%0
-100%27
Infinity%Yes
NaN3
Infinity%2
Infinity%11
1000%10
900%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added