@apolloyh/apollo-agent 0.1.11 → 0.2.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.
Files changed (46) hide show
  1. package/.env.example +7 -0
  2. package/dist/brand.d.ts +2 -2
  3. package/dist/brand.js +2 -2
  4. package/dist/config.d.ts +4 -2
  5. package/dist/config.d.ts.map +1 -1
  6. package/dist/config.js +28 -15
  7. package/dist/coordinator/workflow.d.ts.map +1 -1
  8. package/dist/coordinator/workflow.js +6 -5
  9. package/dist/goal/goal-mode.d.ts +0 -4
  10. package/dist/goal/goal-mode.d.ts.map +1 -1
  11. package/dist/goal/goal-mode.js +6 -5
  12. package/dist/index.js +17 -12
  13. package/dist/llm/anthropic.d.ts +18 -11
  14. package/dist/llm/anthropic.d.ts.map +1 -1
  15. package/dist/llm/anthropic.js +6 -3
  16. package/dist/llm/openai.d.ts +8 -0
  17. package/dist/llm/openai.d.ts.map +1 -0
  18. package/dist/llm/openai.js +214 -0
  19. package/dist/runtime/permissions.d.ts.map +1 -1
  20. package/dist/runtime/permissions.js +5 -4
  21. package/dist/runtime/query-engine.d.ts +4 -1
  22. package/dist/runtime/query-engine.d.ts.map +1 -1
  23. package/dist/runtime/query-engine.js +20 -7
  24. package/dist/sdk.d.ts +6 -2
  25. package/dist/sdk.d.ts.map +1 -1
  26. package/dist/sdk.js +4 -1
  27. package/dist/status-ui.d.ts +1 -10
  28. package/dist/status-ui.d.ts.map +1 -1
  29. package/dist/status-ui.js +9 -7
  30. package/dist/terminal-theme.d.ts +45 -0
  31. package/dist/terminal-theme.d.ts.map +1 -0
  32. package/dist/terminal-theme.js +47 -0
  33. package/dist/thought-fold.d.ts.map +1 -1
  34. package/dist/thought-fold.js +3 -5
  35. package/dist/tools/builtin.js +1 -1
  36. package/dist/tools/registry.d.ts +1 -0
  37. package/dist/tools/registry.d.ts.map +1 -1
  38. package/dist/tools/registry.js +3 -0
  39. package/dist/trace.d.ts +2 -0
  40. package/dist/trace.d.ts.map +1 -1
  41. package/dist/trace.js +56 -30
  42. package/dist/types.d.ts +9 -0
  43. package/dist/types.d.ts.map +1 -1
  44. package/docs/guide.md +13 -2
  45. package/docs/sdk.md +48 -0
  46. package/package.json +2 -1
