@forwardimpact/libeval 0.1.9 → 0.1.11
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/bin/fit-eval.js +103 -72
- package/package.json +4 -2
- package/src/commands/output.js +7 -26
- package/src/commands/run.js +16 -41
- package/src/commands/supervise.js +19 -47
- package/src/commands/tee.js +3 -2
package/bin/fit-eval.js
CHANGED
|
@@ -1,10 +1,100 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { createCli } from "@forwardimpact/libcli";
|
|
5
|
+
import { createLogger } from "@forwardimpact/libtelemetry";
|
|
6
|
+
|
|
3
7
|
import { runOutputCommand } from "../src/commands/output.js";
|
|
4
8
|
import { runTeeCommand } from "../src/commands/tee.js";
|
|
5
9
|
import { runRunCommand } from "../src/commands/run.js";
|
|
6
10
|
import { runSuperviseCommand } from "../src/commands/supervise.js";
|
|
7
11
|
|
|
12
|
+
const { version: VERSION } = JSON.parse(
|
|
13
|
+
readFileSync(new URL("../package.json", import.meta.url), "utf8"),
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
const definition = {
|
|
17
|
+
name: "fit-eval",
|
|
18
|
+
version: VERSION,
|
|
19
|
+
description: "Process Claude Code stream-json output",
|
|
20
|
+
commands: [
|
|
21
|
+
{
|
|
22
|
+
name: "output",
|
|
23
|
+
args: "[--format=FORMAT]",
|
|
24
|
+
description: "Process trace and output formatted result",
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: "tee",
|
|
28
|
+
args: "[output.ndjson]",
|
|
29
|
+
description: "Stream text to stdout, optionally save raw NDJSON",
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: "run",
|
|
33
|
+
args: "[options]",
|
|
34
|
+
description: "Run a single agent via the Claude Agent SDK",
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: "supervise",
|
|
38
|
+
args: "[options]",
|
|
39
|
+
description: "Run a supervised agent-supervisor relay loop",
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
options: {
|
|
43
|
+
format: { type: "string", description: "Output format (json|text)" },
|
|
44
|
+
help: { type: "boolean", short: "h", description: "Show this help" },
|
|
45
|
+
version: { type: "boolean", description: "Show version" },
|
|
46
|
+
json: { type: "boolean", description: "Output help as JSON" },
|
|
47
|
+
"task-file": { type: "string", description: "Path to task file" },
|
|
48
|
+
"task-text": { type: "string", description: "Inline task text" },
|
|
49
|
+
"task-amend": {
|
|
50
|
+
type: "string",
|
|
51
|
+
description: "Additional text appended to task",
|
|
52
|
+
},
|
|
53
|
+
model: {
|
|
54
|
+
type: "string",
|
|
55
|
+
description: "Claude model (default: opus)",
|
|
56
|
+
},
|
|
57
|
+
"max-turns": {
|
|
58
|
+
type: "string",
|
|
59
|
+
description: "Max agentic turns (default: 50)",
|
|
60
|
+
},
|
|
61
|
+
output: { type: "string", description: "Write NDJSON trace to file" },
|
|
62
|
+
cwd: { type: "string", description: "Working directory" },
|
|
63
|
+
"agent-profile": {
|
|
64
|
+
type: "string",
|
|
65
|
+
description: "Agent profile name",
|
|
66
|
+
},
|
|
67
|
+
"allowed-tools": {
|
|
68
|
+
type: "string",
|
|
69
|
+
description: "Comma-separated tool list",
|
|
70
|
+
},
|
|
71
|
+
"supervisor-cwd": {
|
|
72
|
+
type: "string",
|
|
73
|
+
description: "Supervisor working directory",
|
|
74
|
+
},
|
|
75
|
+
"agent-cwd": {
|
|
76
|
+
type: "string",
|
|
77
|
+
description: "Agent working directory",
|
|
78
|
+
},
|
|
79
|
+
"supervisor-profile": {
|
|
80
|
+
type: "string",
|
|
81
|
+
description: "Supervisor profile name",
|
|
82
|
+
},
|
|
83
|
+
"supervisor-allowed-tools": {
|
|
84
|
+
type: "string",
|
|
85
|
+
description: "Supervisor tool list",
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
examples: [
|
|
89
|
+
"fit-eval output --format=text < trace.ndjson",
|
|
90
|
+
"fit-eval run --task-file=task.md --model=opus",
|
|
91
|
+
"fit-eval supervise --task-file=task.md --supervisor-cwd=.",
|
|
92
|
+
],
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const cli = createCli(definition);
|
|
96
|
+
const logger = createLogger("eval");
|
|
97
|
+
|
|
8
98
|
const COMMANDS = {
|
|
9
99
|
output: runOutputCommand,
|
|
10
100
|
tee: runTeeCommand,
|
|
@@ -12,89 +102,30 @@ const COMMANDS = {
|
|
|
12
102
|
supervise: runSuperviseCommand,
|
|
13
103
|
};
|
|
14
104
|
|
|
15
|
-
const HELP_TEXT = `
|
|
16
|
-
Eval CLI — Process Claude Code stream-json output
|
|
17
|
-
|
|
18
|
-
Usage:
|
|
19
|
-
fit-eval <command> [options]
|
|
20
|
-
|
|
21
|
-
Commands:
|
|
22
|
-
output [--format=json|text] Process trace and output formatted result
|
|
23
|
-
tee [output.ndjson] Stream text to stdout, optionally save raw NDJSON
|
|
24
|
-
run [options] Run a single agent via the Claude Agent SDK
|
|
25
|
-
supervise [options] Run a supervised agent ↔ supervisor relay loop
|
|
26
|
-
|
|
27
|
-
Run options:
|
|
28
|
-
--task-file=PATH Path to task file (mutually exclusive with --task-text)
|
|
29
|
-
--task-text=STRING Inline task text (mutually exclusive with --task-file)
|
|
30
|
-
--cwd=DIR Agent working directory (default: .)
|
|
31
|
-
--model=MODEL Claude model to use (default: opus)
|
|
32
|
-
--max-turns=N Maximum agentic turns (default: 50, 0 = unlimited)
|
|
33
|
-
--output=PATH Write NDJSON trace to file (default: stdout)
|
|
34
|
-
--allowed-tools=LIST Comma-separated tools (default: Bash,Read,Glob,Grep,Write,Edit)
|
|
35
|
-
--agent-profile=NAME Agent profile name (passed as --agent to Claude CLI)
|
|
36
|
-
|
|
37
|
-
Supervise options:
|
|
38
|
-
--task-file=PATH Path to task file (mutually exclusive with --task-text)
|
|
39
|
-
--task-text=STRING Inline task text (mutually exclusive with --task-file)
|
|
40
|
-
--supervisor-cwd=DIR Supervisor working directory (default: .)
|
|
41
|
-
--agent-cwd=DIR Agent working directory (default: temp directory)
|
|
42
|
-
--model=MODEL Claude model to use (default: opus)
|
|
43
|
-
--max-turns=N Maximum supervisor ↔ agent exchanges (default: 20, 0 = unlimited)
|
|
44
|
-
--output=PATH Write NDJSON trace to file (default: stdout)
|
|
45
|
-
--allowed-tools=LIST Comma-separated tools for agent (default: Bash,Read,Glob,Grep,Write,Edit)
|
|
46
|
-
--supervisor-allowed-tools=LIST
|
|
47
|
-
Comma-separated tools for supervisor (default: Bash,Read,Glob,Grep,Write,Edit)
|
|
48
|
-
--supervisor-profile=NAME Supervisor agent profile name (passed as --agent to Claude CLI)
|
|
49
|
-
--agent-profile=NAME Agent profile name (passed as --agent to Claude CLI)
|
|
50
|
-
|
|
51
|
-
Options:
|
|
52
|
-
--help Show this help message
|
|
53
|
-
--version Show version number
|
|
54
|
-
|
|
55
|
-
Examples:
|
|
56
|
-
fit-eval output --format=text < trace.ndjson
|
|
57
|
-
fit-eval output --format=json < trace.ndjson
|
|
58
|
-
fit-eval tee < trace.ndjson
|
|
59
|
-
fit-eval tee output.ndjson < trace.ndjson
|
|
60
|
-
fit-eval run --task-text="Perform a security audit of the repository." --model=opus
|
|
61
|
-
fit-eval run --task-file=scenarios/guide-setup/task.md --model=opus
|
|
62
|
-
fit-eval supervise --task-file=scenarios/guide-setup/task.md --supervisor-cwd=.
|
|
63
|
-
`.trim();
|
|
64
|
-
|
|
65
105
|
async function main() {
|
|
66
|
-
const
|
|
106
|
+
const parsed = cli.parse(process.argv.slice(2));
|
|
107
|
+
if (!parsed) process.exit(0);
|
|
67
108
|
|
|
68
|
-
|
|
69
|
-
console.log(HELP_TEXT);
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
109
|
+
const { values, positionals } = parsed;
|
|
72
110
|
|
|
73
|
-
if (
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const { fileURLToPath } = await import("url");
|
|
77
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
78
|
-
const pkg = JSON.parse(
|
|
79
|
-
readFileSync(join(__dirname, "..", "package.json"), "utf8"),
|
|
80
|
-
);
|
|
81
|
-
console.log(pkg.version);
|
|
82
|
-
return;
|
|
111
|
+
if (positionals.length === 0) {
|
|
112
|
+
cli.usageError("no command specified");
|
|
113
|
+
process.exit(2);
|
|
83
114
|
}
|
|
84
115
|
|
|
85
|
-
const
|
|
86
|
-
const handler = COMMANDS[
|
|
116
|
+
const [command, ...args] = positionals;
|
|
117
|
+
const handler = COMMANDS[command];
|
|
87
118
|
|
|
88
119
|
if (!handler) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
process.exit(1);
|
|
120
|
+
cli.usageError(`unknown command "${command}"`);
|
|
121
|
+
process.exit(2);
|
|
92
122
|
}
|
|
93
123
|
|
|
94
|
-
await handler(args
|
|
124
|
+
await handler(values, args);
|
|
95
125
|
}
|
|
96
126
|
|
|
97
127
|
main().catch((error) => {
|
|
98
|
-
|
|
128
|
+
logger.exception("main", error);
|
|
129
|
+
cli.error(error.message);
|
|
99
130
|
process.exit(1);
|
|
100
131
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forwardimpact/libeval",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.11",
|
|
4
4
|
"description": "Process Claude Code stream-json output into structured traces",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "D. Olsson <hi@senzilla.io>",
|
|
@@ -17,7 +17,9 @@
|
|
|
17
17
|
"test": "bun run node --test test/*.test.js"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@anthropic-ai/claude-agent-sdk": "^0.2.
|
|
20
|
+
"@anthropic-ai/claude-agent-sdk": "^0.2.98",
|
|
21
|
+
"@forwardimpact/libcli": "^0.1.0",
|
|
22
|
+
"@forwardimpact/libtelemetry": "^0.1.22"
|
|
21
23
|
},
|
|
22
24
|
"publishConfig": {
|
|
23
25
|
"access": "public"
|
package/src/commands/output.js
CHANGED
|
@@ -6,10 +6,14 @@ import { createTraceCollector } from "@forwardimpact/libeval";
|
|
|
6
6
|
*
|
|
7
7
|
* Usage: fit-eval output [--format=json|text] < trace.ndjson
|
|
8
8
|
*
|
|
9
|
-
* @param {
|
|
9
|
+
* @param {object} values - Parsed option values from cli.parse()
|
|
10
|
+
* @param {string[]} args - Positional arguments
|
|
10
11
|
*/
|
|
11
|
-
export async function runOutputCommand(
|
|
12
|
-
const format =
|
|
12
|
+
export async function runOutputCommand(values, _args) {
|
|
13
|
+
const format =
|
|
14
|
+
values.format === "text" || values.format === "json"
|
|
15
|
+
? values.format
|
|
16
|
+
: "json";
|
|
13
17
|
const collector = createTraceCollector();
|
|
14
18
|
|
|
15
19
|
const chunks = [];
|
|
@@ -28,26 +32,3 @@ export async function runOutputCommand(args) {
|
|
|
28
32
|
process.stdout.write(JSON.stringify(collector.toJSON()) + "\n");
|
|
29
33
|
}
|
|
30
34
|
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Parse --format from args. Supports --format=value and --format value.
|
|
34
|
-
* @param {string[]} args
|
|
35
|
-
* @returns {"text"|"json"}
|
|
36
|
-
*/
|
|
37
|
-
function parseFormat(args) {
|
|
38
|
-
for (let i = 0; i < args.length; i++) {
|
|
39
|
-
if (args[i].startsWith("--format=")) {
|
|
40
|
-
const value = args[i].slice("--format=".length);
|
|
41
|
-
if (value === "text" || value === "json") return value;
|
|
42
|
-
console.error(`Unknown format: ${value}. Using "json".`);
|
|
43
|
-
return "json";
|
|
44
|
-
}
|
|
45
|
-
if (args[i] === "--format" && i + 1 < args.length) {
|
|
46
|
-
const value = args[i + 1];
|
|
47
|
-
if (value === "text" || value === "json") return value;
|
|
48
|
-
console.error(`Unknown format: ${value}. Using "json".`);
|
|
49
|
-
return "json";
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
return "json";
|
|
53
|
-
}
|
package/src/commands/run.js
CHANGED
|
@@ -4,47 +4,32 @@ import { createAgentRunner } from "../agent-runner.js";
|
|
|
4
4
|
import { createTeeWriter } from "../tee-writer.js";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* Parse
|
|
8
|
-
* @param {
|
|
9
|
-
* @param {string} name - Flag name without --
|
|
10
|
-
* @returns {string|undefined}
|
|
11
|
-
*/
|
|
12
|
-
function parseFlag(args, name) {
|
|
13
|
-
const prefix = `--${name}=`;
|
|
14
|
-
for (let i = 0; i < args.length; i++) {
|
|
15
|
-
if (args[i].startsWith(prefix)) return args[i].slice(prefix.length);
|
|
16
|
-
if (args[i] === `--${name}` && i + 1 < args.length) return args[i + 1];
|
|
17
|
-
}
|
|
18
|
-
return undefined;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Parse and validate run command options from args.
|
|
23
|
-
* @param {string[]} args
|
|
7
|
+
* Parse and validate run command options from parsed values.
|
|
8
|
+
* @param {object} values - Parsed option values from cli.parse()
|
|
24
9
|
* @returns {{ taskContent: string, cwd: string, model: string, maxTurns: number, outputPath: string|undefined, agentProfile: string|undefined, allowedTools: string[] }}
|
|
25
10
|
*/
|
|
26
|
-
function parseRunOptions(
|
|
27
|
-
const taskFile =
|
|
28
|
-
const taskText =
|
|
11
|
+
function parseRunOptions(values) {
|
|
12
|
+
const taskFile = values["task-file"];
|
|
13
|
+
const taskText = values["task-text"];
|
|
29
14
|
if (taskFile && taskText)
|
|
30
15
|
throw new Error("--task-file and --task-text are mutually exclusive");
|
|
31
16
|
if (!taskFile && !taskText)
|
|
32
17
|
throw new Error("--task-file or --task-text is required");
|
|
33
18
|
|
|
34
|
-
const maxTurnsRaw =
|
|
35
|
-
const taskAmend =
|
|
19
|
+
const maxTurnsRaw = values["max-turns"] ?? "50";
|
|
20
|
+
const taskAmend = values["task-amend"] ?? undefined;
|
|
36
21
|
let taskContent = taskFile ? readFileSync(taskFile, "utf8") : taskText;
|
|
37
22
|
if (taskAmend) taskContent += `\n\n${taskAmend}`;
|
|
38
23
|
|
|
39
24
|
return {
|
|
40
25
|
taskContent,
|
|
41
|
-
cwd: resolve(
|
|
42
|
-
model:
|
|
26
|
+
cwd: resolve(values.cwd ?? "."),
|
|
27
|
+
model: values.model ?? "opus",
|
|
43
28
|
maxTurns: maxTurnsRaw === "0" ? 0 : parseInt(maxTurnsRaw, 10),
|
|
44
|
-
outputPath:
|
|
45
|
-
agentProfile:
|
|
29
|
+
outputPath: values.output,
|
|
30
|
+
agentProfile: values["agent-profile"] ?? undefined,
|
|
46
31
|
allowedTools: (
|
|
47
|
-
|
|
32
|
+
values["allowed-tools"] ??
|
|
48
33
|
"Bash,Read,Glob,Grep,Write,Edit,Agent,TodoWrite"
|
|
49
34
|
).split(","),
|
|
50
35
|
};
|
|
@@ -55,20 +40,10 @@ function parseRunOptions(args) {
|
|
|
55
40
|
*
|
|
56
41
|
* Usage: fit-eval run [options]
|
|
57
42
|
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
* --task-text=STRING Inline task text (mutually exclusive with --task-file)
|
|
61
|
-
* --cwd=DIR Agent working directory (default: .)
|
|
62
|
-
* --model=MODEL Claude model to use (default: opus)
|
|
63
|
-
* --max-turns=N Maximum agentic turns (default: 50, 0 = unlimited)
|
|
64
|
-
* --output=PATH Write NDJSON trace to file (default: stdout)
|
|
65
|
-
* --allowed-tools=LIST Comma-separated tools (default: Bash,Read,Glob,Grep,Write,Edit)
|
|
66
|
-
* --agent-profile=NAME Agent profile name (passed as --agent to Claude CLI)
|
|
67
|
-
* --task-amend=TEXT Additional text appended to the task prompt
|
|
68
|
-
*
|
|
69
|
-
* @param {string[]} args - Command arguments
|
|
43
|
+
* @param {object} values - Parsed option values from cli.parse()
|
|
44
|
+
* @param {string[]} args - Positional arguments
|
|
70
45
|
*/
|
|
71
|
-
export async function runRunCommand(
|
|
46
|
+
export async function runRunCommand(values, _args) {
|
|
72
47
|
const {
|
|
73
48
|
taskContent,
|
|
74
49
|
cwd,
|
|
@@ -77,7 +52,7 @@ export async function runRunCommand(args) {
|
|
|
77
52
|
outputPath,
|
|
78
53
|
agentProfile,
|
|
79
54
|
allowedTools,
|
|
80
|
-
} = parseRunOptions(
|
|
55
|
+
} = parseRunOptions(values);
|
|
81
56
|
|
|
82
57
|
// When --output is specified, stream text to stdout while writing NDJSON to file.
|
|
83
58
|
// Otherwise, write NDJSON directly to stdout (backwards-compatible).
|
|
@@ -5,56 +5,40 @@ import { createSupervisor } from "../supervisor.js";
|
|
|
5
5
|
import { createTeeWriter } from "../tee-writer.js";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* Parse
|
|
9
|
-
* @param {
|
|
10
|
-
* @param {string} name - Flag name without --
|
|
11
|
-
* @returns {string|undefined}
|
|
12
|
-
*/
|
|
13
|
-
function parseFlag(args, name) {
|
|
14
|
-
const prefix = `--${name}=`;
|
|
15
|
-
for (let i = 0; i < args.length; i++) {
|
|
16
|
-
if (args[i].startsWith(prefix)) return args[i].slice(prefix.length);
|
|
17
|
-
if (args[i] === `--${name}` && i + 1 < args.length) return args[i + 1];
|
|
18
|
-
}
|
|
19
|
-
return undefined;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Parse all supervise flags from args into an options object.
|
|
24
|
-
* @param {string[]} args
|
|
8
|
+
* Parse all supervise flags from parsed values into an options object.
|
|
9
|
+
* @param {object} values - Parsed option values from cli.parse()
|
|
25
10
|
* @returns {object}
|
|
26
11
|
*/
|
|
27
|
-
function parseSuperviseOptions(
|
|
28
|
-
const taskFile =
|
|
29
|
-
const taskText =
|
|
12
|
+
function parseSuperviseOptions(values) {
|
|
13
|
+
const taskFile = values["task-file"];
|
|
14
|
+
const taskText = values["task-text"];
|
|
30
15
|
if (taskFile && taskText)
|
|
31
16
|
throw new Error("--task-file and --task-text are mutually exclusive");
|
|
32
17
|
if (!taskFile && !taskText)
|
|
33
18
|
throw new Error("--task-file or --task-text is required");
|
|
34
19
|
|
|
35
|
-
const supervisorAllowedToolsRaw =
|
|
20
|
+
const supervisorAllowedToolsRaw = values["supervisor-allowed-tools"];
|
|
36
21
|
|
|
37
|
-
const taskAmend =
|
|
22
|
+
const taskAmend = values["task-amend"] ?? undefined;
|
|
38
23
|
let taskContent = taskFile ? readFileSync(taskFile, "utf8") : taskText;
|
|
39
24
|
if (taskAmend) taskContent += `\n\n${taskAmend}`;
|
|
40
25
|
|
|
41
26
|
return {
|
|
42
27
|
taskContent,
|
|
43
|
-
supervisorCwd: resolve(
|
|
28
|
+
supervisorCwd: resolve(values["supervisor-cwd"] ?? "."),
|
|
44
29
|
agentCwd: resolve(
|
|
45
|
-
|
|
46
|
-
mkdtempSync(join(tmpdir(), "fit-eval-agent-")),
|
|
30
|
+
values["agent-cwd"] ?? mkdtempSync(join(tmpdir(), "fit-eval-agent-")),
|
|
47
31
|
),
|
|
48
|
-
model:
|
|
32
|
+
model: values.model ?? "opus",
|
|
49
33
|
maxTurns: (() => {
|
|
50
|
-
const raw =
|
|
34
|
+
const raw = values["max-turns"] ?? "20";
|
|
51
35
|
return raw === "0" ? 0 : parseInt(raw, 10);
|
|
52
36
|
})(),
|
|
53
|
-
outputPath:
|
|
54
|
-
supervisorProfile:
|
|
55
|
-
agentProfile:
|
|
37
|
+
outputPath: values.output,
|
|
38
|
+
supervisorProfile: values["supervisor-profile"] ?? undefined,
|
|
39
|
+
agentProfile: values["agent-profile"] ?? undefined,
|
|
56
40
|
allowedTools: (
|
|
57
|
-
|
|
41
|
+
values["allowed-tools"] ??
|
|
58
42
|
"Bash,Read,Glob,Grep,Write,Edit,Agent,TodoWrite"
|
|
59
43
|
).split(","),
|
|
60
44
|
supervisorAllowedTools: supervisorAllowedToolsRaw
|
|
@@ -68,23 +52,11 @@ function parseSuperviseOptions(args) {
|
|
|
68
52
|
*
|
|
69
53
|
* Usage: fit-eval supervise [options]
|
|
70
54
|
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* --task-text=STRING Inline task text (mutually exclusive with --task-file)
|
|
74
|
-
* --supervisor-cwd=DIR Supervisor working directory (default: .)
|
|
75
|
-
* --agent-cwd=DIR Agent working directory (default: temp directory)
|
|
76
|
-
* --model=MODEL Claude model to use (default: opus)
|
|
77
|
-
* --max-turns=N Maximum supervisor / agent exchanges (default: 20, 0 = unlimited)
|
|
78
|
-
* --output=PATH Write NDJSON trace to file (default: stdout)
|
|
79
|
-
* --allowed-tools=LIST Comma-separated tools for the agent (default: Bash,Read,Glob,Grep,Write,Edit)
|
|
80
|
-
* --supervisor-profile=NAME Supervisor agent profile name (passed as --agent to Claude CLI)
|
|
81
|
-
* --agent-profile=NAME Agent profile name (passed as --agent to Claude CLI)
|
|
82
|
-
* --task-amend=TEXT Additional text appended to the task prompt
|
|
83
|
-
*
|
|
84
|
-
* @param {string[]} args - Command arguments
|
|
55
|
+
* @param {object} values - Parsed option values from cli.parse()
|
|
56
|
+
* @param {string[]} args - Positional arguments
|
|
85
57
|
*/
|
|
86
|
-
export async function runSuperviseCommand(
|
|
87
|
-
const opts = parseSuperviseOptions(
|
|
58
|
+
export async function runSuperviseCommand(values, _args) {
|
|
59
|
+
const opts = parseSuperviseOptions(values);
|
|
88
60
|
|
|
89
61
|
// When --output is specified, stream text to stdout while writing NDJSON to file.
|
|
90
62
|
// Otherwise, write NDJSON directly to stdout (backwards-compatible).
|
package/src/commands/tee.js
CHANGED
|
@@ -9,9 +9,10 @@ import { createTeeWriter } from "../tee-writer.js";
|
|
|
9
9
|
*
|
|
10
10
|
* Usage: fit-eval tee [output.ndjson] < trace.ndjson
|
|
11
11
|
*
|
|
12
|
-
* @param {
|
|
12
|
+
* @param {object} values - Parsed option values from cli.parse()
|
|
13
|
+
* @param {string[]} args - Positional arguments (optional output file path)
|
|
13
14
|
*/
|
|
14
|
-
export async function runTeeCommand(args) {
|
|
15
|
+
export async function runTeeCommand(values, args) {
|
|
15
16
|
const outputPath = args.find((a) => !a.startsWith("-")) ?? null;
|
|
16
17
|
const fileStream = outputPath ? createWriteStream(outputPath) : null;
|
|
17
18
|
|