tines 0.0.90 → 0.0.91

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.
Files changed (2) hide show
  1. package/dist/index.js +85 -28
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,8 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- // src/program.ts
4
- import { readFileSync as readFileSync8 } from "node:fs";
5
-
6
3
  // ../../node_modules/.pnpm/commander@15.0.0/node_modules/commander/lib/error.js
7
4
  var CommanderError = class extends Error {
8
5
  /**
@@ -5533,7 +5530,7 @@ import {
5533
5530
  createWriteStream,
5534
5531
  existsSync as existsSync4,
5535
5532
  mkdirSync as mkdirSync4,
5536
- readFileSync as readFileSync6,
5533
+ readFileSync as readFileSync7,
5537
5534
  rmSync as rmSync2,
5538
5535
  statSync as statSync3,
5539
5536
  unlinkSync,
@@ -5542,6 +5539,17 @@ import {
5542
5539
  import { hostname, platform, arch } from "node:os";
5543
5540
  import { dirname as dirname4, join as join4 } from "node:path";
5544
5541
 
5542
+ // src/version.ts
5543
+ import { readFileSync as readFileSync4 } from "node:fs";
5544
+ function cliVersion() {
5545
+ try {
5546
+ const manifest = new URL("../package.json", import.meta.url);
5547
+ return JSON.parse(readFileSync4(manifest, "utf8")).version ?? "0.0.0-unknown";
5548
+ } catch {
5549
+ return "0.0.0-unknown";
5550
+ }
5551
+ }
5552
+
5545
5553
  // src/daemon/claude-stream.ts
5546
5554
  function clip(value, max) {
5547
5555
  return value.length > max ? `${value.slice(0, max)}\u2026` : value;
@@ -5639,7 +5647,7 @@ var ClaudeStreamRenderer = class {
5639
5647
 
5640
5648
  // src/daemon/cli-refresh.ts
5641
5649
  import { spawn } from "node:child_process";
5642
- import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync4 } from "node:fs";
5650
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync5 } from "node:fs";
5643
5651
  import { dirname as dirname2, join as join2 } from "node:path";
5644
5652
 
5645
5653
  // src/daemon/support.ts
@@ -5676,6 +5684,47 @@ function buildHarnessInvocation(spec, input) {
5676
5684
  }
5677
5685
  }
5678
5686
  }
5687
+ var LAUNCH_ARG_MAX = 160;
5688
+ var SAFE_WORD = /^[A-Za-z0-9_@%+=:,./-]+$/;
5689
+ function launchWord(word) {
5690
+ if (word.length > LAUNCH_ARG_MAX)
5691
+ return shellQuote(`${word.slice(0, LAUNCH_ARG_MAX)}\u2026 [+${word.length - LAUNCH_ARG_MAX} chars]`);
5692
+ return SAFE_WORD.test(word) ? word : shellQuote(word);
5693
+ }
5694
+ function formatLaunchCommand(invocation) {
5695
+ if (invocation.file === "sh" && invocation.args.length === 2 && invocation.args[0] === "-c")
5696
+ return invocation.args[1];
5697
+ return [invocation.file, ...invocation.args].map(launchWord).join(" ");
5698
+ }
5699
+ function formatLaunchBanner(invocation, input, meta) {
5700
+ const fields = [
5701
+ `harness=${meta.harness}`,
5702
+ `model=${input.model ?? "(fixed)"}`,
5703
+ `timeout=${meta.timeoutMinutes}m`,
5704
+ `cli=${meta.cliVersion}`,
5705
+ `workspace=${input.workspace}`
5706
+ ];
5707
+ return `$ ${formatLaunchCommand(invocation)}
5708
+ # tines runner: ${fields.join(" ")}
5709
+ `;
5710
+ }
5711
+ function formatDuration(ms) {
5712
+ const seconds = Math.max(0, Math.round(ms / 1e3));
5713
+ return `${Math.floor(seconds / 60)}m${seconds % 60}s`;
5714
+ }
5715
+ function formatExitLine(exit) {
5716
+ const parts = [];
5717
+ if (exit.code !== null) parts.push(`code=${exit.code}`);
5718
+ if (exit.signal) parts.push(`signal=${exit.signal}`);
5719
+ if (parts.length === 0) parts.push("code=?");
5720
+ if (exit.timedOut) parts.push("(timed out)");
5721
+ return `# tines runner: exit ${parts.join(" ")} after ${formatDuration(exit.durationMs)}
5722
+ `;
5723
+ }
5724
+ function exitLineForRun(run, exit) {
5725
+ if (run.settled) return null;
5726
+ return formatExitLine({ ...exit, timedOut: run.timedOut });
5727
+ }
5679
5728
  var RunTable = class {
5680
5729
  constructor(effects, opts = {}) {
5681
5730
  this.effects = effects;
@@ -5881,7 +5930,7 @@ function binDirOf(prefix) {
5881
5930
  }
5882
5931
  function installedVersion(prefix) {
5883
5932
  try {
5884
- const pkg = readFileSync4(join2(prefix, "node_modules", PACKAGE, "package.json"), "utf8");
5933
+ const pkg = readFileSync5(join2(prefix, "node_modules", PACKAGE, "package.json"), "utf8");
5885
5934
  const version = JSON.parse(pkg).version;
5886
5935
  return typeof version === "string" ? version : null;
5887
5936
  } catch {
@@ -5962,7 +6011,7 @@ import {
5962
6011
  existsSync as existsSync3,
5963
6012
  mkdirSync as mkdirSync3,
5964
6013
  readdirSync as readdirSync2,
5965
- readFileSync as readFileSync5,
6014
+ readFileSync as readFileSync6,
5966
6015
  rmSync,
5967
6016
  statSync as statSync2,
5968
6017
  writeFileSync as writeFileSync2
@@ -5975,7 +6024,7 @@ function defaultConfigDir() {
5975
6024
  function readJsonFile(path2) {
5976
6025
  if (!existsSync3(path2)) return null;
5977
6026
  try {
5978
- return JSON.parse(readFileSync5(path2, "utf8"));
6027
+ return JSON.parse(readFileSync6(path2, "utf8"));
5979
6028
  } catch {
5980
6029
  return null;
5981
6030
  }
@@ -6026,10 +6075,10 @@ function saveDaemonState(path2, runs) {
6026
6075
  }
6027
6076
  function processStartTimeMs(pid) {
6028
6077
  try {
6029
- const stat = readFileSync5(`/proc/${pid}/stat`, "utf8");
6078
+ const stat = readFileSync6(`/proc/${pid}/stat`, "utf8");
6030
6079
  const afterComm = stat.slice(stat.lastIndexOf(")") + 2).split(" ");
6031
6080
  const startTicks = Number(afterComm[19]);
6032
- const btimeLine = readFileSync5("/proc/stat", "utf8").split("\n").find((line) => line.startsWith("btime "));
6081
+ const btimeLine = readFileSync6("/proc/stat", "utf8").split("\n").find((line) => line.startsWith("btime "));
6033
6082
  const btime = Number(btimeLine?.slice("btime ".length));
6034
6083
  if (!Number.isFinite(startTicks) || !Number.isFinite(btime)) return null;
6035
6084
  return btime * 1e3 + startTicks / 100 * 1e3;
@@ -6114,6 +6163,7 @@ function directorySizeBytes(path2) {
6114
6163
 
6115
6164
  // src/daemon/daemon.ts
6116
6165
  var CLI_REFRESH_TTL_MS = 10 * 6e4;
6166
+ var DAEMON_VERSION = cliVersion();
6117
6167
  async function uploadRawLog(run) {
6118
6168
  const path2 = run.rawSpoolPath;
6119
6169
  if (!path2 || !run.rawUpload) return;
@@ -6122,7 +6172,7 @@ async function uploadRawLog(run) {
6122
6172
  await new Promise((resolve) => run.rawSpool?.end(resolve) ?? resolve());
6123
6173
  const size = statSync3(path2).size;
6124
6174
  if (size > 0) {
6125
- let body = readFileSync6(path2);
6175
+ let body = readFileSync7(path2);
6126
6176
  if (body.byteLength > RUN_LOG_RAW_MAX_BYTES) {
6127
6177
  const marker = Buffer.from(
6128
6178
  `{"type":"tines_truncated","dropped_bytes":${body.byteLength - RUN_LOG_RAW_MAX_BYTES}}
@@ -6347,14 +6397,22 @@ async function runDaemon(opts) {
6347
6397
  ` : `warning: no daemon-managed tines CLI; using whatever \`tines\` is on this machine's PATH
6348
6398
  `
6349
6399
  );
6400
+ const harnessInput = {
6401
+ workspace,
6402
+ promptFile: join4(workspace, "prompt.md"),
6403
+ prompt: assignment.prompt,
6404
+ model: assignment.run.model
6405
+ };
6350
6406
  const invocation = buildHarnessInvocation(
6351
6407
  { harness: opts.harness, command: opts.command },
6352
- {
6353
- workspace,
6354
- promptFile: join4(workspace, "prompt.md"),
6355
- prompt: assignment.prompt,
6356
- model: assignment.run.model
6357
- }
6408
+ harnessInput
6409
+ );
6410
+ run.batcher.append(
6411
+ formatLaunchBanner(invocation, harnessInput, {
6412
+ harness: opts.harness,
6413
+ timeoutMinutes: assignment.timeout_minutes,
6414
+ cliVersion: DAEMON_VERSION
6415
+ })
6358
6416
  );
6359
6417
  const child = spawn2(invocation.file, invocation.args, {
6360
6418
  cwd: workspace,
@@ -6401,6 +6459,13 @@ async function runDaemon(opts) {
6401
6459
  void table2.finishAndCleanup(run, "failed", `failed to launch harness: ${message2(err)}`);
6402
6460
  });
6403
6461
  child.on("exit", (code, signal) => {
6462
+ run.drain?.();
6463
+ const closing = exitLineForRun(run, {
6464
+ code,
6465
+ signal,
6466
+ durationMs: Date.now() - (run.spawnedAt ?? Date.now())
6467
+ });
6468
+ if (closing) run.batcher.append(closing);
6404
6469
  if (run.timedOut) {
6405
6470
  void table2.finishAndCleanup(
6406
6471
  run,
@@ -7138,7 +7203,7 @@ function register8(program3) {
7138
7203
  }
7139
7204
 
7140
7205
  // src/commands/workflows.ts
7141
- import { readFileSync as readFileSync7 } from "node:fs";
7206
+ import { readFileSync as readFileSync8 } from "node:fs";
7142
7207
  function readJsonBody(inline, file) {
7143
7208
  if (inline !== void 0 && file !== void 0) {
7144
7209
  die("pass the JSON inline or with --file, not both");
@@ -7147,14 +7212,14 @@ function readJsonBody(inline, file) {
7147
7212
  if (file !== void 0 && file !== "-") {
7148
7213
  let raw;
7149
7214
  try {
7150
- raw = readFileSync7(file, "utf8");
7215
+ raw = readFileSync8(file, "utf8");
7151
7216
  } catch (err) {
7152
7217
  die(`cannot read ${file}: ${err instanceof Error ? err.message : String(err)}`);
7153
7218
  }
7154
7219
  return parseJsonObject(raw, file);
7155
7220
  }
7156
7221
  if (file === "-" || !process.stdin.isTTY) {
7157
- const raw = readFileSync7(0, "utf8");
7222
+ const raw = readFileSync8(0, "utf8");
7158
7223
  if (raw.trim() === "") {
7159
7224
  if (file === "-") die("no JSON on stdin");
7160
7225
  return void 0;
@@ -7308,14 +7373,6 @@ see \`tines workflows create --help\` for the expected shape`
7308
7373
  }
7309
7374
 
7310
7375
  // src/program.ts
7311
- function cliVersion() {
7312
- try {
7313
- const manifest = new URL("../package.json", import.meta.url);
7314
- return JSON.parse(readFileSync8(manifest, "utf8")).version ?? "0.0.0-unknown";
7315
- } catch {
7316
- return "0.0.0-unknown";
7317
- }
7318
- }
7319
7376
  var program2 = new Command();
7320
7377
  program2.name("tines").description("CLI for Tines").version(cliVersion()).enablePositionalOptions();
7321
7378
  registerTime(program2);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tines",
3
- "version": "0.0.90",
3
+ "version": "0.0.91",
4
4
  "description": "CLI for Tines, an orchestration layer for AI agents",
5
5
  "repository": {
6
6
  "type": "git",