zidane 5.13.0 → 5.13.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 (86) hide show
  1. package/README.md +11 -0
  2. package/dist/acp-CEE6C0m_.js +1313 -0
  3. package/dist/acp-CEE6C0m_.js.map +1 -0
  4. package/dist/acp-cli.d.ts +1 -0
  5. package/dist/acp-cli.js +575 -0
  6. package/dist/acp-cli.js.map +1 -0
  7. package/dist/acp.d.ts +616 -0
  8. package/dist/acp.d.ts.map +1 -0
  9. package/dist/acp.js +2 -0
  10. package/dist/{agent-Db4ojCSV.d.ts → agent-D7ZL8B2X.d.ts} +2 -2
  11. package/dist/{agent-Db4ojCSV.d.ts.map → agent-D7ZL8B2X.d.ts.map} +1 -1
  12. package/dist/chat/pure.d.ts +3 -3
  13. package/dist/chat.d.ts +6 -6
  14. package/dist/chat.js +2 -2
  15. package/dist/contexts/daytona.d.ts +3 -3
  16. package/dist/contexts/docker.d.ts +1 -1
  17. package/dist/contexts/docker.d.ts.map +1 -1
  18. package/dist/contexts/docker.js +4 -1
  19. package/dist/contexts/docker.js.map +1 -1
  20. package/dist/contexts/e2b.d.ts +2 -2
  21. package/dist/{contexts-VhV4Af8x.js → contexts-DHi8LPCp.js} +25 -9
  22. package/dist/contexts-DHi8LPCp.js.map +1 -0
  23. package/dist/contexts.d.ts +3 -3
  24. package/dist/contexts.js +1 -1
  25. package/dist/eval.d.ts +1 -1
  26. package/dist/eval.js +2 -2
  27. package/dist/glob-DCWXy_tr.js +128 -0
  28. package/dist/glob-DCWXy_tr.js.map +1 -0
  29. package/dist/{headless-tVN-g6IR.js → headless-Bz1SpTB-.js} +4 -4
  30. package/dist/{headless-tVN-g6IR.js.map → headless-Bz1SpTB-.js.map} +1 -1
  31. package/dist/headless.d.ts +1 -1
  32. package/dist/headless.js +1 -1
  33. package/dist/{index-BEblm0Hu.d.ts → index-BsyPeCSL.d.ts} +3 -3
  34. package/dist/{index-BEblm0Hu.d.ts.map → index-BsyPeCSL.d.ts.map} +1 -1
  35. package/dist/{index-CJ-2g7bY.d.ts → index-CDcQW-2S.d.ts} +3 -3
  36. package/dist/index-CDcQW-2S.d.ts.map +1 -0
  37. package/dist/{index-CrMb8jCE.d.ts → index-CF15aqlk.d.ts} +3 -3
  38. package/dist/{index-CrMb8jCE.d.ts.map → index-CF15aqlk.d.ts.map} +1 -1
  39. package/dist/index.d.ts +7 -7
  40. package/dist/index.js +5 -5
  41. package/dist/lazy-DLOurOC_.js +20 -0
  42. package/dist/lazy-DLOurOC_.js.map +1 -0
  43. package/dist/{logger-Dcrj48qY.d.ts → logger-DItaCwPw.d.ts} +2 -2
  44. package/dist/{logger-Dcrj48qY.d.ts.map → logger-DItaCwPw.d.ts.map} +1 -1
  45. package/dist/mcp.d.ts +1 -1
  46. package/dist/output/stream-json.d.ts +2 -2
  47. package/dist/output/stream-json.js +1 -1
  48. package/dist/output/terminal.d.ts +2 -2
  49. package/dist/{presets-kPEMOCmE.js → presets-5IGiSsxm.js} +2 -2
  50. package/dist/{presets-kPEMOCmE.js.map → presets-5IGiSsxm.js.map} +1 -1
  51. package/dist/presets.d.ts +2 -2
  52. package/dist/presets.js +1 -1
  53. package/dist/{providers-Bo2biCyT.js → providers-DMPAmUuY.js} +6 -12
  54. package/dist/providers-DMPAmUuY.js.map +1 -0
  55. package/dist/providers.d.ts +1 -1
  56. package/dist/providers.js +1 -1
  57. package/dist/restate.d.ts +2 -2
  58. package/dist/session/sqlite.d.ts +1 -1
  59. package/dist/session.d.ts +1 -1
  60. package/dist/skills.d.ts +2 -2
  61. package/dist/{tool-formatters-CkqBgPH4.d.ts → tool-formatters-CNSMadtp.d.ts} +2 -2
  62. package/dist/{tool-formatters-CkqBgPH4.d.ts.map → tool-formatters-CNSMadtp.d.ts.map} +1 -1
  63. package/dist/tools/fetch-url.d.ts +1 -1
  64. package/dist/tools/web-search.d.ts +1 -1
  65. package/dist/{tools-5Bnlq68O.js → tools-CfS7rjuh.js} +38 -55
  66. package/dist/tools-CfS7rjuh.js.map +1 -0
  67. package/dist/tools.d.ts +2 -2
  68. package/dist/tools.js +1 -1
  69. package/dist/{transcript-anchors-D4PwUMyO.js → transcript-anchors-B_a1edre.js} +6 -6
  70. package/dist/{transcript-anchors-D4PwUMyO.js.map → transcript-anchors-B_a1edre.js.map} +1 -1
  71. package/dist/{transcript-anchors-BnLZmASt.d.ts → transcript-anchors-EG-SmZRu.d.ts} +4 -4
  72. package/dist/{transcript-anchors-BnLZmASt.d.ts.map → transcript-anchors-EG-SmZRu.d.ts.map} +1 -1
  73. package/dist/tui.d.ts +3 -3
  74. package/dist/tui.js +4 -4
  75. package/dist/{turn-operations-B6FaQAZN.d.ts → turn-operations-DwtWRYr1.d.ts} +3 -3
  76. package/dist/{turn-operations-B6FaQAZN.d.ts.map → turn-operations-DwtWRYr1.d.ts.map} +1 -1
  77. package/dist/{types-B39tBba1.d.ts → types-Bs2oY7Ux.d.ts} +27 -4
  78. package/dist/types-Bs2oY7Ux.d.ts.map +1 -0
  79. package/dist/types.d.ts +4 -4
  80. package/docs/ACP.md +153 -0
  81. package/package.json +11 -1
  82. package/dist/contexts-VhV4Af8x.js.map +0 -1
  83. package/dist/index-CJ-2g7bY.d.ts.map +0 -1
  84. package/dist/providers-Bo2biCyT.js.map +0 -1
  85. package/dist/tools-5Bnlq68O.js.map +0 -1
  86. package/dist/types-B39tBba1.d.ts.map +0 -1
