@justin06lee/yagami 0.6.1 → 0.8.2

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.
@@ -10,7 +10,7 @@ import {
10
10
  toApiError,
11
11
  toChatCompletion,
12
12
  yagamiConfigDir
13
- } from "./chunk-ZYHC7PXX.js";
13
+ } from "./chunk-EKN223KD.js";
14
14
 
15
15
  // src/server.ts
16
16
  import { serve } from "@hono/node-server";
@@ -374,4 +374,4 @@ export {
374
374
  maskKey,
375
375
  startYagami
376
376
  };
377
- //# sourceMappingURL=chunk-D2PNH6GV.js.map
377
+ //# sourceMappingURL=chunk-UGIJV6FZ.js.map
package/dist/cli.js CHANGED
@@ -13,13 +13,13 @@ import {
13
13
  sessionCachePath,
14
14
  startYagami,
15
15
  writeServerState
16
- } from "./chunk-D2PNH6GV.js";
16
+ } from "./chunk-UGIJV6FZ.js";
17
17
  import {
18
18
  VERSION,
19
19
  YagamiEngine,
20
20
  createProvider,
21
21
  detectProviders
22
- } from "./chunk-ZYHC7PXX.js";
22
+ } from "./chunk-EKN223KD.js";
23
23
 
24
24
  // src/cli.ts
25
25
  import { spawn } from "child_process";
@@ -1,4 +1,16 @@
1
- /** A model a provider reports as available. */
1
+ /** One model-native reasoning setting. */
2
+ interface EngineReasoningEffort {
3
+ id: string;
4
+ description?: string;
5
+ }
6
+ /** One provider service tier (for example Codex's priority tier). */
7
+ interface EngineServiceTier {
8
+ id: string;
9
+ display_name: string;
10
+ description?: string;
11
+ }
12
+ type EngineInputModality = "text" | "image" | "audio" | "document" | (string & {});
13
+ /** A model a provider reports as available, including its native controls. */
2
14
  interface EngineModel {
3
15
  id: string;
4
16
  display_name: string;
@@ -7,6 +19,19 @@ interface EngineModel {
7
19
  resolved_model?: string;
8
20
  /** Provider that serves this model (set by the engine when aggregating). */
9
21
  provider?: string;
22
+ /** Reasoning levels this particular model accepts. */
23
+ reasoning_efforts?: EngineReasoningEffort[];
24
+ default_reasoning_effort?: string;
25
+ input_modalities?: EngineInputModality[];
26
+ supports_adaptive_thinking?: boolean;
27
+ supports_fast_mode?: boolean;
28
+ supports_auto_mode?: boolean;
29
+ supports_personality?: boolean;
30
+ /** Provider-native multi-agent runtime, when the catalog reports one. */
31
+ multi_agent?: string;
32
+ service_tiers?: EngineServiceTier[];
33
+ default_service_tier?: string;
34
+ is_default?: boolean;
10
35
  }
11
36
 
12
37
  /**
@@ -101,6 +126,12 @@ interface ProviderCapabilities {
101
126
  effort: boolean;
102
127
  /** Token-level deltas or whole chunks per message part. */
103
128
  streaming: "tokens" | "chunks";
129
+ /**
130
+ * Can run Anthropic server tools (web search/fetch) inside the turn. Still
131
+ * completions-only: results are folded into the reply, never emitted as
132
+ * `tool_use` blocks for the caller to execute.
133
+ */
134
+ serverTools: boolean;
104
135
  }
105
136
  /** One completion turn, already normalized by the engine. */
