@warlock.js/ai-cli 0.0.0-stage → 5.31.0

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 (139) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/LICENSE +21 -0
  3. package/README.md +69 -2
  4. package/cjs/index.cjs +4576 -0
  5. package/cjs/index.cjs.map +1 -0
  6. package/esm/adapters/aider.d.mts +41 -0
  7. package/esm/adapters/aider.d.mts.map +1 -0
  8. package/esm/adapters/aider.mjs +294 -0
  9. package/esm/adapters/aider.mjs.map +1 -0
  10. package/esm/adapters/amp.d.mts +33 -0
  11. package/esm/adapters/amp.d.mts.map +1 -0
  12. package/esm/adapters/amp.mjs +119 -0
  13. package/esm/adapters/amp.mjs.map +1 -0
  14. package/esm/adapters/antigravity.d.mts +37 -0
  15. package/esm/adapters/antigravity.d.mts.map +1 -0
  16. package/esm/adapters/antigravity.mjs +235 -0
  17. package/esm/adapters/antigravity.mjs.map +1 -0
  18. package/esm/adapters/claude-code.d.mts +30 -0
  19. package/esm/adapters/claude-code.d.mts.map +1 -0
  20. package/esm/adapters/claude-code.mjs +121 -0
  21. package/esm/adapters/claude-code.mjs.map +1 -0
  22. package/esm/adapters/claude-stream.d.mts +32 -0
  23. package/esm/adapters/claude-stream.d.mts.map +1 -0
  24. package/esm/adapters/claude-stream.mjs +140 -0
  25. package/esm/adapters/claude-stream.mjs.map +1 -0
  26. package/esm/adapters/codex.d.mts +37 -0
  27. package/esm/adapters/codex.d.mts.map +1 -0
  28. package/esm/adapters/codex.mjs +320 -0
  29. package/esm/adapters/codex.mjs.map +1 -0
  30. package/esm/adapters/copilot.d.mts +35 -0
  31. package/esm/adapters/copilot.d.mts.map +1 -0
  32. package/esm/adapters/copilot.mjs +244 -0
  33. package/esm/adapters/copilot.mjs.map +1 -0
  34. package/esm/adapters/cursor.d.mts +35 -0
  35. package/esm/adapters/cursor.d.mts.map +1 -0
  36. package/esm/adapters/cursor.mjs +203 -0
  37. package/esm/adapters/cursor.mjs.map +1 -0
  38. package/esm/adapters/droid.d.mts +32 -0
  39. package/esm/adapters/droid.d.mts.map +1 -0
  40. package/esm/adapters/droid.mjs +183 -0
  41. package/esm/adapters/droid.mjs.map +1 -0
  42. package/esm/adapters/grok.d.mts +32 -0
  43. package/esm/adapters/grok.d.mts.map +1 -0
  44. package/esm/adapters/grok.mjs +199 -0
  45. package/esm/adapters/grok.mjs.map +1 -0
  46. package/esm/adapters/index.d.mts +16 -0
  47. package/esm/adapters/index.mjs +18 -0
  48. package/esm/adapters/kimi.d.mts +34 -0
  49. package/esm/adapters/kimi.d.mts.map +1 -0
  50. package/esm/adapters/kimi.mjs +162 -0
  51. package/esm/adapters/kimi.mjs.map +1 -0
  52. package/esm/adapters/mistral-vibe.d.mts +32 -0
  53. package/esm/adapters/mistral-vibe.d.mts.map +1 -0
  54. package/esm/adapters/mistral-vibe.mjs +252 -0
  55. package/esm/adapters/mistral-vibe.mjs.map +1 -0
  56. package/esm/adapters/opencode.d.mts +36 -0
  57. package/esm/adapters/opencode.d.mts.map +1 -0
  58. package/esm/adapters/opencode.mjs +219 -0
  59. package/esm/adapters/opencode.mjs.map +1 -0
  60. package/esm/adapters/qwen-code.d.mts +30 -0
  61. package/esm/adapters/qwen-code.d.mts.map +1 -0
  62. package/esm/adapters/qwen-code.mjs +94 -0
  63. package/esm/adapters/qwen-code.mjs.map +1 -0
  64. package/esm/adapters/reasonix.d.mts +31 -0
  65. package/esm/adapters/reasonix.d.mts.map +1 -0
  66. package/esm/adapters/reasonix.mjs +250 -0
  67. package/esm/adapters/reasonix.mjs.map +1 -0
  68. package/esm/adapters/shared.d.mts +78 -0
  69. package/esm/adapters/shared.d.mts.map +1 -0
  70. package/esm/adapters/shared.mjs +161 -0
  71. package/esm/adapters/shared.mjs.map +1 -0
  72. package/esm/cli-agent.d.mts +40 -0
  73. package/esm/cli-agent.d.mts.map +1 -0
  74. package/esm/cli-agent.mjs +207 -0
  75. package/esm/cli-agent.mjs.map +1 -0
  76. package/esm/cli.d.mts +53 -0
  77. package/esm/cli.d.mts.map +1 -0
  78. package/esm/cli.mjs +61 -0
  79. package/esm/cli.mjs.map +1 -0
  80. package/esm/contracts/adapter.contract.d.mts +154 -0
  81. package/esm/contracts/adapter.contract.d.mts.map +1 -0
  82. package/esm/contracts/events.type.d.mts +111 -0
  83. package/esm/contracts/events.type.d.mts.map +1 -0
  84. package/esm/contracts/index.d.mts +4 -0
  85. package/esm/contracts/mcp.type.d.mts +29 -0
  86. package/esm/contracts/mcp.type.d.mts.map +1 -0
  87. package/esm/contracts/options.type.d.mts +87 -0
  88. package/esm/contracts/options.type.d.mts.map +1 -0
  89. package/esm/errors.d.mts +46 -0
  90. package/esm/errors.d.mts.map +1 -0
  91. package/esm/errors.mjs +32 -0
  92. package/esm/errors.mjs.map +1 -0
  93. package/esm/index.d.mts +31 -0
  94. package/esm/index.mjs +28 -0
  95. package/esm/model/cli-model.d.mts +48 -0
  96. package/esm/model/cli-model.d.mts.map +1 -0
  97. package/esm/model/cli-model.mjs +133 -0
  98. package/esm/model/cli-model.mjs.map +1 -0
  99. package/esm/probe/probe.d.mts +18 -0
  100. package/esm/probe/probe.d.mts.map +1 -0
  101. package/esm/probe/probe.mjs +148 -0
  102. package/esm/probe/probe.mjs.map +1 -0
  103. package/esm/session/aggregate.mjs +86 -0
  104. package/esm/session/aggregate.mjs.map +1 -0
  105. package/esm/session/environment.mjs +71 -0
  106. package/esm/session/environment.mjs.map +1 -0
  107. package/esm/session/run-directory.mjs +74 -0
  108. package/esm/session/run-directory.mjs.map +1 -0
  109. package/esm/session/session.mjs +188 -0
  110. package/esm/session/session.mjs.map +1 -0
  111. package/esm/spawn/invocation.d.mts +35 -0
  112. package/esm/spawn/invocation.d.mts.map +1 -0
  113. package/esm/spawn/invocation.mjs +76 -0
  114. package/esm/spawn/invocation.mjs.map +1 -0
  115. package/esm/spawn/process-tree.mjs +57 -0
  116. package/esm/spawn/process-tree.mjs.map +1 -0
  117. package/esm/spawn/resolve-command.d.mts +73 -0
  118. package/esm/spawn/resolve-command.d.mts.map +1 -0
  119. package/esm/spawn/resolve-command.mjs +109 -0
  120. package/esm/spawn/resolve-command.mjs.map +1 -0
  121. package/esm/stream/event-log.mjs +52 -0
  122. package/esm/stream/event-log.mjs.map +1 -0
  123. package/esm/stream/json-lines.d.mts +33 -0
  124. package/esm/stream/json-lines.d.mts.map +1 -0
  125. package/esm/stream/json-lines.mjs +65 -0
  126. package/esm/stream/json-lines.mjs.map +1 -0
  127. package/esm/stream/line-splitter.mjs +53 -0
  128. package/esm/stream/line-splitter.mjs.map +1 -0
  129. package/esm/utils/toml.d.mts +22 -0
  130. package/esm/utils/toml.d.mts.map +1 -0
  131. package/esm/utils/toml.mjs +53 -0
  132. package/esm/utils/toml.mjs.map +1 -0
  133. package/llms-full.txt +373 -0
  134. package/llms.txt +10 -0
  135. package/package.json +39 -4
  136. package/skills/README.md +13 -0
  137. package/skills/index.md +22 -0
  138. package/skills/run-cli-agents/SKILL.md +186 -0
  139. package/skills/write-a-cli-adapter/SKILL.md +173 -0
