@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
package/.env.example CHANGED
@@ -16,3 +16,10 @@ ANTHROPIC_DEFAULT_SONNET_MODEL_NAME=glm-5.2
16
16
  # ANTHROPIC_TIMEOUT_MS=300000
17
17
  # ANTHROPIC_CACHE_TTL=5m
18
18
  # AGENT_SENDMAIL_PATH=/usr/sbin/sendmail
19
+
20
+ # OpenAI-compatible alternative
21
+ # APOLLO_LLM_PROTOCOL=openai
22
+ # OPENAI_API_KEY=
23
+ # OPENAI_BASE_URL=https://api.openai.com/v1
24
+ # OPENAI_MODEL=gpt-4o-mini
25
+ # OPENAI_MAX_TOKENS_PARAM=max_tokens
package/dist/brand.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  /** Product identity — single source of truth for display strings. */
2
2
  export declare const PRODUCT: {
3
3
  readonly name: "Apollo";
4
- readonly version: "0.1.11";
4
+ readonly version: "0.2.1";
5
5
  readonly tagline: "Your personal agent — answer first, act when needed.";
6
6
  readonly packageName: "@apolloyh/apollo-agent";
7
- readonly userAgent: "ApolloAgent/0.1";
7
+ readonly userAgent: "ApolloAgent/0.2";
8
8
  readonly prompt: "apollo";
9
9
  };
10
10
  /**
package/dist/brand.js CHANGED
@@ -1,10 +1,10 @@
1
1
  /** Product identity — single source of truth for display strings. */
2
2
  export const PRODUCT = {
3
3
  name: "Apollo",
4
- version: "0.1.11",
4
+ version: "0.2.1",
5
5
  tagline: "Your personal agent — answer first, act when needed.",
6
6
  packageName: "@apolloyh/apollo-agent",
7
- userAgent: "ApolloAgent/0.1",
7
+ userAgent: "ApolloAgent/0.2",
8
8
  prompt: "apollo",
9
9
  };
10
10
  /**
package/dist/config.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { AgentConfig, LlmConfig, SubagentConfig } from "./types.js";
2
2
  /** Default Apollo Task roles. */
3
3
  export declare const DEFAULT_AGENTS: SubagentConfig[];
