tines 0.0.143 → 0.0.144

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 +120 -10
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3506,6 +3506,17 @@ function isStaleTierOverride(builtinModel, overrideModel) {
3506
3506
  if (!builtinModel || !overrideModel || builtinModel === overrideModel) return false;
3507
3507
  return (MODEL_PREDECESSORS[builtinModel] ?? []).includes(overrideModel);
3508
3508
  }
3509
+ function ageLabel(at, now = Date.now()) {
3510
+ if (!Number.isFinite(at)) return "\u2014";
3511
+ const seconds = Math.max(0, Math.round((now - at) / 1e3));
3512
+ if (seconds < 60) return `${seconds}s`;
3513
+ if (seconds < 3600) return `${Math.floor(seconds / 60)}m`;
3514
+ if (seconds < 86400) return `${Math.floor(seconds / 3600)}h`;
3515
+ return `${Math.floor(seconds / 86400)}d`;
3516
+ }
3517
+ function prUrlOf(v) {
3518
+ return v.pr_repo_url && v.pr_number !== null ? `${v.pr_repo_url}/pull/${v.pr_number}` : null;
3519
+ }
3509
3520
  function runDurationLabel(run, now = Date.now()) {
3510
3521
  if (!run.started_at) return "\u2014";
3511
3522
  const seconds = Math.max(0, Math.round(((run.ended_at ?? now) - run.started_at) / 1e3));
@@ -4185,7 +4196,7 @@ function artifactSummary(a) {
4185
4196
  case "link":
4186
4197
  return cv.title ? `${cv.title} \u2014 ${cv.url}` : cv.url ?? "";
4187
4198
  case "pr":
4188
- return `${prRefLabel(cv)} \u2014 ${cv.pr_repo_url}/pull/${cv.pr_number}`;
4199
+ return `${prRefLabel(cv)} \u2014 ${prUrlOf(cv)}`;
4189
4200
  }
4190
4201
  }
