tines 0.0.164 → 0.0.166
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 +212 -26
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3130,9 +3130,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3130
3130
|
helpWidth: context.helpWidth,
|
|
3131
3131
|
outputHasColors: context.hasColors
|
|
3132
3132
|
});
|
|
3133
|
-
const
|
|
3134
|
-
if (context.hasColors) return
|
|
3135
|
-
return this._outputConfiguration.stripColor(
|
|
3133
|
+
const text3 = helper.formatHelp(this, helper);
|
|
3134
|
+
if (context.hasColors) return text3;
|
|
3135
|
+
return this._outputConfiguration.stripColor(text3);
|
|
3136
3136
|
}
|
|
3137
3137
|
/**
|
|
3138
3138
|
* @typedef HelpContext
|
|
@@ -3292,7 +3292,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3292
3292
|
* @param {(string | Function)} text - string to add, or a function returning a string
|
|
3293
3293
|
* @return {Command} `this` command for chaining
|
|
3294
3294
|
*/
|
|
3295
|
-
addHelpText(position,
|
|
3295
|
+
addHelpText(position, text3) {
|
|
3296
3296
|
const allowedValues = ["beforeAll", "before", "after", "afterAll"];
|
|
3297
3297
|
if (!allowedValues.includes(position)) {
|
|
3298
3298
|
throw new Error(`Unexpected value for position to addHelpText.
|
|
@@ -3301,10 +3301,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3301
3301
|
const helpEvent = `${position}Help`;
|
|
3302
3302
|
this.on(helpEvent, (context) => {
|
|
3303
3303
|
let helpStr;
|
|
3304
|
-
if (typeof
|
|
3305
|
-
helpStr =
|
|
3304
|
+
if (typeof text3 === "function") {
|
|
3305
|
+
helpStr = text3({ error: context.error, command: context.command });
|
|
3306
3306
|
} else {
|
|
3307
|
-
helpStr =
|
|
3307
|
+
helpStr = text3;
|
|
3308
3308
|
}
|
|
3309
3309
|
if (helpStr) {
|
|
3310
3310
|
context.write(`${helpStr}
|
|
@@ -3527,7 +3527,7 @@ function runCostLabel(run) {
|
|
|
3527
3527
|
if (!usage) return null;
|
|
3528
3528
|
if (usage.cost_usd !== void 0) return `$${usage.cost_usd.toFixed(2)}`;
|
|
3529
3529
|
if (usage.cost_source === "none") return "unreported";
|
|
3530
|
-
const tokens = (usage.input_tokens ?? 0) + (usage.output_tokens ?? 0);
|
|
3530
|
+
const tokens = (usage.input_tokens ?? 0) + (usage.output_tokens ?? 0) + (usage.cache_read_tokens ?? 0) + (usage.cache_write_tokens ?? 0);
|
|
3531
3531
|
return tokens > 0 ? `${tokens.toLocaleString()} tok` : null;
|
|
3532
3532
|
}
|
|
3533
3533
|
function utilizationLabel(quota, activeRuns, stateName = (id) => id) {
|
|
@@ -6159,7 +6159,7 @@ files (v${artifact.current_version.version}):`);
|
|
|
6159
6159
|
(v) => Number.parseInt(v, 10)
|
|
6160
6160
|
).option(
|
|
6161
6161
|
"--out <path>",
|
|
6162
|
-
"write to this file, or into this directory (keeps the stored filename)"
|
|
6162
|
+
"write to this file, or into this directory (keeps the stored filename); folder artifacts require a new or empty directory"
|
|
6163
6163
|
)
|
|
6164
6164
|
).action(
|
|
6165
6165
|
async (ref, name2, opts) => {
|
|
@@ -6184,6 +6184,11 @@ files (v${artifact.current_version.version}):`);
|
|
|
6184
6184
|
if (existsSync3(opts.out) && !statSync2(opts.out).isDirectory()) {
|
|
6185
6185
|
die(`--out for a folder must be a directory, and "${opts.out}" is a file`);
|
|
6186
6186
|
}
|
|
6187
|
+
if (existsSync3(opts.out) && readdirSync(opts.out).length > 0) {
|
|
6188
|
+
die(
|
|
6189
|
+
`refusing to write folder artifact into non-empty directory "${opts.out}"; choose a new or empty directory`
|
|
6190
|
+
);
|
|
6191
|
+
}
|
|
6187
6192
|
const files = version.files ?? [];
|
|
6188
6193
|
let total = 0;
|
|
6189
6194
|
for (const file of files) {
|
|
@@ -6361,12 +6366,12 @@ start one: tines journal append ${issue.project_name}/${issue.number} "- <date>:
|
|
|
6361
6366
|
).action(
|
|
6362
6367
|
async (ref, markdown, opts, command) => {
|
|
6363
6368
|
if (helpGuard(command, markdown)) return;
|
|
6364
|
-
const
|
|
6369
|
+
const text3 = readBodyValue(markdown);
|
|
6365
6370
|
const api = client(opts);
|
|
6366
6371
|
const { scope, note, item } = await resolveJournal(api, ref, opts.state);
|
|
6367
6372
|
printNote(note);
|
|
6368
6373
|
if (item) {
|
|
6369
|
-
const updated = await api.appendContextItem(item.id, { text:
|
|
6374
|
+
const updated = await api.appendContextItem(item.id, { text: text3 });
|
|
6370
6375
|
if (opts.json) return printJson(updated);
|
|
6371
6376
|
return console.log(`appended to the ${scope.label} journal (now v${updated.version})`);
|
|
6372
6377
|
}
|
|
@@ -6376,7 +6381,7 @@ start one: tines journal append ${issue.project_name}/${issue.number} "- <date>:
|
|
|
6376
6381
|
name: JOURNAL_NAME,
|
|
6377
6382
|
project_id: scope.project_id ?? void 0,
|
|
6378
6383
|
workflow_state_id: scope.workflow_state_id ?? void 0,
|
|
6379
|
-
body:
|
|
6384
|
+
body: text3.trim()
|
|
6380
6385
|
});
|
|
6381
6386
|
if (opts.json) return printJson(created);
|
|
6382
6387
|
console.log(`started the ${scope.label} journal (${created.id})`);
|
|
@@ -6384,7 +6389,7 @@ start one: tines journal append ${issue.project_name}/${issue.number} "- <date>:
|
|
|
6384
6389
|
if (!(err instanceof ApiError) || err.code !== "duplicate_context_name") throw err;
|
|
6385
6390
|
const { item: fresh } = await resolveJournal(api, ref, opts.state);
|
|
6386
6391
|
if (!fresh) throw err;
|
|
6387
|
-
const updated = await api.appendContextItem(fresh.id, { text:
|
|
6392
|
+
const updated = await api.appendContextItem(fresh.id, { text: text3 });
|
|
6388
6393
|
if (opts.json) return printJson(updated);
|
|
6389
6394
|
console.log(`appended to the ${scope.label} journal (now v${updated.version})`);
|
|
6390
6395
|
}
|
|
@@ -6933,6 +6938,7 @@ import {
|
|
|
6933
6938
|
} from "node:fs";
|
|
6934
6939
|
import { hostname, platform, arch } from "node:os";
|
|
6935
6940
|
import { dirname as dirname4, join as join5 } from "node:path";
|
|
6941
|
+
import { StringDecoder } from "node:string_decoder";
|
|
6936
6942
|
|
|
6937
6943
|
// src/version.ts
|
|
6938
6944
|
import { readFileSync as readFileSync6 } from "node:fs";
|
|
@@ -6945,6 +6951,17 @@ function cliVersion() {
|
|
|
6945
6951
|
}
|
|
6946
6952
|
}
|
|
6947
6953
|
|
|
6954
|
+
// src/daemon/stream-summary.ts
|
|
6955
|
+
function validMetric(value) {
|
|
6956
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
6957
|
+
}
|
|
6958
|
+
function validProviderSessionId(value) {
|
|
6959
|
+
return typeof value === "string" && value.length >= 1 && value.length <= 255 && Boolean(value.trim()) && !/[\x00-\x1f\x7f]/.test(value);
|
|
6960
|
+
}
|
|
6961
|
+
function copySummary(value) {
|
|
6962
|
+
return { ...value, ...value.usage ? { usage: { ...value.usage } } : {} };
|
|
6963
|
+
}
|
|
6964
|
+
|
|
6948
6965
|
// src/daemon/claude-stream.ts
|
|
6949
6966
|
function clip(value, max) {
|
|
6950
6967
|
return value.length > max ? `${value.slice(0, max)}\u2026` : value;
|
|
@@ -7016,6 +7033,8 @@ var ClaudeStreamRenderer = class {
|
|
|
7016
7033
|
emit;
|
|
7017
7034
|
onEvent;
|
|
7018
7035
|
pending = "";
|
|
7036
|
+
collected = {};
|
|
7037
|
+
finished = false;
|
|
7019
7038
|
write(chunk) {
|
|
7020
7039
|
this.pending += chunk;
|
|
7021
7040
|
let nl = this.pending.indexOf("\n");
|
|
@@ -7027,11 +7046,16 @@ var ClaudeStreamRenderer = class {
|
|
|
7027
7046
|
}
|
|
7028
7047
|
/** Renders any trailing partial line. Call once the harness has exited. */
|
|
7029
7048
|
finish() {
|
|
7049
|
+
if (this.finished) return;
|
|
7050
|
+
this.finished = true;
|
|
7030
7051
|
if (this.pending) {
|
|
7031
7052
|
this.line(this.pending);
|
|
7032
7053
|
this.pending = "";
|
|
7033
7054
|
}
|
|
7034
7055
|
}
|
|
7056
|
+
summary() {
|
|
7057
|
+
return copySummary(this.collected);
|
|
7058
|
+
}
|
|
7035
7059
|
line(raw) {
|
|
7036
7060
|
const trimmed = raw.trim();
|
|
7037
7061
|
if (!trimmed) return;
|
|
@@ -7048,10 +7072,152 @@ var ClaudeStreamRenderer = class {
|
|
|
7048
7072
|
`);
|
|
7049
7073
|
return;
|
|
7050
7074
|
}
|
|
7075
|
+
if (!event || typeof event !== "object" || Array.isArray(event)) return;
|
|
7076
|
+
if (event.type === "result") this.collectResult(event);
|
|
7051
7077
|
this.onEvent?.(event);
|
|
7052
7078
|
for (const line of renderStreamEvent(event)) this.emit(`${line}
|
|
7053
7079
|
`);
|
|
7054
7080
|
}
|
|
7081
|
+
collectResult(event) {
|
|
7082
|
+
if (!this.collected.providerSessionId && validProviderSessionId(event.session_id)) {
|
|
7083
|
+
this.collected.providerSessionId = event.session_id;
|
|
7084
|
+
}
|
|
7085
|
+
if (validMetric(event.num_turns)) this.collected.numTurns = event.num_turns;
|
|
7086
|
+
if (validMetric(event.duration_ms)) this.collected.durationMs = event.duration_ms;
|
|
7087
|
+
const usage = { cost_source: "provider" };
|
|
7088
|
+
let measured = false;
|
|
7089
|
+
if (validMetric(event.total_cost_usd)) {
|
|
7090
|
+
usage.cost_usd = event.total_cost_usd;
|
|
7091
|
+
measured = true;
|
|
7092
|
+
}
|
|
7093
|
+
const raw = event.usage;
|
|
7094
|
+
if (raw && typeof raw === "object" && !Array.isArray(raw)) {
|
|
7095
|
+
for (const [source, destination] of [
|
|
7096
|
+
["input_tokens", "input_tokens"],
|
|
7097
|
+
["output_tokens", "output_tokens"],
|
|
7098
|
+
["cache_read_input_tokens", "cache_read_tokens"],
|
|
7099
|
+
["cache_creation_input_tokens", "cache_write_tokens"]
|
|
7100
|
+
]) {
|
|
7101
|
+
if (validMetric(raw[source])) {
|
|
7102
|
+
usage[destination] = raw[source];
|
|
7103
|
+
measured = true;
|
|
7104
|
+
}
|
|
7105
|
+
}
|
|
7106
|
+
}
|
|
7107
|
+
if (measured) this.collected.usage = usage;
|
|
7108
|
+
}
|
|
7109
|
+
};
|
|
7110
|
+
|
|
7111
|
+
// src/daemon/codex-stream.ts
|
|
7112
|
+
function object(value) {
|
|
7113
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
7114
|
+
}
|
|
7115
|
+
function text2(value) {
|
|
7116
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
7117
|
+
}
|
|
7118
|
+
function renderCodexEvent(event) {
|
|
7119
|
+
const type = event.type;
|
|
7120
|
+
if (type === "thread.started") return ["[session] started"];
|
|
7121
|
+
if (type === "turn.started") return ["[session] turn started"];
|
|
7122
|
+
if (type === "turn.completed") return ["[session] turn completed"];
|
|
7123
|
+
if (type === "turn.failed") {
|
|
7124
|
+
const error = object(event.error);
|
|
7125
|
+
return [`[error] ${clip(text2(error?.message) ?? text2(event.message) ?? "turn failed", 2e3)}`];
|
|
7126
|
+
}
|
|
7127
|
+
if (type === "error") return [`[error] ${clip(text2(event.message) ?? "unknown error", 2e3)}`];
|
|
7128
|
+
if (type !== "item.completed") return [];
|
|
7129
|
+
const item = object(event.item);
|
|
7130
|
+
if (!item) return [];
|
|
7131
|
+
switch (item.type) {
|
|
7132
|
+
case "agent_message":
|
|
7133
|
+
return text2(item.text) ? [`[agent] ${clip(text2(item.text), 2e3)}`] : [];
|
|
7134
|
+
case "command_execution": {
|
|
7135
|
+
const command = text2(item.command) ?? "command";
|
|
7136
|
+
const failed = validMetric(item.exit_code) && item.exit_code !== 0;
|
|
7137
|
+
const output = failed ? text2(item.aggregated_output) : void 0;
|
|
7138
|
+
return [
|
|
7139
|
+
`[tool] ${clip(command, 300)}${failed ? ` (exit ${item.exit_code}${output ? `: ${clip(output, 300)}` : ""})` : ""}`
|
|
7140
|
+
];
|
|
7141
|
+
}
|
|
7142
|
+
case "file_change": {
|
|
7143
|
+
const changes = Array.isArray(item.changes) ? item.changes : [];
|
|
7144
|
+
const paths = changes.map((change) => text2(object(change)?.path)).filter((path2) => Boolean(path2));
|
|
7145
|
+
return [`[tool] file change${paths.length ? `: ${clip(paths.join(", "), 300)}` : ""}`];
|
|
7146
|
+
}
|
|
7147
|
+
case "mcp_tool_call":
|
|
7148
|
+
return [
|
|
7149
|
+
`[tool] ${clip([text2(item.server), text2(item.tool)].filter(Boolean).join("/") || "MCP call", 300)}`
|
|
7150
|
+
];
|
|
7151
|
+
case "web_search":
|
|
7152
|
+
return [`[tool] web search${text2(item.query) ? `: ${clip(text2(item.query), 300)}` : ""}`];
|
|
7153
|
+
default:
|
|
7154
|
+
return [];
|
|
7155
|
+
}
|
|
7156
|
+
}
|
|
7157
|
+
var CodexStreamRenderer = class {
|
|
7158
|
+
constructor(emit) {
|
|
7159
|
+
this.emit = emit;
|
|
7160
|
+
}
|
|
7161
|
+
emit;
|
|
7162
|
+
pending = "";
|
|
7163
|
+
collected = {};
|
|
7164
|
+
finished = false;
|
|
7165
|
+
write(chunk) {
|
|
7166
|
+
this.pending += chunk;
|
|
7167
|
+
let nl = this.pending.indexOf("\n");
|
|
7168
|
+
while (nl !== -1) {
|
|
7169
|
+
this.line(this.pending.slice(0, nl));
|
|
7170
|
+
this.pending = this.pending.slice(nl + 1);
|
|
7171
|
+
nl = this.pending.indexOf("\n");
|
|
7172
|
+
}
|
|
7173
|
+
}
|
|
7174
|
+
finish() {
|
|
7175
|
+
if (this.finished) return;
|
|
7176
|
+
this.finished = true;
|
|
7177
|
+
if (this.pending) this.line(this.pending);
|
|
7178
|
+
this.pending = "";
|
|
7179
|
+
}
|
|
7180
|
+
summary() {
|
|
7181
|
+
return copySummary(this.collected);
|
|
7182
|
+
}
|
|
7183
|
+
line(raw) {
|
|
7184
|
+
const trimmed = raw.trim();
|
|
7185
|
+
if (!trimmed) return;
|
|
7186
|
+
let event;
|
|
7187
|
+
try {
|
|
7188
|
+
const parsed = JSON.parse(trimmed);
|
|
7189
|
+
const parsedObject = object(parsed);
|
|
7190
|
+
if (!parsedObject) return;
|
|
7191
|
+
event = parsedObject;
|
|
7192
|
+
} catch {
|
|
7193
|
+
this.emit(`${raw}
|
|
7194
|
+
`);
|
|
7195
|
+
return;
|
|
7196
|
+
}
|
|
7197
|
+
this.collect(event);
|
|
7198
|
+
for (const line of renderCodexEvent(event)) this.emit(`${line}
|
|
7199
|
+
`);
|
|
7200
|
+
}
|
|
7201
|
+
collect(event) {
|
|
7202
|
+
if (event.type === "thread.started" && !this.collected.providerSessionId && validProviderSessionId(event.thread_id)) {
|
|
7203
|
+
this.collected.providerSessionId = event.thread_id;
|
|
7204
|
+
}
|
|
7205
|
+
if (event.type !== "turn.completed") return;
|
|
7206
|
+
const raw = object(event.usage);
|
|
7207
|
+
if (!raw) return;
|
|
7208
|
+
const totalInput = validMetric(raw.input_tokens) ? raw.input_tokens : void 0;
|
|
7209
|
+
const rawCached = validMetric(raw.cached_input_tokens) ? raw.cached_input_tokens : void 0;
|
|
7210
|
+
const output = validMetric(raw.output_tokens) ? raw.output_tokens : void 0;
|
|
7211
|
+
if (totalInput === void 0 && rawCached === void 0 && output === void 0) return;
|
|
7212
|
+
const usage = {};
|
|
7213
|
+
if (totalInput !== void 0) {
|
|
7214
|
+
const cached = rawCached === void 0 ? void 0 : Math.min(rawCached, totalInput);
|
|
7215
|
+
usage.input_tokens = totalInput - (cached ?? 0);
|
|
7216
|
+
if (cached !== void 0) usage.cache_read_tokens = cached;
|
|
7217
|
+
} else if (rawCached !== void 0) usage.cache_read_tokens = rawCached;
|
|
7218
|
+
if (output !== void 0) usage.output_tokens = output;
|
|
7219
|
+
this.collected.usage = usage;
|
|
7220
|
+
}
|
|
7055
7221
|
};
|
|
7056
7222
|
|
|
7057
7223
|
// src/daemon/rate-limit.ts
|
|
@@ -7154,8 +7320,8 @@ function zonedDate(zone, at) {
|
|
|
7154
7320
|
return { y: get("year"), m: get("month") - 1, d: get("day") };
|
|
7155
7321
|
}
|
|
7156
7322
|
var DURATION = /(\d+)\s*([dhms])/g;
|
|
7157
|
-
function parseResetTime(
|
|
7158
|
-
const raw =
|
|
7323
|
+
function parseResetTime(text3, now) {
|
|
7324
|
+
const raw = text3.trim();
|
|
7159
7325
|
if (!raw) return null;
|
|
7160
7326
|
const relative = raw.match(/^in\s+(.+)$/i);
|
|
7161
7327
|
if (relative) {
|
|
@@ -7274,6 +7440,7 @@ function buildHarnessInvocation(spec, input) {
|
|
|
7274
7440
|
file: "codex",
|
|
7275
7441
|
args: [
|
|
7276
7442
|
"exec",
|
|
7443
|
+
"--json",
|
|
7277
7444
|
"--skip-git-repo-check",
|
|
7278
7445
|
...input.model ? ["--model", input.model] : [],
|
|
7279
7446
|
input.prompt
|
|
@@ -7427,9 +7594,9 @@ var LogBatcher = class {
|
|
|
7427
7594
|
seq = 0;
|
|
7428
7595
|
/** Chunks awaiting a successful send, oldest first. */
|
|
7429
7596
|
pending = [];
|
|
7430
|
-
append(
|
|
7431
|
-
if (!
|
|
7432
|
-
this.buffer +=
|
|
7597
|
+
append(text3) {
|
|
7598
|
+
if (!text3) return;
|
|
7599
|
+
this.buffer += text3;
|
|
7433
7600
|
if (Buffer.byteLength(this.buffer, "utf8") >= (this.opts.maxBytes ?? 32 * 1024)) {
|
|
7434
7601
|
void this.flush();
|
|
7435
7602
|
} else if (!this.timer) {
|
|
@@ -7919,10 +8086,13 @@ async function runDaemon(opts) {
|
|
|
7919
8086
|
const table2 = new RunTable(
|
|
7920
8087
|
{
|
|
7921
8088
|
finish: async (run, status, error, judgment) => {
|
|
8089
|
+
const summary = run.renderer?.summary();
|
|
7922
8090
|
await client2.finishRun(run.runId, {
|
|
7923
8091
|
status,
|
|
7924
8092
|
...error ? { error } : {},
|
|
7925
|
-
...judgment
|
|
8093
|
+
...judgment,
|
|
8094
|
+
usage: summary?.usage ?? { cost_source: "none" },
|
|
8095
|
+
...summary?.providerSessionId ? { provider_session_id: summary.providerSessionId } : {}
|
|
7926
8096
|
});
|
|
7927
8097
|
},
|
|
7928
8098
|
release: (run, { keep, outcome }) => {
|
|
@@ -7971,7 +8141,8 @@ async function runDaemon(opts) {
|
|
|
7971
8141
|
await client2.finishRun(orphan.run_id, {
|
|
7972
8142
|
status: "failed",
|
|
7973
8143
|
error: "daemon restarted; orphaned harness killed",
|
|
7974
|
-
judgment: "interrupted"
|
|
8144
|
+
judgment: "interrupted",
|
|
8145
|
+
usage: { cost_source: "none" }
|
|
7975
8146
|
});
|
|
7976
8147
|
} catch {
|
|
7977
8148
|
}
|
|
@@ -8102,23 +8273,38 @@ async function runDaemon(opts) {
|
|
|
8102
8273
|
(event) => limiter.noteStreamEvent(event)
|
|
8103
8274
|
);
|
|
8104
8275
|
run.renderer = renderer;
|
|
8105
|
-
run.drain = () => renderer.finish();
|
|
8106
8276
|
const spoolPath = join5(opts.configDir, "rawlogs", `${runId}.ndjson`);
|
|
8107
8277
|
mkdirSync4(dirname4(spoolPath), { recursive: true });
|
|
8108
8278
|
run.rawSpoolPath = spoolPath;
|
|
8109
8279
|
run.rawSpool = createWriteStream(spoolPath);
|
|
8110
8280
|
run.rawUpload = (body) => client2.putRunLogRaw(runId, body);
|
|
8281
|
+
const decoder = new StringDecoder("utf8");
|
|
8282
|
+
run.drain = () => {
|
|
8283
|
+
const trailing = decoder.end();
|
|
8284
|
+
if (trailing) renderer.write(trailing);
|
|
8285
|
+
renderer.finish();
|
|
8286
|
+
};
|
|
8111
8287
|
child.stdout?.on("data", (data) => {
|
|
8112
8288
|
run.rawSpool?.write(data);
|
|
8113
|
-
renderer.write(
|
|
8289
|
+
renderer.write(decoder.write(data));
|
|
8114
8290
|
});
|
|
8291
|
+
} else if (opts.harness === "codex") {
|
|
8292
|
+
const renderer = new CodexStreamRenderer((line) => run.batcher.append(line));
|
|
8293
|
+
const decoder = new StringDecoder("utf8");
|
|
8294
|
+
run.renderer = renderer;
|
|
8295
|
+
run.drain = () => {
|
|
8296
|
+
const trailing = decoder.end();
|
|
8297
|
+
if (trailing) renderer.write(trailing);
|
|
8298
|
+
renderer.finish();
|
|
8299
|
+
};
|
|
8300
|
+
child.stdout?.on("data", (data) => renderer.write(decoder.write(data)));
|
|
8115
8301
|
} else {
|
|
8116
8302
|
child.stdout?.on("data", (data) => run.batcher.append(data.toString("utf8")));
|
|
8117
8303
|
}
|
|
8118
8304
|
child.stderr?.on("data", (data) => {
|
|
8119
|
-
const
|
|
8120
|
-
run.batcher.append(
|
|
8121
|
-
run.limiter?.noteStderr(
|
|
8305
|
+
const text3 = data.toString("utf8");
|
|
8306
|
+
run.batcher.append(text3);
|
|
8307
|
+
run.limiter?.noteStderr(text3);
|
|
8122
8308
|
});
|
|
8123
8309
|
run.timeout = setTimeout(() => {
|
|
8124
8310
|
if (run.settled) return;
|
|
@@ -8130,7 +8316,7 @@ async function runDaemon(opts) {
|
|
|
8130
8316
|
child.on("error", (err) => {
|
|
8131
8317
|
void table2.finishAndCleanup(run, "failed", `failed to launch harness: ${message2(err)}`);
|
|
8132
8318
|
});
|
|
8133
|
-
child.on("
|
|
8319
|
+
child.on("close", (code, signal) => {
|
|
8134
8320
|
run.drain?.();
|
|
8135
8321
|
run.limiter?.finish();
|
|
8136
8322
|
const closing = exitLineForRun(run, {
|