@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.
- package/CHANGELOG.md +31 -0
- package/LICENSE +21 -0
- package/README.md +69 -2
- package/cjs/index.cjs +4576 -0
- package/cjs/index.cjs.map +1 -0
- package/esm/adapters/aider.d.mts +41 -0
- package/esm/adapters/aider.d.mts.map +1 -0
- package/esm/adapters/aider.mjs +294 -0
- package/esm/adapters/aider.mjs.map +1 -0
- package/esm/adapters/amp.d.mts +33 -0
- package/esm/adapters/amp.d.mts.map +1 -0
- package/esm/adapters/amp.mjs +119 -0
- package/esm/adapters/amp.mjs.map +1 -0
- package/esm/adapters/antigravity.d.mts +37 -0
- package/esm/adapters/antigravity.d.mts.map +1 -0
- package/esm/adapters/antigravity.mjs +235 -0
- package/esm/adapters/antigravity.mjs.map +1 -0
- package/esm/adapters/claude-code.d.mts +30 -0
- package/esm/adapters/claude-code.d.mts.map +1 -0
- package/esm/adapters/claude-code.mjs +121 -0
- package/esm/adapters/claude-code.mjs.map +1 -0
- package/esm/adapters/claude-stream.d.mts +32 -0
- package/esm/adapters/claude-stream.d.mts.map +1 -0
- package/esm/adapters/claude-stream.mjs +140 -0
- package/esm/adapters/claude-stream.mjs.map +1 -0
- package/esm/adapters/codex.d.mts +37 -0
- package/esm/adapters/codex.d.mts.map +1 -0
- package/esm/adapters/codex.mjs +320 -0
- package/esm/adapters/codex.mjs.map +1 -0
- package/esm/adapters/copilot.d.mts +35 -0
- package/esm/adapters/copilot.d.mts.map +1 -0
- package/esm/adapters/copilot.mjs +244 -0
- package/esm/adapters/copilot.mjs.map +1 -0
- package/esm/adapters/cursor.d.mts +35 -0
- package/esm/adapters/cursor.d.mts.map +1 -0
- package/esm/adapters/cursor.mjs +203 -0
- package/esm/adapters/cursor.mjs.map +1 -0
- package/esm/adapters/droid.d.mts +32 -0
- package/esm/adapters/droid.d.mts.map +1 -0
- package/esm/adapters/droid.mjs +183 -0
- package/esm/adapters/droid.mjs.map +1 -0
- package/esm/adapters/grok.d.mts +32 -0
- package/esm/adapters/grok.d.mts.map +1 -0
- package/esm/adapters/grok.mjs +199 -0
- package/esm/adapters/grok.mjs.map +1 -0
- package/esm/adapters/index.d.mts +16 -0
- package/esm/adapters/index.mjs +18 -0
- package/esm/adapters/kimi.d.mts +34 -0
- package/esm/adapters/kimi.d.mts.map +1 -0
- package/esm/adapters/kimi.mjs +162 -0
- package/esm/adapters/kimi.mjs.map +1 -0
- package/esm/adapters/mistral-vibe.d.mts +32 -0
- package/esm/adapters/mistral-vibe.d.mts.map +1 -0
- package/esm/adapters/mistral-vibe.mjs +252 -0
- package/esm/adapters/mistral-vibe.mjs.map +1 -0
- package/esm/adapters/opencode.d.mts +36 -0
- package/esm/adapters/opencode.d.mts.map +1 -0
- package/esm/adapters/opencode.mjs +219 -0
- package/esm/adapters/opencode.mjs.map +1 -0
- package/esm/adapters/qwen-code.d.mts +30 -0
- package/esm/adapters/qwen-code.d.mts.map +1 -0
- package/esm/adapters/qwen-code.mjs +94 -0
- package/esm/adapters/qwen-code.mjs.map +1 -0
- package/esm/adapters/reasonix.d.mts +31 -0
- package/esm/adapters/reasonix.d.mts.map +1 -0
- package/esm/adapters/reasonix.mjs +250 -0
- package/esm/adapters/reasonix.mjs.map +1 -0
- package/esm/adapters/shared.d.mts +78 -0
- package/esm/adapters/shared.d.mts.map +1 -0
- package/esm/adapters/shared.mjs +161 -0
- package/esm/adapters/shared.mjs.map +1 -0
- package/esm/cli-agent.d.mts +40 -0
- package/esm/cli-agent.d.mts.map +1 -0
- package/esm/cli-agent.mjs +207 -0
- package/esm/cli-agent.mjs.map +1 -0
- package/esm/cli.d.mts +53 -0
- package/esm/cli.d.mts.map +1 -0
- package/esm/cli.mjs +61 -0
- package/esm/cli.mjs.map +1 -0
- package/esm/contracts/adapter.contract.d.mts +154 -0
- package/esm/contracts/adapter.contract.d.mts.map +1 -0
- package/esm/contracts/events.type.d.mts +111 -0
- package/esm/contracts/events.type.d.mts.map +1 -0
- package/esm/contracts/index.d.mts +4 -0
- package/esm/contracts/mcp.type.d.mts +29 -0
- package/esm/contracts/mcp.type.d.mts.map +1 -0
- package/esm/contracts/options.type.d.mts +87 -0
- package/esm/contracts/options.type.d.mts.map +1 -0
- package/esm/errors.d.mts +46 -0
- package/esm/errors.d.mts.map +1 -0
- package/esm/errors.mjs +32 -0
- package/esm/errors.mjs.map +1 -0
- package/esm/index.d.mts +31 -0
- package/esm/index.mjs +28 -0
- package/esm/model/cli-model.d.mts +48 -0
- package/esm/model/cli-model.d.mts.map +1 -0
- package/esm/model/cli-model.mjs +133 -0
- package/esm/model/cli-model.mjs.map +1 -0
- package/esm/probe/probe.d.mts +18 -0
- package/esm/probe/probe.d.mts.map +1 -0
- package/esm/probe/probe.mjs +148 -0
- package/esm/probe/probe.mjs.map +1 -0
- package/esm/session/aggregate.mjs +86 -0
- package/esm/session/aggregate.mjs.map +1 -0
- package/esm/session/environment.mjs +71 -0
- package/esm/session/environment.mjs.map +1 -0
- package/esm/session/run-directory.mjs +74 -0
- package/esm/session/run-directory.mjs.map +1 -0
- package/esm/session/session.mjs +188 -0
- package/esm/session/session.mjs.map +1 -0
- package/esm/spawn/invocation.d.mts +35 -0
- package/esm/spawn/invocation.d.mts.map +1 -0
- package/esm/spawn/invocation.mjs +76 -0
- package/esm/spawn/invocation.mjs.map +1 -0
- package/esm/spawn/process-tree.mjs +57 -0
- package/esm/spawn/process-tree.mjs.map +1 -0
- package/esm/spawn/resolve-command.d.mts +73 -0
- package/esm/spawn/resolve-command.d.mts.map +1 -0
- package/esm/spawn/resolve-command.mjs +109 -0
- package/esm/spawn/resolve-command.mjs.map +1 -0
- package/esm/stream/event-log.mjs +52 -0
- package/esm/stream/event-log.mjs.map +1 -0
- package/esm/stream/json-lines.d.mts +33 -0
- package/esm/stream/json-lines.d.mts.map +1 -0
- package/esm/stream/json-lines.mjs +65 -0
- package/esm/stream/json-lines.mjs.map +1 -0
- package/esm/stream/line-splitter.mjs +53 -0
- package/esm/stream/line-splitter.mjs.map +1 -0
- package/esm/utils/toml.d.mts +22 -0
- package/esm/utils/toml.d.mts.map +1 -0
- package/esm/utils/toml.mjs +53 -0
- package/esm/utils/toml.mjs.map +1 -0
- package/llms-full.txt +373 -0
- package/llms.txt +10 -0
- package/package.json +39 -4
- package/skills/README.md +13 -0
- package/skills/index.md +22 -0
- package/skills/run-cli-agents/SKILL.md +186 -0
- package/skills/write-a-cli-adapter/SKILL.md +173 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { jsonLinesParser, outputText, recordField, stringField } from "../stream/json-lines.mjs";
|
|
2
|
+
import { anthropicUsage, argvPrompt, jsonFile, mcpServersJson, promptFile, requirePrivateHome } from "./shared.mjs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
|
|
5
|
+
//#region ../../packages/ai-cli/src/adapters/droid.ts
|
|
6
|
+
/**
|
|
7
|
+
* Factory Droid (`droid`, npm `droid` / `@factory/cli`).
|
|
8
|
+
*
|
|
9
|
+
* Verified against the real `droid exec --help` of 0.244.0, a real
|
|
10
|
+
* `droid exec` run without credentials (init and error lines), the field
|
|
11
|
+
* names in the shipped code and the docs (`docs.factory.ai/cli/droid-exec`,
|
|
12
|
+
* `/cli/configuration/mcp`), 2026-10-17.
|
|
13
|
+
*
|
|
14
|
+
* - Headless: `droid exec -o stream-json <prompt>` (or `-f <file>`).
|
|
15
|
+
* - Stream: `system/init` (`session_id`, `model`), whole `message` records
|
|
16
|
+
* (`role`, `text`), `tool_call` (`id`, `toolName`, `parameters`),
|
|
17
|
+
* `tool_result` (`id`, `isError`, `value` | `error.message`), a final
|
|
18
|
+
* `completion` (`finalText`, `usage` with Anthropic-style
|
|
19
|
+
* `input_tokens`/`cache_read_input_tokens`/`cache_creation_input_tokens`,
|
|
20
|
+
* read with Anthropic semantics) and `error` (`source`, `message`).
|
|
21
|
+
* Billing is in Factory credits; no USD cost is reported.
|
|
22
|
+
* - Permissions: `standard` is Droid's default **read-only** autonomy; raise
|
|
23
|
+
* it with `args: ["--auto", "medium"]` (low | medium | high). Bypass is
|
|
24
|
+
* `--skip-permissions-unsafe`. Blocked actions end the run non-zero.
|
|
25
|
+
* - MCP: `<home>/.factory/mcp.json` (`mcpServers`); the home is relocated
|
|
26
|
+
* with `FACTORY_HOME_OVERRIDE` (found in the shipped code and confirmed
|
|
27
|
+
* with `droid mcp list`), so per-run MCP needs a private home.
|
|
28
|
+
* - Auth: `FACTORY_API_KEY`.
|
|
29
|
+
*/
|
|
30
|
+
const droidAdapter = {
|
|
31
|
+
name: "droid",
|
|
32
|
+
title: "Factory Droid",
|
|
33
|
+
command: "droid",
|
|
34
|
+
apiKeyEnv: ["FACTORY_API_KEY"],
|
|
35
|
+
homeEnv: ["FACTORY_HOME_OVERRIDE"],
|
|
36
|
+
transports: ["argv", "file"],
|
|
37
|
+
effort: true,
|
|
38
|
+
mcp: true,
|
|
39
|
+
probe: {
|
|
40
|
+
help: [["exec", "--help"]],
|
|
41
|
+
version: ["--version"]
|
|
42
|
+
},
|
|
43
|
+
verification: {
|
|
44
|
+
version: "0.244.0",
|
|
45
|
+
verifiedBy: "help",
|
|
46
|
+
sources: [
|
|
47
|
+
"https://docs.factory.ai/cli/droid-exec/overview",
|
|
48
|
+
"https://docs.factory.ai/cli/configuration/mcp",
|
|
49
|
+
"https://www.npmjs.com/package/droid"
|
|
50
|
+
],
|
|
51
|
+
checkedAt: "2026-10-17"
|
|
52
|
+
},
|
|
53
|
+
plan(context) {
|
|
54
|
+
const args = [
|
|
55
|
+
"exec",
|
|
56
|
+
"--output-format",
|
|
57
|
+
"stream-json",
|
|
58
|
+
"--cwd",
|
|
59
|
+
context.cwd
|
|
60
|
+
];
|
|
61
|
+
const requires = [
|
|
62
|
+
"--output-format",
|
|
63
|
+
"stream-json",
|
|
64
|
+
"--cwd"
|
|
65
|
+
];
|
|
66
|
+
const files = [];
|
|
67
|
+
let tail;
|
|
68
|
+
if (context.model !== void 0) {
|
|
69
|
+
args.push("--model", context.model);
|
|
70
|
+
requires.push("--model");
|
|
71
|
+
}
|
|
72
|
+
if (context.effort !== void 0) {
|
|
73
|
+
args.push("--reasoning-effort", context.effort);
|
|
74
|
+
requires.push("--reasoning-effort");
|
|
75
|
+
}
|
|
76
|
+
if (context.resume !== void 0) {
|
|
77
|
+
args.push("--session-id", context.resume);
|
|
78
|
+
requires.push("--session-id");
|
|
79
|
+
}
|
|
80
|
+
if (context.permission === "bypass") {
|
|
81
|
+
args.push("--skip-permissions-unsafe");
|
|
82
|
+
requires.push("--skip-permissions-unsafe");
|
|
83
|
+
}
|
|
84
|
+
if (context.mcp !== void 0) {
|
|
85
|
+
const home = requirePrivateHome(context, droidAdapter, "MCP servers");
|
|
86
|
+
files.push({
|
|
87
|
+
path: path.join(home, ".factory", "mcp.json"),
|
|
88
|
+
content: jsonFile({ mcpServers: mcpServersJson(context.mcp, { typeField: true }) })
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
if (context.transport === "file") {
|
|
92
|
+
const prompt = promptFile(context);
|
|
93
|
+
files.push(prompt);
|
|
94
|
+
tail = ["--file", prompt.path];
|
|
95
|
+
requires.push("--file");
|
|
96
|
+
} else tail = [argvPrompt(context.prompt)];
|
|
97
|
+
return {
|
|
98
|
+
args,
|
|
99
|
+
tail,
|
|
100
|
+
env: {
|
|
101
|
+
...context.home !== void 0 ? { FACTORY_HOME_OVERRIDE: context.home } : {},
|
|
102
|
+
FACTORY_DROID_AUTO_UPDATE_ENABLED: "false"
|
|
103
|
+
},
|
|
104
|
+
files,
|
|
105
|
+
requires
|
|
106
|
+
};
|
|
107
|
+
},
|
|
108
|
+
parser: createDroidParser
|
|
109
|
+
};
|
|
110
|
+
/** Parser for `droid exec -o stream-json`. */
|
|
111
|
+
function createDroidParser() {
|
|
112
|
+
return jsonLinesParser((record) => {
|
|
113
|
+
switch (stringField(record, "type")) {
|
|
114
|
+
case "system": return stringField(record, "subtype") === "init" ? [{
|
|
115
|
+
type: "session.started",
|
|
116
|
+
sessionRef: stringField(record, "session_id"),
|
|
117
|
+
model: stringField(record, "model"),
|
|
118
|
+
raw: record
|
|
119
|
+
}] : [];
|
|
120
|
+
case "message": {
|
|
121
|
+
const text = stringField(record, "text") ?? "";
|
|
122
|
+
return stringField(record, "role") === "assistant" && text.length > 0 ? [{
|
|
123
|
+
type: "message",
|
|
124
|
+
text,
|
|
125
|
+
delta: false,
|
|
126
|
+
raw: record
|
|
127
|
+
}] : [];
|
|
128
|
+
}
|
|
129
|
+
case "tool_call": return [{
|
|
130
|
+
type: "tool.call",
|
|
131
|
+
id: stringField(record, "id") ?? "",
|
|
132
|
+
name: stringField(record, "toolName") ?? stringField(record, "toolId") ?? "",
|
|
133
|
+
input: record.parameters,
|
|
134
|
+
raw: record
|
|
135
|
+
}];
|
|
136
|
+
case "tool_result": {
|
|
137
|
+
const error = recordField(record, "error");
|
|
138
|
+
const isError = record.isError === true || error !== void 0;
|
|
139
|
+
return [{
|
|
140
|
+
type: "tool.result",
|
|
141
|
+
id: stringField(record, "id") ?? "",
|
|
142
|
+
output: isError && error !== void 0 ? stringField(error, "message") ?? "" : outputText(record.value),
|
|
143
|
+
isError,
|
|
144
|
+
raw: record
|
|
145
|
+
}];
|
|
146
|
+
}
|
|
147
|
+
case "completion": {
|
|
148
|
+
const events = [];
|
|
149
|
+
const usage = anthropicUsage(recordField(record, "usage"));
|
|
150
|
+
if (usage !== void 0) {
|
|
151
|
+
const thinking = recordField(record, "usage")?.thinking_tokens;
|
|
152
|
+
if (typeof thinking === "number" && thinking > 0) usage.reasoningTokens = thinking;
|
|
153
|
+
events.push({
|
|
154
|
+
type: "usage",
|
|
155
|
+
usage,
|
|
156
|
+
cumulative: true,
|
|
157
|
+
raw: record
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
const text = stringField(record, "finalText") ?? "";
|
|
161
|
+
if (text.length > 0) events.push({
|
|
162
|
+
type: "message",
|
|
163
|
+
text,
|
|
164
|
+
delta: false,
|
|
165
|
+
final: true,
|
|
166
|
+
raw: record
|
|
167
|
+
});
|
|
168
|
+
return events;
|
|
169
|
+
}
|
|
170
|
+
case "error": return [{
|
|
171
|
+
type: "error",
|
|
172
|
+
message: stringField(record, "message") ?? "Droid reported an error",
|
|
173
|
+
fatal: true,
|
|
174
|
+
raw: record
|
|
175
|
+
}];
|
|
176
|
+
default: return [];
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
//#endregion
|
|
182
|
+
export { createDroidParser, droidAdapter };
|
|
183
|
+
//# sourceMappingURL=droid.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"droid.mjs","names":[],"sources":["../../../../../../../../packages/ai-cli/src/adapters/droid.ts"],"sourcesContent":["import path from \"node:path\";\nimport type { CliAdapter, CliLaunchFile, CliParsedEvent, CliStreamParser } from \"../contracts\";\nimport { jsonLinesParser, outputText, recordField, stringField } from \"../stream/json-lines\";\nimport {\n anthropicUsage,\n argvPrompt,\n jsonFile,\n mcpServersJson,\n promptFile,\n requirePrivateHome,\n} from \"./shared\";\n\n/**\n * Factory Droid (`droid`, npm `droid` / `@factory/cli`).\n *\n * Verified against the real `droid exec --help` of 0.244.0, a real\n * `droid exec` run without credentials (init and error lines), the field\n * names in the shipped code and the docs (`docs.factory.ai/cli/droid-exec`,\n * `/cli/configuration/mcp`), 2026-10-17.\n *\n * - Headless: `droid exec -o stream-json <prompt>` (or `-f <file>`).\n * - Stream: `system/init` (`session_id`, `model`), whole `message` records\n * (`role`, `text`), `tool_call` (`id`, `toolName`, `parameters`),\n * `tool_result` (`id`, `isError`, `value` | `error.message`), a final\n * `completion` (`finalText`, `usage` with Anthropic-style\n * `input_tokens`/`cache_read_input_tokens`/`cache_creation_input_tokens`,\n * read with Anthropic semantics) and `error` (`source`, `message`).\n * Billing is in Factory credits; no USD cost is reported.\n * - Permissions: `standard` is Droid's default **read-only** autonomy; raise\n * it with `args: [\"--auto\", \"medium\"]` (low | medium | high). Bypass is\n * `--skip-permissions-unsafe`. Blocked actions end the run non-zero.\n * - MCP: `<home>/.factory/mcp.json` (`mcpServers`); the home is relocated\n * with `FACTORY_HOME_OVERRIDE` (found in the shipped code and confirmed\n * with `droid mcp list`), so per-run MCP needs a private home.\n * - Auth: `FACTORY_API_KEY`.\n */\nexport const droidAdapter: CliAdapter = {\n name: \"droid\",\n title: \"Factory Droid\",\n command: \"droid\",\n apiKeyEnv: [\"FACTORY_API_KEY\"],\n homeEnv: [\"FACTORY_HOME_OVERRIDE\"],\n transports: [\"argv\", \"file\"],\n effort: true,\n mcp: true,\n probe: { help: [[\"exec\", \"--help\"]], version: [\"--version\"] },\n verification: {\n version: \"0.244.0\",\n verifiedBy: \"help\",\n sources: [\n \"https://docs.factory.ai/cli/droid-exec/overview\",\n \"https://docs.factory.ai/cli/configuration/mcp\",\n \"https://www.npmjs.com/package/droid\",\n ],\n checkedAt: \"2026-10-17\",\n },\n plan(context) {\n const args = [\"exec\", \"--output-format\", \"stream-json\", \"--cwd\", context.cwd];\n const requires = [\"--output-format\", \"stream-json\", \"--cwd\"];\n const files: CliLaunchFile[] = [];\n let tail: string[];\n\n if (context.model !== undefined) {\n args.push(\"--model\", context.model);\n requires.push(\"--model\");\n }\n\n if (context.effort !== undefined) {\n // Accepted per model from off | none | minimal | low | medium | high | xhigh | max.\n args.push(\"--reasoning-effort\", context.effort);\n requires.push(\"--reasoning-effort\");\n }\n\n if (context.resume !== undefined) {\n args.push(\"--session-id\", context.resume);\n requires.push(\"--session-id\");\n }\n\n if (context.permission === \"bypass\") {\n args.push(\"--skip-permissions-unsafe\");\n requires.push(\"--skip-permissions-unsafe\");\n }\n\n if (context.mcp !== undefined) {\n const home = requirePrivateHome(context, droidAdapter, \"MCP servers\");\n\n files.push({\n path: path.join(home, \".factory\", \"mcp.json\"),\n content: jsonFile({ mcpServers: mcpServersJson(context.mcp, { typeField: true }) }),\n });\n }\n\n if (context.transport === \"file\") {\n const prompt = promptFile(context);\n\n files.push(prompt);\n tail = [\"--file\", prompt.path];\n requires.push(\"--file\");\n } else {\n tail = [argvPrompt(context.prompt)];\n }\n\n return {\n args,\n tail,\n env: {\n ...(context.home !== undefined ? { FACTORY_HOME_OVERRIDE: context.home } : {}),\n FACTORY_DROID_AUTO_UPDATE_ENABLED: \"false\",\n },\n files,\n requires,\n };\n },\n parser: createDroidParser,\n};\n\n/** Parser for `droid exec -o stream-json`. */\nexport function createDroidParser(): CliStreamParser {\n return jsonLinesParser((record): CliParsedEvent[] => {\n switch (stringField(record, \"type\")) {\n case \"system\":\n return stringField(record, \"subtype\") === \"init\"\n ? [\n {\n type: \"session.started\",\n sessionRef: stringField(record, \"session_id\"),\n model: stringField(record, \"model\"),\n raw: record,\n },\n ]\n : [];\n case \"message\": {\n const text = stringField(record, \"text\") ?? \"\";\n\n return stringField(record, \"role\") === \"assistant\" && text.length > 0\n ? [{ type: \"message\", text, delta: false, raw: record }]\n : [];\n }\n case \"tool_call\":\n return [\n {\n type: \"tool.call\",\n id: stringField(record, \"id\") ?? \"\",\n name: stringField(record, \"toolName\") ?? stringField(record, \"toolId\") ?? \"\",\n input: record.parameters,\n raw: record,\n },\n ];\n case \"tool_result\": {\n const error = recordField(record, \"error\");\n const isError = record.isError === true || error !== undefined;\n\n return [\n {\n type: \"tool.result\",\n id: stringField(record, \"id\") ?? \"\",\n output:\n isError && error !== undefined\n ? (stringField(error, \"message\") ?? \"\")\n : outputText(record.value),\n isError,\n raw: record,\n },\n ];\n }\n case \"completion\": {\n const events: CliParsedEvent[] = [];\n const usage = anthropicUsage(recordField(record, \"usage\"));\n\n if (usage !== undefined) {\n const thinking = recordField(record, \"usage\")?.thinking_tokens;\n\n if (typeof thinking === \"number\" && thinking > 0) {\n usage.reasoningTokens = thinking;\n }\n\n events.push({ type: \"usage\", usage, cumulative: true, raw: record });\n }\n\n const text = stringField(record, \"finalText\") ?? \"\";\n\n if (text.length > 0) {\n events.push({ type: \"message\", text, delta: false, final: true, raw: record });\n }\n\n return events;\n }\n case \"error\":\n return [\n {\n type: \"error\",\n message: stringField(record, \"message\") ?? \"Droid reported an error\",\n fatal: true,\n raw: record,\n },\n ];\n default:\n return [];\n }\n });\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { CliAdapter, CliStreamParser } from "../contracts/adapter.contract.mjs";
|
|
2
|
+
//#region ../../packages/ai-cli/src/adapters/grok.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Grok Build (`grok`) — xAI's official coding-agent CLI, installed by the
|
|
5
|
+
* `x.ai/cli/install.sh` script (no npm package).
|
|
6
|
+
*
|
|
7
|
+
* Verified against the docs and source only (the binary is distributed by
|
|
8
|
+
* a curl installer, which was not run): the repo user guide
|
|
9
|
+
* `crates/codegen/xai-grok-pager/docs/user-guide/{14-headless-mode,
|
|
10
|
+
* 07-mcp-servers,05-configuration,22-permissions-and-safety}.md`, the clap
|
|
11
|
+
* definitions in `xai-grok-pager/src/app/cli.rs` and the headless reducer
|
|
12
|
+
* `headless/reducer/acp.rs`, at source version 1.0.45; latest stable 1.0.62
|
|
13
|
+
* (2026-10-17). The capability probe checks every flag against the
|
|
14
|
+
* installed binary's `--help` before the first run.
|
|
15
|
+
*
|
|
16
|
+
* - Headless: `grok -p <prompt>` or `--prompt-file <path>`; piped stdin is
|
|
17
|
+
* not read. `--output-format streaming-json` prints `type`-tagged lines:
|
|
18
|
+
* `text`, `thought`, `tool_call`, `tool_call_update`, `usage` (per model
|
|
19
|
+
* response, `input_tokens` uncached) and a final `end` (session id, totals,
|
|
20
|
+
* `total_cost_usd`); failures print `{"type":"error","message"}`.
|
|
21
|
+
* - Permissions: headless mode answers every approval request with
|
|
22
|
+
* "cancelled" (auto-deny); bypass is `--always-approve`.
|
|
23
|
+
* - MCP: no flag; `[mcp_servers.<name>]` in `$GROK_HOME/config.toml`.
|
|
24
|
+
* - Auth: `XAI_API_KEY`. Update checks are disabled with
|
|
25
|
+
* `GROK_DISABLE_AUTOUPDATER=1`.
|
|
26
|
+
*/
|
|
27
|
+
declare const grokAdapter: CliAdapter;
|
|
28
|
+
/** Parser for `grok -p … --output-format streaming-json`. */
|
|
29
|
+
declare function createGrokParser(): CliStreamParser;
|
|
30
|
+
//#endregion
|
|
31
|
+
export { createGrokParser, grokAdapter };
|
|
32
|
+
//# sourceMappingURL=grok.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grok.d.mts","names":[],"sources":["../../../../../../../../packages/ai-cli/src/adapters/grok.ts"],"mappings":";;;;;AAgDA;;;;AA+EC;AAuBD;;;;AAAmD;;;;;;;;;;;;cAtGtC,WAAA,EAAa,UA+EzB;;iBAuBe,gBAAA,IAAoB,eAAe"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { jsonLinesParser, numberField, outputText, recordField, stringField } from "../stream/json-lines.mjs";
|
|
2
|
+
import { toToml } from "../utils/toml.mjs";
|
|
3
|
+
import { anthropicUsage, argvPrompt, promptFile, requirePrivateHome, unsupportedOption } from "./shared.mjs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
|
|
6
|
+
//#region ../../packages/ai-cli/src/adapters/grok.ts
|
|
7
|
+
/**
|
|
8
|
+
* Grok Build (`grok`) — xAI's official coding-agent CLI, installed by the
|
|
9
|
+
* `x.ai/cli/install.sh` script (no npm package).
|
|
10
|
+
*
|
|
11
|
+
* Verified against the docs and source only (the binary is distributed by
|
|
12
|
+
* a curl installer, which was not run): the repo user guide
|
|
13
|
+
* `crates/codegen/xai-grok-pager/docs/user-guide/{14-headless-mode,
|
|
14
|
+
* 07-mcp-servers,05-configuration,22-permissions-and-safety}.md`, the clap
|
|
15
|
+
* definitions in `xai-grok-pager/src/app/cli.rs` and the headless reducer
|
|
16
|
+
* `headless/reducer/acp.rs`, at source version 1.0.45; latest stable 1.0.62
|
|
17
|
+
* (2026-10-17). The capability probe checks every flag against the
|
|
18
|
+
* installed binary's `--help` before the first run.
|
|
19
|
+
*
|
|
20
|
+
* - Headless: `grok -p <prompt>` or `--prompt-file <path>`; piped stdin is
|
|
21
|
+
* not read. `--output-format streaming-json` prints `type`-tagged lines:
|
|
22
|
+
* `text`, `thought`, `tool_call`, `tool_call_update`, `usage` (per model
|
|
23
|
+
* response, `input_tokens` uncached) and a final `end` (session id, totals,
|
|
24
|
+
* `total_cost_usd`); failures print `{"type":"error","message"}`.
|
|
25
|
+
* - Permissions: headless mode answers every approval request with
|
|
26
|
+
* "cancelled" (auto-deny); bypass is `--always-approve`.
|
|
27
|
+
* - MCP: no flag; `[mcp_servers.<name>]` in `$GROK_HOME/config.toml`.
|
|
28
|
+
* - Auth: `XAI_API_KEY`. Update checks are disabled with
|
|
29
|
+
* `GROK_DISABLE_AUTOUPDATER=1`.
|
|
30
|
+
*/
|
|
31
|
+
const grokAdapter = {
|
|
32
|
+
name: "grok",
|
|
33
|
+
title: "Grok Build",
|
|
34
|
+
command: "grok",
|
|
35
|
+
apiKeyEnv: ["XAI_API_KEY"],
|
|
36
|
+
homeEnv: ["GROK_HOME"],
|
|
37
|
+
transports: ["argv", "file"],
|
|
38
|
+
effort: true,
|
|
39
|
+
mcp: true,
|
|
40
|
+
probe: {
|
|
41
|
+
help: [["--help"]],
|
|
42
|
+
version: ["--version"]
|
|
43
|
+
},
|
|
44
|
+
verification: {
|
|
45
|
+
version: "1.0.62",
|
|
46
|
+
verifiedBy: "docs",
|
|
47
|
+
sources: [
|
|
48
|
+
"https://docs.x.ai/build/cli/headless-scripting",
|
|
49
|
+
"https://github.com/xai-org/grok-build/blob/main/crates/codegen/xai-grok-pager/docs/user-guide/14-headless-mode.md",
|
|
50
|
+
"https://github.com/xai-org/grok-build/blob/main/crates/codegen/xai-grok-pager/docs/user-guide/07-mcp-servers.md"
|
|
51
|
+
],
|
|
52
|
+
checkedAt: "2026-10-17"
|
|
53
|
+
},
|
|
54
|
+
plan(context) {
|
|
55
|
+
const args = ["--output-format", "streaming-json"];
|
|
56
|
+
const requires = ["--output-format", "streaming-json"];
|
|
57
|
+
const files = [];
|
|
58
|
+
let tail;
|
|
59
|
+
if (context.model !== void 0) {
|
|
60
|
+
args.push("--model", context.model);
|
|
61
|
+
requires.push("--model");
|
|
62
|
+
}
|
|
63
|
+
if (context.effort !== void 0) {
|
|
64
|
+
args.push("--reasoning-effort", context.effort);
|
|
65
|
+
requires.push("--reasoning-effort");
|
|
66
|
+
}
|
|
67
|
+
if (context.resume !== void 0) {
|
|
68
|
+
args.push("--resume", context.resume);
|
|
69
|
+
requires.push("--resume");
|
|
70
|
+
}
|
|
71
|
+
if (context.permission === "bypass") {
|
|
72
|
+
args.push("--always-approve");
|
|
73
|
+
requires.push("--always-approve");
|
|
74
|
+
}
|
|
75
|
+
if (context.mcp !== void 0) {
|
|
76
|
+
const home = requirePrivateHome(context, grokAdapter, "MCP servers");
|
|
77
|
+
files.push({
|
|
78
|
+
path: path.join(home, "config.toml"),
|
|
79
|
+
content: toToml({ mcp_servers: grokMcp(context.mcp) })
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
if (context.transport === "file") {
|
|
83
|
+
const prompt = promptFile(context);
|
|
84
|
+
files.push(prompt);
|
|
85
|
+
tail = ["--prompt-file", prompt.path];
|
|
86
|
+
requires.push("--prompt-file");
|
|
87
|
+
} else {
|
|
88
|
+
tail = ["-p", argvPrompt(context.prompt)];
|
|
89
|
+
requires.push("-p");
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
args,
|
|
93
|
+
tail,
|
|
94
|
+
env: {
|
|
95
|
+
...context.home !== void 0 ? { GROK_HOME: context.home } : {},
|
|
96
|
+
GROK_DISABLE_AUTOUPDATER: "1"
|
|
97
|
+
},
|
|
98
|
+
files,
|
|
99
|
+
requires
|
|
100
|
+
};
|
|
101
|
+
},
|
|
102
|
+
parser: createGrokParser
|
|
103
|
+
};
|
|
104
|
+
function grokMcp(servers) {
|
|
105
|
+
const table = {};
|
|
106
|
+
for (const [name, server] of Object.entries(servers)) {
|
|
107
|
+
if (server.type === "sse") throw unsupportedOption(grokAdapter, `MCP server "${name}" uses SSE; Grok Build supports stdio and HTTP servers.`);
|
|
108
|
+
table[name] = server.type === "stdio" ? {
|
|
109
|
+
command: server.command,
|
|
110
|
+
args: server.args ?? [],
|
|
111
|
+
env: server.env
|
|
112
|
+
} : {
|
|
113
|
+
url: server.url,
|
|
114
|
+
headers: server.headers
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
return table;
|
|
118
|
+
}
|
|
119
|
+
/** Parser for `grok -p … --output-format streaming-json`. */
|
|
120
|
+
function createGrokParser() {
|
|
121
|
+
let started = false;
|
|
122
|
+
let sessionRef;
|
|
123
|
+
return {
|
|
124
|
+
...jsonLinesParser((record) => {
|
|
125
|
+
const events = [];
|
|
126
|
+
if (!started) {
|
|
127
|
+
started = true;
|
|
128
|
+
events.push({ type: "session.started" });
|
|
129
|
+
}
|
|
130
|
+
switch (stringField(record, "type")) {
|
|
131
|
+
case "text": {
|
|
132
|
+
const text = stringField(record, "data") ?? "";
|
|
133
|
+
if (text.length > 0) events.push({
|
|
134
|
+
type: "message",
|
|
135
|
+
text,
|
|
136
|
+
delta: true,
|
|
137
|
+
raw: record
|
|
138
|
+
});
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
case "tool_call":
|
|
142
|
+
events.push({
|
|
143
|
+
type: "tool.call",
|
|
144
|
+
id: stringField(record, "toolCallId") ?? "",
|
|
145
|
+
name: stringField(record, "toolName") ?? stringField(record, "title") ?? "",
|
|
146
|
+
input: record.rawInput,
|
|
147
|
+
raw: record
|
|
148
|
+
});
|
|
149
|
+
break;
|
|
150
|
+
case "tool_call_update": {
|
|
151
|
+
const status = stringField(record, "status");
|
|
152
|
+
if (status === "completed" || status === "failed") events.push({
|
|
153
|
+
type: "tool.result",
|
|
154
|
+
id: stringField(record, "toolCallId") ?? "",
|
|
155
|
+
output: outputText(record.rawOutput ?? record.content),
|
|
156
|
+
isError: status === "failed",
|
|
157
|
+
raw: record
|
|
158
|
+
});
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
case "usage": {
|
|
162
|
+
const usage = anthropicUsage(recordField(record, "usage"));
|
|
163
|
+
if (usage !== void 0) events.push({
|
|
164
|
+
type: "usage",
|
|
165
|
+
usage,
|
|
166
|
+
cumulative: false,
|
|
167
|
+
raw: record
|
|
168
|
+
});
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
171
|
+
case "end": {
|
|
172
|
+
sessionRef = stringField(record, "sessionId") ?? sessionRef;
|
|
173
|
+
const usage = anthropicUsage(recordField(record, "usage"), numberField(record, "total_cost_usd"));
|
|
174
|
+
if (usage !== void 0) events.push({
|
|
175
|
+
type: "usage",
|
|
176
|
+
usage,
|
|
177
|
+
cumulative: true,
|
|
178
|
+
raw: record
|
|
179
|
+
});
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
182
|
+
case "error":
|
|
183
|
+
events.push({
|
|
184
|
+
type: "error",
|
|
185
|
+
message: stringField(record, "message") ?? "Grok Build reported an error",
|
|
186
|
+
fatal: true,
|
|
187
|
+
raw: record
|
|
188
|
+
});
|
|
189
|
+
break;
|
|
190
|
+
}
|
|
191
|
+
return events;
|
|
192
|
+
}),
|
|
193
|
+
sessionRef: () => sessionRef
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
//#endregion
|
|
198
|
+
export { createGrokParser, grokAdapter };
|
|
199
|
+
//# sourceMappingURL=grok.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grok.mjs","names":[],"sources":["../../../../../../../../packages/ai-cli/src/adapters/grok.ts"],"sourcesContent":["import path from \"node:path\";\nimport type {\n CliAdapter,\n CliLaunchFile,\n CliMcpServers,\n CliParsedEvent,\n CliStreamParser,\n} from \"../contracts\";\nimport {\n jsonLinesParser,\n numberField,\n outputText,\n recordField,\n stringField,\n} from \"../stream/json-lines\";\nimport { type TomlTable, toToml } from \"../utils/toml\";\nimport {\n anthropicUsage,\n argvPrompt,\n promptFile,\n requirePrivateHome,\n unsupportedOption,\n} from \"./shared\";\n\n/**\n * Grok Build (`grok`) — xAI's official coding-agent CLI, installed by the\n * `x.ai/cli/install.sh` script (no npm package).\n *\n * Verified against the docs and source only (the binary is distributed by\n * a curl installer, which was not run): the repo user guide\n * `crates/codegen/xai-grok-pager/docs/user-guide/{14-headless-mode,\n * 07-mcp-servers,05-configuration,22-permissions-and-safety}.md`, the clap\n * definitions in `xai-grok-pager/src/app/cli.rs` and the headless reducer\n * `headless/reducer/acp.rs`, at source version 1.0.45; latest stable 1.0.62\n * (2026-10-17). The capability probe checks every flag against the\n * installed binary's `--help` before the first run.\n *\n * - Headless: `grok -p <prompt>` or `--prompt-file <path>`; piped stdin is\n * not read. `--output-format streaming-json` prints `type`-tagged lines:\n * `text`, `thought`, `tool_call`, `tool_call_update`, `usage` (per model\n * response, `input_tokens` uncached) and a final `end` (session id, totals,\n * `total_cost_usd`); failures print `{\"type\":\"error\",\"message\"}`.\n * - Permissions: headless mode answers every approval request with\n * \"cancelled\" (auto-deny); bypass is `--always-approve`.\n * - MCP: no flag; `[mcp_servers.<name>]` in `$GROK_HOME/config.toml`.\n * - Auth: `XAI_API_KEY`. Update checks are disabled with\n * `GROK_DISABLE_AUTOUPDATER=1`.\n */\nexport const grokAdapter: CliAdapter = {\n name: \"grok\",\n title: \"Grok Build\",\n command: \"grok\",\n apiKeyEnv: [\"XAI_API_KEY\"],\n homeEnv: [\"GROK_HOME\"],\n transports: [\"argv\", \"file\"],\n effort: true,\n mcp: true,\n probe: { help: [[\"--help\"]], version: [\"--version\"] },\n verification: {\n version: \"1.0.62\",\n verifiedBy: \"docs\",\n sources: [\n \"https://docs.x.ai/build/cli/headless-scripting\",\n \"https://github.com/xai-org/grok-build/blob/main/crates/codegen/xai-grok-pager/docs/user-guide/14-headless-mode.md\",\n \"https://github.com/xai-org/grok-build/blob/main/crates/codegen/xai-grok-pager/docs/user-guide/07-mcp-servers.md\",\n ],\n checkedAt: \"2026-10-17\",\n },\n plan(context) {\n const args = [\"--output-format\", \"streaming-json\"];\n const requires = [\"--output-format\", \"streaming-json\"];\n const files: CliLaunchFile[] = [];\n let tail: string[];\n\n if (context.model !== undefined) {\n args.push(\"--model\", context.model);\n requires.push(\"--model\");\n }\n\n if (context.effort !== undefined) {\n // Grok accepts the framework scale verbatim (none … max, model-dependent).\n args.push(\"--reasoning-effort\", context.effort);\n requires.push(\"--reasoning-effort\");\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(\"--always-approve\");\n requires.push(\"--always-approve\");\n }\n\n if (context.mcp !== undefined) {\n const home = requirePrivateHome(context, grokAdapter, \"MCP servers\");\n\n files.push({\n path: path.join(home, \"config.toml\"),\n content: toToml({ mcp_servers: grokMcp(context.mcp) }),\n });\n }\n\n if (context.transport === \"file\") {\n const prompt = promptFile(context);\n\n files.push(prompt);\n tail = [\"--prompt-file\", prompt.path];\n requires.push(\"--prompt-file\");\n } else {\n tail = [\"-p\", argvPrompt(context.prompt)];\n requires.push(\"-p\");\n }\n\n return {\n args,\n tail,\n env: {\n ...(context.home !== undefined ? { GROK_HOME: context.home } : {}),\n GROK_DISABLE_AUTOUPDATER: \"1\",\n },\n files,\n requires,\n };\n },\n parser: createGrokParser,\n};\n\nfunction grokMcp(servers: CliMcpServers): TomlTable {\n const table: TomlTable = {};\n\n for (const [name, server] of Object.entries(servers)) {\n if (server.type === \"sse\") {\n throw unsupportedOption(\n grokAdapter,\n `MCP server \"${name}\" uses SSE; Grok Build supports stdio and HTTP servers.`,\n );\n }\n\n table[name] =\n server.type === \"stdio\"\n ? { command: server.command, args: server.args ?? [], env: server.env }\n : { url: server.url, headers: server.headers };\n }\n\n return table;\n}\n\n/** Parser for `grok -p … --output-format streaming-json`. */\nexport function createGrokParser(): CliStreamParser {\n let started = false;\n let sessionRef: string | undefined;\n\n const parser = jsonLinesParser((record): CliParsedEvent[] => {\n const events: CliParsedEvent[] = [];\n\n if (!started) {\n started = true;\n events.push({ type: \"session.started\" });\n }\n\n switch (stringField(record, \"type\")) {\n case \"text\": {\n const text = stringField(record, \"data\") ?? \"\";\n\n if (text.length > 0) {\n events.push({ type: \"message\", text, delta: true, raw: record });\n }\n break;\n }\n case \"tool_call\":\n events.push({\n type: \"tool.call\",\n id: stringField(record, \"toolCallId\") ?? \"\",\n name: stringField(record, \"toolName\") ?? stringField(record, \"title\") ?? \"\",\n input: record.rawInput,\n raw: record,\n });\n break;\n case \"tool_call_update\": {\n const status = stringField(record, \"status\");\n\n if (status === \"completed\" || status === \"failed\") {\n events.push({\n type: \"tool.result\",\n id: stringField(record, \"toolCallId\") ?? \"\",\n output: outputText(record.rawOutput ?? record.content),\n isError: status === \"failed\",\n raw: record,\n });\n }\n break;\n }\n case \"usage\": {\n const usage = anthropicUsage(recordField(record, \"usage\"));\n\n if (usage !== undefined) {\n events.push({ type: \"usage\", usage, cumulative: false, raw: record });\n }\n break;\n }\n case \"end\": {\n sessionRef = stringField(record, \"sessionId\") ?? sessionRef;\n\n const usage = anthropicUsage(\n recordField(record, \"usage\"),\n numberField(record, \"total_cost_usd\"),\n );\n\n if (usage !== undefined) {\n events.push({ type: \"usage\", usage, cumulative: true, raw: record });\n }\n break;\n }\n case \"error\":\n events.push({\n type: \"error\",\n message: stringField(record, \"message\") ?? \"Grok Build reported an error\",\n fatal: true,\n raw: record,\n });\n break;\n }\n\n return events;\n });\n\n return { ...parser, sessionRef: () => sessionRef };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { aiderAdapter, createAiderParser, parseAiderCount } from "./aider.mjs";
|
|
2
|
+
import { ampAdapter } from "./amp.mjs";
|
|
3
|
+
import { antigravityAdapter, createAntigravityParser } from "./antigravity.mjs";
|
|
4
|
+
import { claudeCodeAdapter } from "./claude-code.mjs";
|
|
5
|
+
import { ClaudeStreamUsage, createClaudeStreamParser } from "./claude-stream.mjs";
|
|
6
|
+
import { codexAdapter, createCodexParser } from "./codex.mjs";
|
|
7
|
+
import { copilotAdapter, createCopilotParser } from "./copilot.mjs";
|
|
8
|
+
import { createCursorParser, cursorAdapter } from "./cursor.mjs";
|
|
9
|
+
import { createDroidParser, droidAdapter } from "./droid.mjs";
|
|
10
|
+
import { createGrokParser, grokAdapter } from "./grok.mjs";
|
|
11
|
+
import { createKimiParser, kimiAdapter } from "./kimi.mjs";
|
|
12
|
+
import { createVibeParser, mistralVibeAdapter } from "./mistral-vibe.mjs";
|
|
13
|
+
import { createOpencodeParser, opencodeAdapter } from "./opencode.mjs";
|
|
14
|
+
import { qwenCodeAdapter } from "./qwen-code.mjs";
|
|
15
|
+
import { createReasonixParser, reasonixAdapter } from "./reasonix.mjs";
|
|
16
|
+
import { anthropicUsage, argvPrompt, dotenvFile, jsonFile, mapEffort, mcpServersJson, parseArguments, promptFile, requirePrivateHome, unsupportedOption, usageOf } from "./shared.mjs";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { anthropicUsage, argvPrompt, dotenvFile, jsonFile, mapEffort, mcpServersJson, parseArguments, promptFile, requirePrivateHome, unsupportedOption, usageOf } from "./shared.mjs";
|
|
2
|
+
import { aiderAdapter, createAiderParser, parseAiderCount } from "./aider.mjs";
|
|
3
|
+
import { createClaudeStreamParser } from "./claude-stream.mjs";
|
|
4
|
+
import { ampAdapter } from "./amp.mjs";
|
|
5
|
+
import { antigravityAdapter, createAntigravityParser } from "./antigravity.mjs";
|
|
6
|
+
import { claudeCodeAdapter } from "./claude-code.mjs";
|
|
7
|
+
import { codexAdapter, createCodexParser } from "./codex.mjs";
|
|
8
|
+
import { copilotAdapter, createCopilotParser } from "./copilot.mjs";
|
|
9
|
+
import { createCursorParser, cursorAdapter } from "./cursor.mjs";
|
|
10
|
+
import { createDroidParser, droidAdapter } from "./droid.mjs";
|
|
11
|
+
import { createGrokParser, grokAdapter } from "./grok.mjs";
|
|
12
|
+
import { createKimiParser, kimiAdapter } from "./kimi.mjs";
|
|
13
|
+
import { createVibeParser, mistralVibeAdapter } from "./mistral-vibe.mjs";
|
|
14
|
+
import { createOpencodeParser, opencodeAdapter } from "./opencode.mjs";
|
|
15
|
+
import { qwenCodeAdapter } from "./qwen-code.mjs";
|
|
16
|
+
import { createReasonixParser, reasonixAdapter } from "./reasonix.mjs";
|
|
17
|
+
|
|
18
|
+
export { };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { CliAdapter, CliStreamParser } from "../contracts/adapter.contract.mjs";
|
|
2
|
+
//#region ../../packages/ai-cli/src/adapters/kimi.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Kimi Code CLI (`kimi`, npm `@moonshot-ai/kimi-code`) — Moonshot AI's
|
|
5
|
+
* coding agent, the successor of the archived Python `kimi-cli`.
|
|
6
|
+
*
|
|
7
|
+
* Verified against the real `kimi --help` of 2.2.0 and the docs/source at
|
|
8
|
+
* that tag (`docs/en/reference/kimi-command.md`, `apps/kimi-code/src/cli/
|
|
9
|
+
* {options.ts,prompt-render.ts,v2/run-v2-print.ts}`), 2026-10-17.
|
|
10
|
+
*
|
|
11
|
+
* - Headless: `kimi -p <prompt> --output-format stream-json`; the prompt is
|
|
12
|
+
* an argv value only (print mode never reads stdin).
|
|
13
|
+
* - Stream: OpenAI-chat-shaped messages, one per line, never deltas:
|
|
14
|
+
* `{"role":"assistant","content","tool_calls"}`, `{"role":"tool",
|
|
15
|
+
* "tool_call_id","content"}`, and `{"role":"meta","type":…}` records. The
|
|
16
|
+
* session id appears only in the final `session.resume_hint` record.
|
|
17
|
+
* No token usage is printed.
|
|
18
|
+
* - Permissions: print mode always runs in "Never Ask" mode (every tool call
|
|
19
|
+
* runs; only static deny rules apply) and rejects `--yolo`/`--plan`, so
|
|
20
|
+
* there is no standard mode to choose. The adapter refuses
|
|
21
|
+
* `permission: "standard"` instead of pretending to enforce it; pass
|
|
22
|
+
* `"bypass"` to accept the CLI's behaviour.
|
|
23
|
+
* - MCP: no flag; `$KIMI_CODE_HOME/mcp.json` (`mcpServers`), so per-run MCP
|
|
24
|
+
* needs a private home.
|
|
25
|
+
* - Auth: shell `KIMI_API_KEY`/`MOONSHOT_API_KEY` are not read. For an API
|
|
26
|
+
* key set `KIMI_MODEL_NAME` (and optionally `KIMI_MODEL_PROVIDER_TYPE`,
|
|
27
|
+
* `KIMI_MODEL_BASE_URL`) in `env`; `apiKey` becomes `KIMI_MODEL_API_KEY`.
|
|
28
|
+
*/
|
|
29
|
+
declare const kimiAdapter: CliAdapter;
|
|
30
|
+
/** Parser for `kimi -p … --output-format stream-json`. */
|
|
31
|
+
declare function createKimiParser(): CliStreamParser;
|
|
32
|
+
//#endregion
|
|
33
|
+
export { createKimiParser, kimiAdapter };
|
|
34
|
+
//# sourceMappingURL=kimi.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kimi.d.mts","names":[],"sources":["../../../../../../../../packages/ai-cli/src/adapters/kimi.ts"],"mappings":";;;;;AA4CA;;;;AAgEC;AAkBD;;;;AAAmD;;;;;;;;;;;;;;cAlFtC,WAAA,EAAa,UAgEzB;;iBAkBe,gBAAA,IAAoB,eAAe"}
|