automata-cli 0.1.0-008-test-command.60 → 0.1.0-008-test-command.64
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/dist/index.js +140 -16
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -935,7 +935,8 @@ function postComment(issueNumber, body) {
|
|
|
935
935
|
}
|
|
936
936
|
|
|
937
937
|
// src/claude/claudeService.ts
|
|
938
|
-
import { spawnSync as spawnSync4 } from "child_process";
|
|
938
|
+
import { spawn, spawnSync as spawnSync4 } from "child_process";
|
|
939
|
+
import { createInterface } from "readline";
|
|
939
940
|
import { existsSync } from "fs";
|
|
940
941
|
import { delimiter, join as join2 } from "path";
|
|
941
942
|
function resolveCommand(name) {
|
|
@@ -946,29 +947,150 @@ function resolveCommand(name) {
|
|
|
946
947
|
}
|
|
947
948
|
return name;
|
|
948
949
|
}
|
|
949
|
-
|
|
950
|
+
var MODEL_IDS = {
|
|
951
|
+
opus: "claude-opus-4-6",
|
|
952
|
+
sonnet: "claude-sonnet-4-6",
|
|
953
|
+
haiku: "claude-haiku-4-5-20251001"
|
|
954
|
+
};
|
|
955
|
+
function resolveModelOption(opts) {
|
|
956
|
+
const selected = ["opus", "sonnet", "haiku"].filter((m) => opts[m]);
|
|
957
|
+
if (selected.length > 1) {
|
|
958
|
+
process.stderr.write(`Error: --${selected[0]} and --${selected[1]} are mutually exclusive.
|
|
959
|
+
`);
|
|
960
|
+
process.exit(1);
|
|
961
|
+
}
|
|
962
|
+
return selected.length === 1 ? MODEL_IDS[selected[0]] : void 0;
|
|
963
|
+
}
|
|
964
|
+
function invokeClaudeCode(prompt, options = {}) {
|
|
965
|
+
if (options.verbose) {
|
|
966
|
+
return invokeClaudeCodeVerbose(prompt, options.yolo ?? false, options.model);
|
|
967
|
+
}
|
|
968
|
+
invokeClaudeCodeSync(prompt, options.yolo ?? false, options.model);
|
|
969
|
+
}
|
|
970
|
+
function invokeClaudeCodeSync(prompt, yolo, model) {
|
|
950
971
|
const claudeBin = resolveCommand("claude");
|
|
951
|
-
const args =
|
|
972
|
+
const args = [];
|
|
973
|
+
if (yolo) args.push("--dangerously-skip-permissions");
|
|
974
|
+
if (model) args.push("--model", model);
|
|
975
|
+
args.push("-p", prompt);
|
|
952
976
|
const result = spawnSync4(claudeBin, args, { encoding: "utf8", stdio: "inherit" });
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
977
|
+
handleSpawnError(result.error);
|
|
978
|
+
handleExitCode(result.status);
|
|
979
|
+
}
|
|
980
|
+
function invokeClaudeCodeVerbose(prompt, yolo, model) {
|
|
981
|
+
return new Promise((resolve2) => {
|
|
982
|
+
const claudeBin = resolveCommand("claude");
|
|
983
|
+
const args = [];
|
|
984
|
+
if (yolo) args.push("--dangerously-skip-permissions");
|
|
985
|
+
if (model) args.push("--model", model);
|
|
986
|
+
args.push("--verbose", "--output-format", "stream-json", "-p", prompt);
|
|
987
|
+
const child = spawn(claudeBin, args, { stdio: ["inherit", "pipe", "inherit"] });
|
|
988
|
+
const rl = createInterface({ input: child.stdout });
|
|
989
|
+
let turnCount = 0;
|
|
990
|
+
child.on("error", (err) => {
|
|
991
|
+
handleSpawnError(err);
|
|
992
|
+
});
|
|
993
|
+
rl.on("line", (line) => {
|
|
994
|
+
try {
|
|
995
|
+
const event = JSON.parse(line);
|
|
996
|
+
formatEvent(event, turnCount);
|
|
997
|
+
if (event["type"] === "assistant") turnCount++;
|
|
998
|
+
} catch {
|
|
999
|
+
}
|
|
1000
|
+
});
|
|
1001
|
+
child.on("close", (code) => {
|
|
1002
|
+
handleExitCode(code);
|
|
1003
|
+
resolve2();
|
|
1004
|
+
});
|
|
1005
|
+
});
|
|
1006
|
+
}
|
|
1007
|
+
function formatEvent(event, turnCount) {
|
|
1008
|
+
const type = event["type"];
|
|
1009
|
+
if (type === "assistant") {
|
|
1010
|
+
const message = event["message"];
|
|
1011
|
+
const content = message?.["content"];
|
|
1012
|
+
if (!content) return;
|
|
1013
|
+
for (const block of content) {
|
|
1014
|
+
if (block["type"] === "tool_use") {
|
|
1015
|
+
const toolName = block["name"];
|
|
1016
|
+
const input = block["input"];
|
|
1017
|
+
const summary = summarizeTool(toolName, input);
|
|
1018
|
+
process.stderr.write(` [step ${turnCount + 1}] ${summary}
|
|
1019
|
+
`);
|
|
1020
|
+
} else if (block["type"] === "text") {
|
|
1021
|
+
const text = block["text"] ?? "";
|
|
1022
|
+
if (text.length > 0) {
|
|
1023
|
+
const preview = text.length > 120 ? text.slice(0, 120) + "..." : text;
|
|
1024
|
+
const firstLine = preview.split("\n")[0];
|
|
1025
|
+
process.stderr.write(` [step ${turnCount + 1}] ${firstLine}
|
|
1026
|
+
`);
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
958
1029
|
}
|
|
959
|
-
|
|
1030
|
+
} else if (type === "result") {
|
|
1031
|
+
const result = event["result"];
|
|
1032
|
+
const cost = event["cost_usd"];
|
|
1033
|
+
const duration = event["duration_ms"];
|
|
1034
|
+
const turns = event["num_turns"];
|
|
1035
|
+
process.stderr.write("\n--- Result ---\n");
|
|
1036
|
+
if (cost !== void 0 || duration !== void 0 || turns !== void 0) {
|
|
1037
|
+
const parts = [];
|
|
1038
|
+
if (turns !== void 0) parts.push(`${turns} turns`);
|
|
1039
|
+
if (duration !== void 0) parts.push(`${(duration / 1e3).toFixed(1)}s`);
|
|
1040
|
+
if (cost !== void 0) parts.push(`$${cost.toFixed(4)}`);
|
|
1041
|
+
process.stderr.write(` [info] ${parts.join(" | ")}
|
|
960
1042
|
`);
|
|
1043
|
+
}
|
|
1044
|
+
if (result) {
|
|
1045
|
+
process.stdout.write(result + "\n");
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
function summarizeTool(name, input) {
|
|
1050
|
+
if (!input) return `tool: ${name}`;
|
|
1051
|
+
switch (name) {
|
|
1052
|
+
case "Read":
|
|
1053
|
+
return `reading ${input["file_path"] ?? "file"}`;
|
|
1054
|
+
case "Write":
|
|
1055
|
+
return `writing ${input["file_path"] ?? "file"}`;
|
|
1056
|
+
case "Edit":
|
|
1057
|
+
return `editing ${input["file_path"] ?? "file"}`;
|
|
1058
|
+
case "Bash":
|
|
1059
|
+
return `running: ${truncate(String(input["command"] ?? ""), 80)}`;
|
|
1060
|
+
case "Glob":
|
|
1061
|
+
return `searching files: ${input["pattern"] ?? ""}`;
|
|
1062
|
+
case "Grep":
|
|
1063
|
+
return `searching content: ${truncate(String(input["pattern"] ?? ""), 60)}`;
|
|
1064
|
+
case "Agent":
|
|
1065
|
+
return `spawning agent: ${input["description"] ?? name}`;
|
|
1066
|
+
default:
|
|
1067
|
+
return `tool: ${name}`;
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
function truncate(str, max) {
|
|
1071
|
+
return str.length > max ? str.slice(0, max) + "..." : str;
|
|
1072
|
+
}
|
|
1073
|
+
function handleSpawnError(error) {
|
|
1074
|
+
if (!error) return;
|
|
1075
|
+
const err = error;
|
|
1076
|
+
if (err.code === "ENOENT") {
|
|
1077
|
+
process.stderr.write("Error: `claude` CLI is not installed or not on PATH.\n");
|
|
961
1078
|
process.exit(1);
|
|
962
1079
|
}
|
|
963
|
-
|
|
964
|
-
|
|
1080
|
+
process.stderr.write(`Error: ${err.message}
|
|
1081
|
+
`);
|
|
1082
|
+
process.exit(1);
|
|
1083
|
+
}
|
|
1084
|
+
function handleExitCode(status) {
|
|
1085
|
+
if (status !== null && status !== 0) {
|
|
1086
|
+
process.stderr.write(`Error: Claude Code exited with code ${status}.
|
|
965
1087
|
`);
|
|
966
|
-
process.exit(
|
|
1088
|
+
process.exit(status);
|
|
967
1089
|
}
|
|
968
1090
|
}
|
|
969
1091
|
|
|
970
1092
|
// src/commands/getReady.ts
|
|
971
|
-
var implementNextCommand = new Command3("implement-next").description("Find the next open GitHub issue matching the configured filter, claim it, and invoke Claude Code").option("--json", "Output issue details as JSON").option("--no-claude", "Skip Claude Code invocation after claiming the issue").option("--query-only", "Print issue content and exit without claiming or invoking Claude").option("--yolo", "Launch Claude Code with --dangerously-skip-permissions").action((options) => {
|
|
1093
|
+
var implementNextCommand = new Command3("implement-next").description("Find the next open GitHub issue matching the configured filter, claim it, and invoke Claude Code").option("--json", "Output issue details as JSON").option("--no-claude", "Skip Claude Code invocation after claiming the issue").option("--query-only", "Print issue content and exit without claiming or invoking Claude").option("--yolo", "Launch Claude Code with --dangerously-skip-permissions").option("--verbose", "Show step-by-step progress summary and final result").option("--opus", "Use claude-opus-4-6").option("--sonnet", "Use claude-sonnet-4-6").option("--haiku", "Use claude-haiku-4-5-20251001").action(async (options) => {
|
|
972
1094
|
const config = readConfig();
|
|
973
1095
|
if (config.remoteType !== "gh") {
|
|
974
1096
|
process.stderr.write(
|
|
@@ -1024,14 +1146,16 @@ ${issue.body}
|
|
|
1024
1146
|
const prompt = config.claudeSystemPrompt ? `${config.claudeSystemPrompt}
|
|
1025
1147
|
|
|
1026
1148
|
${issue.body}` : issue.body;
|
|
1027
|
-
|
|
1149
|
+
const model = resolveModelOption(options);
|
|
1150
|
+
await invokeClaudeCode(prompt, { yolo: options.yolo, verbose: options.verbose, model });
|
|
1028
1151
|
}
|
|
1029
1152
|
});
|
|
1030
1153
|
|
|
1031
1154
|
// src/commands/test.ts
|
|
1032
1155
|
import { Command as Command4 } from "commander";
|
|
1033
|
-
var testClaudeCmd = new Command4("claude").description("Test Claude Code invocation with a user-supplied prompt").requiredOption("--prompt <string>", "Prompt to send to Claude Code").option("--yolo", "Launch Claude Code with --dangerously-skip-permissions").action((options) => {
|
|
1034
|
-
|
|
1156
|
+
var testClaudeCmd = new Command4("claude").description("Test Claude Code invocation with a user-supplied prompt").requiredOption("--prompt <string>", "Prompt to send to Claude Code").option("--yolo", "Launch Claude Code with --dangerously-skip-permissions").option("--verbose", "Show step-by-step progress summary and final result").option("--opus", "Use claude-opus-4-6").option("--sonnet", "Use claude-sonnet-4-6").option("--haiku", "Use claude-haiku-4-5-20251001").action(async (options) => {
|
|
1157
|
+
const model = resolveModelOption(options);
|
|
1158
|
+
await invokeClaudeCode(options.prompt, { yolo: options.yolo, verbose: options.verbose, model });
|
|
1035
1159
|
});
|
|
1036
1160
|
var testCommand = new Command4("test").description("Test commands for verifying automata integrations").addCommand(testClaudeCmd);
|
|
1037
1161
|
|