@theplato/tiro-cli 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +90 -0
- package/README.md +23 -2
- package/dist/bin/tiro.js +234 -46
- package/package.json +4 -3
- package/SPEC.md +0 -364
- package/dist/bin/tiro.js.map +0 -1
package/dist/bin/tiro.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/bin/tiro.ts","../../src/lib/version.ts","../../src/lib/error.ts","../../src/lib/output/tty.ts","../../src/lib/output/print.ts","../../src/commands/auth/index.ts","../../src/commands/auth/login.ts","../../src/lib/auth/flow.ts","../../src/lib/auth/pkce.ts","../../src/lib/auth/loopback.ts","../../src/lib/auth/browser.ts","../../src/lib/auth/keychain.ts","../../src/lib/auth/token.ts","../../src/lib/config.ts","../../src/commands/auth/status.ts","../../src/commands/auth/logout.ts","../../src/commands/notes/index.ts","../../src/commands/notes/list.ts","../../src/lib/api/client.ts","../../src/lib/api/types.ts","../../src/lib/util/parseDate.ts","../../src/lib/util/noteFilter.ts","../../src/commands/notes/search.ts","../../src/commands/notes/get.ts","../../src/lib/output/file.ts","../../src/lib/output/transcript.ts","../../src/lib/output/format.ts","../../src/commands/notes/transcript.ts","../../src/lib/updateCheck.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { VERSION } from \"../lib/version.ts\";\nimport { TiroError, ExitCode } from \"../lib/error.ts\";\nimport { printError } from \"../lib/output/print.ts\";\nimport { color } from \"../lib/output/tty.ts\";\nimport { registerAuth } from \"../commands/auth/index.ts\";\nimport { registerNotes } from \"../commands/notes/index.ts\";\nimport { emitUpdateBanner, startUpdateCheck } from \"../lib/updateCheck.ts\";\n\nconst EXAMPLES = `\nEXAMPLES\n $ tiro auth login\n $ tiro notes list --since 7d\n $ tiro notes search \"Q3 Planning\" --since 30d --json\n $ tiro notes get <guid> --output ./meeting.md --include transcript\n $ tiro notes transcript <guid> --format md --output ./transcript.md\n\nENVIRONMENT\n TIRO_TOKEN Bearer token (overrides keychain — for CI / agents)\n TIRO_HOSTNAME API base URL (default: https://api.tiro.ooo)\n NO_COLOR Disable colors (https://no-color.org)\n NO_UPDATE_NOTIFIER Set to \"1\" to disable the update banner\n\nDOCS\n https://api-docs.tiro.ooo/cli/overview\n`;\n\nfunction buildProgram(): Command {\n const program = new Command();\n\n program\n .name(\"tiro\")\n .description(\"Tiro AI notes & transcripts — agent-first command line\")\n .version(VERSION, \"-v, --version\", \"Print version\")\n .option(\"--hostname <url>\", \"API base URL (default: https://api.tiro.ooo)\")\n .option(\"--json\", \"Force JSON output\")\n .option(\"--pretty\", \"Force pretty (human) output\")\n .option(\"--quiet\", \"Suppress non-error output\")\n .option(\"--verbose\", \"Verbose logging to stderr\")\n .option(\"--no-color\", \"Disable ANSI colors\")\n .addHelpText(\"after\", EXAMPLES);\n\n program.showHelpAfterError(\"(run `tiro --help` for available commands)\");\n\n registerAuth(program);\n registerNotes(program);\n\n return program;\n}\n\nasync function main(): Promise<void> {\n const program = buildProgram();\n const notifier = await startUpdateCheck();\n try {\n await program.parseAsync(process.argv);\n emitUpdateBanner(notifier);\n } catch (err) {\n handleError(err, program);\n }\n}\n\nfunction handleError(err: unknown, program: Command): never {\n const opts = program.opts<{ json?: boolean; quiet?: boolean }>();\n\n if (err instanceof TiroError) {\n if (opts.json) {\n printError(err.toJSON());\n } else if (!opts.quiet) {\n process.stderr.write(`${color(\"✗\", \"red\", opts)} ${err.message}\\n`);\n if (err.suggestion) {\n process.stderr.write(` ${color(\"→\", \"gray\", opts)} ${err.suggestion}\\n`);\n }\n }\n process.exit(err.exitCode);\n }\n\n if (err instanceof Error) {\n if (opts.json) {\n printError({\n ok: false,\n error: { code: \"internal_error\", message: err.message, errorType: \"internal_error\" },\n });\n } else if (!opts.quiet) {\n process.stderr.write(`${color(\"✗\", \"red\", opts)} ${err.message}\\n`);\n }\n process.exit(ExitCode.Generic);\n }\n\n process.stderr.write(`Unknown error: ${String(err)}\\n`);\n process.exit(ExitCode.Generic);\n}\n\nmain().catch((err) => {\n process.stderr.write(`Fatal: ${String(err)}\\n`);\n process.exit(ExitCode.Generic);\n});\n","export const VERSION = \"0.1.0\";\n","export const ExitCode = {\n Ok: 0,\n Generic: 1,\n Usage: 2,\n AuthRequired: 4,\n ExUsage: 64,\n ExDataErr: 65,\n ExConfig: 78,\n} as const;\n\nexport type ExitCodeValue = (typeof ExitCode)[keyof typeof ExitCode];\n\nexport type ErrorType =\n | \"bad_request\"\n | \"unauthorized\"\n | \"forbidden\"\n | \"not_found\"\n | \"not_acceptable\"\n | \"conflict\"\n | \"payload_too_large\"\n | \"unprocessable_entity\"\n | \"too_many_requests\"\n | \"internal_error\"\n | \"auth_required\"\n | \"config_missing\"\n | \"network_error\";\n\nexport interface ErrorPayload {\n code: string;\n message: string;\n suggestion?: string;\n errorType?: ErrorType;\n httpStatus?: number;\n requestId?: string;\n}\n\nexport class TiroError extends Error {\n readonly code: string;\n readonly suggestion?: string;\n readonly errorType?: ErrorType;\n readonly httpStatus?: number;\n readonly requestId?: string;\n readonly exitCode: ExitCodeValue;\n\n constructor(payload: ErrorPayload, exitCode: ExitCodeValue = ExitCode.Generic) {\n super(payload.message);\n this.name = \"TiroError\";\n this.code = payload.code;\n this.suggestion = payload.suggestion;\n this.errorType = payload.errorType;\n this.httpStatus = payload.httpStatus;\n this.requestId = payload.requestId;\n this.exitCode = exitCode;\n }\n\n toJSON(): { ok: false; error: ErrorPayload } {\n return {\n ok: false,\n error: {\n code: this.code,\n message: this.message,\n ...(this.suggestion !== undefined && { suggestion: this.suggestion }),\n ...(this.errorType !== undefined && { errorType: this.errorType }),\n ...(this.httpStatus !== undefined && { httpStatus: this.httpStatus }),\n ...(this.requestId !== undefined && { requestId: this.requestId }),\n },\n };\n }\n}\n\nexport function authRequired(): TiroError {\n return new TiroError(\n {\n code: \"auth_required\",\n message:\n \"Not authenticated. Run `tiro auth login` to sign in, or set TIRO_TOKEN env var.\",\n suggestion: \"tiro auth login\",\n errorType: \"auth_required\",\n },\n ExitCode.AuthRequired,\n );\n}\n\nexport function configMissing(message: string, suggestion?: string): TiroError {\n return new TiroError(\n {\n code: \"config_missing\",\n message,\n ...(suggestion !== undefined && { suggestion }),\n errorType: \"config_missing\",\n },\n ExitCode.ExConfig,\n );\n}\n","export type OutputMode = \"json\" | \"pretty\";\n\nexport interface OutputOptions {\n json?: boolean;\n pretty?: boolean;\n noColor?: boolean;\n quiet?: boolean;\n}\n\nexport function resolveOutputMode(opts: OutputOptions): OutputMode {\n if (opts.json) return \"json\";\n if (opts.pretty) return \"pretty\";\n return process.stdout.isTTY ? \"pretty\" : \"json\";\n}\n\nexport function colorEnabled(opts: OutputOptions): boolean {\n if (opts.noColor) return false;\n if (process.env[\"NO_COLOR\"]) return false;\n if (process.env[\"FORCE_COLOR\"]) return true;\n return process.stdout.isTTY === true;\n}\n\nconst ANSI = {\n reset: \"\\x1b[0m\",\n bold: \"\\x1b[1m\",\n dim: \"\\x1b[2m\",\n red: \"\\x1b[31m\",\n green: \"\\x1b[32m\",\n yellow: \"\\x1b[33m\",\n blue: \"\\x1b[34m\",\n magenta: \"\\x1b[35m\",\n cyan: \"\\x1b[36m\",\n gray: \"\\x1b[90m\",\n} as const;\n\nexport function color(\n text: string,\n style: keyof typeof ANSI,\n opts: OutputOptions = {},\n): string {\n if (!colorEnabled(opts)) return text;\n return `${ANSI[style]}${text}${ANSI.reset}`;\n}\n","import { resolveOutputMode, type OutputOptions } from \"./tty.ts\";\n\nexport function printOutput(value: unknown, opts: OutputOptions = {}): void {\n if (opts.quiet) return;\n const mode = resolveOutputMode(opts);\n if (mode === \"json\") {\n process.stdout.write(`${JSON.stringify(value)}\\n`);\n } else {\n process.stdout.write(`${JSON.stringify(value, null, 2)}\\n`);\n }\n}\n\nexport function printError(value: unknown): void {\n process.stderr.write(`${JSON.stringify(value)}\\n`);\n}\n\nexport function printNdjson(item: unknown): void {\n process.stdout.write(`${JSON.stringify(item)}\\n`);\n}\n","import { Command } from \"commander\";\nimport { registerAuthLogin } from \"./login.ts\";\nimport { registerAuthStatus } from \"./status.ts\";\nimport { registerAuthLogout } from \"./logout.ts\";\n\nexport function registerAuth(program: Command): void {\n const auth = program.command(\"auth\").description(\"Manage authentication\");\n registerAuthLogin(auth);\n registerAuthStatus(auth);\n registerAuthLogout(auth);\n}\n","import { Command } from \"commander\";\nimport { performLogin } from \"../../lib/auth/flow.ts\";\nimport { printOutput } from \"../../lib/output/print.ts\";\nimport { color } from \"../../lib/output/tty.ts\";\nimport { getHostname } from \"../../lib/config.ts\";\n\ninterface LoginOptions {\n hostname?: string;\n noBrowser?: boolean;\n json?: boolean;\n pretty?: boolean;\n noColor?: boolean;\n quiet?: boolean;\n}\n\nexport function registerAuthLogin(parent: Command): void {\n parent\n .command(\"login\")\n .description(\"Sign in to Tiro via OAuth (browser-based, PKCE)\")\n .option(\"--hostname <url>\", \"API base URL (overrides config / TIRO_HOSTNAME)\")\n .option(\"--no-browser\", \"Print the URL instead of opening a browser\")\n .action(async (opts: LoginOptions, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<LoginOptions>();\n const result = await performLogin({\n ...(opts.hostname !== undefined && { hostname: opts.hostname }),\n noBrowser: opts.noBrowser === true,\n onPrompt: (msg) => {\n if (globalOpts.quiet) return;\n process.stderr.write(`${color(msg, \"cyan\", globalOpts)}\\n`);\n },\n });\n\n const hostname = getHostname(opts.hostname);\n const expiresIso = new Date(result.expiresAt).toISOString();\n\n if (globalOpts.json) {\n printOutput(\n {\n ok: true,\n data: {\n signedIn: true,\n hostname,\n userId: result.userId ?? null,\n expiresAt: expiresIso,\n },\n },\n globalOpts,\n );\n } else if (!globalOpts.quiet) {\n process.stderr.write(`${color(\"✓\", \"green\", globalOpts)} Signed in to ${hostname}\\n`);\n if (result.userId) {\n process.stderr.write(` user: ${result.userId}\\n`);\n }\n process.stderr.write(` token expires: ${expiresIso}\\n`);\n }\n });\n}\n","import { z } from \"zod\";\nimport { TiroError, ExitCode } from \"../error.ts\";\nimport { generatePkce, generateState } from \"./pkce.ts\";\nimport { startLoopbackServer } from \"./loopback.ts\";\nimport { openBrowser } from \"./browser.ts\";\nimport { saveToken, type StoredToken } from \"./keychain.ts\";\nimport { decodeJwtPayload } from \"./token.ts\";\nimport {\n getHostname,\n getOauthClientId,\n setOauthClientId,\n clearOauthClientId,\n} from \"../config.ts\";\n\nconst RegisterResponseSchema = z.object({\n client_id: z.string(),\n client_secret: z.string().optional(),\n});\n\nconst TokenResponseSchema = z.object({\n access_token: z.string(),\n token_type: z.string(),\n expires_in: z.number().optional(),\n scope: z.string().optional(),\n});\n\nconst CALLBACK_TIMEOUT_MS = 5 * 60 * 1000;\nconst DEFAULT_SCOPE = \"mcp:notes:read\";\n\nexport interface LoginOptions {\n hostname?: string;\n noBrowser?: boolean;\n scope?: string;\n onPrompt?: (msg: string) => void;\n}\n\nexport interface LoginResult {\n hostname: string;\n userId: string | undefined;\n expiresAt: number;\n}\n\nexport async function performLogin(options: LoginOptions = {}): Promise<LoginResult> {\n const hostname = getHostname(options.hostname);\n const onPrompt = options.onPrompt ?? ((msg: string) => process.stderr.write(`${msg}\\n`));\n\n const loopback = await startLoopbackServer();\n\n try {\n const clientId = await ensureOauthClient(hostname, loopback.redirectUri);\n const { codeVerifier, codeChallenge } = generatePkce();\n const state = generateState();\n\n const authorizeUrl = buildAuthorizeUrl({\n hostname,\n clientId,\n redirectUri: loopback.redirectUri,\n state,\n codeChallenge,\n scope: options.scope ?? DEFAULT_SCOPE,\n });\n\n if (options.noBrowser) {\n onPrompt(`Open this URL in your browser:\\n${authorizeUrl}`);\n } else {\n onPrompt(`Opening browser for sign-in...`);\n onPrompt(`If the browser does not open, visit:\\n${authorizeUrl}`);\n await openBrowser(authorizeUrl);\n }\n\n const callback = await loopback.waitForCallback(CALLBACK_TIMEOUT_MS);\n\n if (callback.state !== state) {\n throw new TiroError(\n {\n code: \"auth_state_mismatch\",\n message: \"OAuth state mismatch — possible CSRF. Aborting.\",\n errorType: \"unauthorized\",\n },\n ExitCode.Generic,\n );\n }\n\n const tokenRes = await exchangeToken({\n hostname,\n clientId,\n code: callback.code,\n redirectUri: loopback.redirectUri,\n codeVerifier,\n });\n\n const expiresAt = computeExpiry(tokenRes.expires_in);\n const payload = decodeJwtPayload(tokenRes.access_token);\n const userId = typeof payload?.[\"sub\"] === \"string\" ? (payload[\"sub\"] as string) : undefined;\n\n const stored: StoredToken = {\n accessToken: tokenRes.access_token,\n tokenType: tokenRes.token_type,\n expiresAt,\n hostname,\n ...(tokenRes.scope !== undefined && { scope: tokenRes.scope }),\n ...(userId !== undefined && { userId }),\n };\n saveToken(stored);\n\n return { hostname, userId, expiresAt };\n } finally {\n loopback.close();\n }\n}\n\nasync function ensureOauthClient(hostname: string, redirectUri: string): Promise<string> {\n const cached = getOauthClientId();\n if (cached) return cached;\n\n const url = `${hostname}/v1/mcp/oauth/register`;\n let res: Response;\n try {\n res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n client_name: \"tiro-cli\",\n redirect_uris: [redirectUri],\n grant_types: [\"authorization_code\"],\n response_types: [\"code\"],\n token_endpoint_auth_method: \"none\",\n scope: DEFAULT_SCOPE,\n }),\n });\n } catch (err) {\n throw new TiroError(\n {\n code: \"network_error\",\n message: `Failed to reach ${hostname}: ${(err as Error).message}`,\n errorType: \"network_error\",\n suggestion: \"Check your network connection or --hostname.\",\n },\n ExitCode.Generic,\n );\n }\n\n if (!res.ok) {\n const detail = await safeText(res);\n throw new TiroError(\n {\n code: \"oauth_register_failed\",\n message: `Dynamic Client Registration failed: HTTP ${res.status}`,\n errorType: \"internal_error\",\n httpStatus: res.status,\n ...(detail !== \"\" && { suggestion: detail.slice(0, 200) }),\n },\n ExitCode.Generic,\n );\n }\n\n const json = (await res.json()) as unknown;\n const parsed = RegisterResponseSchema.safeParse(json);\n if (!parsed.success) {\n throw new TiroError(\n {\n code: \"oauth_register_invalid\",\n message: \"Registration response did not match expected shape.\",\n errorType: \"internal_error\",\n },\n ExitCode.Generic,\n );\n }\n\n setOauthClientId(parsed.data.client_id);\n return parsed.data.client_id;\n}\n\ninterface AuthorizeUrlInput {\n hostname: string;\n clientId: string;\n redirectUri: string;\n state: string;\n codeChallenge: string;\n scope: string;\n}\n\nfunction buildAuthorizeUrl(input: AuthorizeUrlInput): string {\n const u = new URL(`${input.hostname}/v1/mcp/oauth/authorize`);\n u.searchParams.set(\"response_type\", \"code\");\n u.searchParams.set(\"client_id\", input.clientId);\n u.searchParams.set(\"redirect_uri\", input.redirectUri);\n u.searchParams.set(\"state\", input.state);\n u.searchParams.set(\"code_challenge\", input.codeChallenge);\n u.searchParams.set(\"code_challenge_method\", \"S256\");\n u.searchParams.set(\"scope\", input.scope);\n return u.toString();\n}\n\ninterface ExchangeInput {\n hostname: string;\n clientId: string;\n code: string;\n redirectUri: string;\n codeVerifier: string;\n}\n\nasync function exchangeToken(input: ExchangeInput): Promise<z.infer<typeof TokenResponseSchema>> {\n const url = `${input.hostname}/v1/mcp/oauth/token`;\n const body = new URLSearchParams({\n grant_type: \"authorization_code\",\n code: input.code,\n redirect_uri: input.redirectUri,\n client_id: input.clientId,\n code_verifier: input.codeVerifier,\n });\n\n let res: Response;\n try {\n res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: body.toString(),\n });\n } catch (err) {\n throw new TiroError(\n {\n code: \"network_error\",\n message: `Failed to reach ${input.hostname}: ${(err as Error).message}`,\n errorType: \"network_error\",\n },\n ExitCode.Generic,\n );\n }\n\n if (!res.ok) {\n if (res.status === 400 || res.status === 401) {\n // Cached client_id may have expired (Redis 30-day TTL). Force re-registration on next try.\n clearOauthClientId();\n }\n const detail = await safeText(res);\n throw new TiroError(\n {\n code: \"oauth_token_failed\",\n message: `Token exchange failed: HTTP ${res.status}`,\n errorType: \"unauthorized\",\n httpStatus: res.status,\n ...(detail !== \"\" && { suggestion: detail.slice(0, 200) }),\n },\n ExitCode.AuthRequired,\n );\n }\n\n const json = (await res.json()) as unknown;\n const parsed = TokenResponseSchema.safeParse(json);\n if (!parsed.success) {\n throw new TiroError(\n {\n code: \"oauth_token_invalid\",\n message: \"Token response did not match expected shape.\",\n errorType: \"internal_error\",\n },\n ExitCode.Generic,\n );\n }\n return parsed.data;\n}\n\nfunction computeExpiry(expiresIn?: number): number {\n // McpJwtService issues 180-day tokens; if expires_in absent, fall back to 180 days.\n const fallbackSeconds = 180 * 24 * 60 * 60;\n const seconds = expiresIn ?? fallbackSeconds;\n return Date.now() + seconds * 1000;\n}\n\nasync function safeText(res: Response): Promise<string> {\n try {\n return await res.text();\n } catch {\n return \"\";\n }\n}\n","import { createHash, randomBytes } from \"node:crypto\";\n\nexport interface PkcePair {\n codeVerifier: string;\n codeChallenge: string;\n method: \"S256\";\n}\n\nexport function generatePkce(): PkcePair {\n const codeVerifier = base64url(randomBytes(32));\n const codeChallenge = base64url(createHash(\"sha256\").update(codeVerifier).digest());\n return { codeVerifier, codeChallenge, method: \"S256\" };\n}\n\nexport function generateState(): string {\n return base64url(randomBytes(24));\n}\n\nfunction base64url(buf: Buffer): string {\n return buf\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\");\n}\n","import http from \"node:http\";\nimport type { AddressInfo } from \"node:net\";\n\nexport interface CallbackResult {\n code: string;\n state: string;\n}\n\nexport interface LoopbackServer {\n redirectUri: string;\n port: number;\n waitForCallback: (timeoutMs: number) => Promise<CallbackResult>;\n close: () => void;\n}\n\nexport async function startLoopbackServer(): Promise<LoopbackServer> {\n let pendingResolve: ((r: CallbackResult) => void) | null = null;\n let pendingReject: ((e: Error) => void) | null = null;\n\n const settle = (\n fn: ((arg: CallbackResult) => void) | ((arg: Error) => void),\n arg: CallbackResult | Error,\n ): void => {\n pendingResolve = null;\n pendingReject = null;\n (fn as (arg: CallbackResult | Error) => void)(arg);\n };\n\n const server = http.createServer((req, res) => {\n if (!req.url) {\n res.writeHead(400).end();\n return;\n }\n const url = new URL(req.url, `http://127.0.0.1`);\n if (url.pathname !== \"/callback\") {\n res.writeHead(404, { \"Content-Type\": \"text/plain\" }).end(\"Not found\");\n return;\n }\n\n const code = url.searchParams.get(\"code\");\n const state = url.searchParams.get(\"state\");\n const error = url.searchParams.get(\"error\");\n const errorDesc = url.searchParams.get(\"error_description\") ?? \"\";\n\n if (error) {\n const msg = `OAuth error: ${error}${errorDesc ? ` — ${errorDesc}` : \"\"}`;\n respondPage(res, 500, \"Login failed\", msg);\n if (pendingReject) settle(pendingReject, new Error(msg));\n return;\n }\n if (!code || !state) {\n respondPage(res, 400, \"Missing parameters\", \"Missing `code` or `state`.\");\n if (pendingReject) settle(pendingReject, new Error(\"Missing code or state\"));\n return;\n }\n\n respondPage(\n res,\n 200,\n \"Login successful\",\n \"You're signed in. You can close this tab and return to the terminal.\",\n );\n if (pendingResolve) settle(pendingResolve, { code, state });\n });\n\n await new Promise<void>((resolve) => {\n server.listen(0, \"127.0.0.1\", () => resolve());\n });\n\n const address = server.address() as AddressInfo;\n const port = address.port;\n const redirectUri = `http://127.0.0.1:${port}/callback`;\n\n return {\n redirectUri,\n port,\n waitForCallback(timeoutMs: number) {\n return new Promise<CallbackResult>((resolve, reject) => {\n const timer = setTimeout(() => {\n pendingResolve = null;\n pendingReject = null;\n reject(new Error(`Timed out waiting for OAuth callback (${timeoutMs}ms)`));\n }, timeoutMs);\n pendingResolve = (r) => {\n clearTimeout(timer);\n resolve(r);\n };\n pendingReject = (e) => {\n clearTimeout(timer);\n reject(e);\n };\n });\n },\n close() {\n server.close();\n },\n };\n}\n\nfunction respondPage(\n res: http.ServerResponse,\n status: number,\n title: string,\n body: string,\n): void {\n const html = `<!doctype html>\n<html lang=\"en\">\n<head>\n <meta charset=\"utf-8\">\n <title>${title}</title>\n <style>\n body { font-family: -apple-system, system-ui, sans-serif; padding: 4rem; max-width: 32rem; margin: 0 auto; color: #1a1a1a; }\n h1 { font-size: 1.5rem; margin-bottom: 1rem; }\n p { color: #555; line-height: 1.5; }\n </style>\n</head>\n<body>\n <h1>${title}</h1>\n <p>${body}</p>\n</body>\n</html>`;\n res.writeHead(status, { \"Content-Type\": \"text/html; charset=utf-8\" });\n res.end(html);\n}\n","import open from \"open\";\n\nexport async function openBrowser(url: string): Promise<void> {\n try {\n await open(url, { wait: false });\n } catch {\n // Best-effort. Caller already prints the URL for manual fallback.\n }\n}\n","import { Entry } from \"@napi-rs/keyring\";\nimport { TiroError, ExitCode } from \"../error.ts\";\n\nconst SERVICE = \"io.tiro.cli\";\nconst ACCOUNT = \"default\";\n\nexport interface StoredToken {\n accessToken: string;\n tokenType: string;\n expiresAt: number;\n scope?: string;\n hostname: string;\n userId?: string;\n}\n\nexport function saveToken(token: StoredToken): void {\n const entry = new Entry(SERVICE, ACCOUNT);\n try {\n entry.setPassword(JSON.stringify(token));\n } catch (err) {\n throw new TiroError(\n {\n code: \"keychain_write_failed\",\n message: `Failed to write to OS keychain: ${(err as Error).message}`,\n errorType: \"internal_error\",\n suggestion:\n process.platform === \"linux\"\n ? \"Linux requires a Secret Service daemon (gnome-keyring or kwallet). Or set TIRO_TOKEN env var.\"\n : \"Check OS keychain permissions, or set TIRO_TOKEN env var.\",\n },\n ExitCode.Generic,\n );\n }\n}\n\nexport function loadToken(): StoredToken | null {\n const entry = new Entry(SERVICE, ACCOUNT);\n let raw: string | null;\n try {\n raw = entry.getPassword();\n } catch {\n return null;\n }\n if (!raw) return null;\n try {\n return JSON.parse(raw) as StoredToken;\n } catch {\n return null;\n }\n}\n\nexport function deleteToken(): boolean {\n const entry = new Entry(SERVICE, ACCOUNT);\n try {\n return entry.deletePassword();\n } catch {\n return false;\n }\n}\n","import { loadToken, type StoredToken } from \"./keychain.ts\";\nimport { authRequired } from \"../error.ts\";\n\nexport interface ResolvedToken {\n accessToken: string;\n source: \"env\" | \"keychain\";\n hostname?: string;\n expiresAt?: number;\n userId?: string;\n}\n\nexport function resolveToken(): ResolvedToken | null {\n const envToken = process.env[\"TIRO_TOKEN\"];\n if (envToken) {\n return { accessToken: envToken, source: \"env\" };\n }\n const stored = loadToken();\n if (stored) {\n return {\n accessToken: stored.accessToken,\n source: \"keychain\",\n hostname: stored.hostname,\n expiresAt: stored.expiresAt,\n ...(stored.userId !== undefined && { userId: stored.userId }),\n };\n }\n return null;\n}\n\nexport function requireToken(): ResolvedToken {\n const t = resolveToken();\n if (!t) throw authRequired();\n return t;\n}\n\nexport function decodeJwtPayload(token: string): Record<string, unknown> | null {\n const parts = token.split(\".\");\n if (parts.length !== 3) return null;\n try {\n const payload = parts[1];\n if (!payload) return null;\n const json = Buffer.from(payload, \"base64url\").toString(\"utf8\");\n return JSON.parse(json) as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\nexport function isTokenExpired(stored: StoredToken): boolean {\n return Date.now() >= stored.expiresAt;\n}\n","import Conf from \"conf\";\n\ninterface TiroConfigSchema {\n hostname: string;\n oauthClientId: string | null;\n oauthClientIdRegisteredAt: number | null;\n defaultOutputDir: string | null;\n}\n\nconst DEFAULT_HOSTNAME = \"https://api.tiro.ooo\";\n\nconst config = new Conf<TiroConfigSchema>({\n projectName: \"tiro\",\n defaults: {\n hostname: DEFAULT_HOSTNAME,\n oauthClientId: null,\n oauthClientIdRegisteredAt: null,\n defaultOutputDir: null,\n },\n});\n\nexport function getHostname(override?: string): string {\n if (override) return stripTrailingSlash(override);\n const env = process.env[\"TIRO_HOSTNAME\"];\n if (env) return stripTrailingSlash(env);\n return stripTrailingSlash(config.get(\"hostname\"));\n}\n\nexport function setHostname(hostname: string): void {\n config.set(\"hostname\", stripTrailingSlash(hostname));\n}\n\nexport function getOauthClientId(): string | null {\n const id = config.get(\"oauthClientId\");\n const registeredAt = config.get(\"oauthClientIdRegisteredAt\");\n if (!id || !registeredAt) return null;\n // DCR clients have 30-day TTL on the backend (Redis). Treat them as expired\n // a day earlier to avoid edge-case 401s during exchange.\n const ttlMs = 29 * 24 * 60 * 60 * 1000;\n if (Date.now() - registeredAt > ttlMs) return null;\n return id;\n}\n\nexport function setOauthClientId(clientId: string): void {\n config.set(\"oauthClientId\", clientId);\n config.set(\"oauthClientIdRegisteredAt\", Date.now());\n}\n\nexport function clearOauthClientId(): void {\n config.set(\"oauthClientId\", null);\n config.set(\"oauthClientIdRegisteredAt\", null);\n}\n\nexport function getDefaultOutputDir(): string | null {\n const env = process.env[\"TIRO_OUTPUT_DIR\"];\n if (env) return env;\n return config.get(\"defaultOutputDir\");\n}\n\nexport function getConfigPath(): string {\n return config.path;\n}\n\nfunction stripTrailingSlash(s: string): string {\n return s.endsWith(\"/\") ? s.slice(0, -1) : s;\n}\n","import { Command } from \"commander\";\nimport { resolveToken, decodeJwtPayload } from \"../../lib/auth/token.ts\";\nimport { printOutput } from \"../../lib/output/print.ts\";\nimport { color } from \"../../lib/output/tty.ts\";\nimport { authRequired } from \"../../lib/error.ts\";\n\ninterface StatusReport {\n signedIn: boolean;\n source: \"env\" | \"keychain\";\n hostname: string | null;\n userId: string | null;\n scope: string | null;\n expiresAt: string | null;\n expired: boolean;\n tokenPrefix: string;\n}\n\ninterface StatusOptions {\n json?: boolean;\n pretty?: boolean;\n noColor?: boolean;\n quiet?: boolean;\n}\n\nexport function registerAuthStatus(parent: Command): void {\n parent\n .command(\"status\")\n .description(\"Show current authenticated account and scopes\")\n .action(async (_opts: StatusOptions, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<StatusOptions>();\n const t = resolveToken();\n if (!t) {\n throw authRequired();\n }\n\n const payload = decodeJwtPayload(t.accessToken);\n const sub = typeof payload?.[\"sub\"] === \"string\" ? (payload[\"sub\"] as string) : null;\n const exp = typeof payload?.[\"exp\"] === \"number\" ? (payload[\"exp\"] as number) * 1000 : null;\n const scope = typeof payload?.[\"scope\"] === \"string\" ? (payload[\"scope\"] as string) : null;\n\n const expMs = exp ?? t.expiresAt ?? null;\n const expired = expMs !== null && Date.now() >= expMs;\n\n const report: StatusReport = {\n signedIn: true,\n source: t.source,\n hostname: t.hostname ?? null,\n userId: t.userId ?? sub,\n scope,\n expiresAt: expMs ? new Date(expMs).toISOString() : null,\n expired,\n tokenPrefix: `${t.accessToken.slice(0, 4)}...***`,\n };\n\n if (globalOpts.json || !process.stdout.isTTY) {\n printOutput({ ok: true, data: report }, globalOpts);\n } else {\n const headIcon = expired ? color(\"!\", \"yellow\", globalOpts) : color(\"✓\", \"green\", globalOpts);\n const headText = expired ? \"Token expired\" : \"Signed in\";\n process.stdout.write(`${headIcon} ${headText}\\n`);\n process.stdout.write(` source: ${report.source}\\n`);\n if (report.hostname) process.stdout.write(` hostname: ${report.hostname}\\n`);\n if (report.userId) process.stdout.write(` user: ${report.userId}\\n`);\n if (report.scope) process.stdout.write(` scope: ${report.scope}\\n`);\n if (report.expiresAt) {\n const tag = expired ? color(\" (expired)\", \"red\", globalOpts) : \"\";\n process.stdout.write(` expires at: ${report.expiresAt}${tag}\\n`);\n }\n process.stdout.write(` token: ${report.tokenPrefix}\\n`);\n if (expired) {\n process.stdout.write(\n `\\n${color(\"→\", \"gray\", globalOpts)} Run \\`tiro auth login\\` to refresh.\\n`,\n );\n }\n }\n });\n}\n","import { Command } from \"commander\";\nimport { deleteToken } from \"../../lib/auth/keychain.ts\";\nimport { clearOauthClientId } from \"../../lib/config.ts\";\nimport { printOutput } from \"../../lib/output/print.ts\";\nimport { color } from \"../../lib/output/tty.ts\";\n\ninterface LogoutOptions {\n json?: boolean;\n pretty?: boolean;\n noColor?: boolean;\n quiet?: boolean;\n}\n\nexport function registerAuthLogout(parent: Command): void {\n parent\n .command(\"logout\")\n .description(\"Sign out and clear the stored token\")\n .action(async (_opts: LogoutOptions, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<LogoutOptions>();\n const removed = deleteToken();\n clearOauthClientId();\n\n if (globalOpts.json) {\n printOutput({ ok: true, data: { signedOut: true, hadToken: removed } }, globalOpts);\n } else if (!globalOpts.quiet) {\n if (removed) {\n process.stderr.write(`${color(\"✓\", \"green\", globalOpts)} Signed out\\n`);\n } else {\n process.stderr.write(`${color(\"•\", \"gray\", globalOpts)} No token was stored\\n`);\n }\n }\n });\n}\n","import { Command } from \"commander\";\nimport { registerNotesList } from \"./list.ts\";\nimport { registerNotesSearch } from \"./search.ts\";\nimport { registerNotesGet } from \"./get.ts\";\nimport { registerNotesTranscript } from \"./transcript.ts\";\n\nexport function registerNotes(program: Command): void {\n const notes = program.command(\"notes\").description(\"List, search, and download notes\");\n registerNotesList(notes);\n registerNotesSearch(notes);\n registerNotesGet(notes);\n registerNotesTranscript(notes);\n}\n","import { Command } from \"commander\";\nimport { createApiClient } from \"../../lib/api/client.ts\";\nimport { NoteSchema, PageCursorResponseSchema } from \"../../lib/api/types.ts\";\nimport { printNdjson } from \"../../lib/output/print.ts\";\nimport { resolveOutputMode, color } from \"../../lib/output/tty.ts\";\nimport { parseDate } from \"../../lib/util/parseDate.ts\";\nimport { isVisibleNote } from \"../../lib/util/noteFilter.ts\";\n\ninterface ListOptions {\n keyword?: string;\n folder?: string;\n since?: string;\n until?: string;\n limit?: string;\n cursor?: string;\n includeUntitled?: boolean;\n hostname?: string;\n json?: boolean;\n pretty?: boolean;\n noColor?: boolean;\n quiet?: boolean;\n}\n\nconst ListResponseSchema = PageCursorResponseSchema(NoteSchema);\n\nconst DEFAULT_PAGE_SIZE = 100;\nconst MAX_PAGE_SIZE = 1000;\n\nconst HELP_AFTER = `\nExamples:\n tiro notes list --since 7d\n tiro notes list --keyword \"OKR\" --since 30d --json\n tiro notes list --folder <id> --limit 50\n\nKeyword matching:\n --keyword reorders results by OpenSearch relevance (case-insensitive,\n full-text against note title and paragraph content). When --keyword is\n set, nextCursor is always null. Without --keyword, results are ordered\n by createdAt desc.\n\nNote: placeholder notes (title='Untitled' or sourceType='onboarding') are\nfiltered out by default. A page of N may return fewer than N visible notes —\nkeep paginating to fetch more, or pass --include-untitled to surface them.\n`;\n\nexport function registerNotesList(parent: Command): void {\n parent\n .command(\"list\")\n .description(\"List notes (lightweight metadata).\")\n .option(\"--keyword <text>\", 'Reorder by OpenSearch relevance for this keyword (e.g. \"OKR\")')\n .option(\"--folder <id>\", \"Restrict to a folder and its descendants\")\n .option(\n \"--since <date>\",\n \"Inclusive lower bound on createdAt (ISO-8601 or relative: 7d, 24h, 30m)\",\n )\n .option(\"--until <date>\", \"Exclusive upper bound on createdAt\")\n .option(\n \"--limit <n>\",\n `Max results per page (default ${DEFAULT_PAGE_SIZE}, max ${MAX_PAGE_SIZE})`,\n )\n .option(\"--cursor <token>\", \"Continue a previous page\")\n .option(\n \"--include-untitled\",\n \"Include placeholder notes (title='Untitled' or sourceType='onboarding'). Default: hidden\",\n false,\n )\n .addHelpText(\"after\", HELP_AFTER)\n .action(async (opts: ListOptions, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<ListOptions>();\n const client = createApiClient({\n ...(globalOpts.hostname !== undefined && { hostnameOverride: globalOpts.hostname }),\n });\n\n const params: Record<string, string | number | undefined> = {};\n if (opts.keyword) params[\"keyword\"] = opts.keyword;\n if (opts.folder) params[\"folderId\"] = opts.folder;\n if (opts.since) params[\"createdAtFrom\"] = parseDate(opts.since);\n if (opts.until) params[\"createdAtTo\"] = parseDate(opts.until);\n const size = clampLimit(opts.limit);\n if (size !== undefined) params[\"size\"] = size;\n if (opts.cursor) params[\"cursor\"] = opts.cursor;\n\n const res = await client.getJson(\"/v1/external/notes\", ListResponseSchema, params);\n const visible = opts.includeUntitled === true ? res.content : res.content.filter(isVisibleNote);\n\n const mode = resolveOutputMode(globalOpts);\n if (mode === \"json\") {\n for (const note of visible) printNdjson(note);\n if (res.nextCursor) printNdjson({ _cursor: res.nextCursor });\n } else {\n printPretty(visible, res.nextCursor, globalOpts);\n }\n });\n}\n\nfunction clampLimit(raw?: string): number | undefined {\n if (!raw) return undefined;\n const n = parseInt(raw, 10);\n if (!Number.isFinite(n) || n <= 0) return DEFAULT_PAGE_SIZE;\n return Math.min(n, MAX_PAGE_SIZE);\n}\n\ninterface NoteListItem {\n guid: string;\n title: string;\n createdAt: string;\n recordingDurationSeconds: number;\n webUrl: string;\n}\n\nfunction printPretty(\n notes: NoteListItem[],\n nextCursor: string | null,\n opts: { noColor?: boolean },\n): void {\n if (notes.length === 0) {\n process.stdout.write(`${color(\"(no notes)\", \"gray\", opts)}\\n`);\n return;\n }\n const titleWidth = computeTitleWidth();\n for (const n of notes) {\n const date = n.createdAt.slice(0, 10);\n const dur = formatDuration(n.recordingDurationSeconds);\n const title = truncate(n.title, titleWidth);\n process.stdout.write(\n `${color(date, \"gray\", opts)} ${color(n.guid, \"dim\", opts)} ${color(dur, \"cyan\", opts)} ${title}\\n`,\n );\n }\n if (nextCursor) {\n process.stdout.write(\n `${color(`\\n next: --cursor ${nextCursor}`, \"gray\", opts)}\\n`,\n );\n }\n}\n\nfunction computeTitleWidth(): number {\n const cols = process.stdout.columns;\n if (!cols || cols < 60) return 40;\n return Math.max(20, cols - 60);\n}\n\nfunction truncate(s: string, max: number): string {\n if (s.length <= max) return s;\n return s.slice(0, Math.max(0, max - 1)) + \"…\";\n}\n\nfunction formatDuration(sec: number): string {\n if (!sec || sec <= 0) return \"—\";\n const m = Math.floor(sec / 60);\n const s = Math.floor(sec % 60);\n if (m > 0) return `${m}m${s.toString().padStart(2, \"0\")}s`;\n return `${s}s`;\n}\n","import { z } from \"zod\";\nimport { TiroError, ExitCode, type ErrorType } from \"../error.ts\";\nimport { resolveToken } from \"../auth/token.ts\";\nimport { authRequired } from \"../error.ts\";\nimport { getHostname } from \"../config.ts\";\nimport { ApiErrorSchema } from \"./types.ts\";\n\nexport interface ApiClientOptions {\n hostnameOverride?: string;\n tokenOverride?: string;\n}\n\nexport class TiroApiClient {\n constructor(\n private readonly hostname: string,\n private readonly token: string,\n ) {}\n\n async getJson<S extends z.ZodTypeAny>(\n path: string,\n schema: S,\n params?: Record<string, string | number | undefined>,\n ): Promise<z.infer<S>> {\n const url = this.buildUrl(path, params);\n const res = await this.fetch(url, { method: \"GET\" });\n return this.parseJson(res, schema, \"GET\", path);\n }\n\n async postJson<S extends z.ZodTypeAny>(\n path: string,\n schema: S,\n body: unknown,\n ): Promise<z.infer<S>> {\n const url = this.buildUrl(path);\n const res = await this.fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n return this.parseJson(res, schema, \"POST\", path);\n }\n\n async putJson<S extends z.ZodTypeAny>(\n path: string,\n schema: S,\n body: unknown,\n ): Promise<z.infer<S>> {\n const url = this.buildUrl(path);\n const res = await this.fetch(url, {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n return this.parseJson(res, schema, \"PUT\", path);\n }\n\n async deleteVoid(path: string): Promise<void> {\n const url = this.buildUrl(path);\n const res = await this.fetch(url, { method: \"DELETE\" });\n if (!res.ok) throw await mapHttpError(res, \"DELETE\", path);\n }\n\n private buildUrl(path: string, params?: Record<string, string | number | undefined>): string {\n const base = path.startsWith(\"http\") ? path : `${this.hostname}${path}`;\n const u = new URL(base);\n if (params) {\n for (const [k, v] of Object.entries(params)) {\n if (v !== undefined && v !== null && v !== \"\") {\n u.searchParams.set(k, String(v));\n }\n }\n }\n return u.toString();\n }\n\n private async fetch(url: string, init: RequestInit): Promise<Response> {\n const headers = new Headers(init.headers);\n headers.set(\"Authorization\", `Bearer ${this.token}`);\n headers.set(\"Accept\", \"application/json\");\n try {\n return await fetch(url, { ...init, headers });\n } catch (err) {\n throw new TiroError(\n {\n code: \"network_error\",\n message: `Network error reaching ${this.hostname}: ${(err as Error).message}`,\n errorType: \"network_error\",\n suggestion: \"Check your network or --hostname.\",\n },\n ExitCode.Generic,\n );\n }\n }\n\n private async parseJson<S extends z.ZodTypeAny>(\n res: Response,\n schema: S,\n method: string,\n path: string,\n ): Promise<z.infer<S>> {\n if (!res.ok) throw await mapHttpError(res, method, path);\n let json: unknown;\n try {\n json = await res.json();\n } catch (err) {\n throw new TiroError(\n {\n code: \"invalid_response\",\n message: `Failed to parse JSON from ${method} ${path}: ${(err as Error).message}`,\n errorType: \"internal_error\",\n },\n ExitCode.Generic,\n );\n }\n const parsed = schema.safeParse(json);\n if (!parsed.success) {\n throw new TiroError(\n {\n code: \"schema_mismatch\",\n message: `Response shape did not match expected schema (${method} ${path}).`,\n errorType: \"internal_error\",\n suggestion: parsed.error.issues\n .slice(0, 3)\n .map((i) => `${i.path.join(\".\") || \"(root)\"}: ${i.message}`)\n .join(\"; \"),\n },\n ExitCode.Generic,\n );\n }\n return parsed.data;\n }\n}\n\nasync function mapHttpError(res: Response, method: string, path: string): Promise<TiroError> {\n const requestId = res.headers.get(\"x-request-id\") ?? undefined;\n const exitCode = res.status === 401 ? ExitCode.AuthRequired : ExitCode.Generic;\n\n const apiError = await tryParseApiError(res);\n if (apiError) {\n return new TiroError(\n {\n code: `${apiError.error.errorType}`,\n message: apiError.error.message,\n errorType: apiError.error.errorType as ErrorType,\n httpStatus: res.status,\n ...(requestId !== undefined && { requestId }),\n ...(res.status === 401 && {\n suggestion: \"Run `tiro auth login` to refresh.\",\n }),\n },\n exitCode,\n );\n }\n\n return new TiroError(\n {\n code: \"http_error\",\n message: `${method} ${path} failed: HTTP ${res.status} ${res.statusText}`,\n errorType: httpStatusToErrorType(res.status),\n httpStatus: res.status,\n ...(requestId !== undefined && { requestId }),\n },\n exitCode,\n );\n}\n\nfunction httpStatusToErrorType(status: number): ErrorType {\n if (status === 400) return \"bad_request\";\n if (status === 401) return \"unauthorized\";\n if (status === 403) return \"forbidden\";\n if (status === 404) return \"not_found\";\n if (status === 409) return \"conflict\";\n if (status === 413) return \"payload_too_large\";\n if (status === 422) return \"unprocessable_entity\";\n if (status === 429) return \"too_many_requests\";\n return \"internal_error\";\n}\n\nasync function tryParseApiError(res: Response): Promise<{ error: { code: number; errorType: string; message: string } } | null> {\n try {\n const json = await res.clone().json();\n const parsed = ApiErrorSchema.safeParse(json);\n return parsed.success ? parsed.data : null;\n } catch {\n return null;\n }\n}\n\nexport function createApiClient(opts: ApiClientOptions = {}): TiroApiClient {\n if (opts.tokenOverride) {\n return new TiroApiClient(getHostname(opts.hostnameOverride), opts.tokenOverride);\n }\n const t = resolveToken();\n if (!t) throw authRequired();\n const hostname = getHostname(opts.hostnameOverride ?? t.hostname);\n return new TiroApiClient(hostname, t.accessToken);\n}\n","import { z } from \"zod\";\n\nexport const CollaboratorSchema = z.object({\n guid: z.string(),\n name: z.string(),\n email: z.string(),\n role: z.enum([\"OWNER\", \"EDITOR\", \"VIEWER\"]),\n});\n\nexport const ParticipantSchema = z.object({\n name: z.string().nullable().optional(),\n email: z.string().nullable().optional(),\n});\n\nexport const NoteSchema = z\n .object({\n guid: z.string(),\n title: z.string(),\n createdAt: z.string(),\n updatedAt: z.string(),\n sourceType: z.string(),\n recordingDurationSeconds: z.number(),\n collaborators: z.array(CollaboratorSchema).optional().default([]),\n participants: z.array(ParticipantSchema).optional().default([]),\n webUrl: z.string(),\n recordingStartAt: z.string().nullable().optional(),\n recordingEndAt: z.string().nullable().optional(),\n })\n .passthrough();\nexport type Note = z.infer<typeof NoteSchema>;\n\nexport const TextObjectSchema = z.object({\n type: z.string(),\n content: z.string(),\n});\nexport type TextObject = z.infer<typeof TextObjectSchema>;\n\nexport const SpeakerInfoSchema = z.object({\n label: z.string(),\n personName: z.string().nullable().optional(),\n});\nexport type SpeakerInfo = z.infer<typeof SpeakerInfoSchema>;\n\nexport const DiarizedSegmentSchema = z.object({\n content: z.string(),\n speaker: SpeakerInfoSchema,\n});\nexport type DiarizedSegment = z.infer<typeof DiarizedSegmentSchema>;\n\nexport const ParagraphSchema = z\n .object({\n uuid: z.string(),\n transcribeLocale: z.string().nullable().optional(),\n transcript: TextObjectSchema.nullable().optional(),\n diarizedSegments: z.array(DiarizedSegmentSchema).nullable().optional(),\n timeFrom: z.string().nullable().optional(),\n timeTo: z.string().nullable().optional(),\n locked: z.boolean().optional(),\n })\n .passthrough();\nexport type Paragraph = z.infer<typeof ParagraphSchema>;\n\nexport const McpSegmentSchema = z.object({\n content: z.string(),\n speaker: z\n .object({\n label: z.string(),\n name: z.string().nullable(),\n })\n .nullable(),\n});\nexport type McpSegment = z.infer<typeof McpSegmentSchema>;\n\nexport const McpParagraphSchema = z.object({\n timeFrom: z.string().nullable(),\n timeTo: z.string().nullable(),\n segments: z.array(McpSegmentSchema),\n});\nexport type McpParagraph = z.infer<typeof McpParagraphSchema>;\n\nexport const McpTranscriptSchema = z.object({\n noteGuid: z.string(),\n title: z.string(),\n participants: z.array(z.string()),\n createdAt: z.string(),\n recordingDurationSeconds: z.number(),\n paragraphs: z.array(McpParagraphSchema),\n});\nexport type McpTranscript = z.infer<typeof McpTranscriptSchema>;\n\nexport const PageCursorResponseSchema = <T extends z.ZodTypeAny>(item: T) =>\n z.object({\n content: z.array(item),\n nextCursor: z.string().nullable(),\n });\n\nexport const SimpleListResponseSchema = <T extends z.ZodTypeAny>(item: T) =>\n z.object({\n content: z.array(item),\n });\n\nexport const ApiErrorSchema = z.object({\n error: z.object({\n code: z.number(),\n errorType: z.string(),\n message: z.string(),\n detail: z.string().nullable().optional(),\n }),\n});\nexport type ApiError = z.infer<typeof ApiErrorSchema>;\n","import { TiroError, ExitCode } from \"../error.ts\";\n\nconst RELATIVE_RE = /^(\\d+)([smhdw])$/i;\nconst UNIT_MS: Record<string, number> = {\n s: 1000,\n m: 60_000,\n h: 3_600_000,\n d: 86_400_000,\n w: 604_800_000,\n};\n\nexport function parseDate(input: string): string {\n const trimmed = input.trim();\n\n const rel = trimmed.match(RELATIVE_RE);\n if (rel) {\n const num = parseInt(rel[1] ?? \"\", 10);\n const unit = (rel[2] ?? \"\").toLowerCase();\n const factor = UNIT_MS[unit];\n if (!factor || !Number.isFinite(num)) {\n throw invalidDate(input);\n }\n return new Date(Date.now() - num * factor).toISOString();\n }\n\n const d = new Date(trimmed);\n if (Number.isNaN(d.getTime())) throw invalidDate(input);\n return d.toISOString();\n}\n\nfunction invalidDate(input: string): TiroError {\n return new TiroError(\n {\n code: \"invalid_date\",\n message: `Invalid date: \"${input}\". Use ISO-8601 (e.g. 2026-04-01T10:00:00Z) or relative (e.g. 7d, 24h, 30m).`,\n errorType: \"bad_request\",\n },\n ExitCode.Usage,\n );\n}\n","export interface FilterableNote {\n title?: string | null;\n sourceType?: string | null;\n}\n\nconst PLACEHOLDER_TITLE = \"Untitled\";\nconst PLACEHOLDER_SOURCE_TYPES = new Set<string>([\"onboarding\"]);\n\nexport function isVisibleNote(note: FilterableNote): boolean {\n if (note.title === PLACEHOLDER_TITLE) return false;\n if (note.sourceType !== null && note.sourceType !== undefined && PLACEHOLDER_SOURCE_TYPES.has(note.sourceType)) {\n return false;\n }\n return true;\n}\n","import { Command } from \"commander\";\nimport { createApiClient } from \"../../lib/api/client.ts\";\nimport { NoteSchema, PageCursorResponseSchema } from \"../../lib/api/types.ts\";\nimport { printNdjson } from \"../../lib/output/print.ts\";\nimport { resolveOutputMode, color } from \"../../lib/output/tty.ts\";\nimport { parseDate } from \"../../lib/util/parseDate.ts\";\nimport { isVisibleNote } from \"../../lib/util/noteFilter.ts\";\nimport { TiroError, ExitCode } from \"../../lib/error.ts\";\n\ninterface SearchOptions {\n keyword?: string;\n folder?: string;\n since?: string;\n until?: string;\n limit?: string;\n cursor?: string;\n includeUntitled?: boolean;\n hostname?: string;\n json?: boolean;\n pretty?: boolean;\n noColor?: boolean;\n quiet?: boolean;\n}\n\nconst SearchResponseSchema = PageCursorResponseSchema(NoteSchema).passthrough();\n\nconst DEFAULT_PAGE_SIZE = 100;\nconst MAX_PAGE_SIZE = 1000;\n\nconst HELP_AFTER = `\nExamples:\n tiro notes search \"Q3 Planning\"\n tiro notes search \"Acme Corp\" --since 7d --json\n tiro notes search \"release\" --since 2026-04-01 --until 2026-05-01\n\nKeyword matching:\n Full-text against note title + paragraph content via OpenSearch.\n Case-insensitive. Multi-word keywords are tokenized — \"OKR planning\"\n matches notes containing both terms. The deep search variant (this\n command) hydrates each result with its primary documents (one-pager,\n custom) so an MCP/LLM client can read content alongside metadata in\n one call.\n\nNote: placeholder notes (title='Untitled' or sourceType='onboarding') are\nfiltered out by default. Pass --include-untitled to surface them.\n`;\n\nexport function registerNotesSearch(parent: Command): void {\n parent\n .command(\"search [keyword]\")\n .description(\"Deep keyword search — returns notes hydrated with their primary documents.\")\n .option(\n \"--keyword <text>\",\n 'Alternative to positional keyword (e.g. --keyword \"Q3 Planning\")',\n )\n .option(\"--folder <id>\", \"Restrict hits to a folder and its descendants\")\n .option(\n \"--since <date>\",\n \"Inclusive lower bound on createdAt (ISO-8601 or relative: 7d, 24h, 30m)\",\n )\n .option(\"--until <date>\", \"Exclusive upper bound on createdAt\")\n .option(\n \"--limit <n>\",\n `Max results per page (default ${DEFAULT_PAGE_SIZE}, max ${MAX_PAGE_SIZE})`,\n )\n .option(\n \"--cursor <token>\",\n \"Continue a previous page (reserved — backend currently always null)\",\n )\n .option(\n \"--include-untitled\",\n \"Include placeholder notes. Default: hidden\",\n false,\n )\n .addHelpText(\"after\", HELP_AFTER)\n .action(async (positional: string | undefined, opts: SearchOptions, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<SearchOptions>();\n\n const keyword = (positional ?? opts.keyword ?? \"\").trim();\n if (!keyword) {\n throw new TiroError(\n {\n code: \"missing_keyword\",\n message: \"search requires a keyword (positional or --keyword).\",\n errorType: \"bad_request\",\n suggestion: 'tiro notes search \"OKR\"',\n },\n ExitCode.Usage,\n );\n }\n\n const filter: Record<string, string> = {};\n if (opts.folder) filter[\"folderId\"] = opts.folder;\n if (opts.since) filter[\"createdAtFrom\"] = parseDate(opts.since);\n if (opts.until) filter[\"createdAtTo\"] = parseDate(opts.until);\n\n const pagination: Record<string, string | number> = {};\n const size = clampLimit(opts.limit);\n if (size !== undefined) pagination[\"size\"] = size;\n if (opts.cursor) pagination[\"cursor\"] = opts.cursor;\n\n const body: Record<string, unknown> = { keyword };\n if (Object.keys(filter).length > 0) body[\"filter\"] = filter;\n if (Object.keys(pagination).length > 0) body[\"pagination\"] = pagination;\n\n const client = createApiClient({\n ...(globalOpts.hostname !== undefined && { hostnameOverride: globalOpts.hostname }),\n });\n\n const res = await client.postJson(\n \"/v1/external/notes/search\",\n SearchResponseSchema,\n body,\n );\n const visible = opts.includeUntitled === true ? res.content : res.content.filter(isVisibleNote);\n\n const mode = resolveOutputMode(globalOpts);\n if (mode === \"json\") {\n for (const note of visible) printNdjson(note);\n if (res.nextCursor) printNdjson({ _cursor: res.nextCursor });\n } else {\n printPretty(visible, res.nextCursor, globalOpts);\n }\n });\n}\n\nfunction clampLimit(raw?: string): number | undefined {\n if (!raw) return undefined;\n const n = parseInt(raw, 10);\n if (!Number.isFinite(n) || n <= 0) return DEFAULT_PAGE_SIZE;\n return Math.min(n, MAX_PAGE_SIZE);\n}\n\ninterface NoteListItem {\n guid: string;\n title: string;\n createdAt: string;\n}\n\nfunction printPretty(\n notes: NoteListItem[],\n nextCursor: string | null,\n opts: { noColor?: boolean },\n): void {\n if (notes.length === 0) {\n process.stdout.write(`${color(\"(no matches)\", \"gray\", opts)}\\n`);\n return;\n }\n for (const n of notes) {\n const date = n.createdAt.slice(0, 10);\n process.stdout.write(\n `${color(date, \"gray\", opts)} ${color(n.guid, \"dim\", opts)} ${n.title}\\n`,\n );\n }\n if (nextCursor) {\n process.stdout.write(\n `${color(`\\n next: --cursor ${nextCursor}`, \"gray\", opts)}\\n`,\n );\n }\n}\n","import { Command } from \"commander\";\nimport { createApiClient } from \"../../lib/api/client.ts\";\nimport {\n NoteSchema,\n ParagraphSchema,\n SimpleListResponseSchema,\n PageCursorResponseSchema,\n type Paragraph,\n} from \"../../lib/api/types.ts\";\nimport { writeFileAtomic } from \"../../lib/output/file.ts\";\nimport { formatNote, type FileFormat } from \"../../lib/output/format.ts\";\nimport { paragraphsToMcp } from \"../../lib/output/transcript.ts\";\nimport { printOutput } from \"../../lib/output/print.ts\";\nimport { resolveOutputMode, color } from \"../../lib/output/tty.ts\";\nimport { TiroError, ExitCode } from \"../../lib/error.ts\";\n\ninterface GetOptions {\n output?: string;\n format?: string;\n include?: string;\n force?: boolean;\n hostname?: string;\n json?: boolean;\n pretty?: boolean;\n noColor?: boolean;\n quiet?: boolean;\n}\n\nconst ALLOWED_INCLUDES = new Set([\"transcript\"]);\n\nconst ParagraphsListSchema = SimpleListResponseSchema(ParagraphSchema);\nconst ParagraphsCursorSchema = PageCursorResponseSchema(ParagraphSchema);\n\nexport function registerNotesGet(parent: Command): void {\n parent\n .command(\"get <guid>\")\n .description(\"Get a single note. Outputs to stdout, or saves to a file with --output.\")\n .option(\"--output <path>\", \"Write to file (stdout becomes a single metadata line)\")\n .option(\n \"--format <md|json|txt>\",\n \"Output format (default: md for TTY, json when piped)\",\n )\n .option(\n \"--include <items>\",\n \"Comma-separated extras (v0.2 supports: transcript)\",\n \"\",\n )\n .option(\"--force\", \"Overwrite existing file at --output path\")\n .addHelpText(\"after\", `\nExamples:\n tiro notes get <guid> # markdown to stdout\n tiro notes get <guid> --include transcript # add speaker-attributed paragraphs\n tiro notes get <guid> --output ./meeting.md --include transcript\n tiro notes get <guid> --format json # JSON to stdout\n\nTip for agents: prefer --output <path>. The actual content goes to disk\nand stdout collapses to a single metadata line, keeping your context\nwindow light.\n`)\n .action(async (guid: string, opts: GetOptions, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<GetOptions>();\n\n const includes = parseIncludes(opts.include);\n validateIncludes(includes);\n const format = pickFormat(opts.format, opts.output);\n\n const client = createApiClient({\n ...(globalOpts.hostname !== undefined && { hostnameOverride: globalOpts.hostname }),\n });\n\n const note = await client.getJson(`/v1/external/notes/${guid}`, NoteSchema);\n\n let paragraphs: Paragraph[] | undefined;\n if (includes.has(\"transcript\") || format === \"txt\") {\n paragraphs = await fetchAllParagraphs(client, guid);\n }\n\n const content = formatNote(note, format, {\n includeTranscript: includes.has(\"transcript\"),\n ...(paragraphs !== undefined && { paragraphs }),\n });\n\n if (opts.output) {\n const result = await writeFileAtomic(opts.output, content, {\n ...(opts.force === true && { force: true }),\n });\n printOutput(\n {\n ok: true,\n data: {\n saved: result.path,\n size: result.size,\n format,\n guid: note.guid,\n title: note.title,\n },\n },\n globalOpts,\n );\n return;\n }\n\n const mode = resolveOutputMode(globalOpts);\n if (mode === \"json\" && format !== \"json\") {\n printOutput(\n {\n ok: true,\n data: {\n ...note,\n ...(paragraphs && { transcript: { paragraphs: paragraphsToMcp(paragraphs) } }),\n },\n },\n globalOpts,\n );\n } else if (format === \"json\") {\n process.stdout.write(content);\n } else {\n if (process.stdout.isTTY && format === \"txt\") {\n process.stdout.write(`${color(`# ${note.title}`, \"bold\", globalOpts)}\\n\\n`);\n }\n process.stdout.write(content);\n }\n });\n}\n\nasync function fetchAllParagraphs(\n client: ReturnType<typeof createApiClient>,\n guid: string,\n): Promise<Paragraph[]> {\n const first = await client.getJson(\n `/v1/external/notes/${guid}/paragraphs`,\n ParagraphsCursorSchema.or(ParagraphsListSchema),\n );\n const all: Paragraph[] = [...first.content];\n if (\"nextCursor\" in first) {\n let cursor = first.nextCursor;\n while (cursor) {\n const next = await client.getJson(\n `/v1/external/notes/${guid}/paragraphs`,\n ParagraphsCursorSchema,\n { cursor },\n );\n all.push(...next.content);\n cursor = next.nextCursor;\n }\n }\n return all;\n}\n\nfunction parseIncludes(raw?: string): Set<string> {\n if (!raw) return new Set();\n return new Set(\n raw\n .split(\",\")\n .map((s) => s.trim().toLowerCase())\n .filter((s) => s.length > 0),\n );\n}\n\nfunction validateIncludes(includes: Set<string>): void {\n for (const inc of includes) {\n if (!ALLOWED_INCLUDES.has(inc)) {\n throw new TiroError(\n {\n code: \"invalid_include\",\n message: `Invalid --include \"${inc}\". v0.2.0 supports: transcript.`,\n errorType: \"bad_request\",\n suggestion: \"Use --include transcript\",\n },\n ExitCode.Usage,\n );\n }\n }\n}\n\nfunction pickFormat(format: string | undefined, output: string | undefined): FileFormat {\n const allowed: FileFormat[] = [\"md\", \"json\", \"txt\"];\n if (format) {\n const f = format.toLowerCase() as FileFormat;\n if (!allowed.includes(f)) {\n throw new TiroError(\n {\n code: \"invalid_format\",\n message: `Invalid --format \"${format}\". Allowed: md, json, txt.`,\n errorType: \"bad_request\",\n },\n ExitCode.Usage,\n );\n }\n return f;\n }\n if (output) {\n if (output.endsWith(\".json\")) return \"json\";\n if (output.endsWith(\".txt\")) return \"txt\";\n return \"md\";\n }\n return process.stdout.isTTY ? \"md\" : \"json\";\n}\n","import { mkdir, rename, stat, writeFile, access } from \"node:fs/promises\";\nimport { dirname, resolve } from \"node:path\";\nimport { TiroError, ExitCode } from \"../error.ts\";\n\nexport interface WriteResult {\n path: string;\n size: number;\n}\n\nexport async function writeFileAtomic(\n filepath: string,\n content: string,\n opts: { force?: boolean } = {},\n): Promise<WriteResult> {\n const absPath = resolve(filepath);\n await mkdir(dirname(absPath), { recursive: true });\n\n if (!opts.force) {\n const exists = await fileExists(absPath);\n if (exists) {\n throw new TiroError(\n {\n code: \"file_exists\",\n message: `File already exists: ${absPath}`,\n errorType: \"conflict\",\n suggestion: \"Use --force to overwrite, or pick a different --output.\",\n },\n ExitCode.Generic,\n );\n }\n }\n\n const tmp = `${absPath}.tmp.${process.pid}.${Date.now()}`;\n await writeFile(tmp, content, \"utf8\");\n await rename(tmp, absPath);\n const s = await stat(absPath);\n return { path: absPath, size: s.size };\n}\n\nasync function fileExists(p: string): Promise<boolean> {\n try {\n await access(p);\n return true;\n } catch {\n return false;\n }\n}\n","import type {\n McpParagraph,\n McpSegment,\n McpTranscript,\n Note,\n Paragraph,\n} from \"../api/types.ts\";\n\nexport function buildMcpTranscript(note: Note, paragraphs: Paragraph[]): McpTranscript {\n return {\n noteGuid: note.guid,\n title: note.title,\n participants:\n note.participants\n ?.map((p) => p.name || p.email || \"\")\n .filter((s): s is string => typeof s === \"string\" && s.length > 0) ?? [],\n createdAt: note.createdAt,\n recordingDurationSeconds: note.recordingDurationSeconds,\n paragraphs: paragraphsToMcp(paragraphs),\n };\n}\n\nexport function paragraphsToMcp(paragraphs: Paragraph[]): McpParagraph[] {\n return paragraphs\n .map((p) => ({\n timeFrom: p.timeFrom ?? null,\n timeTo: p.timeTo ?? null,\n segments: paragraphToSegments(p),\n }))\n .filter((p) => p.segments.length > 0);\n}\n\nfunction paragraphToSegments(p: Paragraph): McpSegment[] {\n const ds = p.diarizedSegments;\n if (ds && ds.length > 0) {\n return ds\n .map((s) => ({\n content: stripHtml(s.content),\n speaker: {\n label: s.speaker.label,\n name: s.speaker.personName ? stripHtml(s.speaker.personName) : null,\n },\n }))\n .filter((s) => s.content.length > 0);\n }\n const plain = stripHtml(p.transcript?.content ?? \"\");\n return plain ? [{ content: plain, speaker: null }] : [];\n}\n\nexport function renderTranscriptJson(t: McpTranscript): string {\n return `${JSON.stringify(t, null, 2)}\\n`;\n}\n\nexport function renderTranscriptMarkdown(t: McpTranscript): string {\n const anchor = anchorTime(t);\n const lines: string[] = [];\n lines.push(`# ${t.title}`, \"\");\n\n if (t.participants.length > 0) {\n lines.push(`**Participants**: ${t.participants.join(\", \")}`, \"\");\n }\n\n lines.push(\"## Transcript\", \"\");\n for (const p of t.paragraphs) {\n const ts = elapsed(p.timeFrom, anchor);\n for (const s of p.segments) {\n const who = s.speaker?.name ?? s.speaker?.label ?? \"Unknown\";\n const tag = ts ? `${who}, ${ts}` : who;\n lines.push(`**[${tag}]** ${s.content}`);\n }\n lines.push(\"\");\n }\n\n return `${lines.join(\"\\n\").trimEnd()}\\n`;\n}\n\nexport function renderTranscriptText(t: McpTranscript): string {\n const lines: string[] = [];\n for (const p of t.paragraphs) {\n for (const s of p.segments) {\n const who = s.speaker?.name ?? s.speaker?.label ?? \"Unknown\";\n lines.push(`[${who}] ${s.content}`);\n }\n }\n return `${lines.join(\"\\n\")}\\n`;\n}\n\nfunction anchorTime(t: McpTranscript): string | null {\n for (const p of t.paragraphs) {\n if (p.timeFrom) return p.timeFrom;\n }\n return null;\n}\n\nfunction elapsed(currentIso: string | null, anchorIso: string | null): string {\n if (!currentIso || !anchorIso) return \"\";\n const cur = Date.parse(currentIso);\n const anc = Date.parse(anchorIso);\n if (!Number.isFinite(cur) || !Number.isFinite(anc)) return \"\";\n const seconds = Math.max(0, Math.floor((cur - anc) / 1000));\n const h = Math.floor(seconds / 3600);\n const m = Math.floor((seconds % 3600) / 60);\n const s = seconds % 60;\n if (h > 0) return `${pad(h)}:${pad(m)}:${pad(s)}`;\n return `${pad(m)}:${pad(s)}`;\n}\n\nfunction pad(n: number): string {\n return n.toString().padStart(2, \"0\");\n}\n\nfunction stripHtml(s: string): string {\n return s\n .replace(/<[^>]*>/g, \"\")\n .replace(/ /g, \" \")\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .trim();\n}\n","import type { Note, Paragraph } from \"../api/types.ts\";\nimport {\n buildMcpTranscript,\n paragraphsToMcp,\n renderTranscriptJson,\n renderTranscriptMarkdown,\n renderTranscriptText,\n} from \"./transcript.ts\";\n\nexport type FileFormat = \"md\" | \"json\" | \"txt\";\n\nexport interface FormatOptions {\n includeTranscript?: boolean;\n paragraphs?: Paragraph[];\n}\n\nexport function formatNote(\n note: Note,\n format: FileFormat,\n opts: FormatOptions = {},\n): string {\n switch (format) {\n case \"md\":\n return formatMarkdown(note, opts);\n case \"json\":\n return formatJson(note, opts);\n case \"txt\":\n return formatText(note, opts);\n }\n}\n\nfunction formatMarkdown(note: Note, opts: FormatOptions): string {\n const fm = [\n \"---\",\n `guid: ${escapeYaml(note.guid)}`,\n `title: ${escapeYaml(note.title)}`,\n `createdAt: ${note.createdAt}`,\n `updatedAt: ${note.updatedAt}`,\n `sourceType: ${note.sourceType}`,\n `recordingDurationSeconds: ${note.recordingDurationSeconds}`,\n `webUrl: ${note.webUrl}`,\n ];\n if (note.recordingStartAt) fm.push(`recordingStartAt: ${note.recordingStartAt}`);\n if (note.recordingEndAt) fm.push(`recordingEndAt: ${note.recordingEndAt}`);\n fm.push(\"---\", \"\");\n\n const parts: string[] = [fm.join(\"\\n\"), `# ${note.title}`, \"\"];\n\n if (note.participants && note.participants.length > 0) {\n parts.push(\"## Participants\", \"\");\n for (const p of note.participants) {\n const name = p.name ?? \"(no name)\";\n const email = p.email ? ` <${p.email}>` : \"\";\n parts.push(`- ${name}${email}`);\n }\n parts.push(\"\");\n }\n\n if (opts.includeTranscript && opts.paragraphs && opts.paragraphs.length > 0) {\n const mcp = buildMcpTranscript(note, opts.paragraphs);\n const transcriptBody = renderTranscriptMarkdown(mcp);\n const startsWithHeader = transcriptBody.startsWith(`# ${note.title}`);\n const trimmed = startsWithHeader\n ? transcriptBody.slice(transcriptBody.indexOf(\"\\n\") + 1)\n : transcriptBody;\n parts.push(trimmed.replace(/^\\s*\\n+/, \"\"));\n }\n\n return `${parts.join(\"\\n\").trimEnd()}\\n`;\n}\n\nfunction formatJson(note: Note, opts: FormatOptions): string {\n const out: Record<string, unknown> = { ...note };\n if (opts.includeTranscript && opts.paragraphs) {\n out[\"transcript\"] = { paragraphs: paragraphsToMcp(opts.paragraphs) };\n }\n return `${JSON.stringify(out, null, 2)}\\n`;\n}\n\nfunction formatText(note: Note, opts: FormatOptions): string {\n if (!opts.paragraphs || opts.paragraphs.length === 0) {\n return `${note.title}\\n${note.webUrl}\\n`;\n }\n const mcp = buildMcpTranscript(note, opts.paragraphs);\n return renderTranscriptText(mcp);\n}\n\nfunction escapeYaml(s: string): string {\n if (/[:#\\n\"']/.test(s)) {\n return JSON.stringify(s);\n }\n return s;\n}\n\nexport {\n buildMcpTranscript,\n renderTranscriptJson,\n renderTranscriptMarkdown,\n renderTranscriptText,\n};\n","import { Command } from \"commander\";\nimport { createApiClient } from \"../../lib/api/client.ts\";\nimport {\n ParagraphSchema,\n PageCursorResponseSchema,\n SimpleListResponseSchema,\n NoteSchema,\n type Paragraph,\n} from \"../../lib/api/types.ts\";\nimport { writeFileAtomic } from \"../../lib/output/file.ts\";\nimport {\n buildMcpTranscript,\n renderTranscriptJson,\n renderTranscriptMarkdown,\n renderTranscriptText,\n} from \"../../lib/output/transcript.ts\";\nimport { type FileFormat } from \"../../lib/output/format.ts\";\nimport { printOutput } from \"../../lib/output/print.ts\";\nimport { resolveOutputMode } from \"../../lib/output/tty.ts\";\nimport { TiroError, ExitCode } from \"../../lib/error.ts\";\n\ninterface TranscriptOptions {\n output?: string;\n format?: string;\n force?: boolean;\n hostname?: string;\n json?: boolean;\n pretty?: boolean;\n noColor?: boolean;\n quiet?: boolean;\n}\n\nconst ParagraphsListSchema = SimpleListResponseSchema(ParagraphSchema);\nconst ParagraphsCursorSchema = PageCursorResponseSchema(ParagraphSchema);\n\nexport function registerNotesTranscript(parent: Command): void {\n parent\n .command(\"transcript <guid>\")\n .description(\n \"Get the full transcript of a note as speaker-attributed paragraphs.\\n\" +\n \"JSON output matches MCP get_note_transcript shape exactly.\",\n )\n .option(\"--output <path>\", \"Write to file (stdout = single metadata line)\")\n .option(\n \"--format <md|json|txt>\",\n \"Output format (default: md if TTY, txt when piped; json mirrors MCP)\",\n )\n .option(\"--force\", \"Overwrite existing file at --output path\")\n .addHelpText(\"after\", `\nExamples:\n tiro notes transcript <guid> # md in TTY, txt in pipe\n tiro notes transcript <guid> --format md --output ./t.md\n tiro notes transcript <guid> --format json # MCP-shape JSON\n tiro notes transcript <guid> --format txt --output ./embed.txt\n\nThe --format json output is byte-for-byte identical to MCP's\nget_note_transcript so agents can swap surfaces without changing parsers.\n`)\n .action(async (guid: string, opts: TranscriptOptions, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<TranscriptOptions>();\n const format = pickFormat(opts.format, opts.output, globalOpts);\n\n const client = createApiClient({\n ...(globalOpts.hostname !== undefined && { hostnameOverride: globalOpts.hostname }),\n });\n\n const note = await client.getJson(`/v1/external/notes/${guid}`, NoteSchema);\n const paragraphs = await fetchAllParagraphs(client, guid);\n const mcp = buildMcpTranscript(note, paragraphs);\n\n const content =\n format === \"json\"\n ? renderTranscriptJson(mcp)\n : format === \"md\"\n ? renderTranscriptMarkdown(mcp)\n : renderTranscriptText(mcp);\n\n if (opts.output) {\n const result = await writeFileAtomic(opts.output, content, {\n ...(opts.force === true && { force: true }),\n });\n printOutput(\n {\n ok: true,\n data: {\n saved: result.path,\n size: result.size,\n format,\n guid: note.guid,\n paragraphCount: mcp.paragraphs.length,\n segmentCount: mcp.paragraphs.reduce((sum, p) => sum + p.segments.length, 0),\n },\n },\n globalOpts,\n );\n return;\n }\n\n const mode = resolveOutputMode(globalOpts);\n if (mode === \"json\" && format !== \"json\") {\n printOutput({ ok: true, data: mcp }, globalOpts);\n } else {\n process.stdout.write(content);\n }\n });\n}\n\nasync function fetchAllParagraphs(\n client: ReturnType<typeof createApiClient>,\n guid: string,\n): Promise<Paragraph[]> {\n const first = await client.getJson(\n `/v1/external/notes/${guid}/paragraphs`,\n ParagraphsCursorSchema.or(ParagraphsListSchema),\n );\n const all: Paragraph[] = [...first.content];\n if (\"nextCursor\" in first) {\n let cursor = first.nextCursor;\n while (cursor) {\n const next = await client.getJson(\n `/v1/external/notes/${guid}/paragraphs`,\n ParagraphsCursorSchema,\n { cursor },\n );\n all.push(...next.content);\n cursor = next.nextCursor;\n }\n }\n return all;\n}\n\nfunction pickFormat(\n format: string | undefined,\n output: string | undefined,\n globalOpts: { json?: boolean; pretty?: boolean },\n): FileFormat {\n const allowed: FileFormat[] = [\"md\", \"json\", \"txt\"];\n if (format) {\n const f = format.toLowerCase() as FileFormat;\n if (!allowed.includes(f)) {\n throw new TiroError(\n {\n code: \"invalid_format\",\n message: `Invalid --format \"${format}\". Allowed: md, json, txt.`,\n errorType: \"bad_request\",\n },\n ExitCode.Usage,\n );\n }\n return f;\n }\n if (output) {\n if (output.endsWith(\".json\")) return \"json\";\n if (output.endsWith(\".md\")) return \"md\";\n if (output.endsWith(\".txt\")) return \"txt\";\n return \"md\";\n }\n if (globalOpts.json) return \"json\";\n if (globalOpts.pretty) return \"md\";\n return process.stdout.isTTY ? \"md\" : \"txt\";\n}\n","// update-notifier@7 ships no type definitions. We declare a minimal local\n// surface for the bits we use — runtime is the real authority.\n\nimport updateNotifier from \"update-notifier\";\nimport { readFile } from \"node:fs/promises\";\nimport { fileURLToPath } from \"node:url\";\nimport { dirname, resolve } from \"node:path\";\n\ninterface UpdateInfo {\n current: string;\n latest: string;\n type?: string;\n name?: string;\n}\n\ninterface NotifyOptions {\n isGlobal?: boolean;\n defer?: boolean;\n message?: string;\n boxenOptions?: Record<string, unknown>;\n}\n\nexport interface MinimalNotifier {\n update?: UpdateInfo | null | undefined;\n notify(options?: NotifyOptions): unknown;\n}\n\ninterface NotifierFactory {\n (options: {\n pkg: { name: string; version: string };\n updateCheckInterval?: number;\n shouldNotifyInNpmScript?: boolean;\n }): MinimalNotifier;\n}\n\nconst HERE = dirname(fileURLToPath(import.meta.url));\nconst CANDIDATE_PATHS = [\n resolve(HERE, \"../../package.json\"),\n resolve(HERE, \"../../../package.json\"),\n];\n\nconst ONE_DAY_MS = 24 * 60 * 60 * 1000;\n\ninterface CliPackage {\n name: string;\n version: string;\n}\n\nexport async function startUpdateCheck(): Promise<MinimalNotifier | null> {\n if (process.env[\"NO_UPDATE_NOTIFIER\"] === \"1\") return null;\n if (process.env[\"CI\"]) return null;\n if (process.stdout.isTTY !== true) return null;\n\n const pkg = await loadPkg();\n if (!pkg) return null;\n\n try {\n const factory = updateNotifier as unknown as NotifierFactory;\n return factory({\n pkg,\n updateCheckInterval: ONE_DAY_MS,\n shouldNotifyInNpmScript: false,\n });\n } catch {\n return null;\n }\n}\n\nexport function emitUpdateBanner(notifier: MinimalNotifier | null): void {\n if (!notifier) return;\n if (!notifier.update) return;\n\n notifier.notify({\n isGlobal: true,\n defer: false,\n message:\n \"Update available {currentVersion} \\u2192 {latestVersion}\\n\" +\n \"Run npm install -g {packageName} to update\\n\\n\" +\n \"Changelog: https://www.npmjs.com/package/{packageName}?activeTab=versions\",\n });\n}\n\nasync function loadPkg(): Promise<CliPackage | null> {\n for (const path of CANDIDATE_PATHS) {\n try {\n const raw = await readFile(path, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<CliPackage>;\n if (\n typeof parsed.name === \"string\" &&\n typeof parsed.version === \"string\" &&\n parsed.name.length > 0 &&\n parsed.version.length > 0\n ) {\n return { name: parsed.name, version: parsed.version };\n }\n } catch {\n // try next candidate\n }\n }\n return null;\n}\n"],"mappings":"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","names":["Command","resolve","z","DEFAULT_PAGE_SIZE","MAX_PAGE_SIZE","HELP_AFTER","clampLimit","printPretty","ParagraphsListSchema","ParagraphsCursorSchema","pickFormat","fetchAllParagraphs","dirname","resolve","Command"]}
|