@cryer/star-cli 0.3.8 → 0.3.9

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/dist/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/main.tsx","../src/cli/print-json.ts","../src/config/loader.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { defaultAgentTasks } from \"./agent/agent-tasks\";\nimport { AgentLoop } from \"./agent/loop\";\nimport { formatTokens } from \"./cli/cost\";\nimport { formatStreamError } from \"./cli/format\";\nimport { MAX_IMAGE_BYTES, imageMimeType, readImageInput, resolveMentions } from \"./cli/mentions\";\nimport { UsageTracker, eventToJsonLine } from \"./cli/print-json\";\nimport { SYSTEM_PROMPT } from \"./cli/system-prompt\";\nimport { loadConfigSync } from \"./config/loader\";\nimport { type StarConfig, contextWindowTokens } from \"./config/schema\";\nimport { type CoreMessage, type ImageInput, reconcileToolCalls } from \"./core/messages\";\nimport { createModel, reasoningEffortMetadata } from \"./llm/provider\";\nimport { resolveModelConfig } from \"./llm/registry\";\nimport { loadSessionSnapshots } from \"./session/checkpoints\";\nimport { clearSessions } from \"./session/clear\";\nimport {\n findLatestSession,\n formatSessionEntries,\n listSessionEntries,\n resolveSessionId,\n} from \"./session/list\";\nimport { type SessionMeta, SessionStore } from \"./session/store\";\nimport { defaultTaskManager } from \"./tasks/manager\";\nimport { createDefaultRegistry } from \"./tools\";\nimport { hydrateSnapshots } from \"./tools/fs/snapshots\";\nimport { loadTodos } from \"./tools/todo\";\nimport { VERSION } from \"./version\";\n\nasync function createLoop(\n config: StarConfig,\n modelName: string,\n cwd: string,\n sessionStore: SessionStore | null,\n) {\n const model = createModel(config, modelName);\n const registry = createDefaultRegistry();\n const modelConfig = resolveModelConfig(config, modelName);\n return new AgentLoop({\n model,\n registry,\n config,\n cwd,\n system: SYSTEM_PROMPT,\n sessionStore,\n contextMaxTokens: contextWindowTokens(config, modelName),\n providerMetadata: reasoningEffortMetadata(config, modelName),\n temperature: modelConfig.temperature,\n streamIdleTimeoutSec: modelConfig.streamIdleTimeoutSec,\n streamFirstChunkTimeoutSec: modelConfig.streamFirstChunkTimeoutSec,\n });\n}\n\nasync function printMode(\n loop: AgentLoop,\n prompt: string,\n cwd: string,\n json: boolean,\n imagePaths: string[],\n sessionStore: SessionStore | null,\n): Promise<number> {\n const flagImages: ImageInput[] = [];\n for (const imagePath of imagePaths) {\n if (!imageMimeType(imagePath)) {\n process.stderr.write(\n `[error] unsupported image type: ${imagePath} (supported: png, jpg, jpeg, gif, webp)\\n`,\n );\n return 1;\n }\n const image = await readImageInput(imagePath, cwd);\n if (!image) {\n process.stderr.write(\n `[error] cannot read image: ${imagePath} (missing, unreadable, or larger than ${MAX_IMAGE_BYTES / (1024 * 1024)}MB)\\n`,\n );\n return 1;\n }\n flagImages.push(image);\n }\n const controller = new AbortController();\n process.on(\"SIGINT\", () => controller.abort());\n loop.onHookWarning = (message) => {\n process.stderr.write(`[hook] ${message}\\n`);\n };\n const resolved = await resolveMentions(prompt, cwd);\n if (resolved.attached.length > 0) {\n process.stderr.write(`[attached] ${resolved.attached.join(\", \")}\\n`);\n }\n for (const skip of resolved.skipped) {\n process.stderr.write(`[skipped] @${skip.path}: ${skip.reason}\\n`);\n }\n const images = [...flagImages, ...resolved.images];\n const input: string | { text: string; images: ImageInput[] } =\n images.length > 0 ? { text: resolved.input, images } : resolved.input;\n const usage = new UsageTracker();\n let exitCode = 0;\n try {\n for await (const event of loop.stream(input, controller.signal, {\n persistAs: prompt,\n })) {\n if (json) {\n const line = eventToJsonLine(event);\n if (line) process.stdout.write(`${line}\\n`);\n }\n switch (event.type) {\n case \"text-delta\":\n if (!json) process.stdout.write(event.text);\n break;\n case \"reasoning\":\n break;\n case \"tool-call\":\n if (!json) process.stderr.write(`\\n[tool] ${event.name} ${JSON.stringify(event.args)}\\n`);\n break;\n case \"tool-result\": {\n if (!json) {\n const preview =\n event.content.length > 500\n ? `${event.content.slice(0, 500)}... (truncated)`\n : event.content;\n process.stderr.write(`[result] ${event.isError ? \"ERROR: \" : \"\"}${preview}\\n`);\n }\n break;\n }\n case \"finish\":\n usage.add(event.usage);\n // A resumed session (-c/-r -p) must accumulate this turn's usage,\n // same as the REPL does; plain print runs have no store.\n if (event.usage) {\n sessionStore?.addUsage(event.usage).catch(() => {});\n }\n break;\n case \"retry\": {\n if (!json) {\n const wait =\n event.delayMs !== undefined && event.delayMs >= 1000\n ? ` in ${Math.round(event.delayMs / 1000)}s`\n : \"\";\n process.stderr.write(\n `\\n[retry ${event.attempt}/${event.maxAttempts}${wait}] ${event.reason}\\n`,\n );\n }\n break;\n }\n case \"notice\":\n if (!json) process.stderr.write(`\\n[notice] ${event.message}\\n`);\n break;\n case \"error\":\n if (!json) process.stderr.write(`\\n[error] ${formatStreamError(event.error)}\\n`);\n exitCode = 1;\n break;\n }\n if (exitCode !== 0) break;\n }\n } catch (error) {\n if (!(error instanceof DOMException && error.name === \"AbortError\")) {\n const message = error instanceof Error ? formatStreamError(error) : String(error);\n process.stderr.write(`\\n[error] ${message}\\n`);\n exitCode = 1;\n }\n }\n const usageLine = usage.toJsonLine();\n if (usageLine) {\n if (json) {\n process.stdout.write(`${usageLine}\\n`);\n } else {\n const t = usage.totals;\n process.stderr.write(\n `[usage] ${t.requests} requests, ${formatTokens(t.promptTokens)} prompt + ${formatTokens(t.completionTokens)} completion = ${formatTokens(t.totalTokens)} tokens\\n`,\n );\n }\n }\n if (!json) process.stdout.write(\"\\n\");\n const killedShells = defaultTaskManager.cleanup();\n const killedAgents = defaultAgentTasks.cleanup();\n const stopped = killedShells.length + killedAgents.length;\n if (stopped > 0) {\n process.stderr.write(\n `[info] ${stopped} background task(s) were still running and have been stopped.\\n`,\n );\n }\n return exitCode;\n}\n\nconst program = new Command();\n\nprogram\n .name(\"star\")\n .description(\"Star CLI — an AI agent command-line interface\")\n .version(VERSION)\n .option(\"-m, --model <model>\", \"model to use\")\n .option(\"--permission-mode <mode>\", \"permission mode: ask | auto | readonly | yolo | plan\")\n .option(\"-p, --print <prompt>\", \"non-interactive print mode\")\n .option(\"--json\", \"output NDJSON events on stdout (print mode only)\")\n .option(\n \"--image <path>\",\n \"attach an image file (png/jpg/jpeg/gif/webp, max 5MB); repeatable\",\n (value: string, previous: string[]) => [...previous, value],\n [] as string[],\n )\n .option(\"-r, --resume [sessionId]\", \"resume a previous session (lists sessions when no id given)\")\n .option(\"-c, --continue\", \"continue the most recent session for the current directory\")\n .option(\n \"--clear-sessions [scope]\",\n \"delete stored sessions for the current directory ('all' deletes every session) and exit\",\n )\n .action(async (opts) => {\n const cwd = process.cwd();\n\n if (opts.json && opts.print === undefined) {\n console.error(\n '--json requires print mode: use star -p \"...\" --json (the interactive REPL does not support JSON output).',\n );\n process.exit(1);\n }\n\n if (opts.resume !== undefined && opts.continue) {\n console.error(\"Options --resume and --continue are mutually exclusive: pick one.\");\n process.exit(1);\n }\n\n if (opts.resume === true) {\n const entries = await listSessionEntries(cwd);\n if (entries.length === 0) {\n console.error(\"No sessions found for this directory.\");\n } else {\n console.log(formatSessionEntries(entries));\n }\n process.exit(0);\n }\n\n if (opts.clearSessions !== undefined) {\n const scope = opts.clearSessions;\n if (scope !== true && scope !== \"all\") {\n console.error(`Invalid scope: ${scope}. Use --clear-sessions or --clear-sessions all.`);\n process.exit(1);\n }\n const all = scope === \"all\";\n const removed = await clearSessions(all ? undefined : cwd);\n console.log(\n all\n ? `Deleted ${removed} session(s) across all directories.`\n : `Deleted ${removed} session(s) for this directory.`,\n );\n process.exit(0);\n }\n\n let config: StarConfig;\n try {\n config = loadConfigSync(cwd, { model: opts.model, permissionMode: opts.permissionMode });\n } catch (error) {\n console.error(error instanceof Error ? error.message : String(error));\n process.exit(1);\n }\n\n const modelName = opts.model ?? config.defaultModel;\n if (!modelName) {\n console.error(\n \"No model configured. Add one to ~/.star-cli/config.toml or pass --model.\\n\" +\n \"See README.md for configuration examples.\",\n );\n process.exit(1);\n }\n\n let sessionStore: SessionStore | null = null;\n let resumed: { meta: SessionMeta; messages: CoreMessage[] } | null = null;\n let resumeId: string | null = null;\n if (typeof opts.resume === \"string\") {\n resumeId = await resolveSessionId(opts.resume);\n if (!resumeId) {\n console.error(`Session not found: ${opts.resume}`);\n process.exit(1);\n }\n } else if (opts.continue) {\n const latest = await findLatestSession(cwd);\n if (latest) {\n resumeId = latest.id;\n } else {\n process.stderr.write(\"No previous session for this directory — starting a new session.\\n\");\n }\n }\n\n if (resumeId) {\n // Open the store once and read through it: resumeSession() would open a\n // second SessionStore instance on the same directory whose independent\n // meta cache could race this instance's writes.\n sessionStore = await SessionStore.open(resumeId);\n if (!sessionStore) {\n console.error(`Session not found: ${resumeId}`);\n process.exit(1);\n }\n const [meta, loaded] = await Promise.all([sessionStore.meta(), sessionStore.messages()]);\n const messages = reconcileToolCalls(loaded);\n if (messages.length !== loaded.length) {\n await sessionStore.replaceMessages(messages);\n }\n resumed = { meta, messages };\n } else if (!opts.print) {\n sessionStore = await SessionStore.create(cwd, modelName);\n }\n\n let loop: AgentLoop;\n try {\n loop = await createLoop(config, modelName, cwd, sessionStore);\n } catch (error) {\n console.error(error instanceof Error ? error.message : String(error));\n process.exit(1);\n }\n if (resumed) {\n await loop.loadMessages(resumed.messages);\n // Resuming explicitly continues the project: rehydrate its todo list\n // (fresh sessions leave it alone even when .star/todos.json exists).\n await loadTodos(cwd);\n if (sessionStore) {\n hydrateSnapshots(await loadSessionSnapshots(sessionStore.dir));\n }\n }\n\n if (opts.print) {\n // Let the loop drain instead of process.exit(): force-exiting on Windows\n // can hit a libuv assertion while undici keep-alive handles are closing.\n process.exitCode = await printMode(\n loop,\n opts.print,\n cwd,\n Boolean(opts.json),\n opts.image ?? [],\n sessionStore,\n );\n return;\n }\n\n // The REPL pulls in Ink and every interactive component (~0.4s of module\n // evaluation): load it only on the interactive path so -p, --version,\n // --clear-sessions and session listing stay cheap.\n const { renderRepl } = await import(\"./cli/repl\");\n renderRepl(loop, {\n model: modelName,\n permissionMode: config.permissionMode,\n config,\n cwd,\n sessionStore,\n initialMessages: resumed?.messages,\n initialUsage: resumed?.meta.usage,\n });\n });\n\nprogram.parse(process.argv);\n","import type { StreamEvent, TokenUsage } from \"../core/events\";\n\nexport function eventToJsonLine(event: StreamEvent): string | null {\n switch (event.type) {\n case \"finish\":\n return null;\n case \"error\":\n return JSON.stringify({ type: \"error\", error: { message: event.error.message } });\n default:\n return JSON.stringify(event);\n }\n}\n\nexport class UsageTracker {\n private requests = 0;\n private promptTokens = 0;\n private completionTokens = 0;\n private totalTokens = 0;\n\n add(usage?: TokenUsage): void {\n if (!usage) return;\n this.requests += 1;\n this.promptTokens += usage.promptTokens;\n this.completionTokens += usage.completionTokens;\n this.totalTokens += usage.totalTokens;\n }\n\n get totals(): TokenUsage & { requests: number } {\n return {\n requests: this.requests,\n promptTokens: this.promptTokens,\n completionTokens: this.completionTokens,\n totalTokens: this.totalTokens,\n };\n }\n\n toJsonLine(): string | null {\n if (this.requests === 0) return null;\n return JSON.stringify({\n type: \"usage\",\n requests: this.requests,\n promptTokens: this.promptTokens,\n completionTokens: this.completionTokens,\n totalTokens: this.totalTokens,\n });\n }\n}\n","import fs from \"node:fs\";\nimport { parse } from \"smol-toml\";\nimport { loadEnvFile } from \"./env\";\nimport { globalConfigPath, projectConfigPath } from \"./paths\";\nimport { type CliOverrides, ConfigSchema, type ModelConfig, type StarConfig } from \"./schema\";\n\nconst PartialConfigSchema = ConfigSchema.partial();\n\ntype PartialConfig = ReturnType<typeof PartialConfigSchema.parse>;\n\nfunction parseTomlFile(content: string, filePath: string): PartialConfig {\n let raw: unknown;\n try {\n raw = parse(content);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to parse TOML in ${filePath}: ${message}`);\n }\n const result = PartialConfigSchema.safeParse(raw);\n if (!result.success) {\n throw new Error(`Invalid config in ${filePath}: ${result.error.message}`);\n }\n return result.data;\n}\n\n// Keys a project-level .star/config.toml may set. Anything else (providers,\n// permissionMode, permissions, hooks, ...) stays global-only: a checked-out\n// repo must not be able to plant shell hooks, force yolo mode, or redirect\n// provider traffic to a key-harvesting endpoint.\nconst PROJECT_ALLOWED_KEYS = new Set([\n \"defaultModel\",\n \"models\",\n \"maxSteps\",\n \"contextMaxTokens\",\n \"compactThresholdTokens\",\n \"streamIdleTimeoutSec\",\n \"streamFirstChunkTimeoutSec\",\n \"streamMaxRetries\",\n \"maxAutoContinues\",\n \"contextCompaction\",\n \"sessionBudgetUsd\",\n \"notifyBell\",\n \"notifyBellThresholdSec\",\n \"doomLoopThreshold\",\n \"gitSnapshots\",\n]);\n\n// Safe ranges for the project-provided streaming knobs: a repo must not set\n// pathological values (sub-second idle timeouts, thousands of retries).\nconst PROJECT_STREAM_RANGES = {\n streamIdleTimeoutSec: { min: 5, max: 120 },\n streamFirstChunkTimeoutSec: { min: 30, max: 900 },\n streamMaxRetries: { min: 0, max: 10 },\n} as const;\n\n// 0 disables these protections, so a project may only tighten them, never\n// turn them off (handled at merge time via min()).\nconst PROJECT_PROTECTIVE_MIN_KEYS = new Set([\"maxSteps\", \"doomLoopThreshold\"]);\n\nfunction warnProject(filePath: string, message: string): void {\n process.stderr.write(`[star] ${message} in ${filePath}\\n`);\n}\n\n// Price fields are stripped from project models: a repo defining $0 prices\n// would silently zero out /cost and defeat sessionBudgetUsd.\nfunction stripModelPrices(models: ModelConfig[], filePath: string): ModelConfig[] {\n let stripped = false;\n const out = models.map((model) => {\n const { promptPrice, completionPrice, cacheReadPrice, ...rest } = model;\n if (\n promptPrice !== undefined ||\n completionPrice !== undefined ||\n cacheReadPrice !== undefined\n ) {\n stripped = true;\n }\n return rest;\n });\n if (stripped) {\n warnProject(filePath, \"ignoring price fields in project [[models]]: pricing stays global-only\");\n }\n return out;\n}\n\nfunction sanitizeProjectConfig(project: PartialConfig, filePath: string): PartialConfig {\n const sanitized: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(project)) {\n if (value === undefined) continue;\n if (!PROJECT_ALLOWED_KEYS.has(key)) {\n process.stderr.write(\n `[star] ignoring \"${key}\" in ${filePath}: project config cannot set this key\\n`,\n );\n continue;\n }\n if (key === \"gitSnapshots\" && value === false) {\n // Snapshot tracking protects /undo and /redo; a repo may enable but\n // never disable it.\n warnProject(\n filePath,\n 'ignoring \"gitSnapshots = false\": project config cannot disable this protection',\n );\n continue;\n }\n if (PROJECT_PROTECTIVE_MIN_KEYS.has(key) && value === 0) {\n warnProject(filePath, `ignoring \"${key} = 0\": project config cannot disable this protection`);\n continue;\n }\n const range = PROJECT_STREAM_RANGES[key as keyof typeof PROJECT_STREAM_RANGES];\n if (range && typeof value === \"number\") {\n const clamped = Math.min(range.max, Math.max(range.min, value));\n if (clamped !== value) {\n warnProject(\n filePath,\n `clamping \"${key}\" from ${value} to ${clamped}: project config is limited to ${range.min}–${range.max}`,\n );\n }\n sanitized[key] = clamped;\n continue;\n }\n if (key === \"models\" && Array.isArray(value)) {\n sanitized[key] = stripModelPrices(value as ModelConfig[], filePath);\n continue;\n }\n sanitized[key] = value;\n }\n return sanitized as PartialConfig;\n}\n\n// Project values merge protectively: a repo can tighten safeguards but never\n// relax them. Budgets take the lower bound; guard thresholds take the lower\n// bound too (0 = disabled was already filtered out above).\nfunction mergeProjectConfig(global: PartialConfig, project: PartialConfig): PartialConfig {\n const merged: PartialConfig = { ...global, ...project };\n if (project.sessionBudgetUsd !== undefined && global.sessionBudgetUsd !== undefined) {\n merged.sessionBudgetUsd = Math.min(global.sessionBudgetUsd, project.sessionBudgetUsd);\n }\n if (project.maxSteps !== undefined) {\n merged.maxSteps = Math.min(global.maxSteps ?? 100, project.maxSteps);\n }\n if (project.doomLoopThreshold !== undefined) {\n merged.doomLoopThreshold = Math.min(global.doomLoopThreshold ?? 3, project.doomLoopThreshold);\n }\n return merged;\n}\n\nfunction applyOverrides(config: PartialConfig, overrides?: CliOverrides): PartialConfig {\n if (!overrides) return config;\n const merged = { ...config };\n if (overrides.model !== undefined) merged.defaultModel = overrides.model;\n if (overrides.permissionMode !== undefined) merged.permissionMode = overrides.permissionMode;\n return merged;\n}\n\nasync function readTomlFile(filePath: string): Promise<PartialConfig> {\n let content: string;\n try {\n content = await fs.promises.readFile(filePath, \"utf8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return {};\n throw error;\n }\n return parseTomlFile(content, filePath);\n}\n\nfunction readTomlFileSync(filePath: string): PartialConfig {\n if (!fs.existsSync(filePath)) return {};\n const content = fs.readFileSync(filePath, \"utf8\");\n return parseTomlFile(content, filePath);\n}\n\nexport async function loadConfig(cwd: string, overrides?: CliOverrides): Promise<StarConfig> {\n loadEnvFile();\n const global = await readTomlFile(globalConfigPath());\n const projectPath = projectConfigPath(cwd);\n const project = sanitizeProjectConfig(await readTomlFile(projectPath), projectPath);\n const merged = applyOverrides(mergeProjectConfig(global, project), overrides);\n return ConfigSchema.parse(merged);\n}\n\nexport function loadConfigSync(cwd: string, overrides?: CliOverrides): StarConfig {\n loadEnvFile();\n const global = readTomlFileSync(globalConfigPath());\n const projectPath = projectConfigPath(cwd);\n const project = sanitizeProjectConfig(readTomlFileSync(projectPath), projectPath);\n const merged = applyOverrides(mergeProjectConfig(global, project), overrides);\n return ConfigSchema.parse(merged);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,eAAe;;;ACEjB,SAAS,gBAAgB,OAAmC;AACjE,UAAQ,MAAM,MAAM;AAAA,IAClB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO,KAAK,UAAU,EAAE,MAAM,SAAS,OAAO,EAAE,SAAS,MAAM,MAAM,QAAQ,EAAE,CAAC;AAAA,IAClF;AACE,aAAO,KAAK,UAAU,KAAK;AAAA,EAC/B;AACF;AAEO,IAAM,eAAN,MAAmB;AAAA,EAChB,WAAW;AAAA,EACX,eAAe;AAAA,EACf,mBAAmB;AAAA,EACnB,cAAc;AAAA,EAEtB,IAAI,OAA0B;AAC5B,QAAI,CAAC,MAAO;AACZ,SAAK,YAAY;AACjB,SAAK,gBAAgB,MAAM;AAC3B,SAAK,oBAAoB,MAAM;AAC/B,SAAK,eAAe,MAAM;AAAA,EAC5B;AAAA,EAEA,IAAI,SAA4C;AAC9C,WAAO;AAAA,MACL,UAAU,KAAK;AAAA,MACf,cAAc,KAAK;AAAA,MACnB,kBAAkB,KAAK;AAAA,MACvB,aAAa,KAAK;AAAA,IACpB;AAAA,EACF;AAAA,EAEA,aAA4B;AAC1B,QAAI,KAAK,aAAa,EAAG,QAAO;AAChC,WAAO,KAAK,UAAU;AAAA,MACpB,MAAM;AAAA,MACN,UAAU,KAAK;AAAA,MACf,cAAc,KAAK;AAAA,MACnB,kBAAkB,KAAK;AAAA,MACvB,aAAa,KAAK;AAAA,IACpB,CAAC;AAAA,EACH;AACF;;;AC9CA,OAAO,QAAQ;AACf,SAAS,aAAa;AAKtB,IAAM,sBAAsB,aAAa,QAAQ;AAIjD,SAAS,cAAc,SAAiB,UAAiC;AACvE,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,OAAO;AAAA,EACrB,SAAS,OAAO;AACd,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,UAAM,IAAI,MAAM,2BAA2B,QAAQ,KAAK,OAAO,EAAE;AAAA,EACnE;AACA,QAAM,SAAS,oBAAoB,UAAU,GAAG;AAChD,MAAI,CAAC,OAAO,SAAS;AACnB,UAAM,IAAI,MAAM,qBAAqB,QAAQ,KAAK,OAAO,MAAM,OAAO,EAAE;AAAA,EAC1E;AACA,SAAO,OAAO;AAChB;AAMA,IAAM,uBAAuB,oBAAI,IAAI;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAID,IAAM,wBAAwB;AAAA,EAC5B,sBAAsB,EAAE,KAAK,GAAG,KAAK,IAAI;AAAA,EACzC,4BAA4B,EAAE,KAAK,IAAI,KAAK,IAAI;AAAA,EAChD,kBAAkB,EAAE,KAAK,GAAG,KAAK,GAAG;AACtC;AAIA,IAAM,8BAA8B,oBAAI,IAAI,CAAC,YAAY,mBAAmB,CAAC;AAE7E,SAAS,YAAY,UAAkB,SAAuB;AAC5D,UAAQ,OAAO,MAAM,UAAU,OAAO,OAAO,QAAQ;AAAA,CAAI;AAC3D;AAIA,SAAS,iBAAiB,QAAuB,UAAiC;AAChF,MAAI,WAAW;AACf,QAAM,MAAM,OAAO,IAAI,CAAC,UAAU;AAChC,UAAM,EAAE,aAAa,iBAAiB,gBAAgB,GAAG,KAAK,IAAI;AAClE,QACE,gBAAgB,UAChB,oBAAoB,UACpB,mBAAmB,QACnB;AACA,iBAAW;AAAA,IACb;AACA,WAAO;AAAA,EACT,CAAC;AACD,MAAI,UAAU;AACZ,gBAAY,UAAU,wEAAwE;AAAA,EAChG;AACA,SAAO;AACT;AAEA,SAAS,sBAAsB,SAAwB,UAAiC;AACtF,QAAM,YAAqC,CAAC;AAC5C,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,GAAG;AAClD,QAAI,UAAU,OAAW;AACzB,QAAI,CAAC,qBAAqB,IAAI,GAAG,GAAG;AAClC,cAAQ,OAAO;AAAA,QACb,oBAAoB,GAAG,QAAQ,QAAQ;AAAA;AAAA,MACzC;AACA;AAAA,IACF;AACA,QAAI,QAAQ,kBAAkB,UAAU,OAAO;AAG7C;AAAA,QACE;AAAA,QACA;AAAA,MACF;AACA;AAAA,IACF;AACA,QAAI,4BAA4B,IAAI,GAAG,KAAK,UAAU,GAAG;AACvD,kBAAY,UAAU,aAAa,GAAG,sDAAsD;AAC5F;AAAA,IACF;AACA,UAAM,QAAQ,sBAAsB,GAAyC;AAC7E,QAAI,SAAS,OAAO,UAAU,UAAU;AACtC,YAAM,UAAU,KAAK,IAAI,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,KAAK,CAAC;AAC9D,UAAI,YAAY,OAAO;AACrB;AAAA,UACE;AAAA,UACA,aAAa,GAAG,UAAU,KAAK,OAAO,OAAO,kCAAkC,MAAM,GAAG,SAAI,MAAM,GAAG;AAAA,QACvG;AAAA,MACF;AACA,gBAAU,GAAG,IAAI;AACjB;AAAA,IACF;AACA,QAAI,QAAQ,YAAY,MAAM,QAAQ,KAAK,GAAG;AAC5C,gBAAU,GAAG,IAAI,iBAAiB,OAAwB,QAAQ;AAClE;AAAA,IACF;AACA,cAAU,GAAG,IAAI;AAAA,EACnB;AACA,SAAO;AACT;AAKA,SAAS,mBAAmB,QAAuB,SAAuC;AACxF,QAAM,SAAwB,EAAE,GAAG,QAAQ,GAAG,QAAQ;AACtD,MAAI,QAAQ,qBAAqB,UAAa,OAAO,qBAAqB,QAAW;AACnF,WAAO,mBAAmB,KAAK,IAAI,OAAO,kBAAkB,QAAQ,gBAAgB;AAAA,EACtF;AACA,MAAI,QAAQ,aAAa,QAAW;AAClC,WAAO,WAAW,KAAK,IAAI,OAAO,YAAY,KAAK,QAAQ,QAAQ;AAAA,EACrE;AACA,MAAI,QAAQ,sBAAsB,QAAW;AAC3C,WAAO,oBAAoB,KAAK,IAAI,OAAO,qBAAqB,GAAG,QAAQ,iBAAiB;AAAA,EAC9F;AACA,SAAO;AACT;AAEA,SAAS,eAAe,QAAuB,WAAyC;AACtF,MAAI,CAAC,UAAW,QAAO;AACvB,QAAM,SAAS,EAAE,GAAG,OAAO;AAC3B,MAAI,UAAU,UAAU,OAAW,QAAO,eAAe,UAAU;AACnE,MAAI,UAAU,mBAAmB,OAAW,QAAO,iBAAiB,UAAU;AAC9E,SAAO;AACT;AAaA,SAAS,iBAAiB,UAAiC;AACzD,MAAI,CAAC,GAAG,WAAW,QAAQ,EAAG,QAAO,CAAC;AACtC,QAAM,UAAU,GAAG,aAAa,UAAU,MAAM;AAChD,SAAO,cAAc,SAAS,QAAQ;AACxC;AAWO,SAAS,eAAe,KAAa,WAAsC;AAChF,cAAY;AACZ,QAAM,SAAS,iBAAiB,iBAAiB,CAAC;AAClD,QAAM,cAAc,kBAAkB,GAAG;AACzC,QAAM,UAAU,sBAAsB,iBAAiB,WAAW,GAAG,WAAW;AAChF,QAAM,SAAS,eAAe,mBAAmB,QAAQ,OAAO,GAAG,SAAS;AAC5E,SAAO,aAAa,MAAM,MAAM;AAClC;;;AF9JA,eAAe,WACb,QACA,WACA,KACA,cACA;AACA,QAAM,QAAQ,YAAY,QAAQ,SAAS;AAC3C,QAAM,WAAW,sBAAsB;AACvC,QAAM,cAAc,mBAAmB,QAAQ,SAAS;AACxD,SAAO,IAAI,UAAU;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,IACA,kBAAkB,oBAAoB,QAAQ,SAAS;AAAA,IACvD,kBAAkB,wBAAwB,QAAQ,SAAS;AAAA,IAC3D,aAAa,YAAY;AAAA,IACzB,sBAAsB,YAAY;AAAA,IAClC,4BAA4B,YAAY;AAAA,EAC1C,CAAC;AACH;AAEA,eAAe,UACb,MACA,QACA,KACA,MACA,YACA,cACiB;AACjB,QAAM,aAA2B,CAAC;AAClC,aAAW,aAAa,YAAY;AAClC,QAAI,CAAC,cAAc,SAAS,GAAG;AAC7B,cAAQ,OAAO;AAAA,QACb,mCAAmC,SAAS;AAAA;AAAA,MAC9C;AACA,aAAO;AAAA,IACT;AACA,UAAM,QAAQ,MAAM,eAAe,WAAW,GAAG;AACjD,QAAI,CAAC,OAAO;AACV,cAAQ,OAAO;AAAA,QACb,8BAA8B,SAAS,yCAAyC,mBAAmB,OAAO,KAAK;AAAA;AAAA,MACjH;AACA,aAAO;AAAA,IACT;AACA,eAAW,KAAK,KAAK;AAAA,EACvB;AACA,QAAM,aAAa,IAAI,gBAAgB;AACvC,UAAQ,GAAG,UAAU,MAAM,WAAW,MAAM,CAAC;AAC7C,OAAK,gBAAgB,CAAC,YAAY;AAChC,YAAQ,OAAO,MAAM,UAAU,OAAO;AAAA,CAAI;AAAA,EAC5C;AACA,QAAM,WAAW,MAAM,gBAAgB,QAAQ,GAAG;AAClD,MAAI,SAAS,SAAS,SAAS,GAAG;AAChC,YAAQ,OAAO,MAAM,cAAc,SAAS,SAAS,KAAK,IAAI,CAAC;AAAA,CAAI;AAAA,EACrE;AACA,aAAW,QAAQ,SAAS,SAAS;AACnC,YAAQ,OAAO,MAAM,cAAc,KAAK,IAAI,KAAK,KAAK,MAAM;AAAA,CAAI;AAAA,EAClE;AACA,QAAM,SAAS,CAAC,GAAG,YAAY,GAAG,SAAS,MAAM;AACjD,QAAM,QACJ,OAAO,SAAS,IAAI,EAAE,MAAM,SAAS,OAAO,OAAO,IAAI,SAAS;AAClE,QAAM,QAAQ,IAAI,aAAa;AAC/B,MAAI,WAAW;AACf,MAAI;AACF,qBAAiB,SAAS,KAAK,OAAO,OAAO,WAAW,QAAQ;AAAA,MAC9D,WAAW;AAAA,IACb,CAAC,GAAG;AACF,UAAI,MAAM;AACR,cAAM,OAAO,gBAAgB,KAAK;AAClC,YAAI,KAAM,SAAQ,OAAO,MAAM,GAAG,IAAI;AAAA,CAAI;AAAA,MAC5C;AACA,cAAQ,MAAM,MAAM;AAAA,QAClB,KAAK;AACH,cAAI,CAAC,KAAM,SAAQ,OAAO,MAAM,MAAM,IAAI;AAC1C;AAAA,QACF,KAAK;AACH;AAAA,QACF,KAAK;AACH,cAAI,CAAC,KAAM,SAAQ,OAAO,MAAM;AAAA,SAAY,MAAM,IAAI,IAAI,KAAK,UAAU,MAAM,IAAI,CAAC;AAAA,CAAI;AACxF;AAAA,QACF,KAAK,eAAe;AAClB,cAAI,CAAC,MAAM;AACT,kBAAM,UACJ,MAAM,QAAQ,SAAS,MACnB,GAAG,MAAM,QAAQ,MAAM,GAAG,GAAG,CAAC,oBAC9B,MAAM;AACZ,oBAAQ,OAAO,MAAM,YAAY,MAAM,UAAU,YAAY,EAAE,GAAG,OAAO;AAAA,CAAI;AAAA,UAC/E;AACA;AAAA,QACF;AAAA,QACA,KAAK;AACH,gBAAM,IAAI,MAAM,KAAK;AAGrB,cAAI,MAAM,OAAO;AACf,0BAAc,SAAS,MAAM,KAAK,EAAE,MAAM,MAAM;AAAA,YAAC,CAAC;AAAA,UACpD;AACA;AAAA,QACF,KAAK,SAAS;AACZ,cAAI,CAAC,MAAM;AACT,kBAAM,OACJ,MAAM,YAAY,UAAa,MAAM,WAAW,MAC5C,OAAO,KAAK,MAAM,MAAM,UAAU,GAAI,CAAC,MACvC;AACN,oBAAQ,OAAO;AAAA,cACb;AAAA,SAAY,MAAM,OAAO,IAAI,MAAM,WAAW,GAAG,IAAI,KAAK,MAAM,MAAM;AAAA;AAAA,YACxE;AAAA,UACF;AACA;AAAA,QACF;AAAA,QACA,KAAK;AACH,cAAI,CAAC,KAAM,SAAQ,OAAO,MAAM;AAAA,WAAc,MAAM,OAAO;AAAA,CAAI;AAC/D;AAAA,QACF,KAAK;AACH,cAAI,CAAC,KAAM,SAAQ,OAAO,MAAM;AAAA,UAAa,kBAAkB,MAAM,KAAK,CAAC;AAAA,CAAI;AAC/E,qBAAW;AACX;AAAA,MACJ;AACA,UAAI,aAAa,EAAG;AAAA,IACtB;AAAA,EACF,SAAS,OAAO;AACd,QAAI,EAAE,iBAAiB,gBAAgB,MAAM,SAAS,eAAe;AACnE,YAAM,UAAU,iBAAiB,QAAQ,kBAAkB,KAAK,IAAI,OAAO,KAAK;AAChF,cAAQ,OAAO,MAAM;AAAA,UAAa,OAAO;AAAA,CAAI;AAC7C,iBAAW;AAAA,IACb;AAAA,EACF;AACA,QAAM,YAAY,MAAM,WAAW;AACnC,MAAI,WAAW;AACb,QAAI,MAAM;AACR,cAAQ,OAAO,MAAM,GAAG,SAAS;AAAA,CAAI;AAAA,IACvC,OAAO;AACL,YAAM,IAAI,MAAM;AAChB,cAAQ,OAAO;AAAA,QACb,WAAW,EAAE,QAAQ,cAAc,aAAa,EAAE,YAAY,CAAC,aAAa,aAAa,EAAE,gBAAgB,CAAC,iBAAiB,aAAa,EAAE,WAAW,CAAC;AAAA;AAAA,MAC1J;AAAA,IACF;AAAA,EACF;AACA,MAAI,CAAC,KAAM,SAAQ,OAAO,MAAM,IAAI;AACpC,QAAM,eAAe,mBAAmB,QAAQ;AAChD,QAAM,eAAe,kBAAkB,QAAQ;AAC/C,QAAM,UAAU,aAAa,SAAS,aAAa;AACnD,MAAI,UAAU,GAAG;AACf,YAAQ,OAAO;AAAA,MACb,UAAU,OAAO;AAAA;AAAA,IACnB;AAAA,EACF;AACA,SAAO;AACT;AAEA,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,MAAM,EACX,YAAY,oDAA+C,EAC3D,QAAQ,OAAO,EACf,OAAO,uBAAuB,cAAc,EAC5C,OAAO,4BAA4B,sDAAsD,EACzF,OAAO,wBAAwB,4BAA4B,EAC3D,OAAO,UAAU,kDAAkD,EACnE;AAAA,EACC;AAAA,EACA;AAAA,EACA,CAAC,OAAe,aAAuB,CAAC,GAAG,UAAU,KAAK;AAAA,EAC1D,CAAC;AACH,EACC,OAAO,4BAA4B,6DAA6D,EAChG,OAAO,kBAAkB,4DAA4D,EACrF;AAAA,EACC;AAAA,EACA;AACF,EACC,OAAO,OAAO,SAAS;AACtB,QAAM,MAAM,QAAQ,IAAI;AAExB,MAAI,KAAK,QAAQ,KAAK,UAAU,QAAW;AACzC,YAAQ;AAAA,MACN;AAAA,IACF;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,KAAK,WAAW,UAAa,KAAK,UAAU;AAC9C,YAAQ,MAAM,mEAAmE;AACjF,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,KAAK,WAAW,MAAM;AACxB,UAAM,UAAU,MAAM,mBAAmB,GAAG;AAC5C,QAAI,QAAQ,WAAW,GAAG;AACxB,cAAQ,MAAM,uCAAuC;AAAA,IACvD,OAAO;AACL,cAAQ,IAAI,qBAAqB,OAAO,CAAC;AAAA,IAC3C;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,KAAK,kBAAkB,QAAW;AACpC,UAAM,QAAQ,KAAK;AACnB,QAAI,UAAU,QAAQ,UAAU,OAAO;AACrC,cAAQ,MAAM,kBAAkB,KAAK,iDAAiD;AACtF,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,UAAM,MAAM,UAAU;AACtB,UAAM,UAAU,MAAM,cAAc,MAAM,SAAY,GAAG;AACzD,YAAQ;AAAA,MACN,MACI,WAAW,OAAO,wCAClB,WAAW,OAAO;AAAA,IACxB;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI;AACJ,MAAI;AACF,aAAS,eAAe,KAAK,EAAE,OAAO,KAAK,OAAO,gBAAgB,KAAK,eAAe,CAAC;AAAA,EACzF,SAAS,OAAO;AACd,YAAQ,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AACpE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,YAAY,KAAK,SAAS,OAAO;AACvC,MAAI,CAAC,WAAW;AACd,YAAQ;AAAA,MACN;AAAA,IAEF;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,eAAoC;AACxC,MAAI,UAAiE;AACrE,MAAI,WAA0B;AAC9B,MAAI,OAAO,KAAK,WAAW,UAAU;AACnC,eAAW,MAAM,iBAAiB,KAAK,MAAM;AAC7C,QAAI,CAAC,UAAU;AACb,cAAQ,MAAM,sBAAsB,KAAK,MAAM,EAAE;AACjD,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,WAAW,KAAK,UAAU;AACxB,UAAM,SAAS,MAAM,kBAAkB,GAAG;AAC1C,QAAI,QAAQ;AACV,iBAAW,OAAO;AAAA,IACpB,OAAO;AACL,cAAQ,OAAO,MAAM,yEAAoE;AAAA,IAC3F;AAAA,EACF;AAEA,MAAI,UAAU;AAIZ,mBAAe,MAAM,aAAa,KAAK,QAAQ;AAC/C,QAAI,CAAC,cAAc;AACjB,cAAQ,MAAM,sBAAsB,QAAQ,EAAE;AAC9C,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,UAAM,CAAC,MAAM,MAAM,IAAI,MAAM,QAAQ,IAAI,CAAC,aAAa,KAAK,GAAG,aAAa,SAAS,CAAC,CAAC;AACvF,UAAM,WAAW,mBAAmB,MAAM;AAC1C,QAAI,SAAS,WAAW,OAAO,QAAQ;AACrC,YAAM,aAAa,gBAAgB,QAAQ;AAAA,IAC7C;AACA,cAAU,EAAE,MAAM,SAAS;AAAA,EAC7B,WAAW,CAAC,KAAK,OAAO;AACtB,mBAAe,MAAM,aAAa,OAAO,KAAK,SAAS;AAAA,EACzD;AAEA,MAAI;AACJ,MAAI;AACF,WAAO,MAAM,WAAW,QAAQ,WAAW,KAAK,YAAY;AAAA,EAC9D,SAAS,OAAO;AACd,YAAQ,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AACpE,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,MAAI,SAAS;AACX,UAAM,KAAK,aAAa,QAAQ,QAAQ;AAGxC,UAAM,UAAU,GAAG;AACnB,QAAI,cAAc;AAChB,uBAAiB,MAAM,qBAAqB,aAAa,GAAG,CAAC;AAAA,IAC/D;AAAA,EACF;AAEA,MAAI,KAAK,OAAO;AAGd,YAAQ,WAAW,MAAM;AAAA,MACvB;AAAA,MACA,KAAK;AAAA,MACL;AAAA,MACA,QAAQ,KAAK,IAAI;AAAA,MACjB,KAAK,SAAS,CAAC;AAAA,MACf;AAAA,IACF;AACA;AAAA,EACF;AAKA,QAAM,EAAE,WAAW,IAAI,MAAM,OAAO,oBAAY;AAChD,aAAW,MAAM;AAAA,IACf,OAAO;AAAA,IACP,gBAAgB,OAAO;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,IACA,iBAAiB,SAAS;AAAA,IAC1B,cAAc,SAAS,KAAK;AAAA,EAC9B,CAAC;AACH,CAAC;AAEH,QAAQ,MAAM,QAAQ,IAAI;","names":[]}
1
+ {"version":3,"sources":["../src/main.tsx","../src/cli/print-human.ts","../src/cli/print-json.ts","../src/cli/startup.ts","../src/config/loader.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { defaultAgentTasks } from \"./agent/agent-tasks\";\nimport type { AgentLoop } from \"./agent/loop\";\nimport { formatTokens } from \"./cli/cost\";\nimport { formatStreamError } from \"./cli/format\";\nimport { MAX_IMAGE_BYTES, imageMimeType, readImageInput, resolveMentions } from \"./cli/mentions\";\nimport { printEventLine } from \"./cli/print-human\";\nimport { UsageTracker, eventToJsonLine } from \"./cli/print-json\";\nimport {\n imageRequiresPrintError,\n installStdoutEpipeGuard,\n interactiveRequiresTtyError,\n reportResumeSessions,\n} from \"./cli/startup\";\nimport { SYSTEM_PROMPT } from \"./cli/system-prompt\";\nimport { loadConfigSync } from \"./config/loader\";\nimport { type StarConfig, contextWindowTokens } from \"./config/schema\";\nimport {\n type ImageInput,\n type StarMessage,\n reconcileStarMessages,\n toCoreMessages,\n} from \"./core/messages\";\nimport { resolveModelConfig, resolveStartupModel } from \"./llm/registry\";\nimport { loadSessionSnapshots } from \"./session/checkpoints\";\nimport { clearSessions } from \"./session/clear\";\nimport { findLatestSession, resolveSessionId } from \"./session/list\";\nimport { type SessionMeta, SessionStore } from \"./session/store\";\nimport { defaultTaskManager } from \"./tasks/manager\";\nimport { hydrateSnapshots } from \"./tools/fs/snapshots\";\nimport { loadTodos, setTodoSession } from \"./tools/todo\";\nimport { VERSION } from \"./version\";\n\nasync function createLoop(\n config: StarConfig,\n modelName: string,\n cwd: string,\n sessionStore: SessionStore | null,\n) {\n // Dynamic like the REPL import below: the agent loop pulls in the ai SDK\n // and every @ai-sdk provider (~100ms of module evaluation) that --version,\n // --help, session listing and --clear-sessions never need.\n const [{ AgentLoop }, { createModel, reasoningEffortMetadata }, { createDefaultRegistry }] =\n await Promise.all([import(\"./agent/loop\"), import(\"./llm/provider\"), import(\"./tools\")]);\n const model = createModel(config, modelName);\n const registry = createDefaultRegistry();\n const modelConfig = resolveModelConfig(config, modelName);\n return new AgentLoop({\n model,\n registry,\n config,\n cwd,\n system: SYSTEM_PROMPT,\n sessionStore,\n modelName,\n contextMaxTokens: contextWindowTokens(config, modelName),\n providerMetadata: reasoningEffortMetadata(config, modelName),\n temperature: modelConfig.temperature,\n streamIdleTimeoutSec: modelConfig.streamIdleTimeoutSec,\n streamFirstChunkTimeoutSec: modelConfig.streamFirstChunkTimeoutSec,\n vision: modelConfig.vision,\n });\n}\n\nasync function printMode(\n loop: AgentLoop,\n prompt: string,\n cwd: string,\n json: boolean,\n imagePaths: string[],\n sessionStore: SessionStore | null,\n): Promise<number> {\n const flagImages: ImageInput[] = [];\n for (const imagePath of imagePaths) {\n if (!imageMimeType(imagePath)) {\n process.stderr.write(\n `[error] unsupported image type: ${imagePath} (supported: png, jpg, jpeg, gif, webp)\\n`,\n );\n return 1;\n }\n const image = await readImageInput(imagePath, cwd);\n if (!image) {\n process.stderr.write(\n `[error] cannot read image: ${imagePath} (missing, unreadable, or larger than ${MAX_IMAGE_BYTES / (1024 * 1024)}MB)\\n`,\n );\n return 1;\n }\n flagImages.push(image);\n }\n const controller = new AbortController();\n process.on(\"SIGINT\", () => controller.abort());\n loop.onHookWarning = (message) => {\n process.stderr.write(`[hook] ${message}\\n`);\n };\n const resolved = await resolveMentions(prompt, cwd);\n if (resolved.attached.length > 0) {\n process.stderr.write(`[attached] ${resolved.attached.join(\", \")}\\n`);\n }\n for (const skip of resolved.skipped) {\n process.stderr.write(`[skipped] @${skip.path}: ${skip.reason}\\n`);\n }\n const images = [...flagImages, ...resolved.images];\n const input: string | { text: string; images: ImageInput[] } =\n images.length > 0 ? { text: resolved.input, images } : resolved.input;\n const usage = new UsageTracker();\n let exitCode = 0;\n try {\n for await (const event of loop.stream(input, controller.signal, {\n persistAs: prompt,\n })) {\n if (json) {\n const line = eventToJsonLine(event);\n if (line) process.stdout.write(`${line}\\n`);\n } else {\n // Human-readable path: tool args are the one-line summarizeArgs\n // digest (same as the REPL tool cards), never the full JSON.\n const line = printEventLine(event);\n if (line) {\n (line.stream === \"stdout\" ? process.stdout : process.stderr).write(line.text);\n }\n }\n switch (event.type) {\n case \"finish\":\n usage.add(event.usage);\n // A resumed session (-c/-r -p) must accumulate this turn's usage,\n // same as the REPL does; plain print runs have no store.\n if (event.usage) {\n sessionStore?.addUsage(event.usage).catch(() => {});\n }\n break;\n case \"error\":\n exitCode = 1;\n break;\n }\n if (exitCode !== 0) break;\n }\n } catch (error) {\n if (!(error instanceof DOMException && error.name === \"AbortError\")) {\n const message = error instanceof Error ? formatStreamError(error) : String(error);\n process.stderr.write(`\\n[error] ${message}\\n`);\n exitCode = 1;\n }\n }\n const usageLine = usage.toJsonLine();\n if (usageLine) {\n if (json) {\n process.stdout.write(`${usageLine}\\n`);\n } else {\n const t = usage.totals;\n process.stderr.write(\n `[usage] ${t.requests} requests, ${formatTokens(t.promptTokens)} prompt + ${formatTokens(t.completionTokens)} completion = ${formatTokens(t.totalTokens)} tokens\\n`,\n );\n }\n }\n if (!json) process.stdout.write(\"\\n\");\n const killedShells = defaultTaskManager.cleanup();\n const killedAgents = defaultAgentTasks.cleanup();\n const stopped = killedShells.length + killedAgents.length;\n if (stopped > 0) {\n process.stderr.write(\n `[info] ${stopped} background task(s) were still running and have been stopped.\\n`,\n );\n }\n return exitCode;\n}\n\nconst program = new Command();\n\nprogram\n .name(\"star\")\n .description(\"Star CLI — an AI agent command-line interface\")\n .version(VERSION)\n .option(\"-m, --model <model>\", \"model to use\")\n .option(\"--permission-mode <mode>\", \"permission mode: ask | auto | readonly | yolo | plan\")\n .option(\"-p, --print <prompt>\", \"non-interactive print mode\")\n .option(\"--json\", \"output NDJSON events on stdout (print mode only)\")\n .option(\n \"--image <path>\",\n \"attach an image file (png/jpg/jpeg/gif/webp, max 5MB); repeatable\",\n (value: string, previous: string[]) => [...previous, value],\n [] as string[],\n )\n .option(\"-r, --resume [sessionId]\", \"resume a previous session (lists sessions when no id given)\")\n .option(\"-c, --continue\", \"continue the most recent session for the current directory\")\n .option(\n \"--clear-sessions [scope]\",\n \"delete stored sessions for the current directory ('all' deletes every session) and exit\",\n )\n .action(async (opts) => {\n installStdoutEpipeGuard();\n const cwd = process.cwd();\n\n if (opts.json && opts.print === undefined) {\n console.error(\n '--json requires print mode: use star -p \"...\" --json (the interactive REPL does not support JSON output).',\n );\n process.exit(1);\n }\n\n const imageError = imageRequiresPrintError(opts.print, opts.image ?? []);\n if (imageError) {\n console.error(imageError);\n process.exit(1);\n }\n\n if (opts.resume !== undefined && opts.continue) {\n console.error(\"Options --resume and --continue are mutually exclusive: pick one.\");\n process.exit(1);\n }\n\n if (opts.resume === true) {\n process.exit(await reportResumeSessions(cwd));\n }\n\n if (opts.clearSessions !== undefined) {\n const scope = opts.clearSessions;\n if (scope !== true && scope !== \"all\") {\n console.error(`Invalid scope: ${scope}. Use --clear-sessions or --clear-sessions all.`);\n process.exit(1);\n }\n const all = scope === \"all\";\n const removed = await clearSessions(all ? undefined : cwd);\n console.log(\n all\n ? `Deleted ${removed} session(s) across all directories.`\n : `Deleted ${removed} session(s) for this directory.`,\n );\n process.exit(0);\n }\n\n let config: StarConfig;\n try {\n config = loadConfigSync(cwd, { model: opts.model, permissionMode: opts.permissionMode });\n } catch (error) {\n console.error(error instanceof Error ? error.message : String(error));\n process.exit(1);\n }\n\n let sessionStore: SessionStore | null = null;\n let resumed: { meta: SessionMeta; messages: StarMessage[] } | null = null;\n let resumeId: string | null = null;\n if (typeof opts.resume === \"string\") {\n resumeId = await resolveSessionId(opts.resume);\n if (!resumeId) {\n console.error(`Session not found: ${opts.resume}`);\n process.exit(1);\n }\n } else if (opts.continue) {\n const latest = await findLatestSession(cwd);\n if (latest) {\n resumeId = latest.id;\n } else {\n process.stderr.write(\"No previous session for this directory — starting a new session.\\n\");\n }\n }\n\n if (resumeId) {\n // Open the store once and read through it: resumeSession() would open a\n // second SessionStore instance on the same directory whose independent\n // meta cache could race this instance's writes.\n sessionStore = await SessionStore.open(resumeId);\n if (!sessionStore) {\n console.error(`Session not found: ${resumeId}`);\n process.exit(1);\n }\n const [meta, loaded] = await Promise.all([sessionStore.meta(), sessionStore.starMessages()]);\n const messages = reconcileStarMessages(loaded);\n if (messages.length !== loaded.length) {\n await sessionStore.replaceMessages(messages);\n }\n resumed = { meta, messages };\n setTodoSession(resumeId);\n }\n\n // An explicit --model already landed in config.defaultModel (loader\n // override) and wins; otherwise a resumed session's recorded model is\n // restored when it still resolves in the config.\n const { name: modelName, notice: modelNotice } = resolveStartupModel(\n config,\n opts.model ? undefined : resumed?.meta.model,\n );\n if (modelNotice) {\n process.stderr.write(`${modelNotice}\\n`);\n }\n if (!modelName) {\n console.error(\n \"No model configured. Add one to ~/.star-cli/config.toml or pass --model.\\n\" +\n \"See README.md for configuration examples.\",\n );\n process.exit(1);\n }\n\n if (!resumeId && !opts.print) {\n sessionStore = await SessionStore.create(cwd, modelName);\n setTodoSession(sessionStore.id);\n }\n\n let loop: AgentLoop;\n try {\n loop = await createLoop(config, modelName, cwd, sessionStore);\n } catch (error) {\n console.error(error instanceof Error ? error.message : String(error));\n process.exit(1);\n }\n if (resumed) {\n await loop.loadMessages(resumed.messages);\n // Resuming explicitly continues the project: rehydrate its todo list\n // (fresh sessions leave it alone even when .star/todos.json exists, and\n // a list owned by another session is not adopted).\n await loadTodos(cwd, resumeId ?? undefined);\n if (sessionStore) {\n hydrateSnapshots(await loadSessionSnapshots(sessionStore.dir));\n }\n }\n\n if (opts.print) {\n // Let the loop drain instead of process.exit(): force-exiting on Windows\n // can hit a libuv assertion while undici keep-alive handles are closing.\n process.exitCode = await printMode(\n loop,\n opts.print,\n cwd,\n Boolean(opts.json),\n opts.image ?? [],\n sessionStore,\n );\n return;\n }\n\n // The REPL needs a real terminal on both ends; check before paying for\n // the Ink import so a piped launch fails fast with a clear message.\n const ttyError = interactiveRequiresTtyError({\n stdinTTY: Boolean(process.stdin.isTTY),\n stdoutTTY: Boolean(process.stdout.isTTY),\n });\n if (ttyError) {\n console.error(ttyError);\n process.exit(1);\n }\n\n // The REPL pulls in Ink and every interactive component (~0.4s of module\n // evaluation): load it only on the interactive path so -p, --version,\n // --clear-sessions and session listing stay cheap.\n const { renderRepl } = await import(\"./cli/repl\");\n renderRepl(loop, {\n model: modelName,\n permissionMode: config.permissionMode,\n config,\n cwd,\n sessionStore,\n initialMessages: resumed ? toCoreMessages(resumed.messages) : undefined,\n initialUsage: resumed?.meta.usage,\n });\n });\n\nprogram.parse(process.argv);\n","import type { StreamEvent } from \"../core/events\";\nimport { formatStreamError, summarizeArgs } from \"./format\";\n\nexport interface PrintLine {\n stream: \"stdout\" | \"stderr\";\n text: string;\n}\n\n// Human-readable (-p without --json) rendering of one stream event. Tool\n// args go through the same one-line summarizeArgs digest the REPL tool cards\n// use instead of the full JSON; print-json (machine consumption) keeps the\n// complete payload. Returns null for events this path ignores (reasoning,\n// tool-call progress) — finish is accounted separately via UsageTracker and\n// error additionally flips the exit code, both handled by the caller.\nexport function printEventLine(event: StreamEvent): PrintLine | null {\n switch (event.type) {\n case \"text-delta\":\n return { stream: \"stdout\", text: event.text };\n case \"tool-call\":\n return { stream: \"stderr\", text: `\\n[tool] ${event.name} ${summarizeArgs(event.args)}\\n` };\n case \"tool-result\": {\n const preview =\n event.content.length > 500\n ? `${event.content.slice(0, 500)}... (truncated)`\n : event.content;\n return {\n stream: \"stderr\",\n text: `[result] ${event.isError ? \"ERROR: \" : \"\"}${preview}\\n`,\n };\n }\n case \"retry\": {\n const wait =\n event.delayMs !== undefined && event.delayMs >= 1000\n ? ` in ${Math.round(event.delayMs / 1000)}s`\n : \"\";\n return {\n stream: \"stderr\",\n text: `\\n[retry ${event.attempt}/${event.maxAttempts}${wait}] ${event.reason}\\n`,\n };\n }\n case \"notice\":\n return { stream: \"stderr\", text: `\\n[notice] ${event.message}\\n` };\n case \"error\":\n return { stream: \"stderr\", text: `\\n[error] ${formatStreamError(event.error)}\\n` };\n default:\n return null;\n }\n}\n","import type { StreamEvent, TokenUsage } from \"../core/events\";\n\nexport function eventToJsonLine(event: StreamEvent): string | null {\n switch (event.type) {\n case \"finish\":\n return null;\n case \"error\":\n return JSON.stringify({ type: \"error\", error: { message: event.error.message } });\n default:\n return JSON.stringify(event);\n }\n}\n\nexport class UsageTracker {\n private requests = 0;\n private promptTokens = 0;\n private completionTokens = 0;\n private totalTokens = 0;\n\n add(usage?: TokenUsage): void {\n if (!usage) return;\n this.requests += 1;\n this.promptTokens += usage.promptTokens;\n this.completionTokens += usage.completionTokens;\n this.totalTokens += usage.totalTokens;\n }\n\n get totals(): TokenUsage & { requests: number } {\n return {\n requests: this.requests,\n promptTokens: this.promptTokens,\n completionTokens: this.completionTokens,\n totalTokens: this.totalTokens,\n };\n }\n\n toJsonLine(): string | null {\n if (this.requests === 0) return null;\n return JSON.stringify({\n type: \"usage\",\n requests: this.requests,\n promptTokens: this.promptTokens,\n completionTokens: this.completionTokens,\n totalTokens: this.totalTokens,\n });\n }\n}\n","import { formatSessionEntries, listSessionEntries } from \"../session/list\";\n\n// Guards for the CLI entry paths, kept out of main.tsx (which parses argv at\n// module scope) so tests can exercise them without launching commander.\n\nexport interface StartupStreams {\n stdinTTY: boolean;\n stdoutTTY: boolean;\n}\n\n// --image only has a consumer in print mode; without -p the file would be\n// silently dropped when the REPL starts, so fail at startup instead.\nexport function imageRequiresPrintError(\n print: string | undefined,\n images: readonly string[],\n): string | null {\n if (print !== undefined) return null;\n return images.length > 0 ? \"--image requires -p/--print\" : null;\n}\n\n// Ink needs a real terminal on both ends; piped stdin/stdout used to leave a\n// bare stack or a hung process.\nexport function interactiveRequiresTtyError(streams: StartupStreams): string | null {\n return streams.stdinTTY && streams.stdoutTTY\n ? null\n : \"interactive mode requires a TTY; use -p/--print\";\n}\n\n// A downstream pipe that closes early (star -p \"...\" | head -1) turns the next\n// stdout write into an EPIPE \"error\" event; exit quietly instead of dumping a\n// raw stack.\nexport function installStdoutEpipeGuard(stdout: NodeJS.WriteStream = process.stdout): void {\n stdout.on(\"error\", (error: NodeJS.ErrnoException) => {\n if (error?.code === \"EPIPE\") process.exit(0);\n else throw error;\n });\n}\n\n// `star -r` without an id prints the session picker list and leaves; a script\n// must be able to tell \"no sessions\" apart from a successful listing, hence\n// the non-zero code.\nexport async function reportResumeSessions(cwd: string): Promise<number> {\n const entries = await listSessionEntries(cwd);\n if (entries.length === 0) {\n console.error(\"No sessions found for this directory.\");\n return 1;\n }\n console.log(formatSessionEntries(entries));\n return 0;\n}\n","import fs from \"node:fs\";\nimport { parse } from \"smol-toml\";\nimport { registerSensitivePatterns } from \"../core/sensitive\";\nimport { setWebFetchAllowPrivateHosts } from \"../tools/web/fetch\";\nimport { loadEnvFile } from \"./env\";\nimport { globalConfigPath, projectConfigPath } from \"./paths\";\nimport {\n type CliOverrides,\n ConfigSchema,\n HookConfigSchema,\n type ModelConfig,\n ModelConfigSchema,\n PermissionsConfigSchema,\n ProviderConfigSchema,\n type StarConfig,\n} from \"./schema\";\n\nconst PartialConfigSchema = ConfigSchema.partial();\n\ntype PartialConfig = ReturnType<typeof PartialConfigSchema.parse>;\n\n// Which file a parsed config came from: project files warn differently —\n// schema-known keys the sandbox strips get sanitizeProjectConfig's \"project\n// config cannot set this key\", so the unknown-key diff only reports keys the\n// schema does not know at all.\ntype ConfigScope = \"global\" | \"project\";\n\nfunction parseTomlFile(content: string, filePath: string, scope: ConfigScope): PartialConfig {\n let raw: unknown;\n try {\n raw = parse(content);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to parse TOML in ${filePath}: ${message}`);\n }\n const result = PartialConfigSchema.safeParse(raw);\n if (!result.success) {\n // One readable line per issue instead of zod's single JSON blob.\n const details = result.error.issues\n .map((issue) => {\n const where = issue.path.length > 0 ? issue.path.join(\".\") : \"(root)\";\n return ` ${where}: ${issue.message}`;\n })\n .join(\"\\n\");\n throw new Error(`Invalid config in ${filePath}:\\n${details}`);\n }\n warnUnknownKeys(raw, filePath, scope);\n return result.data;\n}\n\n// Keys a project-level .star/config.toml may set. Anything else (providers,\n// permissionMode, permissions, hooks, ...) stays global-only: a checked-out\n// repo must not be able to plant shell hooks, force yolo mode, or redirect\n// provider traffic to a key-harvesting endpoint.\nconst PROJECT_ALLOWED_KEYS = new Set([\n \"defaultModel\",\n \"models\",\n \"maxSteps\",\n \"contextMaxTokens\",\n \"compactThresholdTokens\",\n \"streamIdleTimeoutSec\",\n \"streamFirstChunkTimeoutSec\",\n \"streamMaxRetries\",\n \"maxAutoContinues\",\n \"contextCompaction\",\n \"sessionBudgetUsd\",\n \"notifyBell\",\n \"notifyBellThresholdSec\",\n \"doomLoopThreshold\",\n \"gitSnapshots\",\n]);\n\n// Safe ranges for the project-provided streaming knobs: a repo must not set\n// pathological values (sub-second idle timeouts, thousands of retries).\nconst PROJECT_STREAM_RANGES = {\n streamIdleTimeoutSec: { min: 5, max: 120 },\n streamFirstChunkTimeoutSec: { min: 30, max: 900 },\n streamMaxRetries: { min: 0, max: 10 },\n} as const;\n\n// 0 disables these protections, so a project may only tighten them, never\n// turn them off (handled at merge time via min()).\nconst PROJECT_PROTECTIVE_MIN_KEYS = new Set([\"maxSteps\", \"doomLoopThreshold\"]);\n\n// Known keys per schema-defined section, for the unknown-key diff.\nconst TOP_LEVEL_KEYS = new Set(Object.keys(ConfigSchema.shape));\nconst SECTION_KEYS: Record<string, { keys: Set<string>; array: boolean }> = {\n permissions: { keys: new Set(Object.keys(PermissionsConfigSchema.shape)), array: false },\n providers: { keys: new Set(Object.keys(ProviderConfigSchema.shape)), array: true },\n models: { keys: new Set(Object.keys(ModelConfigSchema.shape)), array: true },\n hooks: { keys: new Set(Object.keys(HookConfigSchema.shape)), array: true },\n};\n\nfunction editDistance(a: string, b: string): number {\n let previous: number[] = Array.from({ length: b.length + 1 }, (_, i) => i);\n for (let i = 1; i <= a.length; i++) {\n const current: number[] = [i];\n for (let j = 1; j <= b.length; j++) {\n current[j] = Math.min(\n (previous[j] ?? 0) + 1,\n (current[j - 1] ?? 0) + 1,\n (previous[j - 1] ?? 0) + (a[i - 1] === b[j - 1] ? 0 : 1),\n );\n }\n previous = current;\n }\n return previous[b.length] ?? 0;\n}\n\n// Cheap \"did you mean\": case-insensitive Levenshtein against the known keys,\n// accepted when the distance is small relative to the key's length.\nfunction suggestKey(key: string, known: Set<string>): string | undefined {\n const needle = key.toLowerCase();\n let best: string | undefined;\n let bestDistance = Number.POSITIVE_INFINITY;\n for (const candidate of known) {\n const distance = editDistance(needle, candidate.toLowerCase());\n if (distance <= Math.max(1, Math.floor(candidate.length / 4)) && distance < bestDistance) {\n best = candidate;\n bestDistance = distance;\n }\n }\n return best;\n}\n\nfunction warnUnknownKey(keyPath: string, filePath: string, known: Set<string>): void {\n const leaf = keyPath.slice(keyPath.lastIndexOf(\".\") + 1);\n const suggestion = suggestKey(leaf, known);\n const hint = suggestion\n ? `possible typo of \"${suggestion}\"? the key is ignored`\n : \"possible typo? the key is ignored\";\n process.stderr.write(`[star] unknown config key \"${keyPath}\" in ${filePath}: ${hint}\\n`);\n}\n\n// zod object schemas strip unknown keys without a word, so a misspelled\n// option (\"streamMaxRetreis\") would otherwise vanish silently. Diff the raw\n// TOML against the schema shapes and warn once per unknown key — top level\n// plus inside the schema-defined sections ([permissions], [[providers]],\n// [[models]], [[hooks]]). Warnings never block loading. In project files,\n// schema-known sections the sandbox drops wholesale (everything but\n// [[models]]) already get sanitizeProjectConfig's own warning, so their\n// inner keys are not diffed.\nfunction warnUnknownKeys(raw: unknown, filePath: string, scope: ConfigScope): void {\n if (typeof raw !== \"object\" || raw === null) return;\n const table = raw as Record<string, unknown>;\n for (const key of Object.keys(table)) {\n if (!TOP_LEVEL_KEYS.has(key)) warnUnknownKey(key, filePath, TOP_LEVEL_KEYS);\n }\n for (const [section, { keys, array }] of Object.entries(SECTION_KEYS)) {\n if (scope === \"project\" && !PROJECT_ALLOWED_KEYS.has(section)) continue;\n const value = table[section];\n if (array) {\n if (!Array.isArray(value)) continue;\n value.forEach((entry, index) => {\n if (typeof entry !== \"object\" || entry === null) return;\n for (const key of Object.keys(entry)) {\n if (!keys.has(key)) warnUnknownKey(`${section}[${index}].${key}`, filePath, keys);\n }\n });\n continue;\n }\n if (typeof value !== \"object\" || value === null) continue;\n for (const key of Object.keys(value as Record<string, unknown>)) {\n if (!keys.has(key)) warnUnknownKey(`${section}.${key}`, filePath, keys);\n }\n }\n}\n\nfunction warnProject(filePath: string, message: string): void {\n process.stderr.write(`[star] ${message} in ${filePath}\\n`);\n}\n\n// Price fields are stripped from project models: a repo defining $0 prices\n// would silently zero out /cost and defeat sessionBudgetUsd.\nfunction stripModelPrices(models: ModelConfig[], filePath: string): ModelConfig[] {\n let stripped = false;\n const out = models.map((model) => {\n const { promptPrice, completionPrice, cacheReadPrice, ...rest } = model;\n if (\n promptPrice !== undefined ||\n completionPrice !== undefined ||\n cacheReadPrice !== undefined\n ) {\n stripped = true;\n }\n return rest;\n });\n if (stripped) {\n warnProject(filePath, \"ignoring price fields in project [[models]]: pricing stays global-only\");\n }\n return out;\n}\n\nfunction sanitizeProjectConfig(project: PartialConfig, filePath: string): PartialConfig {\n const sanitized: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(project)) {\n if (value === undefined) continue;\n if (!PROJECT_ALLOWED_KEYS.has(key)) {\n process.stderr.write(\n `[star] ignoring \"${key}\" in ${filePath}: project config cannot set this key\\n`,\n );\n continue;\n }\n if (key === \"gitSnapshots\" && value === false) {\n // Snapshot tracking protects /undo and /redo; a repo may enable but\n // never disable it.\n warnProject(\n filePath,\n 'ignoring \"gitSnapshots = false\": project config cannot disable this protection',\n );\n continue;\n }\n if (PROJECT_PROTECTIVE_MIN_KEYS.has(key) && value === 0) {\n warnProject(filePath, `ignoring \"${key} = 0\": project config cannot disable this protection`);\n continue;\n }\n const range = PROJECT_STREAM_RANGES[key as keyof typeof PROJECT_STREAM_RANGES];\n if (range && typeof value === \"number\") {\n const clamped = Math.min(range.max, Math.max(range.min, value));\n if (clamped !== value) {\n warnProject(\n filePath,\n `clamping \"${key}\" from ${value} to ${clamped}: project config is limited to ${range.min}–${range.max}`,\n );\n }\n sanitized[key] = clamped;\n continue;\n }\n if (key === \"models\" && Array.isArray(value)) {\n sanitized[key] = stripModelPrices(value as ModelConfig[], filePath);\n continue;\n }\n sanitized[key] = value;\n }\n return sanitized as PartialConfig;\n}\n\n// Project [[models]] merge with the global table by name: a project entry\n// replaces the same-named global entry, every other global entry survives.\n// (Shallow-spreading the array would let a repo silently swap the user's\n// whole model table — and orphan a global defaultModel pointing into it.)\nfunction mergeModelsByName(\n globalModels: ModelConfig[],\n projectModels: ModelConfig[],\n): ModelConfig[] {\n const projectByName = new Map(projectModels.map((model) => [model.name, model]));\n const merged = globalModels.map((model) => projectByName.get(model.name) ?? model);\n const globalNames = new Set(globalModels.map((model) => model.name));\n for (const model of projectModels) {\n if (!globalNames.has(model.name)) merged.push(model);\n }\n return merged;\n}\n\n// 0 disables these protections (unlimited), so normalize it to +∞ before the\n// min: a project must be able to tighten a globally-disabled guard (global\n// maxSteps = 0, project 5 → 5), never to relax one.\nfunction protectiveMin(a: number, b: number): number {\n const result = Math.min(\n a === 0 ? Number.POSITIVE_INFINITY : a,\n b === 0 ? Number.POSITIVE_INFINITY : b,\n );\n return result === Number.POSITIVE_INFINITY ? 0 : result;\n}\n\n// Project values merge protectively: a repo can tighten safeguards but never\n// relax them. Budgets take the lower bound; guard thresholds take the lower\n// bound too (a project-side 0 = disabled was already filtered out above, and\n// a global 0 normalizes to +∞ via protectiveMin).\nfunction mergeProjectConfig(\n global: PartialConfig,\n project: PartialConfig,\n projectPath: string,\n): PartialConfig {\n const merged: PartialConfig = { ...global, ...project };\n if (project.models !== undefined) {\n merged.models = mergeModelsByName(global.models ?? [], project.models);\n warnProject(projectPath, `project config overrides ${project.models.length} model(s)`);\n }\n if (project.sessionBudgetUsd !== undefined && global.sessionBudgetUsd !== undefined) {\n merged.sessionBudgetUsd = Math.min(global.sessionBudgetUsd, project.sessionBudgetUsd);\n }\n if (project.maxSteps !== undefined) {\n merged.maxSteps = protectiveMin(global.maxSteps ?? 100, project.maxSteps);\n }\n if (project.doomLoopThreshold !== undefined) {\n merged.doomLoopThreshold = protectiveMin(\n global.doomLoopThreshold ?? 3,\n project.doomLoopThreshold,\n );\n }\n return merged;\n}\n\n// Plaintext keys still work, but config.toml is world-readable by default on\n// some setups and gets committed by accident — point users at apiKeyEnv.\nfunction warnPlaintextApiKey(config: PartialConfig): void {\n const offenders: string[] = [];\n for (const provider of config.providers ?? []) {\n if (provider.apiKey !== undefined) offenders.push(`provider \"${provider.name}\"`);\n }\n for (const model of config.models ?? []) {\n if (\"apiKey\" in model && model.apiKey !== undefined) offenders.push(`model \"${model.name}\"`);\n }\n if (offenders.length === 0) return;\n process.stderr.write(\n `[star] plaintext apiKey in config (${offenders.join(\", \")}) is deprecated: store keys in ~/.star-cli/.env and reference them with apiKeyEnv instead\\n`,\n );\n}\n\nfunction applyOverrides(config: PartialConfig, overrides?: CliOverrides): PartialConfig {\n if (!overrides) return config;\n const merged = { ...config };\n if (overrides.model !== undefined) merged.defaultModel = overrides.model;\n if (overrides.permissionMode !== undefined) merged.permissionMode = overrides.permissionMode;\n return merged;\n}\n\nasync function readTomlFile(filePath: string, scope: ConfigScope): Promise<PartialConfig> {\n let content: string;\n try {\n content = await fs.promises.readFile(filePath, \"utf8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return {};\n throw error;\n }\n return parseTomlFile(content, filePath, scope);\n}\n\nfunction readTomlFileSync(filePath: string, scope: ConfigScope): PartialConfig {\n if (!fs.existsSync(filePath)) return {};\n const content = fs.readFileSync(filePath, \"utf8\");\n return parseTomlFile(content, filePath, scope);\n}\n\nexport async function loadConfig(cwd: string, overrides?: CliOverrides): Promise<StarConfig> {\n loadEnvFile();\n const global = await readTomlFile(globalConfigPath(), \"global\");\n const projectPath = projectConfigPath(cwd);\n const project = sanitizeProjectConfig(await readTomlFile(projectPath, \"project\"), projectPath);\n const merged = applyOverrides(mergeProjectConfig(global, project, projectPath), overrides);\n warnPlaintextApiKey(merged);\n return wireRuntimeSettings(ConfigSchema.parse(merged));\n}\n\nexport function loadConfigSync(cwd: string, overrides?: CliOverrides): StarConfig {\n loadEnvFile();\n const global = readTomlFileSync(globalConfigPath(), \"global\");\n const projectPath = projectConfigPath(cwd);\n const project = sanitizeProjectConfig(readTomlFileSync(projectPath, \"project\"), projectPath);\n const merged = applyOverrides(mergeProjectConfig(global, project, projectPath), overrides);\n warnPlaintextApiKey(merged);\n return wireRuntimeSettings(ConfigSchema.parse(merged));\n}\n\n// Pushes config-driven security settings into their runtime consumers. The\n// merged permissions table is global-only at this point (the project sandbox\n// dropped any project-side [permissions]), so these can never be planted by\n// a checked-out repo.\nfunction wireRuntimeSettings(config: StarConfig): StarConfig {\n registerSensitivePatterns(config.permissions.sensitive);\n setWebFetchAllowPrivateHosts(config.webFetchAllowPrivateHosts);\n return config;\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ createModel,
4
+ reasoningEffortMetadata
5
+ } from "./chunk-MVAMPVTA.js";
6
+ import "./chunk-4IRY44TG.js";
7
+ export {
8
+ createModel,
9
+ reasoningEffortMetadata
10
+ };
11
+ //# sourceMappingURL=provider-EWMUPBLH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}