@qxbyte/muse 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/llm/providers/openai-compatible.ts","../src/log/index.ts","../src/types/index.ts","../src/llm/client.ts","../src/tools/registry.ts","../src/tools/types.ts","../src/tools/builtin/read.ts","../src/tools/builtin/write.ts","../src/tools/builtin/edit.ts","../src/tools/builtin/bash.ts","../src/tools/builtin/grep.ts","../src/tools/builtin/glob.ts","../src/tools/builtin/index.ts","../src/permission/index.ts","../src/session/jsonl.ts","../src/loop/agent.ts","../src/loop/system-prompt.ts","../src/config/loader.ts","../src/config/types.ts","../src/config/_env.ts"],"sourcesContent":["/**\n * OpenAI 兼容协议 provider。\n * 覆盖:OpenAI 官方、DeepSeek、Qwen、Moonshot (Kimi)、智谱、OpenRouter、Ollama (其 /v1 endpoint)、自建 vLLM/LocalAI 等。\n *\n * Why 自己包一层而不是直接用 @ai-sdk/openai-compatible:\n * - 抹平 stream 事件差异,统一为本仓库的 LLMEvent 类型\n * - 在 stream 中拼装 tool_call.arguments(OpenAI 流式 tool_call 是分片增量的 JSON 字符串)\n * - 留口子未来插入降级、重试、token 计数估算\n */\n\nimport { createOpenAICompatible } from \"@ai-sdk/openai-compatible\";\nimport { streamText, jsonSchema, tool, type CoreMessage, type ToolSet } from \"ai\";\nimport type {\n LLMClient,\n LLMEvent,\n ModelCapabilities,\n ProviderConfig,\n StreamOptions,\n} from \"../types.js\";\nimport type { Message, AssistantMessage, ToolDefinition } from \"../../types/index.js\";\nimport { log, redactApiKey } from \"../../log/index.js\";\n\ninterface OpenAICompatibleProviderOpts {\n providerName: string;\n baseUrl: string;\n apiKey: string;\n model: string;\n capabilities?: Partial<ModelCapabilities>;\n}\n\nconst DEFAULT_CAPABILITIES: ModelCapabilities = {\n toolCalling: true,\n parallelToolCalls: true,\n vision: false,\n jsonMode: true,\n maxContextWindow: 32_000,\n};\n\nexport class OpenAICompatibleClient implements LLMClient {\n readonly providerName: string;\n readonly model: string;\n readonly capabilities: ModelCapabilities;\n private modelProvider: ReturnType<ReturnType<typeof createOpenAICompatible>>;\n\n constructor(opts: OpenAICompatibleProviderOpts) {\n this.providerName = opts.providerName;\n this.model = opts.model;\n this.capabilities = { ...DEFAULT_CAPABILITIES, ...opts.capabilities };\n\n const provider = createOpenAICompatible({\n name: opts.providerName,\n baseURL: opts.baseUrl,\n apiKey: opts.apiKey,\n });\n this.modelProvider = provider(opts.model);\n\n log.debug(\"LLM provider initialized\", {\n provider: opts.providerName,\n model: opts.model,\n baseUrl: opts.baseUrl,\n apiKey: redactApiKey(opts.apiKey),\n });\n }\n\n async *stream(opts: StreamOptions): AsyncIterable<LLMEvent> {\n const { messages, tools, systemPrompt, temperature, maxTokens, abortSignal } = opts;\n\n const aiMessages = convertMessages(messages, systemPrompt);\n const aiTools = tools ? convertTools(tools) : undefined;\n\n try {\n const result = streamText({\n model: this.modelProvider,\n messages: aiMessages,\n tools: aiTools,\n temperature,\n maxTokens,\n abortSignal,\n });\n\n const seenToolCalls = new Set<string>();\n\n for await (const part of result.fullStream) {\n switch (part.type) {\n case \"text-delta\":\n yield { type: \"text\", delta: part.textDelta };\n break;\n\n case \"tool-call\":\n if (!seenToolCalls.has(part.toolCallId)) {\n seenToolCalls.add(part.toolCallId);\n yield { type: \"tool_call_start\", id: part.toolCallId, name: part.toolName };\n }\n yield {\n type: \"tool_call_complete\",\n id: part.toolCallId,\n name: part.toolName,\n args: part.args,\n };\n break;\n\n case \"finish\":\n yield {\n type: \"finish\",\n reason: mapFinishReason(part.finishReason),\n usage: part.usage\n ? {\n inputTokens: part.usage.promptTokens ?? 0,\n outputTokens: part.usage.completionTokens ?? 0,\n totalTokens: part.usage.totalTokens ?? 0,\n }\n : undefined,\n };\n break;\n\n case \"error\":\n yield { type: \"error\", error: part.error instanceof Error ? part.error : new Error(String(part.error)) };\n break;\n\n default:\n // 忽略其它(如 step-start / step-finish / tool-call-streaming-start 等)\n break;\n }\n }\n } catch (err) {\n yield { type: \"error\", error: err instanceof Error ? err : new Error(String(err)) };\n }\n }\n}\n\n// ---------- helpers ----------\n\nfunction convertMessages(messages: Message[], systemPrompt?: string): CoreMessage[] {\n const result: CoreMessage[] = [];\n if (systemPrompt) {\n result.push({ role: \"system\", content: systemPrompt });\n }\n for (const msg of messages) {\n switch (msg.role) {\n case \"system\":\n result.push({ role: \"system\", content: msg.content });\n break;\n case \"user\":\n if (typeof msg.content === \"string\") {\n result.push({ role: \"user\", content: msg.content });\n } else {\n const text = msg.content\n .filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n .map((p) => p.text)\n .join(\"\\n\");\n result.push({ role: \"user\", content: text });\n }\n break;\n case \"assistant\":\n result.push({ role: \"assistant\", content: convertAssistantContent(msg) });\n break;\n case \"tool\":\n result.push({\n role: \"tool\",\n content: [\n {\n type: \"tool-result\",\n toolCallId: msg.toolUseId,\n toolName: \"_tool\",\n result: msg.content,\n isError: msg.isError ?? false,\n },\n ],\n });\n break;\n }\n }\n return result;\n}\n\ntype AssistantContent = Extract<CoreMessage, { role: \"assistant\" }>[\"content\"];\n\nfunction convertAssistantContent(msg: AssistantMessage): AssistantContent {\n const parts: Array<\n { type: \"text\"; text: string } | { type: \"tool-call\"; toolCallId: string; toolName: string; args: unknown }\n > = [];\n for (const part of msg.content) {\n if (part.type === \"text\") {\n parts.push({ type: \"text\", text: part.text });\n } else if (part.type === \"tool_use\") {\n parts.push({\n type: \"tool-call\",\n toolCallId: part.id,\n toolName: part.name,\n args: part.args,\n });\n }\n }\n // 至少要有一个内容;空数组 SDK 会报错\n if (parts.length === 0) return \"\";\n return parts as AssistantContent;\n}\n\nfunction convertTools(tools: ToolDefinition[]): ToolSet {\n const result: ToolSet = {};\n for (const t of tools) {\n result[t.name] = tool({\n description: t.description,\n parameters: jsonSchema(t.parameters as Parameters<typeof jsonSchema>[0]),\n });\n }\n return result;\n}\n\nfunction mapFinishReason(reason: string | undefined): \"stop\" | \"tool_calls\" | \"length\" | \"content_filter\" | \"error\" | \"unknown\" {\n switch (reason) {\n case \"stop\":\n case \"stop-sequence\":\n return \"stop\";\n case \"tool-calls\":\n case \"tool_calls\":\n return \"tool_calls\";\n case \"length\":\n return \"length\";\n case \"content-filter\":\n case \"content_filter\":\n return \"content_filter\";\n case \"error\":\n return \"error\";\n default:\n return \"unknown\";\n }\n}\n\n// ---------- 预设 provider 工厂 ----------\n\nexport interface PresetConfig {\n baseUrl: string;\n defaultModel: string;\n capabilities?: Partial<ModelCapabilities>;\n}\n\nexport const PRESETS: Record<string, PresetConfig> = {\n openai: {\n baseUrl: \"https://api.openai.com/v1\",\n defaultModel: \"gpt-4o-mini\",\n },\n deepseek: {\n baseUrl: \"https://api.deepseek.com/v1\",\n defaultModel: \"deepseek-chat\",\n capabilities: { maxContextWindow: 128_000 },\n },\n qwen: {\n baseUrl: \"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n defaultModel: \"qwen-plus\",\n capabilities: { maxContextWindow: 128_000 },\n },\n moonshot: {\n baseUrl: \"https://api.moonshot.cn/v1\",\n defaultModel: \"moonshot-v1-32k\",\n capabilities: { maxContextWindow: 32_000 },\n },\n zhipu: {\n baseUrl: \"https://open.bigmodel.cn/api/paas/v4\",\n defaultModel: \"glm-4-flash\",\n capabilities: { maxContextWindow: 128_000 },\n },\n ollama: {\n baseUrl: \"http://localhost:11434/v1\",\n defaultModel: \"llama3.1\",\n capabilities: { maxContextWindow: 8_000 },\n },\n openrouter: {\n baseUrl: \"https://openrouter.ai/api/v1\",\n defaultModel: \"openai/gpt-4o-mini\",\n },\n};\n\nexport function createPresetClient(\n providerName: string,\n config: ProviderConfig,\n model?: string,\n): OpenAICompatibleClient {\n const preset = PRESETS[providerName];\n if (!preset) {\n throw new Error(`Unknown provider preset: ${providerName}. Available: ${Object.keys(PRESETS).join(\", \")}`);\n }\n return new OpenAICompatibleClient({\n providerName,\n baseUrl: (config.baseUrl as string | undefined) ?? preset.baseUrl,\n apiKey: (config.apiKey as string | undefined) ?? \"\",\n model: model ?? preset.defaultModel,\n capabilities: preset.capabilities,\n });\n}\n","/**\n * Logger 包装。第一版用最朴素的 console + 文件追加;后期可替换 pino。\n * Why 不直接用 pino: 简化首版依赖图,等可观测性章节再上 pino。\n */\n\nimport { appendFileSync, mkdirSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nexport type LogLevel = \"trace\" | \"debug\" | \"info\" | \"warn\" | \"error\";\n\nconst LEVELS: Record<LogLevel, number> = {\n trace: 10,\n debug: 20,\n info: 30,\n warn: 40,\n error: 50,\n};\n\ninterface LogEntry {\n time: string;\n level: LogLevel;\n msg: string;\n [key: string]: unknown;\n}\n\nclass Logger {\n private level: LogLevel = \"info\";\n private logPath: string;\n private fileEnabled = true;\n\n constructor() {\n const date = new Date().toISOString().slice(0, 10);\n this.logPath = join(homedir(), \".muse\", \"logs\", `${date}.jsonl`);\n try {\n mkdirSync(dirname(this.logPath), { recursive: true });\n } catch {\n this.fileEnabled = false;\n }\n }\n\n setLevel(level: LogLevel) {\n this.level = level;\n }\n\n private write(level: LogLevel, msg: string, extra?: Record<string, unknown>) {\n if (LEVELS[level] < LEVELS[this.level]) return;\n const entry: LogEntry = {\n time: new Date().toISOString(),\n level,\n msg,\n ...extra,\n };\n if (this.fileEnabled) {\n try {\n appendFileSync(this.logPath, JSON.stringify(entry) + \"\\n\");\n } catch {\n // 落盘失败不阻断主流程\n }\n }\n // 仅 warn/error 默认输出到 stderr,避免污染 stdout\n if (level === \"warn\" || level === \"error\") {\n const prefix = level === \"error\" ? \"[error]\" : \"[warn]\";\n process.stderr.write(`${prefix} ${msg}\\n`);\n }\n }\n\n trace(msg: string, extra?: Record<string, unknown>) { this.write(\"trace\", msg, extra); }\n debug(msg: string, extra?: Record<string, unknown>) { this.write(\"debug\", msg, extra); }\n info(msg: string, extra?: Record<string, unknown>) { this.write(\"info\", msg, extra); }\n warn(msg: string, extra?: Record<string, unknown>) { this.write(\"warn\", msg, extra); }\n error(msg: string, extra?: Record<string, unknown>) { this.write(\"error\", msg, extra); }\n}\n\nexport const log = new Logger();\n\n/** API key 脱敏:前 4 后 4,中间打码。 */\nexport function redactApiKey(key: string | undefined): string {\n if (!key) return \"<unset>\";\n if (key.length <= 12) return \"***\";\n return `${key.slice(0, 4)}...${key.slice(-4)}`;\n}\n","/**\n * 全局共享类型。其它模块按需 re-export 子集。\n * Why 集中:避免类型循环依赖。\n */\n\n// ---------- 消息(与 LLM 交互的最小单元)----------\n\nexport type MessageRole = \"system\" | \"user\" | \"assistant\" | \"tool\";\n\nexport interface TextPart {\n type: \"text\";\n text: string;\n}\n\nexport interface ToolUsePart {\n type: \"tool_use\";\n id: string;\n name: string;\n args: unknown;\n}\n\nexport interface ToolResultPart {\n type: \"tool_result\";\n toolUseId: string;\n content: string;\n isError?: boolean;\n}\n\nexport type ContentPart = TextPart | ToolUsePart | ToolResultPart;\n\nexport interface SystemMessage {\n role: \"system\";\n content: string;\n}\n\nexport interface UserMessage {\n role: \"user\";\n content: string | ContentPart[];\n}\n\nexport interface AssistantMessage {\n role: \"assistant\";\n content: ContentPart[];\n}\n\nexport interface ToolMessage {\n role: \"tool\";\n toolUseId: string;\n content: string;\n isError?: boolean;\n}\n\nexport type Message = SystemMessage | UserMessage | AssistantMessage | ToolMessage;\n\n// ---------- LLM 工具定义(暴露给模型)----------\n\nexport interface ToolDefinition {\n name: string;\n description: string;\n parameters: Record<string, unknown>; // JSON Schema\n}\n\n// ---------- Token 用量 ----------\n\nexport interface TokenUsage {\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n}\n\nexport type FinishReason = \"stop\" | \"tool_calls\" | \"length\" | \"content_filter\" | \"error\" | \"unknown\";\n\n// ---------- 错误 ----------\n\nexport class MuseError extends Error {\n constructor(message: string, public readonly code?: string, public readonly cause?: unknown) {\n super(message);\n this.name = \"MuseError\";\n }\n}\n\nexport class ToolError extends MuseError {\n constructor(message: string, public readonly toolName: string, cause?: unknown) {\n super(message, \"TOOL_ERROR\", cause);\n this.name = \"ToolError\";\n }\n}\n\nexport class PermissionDeniedError extends MuseError {\n constructor(public readonly toolName: string, public readonly reason: string) {\n super(`Permission denied for ${toolName}: ${reason}`, \"PERMISSION_DENIED\");\n this.name = \"PermissionDeniedError\";\n }\n}\n","/**\n * LLMClient 工厂:根据配置创建对应 provider 的客户端。\n *\n * 当前只实现 openai-compatible 协议族(覆盖 95% 国产模型 + OpenAI 本身)。\n * Anthropic 走自己的协议,留待 v0.3 加。\n */\n\nimport { createPresetClient, PRESETS, OpenAICompatibleClient } from \"./providers/index.js\";\nimport type { LLMClient, ModelCapabilities, ProviderConfig } from \"./types.js\";\nimport { MuseError } from \"../types/index.js\";\nimport type { ModelEntry } from \"../config/models.js\";\n\nexport interface CreateClientOpts {\n provider: string;\n model: string;\n providers: Record<string, ProviderConfig>;\n}\n\n/**\n * 当前 active model 的 apiKey 注入到此进程 env 字段下。\n *\n * 业务代码(LLM client)只看到 env name,不直接持有 key 副本。\n * /models 切换或启动加载时由 setActiveModelEnv() 写入;从这里读出来给 client。\n */\nexport const ACTIVE_API_KEY_ENV = \"MUSE_ACTIVE_API_KEY\";\n\n/** 把 entry 的 apiKey 注入 process.env,供 createLLMClientFromModelEntry 读取。 */\nexport function setActiveModelEnv(entry: ModelEntry): void {\n if (entry.apiKey) {\n process.env[ACTIVE_API_KEY_ENV] = entry.apiKey;\n } else {\n delete process.env[ACTIVE_API_KEY_ENV];\n }\n}\n\n/**\n * 从用户在 models.json 里定义的 ModelEntry 构造 LLMClient。\n *\n * apiKey 不直接传值——而是从 process.env[ACTIVE_API_KEY_ENV] 读,调用前必须先\n * setActiveModelEnv(entry) 写入。这样业务代码只看到 env name,不直接持有 key。\n *\n * vendor 字段仅用于显示(providerName 显示在 banner / /status)。\n * 当前所有 entry 走 openai-compatible 协议;未来引入其他协议时按 entry.protocol 分流。\n */\nexport function createLLMClientFromModelEntry(entry: ModelEntry): LLMClient {\n const apiKey = process.env[ACTIVE_API_KEY_ENV] ?? \"\";\n if (!apiKey && !entry.baseUrl.includes(\"localhost\")) {\n throw new MuseError(\n `Model \"${entry.id}\" has no apiKey in env ${ACTIVE_API_KEY_ENV}. ` +\n `Check models.json (or models.local.json) and ensure setActiveModelEnv() was called.`,\n \"MISSING_API_KEY\",\n );\n }\n const capabilities: Partial<ModelCapabilities> = {};\n if (entry.supportsToolCall !== undefined) capabilities.toolCalling = entry.supportsToolCall;\n if (entry.supportsImages !== undefined) capabilities.vision = entry.supportsImages;\n if (entry.contextWindow !== undefined) capabilities.maxContextWindow = entry.contextWindow;\n\n return new OpenAICompatibleClient({\n providerName: entry.vendor ?? \"custom\",\n baseUrl: entry.baseUrl,\n apiKey,\n model: entry.id,\n capabilities,\n });\n}\n\nexport function createLLMClient(opts: CreateClientOpts): LLMClient {\n const { provider, model, providers } = opts;\n const config = providers[provider];\n\n if (!config) {\n throw new MuseError(\n `Provider \"${provider}\" is not configured. Add a \"providers.${provider}\" entry to your settings.json.`,\n \"PROVIDER_NOT_CONFIGURED\",\n );\n }\n\n // 预设 provider(含国产模型)\n if (PRESETS[provider]) {\n if (!config.apiKey && provider !== \"ollama\") {\n throw new MuseError(\n `Provider \"${provider}\" requires apiKey. Set it in settings.json or via the corresponding env var.`,\n \"MISSING_API_KEY\",\n );\n }\n return createPresetClient(provider, config, model);\n }\n\n // 自定义 openai-compatible 端点\n if (config.baseUrl) {\n return new OpenAICompatibleClient({\n providerName: provider,\n baseUrl: config.baseUrl as string,\n apiKey: (config.apiKey as string | undefined) ?? \"\",\n model,\n });\n }\n\n throw new MuseError(\n `Unknown provider \"${provider}\". Either use a preset (${Object.keys(PRESETS).join(\", \")}) or set \"baseUrl\" in providers.${provider}.`,\n \"UNKNOWN_PROVIDER\",\n );\n}\n","/**\n * 工具注册中心:管理所有可用工具,提供查询、调用、转 LLM-tool-definition 的能力。\n */\n\nimport { z } from \"zod\";\nimport type { AnyTool, ToolContext, ToolExecuteResult } from \"./types.js\";\nimport type { ToolDefinition as LLMToolDefinition } from \"../types/index.js\";\nimport { ToolError } from \"../types/index.js\";\n\n/** zod schema → JSON Schema (subset)。仅覆盖 v0.1 需要的类型。 */\nfunction zodToJsonSchema(schema: z.ZodType<unknown>): Record<string, unknown> {\n const def = (schema as unknown as { _def: { typeName: string } })._def;\n\n if (def.typeName === \"ZodObject\") {\n const shape = (schema as unknown as z.ZodObject<Record<string, z.ZodTypeAny>>).shape;\n const properties: Record<string, unknown> = {};\n const required: string[] = [];\n for (const [key, value] of Object.entries(shape)) {\n properties[key] = zodToJsonSchema(value as z.ZodType<unknown>);\n if (!(value as unknown as { isOptional?: () => boolean }).isOptional?.()) {\n required.push(key);\n }\n }\n return {\n type: \"object\",\n properties,\n ...(required.length > 0 ? { required } : {}),\n additionalProperties: false,\n };\n }\n\n if (def.typeName === \"ZodString\") {\n const d = def as unknown as { description?: string };\n return { type: \"string\", ...(d.description ? { description: d.description } : {}) };\n }\n\n if (def.typeName === \"ZodNumber\") {\n return { type: \"number\" };\n }\n\n if (def.typeName === \"ZodBoolean\") {\n return { type: \"boolean\" };\n }\n\n if (def.typeName === \"ZodArray\") {\n const inner = (def as unknown as { type: z.ZodType<unknown> }).type;\n return { type: \"array\", items: zodToJsonSchema(inner) };\n }\n\n if (def.typeName === \"ZodOptional\" || def.typeName === \"ZodDefault\") {\n const inner = (def as unknown as { innerType: z.ZodType<unknown> }).innerType;\n return zodToJsonSchema(inner);\n }\n\n if (def.typeName === \"ZodEnum\") {\n const values = (def as unknown as { values: string[] }).values;\n return { type: \"string\", enum: values };\n }\n\n if (def.typeName === \"ZodUnion\") {\n const opts = (def as unknown as { options: z.ZodType<unknown>[] }).options;\n return { anyOf: opts.map(zodToJsonSchema) };\n }\n\n // Fallback: 任意类型\n return {};\n}\n\nfunction getDescription(schema: z.ZodType<unknown>): string | undefined {\n return (schema as unknown as { description?: string }).description;\n}\n\nexport class ToolRegistry {\n private tools = new Map<string, AnyTool>();\n\n register(tool: AnyTool): void {\n if (this.tools.has(tool.name)) {\n throw new Error(`Tool \"${tool.name}\" already registered.`);\n }\n this.tools.set(tool.name, tool);\n }\n\n registerAll(tools: AnyTool[]): void {\n for (const tool of tools) this.register(tool);\n }\n\n get(name: string): AnyTool | undefined {\n return this.tools.get(name);\n }\n\n has(name: string): boolean {\n return this.tools.has(name);\n }\n\n list(): AnyTool[] {\n return Array.from(this.tools.values());\n }\n\n /** 转为 LLM 可读的 tool definition 数组。可选 filter(如 plan 模式过滤只读工具)。 */\n toLLMDefinitions(filter?: (tool: AnyTool) => boolean): LLMToolDefinition[] {\n let tools = this.list();\n if (filter) tools = tools.filter(filter);\n return tools.map((t) => {\n const schema = zodToJsonSchema(t.parameters);\n // 顶层描述:从 zod schema 的 .describe 拿\n const desc = getDescription(t.parameters);\n if (desc && typeof schema === \"object\" && schema !== null) {\n (schema as Record<string, unknown>).description = desc;\n }\n return {\n name: t.name,\n description: t.description,\n parameters: schema,\n };\n });\n }\n\n /** 调用工具:校验参数 → 执行。 */\n async execute(name: string, rawArgs: unknown, ctx: ToolContext): Promise<ToolExecuteResult> {\n const tool = this.tools.get(name);\n if (!tool) {\n throw new ToolError(`Tool \"${name}\" not found.`, name);\n }\n const parseResult = tool.parameters.safeParse(rawArgs);\n if (!parseResult.success) {\n return {\n content: `Invalid arguments for ${name}: ${parseResult.error.message}`,\n isError: true,\n };\n }\n try {\n return await tool.execute(parseResult.data, ctx);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return { content: `Tool ${name} threw: ${msg}`, isError: true };\n }\n }\n}\n","/**\n * 工具系统类型。\n * 内置工具与 MCP 工具都遵循同一接口。\n */\n\nimport type { z } from \"zod\";\n\nexport type PermissionLevel = \"read\" | \"write\" | \"execute\" | \"network\";\n\nexport interface ToolContext {\n cwd: string;\n abortSignal?: AbortSignal;\n /** 询问用户对该工具调用的批准。返回 true=允许,false=拒绝。 */\n askPermission: (toolName: string, args: unknown, summary: string) => Promise<boolean>;\n /** 主代理可能想在工具内部发起子任务,预留口子。 */\n invokeSubagent?: (prompt: string) => Promise<string>;\n}\n\nexport interface ToolExecuteResult {\n /** 给 LLM 看的文本结果。 */\n content: string;\n /** 标记为错误:让 LLM 知道需要修复。 */\n isError?: boolean;\n /** 给 TUI 展示的摘要(一行)。 */\n summary?: string;\n}\n\nexport interface ToolDefinition<TArgs = unknown> {\n name: string;\n description: string;\n /** zod schema 用于参数校验 + 自动转 JSON Schema。 */\n parameters: z.ZodType<TArgs>;\n /** 权限级别:UI 与 permission 模块据此决定 ask/allow/deny。 */\n permission: PermissionLevel;\n /** 一行摘要,给 TUI 在 \"→ ToolName(...)\" 之后显示。 */\n summarize?: (args: TArgs) => string;\n /** 实际执行函数。 */\n execute: (args: TArgs, ctx: ToolContext) => Promise<ToolExecuteResult>;\n}\n\n/** 类型擦除后的工具,用于 registry 存储 / 调用。 */\nexport interface AnyTool {\n name: string;\n description: string;\n parameters: z.ZodType<unknown>;\n permission: PermissionLevel;\n summarize?: (args: unknown) => string;\n execute: (args: unknown, ctx: ToolContext) => Promise<ToolExecuteResult>;\n}\n\nexport function defineTool<TArgs>(def: ToolDefinition<TArgs>): AnyTool {\n return {\n name: def.name,\n description: def.description,\n parameters: def.parameters as z.ZodType<unknown>,\n permission: def.permission,\n summarize: def.summarize as ((args: unknown) => string) | undefined,\n execute: def.execute as (args: unknown, ctx: ToolContext) => Promise<ToolExecuteResult>,\n };\n}\n","/**\n * Read 工具:读取本地文件,支持 offset/limit 分页。\n * 设计对齐 Claude Code:返回带行号的 `cat -n` 格式。\n */\n\nimport { readFile, stat } from \"node:fs/promises\";\nimport { resolve, isAbsolute } from \"node:path\";\nimport { z } from \"zod\";\nimport { defineTool } from \"../types.js\";\nimport { ToolError } from \"../../types/index.js\";\n\nconst ReadArgs = z.object({\n file_path: z.string().describe(\"Absolute or cwd-relative path to the file.\"),\n offset: z.number().int().min(0).optional().describe(\"Line offset (0-based).\"),\n limit: z.number().int().positive().optional().describe(\"Max lines to read. Default 2000.\"),\n});\n\nconst DEFAULT_LIMIT = 2000;\nconst MAX_LINE_LENGTH = 2000; // 单行超长时截断\n\nexport const ReadTool = defineTool({\n name: \"Read\",\n description: \"Read a file from the local filesystem. Returns content with 1-indexed line numbers (cat -n format). Use offset/limit for large files.\",\n parameters: ReadArgs,\n permission: \"read\",\n summarize: (args) => `Read(${args.file_path}${args.offset != null ? `, offset=${args.offset}` : \"\"}${args.limit != null ? `, limit=${args.limit}` : \"\"})`,\n async execute(args, ctx) {\n const path = isAbsolute(args.file_path) ? args.file_path : resolve(ctx.cwd, args.file_path);\n\n let info;\n try {\n info = await stat(path);\n } catch (err) {\n throw new ToolError(`File not found: ${path}`, \"Read\", err);\n }\n\n if (!info.isFile()) {\n throw new ToolError(`Not a regular file: ${path}`, \"Read\");\n }\n\n const content = await readFile(path, \"utf-8\");\n const lines = content.split(/\\r?\\n/);\n const offset = args.offset ?? 0;\n const limit = args.limit ?? DEFAULT_LIMIT;\n const slice = lines.slice(offset, offset + limit);\n\n const numbered = slice.map((line, i) => {\n const lineNo = offset + i + 1;\n const truncated = line.length > MAX_LINE_LENGTH ? line.slice(0, MAX_LINE_LENGTH) + \"... [truncated]\" : line;\n return `${String(lineNo).padStart(5, \" \")}\\t${truncated}`;\n });\n\n let result = numbered.join(\"\\n\");\n if (offset + limit < lines.length) {\n result += `\\n... [${lines.length - offset - limit} more lines, use offset=${offset + limit} to read next]`;\n }\n\n return {\n content: result || \"(empty file)\",\n summary: `Read ${slice.length} lines from ${args.file_path}`,\n };\n },\n});\n","/**\n * Write 工具:写入文件(创建或覆盖)。\n *\n * 为防误覆盖,约定调用前必须先 Read 过同一路径(除非文件不存在)。\n * 这个约束实际由 LLM 遵守 (prompt 引导);本工具不强制,但记录到日志。\n */\n\nimport { writeFile, mkdir, stat } from \"node:fs/promises\";\nimport { resolve, isAbsolute, dirname } from \"node:path\";\nimport { z } from \"zod\";\nimport { defineTool } from \"../types.js\";\n\nconst WriteArgs = z.object({\n file_path: z.string().describe(\"Absolute or cwd-relative path to the file.\"),\n content: z.string().describe(\"Full content of the file.\"),\n});\n\nexport const WriteTool = defineTool({\n name: \"Write\",\n description: \"Write a complete file to the local filesystem. Creates parent directories if needed. Overwrites existing files — prefer Edit for partial updates.\",\n parameters: WriteArgs,\n permission: \"write\",\n summarize: (args) => `Write(${args.file_path}, ${args.content.length} chars)`,\n async execute(args, ctx) {\n const path = isAbsolute(args.file_path) ? args.file_path : resolve(ctx.cwd, args.file_path);\n\n let existed = false;\n try {\n const info = await stat(path);\n existed = info.isFile();\n } catch {\n // 文件不存在,正常情况\n }\n\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, args.content, \"utf-8\");\n\n return {\n content: existed\n ? `Overwrote ${path} (${args.content.length} bytes).`\n : `Created ${path} (${args.content.length} bytes).`,\n summary: `${existed ? \"Overwrote\" : \"Created\"} ${args.file_path}`,\n };\n },\n});\n","/**\n * Edit 工具:在文件中做精确字符串替换。\n *\n * 必须先 Read 过文件(由调用方/LLM 遵守,不强制校验)。\n * old_string 必须在文件中唯一出现;replace_all=true 时不要求唯一。\n */\n\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { resolve, isAbsolute } from \"node:path\";\nimport { z } from \"zod\";\nimport { defineTool } from \"../types.js\";\nimport { ToolError } from \"../../types/index.js\";\n\nconst EditArgs = z.object({\n file_path: z.string().describe(\"Absolute or cwd-relative path to the file.\"),\n old_string: z.string().describe(\"Exact substring to replace. Must be unique unless replace_all=true.\"),\n new_string: z.string().describe(\"Replacement string.\"),\n replace_all: z.boolean().optional().describe(\"Replace every occurrence. Default false.\"),\n});\n\nexport const EditTool = defineTool({\n name: \"Edit\",\n description: \"Perform an exact string replacement in a file. Old string must be unique unless replace_all=true. Cheaper than Write when only a small part needs to change.\",\n parameters: EditArgs,\n permission: \"write\",\n summarize: (args) => `Edit(${args.file_path})`,\n async execute(args, ctx) {\n const path = isAbsolute(args.file_path) ? args.file_path : resolve(ctx.cwd, args.file_path);\n\n let content: string;\n try {\n content = await readFile(path, \"utf-8\");\n } catch (err) {\n throw new ToolError(`Cannot read ${path}: ${err instanceof Error ? err.message : String(err)}`, \"Edit\", err);\n }\n\n if (args.old_string === args.new_string) {\n return { content: \"old_string is identical to new_string; nothing to do.\", isError: true };\n }\n\n const occurrences = countOccurrences(content, args.old_string);\n if (occurrences === 0) {\n return {\n content: `old_string not found in ${args.file_path}. Did you read the file first? Check whitespace and indentation.`,\n isError: true,\n };\n }\n if (occurrences > 1 && !args.replace_all) {\n return {\n content: `old_string occurs ${occurrences} times in ${args.file_path}. Either expand context to make it unique, or set replace_all=true.`,\n isError: true,\n };\n }\n\n const newContent = args.replace_all\n ? content.split(args.old_string).join(args.new_string)\n : content.replace(args.old_string, args.new_string);\n\n await writeFile(path, newContent, \"utf-8\");\n\n return {\n content: `Edited ${path}: replaced ${args.replace_all ? occurrences : 1} occurrence(s).`,\n summary: `Edited ${args.file_path}`,\n };\n },\n});\n\nfunction countOccurrences(haystack: string, needle: string): number {\n if (needle.length === 0) return 0;\n let count = 0;\n let pos = 0;\n while ((pos = haystack.indexOf(needle, pos)) !== -1) {\n count += 1;\n pos += needle.length;\n }\n return count;\n}\n","/**\n * Bash 工具:执行 shell 命令。\n *\n * 安全:内置 deny 列表(无法 allow 绕过)。\n * 上限:超时 + stdout 截断。\n */\n\nimport { execa } from \"execa\";\nimport { z } from \"zod\";\nimport { defineTool } from \"../types.js\";\n\nconst BashArgs = z.object({\n command: z.string().describe(\"Shell command to run. Will be executed via sh -c.\"),\n timeout: z.number().int().positive().optional().describe(\"Timeout in milliseconds. Default 120000 (2 min). Max 600000.\"),\n description: z.string().optional().describe(\"Brief description (3-10 words) for the UI.\"),\n});\n\nconst DEFAULT_TIMEOUT_MS = 120_000;\nconst MAX_TIMEOUT_MS = 600_000;\nconst MAX_OUTPUT_BYTES = 100_000;\n\n/** 即使在 allow 列表里也强制阻断的危险命令模式。 */\nconst HARD_DENY_PATTERNS: RegExp[] = [\n /\\brm\\s+-rf\\s+\\/(?:\\s|$)/, // rm -rf /\n /\\brm\\s+-rf\\s+~(?:\\/|\\s|$)/, // rm -rf ~ or ~/...\n /\\brm\\s+-rf\\s+\\*/, // rm -rf *\n /\\bdd\\s+.*of=\\/dev\\//, // dd of=/dev/*\n /\\bmkfs\\b/, // mkfs\n /:\\(\\)\\s*\\{\\s*:\\|:&\\s*\\}\\s*;\\s*:/, // fork bomb\n /\\bsudo\\b/, // sudo(v0.1 简单粗暴禁掉)\n /\\bcurl\\s+[^|]*\\|\\s*(?:sh|bash|zsh)/, // curl ... | sh\n /\\bwget\\s+[^|]*\\|\\s*(?:sh|bash|zsh)/, // wget ... | sh\n];\n\nfunction checkDangerous(command: string): { dangerous: true; reason: string } | { dangerous: false } {\n for (const pattern of HARD_DENY_PATTERNS) {\n if (pattern.test(command)) {\n return { dangerous: true, reason: `matches pattern ${pattern}` };\n }\n }\n return { dangerous: false };\n}\n\nexport const BashTool = defineTool({\n name: \"Bash\",\n description: \"Execute a shell command via sh -c. Use for git, file system listings, builds, tests, etc. Avoid interactive commands (prefer non-interactive flags). For file edits use Edit/Write, not sed/echo.\",\n parameters: BashArgs,\n permission: \"execute\",\n summarize: (args) => args.description ?? `Bash: ${args.command.length > 60 ? args.command.slice(0, 60) + \"...\" : args.command}`,\n async execute(args, ctx) {\n const danger = checkDangerous(args.command);\n if (danger.dangerous) {\n return {\n content: `Refused: command blocked by hard deny list (${danger.reason}). If you really need this, ask the user to run it manually.`,\n isError: true,\n };\n }\n\n const timeout = Math.min(args.timeout ?? DEFAULT_TIMEOUT_MS, MAX_TIMEOUT_MS);\n\n try {\n const result = await execa(args.command, {\n shell: \"/bin/sh\",\n cwd: ctx.cwd,\n timeout,\n reject: false,\n stripFinalNewline: false,\n maxBuffer: MAX_OUTPUT_BYTES * 2,\n cancelSignal: ctx.abortSignal,\n });\n\n const stdout = truncate(result.stdout ?? \"\", MAX_OUTPUT_BYTES, \"stdout\");\n const stderr = truncate(result.stderr ?? \"\", MAX_OUTPUT_BYTES, \"stderr\");\n\n const parts: string[] = [];\n if (stdout) parts.push(`<stdout>\\n${stdout}\\n</stdout>`);\n if (stderr) parts.push(`<stderr>\\n${stderr}\\n</stderr>`);\n if (result.timedOut) parts.push(`<timeout>Command exceeded ${timeout}ms.</timeout>`);\n if (result.failed && !result.timedOut) parts.push(`<exit_code>${result.exitCode ?? \"unknown\"}</exit_code>`);\n\n const body = parts.length > 0 ? parts.join(\"\\n\") : \"(no output)\";\n return {\n content: body,\n isError: result.failed,\n summary: result.failed ? `Bash exited ${result.exitCode ?? \"?\"}` : `Bash ok`,\n };\n } catch (err) {\n return {\n content: `Bash threw: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n };\n }\n },\n});\n\nfunction truncate(text: string, max: number, label: string): string {\n if (text.length <= max) return text;\n return text.slice(0, max) + `\\n... [${label} truncated, original ${text.length} bytes]`;\n}\n","/**\n * Grep 工具:基于 ripgrep 包装(若可用),fallback 到 bash grep。\n * v0.1 简单实现:直接调 system rg / grep。\n */\n\nimport { execa } from \"execa\";\nimport { z } from \"zod\";\nimport { defineTool } from \"../types.js\";\n\nconst GrepArgs = z.object({\n pattern: z.string().describe(\"Regex pattern to search for.\"),\n path: z.string().optional().describe(\"File or directory to search in. Default: cwd.\"),\n glob: z.string().optional().describe('Glob filter, e.g. \"*.ts\" or \"src/**/*.tsx\".'),\n output_mode: z.enum([\"content\", \"files_with_matches\", \"count\"]).optional().describe(\"Default: files_with_matches.\"),\n context: z.number().int().min(0).max(50).optional().describe(\"Context lines around each match (use only with output_mode=content).\"),\n case_insensitive: z.boolean().optional(),\n});\n\nlet rgChecked = false;\nlet rgAvailable = false;\n\nasync function checkRipgrep(): Promise<boolean> {\n if (rgChecked) return rgAvailable;\n try {\n await execa(\"rg\", [\"--version\"], { reject: false });\n rgAvailable = true;\n } catch {\n rgAvailable = false;\n }\n rgChecked = true;\n return rgAvailable;\n}\n\nexport const GrepTool = defineTool({\n name: \"Grep\",\n description: \"Search file contents using regex. Prefer this over Bash(grep|find) — handles ignore files & is much faster on large trees.\",\n parameters: GrepArgs,\n permission: \"read\",\n summarize: (args) => `Grep(${args.pattern}${args.path ? `, ${args.path}` : \"\"})`,\n async execute(args, ctx) {\n const hasRg = await checkRipgrep();\n const mode = args.output_mode ?? \"files_with_matches\";\n\n if (hasRg) {\n const cliArgs: string[] = [];\n if (args.case_insensitive) cliArgs.push(\"-i\");\n if (mode === \"files_with_matches\") cliArgs.push(\"-l\");\n else if (mode === \"count\") cliArgs.push(\"-c\");\n else if (args.context != null) cliArgs.push(\"-C\", String(args.context));\n if (args.glob) cliArgs.push(\"--glob\", args.glob);\n cliArgs.push(\"--\", args.pattern, args.path ?? \".\");\n\n const result = await execa(\"rg\", cliArgs, { cwd: ctx.cwd, reject: false, cancelSignal: ctx.abortSignal });\n const out = (result.stdout ?? \"\").trim();\n if (result.exitCode === 0 || result.exitCode === 1) {\n return { content: out || \"(no matches)\", summary: `Grep ${args.pattern}` };\n }\n return { content: `rg failed: ${result.stderr}`, isError: true };\n }\n\n // Fallback: bash grep -r\n const cliArgs = [\"-r\", \"-n\"];\n if (args.case_insensitive) cliArgs.push(\"-i\");\n if (mode === \"files_with_matches\") cliArgs.push(\"-l\");\n else if (mode === \"count\") cliArgs.push(\"-c\");\n cliArgs.push(\"-E\", args.pattern, args.path ?? \".\");\n\n const result = await execa(\"grep\", cliArgs, { cwd: ctx.cwd, reject: false, cancelSignal: ctx.abortSignal });\n const out = (result.stdout ?? \"\").trim();\n if (result.exitCode === 0 || result.exitCode === 1) {\n return { content: out || \"(no matches)\", summary: `Grep ${args.pattern}` };\n }\n return { content: `grep failed: ${result.stderr}`, isError: true };\n },\n});\n","/**\n * Glob 工具:用 fast-glob 列出匹配文件。\n */\n\nimport fg from \"fast-glob\";\nimport { z } from \"zod\";\nimport { defineTool } from \"../types.js\";\n\nconst GlobArgs = z.object({\n pattern: z.string().describe('Glob pattern, e.g. \"src/**/*.ts\" or \"**/*.{md,json}\".'),\n path: z.string().optional().describe(\"Base directory to search from. Default: cwd.\"),\n limit: z.number().int().positive().max(1000).optional().describe(\"Max results. Default 100.\"),\n});\n\nconst DEFAULT_LIMIT = 100;\n\nexport const GlobTool = defineTool({\n name: \"Glob\",\n description: \"Find files by glob pattern. Returns relative paths sorted by modification time (newest first).\",\n parameters: GlobArgs,\n permission: \"read\",\n summarize: (args) => `Glob(${args.pattern}${args.path ? `, ${args.path}` : \"\"})`,\n async execute(args, ctx) {\n const cwd = args.path ?? ctx.cwd;\n const limit = args.limit ?? DEFAULT_LIMIT;\n\n const entries = await fg(args.pattern, {\n cwd,\n onlyFiles: true,\n stats: true,\n dot: false,\n ignore: [\"**/node_modules/**\", \"**/.git/**\", \"**/dist/**\", \"**/.muse/**\"],\n });\n\n // 按 mtime 倒序\n entries.sort((a, b) => {\n const ta = a.stats?.mtime?.getTime() ?? 0;\n const tb = b.stats?.mtime?.getTime() ?? 0;\n return tb - ta;\n });\n\n const truncated = entries.length > limit;\n const paths = entries.slice(0, limit).map((e) => e.path);\n\n let result = paths.join(\"\\n\") || \"(no matches)\";\n if (truncated) {\n result += `\\n... [${entries.length - limit} more, increase limit to see]`;\n }\n return { content: result, summary: `Glob found ${entries.length} file(s)` };\n },\n});\n","import type { AnyTool } from \"../types.js\";\nimport { ReadTool } from \"./read.js\";\nimport { WriteTool } from \"./write.js\";\nimport { EditTool } from \"./edit.js\";\nimport { BashTool } from \"./bash.js\";\nimport { GrepTool } from \"./grep.js\";\nimport { GlobTool } from \"./glob.js\";\n\nexport { ReadTool, WriteTool, EditTool, BashTool, GrepTool, GlobTool };\n\nexport const BUILTIN_TOOLS: AnyTool[] = [\n ReadTool,\n WriteTool,\n EditTool,\n BashTool,\n GrepTool,\n GlobTool,\n];\n","/**\n * 权限模型:三态 allow / ask / deny,叠加 4 档 PermissionMode。\n *\n * 模式匹配(pattern):\n * - \"ToolName\" 精确匹配\n * - \"Bash(<prefix>)\" 匹配 Bash 工具 + 命令前缀\n * - \"Bash(<prefix>:*)\" 通配\n *\n * PermissionMode(详见文档库 permission-modes.md):\n * - default:完全走 settings.permissions 规则\n * - acceptEdits:Edit/Write 自动 allow,其他走 default\n * - plan:只允许 read 类工具,其他全 deny\n * - bypassPermissions:除显式 deny 与 Bash 硬 deny 外全 allow\n *\n * 危险操作(rm -rf / sudo 等)由 Bash 工具内部 HARD_DENY_PATTERNS 兜底,所有模式都不可绕过。\n */\n\nimport type { Permissions } from \"../config/types.js\";\nimport type { PermissionLevel } from \"../tools/types.js\";\n\nexport type Decision = \"allow\" | \"ask\" | \"deny\";\n\nexport type PermissionMode = \"default\" | \"acceptEdits\" | \"plan\" | \"bypassPermissions\";\n\nexport const MODE_CYCLE: readonly PermissionMode[] = [\n \"default\",\n \"acceptEdits\",\n \"plan\",\n \"bypassPermissions\",\n] as const;\n\nexport const MODE_LABEL: Record<PermissionMode, string> = {\n default: \"default permissions on\",\n acceptEdits: \"accept edits on\",\n plan: \"plan mode on\",\n bypassPermissions: \"bypass permissions on\",\n};\n\nexport const MODE_COLOR: Record<PermissionMode, string> = {\n default: \"gray\",\n acceptEdits: \"#EAB308\",\n plan: \"#06B6D4\",\n bypassPermissions: \"#EF4444\",\n};\n\nexport interface PermissionInput {\n toolName: string;\n args: unknown;\n /** Tool 的权限级别;由 Agent loop 从 ToolRegistry 注入。Plan 模式用此区分 read/write。 */\n permission?: PermissionLevel;\n}\n\nexport class PermissionGate {\n private rules: Required<Permissions>;\n private mode: PermissionMode = \"default\";\n\n constructor(rules: Permissions = {}) {\n this.rules = {\n allow: rules.allow ?? [],\n ask: rules.ask ?? [],\n deny: rules.deny ?? [],\n defaultMode: rules.defaultMode ?? \"ask\",\n };\n }\n\n setMode(mode: PermissionMode): void {\n this.mode = mode;\n }\n\n getMode(): PermissionMode {\n return this.mode;\n }\n\n cycleMode(): PermissionMode {\n const i = MODE_CYCLE.indexOf(this.mode);\n this.mode = MODE_CYCLE[(i + 1) % MODE_CYCLE.length];\n return this.mode;\n }\n\n decide(input: PermissionInput): Decision {\n // 用户显式 deny 永远生效,所有模式不可绕过\n if (this.matches(this.rules.deny, input)) return \"deny\";\n\n switch (this.mode) {\n case \"bypassPermissions\":\n return \"allow\";\n\n case \"plan\":\n // 只允许只读工具;写/执行/网络类直接 deny\n return input.permission === \"read\" ? \"allow\" : \"deny\";\n\n case \"acceptEdits\":\n if (input.toolName === \"Edit\" || input.toolName === \"Write\") return \"allow\";\n return this.defaultDecide(input);\n\n case \"default\":\n default:\n return this.defaultDecide(input);\n }\n }\n\n private defaultDecide(input: PermissionInput): Decision {\n if (this.matches(this.rules.allow, input)) return \"allow\";\n if (this.matches(this.rules.ask, input)) return \"ask\";\n switch (this.rules.defaultMode) {\n case \"strict\":\n return \"ask\";\n case \"relaxed\":\n return \"allow\";\n case \"ask\":\n default:\n return \"ask\";\n }\n }\n\n private matches(patterns: string[], input: PermissionInput): boolean {\n for (const pattern of patterns) {\n if (this.matchOne(pattern, input)) return true;\n }\n return false;\n }\n\n private matchOne(pattern: string, input: PermissionInput): boolean {\n // \"ToolName\" 精确匹配\n if (!pattern.includes(\"(\")) {\n return pattern === input.toolName;\n }\n // \"Bash(<prefix>:*)\" 形式\n const m = pattern.match(/^([A-Za-z_][A-Za-z0-9_]*)\\(([^)]*)\\)$/);\n if (!m) return false;\n const [, toolName, sub] = m;\n if (toolName !== input.toolName) return false;\n if (input.toolName === \"Bash\" && typeof input.args === \"object\" && input.args !== null) {\n const cmd = (input.args as { command?: string }).command ?? \"\";\n if (sub.endsWith(\":*\")) {\n const prefix = sub.slice(0, -2);\n return cmd.startsWith(prefix);\n }\n return cmd === sub || cmd.startsWith(sub + \" \");\n }\n return false;\n }\n}\n","/**\n * Session 持久化:append-only JSONL。\n * 路径:~/.muse/projects/<project-hash>/sessions/<uuid>.jsonl\n *\n * 每行一个事件:消息 / 工具调用 / 工具结果 / 使用统计 / ...\n */\n\nimport { appendFile, mkdir, readdir, readFile, stat } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { createHash, randomUUID } from \"node:crypto\";\nimport type { Message, TokenUsage } from \"../types/index.js\";\nimport { log } from \"../log/index.js\";\n\nexport type SessionEvent =\n | { type: \"session_start\"; time: string; cwd: string; provider: string; model: string }\n | { type: \"message\"; time: string; message: Message }\n | { type: \"usage\"; time: string; usage: TokenUsage; provider: string; model: string }\n | { type: \"session_end\"; time: string; reason: \"user_exit\" | \"error\" };\n\nexport interface SessionMeta {\n id: string;\n cwd: string;\n createdAt: string;\n path: string;\n}\n\nexport interface SessionSummary extends SessionMeta {\n /** 首个 user 消息前 60 字符。 */\n preview?: string;\n messageCount: number;\n}\n\nfunction projectHash(cwd: string): string {\n return createHash(\"sha256\").update(cwd).digest(\"hex\").slice(0, 16);\n}\n\nfunction sessionsDir(cwd: string): string {\n return join(homedir(), \".muse\", \"projects\", projectHash(cwd), \"sessions\");\n}\n\nexport class Session {\n readonly meta: SessionMeta;\n private writeQueue: Promise<void> = Promise.resolve();\n\n private constructor(meta: SessionMeta) {\n this.meta = meta;\n }\n\n static async create(cwd: string): Promise<Session> {\n const id = randomUUID();\n const dir = sessionsDir(cwd);\n await mkdir(dir, { recursive: true });\n const path = join(dir, `${id}.jsonl`);\n const meta: SessionMeta = {\n id,\n cwd,\n createdAt: new Date().toISOString(),\n path,\n };\n log.debug(\"session created\", { id, path });\n return new Session(meta);\n }\n\n static async findLatest(cwd: string): Promise<SessionMeta | undefined> {\n const list = await Session.listAll(cwd, 1);\n return list[0];\n }\n\n static async resolve(cwd: string, idOrPrefix: string): Promise<SessionMeta | undefined> {\n const dir = sessionsDir(cwd);\n if (!existsSync(dir)) return undefined;\n const entries = await readdir(dir);\n const matches = entries.filter((e) => e.endsWith(\".jsonl\") && e.startsWith(idOrPrefix));\n if (matches.length === 0) return undefined;\n if (matches.length > 1) {\n throw new Error(`Ambiguous session id \"${idOrPrefix}\" matches ${matches.length} sessions; use more characters.`);\n }\n const top = matches[0];\n const st = await stat(join(dir, top));\n return {\n id: top.replace(/\\.jsonl$/, \"\"),\n cwd,\n createdAt: st.mtime.toISOString(),\n path: join(dir, top),\n };\n }\n\n /**\n * 按修改时间倒序列出当前 cwd 下的 session,附带 preview 与消息数。\n * 读 preview 需要打开每个文件;调用方通过 limit 控制 IO 量。\n */\n static async listAll(cwd: string, limit?: number): Promise<SessionSummary[]> {\n const dir = sessionsDir(cwd);\n if (!existsSync(dir)) return [];\n const entries = await readdir(dir);\n const files = entries.filter((e) => e.endsWith(\".jsonl\"));\n if (files.length === 0) return [];\n\n const stats = await Promise.all(\n files.map(async (f) => {\n const path = join(dir, f);\n const st = await stat(path);\n return { file: f, path, mtime: st.mtime };\n }),\n );\n stats.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());\n\n const truncated = typeof limit === \"number\" ? stats.slice(0, limit) : stats;\n\n const summaries: SessionSummary[] = [];\n for (const s of truncated) {\n const meta: SessionMeta = {\n id: s.file.replace(/\\.jsonl$/, \"\"),\n cwd,\n createdAt: s.mtime.toISOString(),\n path: s.path,\n };\n const summary = await readSummary(meta);\n summaries.push(summary);\n }\n return summaries;\n }\n\n static async open(meta: SessionMeta): Promise<{ session: Session; events: SessionEvent[] }> {\n const session = new Session(meta);\n const events = await session.readAll();\n return { session, events };\n }\n\n /** 从已加载的 events 重建 messages 数组(按时序)。 */\n static messagesFromEvents(events: SessionEvent[]): Message[] {\n const out: Message[] = [];\n for (const ev of events) {\n if (ev.type === \"message\") out.push(ev.message);\n }\n return out;\n }\n\n async append(event: SessionEvent): Promise<void> {\n const line = JSON.stringify(event) + \"\\n\";\n // 串行写入避免交错\n this.writeQueue = this.writeQueue.then(async () => {\n try {\n await mkdir(dirname(this.meta.path), { recursive: true });\n await appendFile(this.meta.path, line, \"utf-8\");\n } catch (err) {\n log.warn(`session append failed: ${err instanceof Error ? err.message : String(err)}`);\n }\n });\n return this.writeQueue;\n }\n\n async readAll(): Promise<SessionEvent[]> {\n if (!existsSync(this.meta.path)) return [];\n const raw = await readFile(this.meta.path, \"utf-8\");\n const events: SessionEvent[] = [];\n for (const line of raw.split(\"\\n\")) {\n if (!line.trim()) continue;\n try {\n events.push(JSON.parse(line) as SessionEvent);\n } catch {\n // skip corrupt lines\n }\n }\n return events;\n }\n}\n\nasync function readSummary(meta: SessionMeta): Promise<SessionSummary> {\n let events: SessionEvent[] = [];\n try {\n const raw = await readFile(meta.path, \"utf-8\");\n for (const line of raw.split(\"\\n\")) {\n if (!line.trim()) continue;\n try {\n events.push(JSON.parse(line) as SessionEvent);\n } catch {\n // skip\n }\n }\n } catch {\n // unreadable; return minimal summary\n }\n const messages = events.filter((e): e is Extract<SessionEvent, { type: \"message\" }> => e.type === \"message\");\n const firstUser = messages.find((e) => e.message.role === \"user\");\n let preview: string | undefined;\n if (firstUser) {\n const c = firstUser.message.content;\n const text = typeof c === \"string\" ? c : c.map((p) => (p.type === \"text\" ? p.text : \"\")).join(\" \").trim();\n preview = text.slice(0, 60).replace(/\\s+/g, \" \");\n }\n return { ...meta, preview, messageCount: messages.length };\n}\n","/**\n * Agent loop:单循环 ReAct。\n *\n * loop:\n * llm.stream(messages, tools)\n * → emit text → 累计 assistant 消息\n * → 收到 tool_call → 累计\n * → finish\n * if no tool_calls: break\n * for each tool_call:\n * check permission → execute → push tool result\n */\n\nimport type { LLMClient, LLMEvent } from \"../llm/types.js\";\nimport type { Message, AssistantMessage, ContentPart, ToolUsePart, TokenUsage } from \"../types/index.js\";\nimport type { ToolRegistry } from \"../tools/registry.js\";\nimport type { ToolContext } from \"../tools/types.js\";\nimport type { PermissionGate, Decision } from \"../permission/index.js\";\nimport type { Session } from \"../session/jsonl.js\";\nimport { log } from \"../log/index.js\";\n\nexport interface AgentEvents {\n onText?: (delta: string) => void;\n onToolCallStart?: (id: string, name: string) => void;\n onToolCallArgs?: (id: string, args: unknown) => void;\n onToolResult?: (id: string, name: string, content: string, isError: boolean, summary?: string) => void;\n onPermissionRequest?: (toolName: string, args: unknown, summary: string) => Promise<boolean>;\n onUsage?: (usage: TokenUsage) => void;\n onError?: (error: Error) => void;\n onTurnEnd?: () => void;\n}\n\nexport interface AgentContext {\n llm: LLMClient;\n tools: ToolRegistry;\n permissions: PermissionGate;\n session: Session;\n cwd: string;\n systemPrompt: string;\n abortSignal?: AbortSignal;\n events?: AgentEvents;\n}\n\nexport class Agent {\n private messages: Message[] = [];\n\n constructor(private ctx: AgentContext) {}\n\n getMessages(): Message[] {\n return this.messages;\n }\n\n setMessages(msgs: Message[]): void {\n this.messages = msgs;\n }\n\n /** 执行一次完整的\"用户输入 → 助手响应(含工具循环) → 等待下一轮输入\"。 */\n async runTurn(userInput: string): Promise<void> {\n const userMessage: Message = { role: \"user\", content: userInput };\n this.messages.push(userMessage);\n await this.ctx.session.append({ type: \"message\", time: new Date().toISOString(), message: userMessage });\n\n // 内部循环:工具调用可能多轮\n while (true) {\n const mode = this.ctx.permissions.getMode();\n const tools = this.ctx.tools.toLLMDefinitions(\n mode === \"plan\" ? (t) => t.permission === \"read\" : undefined,\n );\n const stream = this.ctx.llm.stream({\n messages: this.messages,\n tools,\n systemPrompt: this.ctx.systemPrompt,\n abortSignal: this.ctx.abortSignal,\n });\n\n const assistantParts: ContentPart[] = [];\n const toolCallsToRun: ToolUsePart[] = [];\n let lastError: Error | undefined;\n\n for await (const ev of stream) {\n this.handleEvent(ev, assistantParts, toolCallsToRun, (e) => {\n lastError = e;\n });\n if (lastError) break;\n }\n\n if (lastError) {\n this.ctx.events?.onError?.(lastError);\n log.error(\"agent stream error\", { msg: lastError.message });\n return;\n }\n\n // 把 assistant 消息加入历史\n const assistantMessage: AssistantMessage = { role: \"assistant\", content: assistantParts };\n this.messages.push(assistantMessage);\n await this.ctx.session.append({ type: \"message\", time: new Date().toISOString(), message: assistantMessage });\n\n if (toolCallsToRun.length === 0) {\n this.ctx.events?.onTurnEnd?.();\n return;\n }\n\n // 执行工具调用\n for (const call of toolCallsToRun) {\n await this.runToolCall(call);\n }\n }\n }\n\n private handleEvent(\n ev: LLMEvent,\n assistantParts: ContentPart[],\n toolCallsToRun: ToolUsePart[],\n onError: (e: Error) => void,\n ): void {\n switch (ev.type) {\n case \"text\":\n // 合并到最后一个 text part 或新增\n {\n const last = assistantParts[assistantParts.length - 1];\n if (last && last.type === \"text\") {\n last.text += ev.delta;\n } else {\n assistantParts.push({ type: \"text\", text: ev.delta });\n }\n }\n this.ctx.events?.onText?.(ev.delta);\n break;\n\n case \"tool_call_start\":\n this.ctx.events?.onToolCallStart?.(ev.id, ev.name);\n break;\n\n case \"tool_call_complete\": {\n const callPart: ToolUsePart = { type: \"tool_use\", id: ev.id, name: ev.name, args: ev.args };\n assistantParts.push(callPart);\n toolCallsToRun.push(callPart);\n this.ctx.events?.onToolCallArgs?.(ev.id, ev.args);\n break;\n }\n\n case \"finish\":\n if (ev.usage) {\n this.ctx.events?.onUsage?.(ev.usage);\n this.ctx.session.append({\n type: \"usage\",\n time: new Date().toISOString(),\n usage: ev.usage,\n provider: this.ctx.llm.providerName,\n model: this.ctx.llm.model,\n });\n }\n break;\n\n case \"error\":\n onError(ev.error);\n break;\n }\n }\n\n private async runToolCall(call: ToolUsePart): Promise<void> {\n const tool = this.ctx.tools.get(call.name);\n if (!tool) {\n const result = `Tool \"${call.name}\" is not available.`;\n this.recordToolResult(call.id, call.name, result, true);\n return;\n }\n\n const summary = tool.summarize?.(call.args) ?? `${call.name}(...)`;\n const decision: Decision = this.ctx.permissions.decide({\n toolName: call.name,\n args: call.args,\n permission: tool.permission,\n });\n\n let approved = decision === \"allow\";\n if (decision === \"deny\") {\n const reason =\n this.ctx.permissions.getMode() === \"plan\"\n ? `Denied: you are in plan mode. Only read-only tools are available. Propose changes instead of executing.`\n : `Denied by policy: ${call.name}.`;\n this.recordToolResult(call.id, call.name, reason, true);\n return;\n }\n if (decision === \"ask\") {\n approved = (await this.ctx.events?.onPermissionRequest?.(call.name, call.args, summary)) ?? false;\n if (!approved) {\n this.recordToolResult(call.id, call.name, `User rejected ${call.name}.`, true);\n return;\n }\n }\n\n const toolCtx: ToolContext = {\n cwd: this.ctx.cwd,\n abortSignal: this.ctx.abortSignal,\n askPermission: async () => true, // 已在外层处理\n };\n\n const result = await this.ctx.tools.execute(call.name, call.args, toolCtx);\n this.recordToolResult(call.id, call.name, result.content, result.isError ?? false, result.summary);\n }\n\n private recordToolResult(id: string, name: string, content: string, isError: boolean, summary?: string): void {\n const toolMsg: Message = {\n role: \"tool\",\n toolUseId: id,\n content,\n isError,\n };\n this.messages.push(toolMsg);\n this.ctx.session.append({ type: \"message\", time: new Date().toISOString(), message: toolMsg });\n this.ctx.events?.onToolResult?.(id, name, content, isError, summary);\n }\n}\n","/**\n * System prompt 构造。\n *\n * 风格对齐 Claude Code:简短、命令式、把可用工具与约束摆出来。\n * 中文输出由 ui.lang 控制;英文为默认。\n */\n\nimport { homedir } from \"node:os\";\n\nexport interface SystemPromptOpts {\n cwd: string;\n model: string;\n provider: string;\n lang?: \"en\" | \"zh-CN\";\n toolNames: string[];\n}\n\nexport function buildSystemPrompt(opts: SystemPromptOpts): string {\n const { cwd, model, provider, lang, toolNames } = opts;\n const home = homedir();\n const displayCwd = cwd.startsWith(home) ? cwd.replace(home, \"~\") : cwd;\n\n const sections: string[] = [];\n\n sections.push(`You are Muse, a CLI coding assistant. You are running on the user's local machine via a terminal interface.`);\n\n sections.push(\n `# Environment\\n` +\n `- Working directory: ${displayCwd}\\n` +\n `- LLM backend: ${provider} (${model})\\n` +\n `- Date: ${new Date().toISOString().slice(0, 10)}`,\n );\n\n sections.push(\n `# Available tools\\n` +\n toolNames.map((n) => `- ${n}`).join(\"\\n\") +\n `\\n\\nPrefer the dedicated tool over Bash when one fits (Read for file reading, Edit for partial updates, Write for new files / full rewrites, Grep for content search, Glob for file lookup).`,\n );\n\n sections.push(\n `# Behavior\\n` +\n `- Be concise. State results, not your thinking. Don't narrate every step.\\n` +\n `- Before editing a file you have not seen, Read it first.\\n` +\n `- For Write/Edit/Bash the user may need to approve — proceed normally; the host will gate dangerous calls.\\n` +\n `- If a command may be destructive (rm -rf, force push, drop table, etc.), warn first and let the user run it manually.\\n` +\n `- When the user asks a question that does not need tools, just answer.`,\n );\n\n if (lang === \"zh-CN\") {\n sections.push(`# Output language\\nReply in Chinese (简体中文) unless the user writes in English.`);\n }\n\n return sections.join(\"\\n\\n\");\n}\n","/**\n * 配置加载:\n * 1. 内置默认值\n * 2. ~/.muse/settings.json\n * 3. <cwd>/.muse/settings.json\n * 4. <cwd>/.muse/settings.local.json\n * 5. 环境变量 (MUSE_*)\n * 6. CLI flags (在 cli.tsx 里覆盖)\n *\n * ${ENV_VAR} 占位符在加载后展开。\n */\n\nimport { readFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport type { z } from \"zod\";\nimport { SettingsSchema, type Settings } from \"./types.js\";\nimport { expandEnvVars } from \"./_env.js\";\nimport { log } from \"../log/index.js\";\n\nfunction formatZodIssues(issues: z.ZodIssue[]): string {\n return issues\n .map((i) => `${i.path.join(\".\") || \"<root>\"}: ${i.message}`)\n .join(\"; \");\n}\n\nconst DEFAULTS: Settings = {\n llm: {\n provider: \"deepseek\",\n model: \"deepseek-chat\",\n },\n providers: {\n deepseek: { apiKey: \"${DEEPSEEK_API_KEY}\" },\n openai: { apiKey: \"${OPENAI_API_KEY}\" },\n qwen: { apiKey: \"${DASHSCOPE_API_KEY}\" },\n moonshot: { apiKey: \"${MOONSHOT_API_KEY}\" },\n zhipu: { apiKey: \"${ZHIPU_API_KEY}\" },\n openrouter: { apiKey: \"${OPENROUTER_API_KEY}\" },\n ollama: { baseUrl: \"http://localhost:11434/v1\" },\n },\n permissions: {\n allow: [\"Read\", \"Grep\", \"Glob\"],\n ask: [\"Write\", \"Edit\", \"Bash\"],\n deny: [],\n defaultMode: \"ask\",\n },\n ui: {\n showBanner: true,\n lang: \"en\",\n },\n};\n\nasync function readJsonIfExists(path: string): Promise<unknown | undefined> {\n if (!existsSync(path)) return undefined;\n try {\n const raw = await readFile(path, \"utf-8\");\n return JSON.parse(raw);\n } catch (err) {\n log.warn(`Failed to parse settings at ${path}: ${err instanceof Error ? err.message : String(err)}`);\n return undefined;\n }\n}\n\n/** 深合并:高优先级覆盖低优先级。对象递归,数组/标量覆盖。 */\nfunction deepMerge<T>(low: T, high: Partial<T>): T {\n if (high == null) return low;\n if (typeof low !== \"object\" || typeof high !== \"object\" || low === null || high === null) {\n return high as T;\n }\n if (Array.isArray(high)) return high as unknown as T;\n const result: Record<string, unknown> = { ...(low as Record<string, unknown>) };\n for (const [k, v] of Object.entries(high)) {\n const existing = (low as Record<string, unknown>)[k];\n if (\n v !== null &&\n typeof v === \"object\" &&\n !Array.isArray(v) &&\n existing !== null &&\n typeof existing === \"object\" &&\n !Array.isArray(existing)\n ) {\n result[k] = deepMerge(existing, v as Record<string, unknown>);\n } else {\n result[k] = v;\n }\n }\n return result as T;\n}\n\nexport interface LoadedSettings {\n settings: Settings;\n sources: string[];\n}\n\nexport async function loadSettings(cwd: string = process.cwd()): Promise<LoadedSettings> {\n const sources: string[] = [\"<defaults>\"];\n let merged: Settings = DEFAULTS;\n\n const candidates = [\n join(homedir(), \".muse\", \"settings.json\"),\n join(cwd, \".muse\", \"settings.json\"),\n join(cwd, \".muse\", \"settings.local.json\"),\n ];\n\n for (const path of candidates) {\n const raw = await readJsonIfExists(path);\n if (raw != null) {\n const parsed = SettingsSchema.safeParse(raw);\n if (parsed.success) {\n merged = deepMerge(merged, parsed.data);\n sources.push(path);\n } else {\n log.warn(`Invalid settings at ${path}: ${formatZodIssues(parsed.error.issues)}`);\n }\n }\n }\n\n // Env overrides for the active LLM\n if (process.env.MUSE_PROVIDER && merged.llm) {\n merged = { ...merged, llm: { ...merged.llm, provider: process.env.MUSE_PROVIDER } };\n sources.push(\"env:MUSE_PROVIDER\");\n }\n if (process.env.MUSE_MODEL && merged.llm) {\n merged = { ...merged, llm: { ...merged.llm, model: process.env.MUSE_MODEL } };\n sources.push(\"env:MUSE_MODEL\");\n }\n\n // 展开 ${ENV_VAR} 占位符\n merged = expandEnvVars(merged) as Settings;\n\n return { settings: merged, sources };\n}\n\nexport { DEFAULTS };\nexport { resolve as resolvePath };\n","/**\n * 配置 schema。对应 ~/.muse/settings.json + .muse/settings.json 的内容。\n */\n\nimport { z } from \"zod\";\n\nexport const ProviderConfigSchema = z.object({\n apiKey: z.string().optional(),\n baseUrl: z.string().optional(),\n extraHeaders: z.record(z.string()).optional(),\n}).passthrough();\n\n// 新设计:model id 由 ~/.muse/models.json 提供,settings.json 只保留 active 选择。\n// provider 字段仅用于\"无 models.json 时的 fallback 路径\"(设计文档 §8 兼容层)。\n// 因此两者都可选——/models 切换只写 model,不写 provider。\nexport const LLMConfigSchema = z.object({\n provider: z.string().optional().describe(\"Fallback provider preset (only used when no models.json entry matches).\"),\n model: z.string().optional().describe(\"Active model id; should match an id in models.json.\"),\n temperature: z.number().min(0).max(2).optional(),\n maxTokens: z.number().int().positive().optional(),\n});\n\nexport const PermissionsSchema = z.object({\n allow: z.array(z.string()).optional(),\n ask: z.array(z.string()).optional(),\n deny: z.array(z.string()).optional(),\n defaultMode: z.enum([\"strict\", \"relaxed\", \"ask\"]).optional(),\n});\n\nexport const UISchema = z.object({\n theme: z.enum([\"dark\", \"light\"]).optional(),\n lang: z.enum([\"en\", \"zh-CN\"]).optional(),\n showBanner: z.boolean().optional(),\n});\n\nexport const SettingsSchema = z.object({\n llm: LLMConfigSchema.optional(),\n providers: z.record(ProviderConfigSchema).optional(),\n permissions: PermissionsSchema.optional(),\n ui: UISchema.optional(),\n mcpServers: z.record(z.unknown()).optional(),\n skills: z.object({\n enabled: z.boolean().optional(),\n disabled: z.array(z.string()).optional(),\n }).optional(),\n}).passthrough();\n\nexport type Settings = z.infer<typeof SettingsSchema>;\nexport type LLMConfig = z.infer<typeof LLMConfigSchema>;\nexport type ProviderConfig = z.infer<typeof ProviderConfigSchema>;\nexport type Permissions = z.infer<typeof PermissionsSchema>;\n","/**\n * ${ENV_VAR} 占位符递归展开。\n *\n * settings.json / models.json 都共用这套机制,避免把明文凭证落到可入 git 的文件。\n * 未定义的 env var → 空字符串(不抛错,让上层校验\"必填字段是否非空\"决定行为)。\n */\n\nconst ENV_PATTERN = /\\$\\{([A-Z_][A-Z0-9_]*)\\}/g;\n\nexport function expandEnvVars(value: unknown): unknown {\n if (typeof value === \"string\") {\n return value.replace(ENV_PATTERN, (_match, name) => process.env[name] ?? \"\");\n }\n if (Array.isArray(value)) {\n return value.map(expandEnvVars);\n }\n if (value && typeof value === \"object\") {\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n result[k] = expandEnvVars(v);\n }\n return result;\n }\n return value;\n}\n"],"mappings":"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","names":["tool","stat","resolve","isAbsolute","dirname","z","z","isAbsolute","resolve","stat","dirname","readFile","writeFile","resolve","isAbsolute","z","z","isAbsolute","resolve","readFile","writeFile","z","z","execa","z","z","execa","cliArgs","result","out","z","z","DEFAULT_LIMIT","mkdir","readFile","stat","homedir","dirname","join","join","homedir","mkdir","stat","dirname","readFile","tool","result","homedir","readFile","existsSync","homedir","join","resolve","z","existsSync","readFile","join","homedir"]}
package/package.json ADDED
@@ -0,0 +1,78 @@
1
+ {
2
+ "name": "@qxbyte/muse",
3
+ "version": "0.1.0",
4
+ "description": "A Claude Code-style agent CLI, provider-agnostic, with first-class support for Chinese / self-hostable LLMs",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "homepage": "https://github.com/qxbyte/muse#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/qxbyte/muse.git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/qxbyte/muse/issues"
14
+ },
15
+ "keywords": [
16
+ "agent",
17
+ "cli",
18
+ "llm",
19
+ "tui",
20
+ "ink",
21
+ "claude-code",
22
+ "deepseek",
23
+ "qwen",
24
+ "ollama",
25
+ "openai-compatible"
26
+ ],
27
+ "bin": {
28
+ "muse": "./dist/cli.js"
29
+ },
30
+ "main": "./dist/index.js",
31
+ "module": "./dist/index.js",
32
+ "files": [
33
+ "dist",
34
+ "README.md"
35
+ ],
36
+ "engines": {
37
+ "node": ">=20"
38
+ },
39
+ "publishConfig": {
40
+ "access": "public"
41
+ },
42
+ "scripts": {
43
+ "dev": "tsup --watch",
44
+ "build": "tsup",
45
+ "typecheck": "tsc --noEmit",
46
+ "test": "vitest run",
47
+ "test:watch": "vitest",
48
+ "start": "node ./dist/cli.js",
49
+ "muse": "node ./dist/cli.js",
50
+ "prepublishOnly": "npm run typecheck && npm run build"
51
+ },
52
+ "dependencies": {
53
+ "@ai-sdk/anthropic": "^1.0.0",
54
+ "@ai-sdk/openai": "^1.0.0",
55
+ "@ai-sdk/openai-compatible": "^0.1.0",
56
+ "ai": "^4.0.0",
57
+ "commander": "^12.1.0",
58
+ "diff": "^7.0.0",
59
+ "execa": "^9.5.0",
60
+ "fast-glob": "^3.3.2",
61
+ "ink": "^5.0.1",
62
+ "ink-spinner": "^5.0.0",
63
+ "ink-text-input": "^6.0.0",
64
+ "marked": "^15.0.12",
65
+ "marked-terminal": "^7.3.0",
66
+ "pino": "^9.5.0",
67
+ "react": "^18.3.1",
68
+ "zod": "^3.23.8"
69
+ },
70
+ "devDependencies": {
71
+ "@types/diff": "^7.0.0",
72
+ "@types/node": "^22.10.0",
73
+ "@types/react": "^18.3.0",
74
+ "tsup": "^8.3.0",
75
+ "typescript": "^5.7.0",
76
+ "vitest": "^2.1.0"
77
+ }
78
+ }