@@ -0,0 +1,575 @@
1
+ #!/usr/bin/env bun
2
+ import { b as openaiCompat } from "./messages-CGazSyTL.js";
3
+ import { n as createSandboxContext, r as createProcessContext } from "./contexts-DHi8LPCp.js";
4
+ import { i as basic_default } from "./presets-5IGiSsxm.js";
5
+ import "./session-B69BQSn1.js";
6
+ import { f as arcee, i as openai, l as cerebras, p as anthropic, r as openrouter, t as xai, u as baseten } from "./providers-DMPAmUuY.js";
7
+ import { t as runAcpStdioServer } from "./acp-CEE6C0m_.js";
8
+ import { createDaytonaProvider } from "./contexts/daytona.js";
9
+ import { createDockerContext } from "./contexts/docker.js";
10
+ import { createE2BProvider } from "./contexts/e2b.js";
11
+ import "./session/sqlite.js";
12
+ import { basename } from "node:path";
13
+ import { readFileSync } from "node:fs";
14
+ import { parseArgs } from "node:util";
15
+ //#region src/start/shared-options.ts
16
+ const validThinkingLevels = [
17
+ "off",
18
+ "minimal",
19
+ "low",
20
+ "medium",
21
+ "high",
22
+ "xhigh",
23
+ "max",
24
+ "adaptive"
25
+ ];
26
+ const startProviderNames = [
27
+ "anthropic",
28
+ "openai",
29
+ "openrouter",
30
+ "cerebras",
31
+ "xai",
32
+ "arcee",
33
+ "baseten",
34
+ "local",
35
+ "openai-compat"
36
+ ];
37
+ const startPresetNames = ["basic"];
38
+ const startFormatNames = ["zidane", "provider"];
39
+ var StartUsageError = class extends Error {
40
+ constructor(message) {
41
+ super(message);
42
+ this.name = "StartUsageError";
43
+ }
44
+ };
45
+ /**
46
+ * The shared `bun start` / `zidane run` option table. Exported so
47
+ * `parseStartArgs` (start CLI) can compose it with the Restate-only options
48
+ * and parse argv ONCE — two diverging tables would let new flags silently
49
+ * drift between the two parsers.
50
+ */
51
+ const startLocalArgOptions = {
52
+ "help": {
53
+ type: "boolean",
54
+ short: "h",
55
+ default: false
56
+ },
57
+ "prompt": {
58
+ type: "string",
59
+ short: "p"
60
+ },
61
+ "model": {
62
+ type: "string",
63
+ short: "m"
64
+ },
65
+ "preset": {
66
+ type: "string",
67
+ short: "t",
68
+ default: "basic"
69
+ },
70
+ "system": {
71
+ type: "string",
72
+ short: "s"
73
+ },
74
+ "thinking": {
75
+ type: "string",
76
+ default: "off"
77
+ },
78
+ "provider": {
79
+ type: "string",
80
+ default: "anthropic"
81
+ },
82
+ "base-url": { type: "string" },
83
+ "api-key-env": { type: "string" },
84
+ "headers-env": { type: "string" },
85
+ "header": {
86
+ type: "string",
87
+ multiple: true
88
+ },
89
+ "vision": { type: "boolean" },
90
+ "image-in-tool-result": { type: "boolean" },
91
+ "temperature": { type: "string" },
92
+ "seed": { type: "string" },
93
+ "context": {
94
+ type: "string",
95
+ short: "c",
96
+ default: "process"
97
+ },
98
+ "image": { type: "string" },
99
+ "cwd": { type: "string" },
100
+ "env": {
101
+ type: "string",
102
+ multiple: true
103
+ },
104
+ "pass-env": {
105
+ type: "string",
106
+ multiple: true
107
+ },
108
+ "pregame": { type: "string" },
109
+ "sandbox": { type: "string" },
110
+ "sandbox-on-destroy": { type: "string" },
111
+ "mcp": { type: "string" },
112
+ "session-db": { type: "string" },
113
+ "session-id": { type: "string" },
114
+ "json": {
115
+ type: "boolean",
116
+ default: false
117
+ },
118
+ "stream-json": {
119
+ type: "boolean",
120
+ default: false
121
+ },
122
+ "format": {
123
+ type: "string",
124
+ default: "zidane"
125
+ }
126
+ };
127
+ /**
128
+ * Strict argv parse shared by the start CLIs. `strict: true` rejects unknown
129
+ * flags and stray positionals loudly — without it, a typo'd flag's value
130
+ * silently leaks into the run (e.g. as a bogus prompt). Parse failures are
131
+ * rethrown as {@link StartUsageError}.
132
+ */
133
+ function parseStartArgValues(argv, options) {
134
+ try {
135
+ const { values } = parseArgs({
136
+ args: [...argv],
137
+ options,
138
+ strict: true
139
+ });
140
+ return values;
141
+ } catch (err) {
142
+ throw new StartUsageError(`${err instanceof Error ? err.message : String(err)}\n\nRun with --help for usage.`);
143
+ }
144
+ }
145
+ function parseStartLocalOptions(argv, config = {}) {
146
+ return buildStartLocalOptions(parseStartArgValues(argv, startLocalArgOptions), config);
147
+ }
148
+ /** Assemble {@link StartLocalOptions} from already-parsed argv values. */
149
+ function buildStartLocalOptions(values, config = {}) {
150
+ const { requirePrompt = true, usage = startLocalUsage } = config;
151
+ if (values.help === true) throw new StartUsageError(usage());
152
+ const prompt = values.prompt;
153
+ if (requirePrompt && (!prompt || prompt.trim() === "")) throw new StartUsageError(usage());
154
+ const thinkingRaw = values.thinking || "off";
155
+ if (!validThinkingLevels.includes(thinkingRaw)) throw new Error(`Unknown thinking level: ${thinkingRaw}. Available: ${validThinkingLevels.join(", ")}`);
156
+ const provider = values.provider || "anthropic";
157
+ if (!startProviderNames.includes(provider)) throw new Error(`Unknown provider: ${provider}. Available: ${startProviderNames.join(", ")}`);
158
+ const preset = values.preset || "basic";
159
+ if (!startPresetNames.includes(preset)) throw new Error(`Unknown preset: ${preset}. Available: ${startPresetNames.join(", ")}`);
160
+ if (values.json === true && values["stream-json"] === true) throw new StartUsageError("Use either `--json` or `--stream-json`, not both.");
161
+ const format = values.format || "zidane";
162
+ if (!startFormatNames.includes(format)) throw new Error(`Unknown format: ${format}. Available: ${startFormatNames.join(", ")}`);
163
+ const baseURL = values["base-url"];
164
+ const apiKeyEnv = values["api-key-env"];
165
+ const headersEnv = values["headers-env"];
166
+ const extraHeaders = parseHeaderArgs(values.header, "--header");
167
+ const temperature = parseOptionalNumber(values.temperature, "--temperature");
168
+ const seed = parseOptionalInteger(values.seed, "--seed");
169
+ const env = parseEnvArgs(values.env, values["pass-env"]);
170
+ const context = values.context || "process";
171
+ const pregame = loadPregame(values.pregame, context);
172
+ const sandboxId = resolveSandboxId(values.sandbox, context);
173
+ const sandboxOnDestroy = resolveSandboxOnDestroy(values["sandbox-on-destroy"], context);
174
+ return {
175
+ system: values.system,
176
+ prompt: prompt ?? "",
177
+ model: values.model,
178
+ ...baseURL !== void 0 ? { baseURL } : {},
179
+ ...apiKeyEnv !== void 0 ? { apiKeyEnv } : {},
180
+ ...headersEnv !== void 0 ? { headersEnv } : {},
181
+ ...Object.keys(extraHeaders).length > 0 ? { extraHeaders } : {},
182
+ ...values.vision === true ? { vision: true } : {},
183
+ ...values["image-in-tool-result"] === true ? { imageInToolResult: true } : {},
184
+ ...temperature !== void 0 ? { temperature } : {},
185
+ ...seed !== void 0 ? { seed } : {},
186
+ preset,
187
+ thinking: thinkingRaw,
188
+ provider,
189
+ context,
190
+ image: values.image,
191
+ cwd: values.cwd,
192
+ ...Object.keys(env).length > 0 ? { env } : {},
193
+ ...pregame ? { pregame } : {},
194
+ ...sandboxId ? { sandboxId } : {},
195
+ ...sandboxOnDestroy ? { sandboxOnDestroy } : {},
196
+ mcp: parseMcpConfig(values.mcp),
197
+ sessionDb: values["session-db"],
198
+ sessionId: values["session-id"],
199
+ json: values.json === true,
200
+ streamJson: values["stream-json"] === true,
201
+ format
202
+ };
203
+ }
204
+ function startLocalUsage() {
205
+ return [
206
+ `Usage: bun start --prompt "your message" \\`,
207
+ ` [--provider ${startProviderNames.join("|")}] [--model <id>] [--thinking ${validThinkingLevels.join("|")}]`,
208
+ ` [--base-url <url>] [--api-key-env <NAME>] [--headers-env <NAME>] [--header 'Name: value']`,
209
+ ` [--vision] [--image-in-tool-result] [--temperature <f>] [--seed <n>]`,
210
+ ` [--context process|docker|e2b|daytona] [--image node:22] [--cwd /workspace]`,
211
+ ` [--env KEY=VALUE ...] [--pass-env VARNAME ...] [--pregame setup.sh] [--sandbox <id>] [--sandbox-on-destroy kill|pause|leave]`,
212
+ ` [--mcp '[...]'] [--session-db ./sessions.db] [--session-id <id>] [--json|--stream-json] [--format zidane|provider]`,
213
+ ``,
214
+ ` --stream-json streams COMPLETE TURNS as JSONL (one line per turn), then the result.`,
215
+ ` For the full event stream (text deltas, tool calls, …) use the headless CLI's`,
216
+ ` --output-format stream-json instead.`
217
+ ].join("\n");
218
+ }
219
+ /**
220
+ * Parse the `--mcp` argument: inline JSON (object or array) or a path to a JSON
221
+ * file. Validates that each server declares the fields its transport requires.
222
+ */
223
+ function parseMcpConfig(raw) {
224
+ if (!raw) return void 0;
225
+ let text = raw.trim();
226
+ if (!text.startsWith("[") && !text.startsWith("{")) text = readFileSync(text, "utf8");
227
+ const parsed = JSON.parse(text);
228
+ const configs = Array.isArray(parsed) ? parsed : [parsed];
229
+ for (const config of configs) {
230
+ if (!config.name || !config.transport) throw new Error(`Invalid MCP config: each server needs "name" and "transport". Got: ${JSON.stringify(config)}`);
231
+ if (config.transport === "stdio" && !config.command) throw new Error(`MCP server "${config.name}": stdio transport requires "command"`);
232
+ if ((config.transport === "sse" || config.transport === "streamable-http") && !config.url) throw new Error(`MCP server "${config.name}": ${config.transport} transport requires "url"`);
233
+ }
234
+ return configs;
235
+ }
236
+ function parseOptionalNumber(raw, flag) {
237
+ if (raw === void 0) return void 0;
238
+ const value = Number(raw);
239
+ if (Number.isNaN(value)) throw new Error(`${flag} must be a number, got '${raw}'.`);
240
+ return value;
241
+ }
242
+ function parseOptionalInteger(raw, flag) {
243
+ if (raw === void 0) return void 0;
244
+ const value = Number(raw);
245
+ if (!Number.isInteger(value)) throw new Error(`${flag} must be an integer, got '${raw}'.`);
246
+ return value;
247
+ }
248
+ /**
249
+ * Build the execution-context environment from `--pass-env VARNAME` (forward
250
+ * the named variable from the current shell) and `--env KEY=VALUE` (set a
251
+ * value explicitly). `--pass-env` is applied first so an explicit `--env`
252
+ * wins when both name the same key. An unset `--pass-env` variable is a hard
253
+ * error rather than a silently-empty value.
254
+ */
255
+ function parseEnvArgs(envArgs, passEnvArgs, source = process.env) {
256
+ const env = {};
257
+ for (const name of passEnvArgs ?? []) {
258
+ const key = name.trim();
259
+ if (!key) throw new Error("--pass-env requires a variable name.");
260
+ const value = source[key];
261
+ if (value === void 0) throw new Error(`--pass-env ${key}: environment variable ${key} is not set.`);
262
+ env[key] = value;
263
+ }
264
+ for (const item of envArgs ?? []) {
265
+ const eq = item.indexOf("=");
266
+ const key = eq === -1 ? "" : item.slice(0, eq).trim();
267
+ if (!key) throw new Error(`--env must be formatted as KEY=VALUE, got '${item}'.`);
268
+ env[key] = item.slice(eq + 1);
269
+ }
270
+ return env;
271
+ }
272
+ /**
273
+ * Resolve the `--pregame <file>` setup script. Returns `undefined` when no path
274
+ * is given. The script only runs in remote sandbox contexts (it's uploaded into
275
+ * the ready sandbox before prompting); for any other context this warns and
276
+ * ignores it rather than failing. For supported contexts the file is read
277
+ * eagerly — consistent with `--prompt-file`/`--schema` — so a missing or
278
+ * unreadable file surfaces as a usage error up front rather than mid-spawn.
279
+ * The returned `name` is the basename used for the uploaded file.
280
+ */
281
+ function loadPregame(path, context) {
282
+ if (!path) return void 0;
283
+ if (!supportsRemoteSandboxFlags(context)) {
284
+ console.error(`--pregame is only supported with --context e2b or daytona; ignoring it for context '${context}'.`);
285
+ return;
286
+ }
287
+ let content;
288
+ try {
289
+ content = readFileSync(path, "utf8");
290
+ } catch (err) {
291
+ throw new Error(`--pregame: failed to read '${path}': ${err.message}`);
292
+ }
293
+ return {
294
+ name: basename(path),
295
+ content
296
+ };
297
+ }
298
+ /**
299
+ * Resolve the `--sandbox <id>` argument. Returns `undefined` when no id is
300
+ * given. Connecting to a pre-existing sandbox is supported by the remote
301
+ * sandbox providers; for any other context this warns and ignores it rather
302
+ * than failing, mirroring {@link loadPregame}. A blank value (e.g.
303
+ * `--sandbox ''`) is treated as absent.
304
+ */
305
+ function resolveSandboxId(raw, context) {
306
+ const id = raw?.trim();
307
+ if (!id) return void 0;
308
+ if (!supportsRemoteSandboxFlags(context)) {
309
+ console.error(`--sandbox is only supported with --context e2b or daytona; ignoring it for context '${context}'.`);
310
+ return;
311
+ }
312
+ return id;
313
+ }
314
+ const validSandboxOnDestroyValues = [
315
+ "kill",
316
+ "pause",
317
+ "leave"
318
+ ];
319
+ /**
320
+ * Resolve the `--sandbox-on-destroy kill|pause|leave` argument. Returns
321
+ * `undefined` when not set (the provider defaults to `'kill'` / delete).
322
+ * Applies to remote sandbox contexts; warns and ignores for any other context,
323
+ * mirroring {@link resolveSandboxId} and {@link loadPregame}.
324
+ */
325
+ function resolveSandboxOnDestroy(raw, context) {
326
+ const value = raw?.trim();
327
+ if (!value) return void 0;
328
+ if (!supportsRemoteSandboxFlags(context)) {
329
+ console.error(`--sandbox-on-destroy is only supported with --context e2b or daytona; ignoring it for context '${context}'.`);
330
+ return;
331
+ }
332
+ if (!validSandboxOnDestroyValues.includes(value)) throw new StartUsageError(`--sandbox-on-destroy must be kill|pause|leave, got '${value}'.`);
333
+ return value;
334
+ }
335
+ function supportsRemoteSandboxFlags(context) {
336
+ return context === "e2b" || context === "daytona";
337
+ }
338
+ function parseHeaderArgs(raw, flag) {
339
+ if (!raw || raw.length === 0) return {};
340
+ const headers = {};
341
+ for (const item of raw) {
342
+ const colon = item.indexOf(":");
343
+ const equals = item.indexOf("=");
344
+ const separator = colon === -1 ? equals : equals === -1 ? colon : Math.min(colon, equals);
345
+ if (separator <= 0) throw new Error(`${flag} must be formatted as "Name: value" or "Name=value".`);
346
+ const name = item.slice(0, separator).trim();
347
+ const value = item.slice(separator + 1).trim();
348
+ if (!name || !value) throw new Error(`${flag} must include both a header name and value.`);
349
+ headers[name] = value;
350
+ }
351
+ return headers;
352
+ }
353
+ //#endregion
354
+ //#region src/cli-shared.ts
355
+ /**
356
+ * Build the execution context for a CLI run: `process` (default), `docker`,
357
+ * `e2b`, or `daytona`.
358
+ *
359
+ * The `e2b` backend reads its `E2B_API_KEY` / `E2B_DOMAIN` / `E2B_TEMPLATE`
360
+ * from the environment (point `E2B_DOMAIN` at a self-hosted cluster, and set
361
+ * `E2B_TEMPLATE` to a template that exists there — the default `base` does
362
+ * not); `--cwd` becomes the sandbox working directory.
363
+ *
364
+ * The Daytona backend reads `DAYTONA_API_KEY` / `DAYTONA_API_URL` /
365
+ * `DAYTONA_TARGET` from the environment. `--cwd` becomes the sandbox working
366
+ * directory.
367
+ *
368
+ * `env` (from `--env` / `--pass-env`) is forwarded to whichever context is
369
+ * selected: baked into remote sandboxes at create time, set on the Docker
370
+ * container, or merged into the in-process command environment.
371
+ *
372
+ * `pregame` (from `--pregame`) is supported by the remote sandbox providers:
373
+ * a setup script uploaded and run in the sandbox once it's ready, before
374
+ * prompting begins.
375
+ *
376
+ * `sandboxId` (from `--sandbox`) attaches to a pre-existing remote sandbox
377
+ * instead of creating a fresh one.
378
+ */
379
+ function createCliExecution(type, opts) {
380
+ switch (type) {
381
+ case "docker": return createDockerContext({
382
+ image: opts.image,
383
+ cwd: opts.cwd,
384
+ env: opts.env
385
+ });
386
+ case "e2b": return createSandboxContext(createE2BProvider({
387
+ cwd: opts.cwd,
388
+ env: opts.env,
389
+ ...opts.pregame ? { pregame: opts.pregame } : {},
390
+ ...opts.sandboxId ? { sandboxId: opts.sandboxId } : {},
391
+ ...opts.sandboxOnDestroy ? { onDestroy: opts.sandboxOnDestroy } : {}
392
+ }));
393
+ case "daytona": return createSandboxContext(createDaytonaProvider({
394
+ cwd: opts.cwd,
395
+ env: opts.env,
396
+ ...opts.pregame ? { pregame: opts.pregame } : {},
397
+ ...opts.sandboxId ? { sandboxId: opts.sandboxId } : {},
398
+ ...opts.sandboxOnDestroy ? { onDestroy: opts.sandboxOnDestroy } : {}
399
+ }));
400
+ default: return createProcessContext({
401
+ cwd: opts.cwd,
402
+ env: opts.env
403
+ });
404
+ }
405
+ }
406
+ //#endregion
407
+ //#region src/start/options.ts
408
+ const startProviders = {
409
+ anthropic,
410
+ openai,
411
+ openrouter,
412
+ cerebras,
413
+ xai,
414
+ arcee,
415
+ baseten
416
+ };
417
+ const startPresets = { basic: basic_default };
418
+ function resolvePreset(name) {
419
+ const preset = startPresets[name];
420
+ if (!preset) throw new Error(`Unknown preset: ${name}. Available: ${Object.keys(startPresets).join(", ")}`);
421
+ return preset;
422
+ }
423
+ function createStartProvider(input) {
424
+ const options = typeof input === "string" ? { provider: input } : input;
425
+ const name = options.provider;
426
+ if (name === "local" || name === "openai-compat") return createLocalCompatProvider(options, name);
427
+ const providerFactory = startProviders[name];
428
+ if (!providerFactory) throw new Error(`Unknown provider: ${name}. Available: ${Object.keys(startProviders).join(", ")}, local, openai-compat`);
429
+ warnIgnoredLocalProviderOptions(options, name);
430
+ return providerFactory();
431
+ }
432
+ function createLocalCompatProvider(options, name) {
433
+ const baseURL = options.baseURL ?? process.env.LOCAL_LLM_BASE_URL;
434
+ if (!baseURL) throw new Error("No base URL for the local provider. Pass --base-url or set LOCAL_LLM_BASE_URL (e.g. http://localhost:11434/v1 for Ollama, http://localhost:8000/v1 for vLLM).");
435
+ const apiKey = (options.apiKeyEnv ? process.env[options.apiKeyEnv] : void 0) ?? process.env.LOCAL_LLM_API_KEY ?? "no-key";
436
+ const capabilities = {
437
+ vision: options.vision ?? false,
438
+ imageInToolResult: options.imageInToolResult ?? false
439
+ };
440
+ if (capabilities.imageInToolResult) capabilities.vision = true;
441
+ const extraBodyParams = { stream_options: { include_usage: true } };
442
+ if (options.temperature !== void 0) extraBodyParams.temperature = options.temperature;
443
+ if (options.seed !== void 0) extraBodyParams.seed = options.seed;
444
+ return openaiCompat({
445
+ name,
446
+ baseURL,
447
+ apiKey,
448
+ extraHeaders: resolveLocalExtraHeaders(options),
449
+ capabilities,
450
+ ...options.model ? { defaultModel: options.model } : process.env.LOCAL_LLM_DEFAULT_MODEL ? { defaultModel: process.env.LOCAL_LLM_DEFAULT_MODEL } : {},
451
+ extraBodyParams
452
+ });
453
+ }
454
+ function warnIgnoredLocalProviderOptions(options, provider) {
455
+ const ignored = [
456
+ options.baseURL !== void 0 ? "--base-url" : null,
457
+ options.apiKeyEnv !== void 0 ? "--api-key-env" : null,
458
+ options.headersEnv !== void 0 ? "--headers-env" : null,
459
+ options.extraHeaders !== void 0 ? "--header" : null,
460
+ options.vision !== void 0 ? "--vision" : null,
461
+ options.imageInToolResult !== void 0 ? "--image-in-tool-result" : null,
462
+ options.temperature !== void 0 ? "--temperature" : null,
463
+ options.seed !== void 0 ? "--seed" : null
464
+ ].filter((flag) => flag !== null);
465
+ if (ignored.length > 0) console.error(`[start] ${ignored.join(", ")} only apply to --provider local|openai-compat; ignored for '${provider}'.`);
466
+ }
467
+ function resolveLocalExtraHeaders(options) {
468
+ return {
469
+ ...process.env.LOCAL_LLM_AUTHORIZATION ? { Authorization: process.env.LOCAL_LLM_AUTHORIZATION } : {},
470
+ ...readHeadersEnv(options.headersEnv ?? "LOCAL_LLM_HEADERS"),
471
+ ...options.extraHeaders ?? {}
472
+ };
473
+ }
474
+ function readHeadersEnv(envName) {
475
+ const raw = process.env[envName];
476
+ if (!raw) return {};
477
+ let parsed;
478
+ try {
479
+ parsed = JSON.parse(raw);
480
+ } catch {
481
+ throw new Error(`${envName} must contain a JSON object of string headers.`);
482
+ }
483
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error(`${envName} must contain a JSON object of string headers.`);
484
+ const headers = {};
485
+ for (const [name, value] of Object.entries(parsed)) {
486
+ if (typeof value !== "string") throw new Error(`${envName} header "${name}" must be a string.`);
487
+ headers[name] = value;
488
+ }
489
+ return headers;
490
+ }
491
+ //#endregion
492
+ //#region src/acp-cli.ts
493
+ async function main() {
494
+ if (isHelp(Bun.argv.slice(2))) {
495
+ process.stdout.write(`${usage()}\n`);
496
+ return;
497
+ }
498
+ const options = parseStartLocalOptions(Bun.argv.slice(2), {
499
+ requirePrompt: false,
500
+ usage
501
+ });
502
+ const provider = createStartProvider({
503
+ provider: options.provider,
504
+ model: options.model,
505
+ baseURL: options.baseURL,
506
+ apiKeyEnv: options.apiKeyEnv,
507
+ headersEnv: options.headersEnv,
508
+ extraHeaders: options.extraHeaders,
509
+ vision: options.vision,
510
+ imageInToolResult: options.imageInToolResult,
511
+ temperature: options.temperature,
512
+ seed: options.seed
513
+ });
514
+ const store = options.sessionDb ? (await import("./session/sqlite.js")).createSqliteStore({ path: options.sessionDb }) : void 0;
515
+ const handle = runAcpStdioServer({
516
+ provider,
517
+ model: options.model,
518
+ preset: resolvePreset(options.preset),
519
+ system: options.system,
520
+ store,
521
+ framing: "newline",
522
+ agentOptions: { ...options.mcp ? { mcpServers: options.mcp } : {} },
523
+ execution: (request) => createCliExecution(options.context, {
524
+ image: options.image,
525
+ cwd: request.cwd || options.cwd,
526
+ env: options.env,
527
+ pregame: options.pregame,
528
+ sandboxId: options.sandboxId,
529
+ sandboxOnDestroy: options.sandboxOnDestroy
530
+ }),
531
+ agentInfo: {
532
+ name: "zidane",
533
+ title: "Zidane",
534
+ version: process.env.npm_package_version ?? "1"
535
+ },
536
+ permission: { enabled: true }
537
+ });
538
+ const shutdown = async () => {
539
+ await handle.close();
540
+ store?.close?.();
541
+ };
542
+ process.once("SIGINT", () => {
543
+ shutdown().finally(() => process.exit(130));
544
+ });
545
+ process.once("SIGTERM", () => {
546
+ shutdown().finally(() => process.exit(143));
547
+ });
548
+ }
549
+ function usage() {
550
+ return [
551
+ "Usage: zidane-acp [provider/context options]",
552
+ "",
553
+ "Runs Zidane as an ACP v1 agent over stdio. Prompts are received through ACP session/prompt.",
554
+ "",
555
+ "Common options:",
556
+ " --provider anthropic|openai|openrouter|cerebras|xai|arcee|baseten|local|openai-compat",
557
+ " --model <id>",
558
+ " --context process|docker|e2b|daytona",
559
+ " --cwd <path>",
560
+ " --session-db <path>",
561
+ " --mcp <json>"
562
+ ].join("\n");
563
+ }
564
+ function isHelp(argv) {
565
+ return argv.includes("--help") || argv.includes("-h");
566
+ }
567
+ main().catch((err) => {
568
+ if (err instanceof StartUsageError) process.stderr.write(`${err.message}\n`);
569
+ else process.stderr.write(`ACP server error: ${err instanceof Error ? err.message : String(err)}\n`);
570
+ process.exit(1);
571
+ });
572
+ //#endregion
573
+ export {};
574
+
575
+ //# sourceMappingURL=acp-cli.js.map