@q-agent/agent 0.1.19 → 0.1.20
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/src/runner.js +64 -23
- package/package.json +1 -1
package/dist/src/runner.js
CHANGED
|
@@ -1041,9 +1041,12 @@ async function processAuthoringJob(cfg, job) {
|
|
|
1041
1041
|
}
|
|
1042
1042
|
catch { /* best-effort on Windows */ }
|
|
1043
1043
|
}
|
|
1044
|
+
// Prompt goes as the -p ARGUMENT (not stdin — headless `claude -p` reads the
|
|
1045
|
+
// prompt from argv). stream-json + verbose lets us surface every step live.
|
|
1044
1046
|
const claudeArgs = [
|
|
1045
|
-
"-p",
|
|
1046
|
-
"--output-format", "json",
|
|
1047
|
+
"-p", job.taskPrompt,
|
|
1048
|
+
"--output-format", "stream-json",
|
|
1049
|
+
"--verbose",
|
|
1047
1050
|
"--model", job.model,
|
|
1048
1051
|
"--append-system-prompt-file", systemFile,
|
|
1049
1052
|
"--allowedTools", "Bash", "Read", "Write", "Glob", "Grep",
|
|
@@ -1065,21 +1068,59 @@ async function processAuthoringJob(cfg, job) {
|
|
|
1065
1068
|
claude = (0, child_process_1.spawn)((0, paths_1.claudeCli)(), claudeArgs, {
|
|
1066
1069
|
cwd: workDir,
|
|
1067
1070
|
env: claudeEnv,
|
|
1068
|
-
stdio: ["
|
|
1071
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
1069
1072
|
});
|
|
1070
1073
|
activeChild = claude;
|
|
1071
|
-
|
|
1074
|
+
// Surface each step to the agent console + the run WebSocket so the operator
|
|
1075
|
+
// can watch Claude drive browser-harness live.
|
|
1076
|
+
const emitStep = (line) => {
|
|
1077
|
+
const trimmed = line.length > 300 ? line.slice(0, 300) + "…" : line;
|
|
1078
|
+
console.log(`[authoring ${job.caseId}] ${trimmed}`);
|
|
1079
|
+
(0, bus_1.emit)("authoring-step", { caseId: job.caseId, line: trimmed });
|
|
1080
|
+
void api
|
|
1081
|
+
.postAuthoringEvent(cfg, job.sessionId, "authoring.progress", {
|
|
1082
|
+
case: job.caseId, phase: "step", message: trimmed,
|
|
1083
|
+
})
|
|
1084
|
+
.catch(() => { });
|
|
1085
|
+
};
|
|
1072
1086
|
let cerr = "";
|
|
1073
|
-
|
|
1087
|
+
let finalResult = "";
|
|
1088
|
+
let buf = "";
|
|
1089
|
+
const handleEvent = (ev) => {
|
|
1090
|
+
if (ev.type === "assistant" && ev.message?.content) {
|
|
1091
|
+
for (const c of ev.message.content) {
|
|
1092
|
+
if (c.type === "text" && typeof c.text === "string" && c.text.trim()) {
|
|
1093
|
+
emitStep(`Claude: ${c.text.trim()}`);
|
|
1094
|
+
}
|
|
1095
|
+
else if (c.type === "tool_use") {
|
|
1096
|
+
const inp = c.input || {};
|
|
1097
|
+
const detail = inp.command ?? inp.file_path ?? inp.path ?? inp.pattern ?? JSON.stringify(inp).slice(0, 200);
|
|
1098
|
+
emitStep(`▷ ${String(c.name)}: ${String(detail).replace(/\s+/g, " ").trim()}`);
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
else if (ev.type === "result" && typeof ev.result === "string") {
|
|
1103
|
+
finalResult = ev.result;
|
|
1104
|
+
}
|
|
1105
|
+
};
|
|
1106
|
+
claude.stdout?.on("data", (d) => {
|
|
1107
|
+
buf += String(d);
|
|
1108
|
+
let nl;
|
|
1109
|
+
while ((nl = buf.indexOf("\n")) >= 0) {
|
|
1110
|
+
const line = buf.slice(0, nl).trim();
|
|
1111
|
+
buf = buf.slice(nl + 1);
|
|
1112
|
+
if (!line)
|
|
1113
|
+
continue;
|
|
1114
|
+
try {
|
|
1115
|
+
handleEvent(JSON.parse(line));
|
|
1116
|
+
}
|
|
1117
|
+
catch { /* ignore non-JSON noise */ }
|
|
1118
|
+
}
|
|
1119
|
+
});
|
|
1074
1120
|
claude.stderr?.on("data", (d) => { cerr += String(d); });
|
|
1075
|
-
|
|
1076
|
-
claude.
|
|
1077
|
-
claude.
|
|
1078
|
-
}
|
|
1079
|
-
catch { }
|
|
1080
|
-
await new Promise((resolve) => {
|
|
1081
|
-
claude.on("close", () => resolve());
|
|
1082
|
-
claude.on("error", (e) => { cerr += `\nclaude spawn error: ${e.message}`; resolve(); });
|
|
1121
|
+
const exitCode = await new Promise((resolve) => {
|
|
1122
|
+
claude.on("close", (c) => resolve(c ?? 0));
|
|
1123
|
+
claude.on("error", (e) => { cerr += `\nclaude spawn error: ${e.message}`; resolve(-1); });
|
|
1083
1124
|
});
|
|
1084
1125
|
// 3) Read emitted artifacts.
|
|
1085
1126
|
const specPath = path.join(workDir, job.specFilename);
|
|
@@ -1092,19 +1133,19 @@ async function processAuthoringJob(cfg, job) {
|
|
|
1092
1133
|
}
|
|
1093
1134
|
catch { /* keep default */ }
|
|
1094
1135
|
}
|
|
1095
|
-
let summary = "";
|
|
1096
|
-
try {
|
|
1097
|
-
summary = JSON.parse(cout).result || "";
|
|
1098
|
-
}
|
|
1099
|
-
catch {
|
|
1100
|
-
summary = (cout || cerr).slice(0, 800);
|
|
1101
|
-
}
|
|
1102
|
-
if (!code.trim() && !summary)
|
|
1103
|
-
summary = "Live authoring produced no spec.";
|
|
1104
1136
|
const ok = code.trim().length > 0;
|
|
1137
|
+
let summary = finalResult || "";
|
|
1138
|
+
if (!ok) {
|
|
1139
|
+
// Make failures diagnosable: include claude's exit + stderr tail.
|
|
1140
|
+
const errTail = cerr.trim().slice(-500);
|
|
1141
|
+
summary = `${summary || "Live authoring produced no spec."} (claude exit ${exitCode})` +
|
|
1142
|
+
(errTail ? `\n[claude stderr] ${errTail}` : "");
|
|
1143
|
+
}
|
|
1144
|
+
emitStep(ok ? "✓ spec authored" : `✗ no spec (claude exit ${exitCode})`);
|
|
1145
|
+
// Terminal event so the UI can close the live authoring trail.
|
|
1105
1146
|
await api
|
|
1106
1147
|
.postAuthoringEvent(cfg, job.sessionId, "authoring.progress", {
|
|
1107
|
-
case: job.caseId, phase: ok ? "done" : "failed", message: summary.slice(0,
|
|
1148
|
+
case: job.caseId, phase: ok ? "done" : "failed", message: (summary || "").slice(0, 300),
|
|
1108
1149
|
})
|
|
1109
1150
|
.catch(() => { });
|
|
1110
1151
|
await finalize(code, discovered, summary, ok);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@q-agent/agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.20",
|
|
4
4
|
"description": "Q-Agent Local Agent — claims execution jobs from the Q-Agent server and runs Playwright locally, so manual login/MFA happens on the user's own machine and session credentials never leave it.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"bin": {
|