@@ -0,0 +1,214 @@
1
+ import { ProviderApiError, MalformedStreamError, MalformedToolInputError, } from "./anthropic.js";
2
+ export class OpenAIClient {
3
+ config;
4
+ constructor(config) {
5
+ this.config = config;
6
+ }
7
+ async createMessage(input) {
8
+ const response = await fetch(openAIEndpoint(this.config.baseUrl), {
9
+ method: "POST",
10
+ headers: { "content-type": "application/json", authorization: `Bearer ${this.config.authToken}` },
11
+ body: JSON.stringify({
12
+ model: this.config.model,
13
+ messages: toOpenAIMessages(input.system, input.messages),
14
+ [this.config.openaiMaxTokensParam ?? "max_tokens"]: this.config.maxTokens,
15
+ ...(input.tools.length ? { tools: input.tools.map(toOpenAITool), tool_choice: "auto" } : {}),
16
+ stream: input.stream ?? false,
17
+ ...(input.stream ? { stream_options: { include_usage: true } } : {}),
18
+ }),
19
+ signal: input.signal
20
+ ? AbortSignal.any([input.signal, AbortSignal.timeout(normalizeTimeout(this.config.timeoutMs))])
21
+ : AbortSignal.timeout(normalizeTimeout(this.config.timeoutMs)),
22
+ });
23
+ if (!response.ok)
24
+ throw new ProviderApiError(response.status, await response.text(), response.headers);
25
+ return input.stream ? readOpenAIStream(response, input) : normalizeOpenAIResponse(await response.json());
26
+ }
27
+ }
28
+ function openAIEndpoint(baseUrl) {
29
+ const base = baseUrl.replace(/\/$/, "");
30
+ if (/\/chat\/completions$/i.test(base))
31
+ return base;
32
+ return `${base}${/\/v1$/i.test(base) ? "" : "/v1"}/chat/completions`;
33
+ }
34
+ function toOpenAITool(tool) {
35
+ return { type: "function", function: { name: tool.name, description: tool.description, parameters: tool.input_schema } };
36
+ }
37
+ function toOpenAIMessages(system, messages) {
38
+ const output = system ? [{ role: "system", content: system }] : [];
39
+ for (const message of messages) {
40
+ if (typeof message.content === "string") {
41
+ output.push({ role: message.role, content: message.content });
42
+ continue;
43
+ }
44
+ if (message.role === "assistant") {
45
+ const text = message.content.filter((block) => block.type === "text").map((block) => block.text).join("");
46
+ const toolCalls = message.content.filter((block) => block.type === "tool_use").map((block) => ({
47
+ id: block.id,
48
+ type: "function",
49
+ function: { name: block.name, arguments: JSON.stringify(block.input) },
50
+ }));
51
+ output.push({ role: "assistant", content: text || null, ...(toolCalls.length ? { tool_calls: toolCalls } : {}) });
52
+ continue;
53
+ }
54
+ for (const block of message.content) {
55
+ if (block.type === "tool_result")
56
+ output.push({ role: "tool", tool_call_id: block.tool_use_id, content: block.is_error ? `[error] ${block.content}` : block.content });
57
+ }
58
+ const text = message.content.filter((block) => block.type === "text").map((block) => block.text).join("");
59
+ if (text)
60
+ output.push({ role: "user", content: text });
61
+ }
62
+ return output;
63
+ }
64
+ function normalizeOpenAIResponse(value) {
65
+ const source = value;
66
+ const choice = source.choices?.[0];
67
+ if (!choice?.message)
68
+ throw new MalformedStreamError("OpenAI API returned no assistant message.");
69
+ return {
70
+ id: source.id ?? "",
71
+ type: "message",
72
+ role: "assistant",
73
+ content: normalizeOpenAIContent(choice.message),
74
+ stop_reason: normalizeStopReason(choice.finish_reason),
75
+ usage: normalizeUsage(source.usage),
76
+ };
77
+ }
78
+ async function readOpenAIStream(response, input) {
79
+ if (!response.body)
80
+ throw new MalformedStreamError("OpenAI API returned an empty stream body.");
81
+ const reader = response.body.getReader();
82
+ const decoder = new TextDecoder();
83
+ const tools = new Map();
84
+ let buffer = "", id = "", text = "", thinking = "", stopReason, usage, ended = false;
85
+ const apply = (data) => {
86
+ if (!data || data === "[DONE]")
87
+ return;
88
+ let event;
89
+ try {
90
+ event = JSON.parse(data);
91
+ }
92
+ catch (error) {
93
+ throw new MalformedStreamError("OpenAI API returned malformed JSON in the event stream.", error);
94
+ }
95
+ id ||= event.id ?? "";
96
+ usage = normalizeUsage(event.usage) ?? usage;
97
+ const choice = event.choices?.[0];
98
+ const delta = choice?.delta;
99
+ if (choice?.finish_reason)
100
+ stopReason = normalizeStopReason(choice.finish_reason);
101
+ if (!delta)
102
+ return;
103
+ const reasoning = delta.reasoning_content ?? delta.reasoning;
104
+ if (reasoning) {
105
+ thinking += reasoning;
106
+ input.onThinkingDelta?.({ text: reasoning });
107
+ }
108
+ if (delta.content) {
109
+ text += delta.content;
110
+ input.onTextDelta?.(delta.content);
111
+ }
112
+ for (const part of delta.tool_calls ?? []) {
113
+ const index = part.index ?? 0;
114
+ const tool = tools.get(index) ?? { id: "", name: "", arguments: "" };
115
+ const wasUnnamed = !tool.name;
116
+ tool.id ||= part.id ?? "";
117
+ tool.name += part.function?.name ?? "";
118
+ tool.arguments += part.function?.arguments ?? "";
119
+ tools.set(index, tool);
120
+ if (wasUnnamed && tool.name)
121
+ input.onToolInputDelta?.({ bytes: 0, tool: tool.name });
122
+ if (part.function?.arguments)
123
+ input.onToolInputDelta?.({ bytes: tool.arguments.length, tool: tool.name || undefined, detail: partialToolDetail(tool.arguments) });
124
+ }
125
+ };
126
+ try {
127
+ for (;;) {
128
+ const chunk = await reader.read();
129
+ if (chunk.done) {
130
+ ended = true;
131
+ break;
132
+ }
133
+ buffer += decoder.decode(chunk.value, { stream: true });
134
+ let separator = buffer.match(/\r?\n\r?\n/);
135
+ while (separator?.index !== undefined) {
136
+ const raw = buffer.slice(0, separator.index);
137
+ buffer = buffer.slice(separator.index + separator[0].length);
138
+ apply(parseSseData(raw));
139
+ separator = buffer.match(/\r?\n\r?\n/);
140
+ }
141
+ }
142
+ buffer += decoder.decode();
143
+ if (buffer.trim())
144
+ apply(parseSseData(buffer));
145
+ if (!text && !thinking && !tools.size)
146
+ throw new MalformedStreamError("OpenAI API returned an empty or incomplete event stream.");
147
+ const content = [];
148
+ if (thinking)
149
+ content.push({ type: "thinking", thinking });
150
+ if (text)
151
+ content.push({ type: "text", text });
152
+ for (const [, tool] of [...tools].sort(([a], [b]) => a - b))
153
+ content.push(toToolUse(tool));
154
+ return { id, type: "message", role: "assistant", content, stop_reason: stopReason, usage };
155
+ }
156
+ finally {
157
+ if (!ended)
158
+ await reader.cancel().catch(() => undefined);
159
+ reader.releaseLock();
160
+ }
161
+ }
162
+ function normalizeOpenAIContent(message) {
163
+ const content = [];
164
+ const reasoning = message.reasoning_content ?? message.reasoning;
165
+ if (reasoning)
166
+ content.push({ type: "thinking", thinking: reasoning });
167
+ if (message.content)
168
+ content.push({ type: "text", text: message.content });
169
+ for (const [index, call] of (message.tool_calls ?? []).entries())
170
+ content.push(toToolUse({ id: call.id ?? `call-${index}`, name: call.function?.name ?? "", arguments: call.function?.arguments ?? "" }));
171
+ return content;
172
+ }
173
+ function toToolUse(tool) {
174
+ try {
175
+ return { type: "tool_use", id: tool.id, name: tool.name, input: tool.arguments.trim() ? JSON.parse(tool.arguments) : {} };
176
+ }
177
+ catch (error) {
178
+ throw new MalformedToolInputError(tool.name, tool.arguments.length, error);
179
+ }
180
+ }
181
+ function normalizeUsage(value) {
182
+ if (!value || typeof value !== "object")
183
+ return undefined;
184
+ const usage = value;
185
+ if (typeof usage.prompt_tokens !== "number" && typeof usage.completion_tokens !== "number")
186
+ return undefined;
187
+ return { input_tokens: usage.prompt_tokens ?? 0, output_tokens: usage.completion_tokens ?? 0, cache_creation_input_tokens: 0, cache_read_input_tokens: usage.prompt_tokens_details?.cached_tokens ?? 0 };
188
+ }
189
+ function normalizeStopReason(reason) {
190
+ if (reason === "tool_calls" || reason === "function_call")
191
+ return "tool_use";
192
+ if (reason === "length")
193
+ return "max_tokens";
194
+ if (reason === "stop")
195
+ return "end_turn";
196
+ return reason;
197
+ }
198
+ function parseSseData(raw) {
199
+ return raw.split(/\r?\n/).filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trimStart()).join("\n").trim();
200
+ }
201
+ function partialToolDetail(input) {
202
+ const match = input.slice(0, 8192).match(/"(?:path|file_path|command|query|url|description)"\s*:\s*"((?:\\.|[^"\\])*)"/);
203
+ if (!match?.[1])
204
+ return undefined;
205
+ try {
206
+ return JSON.parse(`"${match[1]}"`);
207
+ }
208
+ catch {
209
+ return undefined;
210
+ }
211
+ }
212
+ function normalizeTimeout(value) {
213
+ return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 300000;
214
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/runtime/permissions.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAG7F,KAAK,kBAAkB,GAAG;IACxB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/C,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;CAC5C,CAAC;AAEF,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,WAAW,EACnB,IAAI,EAAE,SAAS,EACf,SAAS,EAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC,EACpC,OAAO,GAAE,kBAAuB,GAC/B,gBAAgB,CA8BlB;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,eAAe,EAAE,QAAQ,UAAQ,GAAG,MAAM,CAa7G"}
1
+ {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/runtime/permissions.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAI7F,KAAK,kBAAkB,GAAG;IACxB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/C,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;CAC5C,CAAC;AAEF,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,WAAW,EACnB,IAAI,EAAE,SAAS,EACf,SAAS,EAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC,EACpC,OAAO,GAAE,kBAAuB,GAC/B,gBAAgB,CA8BlB;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,eAAe,EAAE,QAAQ,UAAQ,GAAG,MAAM,CAa7G"}
@@ -2,6 +2,7 @@ import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import readline from "node:readline/promises";
4
4
  import { stdin as input, stderr as output } from "node:process";
5
+ import { TERMINAL_ANSI } from "../terminal-theme.js";
5
6
  import { stringify } from "../utils.js";
6
7
  export function createCliApprovalProvider(config, emit, assumeYes, options = {}) {
7
8
  return async (request) => {
@@ -126,11 +127,11 @@ function paint(value, color, enabled) {
126
127
  if (!enabled || color === "normal")
127
128
  return value;
128
129
  const code = color === "dim"
129
- ? "\x1b[90m"
130
+ ? TERMINAL_ANSI.inactive
130
131
  : color === "yellow"
131
- ? "\x1b[33m"
132
+ ? TERMINAL_ANSI.warning
132
133
  : color === "yellowBold"
133
- ? "\x1b[1;33m"
134
- : "\x1b[1;38;2;96;165;250m";
134
+ ? `\x1b[1m${TERMINAL_ANSI.warning}`
135
+ : `\x1b[1m${TERMINAL_ANSI.permission}`;
135
136
  return `${code}${value}\x1b[0m`;
136
137
  }
@@ -1,4 +1,4 @@
1
- import type { AgentConfig, ApprovalProvider, AskUserFn, LlmConfig, Message, SubagentConfig, TraceSink } from "../types.js";
1
+ import type { AgentConfig, ApprovalProvider, AskUserFn, LlmConfig, Message, SubagentConfig, TraceSink, ToolDefinition } from "../types.js";
2
2
  import { type AnthropicUsage } from "../llm/anthropic.js";
3
3
  import { type PlanState } from "../plan/plan-mode.js";
4
4
  import { type WorkflowState } from "../coordinator/workflow.js";
@@ -15,6 +15,8 @@ export type QueryEngineOptions = {
15
15
  depth?: number;
16
16
  askUser?: AskUserFn;
17
17
  sessionId?: string;
18
+ extraTools?: ToolDefinition[];
19
+ memoryEnabled?: boolean;
18
20
  };
19
21
  export type UsageCategory = "main" | "task" | "compaction";
20
22
  type UsageCounters = AnthropicUsage & {
@@ -83,6 +85,7 @@ export declare class QueryEngine {
83
85
  model: string;
84
86
  baseUrl: string;
85
87
  maxTokens: number;
88
+ openaiMaxTokensParam: "max_tokens" | "max_completion_tokens" | undefined;
86
89
  contextMaxChars: number;
87
90
  workspaceRoot: string;
88
91
  };
@@ -1 +1 @@
1
- {"version":3,"file":"query-engine.d.ts","sourceRoot":"","sources":["../../src/runtime/query-engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"query-engine.d.ts","sourceRoot":"","sources":["../../src/runtime/query-engine.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { createHash } from "node:crypto";
2
- import { AnthropicApiError, AnthropicClient, MalformedStreamError, } from "../llm/anthropic.js";
2
+ import { AnthropicClient, MalformedStreamError, ProviderApiError, } from "../llm/anthropic.js";
3
+ import { OpenAIClient } from "../llm/openai.js";
3
4
  import { ContextManager, isContextSummary } from "./context.js";
4
5
  import { buildCompactionTranscript, COMPACTION_SYSTEM_PROMPT, normalizeCompactionSummary, } from "./compaction.js";
5
6
  import { createCliApprovalProvider } from "./permissions.js";
@@ -68,7 +69,9 @@ export class QueryEngine {
68
69
  activeTurnAbort;
69
70
  constructor(options) {
70
71
  this.options = options;
71
- this.client = new AnthropicClient(options.llmConfig);
72
+ this.client = options.llmConfig.protocol === "openai"
73
+ ? new OpenAIClient(options.llmConfig)
74
+ : new AnthropicClient(options.llmConfig);
72
75
  this.contextManager = new ContextManager(options.agentConfig.context, options.emit);
73
76
  this.skillManager = new SkillManager(options.agentConfig);
74
77
  this.mcpManager = new McpManager(options.agentConfig);
@@ -138,6 +141,7 @@ export class QueryEngine {
138
141
  model: this.options.llmConfig.model,
139
142
  baseUrl: this.options.llmConfig.baseUrl,
140
143
  maxTokens: this.options.llmConfig.maxTokens,
144
+ openaiMaxTokensParam: this.options.llmConfig.openaiMaxTokensParam,
141
145
  contextMaxChars: this.options.agentConfig.context.maxChars,
142
146
  workspaceRoot: this.options.agentConfig.workspaceRoot,
143
147
  };
@@ -482,12 +486,19 @@ export class QueryEngine {
482
486
  allowedTools: this.options.subagent?.tools,
483
487
  runTask: isSubagent ? undefined : (agent, prompt, emit) => this.runTask(agent, prompt, emit),
484
488
  });
489
+ if (this.options.memoryEnabled === false) {
490
+ registry.remove("memory_search");
491
+ registry.remove("memory_save");
492
+ registry.remove("memory_list");
493
+ }
494
+ for (const tool of this.options.extraTools ?? [])
495
+ registry.register(tool);
485
496
  registry.setHooks(this.hooks);
486
497
  registry.setPlanMode(this.mode === "plan");
487
498
  const [availableSkills, matchedSkills, memBlock] = await Promise.all([
488
499
  this.skillManager.metadata(),
489
500
  this.matchedSkillsForPrompt(input),
490
- isSubagent ? Promise.resolve("") : memoryContextBlock(this.options.agentConfig.workspaceRoot, input),
501
+ isSubagent || this.options.memoryEnabled === false ? Promise.resolve("") : memoryContextBlock(this.options.agentConfig.workspaceRoot, input),
491
502
  ]);
492
503
  const modeExtra = this.runtimeModeContext();
493
504
  const memoryExtra = this.takeMemoryContext(memBlock);
@@ -669,6 +680,7 @@ export class QueryEngine {
669
680
  isError: result.isError,
670
681
  content: truncate(result.content, 1000),
671
682
  fileChange: result.fileChange,
683
+ artifacts: result.artifacts,
672
684
  });
673
685
  // refresh plan after write
674
686
  if (toolUse.name === "write_file" && this.mode === "plan") {
@@ -942,6 +954,7 @@ export class QueryEngine {
942
954
  }
943
955
  configFingerprint() {
944
956
  return fingerprint({
957
+ protocol: this.options.llmConfig.protocol ?? "anthropic",
945
958
  baseUrl: this.options.llmConfig.baseUrl.replace(/\/$/, ""),
946
959
  model: this.options.llmConfig.model,
947
960
  maxTokens: this.options.llmConfig.maxTokens,
@@ -1101,7 +1114,7 @@ function fingerprint(value) {
1101
1114
  return createHash("sha256").update(content).digest("hex").slice(0, 12);
1102
1115
  }
1103
1116
  function isTransientLlmError(error) {
1104
- if (error instanceof AnthropicApiError) {
1117
+ if (error instanceof ProviderApiError) {
1105
1118
  const shouldRetry = error.responseHeaders.get("x-should-retry");
1106
1119
  if (shouldRetry === "false")
1107
1120
  return false;
@@ -1122,7 +1135,7 @@ function isTransientLlmError(error) {
1122
1135
  return ["ECONNRESET", "ECONNREFUSED", "EPIPE", "ETIMEDOUT", "ENETUNREACH", "EAI_AGAIN"].includes(code ?? "");
1123
1136
  }
1124
1137
  function isContextOverflowError(error) {
1125
- if (!(error instanceof AnthropicApiError))
1138
+ if (!(error instanceof ProviderApiError))
1126
1139
  return false;
1127
1140
  if (error.status === 413)
1128
1141
  return true;
@@ -1132,7 +1145,7 @@ function isContextOverflowError(error) {
1132
1145
  .test(error.responseBody);
1133
1146
  }
1134
1147
  function retryDelayMs(error, attempt) {
1135
- if (error instanceof AnthropicApiError) {
1148
+ if (error instanceof ProviderApiError) {
1136
1149
  const retryAfter = error.responseHeaders.get("retry-after");
1137
1150
  if (retryAfter) {
1138
1151
  const seconds = Number(retryAfter);
@@ -1149,7 +1162,7 @@ function retryDelayMs(error, attempt) {
1149
1162
  return Math.round(base + Math.random() * base * 0.25);
1150
1163
  }
1151
1164
  function retryReason(error) {
1152
- if (error instanceof AnthropicApiError)
1165
+ if (error instanceof ProviderApiError)
1153
1166
  return `provider API ${error.status}`;
1154
1167
  if (error instanceof Error && error.name === "TimeoutError")
1155
1168
  return "provider request timed out";
package/dist/sdk.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  import { QueryEngine, type QueryEngineOptions } from "./runtime/query-engine.js";
2
- import type { AgentConfig, ApprovalProvider, AskUserFn, LlmConfig, TraceSink } from "./types.js";
2
+ import type { AgentConfig, ApprovalProvider, AskUserFn, LlmConfig, ToolDefinition, TraceSink } from "./types.js";
3
3
  export type CreateQueryEngineOptions = {
4
4
  configPath?: string;
5
+ configMode?: "layered" | "isolated";
6
+ workspaceRoot?: string;
5
7
  envPath?: string;
6
8
  agentConfig?: AgentConfig;
7
9
  llmConfig?: LlmConfig;
@@ -11,6 +13,8 @@ export type CreateQueryEngineOptions = {
11
13
  onEvent?: TraceSink;
12
14
  askUser?: AskUserFn;
13
15
  sessionId?: string;
16
+ extraTools?: ToolDefinition[];
17
+ memoryEnabled?: boolean;
14
18
  };
15
19
  export type RunAgentTurnOptions = CreateQueryEngineOptions & {
16
20
  input: string;
@@ -29,5 +33,5 @@ export { createWorkflow, workflowStatusBar } from "./coordinator/workflow.js";
29
33
  export { skillifySession } from "./skillify/skillify.js";
30
34
  export { saveMemory, searchMemories, listMemories } from "./memory/memdir.js";
31
35
  export { listSessions, loadSession, loadLatestSession } from "./session/store.js";
32
- export type { AgentConfig, AnthropicTool, ApprovalProvider, AskUserFn, FileChangeDisplay, LlmConfig, Message, SubagentConfig, ToolDefinition, ToolResult, TraceEvent, } from "./types.js";
36
+ export type { AgentConfig, AnthropicTool, ApprovalProvider, AskUserFn, FileChangeDisplay, LlmConfig, JsonObject, Message, SubagentConfig, ToolDefinition, ToolArtifact, ToolResult, TraceEvent, } from "./types.js";
33
37
  //# sourceMappingURL=sdk.d.ts.map
package/dist/sdk.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../src/sdk.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACjF,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,SAAS,EAAE,SAAS,EAAc,SAAS,EAAE,MAAM,YAAY,CAAC;AAE7G,MAAM,MAAM,wBAAwB,GAAG;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC,CAAC;IACtC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,MAAM,CAAC,EAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC,CAAC;IACnC,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,wBAAwB,GAAG;IAC3D,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,wBAAsB,iBAAiB,CAAC,OAAO,GAAE,wBAA6B,GAAG,OAAO,CAAC,WAAW,CAAC,CAkBpG;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAO5F;AAID,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAClF,YAAY,EACV,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,SAAS,EACT,iBAAiB,EACjB,SAAS,EACT,OAAO,EACP,cAAc,EACd,cAAc,EACd,UAAU,EACV,UAAU,GACX,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../src/sdk.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACjF,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,EAAc,SAAS,EAAE,MAAM,YAAY,CAAC;AAE7H,MAAM,MAAM,wBAAwB,GAAG;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;IACpC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC,CAAC;IACtC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,MAAM,CAAC,EAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC,CAAC;IACnC,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,cAAc,EAAE,CAAC;IAC9B,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,wBAAwB,GAAG;IAC3D,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,wBAAsB,iBAAiB,CAAC,OAAO,GAAE,wBAA6B,GAAG,OAAO,CAAC,WAAW,CAAC,CAqBpG;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAO5F;AAID,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAClF,YAAY,EACV,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,SAAS,EACT,iBAAiB,EACjB,SAAS,EACT,UAAU,EACV,OAAO,EACP,cAAc,EACd,cAAc,EACd,YAAY,EACZ,UAAU,EACV,UAAU,GACX,MAAM,YAAY,CAAC"}
package/dist/sdk.js CHANGED
@@ -3,7 +3,8 @@ import { QueryEngine } from "./runtime/query-engine.js";
3
3
  export async function createQueryEngine(options = {}) {
4
4
  if (options.envPath || !options.llmConfig)
5
5
  loadEnvFile(options.envPath);
6
- const agentConfig = options.agentConfig ?? (await loadAgentConfig(options.configPath));
6
+ const loadedConfig = options.agentConfig ?? (await loadAgentConfig(options.configPath, { isolated: options.configMode === "isolated" }));
7
+ const agentConfig = options.workspaceRoot ? { ...loadedConfig, workspaceRoot: options.workspaceRoot } : loadedConfig;
7
8
  const llmConfig = options.llmConfig ?? loadLlmConfig();
8
9
  const engine = new QueryEngine({
9
10
  agentConfig,
@@ -14,6 +15,8 @@ export async function createQueryEngine(options = {}) {
14
15
  stream: options.stream,
15
16
  askUser: options.askUser,
16
17
  sessionId: options.sessionId,
18
+ extraTools: options.extraTools,
19
+ memoryEnabled: options.memoryEnabled,
17
20
  });
18
21
  if (options.sessionId) {
19
22
  await engine.resumeSession(options.sessionId);
@@ -1,19 +1,10 @@
1
- /**
2
- * Claude Code–style waiting indicator + outcome dots.
3
- *
4
- * Running: morphing sparkle · ✢ ✳ ✶ ✻ ✽ + shimmer label
5
- * Success: green ● (CC uses ● / ⏺ for completed status)
6
- * Failure: red ●
7
- *
8
- * Refs: SpinnerGlyph (stalled→error red), figures BLACK_CIRCLE, BriefIdleStatus ●
9
- */
10
1
  /** Filled circle — CC completed / idle status glyph. */
11
2
  export declare const STATUS_DOT = "\u25CF";
12
3
  export declare function spinnerGlyph(frame: number): string;
13
4
  export declare function glimmerIndex(frame: number, messageWidth: number): number;
14
5
  export declare function shimmerLabel(label: string, frame: number, useColor: boolean): string;
15
6
  export declare function formatSpinnerGlyph(frame: number, useColor: boolean): string;
16
- export declare const STATUS_TICK_MS = 160;
7
+ export declare const STATUS_TICK_MS = 140;
17
8
  export declare function formatWaitLine(options: {
18
9
  frame: number;
19
10
  label: string;
@@ -1 +1 @@
1
- {"version":3,"file":"status-ui.d.ts","sourceRoot":"","sources":["../src/status-ui.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAmCH,wDAAwD;AACxD,eAAO,MAAM,UAAU,WAAM,CAAC;AAE9B,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGlD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAKxE;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,CAkBpF;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,CAO3E;AAED,eAAO,MAAM,cAAc,MAAM,CAAC;AAElC,wBAAgB,cAAc,CAAC,OAAO,EAAE;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACnB,GAAG,MAAM,CAKT;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IACzC,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC;IAC7B,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACnB,GAAG,MAAM,CAcT;AAeD,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,CAErE;AACD,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEjD"}
1
+ {"version":3,"file":"status-ui.d.ts","sourceRoot":"","sources":["../src/status-ui.ts"],"names":[],"mappings":"AA6CA,wDAAwD;AACxD,eAAO,MAAM,UAAU,WAAM,CAAC;AAE9B,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGlD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAKxE;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,CAkBpF;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,CAO3E;AAED,eAAO,MAAM,cAAc,MAAM,CAAC;AAElC,wBAAgB,cAAc,CAAC,OAAO,EAAE;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACnB,GAAG,MAAM,CAKT;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IACzC,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC;IAC7B,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACnB,GAAG,MAAM,CAcT;AAeD,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,CAErE;AACD,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEjD"}
package/dist/status-ui.js CHANGED
@@ -7,18 +7,20 @@
7
7
  *
8
8
  * Refs: SpinnerGlyph (stalled→error red), figures BLACK_CIRCLE, BriefIdleStatus ●
9
9
  */
10
+ import { TERMINAL_DARK_RGB } from "./terminal-theme.js";
10
11
  const SPINNER_CHARS = ["·", "✢", "✳", "✶", "✻", "✽"];
11
12
  const SPINNER_FRAMES = [
12
13
  ...SPINNER_CHARS,
13
14
  ...[...SPINNER_CHARS].reverse(),
14
15
  ];
15
- const GLYPH_EVERY = 3;
16
+ const GLYPH_EVERY = 1;
16
17
  const SHIMMER_EVERY = 4;
17
- const BASE_RGB = { r: 148, g: 163, b: 184 };
18
- const SHIMMER_RGB = { r: 147, g: 197, b: 253 };
19
- const GLYPH_RGB = { r: 96, g: 165, b: 250 };
20
- const GREEN_RGB = { r: 34, g: 197, b: 94 }; // green-500
21
- const RED_RGB = { r: 239, g: 68, b: 68 }; // red-500
18
+ const asRgb = (value) => ({ r: value[0], g: value[1], b: value[2] });
19
+ const BASE_RGB = asRgb(TERMINAL_DARK_RGB.spinnerBase);
20
+ const SHIMMER_RGB = asRgb(TERMINAL_DARK_RGB.spinnerShimmer);
21
+ const GLYPH_RGB = asRgb(TERMINAL_DARK_RGB.spinnerBlue);
22
+ const GREEN_RGB = asRgb(TERMINAL_DARK_RGB.success);
23
+ const RED_RGB = asRgb(TERMINAL_DARK_RGB.error);
22
24
  function lerp(a, b, t) {
23
25
  return Math.round(a + (b - a) * t);
24
26
  }
@@ -77,7 +79,7 @@ export function formatSpinnerGlyph(frame, useColor) {
77
79
  const nearPeak = step === peak || step === SPINNER_FRAMES.length - peak - 1;
78
80
  return `${rgbAnsi(nearPeak ? SHIMMER_RGB : GLYPH_RGB)}${ch}${RESET}`;
79
81
  }
80
- export const STATUS_TICK_MS = 160;
82
+ export const STATUS_TICK_MS = 140;
81
83
  export function formatWaitLine(options) {
82
84
  const glyph = formatSpinnerGlyph(options.frame, options.useColor);
83
85
  const label = shimmerLabel(options.label, options.frame, options.useColor);
@@ -0,0 +1,45 @@
1
+ export type TerminalRgb = readonly [number, number, number];
2
+ /** Canonical brand colors. Terminal surfaces use the softer dark theme below. */
3
+ export declare const APOLLO_BRAND_PALETTE: {
4
+ readonly blue: "#4285F4";
5
+ readonly red: "#EA4335";
6
+ readonly yellow: "#FBBC05";
7
+ readonly green: "#34A853";
8
+ };
9
+ /** Dark terminal palette matched to cc-yh's theme and Monokai Extended syntax colors. */
10
+ export declare const TERMINAL_DARK_RGB: {
11
+ brandBlue: [number, number, number];
12
+ spinnerBase: [number, number, number];
13
+ spinnerBlue: [number, number, number];
14
+ spinnerShimmer: [number, number, number];
15
+ permission: [number, number, number];
16
+ permissionShimmer: [number, number, number];
17
+ success: [number, number, number];
18
+ error: [number, number, number];
19
+ warning: [number, number, number];
20
+ text: [number, number, number];
21
+ inactive: [number, number, number];
22
+ subtle: [number, number, number];
23
+ diffAdded: [number, number, number];
24
+ diffRemoved: [number, number, number];
25
+ keyword: [number, number, number];
26
+ storage: [number, number, number];
27
+ syntaxGreen: [number, number, number];
28
+ literal: [number, number, number];
29
+ string: [number, number, number];
30
+ params: [number, number, number];
31
+ comment: [number, number, number];
32
+ };
33
+ export declare function terminalForeground(rgb: TerminalRgb): string;
34
+ export declare function terminalBackground(rgb: TerminalRgb): string;
35
+ export declare const TERMINAL_ANSI: {
36
+ readonly brandBlue: string;
37
+ readonly permission: string;
38
+ readonly success: string;
39
+ readonly error: string;
40
+ readonly warning: string;
41
+ readonly text: string;
42
+ readonly inactive: string;
43
+ readonly subtle: string;
44
+ };
45
+ //# sourceMappingURL=terminal-theme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-theme.d.ts","sourceRoot":"","sources":["../src/terminal-theme.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAE5D,iFAAiF;AACjF,eAAO,MAAM,oBAAoB;;;;;CAKvB,CAAC;AAEX,yFAAyF;AACzF,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;CAsBS,CAAC;AAExC,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,WAAW,GAAG,MAAM,CAE3D;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,WAAW,GAAG,MAAM,CAE3D;AAED,eAAO,MAAM,aAAa;;;;;;;;;CAShB,CAAC"}
@@ -0,0 +1,47 @@
1
+ /** Canonical brand colors. Terminal surfaces use the softer dark theme below. */
2
+ export const APOLLO_BRAND_PALETTE = {
3
+ blue: "#4285F4",
4
+ red: "#EA4335",
5
+ yellow: "#FBBC05",
6
+ green: "#34A853",
7
+ };
8
+ /** Dark terminal palette matched to cc-yh's theme and Monokai Extended syntax colors. */
9
+ export const TERMINAL_DARK_RGB = {
10
+ brandBlue: [66, 133, 244],
11
+ spinnerBase: [148, 163, 184],
12
+ spinnerBlue: [96, 165, 250],
13
+ spinnerShimmer: [147, 197, 253],
14
+ permission: [177, 185, 249],
15
+ permissionShimmer: [207, 215, 255],
16
+ success: [78, 186, 101],
17
+ error: [255, 107, 128],
18
+ warning: [255, 193, 7],
19
+ text: [248, 248, 242],
20
+ inactive: [153, 153, 153],
21
+ subtle: [80, 80, 80],
22
+ diffAdded: [34, 92, 43],
23
+ diffRemoved: [122, 41, 54],
24
+ keyword: [249, 38, 114],
25
+ storage: [102, 217, 239],
26
+ syntaxGreen: [166, 226, 46],
27
+ literal: [190, 132, 255],
28
+ string: [230, 219, 116],
29
+ params: [253, 151, 31],
30
+ comment: [117, 113, 94],
31
+ };
32
+ export function terminalForeground(rgb) {
33
+ return `\x1b[38;2;${rgb[0]};${rgb[1]};${rgb[2]}m`;
34
+ }
35
+ export function terminalBackground(rgb) {
36
+ return `\x1b[48;2;${rgb[0]};${rgb[1]};${rgb[2]}m`;
37
+ }
38
+ export const TERMINAL_ANSI = {
39
+ brandBlue: terminalForeground(TERMINAL_DARK_RGB.brandBlue),
40
+ permission: terminalForeground(TERMINAL_DARK_RGB.permission),
41
+ success: terminalForeground(TERMINAL_DARK_RGB.success),
42
+ error: terminalForeground(TERMINAL_DARK_RGB.error),
43
+ warning: terminalForeground(TERMINAL_DARK_RGB.warning),
44
+ text: terminalForeground(TERMINAL_DARK_RGB.text),
45
+ inactive: terminalForeground(TERMINAL_DARK_RGB.inactive),
46
+ subtle: terminalForeground(TERMINAL_DARK_RGB.subtle),
47
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"thought-fold.d.ts","sourceRoot":"","sources":["../src/thought-fold.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,MAAM,YAAY,GAAG;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B,CAAC;AAOF,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,OAAO,CAAqB;gBAExB,OAAO,EAAE,kBAAkB;IAIvC,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAI9B,qDAAqD;IACrD,SAAS,IAAI,IAAI;IAQjB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAKlC,YAAY,CAAC,KAAK,EAAE,YAAY,EAAE,QAAQ,SAAM,GAAG,IAAI;IAevD;;;OAGG;IACH,gBAAgB,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,MAAM,UAAQ,EAAE,WAAW,UAAQ,GAAG,YAAY,GAAG,IAAI;IAWnG,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,QAAQ;IAKhB,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,GAAG;CAIZ"}
1
+ {"version":3,"file":"thought-fold.d.ts","sourceRoot":"","sources":["../src/thought-fold.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,MAAM,MAAM,YAAY,GAAG;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B,CAAC;AAIF,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,OAAO,CAAqB;gBAExB,OAAO,EAAE,kBAAkB;IAIvC,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAI9B,qDAAqD;IACrD,SAAS,IAAI,IAAI;IAQjB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAKlC,YAAY,CAAC,KAAK,EAAE,YAAY,EAAE,QAAQ,SAAM,GAAG,IAAI;IAevD;;;OAGG;IACH,gBAAgB,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,MAAM,UAAQ,EAAE,WAAW,UAAQ,GAAG,YAAY,GAAG,IAAI;IAWnG,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,QAAQ;IAKhB,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,GAAG;CAIZ"}
@@ -2,10 +2,8 @@
2
2
  * Bounded terminal preview for model thinking tokens.
3
3
  */
4
4
  import { stripTerminalEscapes } from "./trace.js";
5
- const DIM = "\x1b[90m";
5
+ import { TERMINAL_ANSI } from "./terminal-theme.js";
6
6
  const RESET = "\x1b[0m";
7
- const GREEN = "\x1b[32m";
8
- const RED = "\x1b[31m";
9
7
  export class ThoughtFoldManager {
10
8
  current = null;
11
9
  options;
@@ -65,7 +63,7 @@ export class ThoughtFoldManager {
65
63
  return `${(ms / 1000).toFixed(1)}s`;
66
64
  }
67
65
  printHeader(block) {
68
- const color = block.failed ? RED : GREEN;
66
+ const color = block.failed ? TERMINAL_ANSI.error : TERMINAL_ANSI.success;
69
67
  const dot = this.options.color ? `${color}●${RESET}` : "●";
70
68
  const label = block.failed
71
69
  ? `Failed · ${this.duration(block)}`
@@ -76,6 +74,6 @@ export class ThoughtFoldManager {
76
74
  dim(text) {
77
75
  if (!this.options.color)
78
76
  return text;
79
- return `${DIM}${text}${RESET}`;
77
+ return `${TERMINAL_ANSI.inactive}${text}${RESET}`;
80
78
  }
81
79
  }