@indigoai-us/hq-cli 5.125.0 → 5.127.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 +329 -0
- package/assets/bot-workers/setup/skills/joining-a-team.md +125 -0
- package/assets/bot-workers/setup/skills/your-business.md +270 -0
- package/assets/bot-workers/setup/worker.yaml +189 -58
- package/assets/lanes-hooks/hq-lanes-drain.json +15 -0
- package/assets/lanes-hooks/hq-lanes-drain.mjs +254 -0
- package/assets/lanes-hooks/hq-lanes-drain.sh +21 -0
- package/assets/lanes-reconcile/hq-lanes-reconcile.service +11 -0
- package/assets/lanes-reconcile/hq-lanes-reconcile.timer +12 -0
- package/dist/command-catalog.generated.d.ts +643 -6
- package/dist/command-catalog.generated.js +836 -6
- package/dist/command-registration-plan.d.ts +7 -0
- package/dist/command-registration-plan.js +11 -1
- package/dist/commands/agents.d.ts +12 -0
- package/dist/commands/agents.js +46 -2
- package/dist/commands/bot.d.ts +10 -0
- package/dist/commands/bot.js +6 -0
- package/dist/commands/lanes.d.ts +114 -0
- package/dist/commands/lanes.js +2969 -0
- package/dist/commands/mesh.js +287 -24
- package/dist/commands/onboard-create-identity.d.ts +26 -0
- package/dist/commands/onboard-create-identity.js +23 -0
- package/dist/commands/onboard.js +13 -4
- package/dist/lib/bot/progress.d.ts +6 -0
- package/dist/lib/bot/progress.js +16 -0
- package/dist/lib/bot/runtime/grok.d.ts +30 -7
- package/dist/lib/bot/runtime/grok.js +86 -8
- package/dist/lib/bot/runtime/index.js +15 -8
- package/dist/lib/bot/runtime/messages-stream.d.ts +12 -3
- package/dist/lib/bot/runtime/messages-stream.js +49 -3
- package/dist/lib/lanes/accounts.d.ts +103 -0
- package/dist/lib/lanes/accounts.js +318 -0
- package/dist/lib/lanes/compaction.d.ts +96 -0
- package/dist/lib/lanes/compaction.js +197 -0
- package/dist/lib/lanes/config.d.ts +71 -0
- package/dist/lib/lanes/config.js +408 -0
- package/dist/lib/lanes/delivery.d.ts +151 -0
- package/dist/lib/lanes/delivery.js +354 -0
- package/dist/lib/lanes/dropbox.d.ts +96 -0
- package/dist/lib/lanes/dropbox.js +408 -0
- package/dist/lib/lanes/effort.d.ts +50 -0
- package/dist/lib/lanes/effort.js +109 -0
- package/dist/lib/lanes/errors.d.ts +39 -0
- package/dist/lib/lanes/errors.js +72 -0
- package/dist/lib/lanes/hooks-install.d.ts +81 -0
- package/dist/lib/lanes/hooks-install.js +326 -0
- package/dist/lib/lanes/hq-root.d.ts +19 -0
- package/dist/lib/lanes/hq-root.js +28 -0
- package/dist/lib/lanes/index.d.ts +49 -0
- package/dist/lib/lanes/index.js +27 -0
- package/dist/lib/lanes/liveness.d.ts +95 -0
- package/dist/lib/lanes/liveness.js +332 -0
- package/dist/lib/lanes/machine-identity.d.ts +34 -0
- package/dist/lib/lanes/machine-identity.js +92 -0
- package/dist/lib/lanes/mesh-events.d.ts +109 -0
- package/dist/lib/lanes/mesh-events.js +275 -0
- package/dist/lib/lanes/outpost-dispatch.d.ts +65 -0
- package/dist/lib/lanes/outpost-dispatch.js +90 -0
- package/dist/lib/lanes/questions.d.ts +75 -0
- package/dist/lib/lanes/questions.js +243 -0
- package/dist/lib/lanes/quota.d.ts +95 -0
- package/dist/lib/lanes/quota.js +320 -0
- package/dist/lib/lanes/reconcile-install.d.ts +69 -0
- package/dist/lib/lanes/reconcile-install.js +221 -0
- package/dist/lib/lanes/reconcile.d.ts +102 -0
- package/dist/lib/lanes/reconcile.js +985 -0
- package/dist/lib/lanes/registry.d.ts +116 -0
- package/dist/lib/lanes/registry.js +521 -0
- package/dist/lib/lanes/spawn.d.ts +274 -0
- package/dist/lib/lanes/spawn.js +1363 -0
- package/dist/lib/lanes/store.d.ts +68 -0
- package/dist/lib/lanes/store.js +745 -0
- package/dist/lib/lanes/throttle.d.ts +89 -0
- package/dist/lib/lanes/throttle.js +297 -0
- package/dist/lib/lanes/types.d.ts +535 -0
- package/dist/lib/lanes/types.js +350 -0
- package/dist/lib/lanes/watcher-main.d.ts +9 -0
- package/dist/lib/lanes/watcher-main.js +22 -0
- package/dist/lib/lanes/watcher.d.ts +216 -0
- package/dist/lib/lanes/watcher.js +859 -0
- package/dist/lib/mesh/api.d.ts +71 -7
- package/dist/lib/mesh/api.js +167 -28
- package/dist/lib/mesh/live/backfill-held.d.ts +18 -7
- package/dist/lib/mesh/live/backfill-held.js +66 -21
- package/dist/lib/mesh/live/daemon/config.d.ts +27 -0
- package/dist/lib/mesh/live/daemon/config.js +75 -0
- package/dist/lib/mesh/live/daemon/index.d.ts +4 -3
- package/dist/lib/mesh/live/daemon/index.js +3 -3
- package/dist/lib/mesh/live/daemon/install.d.ts +143 -1
- package/dist/lib/mesh/live/daemon/install.js +444 -2
- package/dist/lib/mesh/live/daemon/paths.d.ts +2 -0
- package/dist/lib/mesh/live/daemon/paths.js +2 -0
- package/dist/lib/mesh/live/daemon/run.d.ts +2 -0
- package/dist/lib/mesh/live/daemon/run.js +111 -54
- package/dist/lib/mesh/live/daemon/state.d.ts +2 -0
- package/dist/lib/mesh/live/daemon/transcript-watch.d.ts +3 -0
- package/dist/lib/mesh/live/daemon/transcript-watch.js +31 -8
- package/dist/lib/scan-packages/index.d.ts +2 -0
- package/dist/lib/scan-packages/index.js +18 -13
- package/dist/lib/work-context/config.d.ts +20 -0
- package/dist/lib/work-context/config.js +26 -5
- package/dist/lib/work-context/reconcile.js +28 -7
- package/dist/lib/work-context/state.d.ts +12 -0
- package/dist/lib/work-context/state.js +131 -3
- package/dist/lib/work-context/windows-acl.d.ts +123 -0
- package/dist/lib/work-context/windows-acl.js +425 -0
- package/dist/utils/pack-contributions.js +5 -4
- package/package.json +3 -1
|
@@ -1,16 +1,39 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Grok CLI headless adapter.
|
|
3
3
|
*
|
|
4
|
-
* grok -p <prompt> --output-format streaming
|
|
4
|
+
* grok -p <prompt> --output-format <streaming format> --always-approve
|
|
5
5
|
* --no-subagents --cwd <cwd> [-m m] [-r <sessionId>]
|
|
6
6
|
*
|
|
7
|
-
* stdout is NDJSON
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
7
|
+
* stdout is NDJSON. Older grok (before 0.2.56) wrote Anthropic Messages
|
|
8
|
+
* shapes under `--output-format streaming-messages-json` (see
|
|
9
|
+
* messages-stream.ts). grok 0.2.56 dropped that value and emits token
|
|
10
|
+
* events under `streaming-json`:
|
|
11
|
+
*
|
|
12
|
+
* {"type":"thought","data":…}
|
|
13
|
+
* {"type":"text","data":"Hi"}
|
|
14
|
+
* {"type":"end","stopReason":"EndTurn","sessionId":…}
|
|
15
|
+
*
|
|
16
|
+
* The format is probed from `grok --help` once per process (and cached).
|
|
17
|
+
* If an older grok still lists `streaming-messages-json`, that is used.
|
|
18
|
+
* If the probe misses and grok rejects the old value, the turn retries
|
|
19
|
+
* with `streaming-json`. The older `{ text, sessionId }` envelope is
|
|
20
|
+
* still accepted.
|
|
12
21
|
*/
|
|
13
22
|
import { type BotRuntime, type RuntimeTurnInput } from "./types.js";
|
|
23
|
+
export declare const GROK_OUTPUT_FORMAT_LEGACY = "streaming-messages-json";
|
|
24
|
+
export declare const GROK_OUTPUT_FORMAT_STREAMING_JSON = "streaming-json";
|
|
25
|
+
export declare function resetGrokOutputFormatCache(): void;
|
|
26
|
+
/** Pick the streaming `--output-format` grok's `--help` says it accepts. */
|
|
27
|
+
export declare function grokOutputFormatFromHelp(helpText: string): string;
|
|
28
|
+
/** Probe `grok --help` once and cache the streaming format. */
|
|
29
|
+
export declare function probeGrokOutputFormat(readHelp?: () => string): string;
|
|
30
|
+
/**
|
|
31
|
+
* When grok 0.2.56 rejects the pre-0.2.56 flag, rewrite argv to
|
|
32
|
+
* `streaming-json` and remember that for later turns.
|
|
33
|
+
*/
|
|
34
|
+
export declare function grokRetryArgsAfterInvalidOutputFormat(args: string[], stderr: string): string[] | undefined;
|
|
14
35
|
export declare function grokPrompt(input: RuntimeTurnInput): string;
|
|
15
|
-
export declare function createGrokRuntime(
|
|
36
|
+
export declare function createGrokRuntime(opts?: {
|
|
37
|
+
grokHelp?: string;
|
|
38
|
+
}): BotRuntime;
|
|
16
39
|
//# sourceMappingURL=grok.d.ts.map
|
|
@@ -1,23 +1,101 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Grok CLI headless adapter.
|
|
3
3
|
*
|
|
4
|
-
* grok -p <prompt> --output-format streaming
|
|
4
|
+
* grok -p <prompt> --output-format <streaming format> --always-approve
|
|
5
5
|
* --no-subagents --cwd <cwd> [-m m] [-r <sessionId>]
|
|
6
6
|
*
|
|
7
|
-
* stdout is NDJSON
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
7
|
+
* stdout is NDJSON. Older grok (before 0.2.56) wrote Anthropic Messages
|
|
8
|
+
* shapes under `--output-format streaming-messages-json` (see
|
|
9
|
+
* messages-stream.ts). grok 0.2.56 dropped that value and emits token
|
|
10
|
+
* events under `streaming-json`:
|
|
11
|
+
*
|
|
12
|
+
* {"type":"thought","data":…}
|
|
13
|
+
* {"type":"text","data":"Hi"}
|
|
14
|
+
* {"type":"end","stopReason":"EndTurn","sessionId":…}
|
|
15
|
+
*
|
|
16
|
+
* The format is probed from `grok --help` once per process (and cached).
|
|
17
|
+
* If an older grok still lists `streaming-messages-json`, that is used.
|
|
18
|
+
* If the probe misses and grok rejects the old value, the turn retries
|
|
19
|
+
* with `streaming-json`. The older `{ text, sessionId }` envelope is
|
|
20
|
+
* still accepted.
|
|
12
21
|
*/
|
|
22
|
+
import { execFileSync } from "node:child_process";
|
|
13
23
|
import { messagesStreamEvents, messagesStreamFailure, messagesStreamResult } from "./messages-stream.js";
|
|
14
24
|
import { parseJsonLine, RuntimeError } from "./types.js";
|
|
25
|
+
export const GROK_OUTPUT_FORMAT_LEGACY = "streaming-messages-json";
|
|
26
|
+
export const GROK_OUTPUT_FORMAT_STREAMING_JSON = "streaming-json";
|
|
27
|
+
let cachedOutputFormat;
|
|
28
|
+
export function resetGrokOutputFormatCache() {
|
|
29
|
+
cachedOutputFormat = undefined;
|
|
30
|
+
}
|
|
31
|
+
/** Pick the streaming `--output-format` grok's `--help` says it accepts. */
|
|
32
|
+
export function grokOutputFormatFromHelp(helpText) {
|
|
33
|
+
const section = /--output-format\s*<OUTPUT_FORMAT>[\s\S]*?\[possible values:\s*([^\]]+)\]/i.exec(helpText);
|
|
34
|
+
const values = (section?.[1] ?? "")
|
|
35
|
+
.split(",")
|
|
36
|
+
.map((s) => s.trim())
|
|
37
|
+
.filter(Boolean);
|
|
38
|
+
if (values.includes(GROK_OUTPUT_FORMAT_LEGACY))
|
|
39
|
+
return GROK_OUTPUT_FORMAT_LEGACY;
|
|
40
|
+
if (values.includes(GROK_OUTPUT_FORMAT_STREAMING_JSON))
|
|
41
|
+
return GROK_OUTPUT_FORMAT_STREAMING_JSON;
|
|
42
|
+
if (helpText.includes(GROK_OUTPUT_FORMAT_LEGACY))
|
|
43
|
+
return GROK_OUTPUT_FORMAT_LEGACY;
|
|
44
|
+
if (/\bstreaming-json\b/.test(helpText))
|
|
45
|
+
return GROK_OUTPUT_FORMAT_STREAMING_JSON;
|
|
46
|
+
return GROK_OUTPUT_FORMAT_LEGACY;
|
|
47
|
+
}
|
|
48
|
+
function defaultGrokHelp() {
|
|
49
|
+
try {
|
|
50
|
+
return execFileSync("grok", ["--help"], {
|
|
51
|
+
encoding: "utf8",
|
|
52
|
+
timeout: 5_000,
|
|
53
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
const e = err;
|
|
58
|
+
return `${e.stdout ?? ""}\n${e.stderr ?? ""}`;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/** Probe `grok --help` once and cache the streaming format. */
|
|
62
|
+
export function probeGrokOutputFormat(readHelp = defaultGrokHelp) {
|
|
63
|
+
if (cachedOutputFormat)
|
|
64
|
+
return cachedOutputFormat;
|
|
65
|
+
let help;
|
|
66
|
+
try {
|
|
67
|
+
help = readHelp();
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
help = "";
|
|
71
|
+
}
|
|
72
|
+
cachedOutputFormat = grokOutputFormatFromHelp(help);
|
|
73
|
+
return cachedOutputFormat;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* When grok 0.2.56 rejects the pre-0.2.56 flag, rewrite argv to
|
|
77
|
+
* `streaming-json` and remember that for later turns.
|
|
78
|
+
*/
|
|
79
|
+
export function grokRetryArgsAfterInvalidOutputFormat(args, stderr) {
|
|
80
|
+
if (!/invalid value ['"]streaming-messages-json['"]/.test(stderr))
|
|
81
|
+
return undefined;
|
|
82
|
+
const i = args.indexOf("--output-format");
|
|
83
|
+
if (i < 0 || args[i + 1] === GROK_OUTPUT_FORMAT_STREAMING_JSON)
|
|
84
|
+
return undefined;
|
|
85
|
+
const next = args.slice();
|
|
86
|
+
next[i + 1] = GROK_OUTPUT_FORMAT_STREAMING_JSON;
|
|
87
|
+
cachedOutputFormat = GROK_OUTPUT_FORMAT_STREAMING_JSON;
|
|
88
|
+
return next;
|
|
89
|
+
}
|
|
15
90
|
export function grokPrompt(input) {
|
|
16
91
|
if (input.sessionId)
|
|
17
92
|
return input.prompt;
|
|
18
93
|
return `${input.systemPrompt}\n\n---\n\nMessage from your owner:\n\n${input.prompt}`;
|
|
19
94
|
}
|
|
20
|
-
export function createGrokRuntime() {
|
|
95
|
+
export function createGrokRuntime(opts = {}) {
|
|
96
|
+
const format = opts.grokHelp !== undefined
|
|
97
|
+
? grokOutputFormatFromHelp(opts.grokHelp)
|
|
98
|
+
: (cachedOutputFormat ?? GROK_OUTPUT_FORMAT_LEGACY);
|
|
21
99
|
return {
|
|
22
100
|
id: "grok",
|
|
23
101
|
binary: "grok",
|
|
@@ -26,7 +104,7 @@ export function createGrokRuntime() {
|
|
|
26
104
|
"-p",
|
|
27
105
|
grokPrompt(input),
|
|
28
106
|
"--output-format",
|
|
29
|
-
|
|
107
|
+
format,
|
|
30
108
|
"--always-approve",
|
|
31
109
|
"--no-subagents",
|
|
32
110
|
"--cwd",
|
|
@@ -5,7 +5,7 @@ import * as os from "node:os";
|
|
|
5
5
|
import * as path from "node:path";
|
|
6
6
|
import { createClaudeRuntime } from "./claude.js";
|
|
7
7
|
import { createCodexRuntime } from "./codex.js";
|
|
8
|
-
import { createGrokRuntime } from "./grok.js";
|
|
8
|
+
import { createGrokRuntime, grokRetryArgsAfterInvalidOutputFormat, probeGrokOutputFormat } from "./grok.js";
|
|
9
9
|
import { parseJsonLine, RuntimeError, turnTimeoutMs, stderrExcerpt, } from "./types.js";
|
|
10
10
|
export * from "./types.js";
|
|
11
11
|
export { createClaudeRuntime, claudePermissionMode } from "./claude.js";
|
|
@@ -16,6 +16,7 @@ export function runtimeFor(id, env = process.env) {
|
|
|
16
16
|
return createClaudeRuntime(env);
|
|
17
17
|
if (id === "codex")
|
|
18
18
|
return createCodexRuntime();
|
|
19
|
+
probeGrokOutputFormat();
|
|
19
20
|
return createGrokRuntime();
|
|
20
21
|
}
|
|
21
22
|
/**
|
|
@@ -220,15 +221,21 @@ export async function runRuntimeTurn(runtime, input, deps = {}) {
|
|
|
220
221
|
}
|
|
221
222
|
: undefined;
|
|
222
223
|
const timeoutMs = deps.timeoutMs ?? turnTimeoutMs(env);
|
|
224
|
+
const spawnOptions = {
|
|
225
|
+
cwd: input.cwd,
|
|
226
|
+
env,
|
|
227
|
+
...(timeoutMs !== undefined ? { timeoutMs } : {}),
|
|
228
|
+
...(onStdoutLine ? { onStdoutLine } : {}),
|
|
229
|
+
...(input.signal ? { signal: input.signal } : {}),
|
|
230
|
+
};
|
|
223
231
|
let result;
|
|
224
232
|
try {
|
|
225
|
-
result = await spawnImpl(binary, args,
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
});
|
|
233
|
+
result = await spawnImpl(binary, args, spawnOptions);
|
|
234
|
+
if (runtime.id === "grok" && result.code !== 0 && !input.signal?.aborted) {
|
|
235
|
+
const retryArgs = grokRetryArgsAfterInvalidOutputFormat(args, result.stderr);
|
|
236
|
+
if (retryArgs)
|
|
237
|
+
result = await spawnImpl(binary, retryArgs, spawnOptions);
|
|
238
|
+
}
|
|
232
239
|
}
|
|
233
240
|
catch (err) {
|
|
234
241
|
const code = err.code;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The NDJSON stream Claude Code (`--output-format stream-json --verbose`) and
|
|
3
|
-
* Grok (`--output-format streaming-messages-json`) both write: Anthropic
|
|
3
|
+
* older Grok (`--output-format streaming-messages-json`) both write: Anthropic
|
|
4
4
|
* Messages wire shapes, one event per line.
|
|
5
5
|
*
|
|
6
6
|
* {"type":"system","subtype":"init","session_id":…}
|
|
@@ -9,9 +9,18 @@
|
|
|
9
9
|
* {"type":"user","message":{"content":[{"type":"tool_result",…}]}}
|
|
10
10
|
* {"type":"result","subtype":"success","is_error":false,"result":"<last message>","session_id":…}
|
|
11
11
|
*
|
|
12
|
-
*
|
|
12
|
+
* grok 0.2.56 dropped `streaming-messages-json` for `streaming-json`, which
|
|
13
|
+
* is token deltas rather than whole messages:
|
|
14
|
+
*
|
|
15
|
+
* {"type":"thought","data":…}
|
|
16
|
+
* {"type":"text","data":"Hi"}
|
|
17
|
+
* {"type":"end","stopReason":"EndTurn","sessionId":…}
|
|
18
|
+
*
|
|
19
|
+
* Text `data` chunks are concatenated for the final reply and never emitted
|
|
20
|
+
* as progress (they are token deltas). Recorded from Claude Code 2.1.258 and
|
|
21
|
+
* grok (model grok-4.6) on 2026-09-12, plus grok 0.2.56 on 2026-09-21;
|
|
13
22
|
* fixtures in runtime/fixtures/. Claude sends one content block per assistant
|
|
14
|
-
* event; Grok sends a whole message (thinking + text + tool_use) per event.
|
|
23
|
+
* event; older Grok sends a whole message (thinking + text + tool_use) per event.
|
|
15
24
|
*/
|
|
16
25
|
import { type RuntimeStreamEvent, type RuntimeTurnResult } from "./types.js";
|
|
17
26
|
/** Progress events in one stream line: top-level assistant text and tool starts only. */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The NDJSON stream Claude Code (`--output-format stream-json --verbose`) and
|
|
3
|
-
* Grok (`--output-format streaming-messages-json`) both write: Anthropic
|
|
3
|
+
* older Grok (`--output-format streaming-messages-json`) both write: Anthropic
|
|
4
4
|
* Messages wire shapes, one event per line.
|
|
5
5
|
*
|
|
6
6
|
* {"type":"system","subtype":"init","session_id":…}
|
|
@@ -9,9 +9,18 @@
|
|
|
9
9
|
* {"type":"user","message":{"content":[{"type":"tool_result",…}]}}
|
|
10
10
|
* {"type":"result","subtype":"success","is_error":false,"result":"<last message>","session_id":…}
|
|
11
11
|
*
|
|
12
|
-
*
|
|
12
|
+
* grok 0.2.56 dropped `streaming-messages-json` for `streaming-json`, which
|
|
13
|
+
* is token deltas rather than whole messages:
|
|
14
|
+
*
|
|
15
|
+
* {"type":"thought","data":…}
|
|
16
|
+
* {"type":"text","data":"Hi"}
|
|
17
|
+
* {"type":"end","stopReason":"EndTurn","sessionId":…}
|
|
18
|
+
*
|
|
19
|
+
* Text `data` chunks are concatenated for the final reply and never emitted
|
|
20
|
+
* as progress (they are token deltas). Recorded from Claude Code 2.1.258 and
|
|
21
|
+
* grok (model grok-4.6) on 2026-09-12, plus grok 0.2.56 on 2026-09-21;
|
|
13
22
|
* fixtures in runtime/fixtures/. Claude sends one content block per assistant
|
|
14
|
-
* event; Grok sends a whole message (thinking + text + tool_use) per event.
|
|
23
|
+
* event; older Grok sends a whole message (thinking + text + tool_use) per event.
|
|
15
24
|
*/
|
|
16
25
|
import { parseJsonLine, RuntimeError } from "./types.js";
|
|
17
26
|
/** Progress events in one stream line: top-level assistant text and tool starts only. */
|
|
@@ -48,6 +57,9 @@ export function messagesStreamEvents(line) {
|
|
|
48
57
|
* RuntimeError for an error result, or when there is nothing usable.
|
|
49
58
|
*/
|
|
50
59
|
export function messagesStreamResult(stdout, runtimeName) {
|
|
60
|
+
const token = grokTokenStreamResult(stdout, runtimeName);
|
|
61
|
+
if (token)
|
|
62
|
+
return token;
|
|
51
63
|
let result = null;
|
|
52
64
|
let sessionId;
|
|
53
65
|
let lastText;
|
|
@@ -78,6 +90,38 @@ export function messagesStreamResult(stdout, runtimeName) {
|
|
|
78
90
|
sessionId = result.session_id;
|
|
79
91
|
return { text, sessionId };
|
|
80
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* grok 0.2.56 `--output-format streaming-json`: concatenate text deltas and
|
|
95
|
+
* take sessionId from the terminal `end` event. Throws on `error`. Null when
|
|
96
|
+
* the stream is not this shape (so the Anthropic Messages parser can run).
|
|
97
|
+
*/
|
|
98
|
+
function grokTokenStreamResult(stdout, runtimeName) {
|
|
99
|
+
let text = "";
|
|
100
|
+
let sessionId;
|
|
101
|
+
let saw = false;
|
|
102
|
+
for (const line of stdout.split("\n")) {
|
|
103
|
+
const ev = parseJsonLine(line);
|
|
104
|
+
if (!ev)
|
|
105
|
+
continue;
|
|
106
|
+
if (ev.type === "text" && typeof ev.data === "string") {
|
|
107
|
+
saw = true;
|
|
108
|
+
text += ev.data;
|
|
109
|
+
}
|
|
110
|
+
else if (ev.type === "thought") {
|
|
111
|
+
saw = true;
|
|
112
|
+
}
|
|
113
|
+
else if (ev.type === "end") {
|
|
114
|
+
saw = true;
|
|
115
|
+
if (typeof ev.sessionId === "string")
|
|
116
|
+
sessionId = ev.sessionId;
|
|
117
|
+
}
|
|
118
|
+
else if (ev.type === "error" && typeof ev.message === "string") {
|
|
119
|
+
const detail = ev.message;
|
|
120
|
+
throw new RuntimeError(`${runtimeName} reported an error: ${detail.slice(0, 200)}`, detail.slice(0, 400), null);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return saw ? { text, sessionId } : null;
|
|
124
|
+
}
|
|
81
125
|
/** The error text of an `is_error` result event, if the stream has one. */
|
|
82
126
|
export function messagesStreamFailure(stdout) {
|
|
83
127
|
let reason;
|
|
@@ -85,6 +129,8 @@ export function messagesStreamFailure(stdout) {
|
|
|
85
129
|
const ev = parseJsonLine(line);
|
|
86
130
|
if (ev?.type === "result" && ev.is_error === true && typeof ev.result === "string" && ev.result.trim())
|
|
87
131
|
reason = ev.result.trim();
|
|
132
|
+
if (ev?.type === "error" && typeof ev.message === "string" && ev.message.trim())
|
|
133
|
+
reason = ev.message.trim();
|
|
88
134
|
}
|
|
89
135
|
return reason;
|
|
90
136
|
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider account resolution (spec §5.5).
|
|
3
|
+
*
|
|
4
|
+
* Naming an account and omitting one mean different things: an explicit
|
|
5
|
+
* disabled id is refused; omitting picks the least-loaded eligible account.
|
|
6
|
+
* Status reports `configured` and `logged_in` separately. logged_in is
|
|
7
|
+
* derived from whether a provider credential file EXISTS — this module
|
|
8
|
+
* never reads, prints, copies, or hashes that file.
|
|
9
|
+
*/
|
|
10
|
+
import { type LaneRecord, type LaneProvider } from "./types.js";
|
|
11
|
+
import type { LanesConfig } from "./types.js";
|
|
12
|
+
export declare const PROVIDER_HOME_ENV: Record<LaneProvider, string>;
|
|
13
|
+
export declare const AUTH_JSON_NAME = "auth.json";
|
|
14
|
+
export declare const CLAUDE_CREDENTIALS_NAME = ".credentials.json";
|
|
15
|
+
/**
|
|
16
|
+
* Credential filenames are a property of the provider. Codex and Grok write
|
|
17
|
+
* auth.json. Claude Code writes .credentials.json (never auth.json) inside
|
|
18
|
+
* the config dir, and can also authenticate via the OS keychain with no
|
|
19
|
+
* file here at all.
|
|
20
|
+
*/
|
|
21
|
+
export declare const PROVIDER_CREDENTIAL_FILES: Record<LaneProvider, readonly string[]>;
|
|
22
|
+
export type AuthState = "file" | "absent" | "unknown";
|
|
23
|
+
export interface AccountDeps {
|
|
24
|
+
existsSync: (p: string) => boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface AccountResolveContext {
|
|
27
|
+
hqRoot?: string;
|
|
28
|
+
existsSync?: (p: string) => boolean;
|
|
29
|
+
loadLanes?: (hqRoot: string) => LaneRecord[];
|
|
30
|
+
/** Already-resolved model for this lane. Beats cliModel and account defaults. */
|
|
31
|
+
model?: string;
|
|
32
|
+
/** `--model` from create, applied to every candidate account. */
|
|
33
|
+
cliModel?: string;
|
|
34
|
+
now?: Date;
|
|
35
|
+
}
|
|
36
|
+
export interface ResolvedAccount {
|
|
37
|
+
provider: LaneProvider;
|
|
38
|
+
id: string;
|
|
39
|
+
home: string;
|
|
40
|
+
enabled: true;
|
|
41
|
+
envVar: string;
|
|
42
|
+
}
|
|
43
|
+
export interface AccountStatus {
|
|
44
|
+
provider: LaneProvider;
|
|
45
|
+
id: string;
|
|
46
|
+
home: string;
|
|
47
|
+
enabled: boolean;
|
|
48
|
+
disabled_reason?: string;
|
|
49
|
+
/** Present in personal/lanes/config.json. */
|
|
50
|
+
configured: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* True when a provider credential file exists. False only when every
|
|
53
|
+
* candidate is absent AND absence is conclusive for that provider
|
|
54
|
+
* (Codex, Grok). Null for Claude when no candidate exists: Claude can
|
|
55
|
+
* authenticate via keychain, so a missing file is not logged-out.
|
|
56
|
+
* Never inspects file contents.
|
|
57
|
+
*/
|
|
58
|
+
logged_in: boolean | null;
|
|
59
|
+
auth_state: AuthState;
|
|
60
|
+
envVar: string;
|
|
61
|
+
}
|
|
62
|
+
export declare function credentialPaths(provider: LaneProvider, home: string): string[];
|
|
63
|
+
/**
|
|
64
|
+
* Existence-only probe. Callers must not read the files this returns paths to.
|
|
65
|
+
*/
|
|
66
|
+
export declare function hasCredentialFile(provider: LaneProvider, home: string, existsSync: (p: string) => boolean): boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Claude with no file in the config dir is unknown, not logged out: the
|
|
69
|
+
* credential may live in the OS keychain or an API-key helper. Codex and
|
|
70
|
+
* Grok write auth.json when logged in, so absence is logged out.
|
|
71
|
+
*/
|
|
72
|
+
export declare function authStateFor(provider: LaneProvider, present: boolean): AuthState;
|
|
73
|
+
export declare function loggedInFromAuthState(state: AuthState): boolean | null;
|
|
74
|
+
/** Admission and listing share this: refuse only a conclusive logged-out. */
|
|
75
|
+
export declare function isLoggedOut(status: Pick<AccountStatus, "logged_in">): boolean;
|
|
76
|
+
/** Auto-select requires a proven credential file, not Claude-unknown. */
|
|
77
|
+
export declare function isCredentialProven(status: Pick<AccountStatus, "logged_in">): boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Occupying states hold a slot: running / awaiting_input / blocked have a
|
|
80
|
+
* live (or paused-live) worker; queued holds a queue slot that will take a
|
|
81
|
+
* running slot. Terminal states do not count.
|
|
82
|
+
*/
|
|
83
|
+
export declare function isOccupyingLaneState(state: LaneRecord["state"]): boolean;
|
|
84
|
+
export declare function occupyingLaneCount(lanes: readonly LaneRecord[], provider: LaneProvider, accountId: string): number;
|
|
85
|
+
export declare function runningLaneCount(lanes: readonly LaneRecord[], provider: LaneProvider, accountId: string): number;
|
|
86
|
+
/** Most recent created_at on this account+provider, any state. Null if none. */
|
|
87
|
+
export declare function lastStartedAt(lanes: readonly LaneRecord[], provider: LaneProvider, accountId: string): string | null;
|
|
88
|
+
/**
|
|
89
|
+
* Pick among enabled, credential-proven accounts by occupying count
|
|
90
|
+
* (lowest wins). Ties break to least-recently-started (oldest created_at),
|
|
91
|
+
* then account id ascending. Accounts at max_running are excluded from
|
|
92
|
+
* start-eligible; if every proven account is at cap the pick still returns
|
|
93
|
+
* one so admission can queue rather than overflow.
|
|
94
|
+
*/
|
|
95
|
+
export declare function selectBalancedAccount(provider: LaneProvider, config: LanesConfig, ctx?: AccountResolveContext): ResolvedAccount;
|
|
96
|
+
export declare function resolveAccount(provider: LaneProvider, requestedId: string | undefined, config: LanesConfig, ctx?: AccountResolveContext): ResolvedAccount;
|
|
97
|
+
/** Codex/Grok path. Kept for callers that still name auth.json. */
|
|
98
|
+
export declare function authJsonPath(home: string): string;
|
|
99
|
+
export declare function accountStatus(provider: LaneProvider, accountId: string, config: LanesConfig, deps?: AccountDeps): AccountStatus;
|
|
100
|
+
export declare function listAccountStatuses(provider: LaneProvider, config: LanesConfig, deps?: AccountDeps): AccountStatus[];
|
|
101
|
+
/** Environment assignment the worker process should receive. */
|
|
102
|
+
export declare function accountEnv(resolved: ResolvedAccount): Record<string, string>;
|
|
103
|
+
//# sourceMappingURL=accounts.d.ts.map
|