106
137
  interface TurnRequest {
@@ -115,6 +146,8 @@ interface TurnRequest {
115
146
  resume?: string;
116
147
  thinking?: ThinkingParam;
117
148
  effort?: string;
149
+ /** CLI tool names to enable for this turn (see `core/serverTools.ts`). */
150
+ serverTools?: string[];
118
151
  signal?: AbortSignal;
119
152
  }
120
153
  type TurnEvent = {
@@ -166,6 +199,64 @@ interface ModelRef {
166
199
  declare function parseModelRef(model: string | undefined, providerIds: Iterable<string>): ModelRef;
167
200
  declare function qualifiedModel(providerId: string, model: string): string;
168
201
  type SessionPermissionDecision = "allow" | "allow_always" | "deny" | "deny_always";
202
+ type SessionInputValue = string | number | boolean | string[];
203
+ interface SessionInputOption {
204
+ value: string;
205
+ label: string;
206
+ description?: string;
207
+ }
208
+ /** One renderable field from a harness question or MCP elicitation. */
209
+ interface SessionInputField {
210
+ id: string;
211
+ label: string;
212
+ description?: string;
213
+ type: "string" | "number" | "integer" | "boolean" | "select" | "multiselect";
214
+ required: boolean;
215
+ secret?: boolean;
216
+ allowOther?: boolean;
217
+ options?: SessionInputOption[];
218
+ format?: string;
219
+ minimum?: number;
220
+ maximum?: number;
221
+ minLength?: number;
222
+ maxLength?: number;
223
+ default?: SessionInputValue;
224
+ }
225
+ /** A provider-neutral blocking request for human input. */
226
+ interface SessionInputRequest {
227
+ provider: string;
228
+ sessionId?: string;
229
+ kind: "questions" | "form" | "url";
230
+ message: string;
231
+ source?: string;
232
+ fields?: SessionInputField[];
233
+ url?: string;
234
+ blocking?: boolean;
235
+ raw?: unknown;
236
+ }
237
+ type SessionInputResponse = {
238
+ action: "accept";
239
+ values?: Record<string, SessionInputValue>;
240
+ } | {
241
+ action: "decline" | "cancel";
242
+ };
243
+ interface SessionInputHandler {
244
+ respond(req: SessionInputRequest, signal?: AbortSignal): Promise<SessionInputResponse>;
245
+ }
246
+ type SessionPlanStatus = "pending" | "in_progress" | "completed";
247
+ interface SessionPlanEntry {
248
+ content: string;
249
+ status: SessionPlanStatus;
250
+ priority?: "high" | "medium" | "low";
251
+ }
252
+ interface SessionPlan {
253
+ id?: string;
254
+ explanation?: string;
255
+ entries?: SessionPlanEntry[];
256
+ markdown?: string;
257
+ uri?: string;
258
+ removed?: boolean;
259
+ }
169
260
  /** A harness asking the host whether a tool may run. */
170
261
  interface SessionPermissionRequest {
171
262
  provider: string;
@@ -185,6 +276,11 @@ interface SessionPermissionHandler {
185
276
  type AgentEvent = {
186
277
  type: "session";
187
278
  sessionId: string;
279
+ }
280
+ /** Provider-native turn id, used by hosts to fork an exact exchange. */
281
+ | {
282
+ type: "turn";
283
+ id: string;
188
284
  } | {
189
285
  type: "text";
190
286
  text: string;
@@ -204,6 +300,9 @@ type AgentEvent = {
204
300
  type: "permission";
205
301
  request: SessionPermissionRequest;
206
302
  decision: SessionPermissionDecision;
303
+ } | {
304
+ type: "plan";
305
+ plan: SessionPlan;
207
306
  } | {
208
307
  type: "done";
209
308
  usage?: Usage;
@@ -222,6 +321,10 @@ interface ProviderSessionOptions {
222
321
  model?: string;
223
322
  /** Provider session id to continue. */
224
323
  resume?: string;
324
+ /** Fork the resumed session instead of continuing it in place. */
325
+ fork?: boolean;
326
+ /** Fork the resumed session through this provider-native turn, inclusive. */
327
+ forkAt?: string;
225
328
  /**
226
329
  * "terminal" loads the same settings the interactive CLI would — user and
227
330
  * project config, CLAUDE.md, skills, hooks, MCP servers. "isolated" loads
@@ -229,6 +332,8 @@ interface ProviderSessionOptions {
229
332
  */
230
333
  parity?: "terminal" | "isolated";
231
334
  permissions: SessionPermissionHandler;
335
+ /** Blocking questions and MCP/ACP elicitations. Omitted means decline safely. */
336
+ input?: SessionInputHandler;
232
337
  appName?: string;
233
338
  effort?: string;
234
339
  thinking?: ThinkingParam;
@@ -237,6 +342,10 @@ interface ProviderSessionOptions {
237
342
  /** Provider-specific escape hatch (Claude: Agent SDK Options; Codex: { sandbox }; ACP: { mode }). */
238
343
  native?: Record<string, unknown>;
239
344
  }
345
+ interface ProviderSessionCapabilities {
346
+ /** Can fork a resumed conversation, optionally at an exact reported turn. */
347
+ fork: boolean;
348
+ }
240
349
  /** One live conversation with a harness: send turns, get normalized events. */
241
350
  interface ProviderSession {
242
351
  readonly provider: string;
@@ -248,6 +357,7 @@ interface ProviderSession {
248
357
  }
249
358
  /** Providers that can host agentic sessions implement this too. */
250
359
  interface SessionProvider extends Provider {
360
+ readonly sessionCapabilities: ProviderSessionCapabilities;
251
361
  openSession(options: ProviderSessionOptions): ProviderSession;
252
362
  }
253
363
  declare function isSessionProvider(p: Provider): p is SessionProvider;
@@ -269,6 +379,9 @@ declare class CodexProvider implements SessionProvider {
269
379
  readonly executable: string;
270
380
  readonly loginCommand = "codex login";
271
381
  readonly capabilities: ProviderCapabilities;
382
+ readonly sessionCapabilities: {
383
+ readonly fork: true;
384
+ };
272
385
  private readonly workDir;
273
386
  private readonly sandbox;
274
387
  private readonly env;
@@ -490,4 +603,4 @@ interface HostEngineConfig {
490
603
  }
491
604
  declare function loadHostEngineConfig(): HostEngineConfig;
492
605
 
493
- export { ApiError as A, type StreamResultInfo as B, CodexProvider as C, type DetectedProvider as D, type EngineModel as E, type StreamStart as F, type SystemParam as G, type HostEngineConfig as H, createProvider as I, detectProviders as J, isSessionProvider as K, type LoadedProviders as L, type MessagesRequest as M, loadHostEngineConfig as N, loadProviders as O, type Provider as P, parseModelRef as Q, presetFor as R, type SseEvent as S, type TurnRequest as T, type Usage as U, qualifiedModel as V, yagamiConfigDir as W, YagamiEngine as Y, type MessagesResponse as a, type EngineOptions as b, type ProviderCapabilities as c, type TurnEvent as d, type SessionProvider as e, type ProviderSessionOptions as f, type ProviderSession as g, type AgentEvent as h, type ApiErrorType as i, type CodexProviderOptions as j, type CodexSandboxMode as k, type CompleteResult as l, type ContentBlock as m, type ContentBlockParam as n, type MessageParam as o, type ModelRef as p, PROVIDER_PRESETS as q, type ProviderConfigEntry as r, type ProviderKind as s, type ProviderPreset as t, SessionCache as u, type SessionCacheOptions as v, type SessionPermissionDecision as w, type SessionPermissionHandler as x, type SessionPermissionRequest as y, type StreamOptions as z };
606
+ export { type Usage as $, ApiError as A, type SessionInputField as B, CodexProvider as C, type DetectedProvider as D, type EngineModel as E, type SessionInputHandler as F, type SessionInputOption as G, type HostEngineConfig as H, type SessionInputRequest as I, type SessionInputResponse as J, type SessionInputValue as K, type LoadedProviders as L, type MessagesRequest as M, type SessionPermissionDecision as N, type SessionPermissionHandler as O, type Provider as P, type SessionPermissionRequest as Q, type SessionPlan as R, type SseEvent as S, type TurnRequest as T, type SessionPlanEntry as U, type SessionPlanStatus as V, type StreamOptions as W, type StreamResultInfo as X, YagamiEngine as Y, type StreamStart as Z, type SystemParam as _, type MessagesResponse as a, createProvider as a0, detectProviders as a1, isSessionProvider as a2, loadHostEngineConfig as a3, loadProviders as a4, parseModelRef as a5, presetFor as a6, qualifiedModel as a7, yagamiConfigDir as a8, type EngineOptions as b, type ProviderCapabilities as c, type TurnEvent as d, type SessionProvider as e, type ProviderSessionOptions as f, type ProviderSession as g, type AgentEvent as h, type ApiErrorType as i, type CodexProviderOptions as j, type CodexSandboxMode as k, type CompleteResult as l, type ContentBlock as m, type ContentBlockParam as n, type EngineInputModality as o, type EngineReasoningEffort as p, type EngineServiceTier as q, type MessageParam as r, type ModelRef as s, PROVIDER_PRESETS as t, type ProviderConfigEntry as u, type ProviderKind as v, type ProviderPreset as w, type ProviderSessionCapabilities as x, SessionCache as y, type SessionCacheOptions as z };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
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
- 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, RewindFilesResult } from '@anthropic-ai/claude-agent-sdk';
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-CbGD5-lN.js';
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, o as EngineInputModality, p as EngineReasoningEffort, q as EngineServiceTier, H as HostEngineConfig, L as LoadedProviders, r as MessageParam, s as ModelRef, t as PROVIDER_PRESETS, u as ProviderConfigEntry, v as ProviderKind, w as ProviderPreset, x as ProviderSessionCapabilities, y as SessionCache, z as SessionCacheOptions, B as SessionInputField, F as SessionInputHandler, G as SessionInputOption, I as SessionInputRequest, J as SessionInputResponse, K as SessionInputValue, N as SessionPermissionDecision, O as SessionPermissionHandler, Q as SessionPermissionRequest, R as SessionPlan, U as SessionPlanEntry, V as SessionPlanStatus, W as StreamOptions, X as StreamResultInfo, Z as StreamStart, _ as SystemParam, $ as Usage, a0 as createProvider, a1 as detectProviders, a2 as isSessionProvider, a3 as loadHostEngineConfig, a4 as loadProviders, a5 as parseModelRef, a6 as presetFor, a7 as qualifiedModel, a8 as yagamiConfigDir } from './hostConfig-CbGD5-lN.js';
3
+ import { Options, SDKUserMessage, Query, SettingSource, PermissionUpdate, CanUseTool, PermissionResult, SDKMessage, ModelInfo, RewindFilesResult } from '@anthropic-ai/claude-agent-sdk';
4
4
  export { Options as AgentOptions, CanUseTool, PermissionMode, Query, RewindFilesResult, SDKMessage, SDKUserMessage } from '@anthropic-ai/claude-agent-sdk';
5
- import { ClientSideConnection, InitializeResponse, SessionNotification, RequestPermissionRequest, RequestPermissionResponse } from '@agentclientprotocol/sdk';
5
+ import { ClientSideConnection, InitializeResponse, SessionNotification, RequestPermissionRequest, RequestPermissionResponse, CreateElicitationRequest, CreateElicitationResponse } from '@agentclientprotocol/sdk';
6
6
 
7
7
  /**
8
8
  * OpenAI Chat Completions dialect: translation to and from the Anthropic
@@ -89,9 +89,10 @@ interface TranslatedChatRequest {
89
89
  }
90
90
  /**
91
91
  * Translate an OpenAI Chat Completions request into the Anthropic Messages
92
- * request the engine runs. Tool calling is rejected (yagami is
93
- * completions-only by design); knobs no CLI engine exposes are collected
94
- * into `extraIgnored` instead of failing the request.
92
+ * request the engine runs. Function calling is rejected nothing here ever
93
+ * hands a tool call back to the caller. (Anthropic server tools, which run
94
+ * inside the engine, are available on the Anthropic dialect.) Knobs no CLI
95
+ * engine exposes are collected into `extraIgnored` instead of failing.
95
96
  */
96
97
  declare function chatToMessagesRequest(body: ChatCompletionsRequest): TranslatedChatRequest;
97
98
  /** Anthropic Messages response → OpenAI chat.completion. */
@@ -358,10 +359,7 @@ declare class AgentSession implements AsyncIterable<SDKMessage> {
358
359
  /** Switch permission mode mid-session (default/acceptEdits/plan/bypassPermissions). */
359
360
  setPermissionMode(mode: "default" | "acceptEdits" | "plan" | "bypassPermissions"): Promise<void>;
360
361
  /** Models the CLI reports as available (for a picker). */
361
- supportedModels(): Promise<Array<{
362
- value: string;
363
- displayName: string;
364
- }>>;
362
+ supportedModels(): Promise<ModelInfo[]>;
365
363
  /**
366
364
  * Rewind tracked files to their state at a user message (the CLI's
367
365
  * /rewind). Needs `enableFileCheckpointing: true` in the session options —
@@ -450,6 +448,7 @@ declare class ClaudeProvider implements Provider {
450
448
  interface AcpHandlers {
451
449
  onUpdate?: (n: SessionNotification) => void;
452
450
  onPermission?: (p: RequestPermissionRequest) => Promise<RequestPermissionResponse>;
451
+ onInput?: (p: CreateElicitationRequest) => Promise<CreateElicitationResponse>;
453
452
  }
454
453
  /** A live ACP agent process plus its negotiated connection. */
455
454
  interface AcpConnection {
@@ -475,6 +474,12 @@ interface AcpProviderOptions {
475
474
  installHint?: string;
476
475
  /** Test seam: replaces process spawning. */
477
476
  connect?: (cwd: string) => Promise<AcpConnection>;
477
+ /** How long a spawned agent gets to finish the ACP handshake before it is
478
+ * killed (default 30 s). */
479
+ handshakeTimeoutMs?: number;
480
+ /** How long a model-list or version probe may take end to end before the
481
+ * agent is closed and the probe fails (default 20 s). */
482
+ probeTimeoutMs?: number;
478
483
  }
479
484
  /**
480
485
  * Any agent speaking the Agent Client Protocol over stdio — OpenCode,
@@ -487,12 +492,17 @@ declare class AcpProvider implements SessionProvider {
487
492
  readonly executable: string;
488
493
  readonly loginCommand: string;
489
494
  readonly capabilities: ProviderCapabilities;
495
+ readonly sessionCapabilities: {
496
+ readonly fork: false;
497
+ };
490
498
  private readonly args;
491
499
  private readonly env;
492
500
  private readonly workDir;
493
501
  private readonly appName;
494
502
  private readonly modelConfigId;
495
503
  private readonly connectImpl;
504
+ private readonly handshakeTimeoutMs;
505
+ private readonly probeTimeoutMs;
496
506
  constructor(options: AcpProviderOptions);
497
507
  private spawnConnection;
498
508
  private classify;
@@ -505,6 +515,15 @@ declare class AcpProvider implements SessionProvider {
505
515
  */
506
516
  openSession(options: ProviderSessionOptions): ProviderSession;
507
517
  private selectModel;
518
+ private selectEffort;
519
+ /**
520
+ * Run a short question against a fresh agent and close it, whatever
521
+ * happens. The deadline covers the whole exchange: an agent that answers
522
+ * the handshake and then sits on newSession forever (Gemini, signed out
523
+ * or mid-update) used to hold the probe open — and its process alive —
524
+ * for as long as the host ran.
525
+ */
526
+ private probe;
508
527
  listModels(): Promise<EngineModel[]>;
509
528
  /**
510
529
  * The agent's self-reported name/version from the ACP handshake. When the
@@ -535,6 +554,6 @@ declare function resolveExecutable(providerId: string, name: string, installHint
535
554
  */
536
555
  declare function resolveClaudeExecutable(explicit?: string): string;
537
556
 
538
- declare const VERSION = "0.5.0";
557
+ declare const VERSION = "0.8.2";
539
558
 
540
559
  export { type AcpConnection, AcpProvider, type AcpProviderOptions, AgentSession, type AgentSessionOptions, ApiError, AuthRequiredError, ChatChunkTranslator, type ChatCompletion, type ChatCompletionChunk, type ChatCompletionsRequest, type ChatMessageParam, ClaudeProvider, type ClaudeProviderOptions, type ClaudeSessionOptions, EngineModel, EngineOptions, type MessageStreamEvent, MessagesRequest, MessagesResponse, type OpenAiUsage, type Parity, PermissionAdapter, type PermissionAdapterOptions, type PermissionDecision, type PermissionHandler, type PermissionRequest, Provider, ProviderCapabilities, ProviderError, ProviderNotInstalledError, ProviderSession, ProviderSessionOptions, SessionProvider, SseEvent, type TranslatedChatRequest, TurnEvent, TurnRequest, VERSION, type VersionSkew, Yagami, type YagamiChatCompletions, YagamiEngine, YagamiError, type YagamiMessages, type YagamiOptions, chatToMessagesRequest, claudeCodeSession, findExecutable, modelListBody, openAiErrorBody, resolveClaudeExecutable, resolveExecutable, settingSourcesFor, startAgentSession, toApiError, toChatCompletion };
package/dist/index.js CHANGED
@@ -31,7 +31,7 @@ import {
31
31
  toApiError,
32
32
  toChatCompletion,
33
33
  yagamiConfigDir
34
- } from "./chunk-ZYHC7PXX.js";
34
+ } from "./chunk-EKN223KD.js";
35
35
 
36
36
  // src/core/client.ts
37
37
  var Yagami = class {
@@ -278,8 +278,7 @@ var AgentSession = class {
278
278
  /** Models the CLI reports as available (for a picker). */
279
279
  async supportedModels() {
280
280
  this.ensureStarted();
281
- const models = await this.query.supportedModels();
282
- return models.map((m) => ({ value: m.value, displayName: m.displayName }));
281
+ return this.query.supportedModels();
283
282
  }
284
283
  /**
285
284
  * Rewind tracked files to their state at a user message (the CLI's
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 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"]}
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 ModelInfo,\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<ModelInfo[]> {\n this.ensureStarted();\n return this.query!.supportedModels();\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/dist/server.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ServerType } from '@hono/node-server';
2
- import { r as ProviderConfigEntry, M as MessagesRequest, l as CompleteResult, z as StreamOptions, F as StreamStart, E as EngineModel, Y as YagamiEngine, u as SessionCache } from './hostConfig-HmZ3z297.js';
3
- export { W as yagamiConfigDir } from './hostConfig-HmZ3z297.js';
2
+ import { u as ProviderConfigEntry, M as MessagesRequest, l as CompleteResult, W as StreamOptions, Z as StreamStart, E as EngineModel, Y as YagamiEngine, y as SessionCache } from './hostConfig-CbGD5-lN.js';
3
+ export { a8 as yagamiConfigDir } from './hostConfig-CbGD5-lN.js';
4
4
  import { Hono } from 'hono';
5
5
 
6
6
  interface YagamiConfig {
package/dist/server.js CHANGED
@@ -13,10 +13,10 @@ import {
13
13
  sessionCachePath,
14
14
  startYagami,
15
15
  writeServerState
16
- } from "./chunk-D2PNH6GV.js";
16
+ } from "./chunk-UGIJV6FZ.js";
17
17
  import {
18
18
  yagamiConfigDir
19
- } from "./chunk-ZYHC7PXX.js";
19
+ } from "./chunk-EKN223KD.js";
20
20
  export {
21
21
  clearServerState,
22
22
  configFilePath,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@justin06lee/yagami",
3
- "version": "0.6.1",
3
+ "version": "0.8.2",
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",