@justin06lee/yagami 0.6.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -137,6 +137,9 @@ session.send("now add a test for the edge case"); // next turn resumes the sam
137
137
  await session.interrupt(); // the CLI's Esc
138
138
  await session.setModel("opus"); // the CLI's /model
139
139
  await session.setPermissionMode("plan"); // shift+tab
140
+ // the CLI's /rewind: restore tracked files to their state at a user
141
+ // message's uuid (needs options: { enableFileCheckpointing: true })
142
+ await session.rewindFiles(userMessageUuid);
140
143
  session.close();
141
144
  ```
142
145
 
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { S as SseEvent, M as MessagesRequest, E as EngineModel, A as ApiError, a as MessagesResponse, Y as YagamiEngine, b as EngineOptions, P as Provider, c as ProviderCapabilities, T as TurnRequest, d as TurnEvent, e as SessionProvider, f as ProviderSessionOptions, g as ProviderSession } from './hostConfig-HmZ3z297.js';
2
2
  export { h as AgentEvent, i as ApiErrorType, C as CodexProvider, j as CodexProviderOptions, k as CodexSandboxMode, l as CompleteResult, m as ContentBlock, n as ContentBlockParam, D as DetectedProvider, H as HostEngineConfig, L as LoadedProviders, o as MessageParam, p as ModelRef, q as PROVIDER_PRESETS, r as ProviderConfigEntry, s as ProviderKind, t as ProviderPreset, u as SessionCache, v as SessionCacheOptions, w as SessionPermissionDecision, x as SessionPermissionHandler, y as SessionPermissionRequest, z as StreamOptions, B as StreamResultInfo, F as StreamStart, G as SystemParam, U as Usage, I as createProvider, J as detectProviders, K as isSessionProvider, N as loadHostEngineConfig, O as loadProviders, Q as parseModelRef, R as presetFor, V as qualifiedModel, W as yagamiConfigDir } from './hostConfig-HmZ3z297.js';
3
- import { Options, SDKUserMessage, Query, SettingSource, PermissionUpdate, CanUseTool, PermissionResult, SDKMessage } from '@anthropic-ai/claude-agent-sdk';
4
- export { Options as AgentOptions, CanUseTool, PermissionMode, Query, SDKMessage, SDKUserMessage } from '@anthropic-ai/claude-agent-sdk';
3
+ import { Options, SDKUserMessage, Query, SettingSource, PermissionUpdate, CanUseTool, PermissionResult, SDKMessage, RewindFilesResult } from '@anthropic-ai/claude-agent-sdk';
4
+ export { Options as AgentOptions, CanUseTool, PermissionMode, Query, RewindFilesResult, SDKMessage, SDKUserMessage } from '@anthropic-ai/claude-agent-sdk';
5
5
  import { ClientSideConnection, InitializeResponse, SessionNotification, RequestPermissionRequest, RequestPermissionResponse } from '@agentclientprotocol/sdk';
6
6
 
7
7
  /**
@@ -362,6 +362,16 @@ declare class AgentSession implements AsyncIterable<SDKMessage> {
362
362
  value: string;
363
363
  displayName: string;
364
364
  }>>;
365
+ /**
366
+ * Rewind tracked files to their state at a user message (the CLI's
367
+ * /rewind). Needs `enableFileCheckpointing: true` in the session options —
368
+ * without it the CLI answers `canRewind: false`. Pass `dryRun` to preview
369
+ * the change counts without touching the worktree. Starts the process if
370
+ * no turn has run yet (checkpoints ride the resumed session's history).
371
+ */
372
+ rewindFiles(userMessageId: string, options?: {
373
+ dryRun?: boolean;
374
+ }): Promise<RewindFilesResult>;
365
375
  /** End the session and tear down the process. */
366
376
  close(): void;
367
377
  }
package/dist/index.js CHANGED
@@ -281,6 +281,18 @@ var AgentSession = class {
281
281
  const models = await this.query.supportedModels();
282
282
  return models.map((m) => ({ value: m.value, displayName: m.displayName }));
283
283
  }
284
+ /**
285
+ * Rewind tracked files to their state at a user message (the CLI's
286
+ * /rewind). Needs `enableFileCheckpointing: true` in the session options —
287
+ * without it the CLI answers `canRewind: false`. Pass `dryRun` to preview
288
+ * the change counts without touching the worktree. Starts the process if
289
+ * no turn has run yet (checkpoints ride the resumed session's history).
290
+ */
291
+ async rewindFiles(userMessageId, options) {
292
+ if (this.closed) throw new Error("session is closed");
293
+ this.ensureStarted();
294
+ return this.query.rewindFiles(userMessageId, options);
295
+ }
284
296
  /** End the session and tear down the process. */
285
297
  close() {
286
298
  if (this.closed) return;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/client.ts","../src/core/session.ts","../src/core/agentSession.ts","../src/core/parity.ts","../src/core/permission.ts"],"sourcesContent":["/**\n * `Yagami` — the zero-config library client. `new Yagami()` needs no URL and\n * no API key: it finds the coding-agent CLIs already installed and signed in\n * on this machine (the same T3-Code trick the server does) and mirrors the\n * Anthropic and OpenAI SDK surfaces on top of them, so an app written\n * against either SDK shape drops in with nothing to configure.\n *\n * By default it also reads the host's yagami config\n * (~/.config/yagami/config.json), so an embedded client and the `yagami`\n * binary on the same machine agree on providers, paths, and defaults.\n */\n\nimport { YagamiEngine, type EngineOptions } from \"./engine.js\";\nimport { loadHostEngineConfig } from \"./hostConfig.js\";\nimport { ApiError, type MessagesRequest, type MessagesResponse } from \"./types.js\";\nimport type { EngineModel } from \"./models.js\";\nimport {\n ChatChunkTranslator,\n chatToMessagesRequest,\n modelListBody,\n toChatCompletion,\n type ChatCompletion,\n type ChatCompletionChunk,\n type ChatCompletionsRequest,\n} from \"./openai.js\";\n\nexport interface YagamiOptions extends EngineOptions {\n /**\n * Merge the host machine's yagami config (providers, defaults) under any\n * explicit options, so library and binary stay in sync. Default true;\n * ignored when explicit `providers` instances are passed.\n */\n syncHostConfig?: boolean;\n}\n\n/** An Anthropic stream event's payload (`message_start`, `content_block_delta`, …). */\nexport interface MessageStreamEvent {\n type: string;\n [key: string]: unknown;\n}\n\nexport interface YagamiMessages {\n /** Anthropic-SDK-shaped: non-stream resolves to the message; `stream: true` yields stream events. */\n create(req: MessagesRequest & { stream: true }): AsyncGenerator<MessageStreamEvent, void, undefined>;\n create(req: MessagesRequest & { stream?: false | undefined }): Promise<MessagesResponse>;\n /** Always-streaming variant (the SDK's `messages.stream`). */\n stream(req: MessagesRequest): AsyncGenerator<MessageStreamEvent, void, undefined>;\n}\n\nexport interface YagamiChatCompletions {\n /** OpenAI-SDK-shaped: non-stream resolves to a chat.completion; `stream: true` yields chunks. */\n create(req: ChatCompletionsRequest & { stream: true }): AsyncGenerator<ChatCompletionChunk, void, undefined>;\n create(req: ChatCompletionsRequest & { stream?: false | undefined }): Promise<ChatCompletion>;\n}\n\nexport class Yagami {\n /** The underlying engine, for anything beyond the SDK-shaped surface. */\n readonly engine: YagamiEngine;\n\n constructor(options: YagamiOptions = {}) {\n const { syncHostConfig, ...engineOptions } = options;\n const host = syncHostConfig === false || engineOptions.providers ? {} : loadHostEngineConfig();\n this.engine = new YagamiEngine({ ...host, ...definedProps(engineOptions) });\n }\n\n readonly messages: YagamiMessages = (() => {\n const streamEvents = (req: MessagesRequest) => this.streamMessageEvents(req);\n const complete = async (req: MessagesRequest) => (await this.engine.complete(req)).response;\n function create(req: MessagesRequest & { stream: true }): AsyncGenerator<MessageStreamEvent, void, undefined>;\n function create(req: MessagesRequest & { stream?: false | undefined }): Promise<MessagesResponse>;\n function create(req: MessagesRequest): unknown {\n return req.stream === true ? streamEvents(req) : complete(req);\n }\n return { create, stream: streamEvents };\n })();\n\n readonly chat: { completions: YagamiChatCompletions } = (() => {\n const streamChunks = (req: ChatCompletionsRequest) => this.streamChatChunks(req);\n const complete = async (req: ChatCompletionsRequest) => {\n const { req: translated } = chatToMessagesRequest(req);\n return toChatCompletion((await this.engine.complete(translated)).response);\n };\n function create(req: ChatCompletionsRequest & { stream: true }): AsyncGenerator<ChatCompletionChunk, void, undefined>;\n function create(req: ChatCompletionsRequest & { stream?: false | undefined }): Promise<ChatCompletion>;\n function create(req: ChatCompletionsRequest): unknown {\n return req.stream === true ? streamChunks(req) : complete(req);\n }\n return { completions: { create } };\n })();\n\n readonly models = {\n /** Both SDK shapes at once (Anthropic + OpenAI model-list fields). */\n list: async (): Promise<ReturnType<typeof modelListBody>> => modelListBody(await this.engine.listModels()),\n /** The engine's raw model list. */\n raw: (): Promise<EngineModel[]> => this.engine.listModels(),\n };\n\n private async *streamMessageEvents(req: MessagesRequest): AsyncGenerator<MessageStreamEvent, void, undefined> {\n const { events } = this.engine.stream(req);\n for await (const ev of events) {\n if (ev.event === \"error\") throw errorFromEvent(ev.data);\n yield ev.data as MessageStreamEvent;\n }\n }\n\n private async *streamChatChunks(req: ChatCompletionsRequest): AsyncGenerator<ChatCompletionChunk, void, undefined> {\n const { req: translated, includeUsage } = chatToMessagesRequest({ ...req, stream: true });\n const translator = new ChatChunkTranslator(includeUsage);\n const { events } = this.engine.stream(translated);\n for await (const ev of events) {\n if (ev.event === \"error\") throw errorFromEvent(ev.data);\n for (const chunk of translator.push(ev)) yield chunk as ChatCompletionChunk;\n }\n }\n}\n\nfunction errorFromEvent(data: unknown): ApiError {\n const error = (data as { error?: { type?: string; message?: string } } | undefined)?.error;\n return new ApiError(500, (error?.type as ApiError[\"type\"]) ?? \"api_error\", error?.message ?? \"stream error\");\n}\n\nfunction definedProps<T extends object>(obj: T): Partial<T> {\n return Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined)) as Partial<T>;\n}\n","import {\n query,\n type Options,\n type Query,\n type SDKUserMessage,\n} from \"@anthropic-ai/claude-agent-sdk\";\nimport { resolveClaudeExecutable } from \"./executable.js\";\n\nexport interface ClaudeSessionOptions {\n /** Path to the `claude` binary. Auto-resolved when omitted. */\n claudePath?: string;\n /** Agent SDK options; merged over yagami's defaults. */\n options?: Options;\n}\n\n/**\n * Full agentic Claude Code session (tools, permissions, plan mode — the\n * works), backed by the user's installed, signed-in CLI. This is the\n * embeddable \"what T3 Code does\" primitive for building UIs on top of\n * Claude Code: unlike the Messages-API engine, nothing is restricted here.\n *\n * Defaults to the `claude_code` system prompt preset so behavior matches the\n * interactive CLI; pass `options.systemPrompt` to override.\n */\nexport function claudeCodeSession(\n prompt: string | AsyncIterable<SDKUserMessage>,\n sessionOptions: ClaudeSessionOptions = {},\n): Query {\n const claudePath = resolveClaudeExecutable(\n sessionOptions.claudePath ?? sessionOptions.options?.pathToClaudeCodeExecutable,\n );\n return query({\n prompt,\n options: {\n systemPrompt: { type: \"preset\", preset: \"claude_code\" },\n ...sessionOptions.options,\n pathToClaudeCodeExecutable: claudePath,\n },\n });\n}\n\nexport type {\n Options as AgentOptions,\n Query,\n SDKMessage,\n SDKUserMessage,\n PermissionMode,\n CanUseTool,\n} from \"@anthropic-ai/claude-agent-sdk\";\n","import {\n query,\n type Options,\n type Query,\n type SDKMessage,\n type SDKUserMessage,\n} from \"@anthropic-ai/claude-agent-sdk\";\nimport { resolveClaudeExecutable } from \"./executable.js\";\nimport { classifyProviderFailure } from \"./errors.js\";\nimport { settingSourcesFor, type Parity } from \"./parity.js\";\nimport { PermissionAdapter, type PermissionHandler, type PermissionAdapterOptions } from \"./permission.js\";\nimport { AsyncQueue } from \"./providers/queue.js\";\nimport { VERSION } from \"../version.js\";\n\nexport interface AgentSessionOptions {\n /** Path to the `claude` binary. Auto-resolved when omitted. */\n claudePath?: string;\n /** Project directory the agent works in. */\n cwd?: string;\n /** How closely to mirror the interactive terminal (default \"terminal\"). */\n parity?: Parity;\n /** Model id/alias; the CLI default when omitted. */\n model?: string;\n /** Host permission callback (see {@link PermissionAdapter}). */\n onPermission?: PermissionHandler;\n /** Options for the permission adapter (fallback, auto-allow/deny). */\n permission?: PermissionAdapterOptions;\n /** Reported to the CLI as the client application (e.g. your app name). */\n appName?: string;\n /** Extra Agent SDK options, merged last (wins over the above). */\n options?: Options;\n}\n\n/**\n * A long-lived, agentic Claude Code session for building a UI on top of the\n * CLI — the ruri use case. It keeps one warm process across turns (so only\n * the first turn pays cold-start), threads permission decisions to a host\n * callback, mirrors your terminal settings by default, and exposes the\n * lifecycle the interactive CLI gives you for free: send, interrupt, resume,\n * change model/permission mode, close.\n *\n * Everything the model produces is an {@link SDKMessage} you render yourself.\n */\nexport class AgentSession implements AsyncIterable<SDKMessage> {\n readonly permissions: PermissionAdapter;\n private readonly claudePath: string;\n private readonly appName: string;\n private readonly baseOptions: Options;\n private readonly input = new AsyncQueue<SDKUserMessage>();\n private query: Query | undefined;\n private started = false;\n private closed = false;\n private currentSessionId: string | undefined;\n\n constructor(options: AgentSessionOptions = {}) {\n this.claudePath = resolveClaudeExecutable(options.claudePath ?? options.options?.pathToClaudeCodeExecutable);\n this.appName = options.appName ?? \"yagami\";\n this.permissions = new PermissionAdapter(options.permission ?? {});\n if (options.onPermission) this.permissions.setHandler(options.onPermission);\n this.baseOptions = {\n systemPrompt: { type: \"preset\", preset: \"claude_code\" },\n settingSources: settingSourcesFor(options.parity ?? \"terminal\"),\n includePartialMessages: true,\n ...(options.cwd ? { cwd: options.cwd } : {}),\n ...(options.model ? { model: options.model } : {}),\n ...options.options,\n canUseTool: options.options?.canUseTool ?? this.permissions.canUseTool,\n pathToClaudeCodeExecutable: this.claudePath,\n env: {\n ...process.env,\n CLAUDE_AGENT_SDK_CLIENT_APP: `${this.appName}/${VERSION}`,\n ...options.options?.env,\n },\n };\n }\n\n /** Set (or clear) the host permission callback after construction. */\n setPermissionHandler(handler: PermissionHandler | undefined): void {\n this.permissions.setHandler(handler);\n }\n\n /** The live Claude Code session id, once the first turn has started. */\n get sessionId(): string | undefined {\n return this.currentSessionId;\n }\n\n /** Queue a user turn. The process starts on the first send and stays warm. */\n send(text: string, options: { images?: Array<{ data: string; mediaType?: string }> } = {}): void {\n if (this.closed) throw new Error(\"session is closed\");\n const content =\n options.images && options.images.length > 0\n ? [\n ...options.images.map((img) => ({ type: \"image\" as const, source: { type: \"base64\" as const, media_type: img.mediaType ?? \"image/png\", data: img.data } })),\n { type: \"text\" as const, text },\n ]\n : text;\n this.input.push({\n type: \"user\",\n message: { role: \"user\", content } as SDKUserMessage[\"message\"],\n parent_tool_use_id: null,\n session_id: this.currentSessionId ?? \"\",\n } as SDKUserMessage);\n this.ensureStarted();\n }\n\n private ensureStarted(): void {\n if (this.started) return;\n this.started = true;\n this.query = query({ prompt: this.input, options: this.baseOptions });\n }\n\n /** Iterate every SDK message the agent produces across all turns. */\n async *[Symbol.asyncIterator](): AsyncIterator<SDKMessage> {\n this.ensureStarted();\n try {\n for await (const msg of this.query!) {\n if (msg.type === \"system\" && msg.subtype === \"init\") this.currentSessionId = msg.session_id;\n else if (msg.type === \"result\") this.currentSessionId = msg.session_id;\n yield msg;\n }\n } catch (err) {\n throw classifyProviderFailure(\"claude\", \"claude (then /login)\", err);\n }\n }\n\n /** Interrupt the in-flight turn (the CLI's Esc/Ctrl-C). */\n async interrupt(): Promise<void> {\n await this.query?.interrupt();\n }\n\n /** Switch models mid-session (the CLI's /model). */\n async setModel(model: string): Promise<void> {\n await this.query?.setModel(model);\n }\n\n /** Switch permission mode mid-session (default/acceptEdits/plan/bypassPermissions). */\n async setPermissionMode(mode: \"default\" | \"acceptEdits\" | \"plan\" | \"bypassPermissions\"): Promise<void> {\n await this.query?.setPermissionMode(mode);\n }\n\n /** Models the CLI reports as available (for a picker). */\n async supportedModels(): Promise<Array<{ value: string; displayName: string }>> {\n this.ensureStarted();\n const models = await this.query!.supportedModels();\n return models.map((m) => ({ value: m.value, displayName: m.displayName }));\n }\n\n /** End the session and tear down the process. */\n close(): void {\n if (this.closed) return;\n this.closed = true;\n this.input.end();\n this.query?.close();\n }\n}\n\n/**\n * Convenience: start an {@link AgentSession} and immediately send one turn.\n * Returns the session so callers can iterate it, interrupt, or send more.\n */\nexport function startAgentSession(prompt: string, options: AgentSessionOptions = {}): AgentSession {\n const session = new AgentSession(options);\n session.send(prompt);\n return session;\n}\n","import type { SettingSource } from \"@anthropic-ai/claude-agent-sdk\";\n\n/**\n * How closely an embedded session should mirror the interactive `claude`\n * terminal. This resolves the single most common surprise in library mode:\n * the Agent SDK loads none of your settings by default.\n *\n * - `\"terminal\"` — behave like your CLI: load user + project + local\n * settings, so CLAUDE.md, skills, hooks, and .mcp.json all apply.\n * - `\"isolated\"` — load nothing (the raw SDK default); the app supplies\n * everything explicitly. Best when the session must be reproducible or\n * must not pick up the developer's personal config.\n * - `\"project\"` — load project + local settings but not the user's global\n * ones: shared repo config without personal CLAUDE.md/skills.\n */\nexport type Parity = \"terminal\" | \"project\" | \"isolated\";\n\nconst SETTING_SOURCES: Record<Parity, SettingSource[]> = {\n terminal: [\"user\", \"project\", \"local\"],\n project: [\"project\", \"local\"],\n isolated: [],\n};\n\n/** The `settingSources` a parity level maps to. */\nexport function settingSourcesFor(parity: Parity): SettingSource[] {\n return [...SETTING_SOURCES[parity]];\n}\n","import type {\n CanUseTool,\n PermissionResult,\n PermissionUpdate,\n} from \"@anthropic-ai/claude-agent-sdk\";\n\n/** A tool-use request handed to the host for a decision. */\nexport interface PermissionRequest {\n toolName: string;\n input: Record<string, unknown>;\n signal: AbortSignal;\n /**\n * Suggested permission updates the host can echo back to stop being asked\n * again this session (e.g. behind an \"always allow\" button).\n */\n suggestions?: PermissionUpdate[];\n}\n\n/**\n * The host's answer. `allow` optionally rewrites the tool input and/or\n * persists permission updates for the rest of the session; `deny` carries a\n * message the model sees and can optionally interrupt the turn.\n */\nexport type PermissionDecision =\n | { behavior: \"allow\"; updatedInput?: Record<string, unknown>; updatedPermissions?: PermissionUpdate[] }\n | { behavior: \"deny\"; message?: string; interrupt?: boolean };\n\n/** What the app implements: show UI, return a decision. */\nexport type PermissionHandler = (req: PermissionRequest) => PermissionDecision | Promise<PermissionDecision>;\n\nexport interface PermissionAdapterOptions {\n /**\n * Decision used when no handler is set, a handler throws, or the request is\n * aborted. Defaults to denying — the safe choice for an unattended host.\n */\n fallback?: \"allow\" | \"deny\";\n /** Tool names to auto-allow without ever calling the handler. */\n autoAllow?: Iterable<string>;\n /** Tool names to auto-deny without ever calling the handler. */\n autoDeny?: Iterable<string>;\n}\n\n/**\n * Turns a host-supplied {@link PermissionHandler} into the Agent SDK's\n * {@link CanUseTool} callback, owning the state machine so the app only has\n * to answer one question: allow or deny this tool call?\n *\n * The policy (what to auto-approve) stays with the app — yagami never bakes\n * in a permissive default. Without a handler, everything falls back (deny by\n * default), so a session is safe before the UI is wired up.\n */\nexport class PermissionAdapter {\n private handler: PermissionHandler | undefined;\n private readonly fallback: \"allow\" | \"deny\";\n private readonly autoAllow: Set<string>;\n private readonly autoDeny: Set<string>;\n\n constructor(options: PermissionAdapterOptions = {}) {\n this.fallback = options.fallback ?? \"deny\";\n this.autoAllow = new Set(options.autoAllow ?? []);\n this.autoDeny = new Set(options.autoDeny ?? []);\n }\n\n /** Install (or replace) the host decision callback. */\n setHandler(handler: PermissionHandler | undefined): void {\n this.handler = handler;\n }\n\n allowTool(toolName: string): void {\n this.autoDeny.delete(toolName);\n this.autoAllow.add(toolName);\n }\n\n denyTool(toolName: string): void {\n this.autoAllow.delete(toolName);\n this.autoDeny.add(toolName);\n }\n\n private fallbackResult(reason: string): PermissionResult {\n return this.fallback === \"allow\"\n ? { behavior: \"allow\", updatedInput: {} }\n : { behavior: \"deny\", message: reason };\n }\n\n /**\n * The callback to hand to `claudeCodeSession`/the Agent SDK. Typed to\n * always resolve (never null), and assignable to the SDK's CanUseTool.\n */\n readonly canUseTool: (\n ...args: Parameters<CanUseTool>\n ) => Promise<PermissionResult> = async (toolName, input, options) => {\n if (this.autoDeny.has(toolName)) {\n return { behavior: \"deny\", message: `tool \"${toolName}\" is disabled for this session` };\n }\n if (this.autoAllow.has(toolName)) {\n return { behavior: \"allow\", updatedInput: input };\n }\n if (!this.handler) return this.fallbackResult(`no permission handler is set; denying \"${toolName}\"`);\n if (options.signal.aborted) return this.fallbackResult(\"request aborted\");\n\n let decision: PermissionDecision;\n try {\n decision = await this.handler({\n toolName,\n input,\n signal: options.signal,\n ...(options.suggestions ? { suggestions: options.suggestions } : {}),\n });\n } catch (err) {\n return this.fallbackResult(`permission handler threw: ${err instanceof Error ? err.message : String(err)}`);\n }\n\n if (decision.behavior === \"allow\") {\n return {\n behavior: \"allow\",\n updatedInput: decision.updatedInput ?? input,\n ...(decision.updatedPermissions ? { updatedPermissions: decision.updatedPermissions } : {}),\n };\n }\n return {\n behavior: \"deny\",\n message: decision.message ?? `tool \"${toolName}\" denied by host`,\n ...(decision.interrupt ? { interrupt: true } : {}),\n };\n };\n}\n"],"mappings":"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","names":["query","query"]}
