@sequelsh/cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +61 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1068 -0
- package/dist/index.js.map +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["config?: AuthConfig | null","config: AuthConfig","isLoggedIn","buf: Buffer","apiUrl: string","params: Record<string, string>","redirectUri: string","accessToken: string","expectedState: string","resolveCode!: (code: string) => void","rejectCode!: (err: Error) => void","title: string","message: string","options?: { silent?: boolean }","next: AuthConfig","entry: TokenEntry","status: number","message: string","path: string","options: RequestOptions","headers: Record<string, string>","body: string | undefined","text","id: string","appId: string","body: Record<string, unknown>","token: string","connectionId: string","tool: string","params: Record<string, unknown>","useCase: string","connectionIds?: string[]","name: string","on: boolean","data: unknown","value: unknown","rows: Array<Record<string, unknown>>","columns?: string[]","message: string","connector: Connector","token: string","source?: string","connector: Connector | undefined","credentials: Record<string, string>","p","s","res","result","idOrShort: string","message: string","c: Connection","idOrShort?: string","config: { schemaFilters: string[] | null; instructions: string | null } | null","apiUrl: string","apiKey: string","opts: InstallOptions","vendor: string","path: string","mutate: (cfg: Record<string, unknown>) => void","cfg: Record<string, unknown>","key: string","value: unknown","mcpClients: McpClientDef[]","slug: string","slugArg?: string","scope: Scope","key: string","useCase: string","opts: { connection?: string[] }","connectionId: string","tool: string","opts: { data?: string }","params: Record<string, unknown>","fn: (...args: A) => Promise<void>","usecase: string","opts: { connection?: string[] }","connectionId: string","tool: string","opts: { data?: string }"],"sources":["../src/lib/config.ts","../src/lib/auth.ts","../src/lib/api.ts","../src/lib/output.ts","../src/commands/login.ts","../src/commands/logout.ts","../src/commands/switch.ts","../src/commands/connect.ts","../src/commands/sources.ts","../src/lib/mcp-clients.ts","../src/commands/install.ts","../src/commands/search.ts","../src/commands/execute.ts","../src/index.ts"],"sourcesContent":["import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { mkdirSync, readFileSync, writeFileSync, rmSync, existsSync, chmodSync } from \"node:fs\";\n\n/** Default production API base. Override with SEQUEL_API_URL for local/dev. */\nexport const DEFAULT_API_URL = \"https://api.sequel.sh\";\n\n/** One OAuth token bundle, scoped to a single organization. */\nexport interface TokenEntry {\n accessToken: string;\n refreshToken: string;\n /** ms epoch when the access token expires. */\n expiresAt: number;\n}\n\nexport interface OrgRef {\n id: string;\n name: string;\n slug: string;\n role: string;\n}\n\nexport interface UserRef {\n id: string;\n email: string;\n name: string;\n}\n\n/**\n * The on-disk shape of ~/.sequel/auth.json.\n *\n * Multi-token cache: one genuine org-bound OAuth token per organization, keyed\n * by org id. `activeOrgId` selects which token requests use right now. Switching\n * orgs is an offline swap when the target org already has a cached token.\n */\nexport interface AuthConfig {\n version: 1;\n apiUrl: string;\n /** Persisted dynamic client registration, reused across logins. */\n clientId?: string;\n activeOrgId?: string;\n tokens: Record<string, TokenEntry>;\n user?: UserRef;\n /** Cached membership list for the `switch` UI. */\n orgs?: OrgRef[];\n}\n\n/** Directory holding the CLI's state. Overridable for tests. */\nexport function configDir(): string {\n return process.env.SEQUEL_CONFIG_DIR || join(homedir(), \".sequel\");\n}\n\nexport function configPath(): string {\n return join(configDir(), \"auth.json\");\n}\n\n/** The API base URL: explicit env wins, then a saved value, then the default. */\nexport function resolveApiUrl(config?: AuthConfig | null): string {\n return process.env.SEQUEL_API_URL || config?.apiUrl || DEFAULT_API_URL;\n}\n\nfunction emptyConfig(): AuthConfig {\n return { version: 1, apiUrl: resolveApiUrl(), tokens: {} };\n}\n\n/** Read auth.json, returning a fresh empty config if missing or corrupt. */\nexport function readConfig(): AuthConfig {\n const path = configPath();\n if (!existsSync(path)) return emptyConfig();\n try {\n const parsed = JSON.parse(readFileSync(path, \"utf8\")) as AuthConfig;\n if (!parsed || typeof parsed !== \"object\" || !parsed.tokens) return emptyConfig();\n parsed.tokens ??= {};\n return parsed;\n } catch {\n // Corrupt file — start clean rather than crash.\n return emptyConfig();\n }\n}\n\n/** Persist auth.json with locked-down permissions (dir 0700, file 0600). */\nexport function writeConfig(config: AuthConfig): void {\n const dir = configDir();\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n const path = configPath();\n writeFileSync(path, `${JSON.stringify(config, null, 2)}\\n`, { mode: 0o600 });\n // writeFileSync only applies mode on create; enforce it on existing files too.\n chmodSync(path, 0o600);\n}\n\n/** Remove all stored credentials. Idempotent. */\nexport function clearConfig(): void {\n const path = configPath();\n if (existsSync(path)) rmSync(path);\n}\n\nexport function isLoggedIn(config: AuthConfig): boolean {\n return Boolean(config.activeOrgId && config.tokens[config.activeOrgId]);\n}\n","import { createHash, randomBytes } from \"node:crypto\";\nimport { createServer } from \"node:http\";\nimport { AddressInfo } from \"node:net\";\nimport open from \"open\";\nimport {\n type AuthConfig,\n type OrgRef,\n type TokenEntry,\n type UserRef,\n readConfig,\n writeConfig,\n resolveApiUrl,\n} from \"./config\";\n\n/** Refresh a token this many ms before it actually expires. */\nconst EXPIRY_SKEW_MS = 60_000;\n\nfunction base64url(buf: Buffer): string {\n return buf.toString(\"base64url\");\n}\n\n/** PKCE pair: challenge = base64url(sha256(verifier)), matching the API's S256. */\nexport function generatePkce(): { verifier: string; challenge: string } {\n const verifier = base64url(randomBytes(32));\n const challenge = base64url(createHash(\"sha256\").update(verifier).digest());\n return { verifier, challenge };\n}\n\ninterface TokenResponse {\n access_token: string;\n refresh_token: string;\n expires_in: number;\n token_type: string;\n}\n\ninterface WhoAmI {\n id: string;\n name: string;\n email: string;\n organizationId: string;\n}\n\n/** POST the OAuth token endpoint (form-encoded, per RFC 6749). */\nasync function postToken(apiUrl: string, params: Record<string, string>): Promise<TokenResponse> {\n const res = await fetch(`${apiUrl}/oauth/token`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams(params).toString(),\n });\n if (!res.ok) {\n const body = await res.text().catch(() => \"\");\n throw new Error(`Token request failed (${res.status}): ${body}`);\n }\n return (await res.json()) as TokenResponse;\n}\n\n/** Register a fresh dynamic OAuth client bound to this run's loopback URI. */\nasync function registerClient(apiUrl: string, redirectUri: string): Promise<string> {\n const res = await fetch(`${apiUrl}/oauth/register`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ client_name: \"Sequel CLI\", redirect_uris: [redirectUri] }),\n });\n if (!res.ok) {\n const body = await res.text().catch(() => \"\");\n throw new Error(`Client registration failed (${res.status}): ${body}`);\n }\n const data = (await res.json()) as { client_id: string };\n return data.client_id;\n}\n\nasync function fetchWhoAmI(apiUrl: string, accessToken: string): Promise<WhoAmI> {\n const res = await fetch(`${apiUrl}/users/me`, {\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n if (!res.ok) throw new Error(`Failed to resolve identity (${res.status})`);\n return (await res.json()) as WhoAmI;\n}\n\nexport async function fetchOrganizations(apiUrl: string, accessToken: string): Promise<OrgRef[]> {\n const res = await fetch(`${apiUrl}/organizations`, {\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n if (!res.ok) throw new Error(`Failed to list organizations (${res.status})`);\n const rows = (await res.json()) as Array<{\n role: string;\n organization: { id: string; name: string; slug: string };\n }>;\n return rows.map((r) => ({\n id: r.organization.id,\n name: r.organization.name,\n slug: r.organization.slug,\n role: r.role,\n }));\n}\n\n/**\n * Wait for the browser to hit the loopback redirect and hand back `?code&state`.\n * Resolves with the authorization code once `state` is verified.\n */\nfunction waitForCallback(\n expectedState: string,\n): { server: ReturnType<typeof createServer>; port: Promise<number>; code: Promise<string> } {\n let resolveCode!: (code: string) => void;\n let rejectCode!: (err: Error) => void;\n const code = new Promise<string>((resolve, reject) => {\n resolveCode = resolve;\n rejectCode = reject;\n });\n\n const server = createServer((req, res) => {\n const url = new URL(req.url ?? \"/\", \"http://127.0.0.1\");\n if (url.pathname !== \"/callback\") {\n res.writeHead(404).end(\"Not found\");\n return;\n }\n const error = url.searchParams.get(\"error\");\n const returnedState = url.searchParams.get(\"state\");\n const returnedCode = url.searchParams.get(\"code\");\n\n const finish = (title: string, message: string) => {\n res.writeHead(200, { \"Content-Type\": \"text/html; charset=utf-8\" });\n res.end(\n `<!doctype html><html><head><title>${title}</title></head><body style=\"font-family:system-ui;padding:3rem;text-align:center\"><h2>${title}</h2><p>${message}</p><p>You can close this tab and return to your terminal.</p></body></html>`,\n );\n };\n\n if (error) {\n finish(\"Sign-in failed\", `The authorization server returned: ${error}`);\n rejectCode(new Error(`Authorization failed: ${error}`));\n return;\n }\n if (!returnedState || returnedState !== expectedState) {\n finish(\"Sign-in failed\", \"State mismatch — possible CSRF. Please try again.\");\n rejectCode(new Error(\"State mismatch in OAuth callback\"));\n return;\n }\n if (!returnedCode) {\n finish(\"Sign-in failed\", \"No authorization code was returned.\");\n rejectCode(new Error(\"Missing authorization code\"));\n return;\n }\n finish(\"Signed in to Sequel\", \"Authentication complete.\");\n resolveCode(returnedCode);\n });\n\n const port = new Promise<number>((resolve, reject) => {\n server.on(\"error\", reject);\n server.listen(0, \"127.0.0.1\", () => resolve((server.address() as AddressInfo).port));\n });\n\n return { server, port, code };\n}\n\nexport interface LoginResult {\n user: UserRef;\n org: OrgRef | undefined;\n organizationId: string;\n}\n\n/**\n * Run the full OAuth 2.0 + PKCE loopback flow: register a client, open the\n * browser to the consent page (where the user picks an org), capture the code,\n * exchange it for an org-bound token, then cache that token keyed by its org.\n *\n * Shared by `login` and `switch` (for orgs without a cached token).\n */\nexport async function runLoginFlow(options?: { silent?: boolean }): Promise<LoginResult> {\n const config = readConfig();\n const apiUrl = resolveApiUrl(config);\n\n const { verifier, challenge } = generatePkce();\n const state = base64url(randomBytes(16));\n\n const { server, port: portPromise, code: codePromise } = waitForCallback(state);\n const port = await portPromise;\n const redirectUri = `http://127.0.0.1:${port}/callback`;\n\n try {\n const clientId = await registerClient(apiUrl, redirectUri);\n\n const authorizeUrl = new URL(`${apiUrl}/oauth/authorize`);\n authorizeUrl.searchParams.set(\"client_id\", clientId);\n authorizeUrl.searchParams.set(\"redirect_uri\", redirectUri);\n authorizeUrl.searchParams.set(\"response_type\", \"code\");\n authorizeUrl.searchParams.set(\"code_challenge\", challenge);\n authorizeUrl.searchParams.set(\"code_challenge_method\", \"S256\");\n authorizeUrl.searchParams.set(\"state\", state);\n\n if (!options?.silent) {\n // open() can fail in headless envs — never block the flow on it.\n open(authorizeUrl.toString()).catch(() => {});\n }\n // Always surface the URL so the user can open it manually if needed.\n process.stderr.write(`\\nOpen this URL to continue:\\n${authorizeUrl.toString()}\\n\\n`);\n\n const code = await codePromise;\n\n const token = await postToken(apiUrl, {\n grant_type: \"authorization_code\",\n code,\n redirect_uri: redirectUri,\n client_id: clientId,\n code_verifier: verifier,\n });\n\n const me = await fetchWhoAmI(apiUrl, token.access_token);\n const orgs = await fetchOrganizations(apiUrl, token.access_token).catch(() => config.orgs ?? []);\n\n const next: AuthConfig = {\n ...config,\n version: 1,\n apiUrl,\n clientId,\n activeOrgId: me.organizationId,\n tokens: {\n ...config.tokens,\n [me.organizationId]: {\n accessToken: token.access_token,\n refreshToken: token.refresh_token,\n expiresAt: Date.now() + token.expires_in * 1000,\n },\n },\n user: { id: me.id, email: me.email, name: me.name },\n orgs,\n };\n writeConfig(next);\n\n return {\n user: next.user!,\n org: orgs.find((o) => o.id === me.organizationId),\n organizationId: me.organizationId,\n };\n } finally {\n server.close();\n }\n}\n\n/** True when there's a cached token for the active org (cheap, non-throwing). */\nexport function isLoggedIn(): boolean {\n const config = readConfig();\n const orgId = config.activeOrgId;\n return Boolean(orgId && config.tokens[orgId]);\n}\n\n/**\n * Return a valid access token for the active org, refreshing it in place when\n * expired. Throws a friendly error if there is no token or the refresh fails.\n */\nexport async function getValidAccessToken(): Promise<{ token: string; config: AuthConfig }> {\n const config = readConfig();\n const orgId = config.activeOrgId;\n if (!orgId || !config.tokens[orgId]) {\n throw new Error(\"Not logged in. Run `sequel login` first.\");\n }\n\n const entry: TokenEntry = config.tokens[orgId];\n if (entry.expiresAt - EXPIRY_SKEW_MS > Date.now()) {\n return { token: entry.accessToken, config };\n }\n\n // Access token expired — rotate via the refresh grant.\n const apiUrl = resolveApiUrl(config);\n try {\n const refreshed = await postToken(apiUrl, {\n grant_type: \"refresh_token\",\n refresh_token: entry.refreshToken,\n client_id: config.clientId ?? \"\",\n });\n config.tokens[orgId] = {\n accessToken: refreshed.access_token,\n refreshToken: refreshed.refresh_token,\n expiresAt: Date.now() + refreshed.expires_in * 1000,\n };\n writeConfig(config);\n return { token: refreshed.access_token, config };\n } catch {\n throw new Error(\n \"Your session for this organization has expired. Run `sequel login` (or `sequel switch`) to sign in again.\",\n );\n }\n}\n","import { getValidAccessToken } from \"./auth\";\nimport { resolveApiUrl } from \"./config\";\n\nexport class ApiError extends Error {\n constructor(\n public status: number,\n message: string,\n ) {\n super(message);\n this.name = \"ApiError\";\n }\n}\n\ninterface RequestOptions {\n method?: string;\n query?: Record<string, string | undefined>;\n body?: Record<string, unknown>;\n /**\n * How the active org id is attached to the request:\n * - \"query\" → ?organizationId=<org> (default; most GET/DELETE routes)\n * - \"organizationId\" → merged into the JSON body as organizationId\n * - \"organization_id\" → merged into the JSON body as organization_id (execute)\n * - \"none\" → not attached (e.g. /connectors, /oauth/*)\n */\n org?: \"query\" | \"organizationId\" | \"organization_id\" | \"none\";\n}\n\n/**\n * Authenticated request against the Sequel API using the active org's token.\n * Refreshes the token transparently and scopes the call to that org.\n */\nexport async function request<T = unknown>(path: string, options: RequestOptions = {}): Promise<T> {\n const { token, config } = await getValidAccessToken();\n const apiUrl = resolveApiUrl(config);\n const orgId = config.activeOrgId;\n const orgMode = options.org ?? \"query\";\n\n const url = new URL(`${apiUrl}${path}`);\n if (orgMode === \"query\" && orgId) url.searchParams.set(\"organizationId\", orgId);\n for (const [k, v] of Object.entries(options.query ?? {})) {\n if (v !== undefined) url.searchParams.set(k, v);\n }\n\n let bodyObj = options.body;\n if ((orgMode === \"organizationId\" || orgMode === \"organization_id\") && orgId) {\n bodyObj = { ...(bodyObj ?? {}), [orgMode]: orgId };\n }\n\n const headers: Record<string, string> = { Authorization: `Bearer ${token}` };\n let body: string | undefined;\n if (bodyObj !== undefined) {\n headers[\"Content-Type\"] = \"application/json\";\n body = JSON.stringify(bodyObj);\n }\n\n const res = await fetch(url.toString(), { method: options.method ?? \"GET\", headers, body });\n\n if (!res.ok) {\n let message = `Request failed (${res.status})`;\n const text = await res.text().catch(() => \"\");\n try {\n const json = JSON.parse(text) as { error?: string };\n if (json.error) message = json.error;\n } catch {\n if (text) message = text;\n }\n throw new ApiError(res.status, message);\n }\n\n if (res.status === 204) return undefined as T;\n const text = await res.text();\n return (text ? JSON.parse(text) : undefined) as T;\n}\n\n/** The active organization id, or throws if not logged in. */\nexport async function activeOrgId(): Promise<string> {\n const { config } = await getValidAccessToken();\n if (!config.activeOrgId) throw new Error(\"No active organization. Run `sequel login`.\");\n return config.activeOrgId;\n}\n\n// ── Types ──────────────────────────────────────────────────────────────────────\n\nexport interface Connector {\n id: string;\n name: string;\n description: string;\n icon: string;\n appType: \"database\" | \"app\" | \"mcp\";\n live: boolean;\n authId: string;\n credentialsSchema?: Record<string, unknown>;\n userInputFields?: string[];\n canResolveName?: boolean;\n configuration?: { type: string } | null;\n}\n\nexport interface Connection {\n id: string;\n shortId: string;\n name: string;\n type: string;\n createdBy?: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport type LinkCreateResponse =\n | { status: \"success\"; connection: Connection }\n | { status: \"pending\"; link_token: string; redirect_url: string; expires_at: string };\n\nexport interface LinkStatus {\n status: \"pending\" | \"oauth_in_progress\" | \"awaiting_configuration\" | \"success\" | \"failed\" | \"completed\";\n connectionId?: string;\n connection_id?: string;\n reason?: string;\n}\n\nexport interface ExecuteResult {\n data: Array<Record<string, unknown>>;\n columns: string[];\n row_count: number;\n truncated: boolean;\n}\n\nexport interface SearchToolRef {\n tool_id: string;\n input_schema: Record<string, unknown>;\n output_schema: Record<string, unknown> | null;\n relevant_tables: string[];\n}\n\nexport interface SearchResult {\n connection_id: string;\n connection_name: string;\n app_id: string;\n use_case: string;\n instructions: string;\n tools: SearchToolRef[];\n}\n\n// ── Endpoint wrappers ───────────────────────────────────────────────────────────\n\nexport function listConnectors(): Promise<Connector[]> {\n return request<Connector[]>(\"/connectors\", { org: \"none\" });\n}\n\nexport function listConnections(): Promise<Connection[]> {\n return request<Connection[]>(\"/connections\");\n}\n\nexport function getConnection(id: string): Promise<Connection> {\n return request<Connection>(`/connections/${id}`);\n}\n\nexport function deleteConnection(id: string): Promise<Connection> {\n return request<Connection>(`/connections/${id}`, { method: \"DELETE\" });\n}\n\nexport function testConnection(id: string): Promise<{ success: boolean; message: string }> {\n return request(`/connections/${id}/test`, { method: \"POST\", org: \"organizationId\" });\n}\n\nexport function getConnectionConfig(\n id: string,\n): Promise<{ schemaFilters: string[] | null; instructions: string | null }> {\n return request(`/connections/${id}/config`);\n}\n\n/** Mint a connect link / create a connection for the given connector. */\nexport function createLink(appId: string, body: Record<string, unknown>): Promise<LinkCreateResponse> {\n // POST /link/:appId resolves the org from the token's session, which always\n // matches the active org in the multi-token model — no org param needed.\n return request<LinkCreateResponse>(`/link/${appId}`, { method: \"POST\", org: \"none\", body });\n}\n\n/**\n * Poll a connect link's status. Uses the authenticated route, which (unlike the\n * public one) reports terminal states — `completed`/`failed` — so the CLI can\n * tell when the browser flow has finished.\n */\nexport function getLinkStatus(token: string): Promise<LinkStatus> {\n return request<LinkStatus>(`/link/${token}/status`, { org: \"none\" });\n}\n\nexport function execute(\n connectionId: string,\n tool: string,\n params: Record<string, unknown>,\n): Promise<ExecuteResult> {\n return request<ExecuteResult>(\"/execute\", {\n method: \"POST\",\n org: \"organization_id\",\n body: { connection_id: connectionId, tool, params },\n });\n}\n\nexport function search(useCase: string, connectionIds?: string[]): Promise<{ results: SearchResult[] }> {\n return request<{ results: SearchResult[] }>(\"/search\", {\n method: \"POST\",\n org: \"organization_id\",\n body: {\n action_info: `CLI search: ${useCase}`,\n use_case: useCase,\n connection_ids: connectionIds,\n },\n });\n}\n\nexport async function createApiKey(name: string): Promise<{ key: string; keyPrefix: string }> {\n const orgId = await activeOrgId();\n return request(`/organizations/${orgId}/api-keys`, { method: \"POST\", org: \"none\", body: { name } });\n}\n","import pc from \"picocolors\";\n\nexport { pc };\n\n/** True when the user passed a global --json flag (set by index.ts). */\nlet jsonMode = false;\nexport function setJsonMode(on: boolean): void {\n jsonMode = on;\n}\nexport function isJsonMode(): boolean {\n return jsonMode;\n}\n\nexport function printJson(data: unknown): void {\n process.stdout.write(`${JSON.stringify(data, null, 2)}\\n`);\n}\n\nfunction cell(value: unknown): string {\n if (value === null || value === undefined) return \"\";\n if (typeof value === \"object\") return JSON.stringify(value);\n return String(value);\n}\n\n/**\n * Render an array of records as an aligned text table. `columns` controls order\n * and which keys are shown; defaults to the union of keys in the first row.\n */\nexport function renderTable(rows: Array<Record<string, unknown>>, columns?: string[]): string {\n if (rows.length === 0) return pc.dim(\"(no rows)\");\n const cols = columns ?? Object.keys(rows[0]);\n const widths = cols.map((c) => Math.max(c.length, ...rows.map((r) => cell(r[c]).length)));\n\n const header = cols.map((c, i) => pc.bold(c.padEnd(widths[i]))).join(\" \");\n const sep = cols.map((_, i) => \"─\".repeat(widths[i])).join(\" \");\n const body = rows\n .map((r) => cols.map((c, i) => cell(r[c]).padEnd(widths[i])).join(\" \"))\n .join(\"\\n\");\n\n return `${header}\\n${pc.dim(sep)}\\n${body}`;\n}\n\nexport function printTable(rows: Array<Record<string, unknown>>, columns?: string[]): void {\n process.stdout.write(`${renderTable(rows, columns)}\\n`);\n}\n\nexport function success(message: string): void {\n process.stdout.write(`${pc.green(\"✓\")} ${message}\\n`);\n}\n\nexport function info(message: string): void {\n process.stdout.write(`${message}\\n`);\n}\n\nexport function fail(message: string): void {\n process.stderr.write(`${pc.red(\"✗\")} ${message}\\n`);\n}\n","import * as p from \"@clack/prompts\";\nimport { runLoginFlow } from \"../lib/auth\";\nimport { pc, success } from \"../lib/output\";\n\nexport async function loginCommand(): Promise<void> {\n p.intro(pc.cyan(\"Sign in to Sequel\"));\n p.log.info(\"Opening your browser to authorize…\");\n const res = await runLoginFlow();\n success(`Logged in as ${pc.bold(res.user.email)}${res.org ? ` · ${pc.bold(res.org.name)}` : \"\"}`);\n p.outro(\"You're all set. Try `sequel sources list` or `sequel connect`.\");\n}\n","import { clearConfig, isLoggedIn, readConfig } from \"../lib/config\";\nimport { info, success } from \"../lib/output\";\n\nexport async function logoutCommand(): Promise<void> {\n const config = readConfig();\n if (!isLoggedIn(config)) {\n info(\"You are not logged in.\");\n return;\n }\n clearConfig();\n success(\"Logged out. Cached credentials removed from ~/.sequel/auth.json.\");\n}\n","import * as p from \"@clack/prompts\";\nimport { fetchOrganizations, getValidAccessToken, runLoginFlow } from \"../lib/auth\";\nimport { isLoggedIn, readConfig, resolveApiUrl, writeConfig } from \"../lib/config\";\nimport { pc, success } from \"../lib/output\";\n\nexport async function switchCommand(): Promise<void> {\n const config = readConfig();\n if (!isLoggedIn(config)) {\n throw new Error(\"Not logged in. Run `sequel login` first.\");\n }\n\n // Refresh the membership list with the active org's token.\n let orgs = config.orgs ?? [];\n try {\n const { token } = await getValidAccessToken();\n orgs = await fetchOrganizations(resolveApiUrl(config), token);\n writeConfig({ ...readConfig(), orgs });\n } catch {\n // fall back to cached orgs\n }\n if (orgs.length === 0) throw new Error(\"No organizations available for this account.\");\n\n const selection = await p.select({\n message: \"Switch to organization\",\n options: orgs.map((o) => ({\n value: o.id,\n label: o.id === config.activeOrgId ? `${o.name} ${pc.dim(\"(current)\")}` : o.name,\n hint: config.tokens[o.id] ? o.role : \"sign-in required\",\n })),\n });\n if (p.isCancel(selection)) {\n p.cancel(\"Cancelled.\");\n return;\n }\n\n const orgId = selection as string;\n const org = orgs.find((o) => o.id === orgId);\n const fresh = readConfig();\n\n if (fresh.tokens[orgId]) {\n // Already authorized — instant, offline swap.\n writeConfig({ ...fresh, activeOrgId: orgId });\n success(`Switched to ${pc.bold(org?.name ?? orgId)}.`);\n return;\n }\n\n // No cached token for this org — sign in so the user can authorize it.\n p.log.info(`You haven't authorized ${pc.bold(org?.name ?? orgId)} yet — opening your browser…`);\n const res = await runLoginFlow();\n success(`Switched to ${pc.bold(res.org?.name ?? res.organizationId)}.`);\n}\n","import * as p from \"@clack/prompts\";\nimport open from \"open\";\nimport {\n type Connector,\n createLink,\n getLinkStatus,\n listConnectors,\n} from \"../lib/api\";\nimport { info, pc, success } from \"../lib/output\";\n\nconst SECRET_RE = /pass|secret|token|key|connection|credential/i;\n\nfunction fieldsFor(connector: Connector): string[] {\n if (connector.userInputFields?.length) return connector.userInputFields;\n const props = (connector.credentialsSchema as { properties?: Record<string, unknown> } | undefined)?.properties;\n return props ? Object.keys(props) : [];\n}\n\nfunction isOAuth(connector: Connector): boolean {\n return Boolean(connector.configuration) || /oauth/i.test(connector.authId);\n}\n\n/** Poll a pending connect link until it completes or fails (or times out). */\nasync function pollLink(token: string): Promise<{ ok: boolean; reason?: string }> {\n const deadline = Date.now() + 5 * 60_000;\n while (Date.now() < deadline) {\n await new Promise((r) => setTimeout(r, 2000));\n let status;\n try {\n status = await getLinkStatus(token);\n } catch {\n continue; // transient — keep polling\n }\n if (status.status === \"failed\") return { ok: false, reason: status.reason };\n if (status.status === \"success\" || status.status === \"completed\") return { ok: true };\n }\n return { ok: false, reason: \"Timed out waiting for the browser to finish.\" };\n}\n\nexport async function connectCommand(source?: string): Promise<void> {\n const connectors = await listConnectors();\n\n let connector: Connector | undefined;\n if (source) {\n connector = connectors.find((c) => c.id === source);\n if (!connector) {\n throw new Error(\n `Unknown connector \"${source}\". Available: ${connectors.map((c) => c.id).join(\", \")}`,\n );\n }\n } else {\n const choice = await p.select({\n message: \"Which data source do you want to connect?\",\n options: connectors\n .slice()\n .sort((a, b) => a.appType.localeCompare(b.appType) || a.name.localeCompare(b.name))\n .map((c) => ({ value: c.id, label: c.name, hint: c.appType })),\n });\n if (p.isCancel(choice)) {\n p.cancel(\"Cancelled.\");\n return;\n }\n connector = connectors.find((c) => c.id === (choice as string))!;\n }\n\n p.intro(`Connect ${pc.bold(connector.name)}`);\n\n if (!isOAuth(connector)) {\n // Pre-auth connector: collect credential fields in the terminal.\n const fields = fieldsFor(connector);\n const credentials: Record<string, string> = {};\n for (const field of fields) {\n const secret = SECRET_RE.test(field);\n const value = await (secret ? p.password : p.text)({\n message: field,\n });\n if (p.isCancel(value)) {\n p.cancel(\"Cancelled.\");\n return;\n }\n credentials[field] = value as string;\n }\n const name = await p.text({ message: \"Name for this source (optional)\", placeholder: connector.name });\n if (p.isCancel(name)) {\n p.cancel(\"Cancelled.\");\n return;\n }\n\n const s = p.spinner();\n s.start(\"Validating credentials…\");\n const res = await createLink(connector.id, {\n credentials,\n ...(name ? { name } : {}),\n });\n if (res.status === \"success\") {\n s.stop(\"Connected.\");\n success(`Created source ${pc.bold(res.connection.name)} (${res.connection.shortId}).`);\n return;\n }\n // Fallback: server wants more input — finish in the browser.\n s.stop(\"Continue in your browser…\");\n open(res.redirect_url).catch(() => {});\n info(`Open: ${res.redirect_url}`);\n const result = await pollLink(res.link_token);\n if (result.ok) success(\"Connected.\");\n else throw new Error(result.reason ?? \"Connection failed.\");\n return;\n }\n\n // OAuth connector: mint a link and let the polished web flow handle consent\n // (and any pre-OAuth fields like a project id), then poll for completion.\n const res = await createLink(connector.id, {});\n if (res.status === \"success\") {\n success(`Created source ${pc.bold(res.connection.name)} (${res.connection.shortId}).`);\n return;\n }\n open(res.redirect_url).catch(() => {});\n info(`Complete authorization in your browser:\\n${res.redirect_url}`);\n const s = p.spinner();\n s.start(\"Waiting for you to finish in the browser…\");\n const result = await pollLink(res.link_token);\n if (result.ok) {\n s.stop(\"Connected.\");\n success(\"Source connected.\");\n } else {\n s.stop(\"Failed.\");\n throw new Error(result.reason ?? \"Connection failed.\");\n }\n}\n","import * as p from \"@clack/prompts\";\nimport {\n type Connection,\n deleteConnection,\n getConnection,\n getConnectionConfig,\n listConnections,\n testConnection,\n} from \"../lib/api\";\nimport { info, isJsonMode, pc, printJson, printTable, success } from \"../lib/output\";\n\n/** Resolve a user-supplied id (uuid or shortId) to the connection's real id. */\nasync function resolveConnection(idOrShort: string): Promise<Connection> {\n const all = await listConnections();\n const match = all.find((c) => c.id === idOrShort || c.shortId === idOrShort);\n if (!match) throw new Error(`No source found matching \"${idOrShort}\".`);\n return match;\n}\n\nasync function pickConnection(message: string): Promise<Connection | undefined> {\n const all = await listConnections();\n if (all.length === 0) {\n info(\"No sources connected yet. Run `sequel connect`.\");\n return undefined;\n }\n const choice = await p.select({\n message,\n options: all.map((c) => ({ value: c.shortId, label: `${c.name} (${c.shortId})`, hint: c.type })),\n });\n if (p.isCancel(choice)) return undefined;\n return all.find((c) => c.shortId === (choice as string));\n}\n\nfunction toRow(c: Connection): Record<string, unknown> {\n return { id: c.shortId, name: c.name, type: c.type, created: c.createdAt.slice(0, 10) };\n}\n\nexport async function sourcesList(): Promise<void> {\n const connections = await listConnections();\n if (isJsonMode()) return printJson(connections);\n if (connections.length === 0) return info(\"No sources connected yet. Run `sequel connect`.\");\n printTable(connections.map(toRow), [\"id\", \"name\", \"type\", \"created\"]);\n}\n\nexport async function sourcesActive(): Promise<void> {\n const connections = await listConnections();\n const rows = await Promise.all(\n connections.map(async (c) => {\n let status = \"unknown\";\n try {\n const t = await testConnection(c.id);\n status = t.success ? \"healthy\" : \"error\";\n } catch {\n status = \"error\";\n }\n return { ...toRow(c), status };\n }),\n );\n if (isJsonMode()) return printJson(rows);\n if (rows.length === 0) return info(\"No sources connected yet. Run `sequel connect`.\");\n printTable(rows, [\"id\", \"name\", \"type\", \"status\", \"created\"]);\n}\n\nexport async function sourcesInfo(idOrShort?: string): Promise<void> {\n const conn = idOrShort ? await resolveConnection(idOrShort) : await pickConnection(\"Source to inspect\");\n if (!conn) return;\n const full = await getConnection(conn.id);\n let config: { schemaFilters: string[] | null; instructions: string | null } | null = null;\n try {\n config = await getConnectionConfig(conn.id);\n } catch {\n /* config may be absent */\n }\n if (isJsonMode()) return printJson({ ...full, config });\n\n info(`${pc.bold(full.name)} ${pc.dim(full.shortId)}`);\n info(`type: ${full.type}`);\n info(`id: ${full.id}`);\n info(`created: ${full.createdAt}`);\n if (config?.schemaFilters?.length) info(`schemas: ${config.schemaFilters.join(\", \")}`);\n if (config?.instructions) info(`\\n${pc.dim(config.instructions)}`);\n}\n\nexport async function sourcesDelete(idOrShort?: string): Promise<void> {\n const conn = idOrShort ? await resolveConnection(idOrShort) : await pickConnection(\"Source to delete\");\n if (!conn) return;\n const confirmed = await p.confirm({ message: `Delete ${pc.bold(conn.name)} (${conn.shortId})? This cannot be undone.` });\n if (p.isCancel(confirmed) || !confirmed) {\n info(\"Cancelled.\");\n return;\n }\n await deleteConnection(conn.id);\n success(`Deleted ${conn.name} (${conn.shortId}).`);\n}\n","import { homedir, platform } from \"node:os\";\nimport { join } from \"node:path\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport YAML from \"yaml\";\n\nexport type Scope = \"global\" | \"local\";\n\nexport interface InstallOptions {\n apiUrl: string;\n apiKey: string;\n scope: Scope;\n /** Project root for local scope (defaults to cwd). Injectable for tests. */\n cwd?: string;\n /** Home dir override for tests. */\n home?: string;\n}\n\n/** What happened during install — either a file we wrote or a command to run. */\nexport type InstallResult =\n | { kind: \"file\"; path: string }\n | { kind: \"command\"; command: string; args: string[] };\n\nexport interface McpClientDef {\n slug: string;\n name: string;\n scopes: Scope[];\n /** Human-readable target (path or command) for a scope, for previews. */\n describe(opts: InstallOptions): string;\n install(opts: InstallOptions): InstallResult;\n}\n\nconst SERVER_NAME = \"sequel\";\nconst mcpUrl = (apiUrl: string) => `${apiUrl.replace(/\\/$/, \"\")}/mcp`;\nconst bearer = (apiKey: string) => `Bearer ${apiKey}`;\n\nfunction home(opts: InstallOptions): string {\n return opts.home ?? homedir();\n}\nfunction cwd(opts: InstallOptions): string {\n return opts.cwd ?? process.cwd();\n}\n\n/** OS-specific application-support dir for a vendor folder. */\nfunction appSupport(opts: InstallOptions, vendor: string): string {\n const h = home(opts);\n switch (platform()) {\n case \"darwin\":\n return join(h, \"Library\", \"Application Support\", vendor);\n case \"win32\":\n return join(process.env.APPDATA ?? join(h, \"AppData\", \"Roaming\"), vendor);\n default:\n return join(process.env.XDG_CONFIG_HOME ?? join(h, \".config\"), vendor);\n }\n}\n\n/** Read+merge+write a JSON config, preserving every other key already present. */\nfunction mergeJson(path: string, mutate: (cfg: Record<string, unknown>) => void): void {\n let cfg: Record<string, unknown> = {};\n if (existsSync(path)) {\n try {\n cfg = JSON.parse(readFileSync(path, \"utf8\")) as Record<string, unknown>;\n } catch {\n cfg = {};\n }\n }\n mutate(cfg);\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, `${JSON.stringify(cfg, null, 2)}\\n`);\n}\n\nfunction mergeYaml(path: string, mutate: (cfg: Record<string, unknown>) => void): void {\n let cfg: Record<string, unknown> = {};\n if (existsSync(path)) {\n try {\n cfg = (YAML.parse(readFileSync(path, \"utf8\")) as Record<string, unknown>) ?? {};\n } catch {\n cfg = {};\n }\n }\n mutate(cfg);\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, YAML.stringify(cfg));\n}\n\nfunction setNested(cfg: Record<string, unknown>, key: string, value: unknown): void {\n const obj = (cfg[key] as Record<string, unknown>) ?? {};\n obj[SERVER_NAME] = value;\n cfg[key] = obj;\n}\n\n// ── Client definitions ──────────────────────────────────────────────────────────\n\nexport const mcpClients: McpClientDef[] = [\n {\n slug: \"claude\",\n name: \"Claude Desktop\",\n scopes: [\"global\"],\n describe: (o) => join(appSupport(o, \"Claude\"), \"claude_desktop_config.json\"),\n install(o) {\n const path = join(appSupport(o, \"Claude\"), \"claude_desktop_config.json\");\n mergeJson(path, (cfg) =>\n setNested(cfg, \"mcpServers\", {\n url: mcpUrl(o.apiUrl),\n headers: { Authorization: bearer(o.apiKey) },\n }),\n );\n return { kind: \"file\", path };\n },\n },\n {\n slug: \"claude-code\",\n name: \"Claude Code\",\n scopes: [\"global\", \"local\"],\n describe: (o) =>\n `claude mcp add --scope ${o.scope === \"global\" ? \"user\" : \"local\"} --transport http ${SERVER_NAME} …`,\n install(o) {\n return {\n kind: \"command\",\n command: \"claude\",\n args: [\n \"mcp\",\n \"add\",\n \"--scope\",\n o.scope === \"global\" ? \"user\" : \"local\",\n \"--transport\",\n \"http\",\n SERVER_NAME,\n mcpUrl(o.apiUrl),\n \"--header\",\n `Authorization: ${bearer(o.apiKey)}`,\n ],\n };\n },\n },\n {\n slug: \"cursor\",\n name: \"Cursor\",\n scopes: [\"global\", \"local\"],\n describe: (o) => (o.scope === \"global\" ? join(home(o), \".cursor\", \"mcp.json\") : join(cwd(o), \".cursor\", \"mcp.json\")),\n install(o) {\n const path = o.scope === \"global\" ? join(home(o), \".cursor\", \"mcp.json\") : join(cwd(o), \".cursor\", \"mcp.json\");\n mergeJson(path, (cfg) =>\n setNested(cfg, \"mcpServers\", {\n url: mcpUrl(o.apiUrl),\n headers: { Authorization: bearer(o.apiKey) },\n }),\n );\n return { kind: \"file\", path };\n },\n },\n {\n slug: \"vscode\",\n name: \"VS Code\",\n scopes: [\"global\", \"local\"],\n describe: (o) =>\n o.scope === \"global\" ? join(appSupport(o, \"Code\"), \"User\", \"mcp.json\") : join(cwd(o), \".vscode\", \"mcp.json\"),\n install(o) {\n const path =\n o.scope === \"global\" ? join(appSupport(o, \"Code\"), \"User\", \"mcp.json\") : join(cwd(o), \".vscode\", \"mcp.json\");\n mergeJson(path, (cfg) =>\n setNested(cfg, \"servers\", {\n url: mcpUrl(o.apiUrl),\n type: \"http\",\n headers: { Authorization: bearer(o.apiKey) },\n }),\n );\n return { kind: \"file\", path };\n },\n },\n {\n slug: \"windsurf\",\n name: \"Windsurf\",\n scopes: [\"global\"],\n describe: (o) => join(home(o), \".codeium\", \"windsurf\", \"mcp_config.json\"),\n install(o) {\n const path = join(home(o), \".codeium\", \"windsurf\", \"mcp_config.json\");\n mergeJson(path, (cfg) =>\n setNested(cfg, \"mcpServers\", {\n // Windsurf uses `serverUrl`, not `url`.\n serverUrl: mcpUrl(o.apiUrl),\n headers: { Authorization: bearer(o.apiKey) },\n }),\n );\n return { kind: \"file\", path };\n },\n },\n {\n slug: \"zed\",\n name: \"Zed\",\n scopes: [\"global\", \"local\"],\n describe: (o) =>\n o.scope === \"global\" ? join(home(o), \".config\", \"zed\", \"settings.json\") : join(cwd(o), \".zed\", \"settings.json\"),\n install(o) {\n const path =\n o.scope === \"global\"\n ? join(home(o), \".config\", \"zed\", \"settings.json\")\n : join(cwd(o), \".zed\", \"settings.json\");\n mergeJson(path, (cfg) =>\n setNested(cfg, \"context_servers\", {\n url: mcpUrl(o.apiUrl),\n settings: { headers: { Authorization: bearer(o.apiKey) } },\n }),\n );\n return { kind: \"file\", path };\n },\n },\n {\n slug: \"codex\",\n name: \"Codex\",\n scopes: [\"global\"],\n describe: (o) => join(home(o), \".codex\", \"config.yaml\"),\n install(o) {\n const path = join(home(o), \".codex\", \"config.yaml\");\n mergeYaml(path, (cfg) =>\n setNested(cfg, \"mcp_servers\", {\n url: mcpUrl(o.apiUrl),\n headers: { Authorization: bearer(o.apiKey) },\n }),\n );\n return { kind: \"file\", path };\n },\n },\n];\n\nexport function getMcpClient(slug: string): McpClientDef | undefined {\n return mcpClients.find((c) => c.slug === slug);\n}\n","import { execFileSync } from \"node:child_process\";\nimport * as p from \"@clack/prompts\";\nimport { createApiKey } from \"../lib/api\";\nimport { isLoggedIn } from \"../lib/auth\";\nimport { readConfig, resolveApiUrl } from \"../lib/config\";\nimport { type Scope, getMcpClient, mcpClients } from \"../lib/mcp-clients\";\nimport { pc, success } from \"../lib/output\";\n\nexport async function installCommand(slugArg?: string): Promise<void> {\n p.intro(pc.cyan(\"Install the Sequel MCP server\"));\n\n if (!isLoggedIn()) {\n p.cancel(\"Not logged in. Run `sequel login` first.\");\n return;\n }\n\n let slug = slugArg;\n if (!slug) {\n const choice = await p.select({\n message: \"Which coding agent do you want to install Sequel into?\",\n options: mcpClients.map((c) => ({ value: c.slug, label: c.name })),\n });\n if (p.isCancel(choice)) return p.cancel(\"Cancelled.\");\n slug = choice as string;\n }\n\n const client = getMcpClient(slug);\n if (!client) throw new Error(`Unknown agent \"${slug}\". Options: ${mcpClients.map((c) => c.slug).join(\", \")}`);\n\n let scope: Scope = client.scopes[0];\n if (client.scopes.length > 1) {\n const choice = await p.select({\n message: \"Install scope\",\n options: [\n { value: \"global\", label: \"Global\", hint: \"available everywhere on this machine\" },\n { value: \"local\", label: \"Local\", hint: \"this project only\" },\n ].filter((o) => client.scopes.includes(o.value as Scope)),\n });\n if (p.isCancel(choice)) return p.cancel(\"Cancelled.\");\n scope = choice as Scope;\n }\n\n const config = readConfig();\n const apiUrl = resolveApiUrl(config);\n\n const s = p.spinner();\n s.start(\"Creating a Sequel API key for this agent…\");\n let key: string;\n try {\n ({ key } = await createApiKey(`Sequel CLI (${client.name})`));\n } catch (err) {\n s.stop(\"Failed to create API key.\");\n throw err;\n }\n s.stop(\"API key created.\");\n\n const result = client.install({ apiUrl, apiKey: key, scope });\n\n if (result.kind === \"command\") {\n // e.g. Claude Code: run `claude mcp add …`.\n try {\n execFileSync(result.command, result.args, { stdio: \"inherit\" });\n } catch {\n throw new Error(\n `Failed to run \\`${result.command}\\`. Make sure it's installed, or run manually:\\n${result.command} ${result.args.join(\" \")}`,\n );\n }\n success(`Installed Sequel into ${client.name} (${scope}).`);\n } else {\n success(`Installed Sequel into ${client.name}.`);\n p.log.info(`Config written to ${pc.dim(result.path)}`);\n }\n\n p.outro(`Restart ${client.name} and ask it to \"list my Sequel connections\" to verify.`);\n}\n","import { search } from \"../lib/api\";\nimport { info, isJsonMode, pc, printJson } from \"../lib/output\";\n\nexport async function searchCommand(useCase: string, opts: { connection?: string[] }): Promise<void> {\n const res = await search(useCase, opts.connection);\n if (isJsonMode()) return printJson(res);\n\n if (res.results.length === 0) {\n info(\"No matching tools found across your connected sources.\");\n return;\n }\n\n for (const r of res.results) {\n info(`\\n${pc.bold(r.connection_name)} ${pc.dim(`(${r.connection_id} · ${r.app_id})`)}`);\n if (r.instructions) info(pc.dim(r.instructions));\n for (const tool of r.tools) {\n info(` ${pc.cyan(tool.tool_id)}`);\n if (tool.relevant_tables?.length) info(` tables: ${tool.relevant_tables.join(\", \")}`);\n }\n info(pc.dim(` → sequel execute ${r.connection_id} ${r.tools[0]?.tool_id ?? \"<tool>\"} -d '{…}'`));\n }\n}\n","import { execute } from \"../lib/api\";\nimport { info, isJsonMode, pc, printJson, printTable } from \"../lib/output\";\n\nexport async function executeCommand(\n connectionId: string,\n tool: string,\n opts: { data?: string },\n): Promise<void> {\n let params: Record<string, unknown> = {};\n if (opts.data) {\n try {\n params = JSON.parse(opts.data) as Record<string, unknown>;\n } catch {\n throw new Error(\"Invalid JSON passed to -d/--data.\");\n }\n }\n\n const res = await execute(connectionId, tool, params);\n if (isJsonMode()) return printJson(res);\n\n if (res.data.length === 0) {\n info(pc.dim(\"(0 rows)\"));\n return;\n }\n printTable(res.data, res.columns.length ? res.columns : undefined);\n info(pc.dim(`\\n${res.row_count} row(s)${res.truncated ? \" (truncated)\" : \"\"}`));\n}\n","import { Command } from \"commander\";\nimport { ApiError } from \"./lib/api\";\nimport { fail, setJsonMode } from \"./lib/output\";\nimport { loginCommand } from \"./commands/login\";\nimport { logoutCommand } from \"./commands/logout\";\nimport { switchCommand } from \"./commands/switch\";\nimport { connectCommand } from \"./commands/connect\";\nimport { sourcesActive, sourcesDelete, sourcesInfo, sourcesList } from \"./commands/sources\";\nimport { installCommand } from \"./commands/install\";\nimport { searchCommand } from \"./commands/search\";\nimport { executeCommand } from \"./commands/execute\";\n\nconst program = new Command();\n\nprogram\n .name(\"sequel\")\n .description(\"Sequel CLI — connect data sources and run tools from your terminal\")\n .version(\"0.0.0\")\n .option(\"--json\", \"output machine-readable JSON\")\n .enablePositionalOptions();\n\n/** Wrap a command action with shared --json handling and error reporting. */\nfunction action<A extends unknown[]>(fn: (...args: A) => Promise<void>) {\n return async (...args: A) => {\n if (program.opts().json) setJsonMode(true);\n try {\n await fn(...args);\n } catch (err) {\n if (err instanceof ApiError && err.status === 401) {\n fail(\"Unauthorized. Run `sequel login` to sign in again.\");\n } else {\n fail(err instanceof Error ? err.message : String(err));\n }\n process.exitCode = 1;\n }\n };\n}\n\nprogram.command(\"login\").description(\"Sign in to Sequel\").action(action(loginCommand));\nprogram.command(\"logout\").description(\"Sign out and remove cached credentials\").action(action(logoutCommand));\nprogram.command(\"switch\").description(\"Switch the active organization\").action(action(switchCommand));\n\nprogram\n .command(\"connect\")\n .argument(\"[source]\", \"connector id (e.g. postgres); omit to choose interactively\")\n .description(\"Connect a new data source\")\n .action(action(connectCommand));\n\nconst sources = program.command(\"sources\").description(\"Manage connected data sources\");\nsources.command(\"list\", { isDefault: true }).description(\"List connected sources\").action(action(sourcesList));\nsources.command(\"active\").description(\"List sources with live health status\").action(action(sourcesActive));\nsources\n .command(\"info\")\n .argument(\"[id]\", \"source id or short id\")\n .description(\"Show details for a source\")\n .action(action(sourcesInfo));\nsources\n .command(\"delete\")\n .argument(\"[id]\", \"source id or short id\")\n .description(\"Delete a source\")\n .action(action(sourcesDelete));\n\nprogram\n .command(\"install\")\n .argument(\"[agent]\", \"coding agent slug (e.g. cursor, claude-code)\")\n .description(\"Install the Sequel MCP server into a coding agent\")\n .action(action(installCommand));\n\nprogram\n .command(\"search\")\n .argument(\"<usecase>\", \"what you want to do, e.g. \\\"monthly revenue\\\"\")\n .option(\"-c, --connection <id...>\", \"limit to specific connection short ids\")\n .description(\"Find the right tools for a use case across your sources\")\n .action(action((usecase: string, opts: { connection?: string[] }) => searchCommand(usecase, opts)));\n\nprogram\n .command(\"execute\")\n .argument(\"<connection_id>\", \"connection short id\")\n .argument(\"<tool>\", \"tool id, e.g. postgres.query\")\n .option(\"-d, --data <json>\", \"tool input as a JSON string\")\n .description(\"Execute a tool against a connection\")\n .action(action((connectionId: string, tool: string, opts: { data?: string }) => executeCommand(connectionId, tool, opts)));\n\nprogram.parseAsync(process.argv).catch((err) => {\n fail(err instanceof Error ? err.message : String(err));\n process.exit(1);\n});\n"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sequelsh/cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Sequel CLI — connect data sources and run tools from your terminal.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"sequel": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"import": "./dist/index.js",
|
|
16
|
+
"types": "./dist/index.d.ts"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">=18"
|
|
21
|
+
},
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/sequelsh/sequel.git",
|
|
25
|
+
"directory": "packages/cli"
|
|
26
|
+
},
|
|
27
|
+
"homepage": "https://sequel.sh",
|
|
28
|
+
"keywords": [
|
|
29
|
+
"sequel",
|
|
30
|
+
"cli",
|
|
31
|
+
"mcp",
|
|
32
|
+
"sql",
|
|
33
|
+
"data",
|
|
34
|
+
"ai",
|
|
35
|
+
"agents"
|
|
36
|
+
],
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public"
|
|
39
|
+
},
|
|
40
|
+
"scripts": {
|
|
41
|
+
"dev": "bun run src/index.ts",
|
|
42
|
+
"cli": "bun run src/index.ts",
|
|
43
|
+
"build": "tsdown",
|
|
44
|
+
"build:binaries": "bun run scripts/build-binaries.ts",
|
|
45
|
+
"test": "vitest run",
|
|
46
|
+
"test:watch": "vitest",
|
|
47
|
+
"typecheck": "tsc --noEmit",
|
|
48
|
+
"clean": "rm -rf dist"
|
|
49
|
+
},
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"@clack/prompts": "^0.8.2",
|
|
52
|
+
"commander": "^12.1.0",
|
|
53
|
+
"open": "^10.1.0",
|
|
54
|
+
"picocolors": "^1.1.1",
|
|
55
|
+
"yaml": "^2.5.1"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@sequel/typescript-config": "workspace:*",
|
|
59
|
+
"@types/node": "^22.10.0",
|
|
60
|
+
"tsdown": "^0.9.0",
|
|
61
|
+
"typescript": "^5.7.0",
|
|
62
|
+
"vitest": "^3.0.0"
|
|
63
|
+
}
|
|
64
|
+
}
|