4191
4202
  function artifactTypeLabel(a) {
@@ -4235,6 +4246,84 @@ function commentLines(comment) {
4235
4246
  const header = ` [${timestamp(comment.created_at)}] ${actorLabel(comment.actor)} (${comment.id})${comment.updated_at ? " (edited)" : ""}:`;
4236
4247
  return ["", header, ...comment.body.split("\n").map((line) => ` ${line}`)];
4237
4248
  }
4249
+ function sinceLastRunLines(since, now = Date.now()) {
4250
+ const prev = since.previous_run;
4251
+ const ended = prev.ended_at === null ? "not ended" : `ended ${ageLabel(prev.ended_at, now)} ago`;
4252
+ const lines = [
4253
+ `since the last run (${prev.state_at_start_name ?? "unknown state"}, ${prev.run_id} ${ended}):`
4254
+ ];
4255
+ const t = since.transition;
4256
+ if (t) {
4257
+ const via = t.action ? `via "${t.action}"` : "moved directly";
4258
+ const stale = since.stale_artifacts.length > 0 ? ` \u2014 now stale: ${since.stale_artifacts.join(", ")}` : "";
4259
+ lines.push(
4260
+ ` moved from ${t.from_state.name} ${via} by ${actorLabel(t.actor)} ${ageLabel(t.at, now)} ago${stale}`
4261
+ );
4262
+ }
4263
+ for (const c of since.comments) lines.push(...commentLines(c));
4264
+ if (since.comment_count > since.comments.length) {
4265
+ const hidden = since.comment_count - since.comments.length;
4266
+ lines.push(` \u2026 and ${hidden} earlier comment${hidden === 1 ? "" : "s"}`);
4267
+ }
4268
+ return lines;
4269
+ }
4270
+ function roundLines(round, now = Date.now()) {
4271
+ const b = round.boundary;
4272
+ const from = b ? `since ${actorLabel(b.actor)} ${b.action ? `moved "${b.action}"` : "moved it directly"} ${timestamp(b.at)}` : `since created ${timestamp(round.boundary_at)}`;
4273
+ const lines = [`round (${round.run_count} run${round.run_count === 1 ? "" : "s"} ${from}):`];
4274
+ for (const stage of round.stages) {
4275
+ const [latest, ...earlier] = stage.runs;
4276
+ if (!latest) continue;
4277
+ lines.push(` ${stage.state.name ?? stage.state.id} \u2014 ${runHeadline(latest, now)}`);
4278
+ if (latest.artifacts.length > 0) {
4279
+ lines.push(` ${latest.artifacts.map(artifactChangeLabel).join(" \xB7 ")}`);
4280
+ }
4281
+ for (const run of earlier) lines.push(` ${earlierAttemptLine(run, now)}`);
4282
+ if (latest.summary_comment) {
4283
+ lines.push(` summary (${latest.summary_comment.id}):`);
4284
+ for (const line of latest.summary_comment.body.split("\n")) lines.push(` ${line}`);
4285
+ }
4286
+ const earlierComments = latest.earlier_comment_ids;
4287
+ if (earlierComments.length > 0) {
4288
+ lines.push(
4289
+ ` ${earlierComments.length} earlier comment${earlierComments.length === 1 ? "" : "s"}: ${earlierComments.join(", ")}`
4290
+ );
4291
+ }
4292
+ }
4293
+ return lines;
4294
+ }
4295
+ function runHeadline(run, now) {
4296
+ const cost = runCostLabel(run);
4297
+ return [
4298
+ `${run.run_id} on ${run.runner_name}`,
4299
+ runDurationLabel(run, now),
4300
+ run.outcome ?? run.status,
4301
+ ...cost ? [cost] : [],
4302
+ run.transition ? `"${run.transition.action ?? "moved directly"}" \u2192 ${run.transition.to_state.name}` : "no transition"
4303
+ ].join(" \xB7 ");
4304
+ }
4305
+ function earlierAttemptLine(run, now) {
4306
+ const back = run.returned_via;
4307
+ const how = back ? back.action ? `sent back by ${back.from_state.name} ("${back.action}")` : "moved directly back" : "never came back";
4308
+ return `${run.run_id} \xB7 ${runDurationLabel(run, now)} \xB7 ${run.outcome ?? run.status} \xB7 ${how}`;
4309
+ }
4310
+ function artifactChangeLabel(a) {
4311
+ const versions = a.from_version === null ? `v${a.to_version}` : `v${a.from_version} \u2192 v${a.to_version}`;
4312
+ const extra = a.pr_url ? ` (${a.pr_url})` : a.files ? ` (${a.files.length} file${a.files.length === 1 ? "" : "s"})` : "";
4313
+ return `${a.name} ${versions}${extra}`;
4314
+ }
4315
+ function arrivedViaLabel(via) {
4316
+ if (!via) return "\u2014";
4317
+ return via.action ?? "moved directly";
4318
+ }
4319
+ function roundSummaryLabel(summary) {
4320
+ if (!summary) return "\u2014";
4321
+ const parts = [
4322
+ ...summary.pr_url ? [`PR ${summary.pr_url.split("/").pop()}`] : [],
4323
+ ...summary.artifacts.map((a) => `${a.name} v${a.version}`)
4324
+ ];
4325
+ return parts.length > 0 ? parts.join(" \xB7 ") : "\u2014";
4326
+ }
4238
4327
  function runRow(run) {
4239
4328
  return [
4240
4329
  run.id,
@@ -4258,14 +4347,8 @@ function byteSize(bytes) {
4258
4347
  const rounded = unit <= 1 ? Math.round(value) : Math.round(value * 10) / 10;
4259
4348
  return `${unit <= 1 ? rounded : rounded.toFixed(1)} ${units[unit]}`;
4260
4349
  }
4261
- function ageLabel(isoTimestamp, now = Date.now()) {
4262
- const then = Date.parse(isoTimestamp);
4263
- if (!Number.isFinite(then)) return "\u2014";
4264
- const seconds = Math.max(0, Math.round((now - then) / 1e3));
4265
- if (seconds < 60) return `${seconds}s`;
4266
- if (seconds < 3600) return `${Math.floor(seconds / 60)}m`;
4267
- if (seconds < 86400) return `${Math.floor(seconds / 3600)}h`;
4268
- return `${Math.floor(seconds / 86400)}d`;
4350
+ function ageLabel2(isoTimestamp, now = Date.now()) {
4351
+ return ageLabel(Date.parse(isoTimestamp), now);
4269
4352
  }
4270
4353
  function hoursLabel(ms, now = Date.now()) {
4271
4354
  const hours = Math.max(0, now - ms) / 36e5;
@@ -4277,7 +4360,7 @@ function keptWorkspaceRow(kept, sizeBytes, now = Date.now()) {
4277
4360
  kept.run_id,
4278
4361
  kept.issue_ref ?? "\u2014",
4279
4362
  kept.status,
4280
- ageLabel(kept.kept_at, now),
4363
+ ageLabel2(kept.kept_at, now),
4281
4364
  byteSize(sizeBytes),
4282
4365
  kept.path
4283
4366
  ];
@@ -5276,6 +5359,14 @@ allowed actions: ${allowed.length ? allowed.join(", ") : "none (terminal state)"
5276
5359
  for (const line of rest) console.log(` ${line}`);
5277
5360
  }
5278
5361
  }
5362
+ if (issue.since_last_run && issue.effective_state.category === "active") {
5363
+ console.log("");
5364
+ for (const line of sinceLastRunLines(issue.since_last_run)) console.log(line);
5365
+ }
5366
+ if (issue.round && issue.effective_state.category === "awaiting_human") {
5367
+ console.log("");
5368
+ for (const line of roundLines(issue.round)) console.log(line);
5369
+ }
5279
5370
  if (issue.comments.length > 0) {
5280
5371
  console.log(`
5281
5372
  comments (${issue.comments.length}):`);
@@ -5396,6 +5487,25 @@ function register2(program3) {
5396
5487
  );
5397
5488
  printList(res, opts, (items) => {
5398
5489
  if (items.length === 0) return console.log(opts.ready ? "no ready issues" : "no issues");
5490
+ if (opts.category === "awaiting_human") {
5491
+ table([
5492
+ ["REF", "TITLE", "STATE", "WAITING", "VIA", "ROUND", ""],
5493
+ ...items.map((i) => [
5494
+ `${i.project_name}/${i.number}`,
5495
+ i.title,
5496
+ i.effective_state.name,
5497
+ ageLabel2(new Date(i.state_entered_at).toISOString()),
5498
+ arrivedViaLabel(i.arrived_via),
5499
+ roundSummaryLabel(i.round_summary ?? null),
5500
+ [
5501
+ i.open_blockers.length > 0 ? "blocked" : "",
5502
+ i.duplicate_of ? "dup" : "",
5503
+ ...i.labels.map((l) => `[${l.name}]`)
5504
+ ].filter(Boolean).join(" ")
5505
+ ])
5506
+ ]);
5507
+ return;
5508
+ }
5399
5509
  table([
5400
5510
  ["REF", "TITLE", "STATE", "CATEGORY", "LAST ACTIVITY", ""],
5401
5511
  ...items.map((i) => [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tines",
3
- "version": "0.0.143",
3
+ "version": "0.0.144",
4
4
  "description": "CLI for Tines, an orchestration layer for AI agents",
5
5
  "repository": {
6
6
  "type": "git",