1
+ {"version":3,"sources":["../src/core/client.ts","../src/core/session.ts","../src/core/agentSession.ts","../src/core/parity.ts","../src/core/permission.ts"],"sourcesContent":["/**\n * `Yagami` — the zero-config library client. `new Yagami()` needs no URL and\n * no API key: it finds the coding-agent CLIs already installed and signed in\n * on this machine (the same T3-Code trick the server does) and mirrors the\n * Anthropic and OpenAI SDK surfaces on top of them, so an app written\n * against either SDK shape drops in with nothing to configure.\n *\n * By default it also reads the host's yagami config\n * (~/.config/yagami/config.json), so an embedded client and the `yagami`\n * binary on the same machine agree on providers, paths, and defaults.\n */\n\nimport { YagamiEngine, type EngineOptions } from \"./engine.js\";\nimport { loadHostEngineConfig } from \"./hostConfig.js\";\nimport { ApiError, type MessagesRequest, type MessagesResponse } from \"./types.js\";\nimport type { EngineModel } from \"./models.js\";\nimport {\n ChatChunkTranslator,\n chatToMessagesRequest,\n modelListBody,\n toChatCompletion,\n type ChatCompletion,\n type ChatCompletionChunk,\n type ChatCompletionsRequest,\n} from \"./openai.js\";\n\nexport interface YagamiOptions extends EngineOptions {\n /**\n * Merge the host machine's yagami config (providers, defaults) under any\n * explicit options, so library and binary stay in sync. Default true;\n * ignored when explicit `providers` instances are passed.\n */\n syncHostConfig?: boolean;\n}\n\n/** An Anthropic stream event's payload (`message_start`, `content_block_delta`, …). */\nexport interface MessageStreamEvent {\n type: string;\n [key: string]: unknown;\n}\n\nexport interface YagamiMessages {\n /** Anthropic-SDK-shaped: non-stream resolves to the message; `stream: true` yields stream events. */\n create(req: MessagesRequest & { stream: true }): AsyncGenerator<MessageStreamEvent, void, undefined>;\n create(req: MessagesRequest & { stream?: false | undefined }): Promise<MessagesResponse>;\n /** Always-streaming variant (the SDK's `messages.stream`). */\n stream(req: MessagesRequest): AsyncGenerator<MessageStreamEvent, void, undefined>;\n}\n\nexport interface YagamiChatCompletions {\n /** OpenAI-SDK-shaped: non-stream resolves to a chat.completion; `stream: true` yields chunks. */\n create(req: ChatCompletionsRequest & { stream: true }): AsyncGenerator<ChatCompletionChunk, void, undefined>;\n create(req: ChatCompletionsRequest & { stream?: false | undefined }): Promise<ChatCompletion>;\n}\n\nexport class Yagami {\n /** The underlying engine, for anything beyond the SDK-shaped surface. */\n readonly engine: YagamiEngine;\n\n constructor(options: YagamiOptions = {}) {\n const { syncHostConfig, ...engineOptions } = options;\n const host = syncHostConfig === false || engineOptions.providers ? {} : loadHostEngineConfig();\n this.engine = new YagamiEngine({ ...host, ...definedProps(engineOptions) });\n }\n\n readonly messages: YagamiMessages = (() => {\n const streamEvents = (req: MessagesRequest) => this.streamMessageEvents(req);\n const complete = async (req: MessagesRequest) => (await this.engine.complete(req)).response;\n function create(req: MessagesRequest & { stream: true }): AsyncGenerator<MessageStreamEvent, void, undefined>;\n function create(req: MessagesRequest & { stream?: false | undefined }): Promise<MessagesResponse>;\n function create(req: MessagesRequest): unknown {\n return req.stream === true ? streamEvents(req) : complete(req);\n }\n return { create, stream: streamEvents };\n })();\n\n readonly chat: { completions: YagamiChatCompletions } = (() => {\n const streamChunks = (req: ChatCompletionsRequest) => this.streamChatChunks(req);\n const complete = async (req: ChatCompletionsRequest) => {\n const { req: translated } = chatToMessagesRequest(req);\n return toChatCompletion((await this.engine.complete(translated)).response);\n };\n function create(req: ChatCompletionsRequest & { stream: true }): AsyncGenerator<ChatCompletionChunk, void, undefined>;\n function create(req: ChatCompletionsRequest & { stream?: false | undefined }): Promise<ChatCompletion>;\n function create(req: ChatCompletionsRequest): unknown {\n return req.stream === true ? streamChunks(req) : complete(req);\n }\n return { completions: { create } };\n })();\n\n readonly models = {\n /** Both SDK shapes at once (Anthropic + OpenAI model-list fields). */\n list: async (): Promise<ReturnType<typeof modelListBody>> => modelListBody(await this.engine.listModels()),\n /** The engine's raw model list. */\n raw: (): Promise<EngineModel[]> => this.engine.listModels(),\n };\n\n private async *streamMessageEvents(req: MessagesRequest): AsyncGenerator<MessageStreamEvent, void, undefined> {\n const { events } = this.engine.stream(req);\n for await (const ev of events) {\n if (ev.event === \"error\") throw errorFromEvent(ev.data);\n yield ev.data as MessageStreamEvent;\n }\n }\n\n private async *streamChatChunks(req: ChatCompletionsRequest): AsyncGenerator<ChatCompletionChunk, void, undefined> {\n const { req: translated, includeUsage } = chatToMessagesRequest({ ...req, stream: true });\n const translator = new ChatChunkTranslator(includeUsage);\n const { events } = this.engine.stream(translated);\n for await (const ev of events) {\n if (ev.event === \"error\") throw errorFromEvent(ev.data);\n for (const chunk of translator.push(ev)) yield chunk as ChatCompletionChunk;\n }\n }\n}\n\nfunction errorFromEvent(data: unknown): ApiError {\n const error = (data as { error?: { type?: string; message?: string } } | undefined)?.error;\n return new ApiError(500, (error?.type as ApiError[\"type\"]) ?? \"api_error\", error?.message ?? \"stream error\");\n}\n\nfunction definedProps<T extends object>(obj: T): Partial<T> {\n return Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined)) as Partial<T>;\n}\n","import {\n query,\n type Options,\n type Query,\n type SDKUserMessage,\n} from \"@anthropic-ai/claude-agent-sdk\";\nimport { resolveClaudeExecutable } from \"./executable.js\";\n\nexport interface ClaudeSessionOptions {\n /** Path to the `claude` binary. Auto-resolved when omitted. */\n claudePath?: string;\n /** Agent SDK options; merged over yagami's defaults. */\n options?: Options;\n}\n\n/**\n * Full agentic Claude Code session (tools, permissions, plan mode — the\n * works), backed by the user's installed, signed-in CLI. This is the\n * embeddable \"what T3 Code does\" primitive for building UIs on top of\n * Claude Code: unlike the Messages-API engine, nothing is restricted here.\n *\n * Defaults to the `claude_code` system prompt preset so behavior matches the\n * interactive CLI; pass `options.systemPrompt` to override.\n */\nexport function claudeCodeSession(\n prompt: string | AsyncIterable<SDKUserMessage>,\n sessionOptions: ClaudeSessionOptions = {},\n): Query {\n const claudePath = resolveClaudeExecutable(\n sessionOptions.claudePath ?? sessionOptions.options?.pathToClaudeCodeExecutable,\n );\n return query({\n prompt,\n options: {\n systemPrompt: { type: \"preset\", preset: \"claude_code\" },\n ...sessionOptions.options,\n pathToClaudeCodeExecutable: claudePath,\n },\n });\n}\n\nexport type {\n Options as AgentOptions,\n Query,\n RewindFilesResult,\n SDKMessage,\n SDKUserMessage,\n PermissionMode,\n CanUseTool,\n} from \"@anthropic-ai/claude-agent-sdk\";\n","import {\n query,\n type Options,\n type Query,\n type RewindFilesResult,\n type SDKMessage,\n type SDKUserMessage,\n} from \"@anthropic-ai/claude-agent-sdk\";\nimport { resolveClaudeExecutable } from \"./executable.js\";\nimport { classifyProviderFailure } from \"./errors.js\";\nimport { settingSourcesFor, type Parity } from \"./parity.js\";\nimport { PermissionAdapter, type PermissionHandler, type PermissionAdapterOptions } from \"./permission.js\";\nimport { AsyncQueue } from \"./providers/queue.js\";\nimport { VERSION } from \"../version.js\";\n\nexport interface AgentSessionOptions {\n /** Path to the `claude` binary. Auto-resolved when omitted. */\n claudePath?: string;\n /** Project directory the agent works in. */\n cwd?: string;\n /** How closely to mirror the interactive terminal (default \"terminal\"). */\n parity?: Parity;\n /** Model id/alias; the CLI default when omitted. */\n model?: string;\n /** Host permission callback (see {@link PermissionAdapter}). */\n onPermission?: PermissionHandler;\n /** Options for the permission adapter (fallback, auto-allow/deny). */\n permission?: PermissionAdapterOptions;\n /** Reported to the CLI as the client application (e.g. your app name). */\n appName?: string;\n /** Extra Agent SDK options, merged last (wins over the above). */\n options?: Options;\n}\n\n/**\n * A long-lived, agentic Claude Code session for building a UI on top of the\n * CLI — the ruri use case. It keeps one warm process across turns (so only\n * the first turn pays cold-start), threads permission decisions to a host\n * callback, mirrors your terminal settings by default, and exposes the\n * lifecycle the interactive CLI gives you for free: send, interrupt, resume,\n * change model/permission mode, close.\n *\n * Everything the model produces is an {@link SDKMessage} you render yourself.\n */\nexport class AgentSession implements AsyncIterable<SDKMessage> {\n readonly permissions: PermissionAdapter;\n private readonly claudePath: string;\n private readonly appName: string;\n private readonly baseOptions: Options;\n private readonly input = new AsyncQueue<SDKUserMessage>();\n private query: Query | undefined;\n private started = false;\n private closed = false;\n private currentSessionId: string | undefined;\n\n constructor(options: AgentSessionOptions = {}) {\n this.claudePath = resolveClaudeExecutable(options.claudePath ?? options.options?.pathToClaudeCodeExecutable);\n this.appName = options.appName ?? \"yagami\";\n this.permissions = new PermissionAdapter(options.permission ?? {});\n if (options.onPermission) this.permissions.setHandler(options.onPermission);\n this.baseOptions = {\n systemPrompt: { type: \"preset\", preset: \"claude_code\" },\n settingSources: settingSourcesFor(options.parity ?? \"terminal\"),\n includePartialMessages: true,\n ...(options.cwd ? { cwd: options.cwd } : {}),\n ...(options.model ? { model: options.model } : {}),\n ...options.options,\n canUseTool: options.options?.canUseTool ?? this.permissions.canUseTool,\n pathToClaudeCodeExecutable: this.claudePath,\n env: {\n ...process.env,\n CLAUDE_AGENT_SDK_CLIENT_APP: `${this.appName}/${VERSION}`,\n ...options.options?.env,\n },\n };\n }\n\n /** Set (or clear) the host permission callback after construction. */\n setPermissionHandler(handler: PermissionHandler | undefined): void {\n this.permissions.setHandler(handler);\n }\n\n /** The live Claude Code session id, once the first turn has started. */\n get sessionId(): string | undefined {\n return this.currentSessionId;\n }\n\n /** Queue a user turn. The process starts on the first send and stays warm. */\n send(text: string, options: { images?: Array<{ data: string; mediaType?: string }> } = {}): void {\n if (this.closed) throw new Error(\"session is closed\");\n const content =\n options.images && options.images.length > 0\n ? [\n ...options.images.map((img) => ({ type: \"image\" as const, source: { type: \"base64\" as const, media_type: img.mediaType ?? \"image/png\", data: img.data } })),\n { type: \"text\" as const, text },\n ]\n : text;\n this.input.push({\n type: \"user\",\n message: { role: \"user\", content } as SDKUserMessage[\"message\"],\n parent_tool_use_id: null,\n session_id: this.currentSessionId ?? \"\",\n } as SDKUserMessage);\n this.ensureStarted();\n }\n\n private ensureStarted(): void {\n if (this.started) return;\n this.started = true;\n this.query = query({ prompt: this.input, options: this.baseOptions });\n }\n\n /** Iterate every SDK message the agent produces across all turns. */\n async *[Symbol.asyncIterator](): AsyncIterator<SDKMessage> {\n this.ensureStarted();\n try {\n for await (const msg of this.query!) {\n if (msg.type === \"system\" && msg.subtype === \"init\") this.currentSessionId = msg.session_id;\n else if (msg.type === \"result\") this.currentSessionId = msg.session_id;\n yield msg;\n }\n } catch (err) {\n throw classifyProviderFailure(\"claude\", \"claude (then /login)\", err);\n }\n }\n\n /** Interrupt the in-flight turn (the CLI's Esc/Ctrl-C). */\n async interrupt(): Promise<void> {\n await this.query?.interrupt();\n }\n\n /** Switch models mid-session (the CLI's /model). */\n async setModel(model: string): Promise<void> {\n await this.query?.setModel(model);\n }\n\n /** Switch permission mode mid-session (default/acceptEdits/plan/bypassPermissions). */\n async setPermissionMode(mode: \"default\" | \"acceptEdits\" | \"plan\" | \"bypassPermissions\"): Promise<void> {\n await this.query?.setPermissionMode(mode);\n }\n\n /** Models the CLI reports as available (for a picker). */\n async supportedModels(): Promise<Array<{ value: string; displayName: string }>> {\n this.ensureStarted();\n const models = await this.query!.supportedModels();\n return models.map((m) => ({ value: m.value, displayName: m.displayName }));\n }\n\n /**\n * Rewind tracked files to their state at a user message (the CLI's\n * /rewind). Needs `enableFileCheckpointing: true` in the session options —\n * without it the CLI answers `canRewind: false`. Pass `dryRun` to preview\n * the change counts without touching the worktree. Starts the process if\n * no turn has run yet (checkpoints ride the resumed session's history).\n */\n async rewindFiles(\n userMessageId: string,\n options?: { dryRun?: boolean },\n ): Promise<RewindFilesResult> {\n if (this.closed) throw new Error(\"session is closed\");\n this.ensureStarted();\n return this.query!.rewindFiles(userMessageId, options);\n }\n\n /** End the session and tear down the process. */\n close(): void {\n if (this.closed) return;\n this.closed = true;\n this.input.end();\n this.query?.close();\n }\n}\n\n/**\n * Convenience: start an {@link AgentSession} and immediately send one turn.\n * Returns the session so callers can iterate it, interrupt, or send more.\n */\nexport function startAgentSession(prompt: string, options: AgentSessionOptions = {}): AgentSession {\n const session = new AgentSession(options);\n session.send(prompt);\n return session;\n}\n","import type { SettingSource } from \"@anthropic-ai/claude-agent-sdk\";\n\n/**\n * How closely an embedded session should mirror the interactive `claude`\n * terminal. This resolves the single most common surprise in library mode:\n * the Agent SDK loads none of your settings by default.\n *\n * - `\"terminal\"` — behave like your CLI: load user + project + local\n * settings, so CLAUDE.md, skills, hooks, and .mcp.json all apply.\n * - `\"isolated\"` — load nothing (the raw SDK default); the app supplies\n * everything explicitly. Best when the session must be reproducible or\n * must not pick up the developer's personal config.\n * - `\"project\"` — load project + local settings but not the user's global\n * ones: shared repo config without personal CLAUDE.md/skills.\n */\nexport type Parity = \"terminal\" | \"project\" | \"isolated\";\n\nconst SETTING_SOURCES: Record<Parity, SettingSource[]> = {\n terminal: [\"user\", \"project\", \"local\"],\n project: [\"project\", \"local\"],\n isolated: [],\n};\n\n/** The `settingSources` a parity level maps to. */\nexport function settingSourcesFor(parity: Parity): SettingSource[] {\n return [...SETTING_SOURCES[parity]];\n}\n","import type {\n CanUseTool,\n PermissionResult,\n PermissionUpdate,\n} from \"@anthropic-ai/claude-agent-sdk\";\n\n/** A tool-use request handed to the host for a decision. */\nexport interface PermissionRequest {\n toolName: string;\n input: Record<string, unknown>;\n signal: AbortSignal;\n /**\n * Suggested permission updates the host can echo back to stop being asked\n * again this session (e.g. behind an \"always allow\" button).\n */\n suggestions?: PermissionUpdate[];\n}\n\n/**\n * The host's answer. `allow` optionally rewrites the tool input and/or\n * persists permission updates for the rest of the session; `deny` carries a\n * message the model sees and can optionally interrupt the turn.\n */\nexport type PermissionDecision =\n | { behavior: \"allow\"; updatedInput?: Record<string, unknown>; updatedPermissions?: PermissionUpdate[] }\n | { behavior: \"deny\"; message?: string; interrupt?: boolean };\n\n/** What the app implements: show UI, return a decision. */\nexport type PermissionHandler = (req: PermissionRequest) => PermissionDecision | Promise<PermissionDecision>;\n\nexport interface PermissionAdapterOptions {\n /**\n * Decision used when no handler is set, a handler throws, or the request is\n * aborted. Defaults to denying — the safe choice for an unattended host.\n */\n fallback?: \"allow\" | \"deny\";\n /** Tool names to auto-allow without ever calling the handler. */\n autoAllow?: Iterable<string>;\n /** Tool names to auto-deny without ever calling the handler. */\n autoDeny?: Iterable<string>;\n}\n\n/**\n * Turns a host-supplied {@link PermissionHandler} into the Agent SDK's\n * {@link CanUseTool} callback, owning the state machine so the app only has\n * to answer one question: allow or deny this tool call?\n *\n * The policy (what to auto-approve) stays with the app — yagami never bakes\n * in a permissive default. Without a handler, everything falls back (deny by\n * default), so a session is safe before the UI is wired up.\n */\nexport class PermissionAdapter {\n private handler: PermissionHandler | undefined;\n private readonly fallback: \"allow\" | \"deny\";\n private readonly autoAllow: Set<string>;\n private readonly autoDeny: Set<string>;\n\n constructor(options: PermissionAdapterOptions = {}) {\n this.fallback = options.fallback ?? \"deny\";\n this.autoAllow = new Set(options.autoAllow ?? []);\n this.autoDeny = new Set(options.autoDeny ?? []);\n }\n\n /** Install (or replace) the host decision callback. */\n setHandler(handler: PermissionHandler | undefined): void {\n this.handler = handler;\n }\n\n allowTool(toolName: string): void {\n this.autoDeny.delete(toolName);\n this.autoAllow.add(toolName);\n }\n\n denyTool(toolName: string): void {\n this.autoAllow.delete(toolName);\n this.autoDeny.add(toolName);\n }\n\n private fallbackResult(reason: string): PermissionResult {\n return this.fallback === \"allow\"\n ? { behavior: \"allow\", updatedInput: {} }\n : { behavior: \"deny\", message: reason };\n }\n\n /**\n * The callback to hand to `claudeCodeSession`/the Agent SDK. Typed to\n * always resolve (never null), and assignable to the SDK's CanUseTool.\n */\n readonly canUseTool: (\n ...args: Parameters<CanUseTool>\n ) => Promise<PermissionResult> = async (toolName, input, options) => {\n if (this.autoDeny.has(toolName)) {\n return { behavior: \"deny\", message: `tool \"${toolName}\" is disabled for this session` };\n }\n if (this.autoAllow.has(toolName)) {\n return { behavior: \"allow\", updatedInput: input };\n }\n if (!this.handler) return this.fallbackResult(`no permission handler is set; denying \"${toolName}\"`);\n if (options.signal.aborted) return this.fallbackResult(\"request aborted\");\n\n let decision: PermissionDecision;\n try {\n decision = await this.handler({\n toolName,\n input,\n signal: options.signal,\n ...(options.suggestions ? { suggestions: options.suggestions } : {}),\n });\n } catch (err) {\n return this.fallbackResult(`permission handler threw: ${err instanceof Error ? err.message : String(err)}`);\n }\n\n if (decision.behavior === \"allow\") {\n return {\n behavior: \"allow\",\n updatedInput: decision.updatedInput ?? input,\n ...(decision.updatedPermissions ? { updatedPermissions: decision.updatedPermissions } : {}),\n };\n }\n return {\n behavior: \"deny\",\n message: decision.message ?? `tool \"${toolName}\" denied by host`,\n ...(decision.interrupt ? { interrupt: true } : {}),\n };\n };\n}\n"],"mappings":"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","names":["query","query"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@justin06lee/yagami",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "description": "Self-hosted Anthropic- and OpenAI-compatible API backed by your signed-in coding-agent CLIs, plus a zero-config library for driving them from your own apps — no API keys needed.",
5
5
  "type": "module",
6
6
  "license": "MIT",