@@ -0,0 +1,162 @@
1
+ import { asArray, asRecord, jsonLinesParser, outputText, stringField } from "../stream/json-lines.mjs";
2
+ import { argvPrompt, jsonFile, mcpServersJson, parseArguments, requirePrivateHome, unsupportedOption } from "./shared.mjs";
3
+ import path from "node:path";
4
+
5
+ //#region ../../packages/ai-cli/src/adapters/kimi.ts
6
+ /**
7
+ * Kimi Code CLI (`kimi`, npm `@moonshot-ai/kimi-code`) — Moonshot AI's
8
+ * coding agent, the successor of the archived Python `kimi-cli`.
9
+ *
10
+ * Verified against the real `kimi --help` of 2.2.0 and the docs/source at
11
+ * that tag (`docs/en/reference/kimi-command.md`, `apps/kimi-code/src/cli/
12
+ * {options.ts,prompt-render.ts,v2/run-v2-print.ts}`), 2026-10-17.
13
+ *
14
+ * - Headless: `kimi -p <prompt> --output-format stream-json`; the prompt is
15
+ * an argv value only (print mode never reads stdin).
16
+ * - Stream: OpenAI-chat-shaped messages, one per line, never deltas:
17
+ * `{"role":"assistant","content","tool_calls"}`, `{"role":"tool",
18
+ * "tool_call_id","content"}`, and `{"role":"meta","type":…}` records. The
19
+ * session id appears only in the final `session.resume_hint` record.
20
+ * No token usage is printed.
21
+ * - Permissions: print mode always runs in "Never Ask" mode (every tool call
22
+ * runs; only static deny rules apply) and rejects `--yolo`/`--plan`, so
23
+ * there is no standard mode to choose. The adapter refuses
24
+ * `permission: "standard"` instead of pretending to enforce it; pass
25
+ * `"bypass"` to accept the CLI's behaviour.
26
+ * - MCP: no flag; `$KIMI_CODE_HOME/mcp.json` (`mcpServers`), so per-run MCP
27
+ * needs a private home.
28
+ * - Auth: shell `KIMI_API_KEY`/`MOONSHOT_API_KEY` are not read. For an API
29
+ * key set `KIMI_MODEL_NAME` (and optionally `KIMI_MODEL_PROVIDER_TYPE`,
30
+ * `KIMI_MODEL_BASE_URL`) in `env`; `apiKey` becomes `KIMI_MODEL_API_KEY`.
31
+ */
32
+ const kimiAdapter = {
33
+ name: "kimi",
34
+ title: "Kimi Code",
35
+ command: "kimi",
36
+ apiKeyEnv: ["KIMI_MODEL_API_KEY"],
37
+ homeEnv: ["KIMI_CODE_HOME"],
38
+ transports: ["argv"],
39
+ effort: false,
40
+ mcp: true,
41
+ probe: {
42
+ help: [["--help"]],
43
+ version: ["--version"]
44
+ },
45
+ verification: {
46
+ version: "2.2.0",
47
+ verifiedBy: "help",
48
+ sources: [
49
+ "https://moonshotai.github.io/kimi-code/",
50
+ "https://github.com/MoonshotAI/kimi-code/blob/%40moonshot-ai/kimi-code%402.2.0/docs/en/reference/kimi-command.md",
51
+ "https://github.com/MoonshotAI/kimi-code/blob/%40moonshot-ai/kimi-code%402.2.0/docs/en/customization/mcp.md"
52
+ ],
53
+ checkedAt: "2026-10-17"
54
+ },
55
+ plan(context) {
56
+ if (context.permission !== "bypass") throw unsupportedOption(kimiAdapter, "print mode runs every tool call without asking and has no standard approval mode; pass `permission: \"bypass\"` to run it.");
57
+ const args = ["--output-format", "stream-json"];
58
+ const requires = [
59
+ "-p",
60
+ "--output-format",
61
+ "stream-json"
62
+ ];
63
+ const files = [];
64
+ if (context.model !== void 0) {
65
+ args.push("--model", context.model);
66
+ requires.push("--model");
67
+ }
68
+ if (context.resume !== void 0) {
69
+ args.push("--session", context.resume);
70
+ requires.push("--session");
71
+ }
72
+ if (context.mcp !== void 0) {
73
+ const home = requirePrivateHome(context, kimiAdapter, "MCP servers");
74
+ files.push({
75
+ path: path.join(home, "mcp.json"),
76
+ content: jsonFile({ mcpServers: kimiMcp(context.mcp) })
77
+ });
78
+ }
79
+ return {
80
+ args,
81
+ tail: ["-p", argvPrompt(context.prompt)],
82
+ env: {
83
+ ...context.home !== void 0 ? { KIMI_CODE_HOME: context.home } : {},
84
+ KIMI_CODE_NO_AUTO_UPDATE: "1",
85
+ KIMI_DISABLE_TELEMETRY: "1"
86
+ },
87
+ files,
88
+ requires
89
+ };
90
+ },
91
+ parser: createKimiParser
92
+ };
93
+ /** Kimi's `mcpServers`: SSE servers are marked with `transport: "sse"`. */
94
+ function kimiMcp(servers) {
95
+ const rendered = mcpServersJson(servers);
96
+ for (const [name, server] of Object.entries(servers)) {
97
+ const entry = rendered[name];
98
+ if (server.type === "sse" && entry !== void 0) entry.transport = "sse";
99
+ }
100
+ return rendered;
101
+ }
102
+ /** Parser for `kimi -p … --output-format stream-json`. */
103
+ function createKimiParser() {
104
+ let sessionRef;
105
+ return {
106
+ ...jsonLinesParser((record) => {
107
+ const role = stringField(record, "role");
108
+ if (role === "meta") {
109
+ const type = stringField(record, "type");
110
+ if (type === "system.version") return [{
111
+ type: "session.started",
112
+ raw: record
113
+ }];
114
+ if (type === "session.resume_hint") {
115
+ sessionRef = stringField(record, "session_id");
116
+ return [];
117
+ }
118
+ if (type === "turn.step.retrying") return [{
119
+ type: "error",
120
+ message: `retrying after ${stringField(record, "error_name") ?? "error"}: ${stringField(record, "error_message") ?? ""}`,
121
+ raw: record
122
+ }];
123
+ return [];
124
+ }
125
+ if (role === "assistant") {
126
+ const events = [];
127
+ const content = stringField(record, "content");
128
+ if (content !== void 0 && content.length > 0) events.push({
129
+ type: "message",
130
+ text: content,
131
+ delta: false,
132
+ raw: record
133
+ });
134
+ for (const item of asArray(record.tool_calls)) {
135
+ const call = asRecord(item);
136
+ const fn = asRecord(call?.function);
137
+ events.push({
138
+ type: "tool.call",
139
+ id: stringField(call, "id") ?? "",
140
+ name: stringField(fn, "name") ?? "",
141
+ input: parseArguments(fn?.arguments),
142
+ raw: item
143
+ });
144
+ }
145
+ return events;
146
+ }
147
+ if (role === "tool") return [{
148
+ type: "tool.result",
149
+ id: stringField(record, "tool_call_id") ?? "",
150
+ output: outputText(record.content),
151
+ isError: false,
152
+ raw: record
153
+ }];
154
+ return [];
155
+ }),
156
+ sessionRef: () => sessionRef
157
+ };
158
+ }
159
+
160
+ //#endregion
161
+ export { createKimiParser, kimiAdapter };
162
+ //# sourceMappingURL=kimi.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kimi.mjs","names":[],"sources":["../../../../../../../../packages/ai-cli/src/adapters/kimi.ts"],"sourcesContent":["import path from \"node:path\";\nimport type {\n CliAdapter,\n CliLaunchFile,\n CliMcpServers,\n CliParsedEvent,\n CliStreamParser,\n} from \"../contracts\";\nimport { asArray, asRecord, jsonLinesParser, outputText, stringField } from \"../stream/json-lines\";\nimport {\n argvPrompt,\n jsonFile,\n mcpServersJson,\n parseArguments,\n requirePrivateHome,\n unsupportedOption,\n} from \"./shared\";\n\n/**\n * Kimi Code CLI (`kimi`, npm `@moonshot-ai/kimi-code`) — Moonshot AI's\n * coding agent, the successor of the archived Python `kimi-cli`.\n *\n * Verified against the real `kimi --help` of 2.2.0 and the docs/source at\n * that tag (`docs/en/reference/kimi-command.md`, `apps/kimi-code/src/cli/\n * {options.ts,prompt-render.ts,v2/run-v2-print.ts}`), 2026-10-17.\n *\n * - Headless: `kimi -p <prompt> --output-format stream-json`; the prompt is\n * an argv value only (print mode never reads stdin).\n * - Stream: OpenAI-chat-shaped messages, one per line, never deltas:\n * `{\"role\":\"assistant\",\"content\",\"tool_calls\"}`, `{\"role\":\"tool\",\n * \"tool_call_id\",\"content\"}`, and `{\"role\":\"meta\",\"type\":…}` records. The\n * session id appears only in the final `session.resume_hint` record.\n * No token usage is printed.\n * - Permissions: print mode always runs in \"Never Ask\" mode (every tool call\n * runs; only static deny rules apply) and rejects `--yolo`/`--plan`, so\n * there is no standard mode to choose. The adapter refuses\n * `permission: \"standard\"` instead of pretending to enforce it; pass\n * `\"bypass\"` to accept the CLI's behaviour.\n * - MCP: no flag; `$KIMI_CODE_HOME/mcp.json` (`mcpServers`), so per-run MCP\n * needs a private home.\n * - Auth: shell `KIMI_API_KEY`/`MOONSHOT_API_KEY` are not read. For an API\n * key set `KIMI_MODEL_NAME` (and optionally `KIMI_MODEL_PROVIDER_TYPE`,\n * `KIMI_MODEL_BASE_URL`) in `env`; `apiKey` becomes `KIMI_MODEL_API_KEY`.\n */\nexport const kimiAdapter: CliAdapter = {\n name: \"kimi\",\n title: \"Kimi Code\",\n command: \"kimi\",\n apiKeyEnv: [\"KIMI_MODEL_API_KEY\"],\n homeEnv: [\"KIMI_CODE_HOME\"],\n transports: [\"argv\"],\n effort: false,\n mcp: true,\n probe: { help: [[\"--help\"]], version: [\"--version\"] },\n verification: {\n version: \"2.2.0\",\n verifiedBy: \"help\",\n sources: [\n \"https://moonshotai.github.io/kimi-code/\",\n \"https://github.com/MoonshotAI/kimi-code/blob/%40moonshot-ai/kimi-code%402.2.0/docs/en/reference/kimi-command.md\",\n \"https://github.com/MoonshotAI/kimi-code/blob/%40moonshot-ai/kimi-code%402.2.0/docs/en/customization/mcp.md\",\n ],\n checkedAt: \"2026-10-17\",\n },\n plan(context) {\n if (context.permission !== \"bypass\") {\n throw unsupportedOption(\n kimiAdapter,\n 'print mode runs every tool call without asking and has no standard approval mode; pass `permission: \"bypass\"` to run it.',\n );\n }\n\n const args = [\"--output-format\", \"stream-json\"];\n const requires = [\"-p\", \"--output-format\", \"stream-json\"];\n const files: CliLaunchFile[] = [];\n\n if (context.model !== undefined) {\n args.push(\"--model\", context.model);\n requires.push(\"--model\");\n }\n\n if (context.resume !== undefined) {\n args.push(\"--session\", context.resume);\n requires.push(\"--session\");\n }\n\n if (context.mcp !== undefined) {\n const home = requirePrivateHome(context, kimiAdapter, \"MCP servers\");\n\n files.push({\n path: path.join(home, \"mcp.json\"),\n content: jsonFile({ mcpServers: kimiMcp(context.mcp) }),\n });\n }\n\n return {\n args,\n tail: [\"-p\", argvPrompt(context.prompt)],\n env: {\n ...(context.home !== undefined ? { KIMI_CODE_HOME: context.home } : {}),\n KIMI_CODE_NO_AUTO_UPDATE: \"1\",\n KIMI_DISABLE_TELEMETRY: \"1\",\n },\n files,\n requires,\n };\n },\n parser: createKimiParser,\n};\n\n/** Kimi's `mcpServers`: SSE servers are marked with `transport: \"sse\"`. */\nfunction kimiMcp(servers: CliMcpServers): Record<string, unknown> {\n const rendered = mcpServersJson(servers);\n\n for (const [name, server] of Object.entries(servers)) {\n const entry = rendered[name];\n\n if (server.type === \"sse\" && entry !== undefined) {\n entry.transport = \"sse\";\n }\n }\n\n return rendered;\n}\n\n/** Parser for `kimi -p … --output-format stream-json`. */\nexport function createKimiParser(): CliStreamParser {\n let sessionRef: string | undefined;\n\n const parser = jsonLinesParser((record): CliParsedEvent[] => {\n const role = stringField(record, \"role\");\n\n if (role === \"meta\") {\n const type = stringField(record, \"type\");\n\n if (type === \"system.version\") {\n return [{ type: \"session.started\", raw: record }];\n }\n\n if (type === \"session.resume_hint\") {\n sessionRef = stringField(record, \"session_id\");\n\n return [];\n }\n\n if (type === \"turn.step.retrying\") {\n return [\n {\n type: \"error\",\n message: `retrying after ${stringField(record, \"error_name\") ?? \"error\"}: ${stringField(record, \"error_message\") ?? \"\"}`,\n raw: record,\n },\n ];\n }\n\n return [];\n }\n\n if (role === \"assistant\") {\n const events: CliParsedEvent[] = [];\n const content = stringField(record, \"content\");\n\n if (content !== undefined && content.length > 0) {\n events.push({ type: \"message\", text: content, delta: false, raw: record });\n }\n\n for (const item of asArray(record.tool_calls)) {\n const call = asRecord(item);\n const fn = asRecord(call?.function);\n\n events.push({\n type: \"tool.call\",\n id: stringField(call, \"id\") ?? \"\",\n name: stringField(fn, \"name\") ?? \"\",\n input: parseArguments(fn?.arguments),\n raw: item,\n });\n }\n\n return events;\n }\n\n if (role === \"tool\") {\n return [\n {\n type: \"tool.result\",\n id: stringField(record, \"tool_call_id\") ?? \"\",\n output: outputText(record.content),\n isError: false,\n raw: record,\n },\n ];\n }\n\n return [];\n });\n\n return { ...parser, sessionRef: () => sessionRef };\n}\n"],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import { CliAdapter, CliLaunchContext, CliStreamParser } from "../contracts/adapter.contract.mjs";
2
+ //#region ../../packages/ai-cli/src/adapters/mistral-vibe.d.ts
3
+ /**
4
+ * Mistral Vibe (`vibe`, PyPI `mistral-vibe`).
5
+ *
6
+ * Verified against the official repo at tag v2.26.1 only (README,
7
+ * `vibe/cli/entrypoint.py`, `vibe/cli/programmatic.py`,
8
+ * `vibe/app_server/run_export.py`, `vibe/core/config/*`); Vibe needs Python
9
+ * 3.12, so no real `--help` was run, 2026-10-17. The capability probe checks
10
+ * every flag against the installed `--help`.
11
+ *
12
+ * - Headless: `vibe -p <prompt> --output streaming` (or `--prompt-file`;
13
+ * `-p` with no value reads stdin). The stream is NDJSON of completed
14
+ * history entries (camelCase): `message` (`role`, `content[].text`), and
15
+ * `effect` — a tool call and its result in one line (`detail.toolName`,
16
+ * `detail.input`, `state.status`, `state.outputText`/`state.error`).
17
+ * There is no usage, cost or final record in the stream, so the adapter
18
+ * adds `--output-dir` and reads usage, cost, session id and outcome from
19
+ * `export.json` when the stream ends.
20
+ * - Model: no flag; `VIBE_ACTIVE_MODEL=<alias>` (set from `model`). Effort
21
+ * is a per-model config field, so `effort` is refused.
22
+ * - Permissions: headless auto-denies every approval (the default agent
23
+ * only auto-approves file edits); bypass is `--auto-approve`.
24
+ * - MCP: `[[mcp_servers]]` in `$VIBE_HOME/config.toml` (private home).
25
+ * - Auth: `MISTRAL_API_KEY`; home `VIBE_HOME`.
26
+ */
27
+ declare const mistralVibeAdapter: CliAdapter;
28
+ /** Parser for `vibe -p … --output streaming` (plus the run's `export.json`). */
29
+ declare function createVibeParser(context?: CliLaunchContext): CliStreamParser;
30
+ //#endregion
31
+ export { createVibeParser, mistralVibeAdapter };
32
+ //# sourceMappingURL=mistral-vibe.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mistral-vibe.d.mts","names":[],"sources":["../../../../../../../../packages/ai-cli/src/adapters/mistral-vibe.ts"],"mappings":";;;;;AAkDA;;;;AAuEC;AAiFD;;;;;;;;AAA6E;;;;;;;;cAxJhE,kBAAA,EAAoB,UAuEhC;;iBAiFe,gBAAA,CAAiB,OAAA,GAAU,gBAAA,GAAmB,eAAe"}
@@ -0,0 +1,252 @@
1
+ import { asArray, asRecord, jsonLinesParser, numberField, outputText, parseJsonLine, recordField, stringField } from "../stream/json-lines.mjs";
2
+ import { toToml } from "../utils/toml.mjs";
3
+ import { argvPrompt, promptFile, requirePrivateHome, usageOf } from "./shared.mjs";
4
+ import { readFileSync } from "node:fs";
5
+ import path from "node:path";
6
+
7
+ //#region ../../packages/ai-cli/src/adapters/mistral-vibe.ts
8
+ /** Folder (inside the run directory) Vibe writes `export.json` to. */
9
+ const EXPORT_DIR = "vibe-output";
10
+ /**
11
+ * Mistral Vibe (`vibe`, PyPI `mistral-vibe`).
12
+ *
13
+ * Verified against the official repo at tag v2.26.1 only (README,
14
+ * `vibe/cli/entrypoint.py`, `vibe/cli/programmatic.py`,
15
+ * `vibe/app_server/run_export.py`, `vibe/core/config/*`); Vibe needs Python
16
+ * 3.12, so no real `--help` was run, 2026-10-17. The capability probe checks
17
+ * every flag against the installed `--help`.
18
+ *
19
+ * - Headless: `vibe -p <prompt> --output streaming` (or `--prompt-file`;
20
+ * `-p` with no value reads stdin). The stream is NDJSON of completed
21
+ * history entries (camelCase): `message` (`role`, `content[].text`), and
22
+ * `effect` — a tool call and its result in one line (`detail.toolName`,
23
+ * `detail.input`, `state.status`, `state.outputText`/`state.error`).
24
+ * There is no usage, cost or final record in the stream, so the adapter
25
+ * adds `--output-dir` and reads usage, cost, session id and outcome from
26
+ * `export.json` when the stream ends.
27
+ * - Model: no flag; `VIBE_ACTIVE_MODEL=<alias>` (set from `model`). Effort
28
+ * is a per-model config field, so `effort` is refused.
29
+ * - Permissions: headless auto-denies every approval (the default agent
30
+ * only auto-approves file edits); bypass is `--auto-approve`.
31
+ * - MCP: `[[mcp_servers]]` in `$VIBE_HOME/config.toml` (private home).
32
+ * - Auth: `MISTRAL_API_KEY`; home `VIBE_HOME`.
33
+ */
34
+ const mistralVibeAdapter = {
35
+ name: "mistral-vibe",
36
+ title: "Mistral Vibe",
37
+ command: "vibe",
38
+ apiKeyEnv: ["MISTRAL_API_KEY"],
39
+ homeEnv: ["VIBE_HOME"],
40
+ transports: [
41
+ "argv",
42
+ "file",
43
+ "stdin"
44
+ ],
45
+ effort: false,
46
+ mcp: true,
47
+ probe: {
48
+ help: [["--help"]],
49
+ version: ["--version"]
50
+ },
51
+ verification: {
52
+ version: "2.26.1",
53
+ verifiedBy: "docs",
54
+ sources: [
55
+ "https://github.com/mistralai/mistral-vibe/blob/v2.26.1/README.md",
56
+ "https://github.com/mistralai/mistral-vibe/blob/v2.26.1/vibe/cli/entrypoint.py",
57
+ "https://github.com/mistralai/mistral-vibe/blob/v2.26.1/vibe/cli/programmatic.py"
58
+ ],
59
+ checkedAt: "2026-10-17"
60
+ },
61
+ plan(context) {
62
+ const args = [
63
+ "--output",
64
+ "streaming",
65
+ "--output-dir",
66
+ path.join(context.runDir, EXPORT_DIR)
67
+ ];
68
+ const requires = [
69
+ "--output",
70
+ "streaming",
71
+ "--output-dir"
72
+ ];
73
+ const files = [];
74
+ const env = {};
75
+ if (context.model !== void 0) env.VIBE_ACTIVE_MODEL = context.model;
76
+ if (context.resume !== void 0) {
77
+ args.push("--resume", context.resume);
78
+ requires.push("--resume");
79
+ }
80
+ if (context.permission === "bypass") {
81
+ args.push("--auto-approve");
82
+ requires.push("--auto-approve");
83
+ }
84
+ if (context.mcp !== void 0) {
85
+ const home = requirePrivateHome(context, mistralVibeAdapter, "MCP servers");
86
+ files.push({
87
+ path: path.join(home, "config.toml"),
88
+ content: toToml({ mcp_servers: vibeMcp(context.mcp) })
89
+ });
90
+ }
91
+ if (context.home !== void 0) env.VIBE_HOME = context.home;
92
+ if (context.transport === "file") {
93
+ const prompt = promptFile(context);
94
+ files.push(prompt);
95
+ requires.push("--prompt-file");
96
+ return {
97
+ args,
98
+ tail: ["--prompt-file", prompt.path],
99
+ env,
100
+ files,
101
+ requires
102
+ };
103
+ }
104
+ requires.push("-p");
105
+ if (context.transport === "stdin") return {
106
+ args,
107
+ tail: ["-p"],
108
+ stdin: context.prompt,
109
+ env,
110
+ files,
111
+ requires
112
+ };
113
+ return {
114
+ args,
115
+ tail: ["-p", argvPrompt(context.prompt)],
116
+ env,
117
+ files,
118
+ requires
119
+ };
120
+ },
121
+ parser: createVibeParser
122
+ };
123
+ function vibeMcp(servers) {
124
+ return Object.entries(servers).map(([name, server]) => server.type === "stdio" ? {
125
+ name,
126
+ transport: "stdio",
127
+ command: server.command,
128
+ args: server.args ?? [],
129
+ env: server.env
130
+ } : {
131
+ name,
132
+ transport: server.type === "http" ? "streamable-http" : "http",
133
+ url: server.url,
134
+ auth: server.headers !== void 0 ? {
135
+ type: "static",
136
+ headers: server.headers
137
+ } : void 0
138
+ });
139
+ }
140
+ /** Read Vibe's `export.json`: usage, cost, session id and outcome of the run. */
141
+ function exportEvents(context) {
142
+ if (context === void 0) return { events: [] };
143
+ let report;
144
+ try {
145
+ report = parseJsonLine(readFileSync(path.join(context.runDir, EXPORT_DIR, "export.json"), "utf8"));
146
+ } catch {
147
+ return { events: [] };
148
+ }
149
+ if (report === void 0) return { events: [] };
150
+ const events = [];
151
+ const usage = recordField(report, "usage");
152
+ if (usage !== void 0) {
153
+ const cached = numberField(usage, "cached_input_tokens");
154
+ events.push({
155
+ type: "usage",
156
+ cumulative: true,
157
+ usage: usageOf({
158
+ input: numberField(usage, "input_tokens"),
159
+ output: numberField(usage, "output_tokens"),
160
+ total: numberField(usage, "total_tokens"),
161
+ cachedTokens: cached !== void 0 && cached > 0 ? cached : void 0,
162
+ costUSD: numberField(report, "cost_usd")
163
+ }),
164
+ raw: report
165
+ });
166
+ }
167
+ const outcome = stringField(report, "outcome");
168
+ if (outcome !== void 0 && outcome !== "finished") events.push({
169
+ type: "error",
170
+ message: stringField(recordField(report, "error"), "message") ?? `Mistral Vibe stopped: ${outcome}`,
171
+ fatal: true,
172
+ raw: report
173
+ });
174
+ return {
175
+ events,
176
+ sessionRef: stringField(report, "session_id")
177
+ };
178
+ }
179
+ /** Parser for `vibe -p … --output streaming` (plus the run's `export.json`). */
180
+ function createVibeParser(context) {
181
+ let started = false;
182
+ let sessionRef;
183
+ return {
184
+ ...jsonLinesParser((record) => {
185
+ const events = [];
186
+ const session = stringField(record, "sessionId");
187
+ if (session !== void 0) sessionRef = session;
188
+ if (!started) {
189
+ started = true;
190
+ events.push({
191
+ type: "session.started",
192
+ sessionRef: session,
193
+ raw: record
194
+ });
195
+ }
196
+ switch (stringField(record, "type")) {
197
+ case "message": {
198
+ if (stringField(record, "role") !== "assistant") break;
199
+ const text = asArray(record.content).map((block) => stringField(asRecord(block), "text") ?? "").join("");
200
+ if (text.length > 0) events.push({
201
+ type: "message",
202
+ text,
203
+ delta: false,
204
+ raw: record
205
+ });
206
+ break;
207
+ }
208
+ case "effect": {
209
+ const detail = recordField(record, "detail");
210
+ const state = recordField(record, "state");
211
+ const status = stringField(state, "status");
212
+ const id = stringField(record, "id") ?? "";
213
+ events.push({
214
+ type: "tool.call",
215
+ id,
216
+ name: stringField(detail, "toolName") ?? stringField(record, "title") ?? "",
217
+ input: detail?.input,
218
+ raw: record
219
+ });
220
+ if (status === "completed" || status === "failed" || status === "cancelled" || status === "skipped") {
221
+ const error = stringField(recordField(state, "error"), "message");
222
+ events.push({
223
+ type: "tool.result",
224
+ id,
225
+ output: error ?? stringField(state, "outputText") ?? outputText(state?.output),
226
+ isError: status !== "completed",
227
+ raw: record
228
+ });
229
+ }
230
+ break;
231
+ }
232
+ case "notice":
233
+ if (stringField(record, "level") === "error") events.push({
234
+ type: "error",
235
+ message: stringField(record, "message") ?? "error",
236
+ raw: record
237
+ });
238
+ break;
239
+ }
240
+ return events;
241
+ }, () => {
242
+ const exported = exportEvents(context);
243
+ sessionRef = exported.sessionRef ?? sessionRef;
244
+ return exported.events;
245
+ }),
246
+ sessionRef: () => sessionRef
247
+ };
248
+ }
249
+
250
+ //#endregion
251
+ export { createVibeParser, mistralVibeAdapter };
252
+ //# sourceMappingURL=mistral-vibe.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mistral-vibe.mjs","names":[],"sources":["../../../../../../../../packages/ai-cli/src/adapters/mistral-vibe.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type {\n CliAdapter,\n CliLaunchContext,\n CliLaunchFile,\n CliMcpServers,\n CliParsedEvent,\n CliStreamParser,\n} from \"../contracts\";\nimport {\n asArray,\n asRecord,\n jsonLinesParser,\n numberField,\n outputText,\n parseJsonLine,\n recordField,\n stringField,\n} from \"../stream/json-lines\";\nimport { type TomlTable, toToml } from \"../utils/toml\";\nimport { argvPrompt, promptFile, requirePrivateHome, usageOf } from \"./shared\";\n\n/** Folder (inside the run directory) Vibe writes `export.json` to. */\nconst EXPORT_DIR = \"vibe-output\";\n\n/**\n * Mistral Vibe (`vibe`, PyPI `mistral-vibe`).\n *\n * Verified against the official repo at tag v2.26.1 only (README,\n * `vibe/cli/entrypoint.py`, `vibe/cli/programmatic.py`,\n * `vibe/app_server/run_export.py`, `vibe/core/config/*`); Vibe needs Python\n * 3.12, so no real `--help` was run, 2026-10-17. The capability probe checks\n * every flag against the installed `--help`.\n *\n * - Headless: `vibe -p <prompt> --output streaming` (or `--prompt-file`;\n * `-p` with no value reads stdin). The stream is NDJSON of completed\n * history entries (camelCase): `message` (`role`, `content[].text`), and\n * `effect` — a tool call and its result in one line (`detail.toolName`,\n * `detail.input`, `state.status`, `state.outputText`/`state.error`).\n * There is no usage, cost or final record in the stream, so the adapter\n * adds `--output-dir` and reads usage, cost, session id and outcome from\n * `export.json` when the stream ends.\n * - Model: no flag; `VIBE_ACTIVE_MODEL=<alias>` (set from `model`). Effort\n * is a per-model config field, so `effort` is refused.\n * - Permissions: headless auto-denies every approval (the default agent\n * only auto-approves file edits); bypass is `--auto-approve`.\n * - MCP: `[[mcp_servers]]` in `$VIBE_HOME/config.toml` (private home).\n * - Auth: `MISTRAL_API_KEY`; home `VIBE_HOME`.\n */\nexport const mistralVibeAdapter: CliAdapter = {\n name: \"mistral-vibe\",\n title: \"Mistral Vibe\",\n command: \"vibe\",\n apiKeyEnv: [\"MISTRAL_API_KEY\"],\n homeEnv: [\"VIBE_HOME\"],\n transports: [\"argv\", \"file\", \"stdin\"],\n effort: false,\n mcp: true,\n probe: { help: [[\"--help\"]], version: [\"--version\"] },\n verification: {\n version: \"2.26.1\",\n verifiedBy: \"docs\",\n sources: [\n \"https://github.com/mistralai/mistral-vibe/blob/v2.26.1/README.md\",\n \"https://github.com/mistralai/mistral-vibe/blob/v2.26.1/vibe/cli/entrypoint.py\",\n \"https://github.com/mistralai/mistral-vibe/blob/v2.26.1/vibe/cli/programmatic.py\",\n ],\n checkedAt: \"2026-10-17\",\n },\n plan(context) {\n const args = [\"--output\", \"streaming\", \"--output-dir\", path.join(context.runDir, EXPORT_DIR)];\n const requires = [\"--output\", \"streaming\", \"--output-dir\"];\n const files: CliLaunchFile[] = [];\n const env: Record<string, string> = {};\n\n if (context.model !== undefined) {\n env.VIBE_ACTIVE_MODEL = context.model;\n }\n\n if (context.resume !== undefined) {\n args.push(\"--resume\", context.resume);\n requires.push(\"--resume\");\n }\n\n if (context.permission === \"bypass\") {\n args.push(\"--auto-approve\");\n requires.push(\"--auto-approve\");\n }\n\n if (context.mcp !== undefined) {\n const home = requirePrivateHome(context, mistralVibeAdapter, \"MCP servers\");\n\n files.push({\n path: path.join(home, \"config.toml\"),\n content: toToml({ mcp_servers: vibeMcp(context.mcp) }),\n });\n }\n\n if (context.home !== undefined) {\n env.VIBE_HOME = context.home;\n }\n\n if (context.transport === \"file\") {\n const prompt = promptFile(context);\n\n files.push(prompt);\n requires.push(\"--prompt-file\");\n\n return { args, tail: [\"--prompt-file\", prompt.path], env, files, requires };\n }\n\n requires.push(\"-p\");\n\n if (context.transport === \"stdin\") {\n return { args, tail: [\"-p\"], stdin: context.prompt, env, files, requires };\n }\n\n return { args, tail: [\"-p\", argvPrompt(context.prompt)], env, files, requires };\n },\n parser: createVibeParser,\n};\n\nfunction vibeMcp(servers: CliMcpServers): TomlTable[] {\n return Object.entries(servers).map(([name, server]): TomlTable =>\n server.type === \"stdio\"\n ? {\n name,\n transport: \"stdio\",\n command: server.command,\n args: server.args ?? [],\n env: server.env,\n }\n : {\n name,\n transport: server.type === \"http\" ? \"streamable-http\" : \"http\",\n url: server.url,\n auth:\n server.headers !== undefined ? { type: \"static\", headers: server.headers } : undefined,\n },\n );\n}\n\n/** Read Vibe's `export.json`: usage, cost, session id and outcome of the run. */\nfunction exportEvents(context: CliLaunchContext | undefined): {\n events: CliParsedEvent[];\n sessionRef?: string;\n} {\n if (context === undefined) {\n return { events: [] };\n }\n\n let report: Record<string, unknown> | undefined;\n\n try {\n report = parseJsonLine(\n readFileSync(path.join(context.runDir, EXPORT_DIR, \"export.json\"), \"utf8\"),\n );\n } catch {\n return { events: [] };\n }\n\n if (report === undefined) {\n return { events: [] };\n }\n\n const events: CliParsedEvent[] = [];\n const usage = recordField(report, \"usage\");\n\n if (usage !== undefined) {\n const cached = numberField(usage, \"cached_input_tokens\");\n\n events.push({\n type: \"usage\",\n cumulative: true,\n usage: usageOf({\n input: numberField(usage, \"input_tokens\"),\n output: numberField(usage, \"output_tokens\"),\n total: numberField(usage, \"total_tokens\"),\n cachedTokens: cached !== undefined && cached > 0 ? cached : undefined,\n costUSD: numberField(report, \"cost_usd\"),\n }),\n raw: report,\n });\n }\n\n const outcome = stringField(report, \"outcome\");\n\n if (outcome !== undefined && outcome !== \"finished\") {\n events.push({\n type: \"error\",\n message:\n stringField(recordField(report, \"error\"), \"message\") ?? `Mistral Vibe stopped: ${outcome}`,\n fatal: true,\n raw: report,\n });\n }\n\n return { events, sessionRef: stringField(report, \"session_id\") };\n}\n\n/** Parser for `vibe -p … --output streaming` (plus the run's `export.json`). */\nexport function createVibeParser(context?: CliLaunchContext): CliStreamParser {\n let started = false;\n let sessionRef: string | undefined;\n\n const parser = jsonLinesParser(\n (record): CliParsedEvent[] => {\n const events: CliParsedEvent[] = [];\n const session = stringField(record, \"sessionId\");\n\n if (session !== undefined) {\n sessionRef = session;\n }\n\n if (!started) {\n started = true;\n events.push({ type: \"session.started\", sessionRef: session, raw: record });\n }\n\n switch (stringField(record, \"type\")) {\n case \"message\": {\n if (stringField(record, \"role\") !== \"assistant\") {\n break;\n }\n\n const text = asArray(record.content)\n .map((block) => stringField(asRecord(block), \"text\") ?? \"\")\n .join(\"\");\n\n if (text.length > 0) {\n events.push({ type: \"message\", text, delta: false, raw: record });\n }\n break;\n }\n case \"effect\": {\n const detail = recordField(record, \"detail\");\n const state = recordField(record, \"state\");\n const status = stringField(state, \"status\");\n const id = stringField(record, \"id\") ?? \"\";\n\n events.push({\n type: \"tool.call\",\n id,\n name: stringField(detail, \"toolName\") ?? stringField(record, \"title\") ?? \"\",\n input: detail?.input,\n raw: record,\n });\n\n if (\n status === \"completed\" ||\n status === \"failed\" ||\n status === \"cancelled\" ||\n status === \"skipped\"\n ) {\n const error = stringField(recordField(state, \"error\"), \"message\");\n\n events.push({\n type: \"tool.result\",\n id,\n output: error ?? stringField(state, \"outputText\") ?? outputText(state?.output),\n isError: status !== \"completed\",\n raw: record,\n });\n }\n break;\n }\n case \"notice\":\n if (stringField(record, \"level\") === \"error\") {\n events.push({\n type: \"error\",\n message: stringField(record, \"message\") ?? \"error\",\n raw: record,\n });\n }\n break;\n }\n\n return events;\n },\n () => {\n const exported = exportEvents(context);\n\n sessionRef = exported.sessionRef ?? sessionRef;\n\n return exported.events;\n },\n );\n\n return { ...parser, sessionRef: () => sessionRef };\n}\n"],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import { CliAdapter, CliStreamParser } from "../contracts/adapter.contract.mjs";
2
+ //#region ../../packages/ai-cli/src/adapters/opencode.d.ts
3
+ /**
4
+ * OpenCode (`opencode`, npm `opencode-ai`).
5
+ *
6
+ * Verified against the real `opencode --help` / `opencode run --help` of
7
+ * 1.19.3, the CLI source at that tag (`packages/opencode/src/cli/cmd/run.ts`)
8
+ * and the docs (`cli.mdx`, `config.mdx`, `mcp-servers.mdx`,
9
+ * `permissions.mdx`), 2026-10-17.
10
+ *
11
+ * - Headless: `opencode run --format json <message..>`; with no message,
12
+ * piped stdin is the prompt.
13
+ * - Stream: `{"type","timestamp","sessionID","part"|"error"}` lines of six
14
+ * types: `step_start`, `text` (whole text blocks, no deltas), `reasoning`,
15
+ * `tool_use` (emitted once the tool finished — call and result together,
16
+ * `state.status` `completed`/`error`), `step_finish` (per-step `cost` in
17
+ * USD and `tokens{input,output,reasoning,cache{read,write}}`, input net of
18
+ * cache) and `error{error:{name,data:{message}}}`. No init or final record.
19
+ * - Permissions: `standard` keeps OpenCode's own rules (permissive by
20
+ * default; anything that would ask is auto-rejected in `run`); bypass is
21
+ * `--auto`.
22
+ * - MCP: the `mcp` key of a config file named by `OPENCODE_CONFIG`, written
23
+ * to the run directory — works with any home.
24
+ * - Home: OpenCode follows XDG; a private/owned home sets `XDG_CONFIG_HOME`,
25
+ * `XDG_DATA_HOME` (auth lives here), `XDG_STATE_HOME` and `XDG_CACHE_HOME`
26
+ * beneath it. Provider keys use the provider's own variable
27
+ * (`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, …) — pass them through `env`.
28
+ * - The working directory is passed with `--dir`, because OpenCode prefers a
29
+ * (possibly stale) `PWD` over the process cwd.
30
+ */
31
+ declare const opencodeAdapter: CliAdapter;
32
+ /** Parser for `opencode run --format json`. */
33
+ declare function createOpencodeParser(): CliStreamParser;
34
+ //#endregion
35
+ export { createOpencodeParser, opencodeAdapter };
36
+ //# sourceMappingURL=opencode.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opencode.d.mts","names":[],"sources":["../../../../../../../../packages/ai-cli/src/adapters/opencode.ts"],"mappings":";;;;;AA6CA;;;;AA8EC;AA0BD;;;;AAAuD;;;;;;;;;;;;;;;;cAxG1C,eAAA,EAAiB,UA8E7B;;iBA0Be,oBAAA,IAAwB,eAAe"}