4
- export declare const MISSING_AUTH_TOKEN_MESSAGE = "Missing ANTHROPIC_AUTH_TOKEN. Add it to ~/.apollo/.env, .apollo/.env, .env, or your shell, then restart Apollo.";
4
+ export declare const MISSING_AUTH_TOKEN_MESSAGE = "Missing model API token. Set ANTHROPIC_AUTH_TOKEN or OPENAI_API_KEY, then restart Apollo.";
5
5
  export declare function ensureUserEnvFile(): {
6
6
  path: string;
7
7
  created: boolean;
@@ -14,7 +14,9 @@ export declare function ensureUserConfigExampleFile(): {
14
14
  path: string;
15
15
  created: boolean;
16
16
  };
17
- export declare function loadAgentConfig(configPath?: string): Promise<AgentConfig>;
17
+ export declare function loadAgentConfig(configPath?: string, options?: {
18
+ isolated?: boolean;
19
+ }): Promise<AgentConfig>;
18
20
  /**
19
21
  * Load an explicit env file, or discover project env then ~/.apollo/.env.
20
22
  * By default **overrides** existing shell vars so local agent config wins.
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEzE,iCAAiC;AACjC,eAAO,MAAM,cAAc,EAAE,cAAc,EAkC1C,CAAC;AAsBF,eAAO,MAAM,0BAA0B,oHAC4E,CAAC;AAwBpH,wBAAgB,iBAAiB,IAAI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAatE;AAED,wBAAgB,oBAAoB,IAAI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAazE;AAED,wBAAgB,2BAA2B,IAAI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAchF;AAED,wBAAsB,eAAe,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAkD/E;AAiBD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAwB3F;AAYD,wBAAgB,aAAa,CAAC,OAAO,GAAE;IAAE,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,SAAS,CAkCrF"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEzE,iCAAiC;AACjC,eAAO,MAAM,cAAc,EAAE,cAAc,EAkC1C,CAAC;AAsBF,eAAO,MAAM,0BAA0B,8FACsD,CAAC;AA8B9F,wBAAgB,iBAAiB,IAAI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAatE;AAED,wBAAgB,oBAAoB,IAAI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAazE;AAED,wBAAgB,2BAA2B,IAAI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAchF;AAED,wBAAsB,eAAe,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAkDrH;AAiBD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAwB3F;AAYD,wBAAgB,aAAa,CAAC,OAAO,GAAE;IAAE,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,SAAS,CAsCrF"}
package/dist/config.js CHANGED
@@ -55,7 +55,7 @@ const defaultConfig = {
55
55
  };
56
56
  const DEFAULT_CONFIG_PATH = ".apollo/config.json";
57
57
  const LEGACY_CONFIG_PATH = "agent.config.json";
58
- export const MISSING_AUTH_TOKEN_MESSAGE = "Missing ANTHROPIC_AUTH_TOKEN. Add it to ~/.apollo/.env, .apollo/.env, .env, or your shell, then restart Apollo.";
58
+ export const MISSING_AUTH_TOKEN_MESSAGE = "Missing model API token. Set ANTHROPIC_AUTH_TOKEN or OPENAI_API_KEY, then restart Apollo.";
59
59
  const USER_ENV_TEMPLATE = `# Apollo uses Anthropic-compatible environment variable names.
60
60
  # Add your provider token below, then restart Apollo.
61
61
  ANTHROPIC_AUTH_TOKEN=
@@ -63,6 +63,12 @@ ANTHROPIC_AUTH_TOKEN=
63
63
  # Optional provider settings:
64
64
  # ANTHROPIC_BASE_URL=https://api.anthropic.com
65
65
  # ANTHROPIC_MODEL=claude-haiku-4-5
66
+
67
+ # OpenAI-compatible alternative:
68
+ # APOLLO_LLM_PROTOCOL=openai
69
+ # OPENAI_API_KEY=
70
+ # OPENAI_BASE_URL=https://api.openai.com/v1
71
+ # OPENAI_MODEL=gpt-4o-mini
66
72
  `;
67
73
  const USER_CONFIG_TEMPLATE = `${JSON.stringify({
68
74
  systemPrompt: "",
@@ -122,12 +128,12 @@ export function ensureUserConfigExampleFile() {
122
128
  throw error;
123
129
  }
124
130
  }
125
- export async function loadAgentConfig(configPath) {
131
+ export async function loadAgentConfig(configPath, options = {}) {
126
132
  const userConfigPath = path.join(os.homedir(), ".apollo", "config.json");
127
133
  const projectConfigPath = [DEFAULT_CONFIG_PATH, LEGACY_CONFIG_PATH].find(fsSync.existsSync);
128
134
  const layers = [
129
- ...(fsSync.existsSync(userConfigPath) ? [{ file: userConfigPath, projectScoped: false }] : []),
130
- ...(projectConfigPath ? [{ file: projectConfigPath, projectScoped: true }] : []),
135
+ ...(!options.isolated && fsSync.existsSync(userConfigPath) ? [{ file: userConfigPath, projectScoped: false }] : []),
136
+ ...(!options.isolated && projectConfigPath ? [{ file: projectConfigPath, projectScoped: true }] : []),
131
137
  ...(configPath ? [{ file: configPath, projectScoped: true }] : []),
132
138
  ];
133
139
  const seen = new Set();
@@ -223,13 +229,15 @@ function unwrapEnvValue(value) {
223
229
  return value;
224
230
  }
225
231
  export function loadLlmConfig(options = {}) {
226
- const authToken = process.env.ANTHROPIC_AUTH_TOKEN;
227
- const baseUrl = process.env.ANTHROPIC_BASE_URL ?? "https://api.anthropic.com";
228
- const model = process.env.ANTHROPIC_MODEL ||
229
- process.env.ANTHROPIC_DEFAULT_HAIKU_MODEL ||
230
- process.env.ANTHROPIC_DEFAULT_HAIKU_MODEL_NAME ||
231
- process.env.ANTHROPIC_DEFAULT_SONNET_MODEL_NAME ||
232
- "claude-haiku-4-5";
232
+ const requestedProtocol = process.env.APOLLO_LLM_PROTOCOL ?? (process.env.OPENAI_API_KEY && !process.env.ANTHROPIC_AUTH_TOKEN ? "openai" : "anthropic");
233
+ if (requestedProtocol !== "anthropic" && requestedProtocol !== "openai")
234
+ throw new Error("APOLLO_LLM_PROTOCOL must be anthropic or openai.");
235
+ const protocol = requestedProtocol;
236
+ const authToken = protocol === "openai" ? process.env.OPENAI_API_KEY : process.env.ANTHROPIC_AUTH_TOKEN;
237
+ const baseUrl = protocol === "openai" ? process.env.OPENAI_BASE_URL ?? "https://api.openai.com/v1" : process.env.ANTHROPIC_BASE_URL ?? "https://api.anthropic.com";
238
+ const model = protocol === "openai"
239
+ ? process.env.OPENAI_MODEL ?? "gpt-4o-mini"
240
+ : process.env.ANTHROPIC_MODEL || process.env.ANTHROPIC_DEFAULT_HAIKU_MODEL || process.env.ANTHROPIC_DEFAULT_HAIKU_MODEL_NAME || process.env.ANTHROPIC_DEFAULT_SONNET_MODEL_NAME || "claude-haiku-4-5";
233
241
  if (!authToken && !options.allowMissingAuth)
234
242
  throw new Error(MISSING_AUTH_TOKEN_MESSAGE);
235
243
  const cacheTtl = process.env.ANTHROPIC_CACHE_TTL ?? "5m";
@@ -237,25 +245,30 @@ export function loadLlmConfig(options = {}) {
237
245
  throw new Error("ANTHROPIC_CACHE_TTL must be 5m or 1h.");
238
246
  }
239
247
  const providerDefaultMaxTokens = /(?:^glm-|bigmodel\.cn)/i.test(`${model} ${baseUrl}`) ? 128 * 1024 : 4096;
240
- const maxTokens = positiveNumberEnv("ANTHROPIC_MAX_TOKENS", providerDefaultMaxTokens, true);
241
- const timeoutMs = positiveNumberEnv("ANTHROPIC_TIMEOUT_MS", 300000, true);
248
+ const maxTokens = positiveNumberEnv(protocol === "openai" ? "OPENAI_MAX_TOKENS" : "ANTHROPIC_MAX_TOKENS", providerDefaultMaxTokens, true);
249
+ const timeoutMs = positiveNumberEnv(protocol === "openai" ? "OPENAI_TIMEOUT_MS" : "ANTHROPIC_TIMEOUT_MS", 300000, true);
250
+ const openaiMaxTokensParam = process.env.OPENAI_MAX_TOKENS_PARAM ?? (/^(?:o[134]-|gpt-5)/i.test(model) ? "max_completion_tokens" : "max_tokens");
251
+ if (openaiMaxTokensParam !== "max_tokens" && openaiMaxTokensParam !== "max_completion_tokens")
252
+ throw new Error("OPENAI_MAX_TOKENS_PARAM must be max_tokens or max_completion_tokens.");
242
253
  let parsedBaseUrl;
243
254
  try {
244
255
  parsedBaseUrl = new URL(baseUrl);
245
256
  }
246
257
  catch {
247
- throw new Error("ANTHROPIC_BASE_URL must be a valid HTTP or HTTPS URL.");
258
+ throw new Error("Model base URL must be a valid HTTP or HTTPS URL.");
248
259
  }
249
260
  if (parsedBaseUrl.protocol !== "http:" && parsedBaseUrl.protocol !== "https:") {
250
- throw new Error("ANTHROPIC_BASE_URL must be a valid HTTP or HTTPS URL.");
261
+ throw new Error("Model base URL must be a valid HTTP or HTTPS URL.");
251
262
  }
252
263
  return {
264
+ protocol,
253
265
  authToken: authToken ?? "",
254
266
  baseUrl,
255
267
  model,
256
268
  maxTokens,
257
269
  timeoutMs,
258
270
  cacheTtl,
271
+ openaiMaxTokensParam,
259
272
  };
260
273
  }
261
274
  function positiveNumberEnv(name, fallback, integer) {
@@ -1 +1 @@
1
- {"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../../src/coordinator/workflow.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAEjE,MAAM,MAAM,SAAS,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;AAEtD,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,qBAAqB,EAAE,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,SAAI,GAAG,aAAa,CAY1E;AAED,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAgC3E;AAED,wBAAgB,cAAc,CAC5B,EAAE,EAAE,aAAa,EACjB,IAAI,EAAE,SAAS,EACf,MAAM,EAAE,qBAAqB,CAAC,QAAQ,CAAC,EACvC,OAAO,CAAC,EAAE,MAAM,GACf,aAAa,CAcf;AAED,wBAAgB,YAAY,CAAC,EAAE,EAAE,aAAa,GAAG,qBAAqB,GAAG,SAAS,CAEjF;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,aAAa,GAAG,MAAM,CAqB7D;AAED,+CAA+C;AAC/C,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,aAAa,CAgCnF"}
1
+ {"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../../src/coordinator/workflow.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAGjE,MAAM,MAAM,SAAS,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;AAEtD,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,qBAAqB,EAAE,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,SAAI,GAAG,aAAa,CAY1E;AAED,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAgC3E;AAED,wBAAgB,cAAc,CAC5B,EAAE,EAAE,aAAa,EACjB,IAAI,EAAE,SAAS,EACf,MAAM,EAAE,qBAAqB,CAAC,QAAQ,CAAC,EACvC,OAAO,CAAC,EAAE,MAAM,GACf,aAAa,CAcf;AAED,wBAAgB,YAAY,CAAC,EAAE,EAAE,aAAa,GAAG,qBAAqB,GAAG,SAAS,CAEjF;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,aAAa,GAAG,MAAM,CAqB7D;AAED,+CAA+C;AAC/C,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,aAAa,CAgCnF"}
@@ -1,3 +1,4 @@
1
+ import { TERMINAL_ANSI } from "../terminal-theme.js";
1
2
  export function createWorkflow(goal, maxRetries = 2) {
2
3
  return {
3
4
  goal,
@@ -12,12 +13,12 @@ export function createWorkflow(goal, maxRetries = 2) {
12
13
  };
13
14
  }
14
15
  export function workflowStatusBar(wf, color) {
15
- const dim = color ? "\x1b[90m" : "";
16
+ const dim = color ? TERMINAL_ANSI.inactive : "";
16
17
  const reset = color ? "\x1b[0m" : "";
17
- const green = color ? "\x1b[32m" : "";
18
- const red = color ? "\x1b[31m" : "";
19
- const blue = color ? "\x1b[38;2;96;165;250m" : "";
20
- const yellow = color ? "\x1b[33m" : "";
18
+ const green = color ? TERMINAL_ANSI.success : "";
19
+ const red = color ? TERMINAL_ANSI.error : "";
20
+ const blue = color ? TERMINAL_ANSI.permission : "";
21
+ const yellow = color ? TERMINAL_ANSI.warning : "";
21
22
  const parts = wf.phases.map((p) => {
22
23
  let mark = "○";
23
24
  let c = dim;
@@ -1,7 +1,3 @@
1
- /**
2
- * Goal mode — pursue a user goal until done (open-ended autonomous loop).
3
- * Differs from fixed 4-phase workflow: steps are free-form; exit via markers or /goal stop.
4
- */
5
1
  export type GoalStatus = "active" | "completed" | "failed" | "blocked" | "paused";
6
2
  export type GoalState = {
7
3
  goal: string;
@@ -1 +1 @@
1
- {"version":3,"file":"goal-mode.d.ts","sourceRoot":"","sources":["../../src/goal/goal-mode.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;AAElF,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,CAAC;IACnB,sCAAsC;IACtC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,6BAA6B;IAC7B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,SAAK,EAAE,QAAQ,GAAE,MAAM,EAAO,GAAG,SAAS,CAU/F;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAsClE;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,SAAS,GAAG,MAAM,CA2CpD;AAED,iDAAiD;AACjD,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,CAiCtE;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,SAAS,GAAG,OAAO,CAExD;AAED,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,SAAS,GAAG,MAAM,CAO3D"}
1
+ {"version":3,"file":"goal-mode.d.ts","sourceRoot":"","sources":["../../src/goal/goal-mode.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;AAElF,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,CAAC;IACnB,sCAAsC;IACtC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,6BAA6B;IAC7B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,SAAK,EAAE,QAAQ,GAAE,MAAM,EAAO,GAAG,SAAS,CAU/F;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAsClE;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,SAAS,GAAG,MAAM,CA2CpD;AAED,iDAAiD;AACjD,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,CAiCtE;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,SAAS,GAAG,OAAO,CAExD;AAED,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,SAAS,GAAG,MAAM,CAO3D"}
@@ -2,6 +2,7 @@
2
2
  * Goal mode — pursue a user goal until done (open-ended autonomous loop).
3
3
  * Differs from fixed 4-phase workflow: steps are free-form; exit via markers or /goal stop.
4
4
  */
5
+ import { TERMINAL_ANSI } from "../terminal-theme.js";
5
6
  export function createGoal(goal, maxIterations = 12, criteria = []) {
6
7
  return {
7
8
  goal: goal.trim(),
@@ -14,12 +15,12 @@ export function createGoal(goal, maxIterations = 12, criteria = []) {
14
15
  };
15
16
  }
16
17
  export function goalStatusBar(g, color) {
17
- const dim = color ? "\x1b[90m" : "";
18
+ const dim = color ? TERMINAL_ANSI.inactive : "";
18
19
  const reset = color ? "\x1b[0m" : "";
19
- const green = color ? "\x1b[32m" : "";
20
- const red = color ? "\x1b[31m" : "";
21
- const yellow = color ? "\x1b[33m" : "";
22
- const blue = color ? "\x1b[38;2;96;165;250m" : "";
20
+ const green = color ? TERMINAL_ANSI.success : "";
21
+ const red = color ? TERMINAL_ANSI.error : "";
22
+ const yellow = color ? TERMINAL_ANSI.warning : "";
23
+ const blue = color ? TERMINAL_ANSI.permission : "";
23
24
  let mark = "◉";
24
25
  let c = yellow;
25
26
  if (g.status === "completed") {
package/dist/index.js CHANGED
@@ -11,6 +11,7 @@ import { createCliApprovalProvider } from "./runtime/permissions.js";
11
11
  import { formatResumeTime, moveResumeSelection, resumeHistoryEntries } from "./session/resume-ui.js";
12
12
  import { formatOutcomeLine, formatWaitLine, STATUS_TICK_MS } from "./status-ui.js";
13
13
  import { ThoughtFoldManager } from "./thought-fold.js";
14
+ import { TERMINAL_ANSI } from "./terminal-theme.js";
14
15
  import { workflowStatusBar } from "./coordinator/workflow.js";
15
16
  import { CliTraceRenderer, stripTerminalEscapes } from "./trace.js";
16
17
  let activeCliInput;
@@ -630,7 +631,7 @@ async function pickSessionWithArrows(sessions) {
630
631
  const marker = active ? "›" : " ";
631
632
  const title = truncateDisplay(session.title || "untitled", Math.min(42, width));
632
633
  const line = `${marker} ${title} ${formatResumeTime(session.updatedAt)} ${session.id}`;
633
- lines.push(active ? `\x1b[1;38;2;96;165;250m${line}\x1b[0m` : line);
634
+ lines.push(active ? `\x1b[1m${TERMINAL_ANSI.permission}${line}\x1b[0m` : line);
634
635
  }
635
636
  lines.push("", "↑/↓ select · Enter resume · Esc cancel");
636
637
  stdout.write(`${lines.join("\n")}\n`);
@@ -671,7 +672,7 @@ function renderResumedHistory(snapshot, color) {
671
672
  if (!entries.length)
672
673
  return;
673
674
  const dim = color ? "\x1b[2m" : "";
674
- const blue = color ? "\x1b[38;2;96;165;250m" : "";
675
+ const blue = color ? TERMINAL_ANSI.permission : "";
675
676
  const reset = color ? "\x1b[0m" : "";
676
677
  stdout.write(`\n${dim}Conversation history · ${entries.length} entries${reset}\n\n`);
677
678
  const historyRenderer = new CliTraceRenderer({
@@ -994,7 +995,7 @@ function startTurnInput(runtime, color, history, pendingMessages) {
994
995
  async function readCliLine(options) {
995
996
  if (!stdin.isTTY || !stdout.isTTY) {
996
997
  const p = PRODUCT.prompt;
997
- stdout.write(options.color ? `\x1b[38;2;96;165;250m${p}>\x1b[0m ` : `${p}> `);
998
+ stdout.write(options.color ? `${TERMINAL_ANSI.brandBlue}${p}>\x1b[0m ` : `${p}> `);
998
999
  return readStdinLine();
999
1000
  }
1000
1001
  let buffer = "";
@@ -1077,7 +1078,11 @@ async function readCliLine(options) {
1077
1078
  stdout.write(lines.join("\n"));
1078
1079
  renderedLines = lines.length;
1079
1080
  const view = renderInputView(buffer, cursor, inputContentWidth(), pastedTextBlocks);
1080
- renderedCursorLine = (renderLiveStatusLine(options.color) ? 2 : 1) + view.cursorLine;
1081
+ const statusRows = renderLiveStatusLine(options.color) ? 1 : 0;
1082
+ const thinkingRows = liveStatus?.text === "Thinking" && liveThinkingPreview
1083
+ ? renderLiveThinkingLines(liveThinkingPreview, options.color).length
1084
+ : 0;
1085
+ renderedCursorLine = statusRows + thinkingRows + 1 + view.cursorLine;
1081
1086
  const rowsBelowInput = lines.length - 1 - renderedCursorLine;
1082
1087
  stdout.write(`\x1b[${rowsBelowInput}A\r\x1b[${3 + view.cursorWidth}G`);
1083
1088
  stdout.write(options.queueMode && !buffer ? "\x1b[?25l" : "\x1b[?25h");
@@ -1387,7 +1392,7 @@ async function askChoice(prompt, choices, initial, color) {
1387
1392
  let selected = Math.max(0, Math.min(initial, choices.length - 1));
1388
1393
  let renderedLines = 0;
1389
1394
  const previousRawMode = stdin.isRaw;
1390
- const blue = color ? "\x1b[1;38;2;96;165;250m" : "";
1395
+ const blue = color ? `\x1b[1m${TERMINAL_ANSI.permission}` : "";
1391
1396
  const dim = color ? "\x1b[90m" : "";
1392
1397
  const reset = color ? "\x1b[0m" : "";
1393
1398
  const clear = () => {
@@ -1479,10 +1484,10 @@ async function readStdinLine() {
1479
1484
  }
1480
1485
  function renderSlashCommandMenu(useColor) {
1481
1486
  const width = Math.max(...slashCommands.map((c) => displayLength(c.usage)));
1482
- const title = useColor ? "\x1b[38;2;96;165;250mSlash commands\x1b[0m" : "Slash commands";
1487
+ const title = useColor ? `${TERMINAL_ANSI.permission}Slash commands\x1b[0m` : "Slash commands";
1483
1488
  const rows = slashCommands
1484
1489
  .map((command) => {
1485
- const usage = useColor ? `\x1b[38;2;96;165;250m${command.usage}\x1b[0m` : command.usage;
1490
+ const usage = useColor ? `${TERMINAL_ANSI.permission}${command.usage}\x1b[0m` : command.usage;
1486
1491
  return ` ${padDisplay(command.usage, width, usage)} ${command.description}`;
1487
1492
  })
1488
1493
  .join("\n");
@@ -1491,7 +1496,7 @@ function renderSlashCommandMenu(useColor) {
1491
1496
  function renderSlashPaletteLines(selectedIndex, useColor, filtered, buffer) {
1492
1497
  const query = buffer.startsWith("/") ? buffer.slice(1) : buffer;
1493
1498
  const title = useColor
1494
- ? `\x1b[38;2;96;165;250mCommands${query ? ` · “${query}”` : ""}\x1b[0m`
1499
+ ? `${TERMINAL_ANSI.permission}Commands${query ? ` · “${query}”` : ""}\x1b[0m`
1495
1500
  : `Commands${query ? ` · “${query}”` : ""}`;
1496
1501
  if (filtered.length === 0) {
1497
1502
  const empty = useColor ? "\x1b[90m (no matching commands)\x1b[0m" : " (no matching commands)";
@@ -1562,7 +1567,7 @@ class TaskActivityLog {
1562
1567
  render(useColor) {
1563
1568
  if (this.activities.length === 0)
1564
1569
  return "\nNo Task activity yet.\n";
1565
- const title = useColor ? "\x1b[38;2;96;165;250mTasks\x1b[0m" : "Tasks";
1570
+ const title = useColor ? `${TERMINAL_ANSI.permission}Tasks\x1b[0m` : "Tasks";
1566
1571
  const rows = this.activities
1567
1572
  .slice(-12)
1568
1573
  .map((a) => this.renderActivity(a, useColor))
@@ -1590,7 +1595,7 @@ class TaskActivityLog {
1590
1595
  function paint(text, colorName, useColor) {
1591
1596
  if (!useColor)
1592
1597
  return text;
1593
- const code = colorName === "green" ? "\x1b[32m" : colorName === "blue" ? "\x1b[38;2;96;165;250m" : "\x1b[90m";
1598
+ const code = colorName === "green" ? TERMINAL_ANSI.success : colorName === "blue" ? TERMINAL_ANSI.permission : TERMINAL_ANSI.inactive;
1594
1599
  return `${code}${text}\x1b[0m`;
1595
1600
  }
1596
1601
  function compactLine(text, max) {
@@ -1600,7 +1605,7 @@ function compactLine(text, max) {
1600
1605
  return truncateDisplay(normalized, max);
1601
1606
  }
1602
1607
  function renderInputPrompt(useColor) {
1603
- return useColor ? "\x1b[38;2;96;165;250m›\x1b[0m " : "› ";
1608
+ return useColor ? `${TERMINAL_ANSI.brandBlue}›\x1b[0m ` : "› ";
1604
1609
  }
1605
1610
  function renderTurnInputHint(useColor) {
1606
1611
  const hint = "Type to queue a message · Esc to interrupt";
@@ -1654,7 +1659,7 @@ function renderInputBorder(position, useColor) {
1654
1659
  return useColor ? `\x1b[38;2;84;94;112m${line}\x1b[0m` : line;
1655
1660
  }
1656
1661
  function renderWelcomeBanner(options) {
1657
- const blue = options.color ? "\x1b[38;2;96;165;250m" : "";
1662
+ const blue = options.color ? TERMINAL_ANSI.brandBlue : "";
1658
1663
  const green = options.color ? "\x1b[32m" : "";
1659
1664
  const dim = options.color ? "\x1b[90m" : "";
1660
1665
  const reset = options.color ? "\x1b[0m" : "";
@@ -21,30 +21,37 @@ export type ToolInputDelta = {
21
21
  export type ThinkingDelta = {
22
22
  text: string;
23
23
  };
24
+ export type CreateMessageInput = {
25
+ system: string;
26
+ messages: Message[];
27
+ tools: AnthropicTool[];
28
+ stream?: boolean;
29
+ signal?: AbortSignal;
30
+ onTextDelta?: (text: string) => void;
31
+ onThinkingDelta?: (event: ThinkingDelta) => void;
32
+ onToolInputDelta?: (event: ToolInputDelta) => void;
33
+ };
34
+ export interface LlmClient {
35
+ createMessage(input: CreateMessageInput): Promise<AnthropicResponse>;
36
+ }
24
37
  export declare class MalformedStreamError extends Error {
25
38
  constructor(message: string, cause?: unknown);
26
39
  }
27
40
  export declare class MalformedToolInputError extends MalformedStreamError {
28
41
  constructor(tool: string, bytes: number, cause: unknown);
29
42
  }
30
- export declare class AnthropicApiError extends Error {
43
+ export declare class ProviderApiError extends Error {
31
44
  readonly status: number;
32
45
  readonly responseBody: string;
33
46
  readonly responseHeaders: Headers;
34
47
  constructor(status: number, responseBody: string, responseHeaders: Headers);
35
48
  }
49
+ export declare class AnthropicApiError extends ProviderApiError {
50
+ name: string;
51
+ }
36
52
  export declare class AnthropicClient {
37
53
  private readonly config;
38
54
  constructor(config: LlmConfig);
39
- createMessage(input: {
40
- system: string;
41
- messages: Message[];
42
- tools: AnthropicTool[];
43
- stream?: boolean;
44
- signal?: AbortSignal;
45
- onTextDelta?: (text: string) => void;
46
- onThinkingDelta?: (event: ThinkingDelta) => void;
47
- onToolInputDelta?: (event: ToolInputDelta) => void;
48
- }): Promise<AnthropicResponse>;
55
+ createMessage(input: CreateMessageInput): Promise<AnthropicResponse>;
49
56
  }
50
57
  //# sourceMappingURL=anthropic.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/llm/anthropic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEnF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,cAAc,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,2BAA2B,EAAE,MAAM,CAAC;IACpC,uBAAuB,EAAE,MAAM,CAAC;CACjC,CAAC;AAOF,MAAM,MAAM,cAAc,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAC/E,MAAM,MAAM,aAAa,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7C,qBAAa,oBAAqB,SAAQ,KAAK;gBACjC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAI7C;AAED,qBAAa,uBAAwB,SAAQ,oBAAoB;gBACnD,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;CAIxD;AAED,qBAAa,iBAAkB,SAAQ,KAAK;aAExB,MAAM,EAAE,MAAM;aACd,YAAY,EAAE,MAAM;aACpB,eAAe,EAAE,OAAO;gBAFxB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,OAAO;CAK3C;AAED,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,SAAS;IAExC,aAAa,CAAC,KAAK,EAAE;QACzB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,OAAO,EAAE,CAAC;QACpB,KAAK,EAAE,aAAa,EAAE,CAAC;QACvB,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,MAAM,CAAC,EAAE,WAAW,CAAC;QACrB,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;QACrC,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;QACjD,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;KACpD,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAsC/B"}
1
+ {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/llm/anthropic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEnF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,cAAc,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,2BAA2B,EAAE,MAAM,CAAC;IACpC,uBAAuB,EAAE,MAAM,CAAC;CACjC,CAAC;AAOF,MAAM,MAAM,cAAc,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAC/E,MAAM,MAAM,aAAa,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAC7C,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IACjD,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;CACpD,CAAC;AAEF,MAAM,WAAW,SAAS;IACxB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACtE;AAED,qBAAa,oBAAqB,SAAQ,KAAK;gBACjC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAI7C;AAED,qBAAa,uBAAwB,SAAQ,oBAAoB;gBACnD,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;CAIxD;AAED,qBAAa,gBAAiB,SAAQ,KAAK;aAEvB,MAAM,EAAE,MAAM;aACd,YAAY,EAAE,MAAM;aACpB,eAAe,EAAE,OAAO;gBAFxB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,OAAO;CAK3C;AAED,qBAAa,iBAAkB,SAAQ,gBAAgB;IAC5C,IAAI,SAAuB;CACrC;AAED,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,SAAS;IAExC,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAsC3E"}
@@ -10,18 +10,21 @@ export class MalformedToolInputError extends MalformedStreamError {
10
10
  this.name = "MalformedToolInputError";
11
11
  }
12
12
  }
13
- export class AnthropicApiError extends Error {
13
+ export class ProviderApiError extends Error {
14
14
  status;
15
15
  responseBody;
16
16
  responseHeaders;
17
17
  constructor(status, responseBody, responseHeaders) {
18
- super(`Anthropic API error ${status}: ${responseBody}`);
18
+ super(`Provider API error ${status}: ${responseBody}`);
19
19
  this.status = status;
20
20
  this.responseBody = responseBody;
21
21
  this.responseHeaders = responseHeaders;
22
- this.name = "AnthropicApiError";
22
+ this.name = "ProviderApiError";
23
23
  }
24
24
  }
25
+ export class AnthropicApiError extends ProviderApiError {
26
+ name = "AnthropicApiError";
27
+ }
25
28
  export class AnthropicClient {
26
29
  config;
27
30
  constructor(config) {
@@ -0,0 +1,8 @@
1
+ import type { LlmConfig } from "../types.js";
2
+ import { type AnthropicResponse, type CreateMessageInput, type LlmClient } from "./anthropic.js";
3
+ export declare class OpenAIClient implements LlmClient {
4
+ private readonly config;
5
+ constructor(config: LlmConfig);
6
+ createMessage(input: CreateMessageInput): Promise<AnthropicResponse>;
7
+ }
8
+ //# sourceMappingURL=openai.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/llm/openai.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA2C,SAAS,EAAW,MAAM,aAAa,CAAC;AAC/F,OAAO,EAIL,KAAK,iBAAiB,EAEtB,KAAK,kBAAkB,EACvB,KAAK,SAAS,EACf,MAAM,gBAAgB,CAAC;AAKxB,qBAAa,YAAa,YAAW,SAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,SAAS;IAExC,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAmB3E"}