CLI
Headless 与脚本
Headless 模式
将 headless 模式用于脚本、bot 或其他机器友好型任务。
grok -p "Your prompt here"常用 flags:
| Flag | 作用 |
|---|---|
-p, --single <PROMPT> | 发送一个 prompt |
-m, --model <MODEL> | 选择模型 |
-s, --session-id <ID> | 创建或恢复命名的 headless session |
-r, --resume <ID> | 恢复现有 session |
-c, --continue | 继续当前目录最近的 session |
--cwd <PATH> | 设置工作目录 |
--output-format <FMT> | 选择 plain、json 或 streaming-json |
--always-approve | 自动批准工具执行 |
--no-alt-screen | 内联运行(不使用 alternate screen / fullscreen TUI) |
Sessions: Headless sessions(通过 --session-id、--resume、--continue)存储在 ~/.grok/sessions 中。
在 xai-grok-shell 中禁止更新: 在脚本、CI 或其他自动化环境中使用 headless 模式(-p)或 ACP(grok agent stdio)时,传递 --no-auto-update(例如 grok --no-auto-update -p "...")以跳过后台更新检查。也可以设置 auto_update = false,将其放在 [cli] section 下,该 section 位于 ~/.grok/config.toml,以永久禁用更新。
输出格式
plain:人类可读文本json:结束时输出一个 JSON objectstreaming-json:以 newline 分隔的 JSON events
grok -p "List TODO comments" --output-format json
grok -p "Explain the architecture" --output-format streaming-jsonStreaming JSON 会在 event 到达时增量输出。
ACP
需要 IDE 或 tool integration 而不是 terminal session 时,请使用 ACP。
grok agent stdio该命令通过 stdin/stdout 上的 JSON-RPC 将 Grok 作为 ACP agent 运行。下面的示例假定 grok 已在本地完成身份验证,或已设置 XAI_API_KEY。session/prompt 返回 completion metadata;assistant 文本本身以 session/update chunks 到达。
import { spawn } from "node:child_process";
import readline from "node:readline";
import process from "node:process";
const proc = spawn("grok", ["agent", "stdio"], { stdio: ["pipe", "pipe", "pipe"] });
const rl = readline.createInterface({ input: proc.stdout });
const pending = new Map();
let nextId = 1;
let text = "";
proc.stderr.on("data", chunk => process.stderr.write(chunk));
rl.on("line", line => {
const message = JSON.parse(line);
if (message.method === "session/update") {
const update = message.params?.update;
if (update?.sessionUpdate === "agent_message_chunk" && update.content?.text) {
text += update.content.text;
}
return;
}
const pendingRequest = pending.get(message.id);
if (!pendingRequest) return;
pending.delete(message.id);
if (message.error) {
pendingRequest.reject(new Error(message.error.message ?? JSON.stringify(message.error)));
} else {
pendingRequest.resolve(message.result ?? {});
}
});
function request(method, params, timeoutMs = 30000) {
const id = nextId++;
return new Promise((resolve, reject) => {
const timer = setTimeout(() => {
pending.delete(id);
reject(new Error(`${method} timed out`));
}, timeoutMs);
pending.set(id, {
resolve(result) {
clearTimeout(timer);
resolve(result);
},
reject(error) {
clearTimeout(timer);
reject(error);
},
});
proc.stdin.write(JSON.stringify({ jsonrpc: "2.0", id, method, params }) + "\n");
});
}
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
try {
const init = await request("initialize", {
protocolVersion: 1,
clientCapabilities: {
fs: { readTextFile: true, writeTextFile: true },
terminal: true,
},
});
const authMethods = new Set((init.authMethods ?? []).map(method => method.id));
const methodId =
process.env.XAI_API_KEY && authMethods.has("xai.api_key")
? "xai.api_key"
: authMethods.has("cached_token")
? "cached_token"
: null;
if (!methodId) {
throw new Error("Run `grok login` first, or set XAI_API_KEY.");
}
await request("authenticate", { methodId, _meta: { headless: true } });
const { sessionId } = await request("session/new", {
cwd: process.cwd(),
mcpServers: [],
});
const prompt = await request("session/prompt", {
sessionId,
prompt: [{ type: "text", text: "Say hello in one short sentence." }],
});
let lastLength = -1;
let stableChecks = 0;
while (stableChecks < 2) {
await sleep(150);
if (text.length === lastLength) {
stableChecks += 1;
} else {
lastLength = text.length;
stableChecks = 0;
}
}
console.log(text.trim() || `No text returned (stopReason=${prompt.stopReason})`);
} finally {
rl.close();
proc.kill();
}