tines 0.0.152 → 0.0.153

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 +28 -7
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -4198,6 +4198,9 @@ async function listAll(fetchPage, opts = {}) {
4198
4198
  return items;
4199
4199
  }
4200
4200
 
4201
+ // ../shared/src/routing.ts
4202
+ var INHERIT_RUNNER_ID = "*";
4203
+
4201
4204
  // src/format.ts
4202
4205
  function timestamp(ms) {
4203
4206
  return new Date(ms).toISOString().replace("T", " ").slice(0, 19);
@@ -4308,6 +4311,9 @@ function runnerStatusLabel(runner) {
4308
4311
  }
4309
4312
  function ruleTargetsLabel(rule) {
4310
4313
  if (rule.targets.length === 0) return "(no targets)";
4314
+ if (rule.targets.length === 1 && rule.targets[0]?.runner_id === "*") {
4315
+ return `*:${rule.targets[0].tier} (inherited runners)`;
4316
+ }
4311
4317
  return rule.targets.map(
4312
4318
  (t) => `${t.runner_name}${t.tier ? `:${t.tier}` : ""}${t.runner_status === "paused" ? " (paused)" : ""}`
4313
4319
  ).join(" \u2192 ");
@@ -5497,6 +5503,8 @@ pinned to ${ex.pin.runner_name ?? ex.pin.runner_id}${ex.pin.tier ? `:${ex.pin.ti
5497
5503
  } else if (ex.matched_rule) {
5498
5504
  console.log(`
5499
5505
  matched rule: ${ex.matched_rule.scope_label}`);
5506
+ if (ex.tier_override) console.log(`tier override: ${ex.tier_override}`);
5507
+ if (ex.runner_rule) console.log(`runner source: ${ex.runner_rule.scope_label}`);
5500
5508
  }
5501
5509
  if (ex.targets.length > 0) {
5502
5510
  console.log("targets (preference order):");
@@ -6720,16 +6728,29 @@ function register7(program3) {
6720
6728
  );
6721
6729
  withCommon(
6722
6730
  routing.command("set <target...>").description(
6723
- "Create or replace the rule at a scope: an ordered list of <runner>[:tier] targets"
6731
+ "Create or replace a rule with <runner>[:tier] targets, or scoped '*:smartest' tier inheritance"
6724
6732
  ).option("-p, --project <name>", "scope: project name or id").option("-s, --state <workflow/state>", "scope: workflow-qualified state").option("-l, --label <name>", "scope: issue label name or id")
6725
6733
  ).action(async (targetSpecs, opts) => {
6734
+ const parsed = targetSpecs.map(parseTargetSpec);
6735
+ const wildcard = parsed.filter((target) => target.name === INHERIT_RUNNER_ID);
6736
+ if (wildcard.length > 0) {
6737
+ if (parsed.length !== 1) die("'*:tier' cannot be mixed with runner targets");
6738
+ if (!wildcard[0].tier)
6739
+ die("the '*' target requires an explicit tier, for example '*:smartest'");
6740
+ if (opts.project === void 0 && opts.state === void 0 && opts.label === void 0) {
6741
+ die("a tier-only rule requires --project, --state, or --label");
6742
+ }
6743
+ }
6726
6744
  const api = client(opts);
6727
6745
  const scope = await resolveRoutingScope(api, opts);
6728
6746
  const targets = [];
6729
- for (const spec of targetSpecs) {
6730
- const { name: name2, tier } = parseTargetSpec(spec);
6731
- const runner = await resolveRunner(api, name2);
6732
- targets.push(tier ? { runner_id: runner.id, tier } : { runner_id: runner.id });
6747
+ for (const { name: name2, tier } of parsed) {
6748
+ if (name2 === INHERIT_RUNNER_ID) {
6749
+ targets.push({ runner_id: INHERIT_RUNNER_ID, tier });
6750
+ } else {
6751
+ const runner = await resolveRunner(api, name2);
6752
+ targets.push(tier ? { runner_id: runner.id, tier } : { runner_id: runner.id });
6753
+ }
6733
6754
  }
6734
6755
  const { items } = await api.listRoutingRules();
6735
6756
  const existing = items.find(
@@ -6748,7 +6769,7 @@ function register7(program3) {
6748
6769
  for (const warning of rule.warnings) console.log(`warning: ${warning.message}`);
6749
6770
  });
6750
6771
  withCommon(
6751
- routing.command("clear").description("Delete the rule at a scope (issues it matched stop dispatching)").option("-p, --project <name>", "scope: project name or id").option("-s, --state <workflow/state>", "scope: workflow-qualified state").option("-l, --label <name>", "scope: issue label name or id")
6772
+ routing.command("clear").description("Delete the rule at a scope (matching issues are re-evaluated)").option("-p, --project <name>", "scope: project name or id").option("-s, --state <workflow/state>", "scope: workflow-qualified state").option("-l, --label <name>", "scope: issue label name or id")
6752
6773
  ).action(async (opts) => {
6753
6774
  const api = client(opts);
6754
6775
  const scope = await resolveRoutingScope(api, opts);
@@ -8745,7 +8766,7 @@ function queueHeadline(block) {
8745
8766
  case "no_rule":
8746
8767
  return "no matching routing rule";
8747
8768
  case "no_targets":
8748
- return "the matching rule has no targets";
8769
+ return "the matching rule has no effective targets";
8749
8770
  case "ambiguous_rule":
8750
8771
  return "two routing rules tie";
8751
8772
  case "pin_missing":
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tines",
3
- "version": "0.0.152",
3
+ "version": "0.0.153",
4
4
  "description": "CLI for Tines, an orchestration layer for AI agents",
5
5
  "repository": {
6
6
  "type": "git",