tines 0.0.204 → 0.0.206

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 +430 -115
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3536,22 +3536,22 @@ function runDurationLabel(run2, now = Date.now()) {
3536
3536
  return seconds < 60 ? `${seconds}s` : `${Math.floor(seconds / 60)}m`;
3537
3537
  }
3538
3538
  function runCostLabel(run2) {
3539
- const usage = run2.usage;
3540
- if (!usage) return null;
3541
- if (usage.cost_usd !== void 0) {
3542
- const dollars = usage.cost_usd === 0 ? "$0" : usage.cost_usd < 0.01 ? "<$0.01" : `$${usage.cost_usd.toFixed(2)}`;
3543
- const source = usage.cost_source === "provider" ? "Reported" : usage.cost_source === "priced" ? "Estimated" : "Recorded";
3539
+ const usage2 = run2.usage;
3540
+ if (!usage2) return null;
3541
+ if (usage2.cost_usd !== void 0) {
3542
+ const dollars = usage2.cost_usd === 0 ? "$0" : usage2.cost_usd < 0.01 ? "<$0.01" : `$${usage2.cost_usd.toFixed(2)}`;
3543
+ const source = usage2.cost_source === "provider" ? "Reported" : usage2.cost_source === "priced" ? "Estimated" : "Recorded";
3544
3544
  return `${dollars} ${source}`;
3545
3545
  }
3546
- if (usage.pricing?.status === "unpriced") return "Unpriced";
3547
- if (usage.cost_source === "none") return "Unreported";
3546
+ if (usage2.pricing?.status === "unpriced") return "Unpriced";
3547
+ if (usage2.cost_source === "none") return "Unreported";
3548
3548
  const measured = [
3549
- usage.input_tokens,
3550
- usage.output_tokens,
3551
- usage.cache_read_tokens,
3552
- usage.cache_write_tokens
3549
+ usage2.input_tokens,
3550
+ usage2.output_tokens,
3551
+ usage2.cache_read_tokens,
3552
+ usage2.cache_write_tokens
3553
3553
  ].some((value) => value !== void 0);
3554
- const tokens = (usage.input_tokens ?? 0) + (usage.output_tokens ?? 0) + (usage.cache_read_tokens ?? 0) + (usage.cache_write_tokens ?? 0);
3554
+ const tokens = (usage2.input_tokens ?? 0) + (usage2.output_tokens ?? 0) + (usage2.cache_read_tokens ?? 0) + (usage2.cache_write_tokens ?? 0);
3555
3555
  return tokens > 0 ? `${tokens.toLocaleString()} tok` : measured ? "Unpriced" : null;
3556
3556
  }
3557
3557
  function utilizationLabel(quota, activeRuns, stateName = (id2) => id2) {
@@ -3587,8 +3587,8 @@ function str(v) {
3587
3587
  function isoTime(v) {
3588
3588
  return typeof v === "number" && Number.isFinite(v) ? new Date(v).toISOString() : "an unknown time";
3589
3589
  }
3590
- function joinChanged(v, sep3) {
3591
- return Array.isArray(v) ? v.join(sep3) : "";
3590
+ function joinChanged(v, sep4) {
3591
+ return Array.isArray(v) ? v.join(sep4) : "";
3592
3592
  }
3593
3593
  function action(type) {
3594
3594
  return type.split(".")[1] ?? type;
@@ -5354,30 +5354,30 @@ function structuralDocument(value, allowMissingDigest) {
5354
5354
  throw new LibraryValidationError([
5355
5355
  { path: "", code: "invalid_document", message: "Library document must be an object" }
5356
5356
  ]);
5357
- const object3 = value;
5358
- if (object3.format !== "tines.library")
5357
+ const object4 = value;
5358
+ if (object4.format !== "tines.library")
5359
5359
  throw new LibraryValidationError([
5360
5360
  { path: "/format", code: "invalid_format", message: "Expected tines.library" }
5361
5361
  ]);
5362
- if (object3.version !== 3)
5362
+ if (object4.version !== 3)
5363
5363
  throw new LibraryValidationError([
5364
5364
  {
5365
5365
  path: "/version",
5366
5366
  code: "unsupported_version",
5367
- message: `Unsupported library version ${String(object3.version)}`
5367
+ message: `Unsupported library version ${String(object4.version)}`
5368
5368
  }
5369
5369
  ]);
5370
- if (object3.profile !== "workflow" && object3.profile !== "library")
5370
+ if (object4.profile !== "workflow" && object4.profile !== "library")
5371
5371
  throw new LibraryValidationError([
5372
5372
  { path: "/profile", code: "invalid_profile", message: "Expected workflow or library profile" }
5373
5373
  ]);
5374
- const allowed = TOP_LEVEL[object3.profile];
5375
- const unknown = Object.keys(object3).find((key) => !allowed.includes(key));
5374
+ const allowed = TOP_LEVEL[object4.profile];
5375
+ const unknown = Object.keys(object4).find((key) => !allowed.includes(key));
5376
5376
  if (unknown)
5377
5377
  throw new LibraryValidationError([
5378
5378
  { path: `/${unknown}`, code: "unknown_field", message: `Unknown field ${unknown}` }
5379
5379
  ]);
5380
- if (!Number.isSafeInteger(object3.exported_at) || object3.exported_at < 0)
5380
+ if (!Number.isSafeInteger(object4.exported_at) || object4.exported_at < 0)
5381
5381
  throw new LibraryValidationError([
5382
5382
  {
5383
5383
  path: "/exported_at",
@@ -5385,7 +5385,7 @@ function structuralDocument(value, allowMissingDigest) {
5385
5385
  message: "exported_at must be a non-negative safe integer"
5386
5386
  }
5387
5387
  ]);
5388
- if (!(allowMissingDigest && object3.digest === void 0) && (typeof object3.digest !== "string" || !/^sha256:[0-9a-f]{64}$/.test(object3.digest)))
5388
+ if (!(allowMissingDigest && object4.digest === void 0) && (typeof object4.digest !== "string" || !/^sha256:[0-9a-f]{64}$/.test(object4.digest)))
5389
5389
  throw new LibraryValidationError([
5390
5390
  {
5391
5391
  path: "/digest",
@@ -5395,14 +5395,14 @@ function structuralDocument(value, allowMissingDigest) {
5395
5395
  ]);
5396
5396
  for (const key of allowed) {
5397
5397
  if (key === "digest" && allowMissingDigest) continue;
5398
- if (!(key in object3))
5398
+ if (!(key in object4))
5399
5399
  throw new LibraryValidationError([
5400
5400
  { path: `/${key}`, code: "missing_field", message: `Missing required field ${key}` }
5401
5401
  ]);
5402
5402
  }
5403
5403
  return {
5404
- ...object3,
5405
- digest: typeof object3.digest === "string" ? object3.digest : ""
5404
+ ...object4,
5405
+ digest: typeof object4.digest === "string" ? object4.digest : ""
5406
5406
  };
5407
5407
  }
5408
5408
  async function parseLibraryV3Document(input2, options = {}) {
@@ -5751,11 +5751,11 @@ function assertNewStatesHavePrompts(states, prompts) {
5751
5751
  }
5752
5752
  }
5753
5753
  function parseScheduleRef(ref) {
5754
- const sep3 = ref.indexOf("/");
5755
- if (sep3 < 1 || sep3 === ref.length - 1) {
5754
+ const sep4 = ref.indexOf("/");
5755
+ if (sep4 < 1 || sep4 === ref.length - 1) {
5756
5756
  throw new CliError(`schedule reference must look like <project>/<name>, got "${ref}"`);
5757
5757
  }
5758
- return { project: ref.slice(0, sep3), name: ref.slice(sep3 + 1) };
5758
+ return { project: ref.slice(0, sep4), name: ref.slice(sep4 + 1) };
5759
5759
  }
5760
5760
  function parseIssueRef(ref) {
5761
5761
  const match = ref.match(/^(.+)\/(\d+)$/);
@@ -5763,12 +5763,12 @@ function parseIssueRef(ref) {
5763
5763
  return { project: match[1], number: Number.parseInt(match[2], 10) };
5764
5764
  }
5765
5765
  function parseFileSpec(spec) {
5766
- const sep3 = spec.indexOf("=");
5767
- if (sep3 < 1 || sep3 === spec.length - 1) {
5766
+ const sep4 = spec.indexOf("=");
5767
+ if (sep4 < 1 || sep4 === spec.length - 1) {
5768
5768
  throw new CliError(`--file must look like <path>=@<local-file>, got "${spec}"`);
5769
5769
  }
5770
- const path2 = spec.slice(0, sep3);
5771
- const source = spec.slice(sep3 + 1);
5770
+ const path2 = spec.slice(0, sep4);
5771
+ const source = spec.slice(sep4 + 1);
5772
5772
  if (!source.startsWith("@")) {
5773
5773
  throw new CliError(
5774
5774
  `skill file content always comes from a local file: --file ${path2}=@<local-file>`
@@ -5782,10 +5782,10 @@ function parseFileSpec(spec) {
5782
5782
  }
5783
5783
  }
5784
5784
  function parseTargetSpec(spec) {
5785
- const sep3 = spec.lastIndexOf(":");
5786
- if (sep3 === -1) return { name: spec };
5787
- const name2 = spec.slice(0, sep3);
5788
- const tier = spec.slice(sep3 + 1);
5785
+ const sep4 = spec.lastIndexOf(":");
5786
+ if (sep4 === -1) return { name: spec };
5787
+ const name2 = spec.slice(0, sep4);
5788
+ const tier = spec.slice(sep4 + 1);
5789
5789
  if (!name2) throw new CliError(`target must look like <runner>[:tier], got "${spec}"`);
5790
5790
  if (!MODEL_TIERS.includes(tier)) {
5791
5791
  throw new CliError(`unknown tier "${tier}" in "${spec}" (tiers: ${MODEL_TIERS.join(", ")})`);
@@ -5997,12 +5997,12 @@ async function resolveLabelFlag(api, ref) {
5997
5997
  return match.id;
5998
5998
  }
5999
5999
  async function resolveStateFlag(api, ref) {
6000
- const sep3 = ref.indexOf("/");
6001
- if (sep3 < 1 || sep3 === ref.length - 1) {
6000
+ const sep4 = ref.indexOf("/");
6001
+ if (sep4 < 1 || sep4 === ref.length - 1) {
6002
6002
  die(`--state must look like <workflow>/<state>, got "${ref}"`);
6003
6003
  }
6004
- const workflow2 = await resolveWorkflow(api, ref.slice(0, sep3));
6005
- const stateRef2 = ref.slice(sep3 + 1);
6004
+ const workflow2 = await resolveWorkflow(api, ref.slice(0, sep4));
6005
+ const stateRef2 = ref.slice(sep4 + 1);
6006
6006
  const state = workflow2.states.find((s) => s.name === stateRef2) ?? workflow2.states.find((s) => s.id === stateRef2);
6007
6007
  if (!state) {
6008
6008
  die(
@@ -8503,8 +8503,8 @@ import {
8503
8503
  writeFileSync as writeFileSync3
8504
8504
  } from "node:fs";
8505
8505
  import { randomUUID } from "node:crypto";
8506
- import { dirname as dirname4, join as join5 } from "node:path";
8507
- import { StringDecoder } from "node:string_decoder";
8506
+ import { dirname as dirname4, join as join6 } from "node:path";
8507
+ import { StringDecoder as StringDecoder2 } from "node:string_decoder";
8508
8508
 
8509
8509
  // src/version.ts
8510
8510
  import { readFileSync as readFileSync6 } from "node:fs";
@@ -8531,7 +8531,17 @@ function copySummary(value) {
8531
8531
  ...value.pricingEvidence ? {
8532
8532
  pricingEvidence: {
8533
8533
  ...value.pricingEvidence,
8534
- ...value.pricingEvidence.raw_usage ? { raw_usage: { ...value.pricingEvidence.raw_usage } } : {}
8534
+ ...value.pricingEvidence.raw_usage ? { raw_usage: { ...value.pricingEvidence.raw_usage } } : {},
8535
+ ...value.pricingEvidence.request_context ? {
8536
+ request_context: {
8537
+ ...value.pricingEvidence.request_context,
8538
+ ...value.pricingEvidence.request_context.status === "complete" ? {
8539
+ reconciled_usage: {
8540
+ ...value.pricingEvidence.request_context.reconciled_usage
8541
+ }
8542
+ } : {}
8543
+ }
8544
+ } : {}
8535
8545
  }
8536
8546
  } : {}
8537
8547
  };
@@ -8659,10 +8669,10 @@ var ClaudeStreamRenderer = class {
8659
8669
  }
8660
8670
  if (validMetric(event.num_turns)) this.collected.numTurns = event.num_turns;
8661
8671
  if (validMetric(event.duration_ms)) this.collected.durationMs = event.duration_ms;
8662
- const usage = { cost_source: "provider" };
8672
+ const usage2 = { cost_source: "provider" };
8663
8673
  let measured = false;
8664
8674
  if (validMetric(event.total_cost_usd)) {
8665
- usage.cost_usd = event.total_cost_usd;
8675
+ usage2.cost_usd = event.total_cost_usd;
8666
8676
  measured = true;
8667
8677
  }
8668
8678
  const raw = event.usage;
@@ -8674,12 +8684,12 @@ var ClaudeStreamRenderer = class {
8674
8684
  ["cache_creation_input_tokens", "cache_write_tokens"]
8675
8685
  ]) {
8676
8686
  if (validMetric(raw[source])) {
8677
- usage[destination] = raw[source];
8687
+ usage2[destination] = raw[source];
8678
8688
  measured = true;
8679
8689
  }
8680
8690
  }
8681
8691
  }
8682
- if (measured) this.collected.usage = usage;
8692
+ if (measured) this.collected.usage = usage2;
8683
8693
  }
8684
8694
  };
8685
8695
 
@@ -8836,12 +8846,12 @@ var CodexStreamRenderer = class {
8836
8846
  this.stickyStatus = "nonmonotonic";
8837
8847
  }
8838
8848
  status = this.stickyStatus ?? status;
8839
- const usage = {};
8840
- if (complete) usage.input_tokens = input2;
8841
- if (rawCached !== void 0) usage.cache_read_tokens = rawCached;
8842
- if (rawWrite !== void 0) usage.cache_write_tokens = rawWrite;
8843
- if (output !== void 0) usage.output_tokens = output;
8844
- this.collected.usage = usage;
8849
+ const usage2 = {};
8850
+ if (complete) usage2.input_tokens = input2;
8851
+ if (rawCached !== void 0) usage2.cache_read_tokens = rawCached;
8852
+ if (rawWrite !== void 0) usage2.cache_write_tokens = rawWrite;
8853
+ if (output !== void 0) usage2.output_tokens = output;
8854
+ this.collected.usage = usage2;
8845
8855
  this.updateEvidence(status, void 0, rawUsage);
8846
8856
  }
8847
8857
  updateEvidence(status, rerouted, rawUsage) {
@@ -8862,6 +8872,261 @@ var CodexStreamRenderer = class {
8862
8872
  }
8863
8873
  };
8864
8874
 
8875
+ // src/daemon/codex-rollout.ts
8876
+ import { open, opendir, realpath, stat } from "node:fs/promises";
8877
+ import { isAbsolute, join as join3, relative, resolve, sep } from "node:path";
8878
+ import { homedir as homedir2 } from "node:os";
8879
+ import { StringDecoder } from "node:string_decoder";
8880
+ var CODEX_ROLLOUT_MAX_BYTES = 128 * 1024 * 1024;
8881
+ var CODEX_ROLLOUT_MAX_LINE_BYTES = 8 * 1024 * 1024;
8882
+ var CODEX_ROLLOUT_MAX_LINES = 25e4;
8883
+ var CODEX_ROLLOUT_MAX_REQUESTS = 1e4;
8884
+ var CODEX_ROLLOUT_TIMEOUT_MS = 5e3;
8885
+ var SUPPORTED_VERSION = "0.153.4";
8886
+ var FIELDS = [
8887
+ "input_tokens",
8888
+ "cached_input_tokens",
8889
+ "cache_write_input_tokens",
8890
+ "output_tokens"
8891
+ ];
8892
+ var unavailable = (reason) => ({
8893
+ version: 1,
8894
+ normalization: "codex-rollout-delta-v1",
8895
+ status: "unavailable",
8896
+ reason
8897
+ });
8898
+ var invalid2 = (reason, harness_version) => ({
8899
+ version: 1,
8900
+ normalization: "codex-rollout-delta-v1",
8901
+ ...harness_version ? { harness_version: harness_version.slice(0, 100) } : {},
8902
+ status: "invalid",
8903
+ reason
8904
+ });
8905
+ function object3(value) {
8906
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
8907
+ }
8908
+ function usage(value, validateClasses = true) {
8909
+ const raw = object3(value);
8910
+ if (!raw) return;
8911
+ const out = {};
8912
+ for (const field of FIELDS) {
8913
+ const metric = raw[field];
8914
+ if (!Number.isSafeInteger(metric) || metric < 0) return;
8915
+ out[field] = metric;
8916
+ }
8917
+ if (validateClasses && out.cached_input_tokens + out.cache_write_input_tokens > out.input_tokens)
8918
+ return;
8919
+ return out;
8920
+ }
8921
+ function equal(a, b) {
8922
+ return FIELDS.every((field) => a[field] === b[field]);
8923
+ }
8924
+ function reconcileCodexRollout(records, input2) {
8925
+ let metadata = false;
8926
+ let harnessVersion;
8927
+ let observedModel;
8928
+ let previous = {
8929
+ input_tokens: 0,
8930
+ cached_input_tokens: 0,
8931
+ cache_write_input_tokens: 0,
8932
+ output_tokens: 0
8933
+ };
8934
+ let observed = false;
8935
+ let requestCount = 0;
8936
+ let maxRequestInput = 0;
8937
+ let previousLast = { ...previous };
8938
+ for (const value of records) {
8939
+ const record = object3(value);
8940
+ const payload = object3(record?.payload);
8941
+ if (record?.type === "session_meta") {
8942
+ if (metadata) return invalid2("metadata_mismatch", harnessVersion);
8943
+ harnessVersion = typeof payload?.cli_version === "string" ? payload.cli_version : void 0;
8944
+ if (payload?.id !== input2.threadId || payload?.source !== "exec" || payload?.originator !== "codex_exec")
8945
+ return invalid2("metadata_mismatch", harnessVersion);
8946
+ metadata = true;
8947
+ continue;
8948
+ }
8949
+ if (record?.type === "turn_context" && typeof payload?.model === "string") {
8950
+ observedModel ??= payload.model;
8951
+ if (observedModel !== payload.model || input2.model && payload.model !== input2.model)
8952
+ return invalid2("model_mismatch", harnessVersion);
8953
+ continue;
8954
+ }
8955
+ if (record?.type !== "event_msg" || payload?.type !== "token_count") continue;
8956
+ const info = object3(payload.info);
8957
+ if (!info) continue;
8958
+ const total = usage(info.total_token_usage);
8959
+ const last = usage(info.last_token_usage, false);
8960
+ if (!total || !last) return invalid2("missing_dimension", harnessVersion);
8961
+ observed = true;
8962
+ if (equal(total, previous)) {
8963
+ if (!equal(last, previousLast)) return invalid2("delta_mismatch", harnessVersion);
8964
+ continue;
8965
+ }
8966
+ if (FIELDS.some((field) => total[field] < previous[field]))
8967
+ return invalid2("nonmonotonic", harnessVersion);
8968
+ const delta = {};
8969
+ for (const field of FIELDS) delta[field] = total[field] - previous[field];
8970
+ if (delta.cached_input_tokens + delta.cache_write_input_tokens > delta.input_tokens)
8971
+ return invalid2("nonmonotonic", harnessVersion);
8972
+ if (!equal(delta, last)) return invalid2("delta_mismatch", harnessVersion);
8973
+ requestCount++;
8974
+ if (requestCount > CODEX_ROLLOUT_MAX_REQUESTS) return invalid2("limit_exceeded", harnessVersion);
8975
+ maxRequestInput = Math.max(maxRequestInput, delta.input_tokens);
8976
+ previous = total;
8977
+ previousLast = delta;
8978
+ }
8979
+ if (!metadata) return invalid2("metadata_mismatch", harnessVersion);
8980
+ if (harnessVersion !== SUPPORTED_VERSION) {
8981
+ return {
8982
+ version: 1,
8983
+ normalization: "codex-rollout-delta-v1",
8984
+ ...harnessVersion ? { harness_version: harnessVersion.slice(0, 100) } : {},
8985
+ status: "unsupported",
8986
+ reason: "unsupported_version"
8987
+ };
8988
+ }
8989
+ const terminalZero = FIELDS.every((field) => input2.terminalUsage[field] === 0);
8990
+ if (!observed && !terminalZero) return invalid2("missing_dimension", harnessVersion);
8991
+ if (!equal(previous, input2.terminalUsage)) return invalid2("terminal_mismatch", harnessVersion);
8992
+ return {
8993
+ version: 1,
8994
+ normalization: "codex-rollout-delta-v1",
8995
+ harness_version: SUPPORTED_VERSION,
8996
+ status: "complete",
8997
+ request_count: requestCount,
8998
+ max_request_input_tokens: maxRequestInput,
8999
+ reconciled_usage: { ...previous }
9000
+ };
9001
+ }
9002
+ function resolveCodexHome(env, workspace) {
9003
+ const configured = env.CODEX_HOME;
9004
+ return configured ? resolve(workspace, configured) : join3(homedir2(), ".codex");
9005
+ }
9006
+ function dateDirectories(startedAt, endedAt) {
9007
+ const first = new Date(startedAt);
9008
+ first.setUTCDate(first.getUTCDate() - 1);
9009
+ first.setUTCHours(0, 0, 0, 0);
9010
+ const last = new Date(endedAt);
9011
+ last.setUTCDate(last.getUTCDate() + 1);
9012
+ last.setUTCHours(0, 0, 0, 0);
9013
+ const result = [];
9014
+ for (let date = first; date <= last; date = new Date(date.getTime() + 864e5)) {
9015
+ result.push(
9016
+ join3(
9017
+ String(date.getUTCFullYear()),
9018
+ String(date.getUTCMonth() + 1).padStart(2, "0"),
9019
+ String(date.getUTCDate()).padStart(2, "0")
9020
+ )
9021
+ );
9022
+ if (result.length > 10) return null;
9023
+ }
9024
+ return result;
9025
+ }
9026
+ async function readCodexRolloutRecords(stream, timeoutMs) {
9027
+ let timedOut = false;
9028
+ const timer = setTimeout(
9029
+ () => {
9030
+ timedOut = true;
9031
+ stream.destroy(new Error("Codex rollout read deadline exceeded"));
9032
+ },
9033
+ Math.max(0, timeoutMs)
9034
+ );
9035
+ const decoder = new StringDecoder("utf8");
9036
+ let pending = "";
9037
+ let bytes2 = 0;
9038
+ let lines2 = 0;
9039
+ const records = [];
9040
+ const consume = (line) => {
9041
+ if (++lines2 > CODEX_ROLLOUT_MAX_LINES || Buffer.byteLength(line) > CODEX_ROLLOUT_MAX_LINE_BYTES)
9042
+ return { reason: "limit_exceeded" };
9043
+ if (!line.trim()) return;
9044
+ try {
9045
+ records.push(JSON.parse(line));
9046
+ } catch {
9047
+ return { reason: "malformed" };
9048
+ }
9049
+ };
9050
+ try {
9051
+ for await (const value of stream) {
9052
+ const chunk = Buffer.isBuffer(value) ? value : Buffer.from(value);
9053
+ bytes2 += chunk.length;
9054
+ if (bytes2 > CODEX_ROLLOUT_MAX_BYTES) return { reason: "limit_exceeded" };
9055
+ pending += decoder.write(chunk);
9056
+ let newline;
9057
+ while ((newline = pending.indexOf("\n")) >= 0) {
9058
+ const failure = consume(pending.slice(0, newline));
9059
+ if (failure) return failure;
9060
+ pending = pending.slice(newline + 1);
9061
+ }
9062
+ if (Buffer.byteLength(pending) > CODEX_ROLLOUT_MAX_LINE_BYTES)
9063
+ return { reason: "limit_exceeded" };
9064
+ }
9065
+ pending += decoder.end();
9066
+ if (pending.length) {
9067
+ const failure = consume(pending);
9068
+ if (failure) return failure;
9069
+ }
9070
+ return { records };
9071
+ } catch {
9072
+ return { reason: timedOut ? "limit_exceeded" : "read_failed" };
9073
+ } finally {
9074
+ clearTimeout(timer);
9075
+ stream.destroy();
9076
+ }
9077
+ }
9078
+ async function collectCodexRequestContext(input2) {
9079
+ if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(input2.threadId))
9080
+ return unavailable("thread_id_missing");
9081
+ const dates = dateDirectories(input2.startedAt, input2.endedAt);
9082
+ if (!dates) return unavailable("limit_exceeded");
9083
+ const sessions = join3(input2.codexHome, "sessions");
9084
+ let root;
9085
+ try {
9086
+ root = await realpath(sessions);
9087
+ } catch {
9088
+ return unavailable("rollout_missing");
9089
+ }
9090
+ const candidates = [];
9091
+ let entries = 0;
9092
+ const deadline = Date.now() + CODEX_ROLLOUT_TIMEOUT_MS;
9093
+ try {
9094
+ for (const date of dates) {
9095
+ const directory = join3(root, date);
9096
+ let stream;
9097
+ try {
9098
+ stream = await opendir(directory);
9099
+ } catch {
9100
+ continue;
9101
+ }
9102
+ for await (const entry of stream) {
9103
+ if (++entries > 2e4 || Date.now() > deadline) return unavailable("limit_exceeded");
9104
+ if ((entry.isFile() || entry.isSymbolicLink()) && entry.name.startsWith("rollout-") && entry.name.endsWith(`-${input2.threadId}.jsonl`))
9105
+ candidates.push(join3(directory, entry.name));
9106
+ }
9107
+ }
9108
+ if (candidates.length === 0) return unavailable("rollout_missing");
9109
+ if (candidates.length !== 1) return unavailable("rollout_ambiguous");
9110
+ const candidate = await realpath(candidates[0]);
9111
+ const inside = relative(root, candidate);
9112
+ if (inside.startsWith(`..${sep}`) || inside === ".." || isAbsolute(inside))
9113
+ return unavailable("unsafe_path");
9114
+ const before = await stat(candidate);
9115
+ if (!before.isFile() || before.size > CODEX_ROLLOUT_MAX_BYTES)
9116
+ return unavailable("limit_exceeded");
9117
+ const handle = await open(candidate, "r");
9118
+ const read = await readCodexRolloutRecords(handle.createReadStream(), deadline - Date.now());
9119
+ if ("reason" in read)
9120
+ return read.reason === "malformed" ? invalid2("malformed") : unavailable(read.reason);
9121
+ const after = await stat(candidate);
9122
+ if (before.dev !== after.dev || before.ino !== after.ino || before.size !== after.size || before.mtimeMs !== after.mtimeMs)
9123
+ return invalid2("read_failed");
9124
+ return reconcileCodexRollout(read.records, input2);
9125
+ } catch {
9126
+ return unavailable("read_failed");
9127
+ }
9128
+ }
9129
+
8865
9130
  // src/daemon/rate-limit.ts
8866
9131
  var USAGE_LIMIT_PREFIXES = [
8867
9132
  "You've hit your",
@@ -8965,11 +9230,11 @@ var DURATION = /(\d+)\s*([dhms])/g;
8965
9230
  function parseResetTime(text4, now) {
8966
9231
  const raw = text4.trim();
8967
9232
  if (!raw) return null;
8968
- const relative = raw.match(/^in\s+(.+)$/i);
8969
- if (relative) {
9233
+ const relative2 = raw.match(/^in\s+(.+)$/i);
9234
+ if (relative2) {
8970
9235
  let ms = 0;
8971
9236
  let matched = false;
8972
- for (const [, amount, unit] of relative[1].matchAll(DURATION)) {
9237
+ for (const [, amount, unit] of relative2[1].matchAll(DURATION)) {
8973
9238
  const n = Number(amount);
8974
9239
  ms += n * { d: 864e5, h: 36e5, m: 6e4, s: 1e3 }[unit];
8975
9240
  matched = true;
@@ -9052,10 +9317,10 @@ var RateLimitDetector = class {
9052
9317
  // src/daemon/cli-refresh.ts
9053
9318
  import { spawn } from "node:child_process";
9054
9319
  import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync7 } from "node:fs";
9055
- import { dirname as dirname3, join as join3 } from "node:path";
9320
+ import { dirname as dirname3, join as join4 } from "node:path";
9056
9321
 
9057
9322
  // src/daemon/support.ts
9058
- import { delimiter, sep } from "node:path";
9323
+ import { delimiter, sep as sep2 } from "node:path";
9059
9324
  var HARNESS_KINDS = ["claude_code", "codex", "custom"];
9060
9325
  var KEEP_WORKSPACES_MODES = ["never", "failed", "always"];
9061
9326
  function keepWorkspace(mode, outcome) {
@@ -9359,7 +9624,7 @@ function pendingSelfUpdate(cli, running) {
9359
9624
  return isNewerVersion(cli.version, running) ? cli.version : null;
9360
9625
  }
9361
9626
  function pathWithin(path2, dir) {
9362
- const root = dir.endsWith(sep) ? dir : dir + sep;
9627
+ const root = dir.endsWith(sep2) ? dir : dir + sep2;
9363
9628
  return path2.startsWith(root);
9364
9629
  }
9365
9630
  function buildSpawnEnv(base, opts) {
@@ -9379,14 +9644,14 @@ function buildSpawnEnv(base, opts) {
9379
9644
  var PACKAGE = "tines";
9380
9645
  var NPM_ARGS = ["--min-release-age=0", "--no-audit", "--no-fund", "--loglevel=error"];
9381
9646
  function agentCliPrefix(configDir) {
9382
- return join3(configDir, "cli");
9647
+ return join4(configDir, "cli");
9383
9648
  }
9384
9649
  function binDirOf(prefix) {
9385
- return join3(prefix, "node_modules", ".bin");
9650
+ return join4(prefix, "node_modules", ".bin");
9386
9651
  }
9387
9652
  function installedVersion(prefix) {
9388
9653
  try {
9389
- const pkg = readFileSync7(join3(prefix, "node_modules", PACKAGE, "package.json"), "utf8");
9654
+ const pkg = readFileSync7(join4(prefix, "node_modules", PACKAGE, "package.json"), "utf8");
9390
9655
  const version = JSON.parse(pkg).version;
9391
9656
  return typeof version === "string" ? version : null;
9392
9657
  } catch {
@@ -9395,11 +9660,11 @@ function installedVersion(prefix) {
9395
9660
  }
9396
9661
  function lastGood(prefix) {
9397
9662
  const binDir = binDirOf(prefix);
9398
- if (!existsSync4(join3(binDir, PACKAGE))) return AMBIENT_CLI;
9663
+ if (!existsSync4(join4(binDir, PACKAGE))) return AMBIENT_CLI;
9399
9664
  return { binDir, version: installedVersion(prefix), source: "stale" };
9400
9665
  }
9401
9666
  function runNpm(file, args, cwd, timeoutMs) {
9402
- return new Promise((resolve) => {
9667
+ return new Promise((resolve2) => {
9403
9668
  let output = "";
9404
9669
  let done = false;
9405
9670
  let timedOut = false;
@@ -9414,7 +9679,7 @@ function runNpm(file, args, cwd, timeoutMs) {
9414
9679
  if (done) return;
9415
9680
  done = true;
9416
9681
  clearTimeout(timer);
9417
- resolve({ ...result, timedOut, output });
9682
+ resolve2({ ...result, timedOut, output });
9418
9683
  };
9419
9684
  child.stdout?.on("data", (data) => output += data.toString("utf8"));
9420
9685
  child.stderr?.on("data", (data) => output += data.toString("utf8"));
@@ -9440,7 +9705,7 @@ async function installAgentCli(opts) {
9440
9705
  const args = ["install", "--prefix", prefix, `${PACKAGE}@latest`, ...NPM_ARGS];
9441
9706
  let result = await runNpm("npm", args, prefix, timeoutMs);
9442
9707
  if (result.spawnError?.code === "ENOENT") {
9443
- const sibling = join3(dirname3(process.execPath), "npm");
9708
+ const sibling = join4(dirname3(process.execPath), "npm");
9444
9709
  if (existsSync4(sibling)) result = await runNpm(sibling, args, prefix, timeoutMs);
9445
9710
  }
9446
9711
  if (result.code !== 0) {
@@ -9467,12 +9732,12 @@ import { arch, hostname, platform } from "node:os";
9467
9732
 
9468
9733
  // src/daemon/store.ts
9469
9734
  import { readdirSync as readdirSync2, readFileSync as readFileSync8, rmSync as rmSync2, statSync as statSync3 } from "node:fs";
9470
- import { join as join4 } from "node:path";
9735
+ import { join as join5 } from "node:path";
9471
9736
  function credentialsKey(url, name2) {
9472
9737
  return `${url.replace(/\/+$/, "")}#${name2}`;
9473
9738
  }
9474
9739
  function credentialsPath(dir) {
9475
- return join4(dir, "runners.json");
9740
+ return join5(dir, "runners.json");
9476
9741
  }
9477
9742
  function loadRunnerCredentials(dir, url, name2) {
9478
9743
  const all = readJsonFile(credentialsPath(dir));
@@ -9495,7 +9760,7 @@ function clearRunnerCredentials(dir, url, name2) {
9495
9760
  writeJsonFile(path2, all, { secret: true });
9496
9761
  }
9497
9762
  function daemonStatePath(dir, runnerId) {
9498
- return join4(dir, `daemon-state-${runnerId}.json`);
9763
+ return join5(dir, `daemon-state-${runnerId}.json`);
9499
9764
  }
9500
9765
  function loadDaemonState(path2) {
9501
9766
  const state = readJsonFile(path2);
@@ -9509,8 +9774,8 @@ function saveDaemonState(path2, runs) {
9509
9774
  }
9510
9775
  function processStartTimeMs(pid) {
9511
9776
  try {
9512
- const stat = readFileSync8(`/proc/${pid}/stat`, "utf8");
9513
- const afterComm = stat.slice(stat.lastIndexOf(")") + 2).split(" ");
9777
+ const stat2 = readFileSync8(`/proc/${pid}/stat`, "utf8");
9778
+ const afterComm = stat2.slice(stat2.lastIndexOf(")") + 2).split(" ");
9514
9779
  const startTicks = Number(afterComm[19]);
9515
9780
  const btimeLine = readFileSync8("/proc/stat", "utf8").split("\n").find((line) => line.startsWith("btime "));
9516
9781
  const btime = Number(btimeLine?.slice("btime ".length));
@@ -9521,10 +9786,10 @@ function processStartTimeMs(pid) {
9521
9786
  }
9522
9787
  }
9523
9788
  function workspacesDir(configDir) {
9524
- return join4(configDir, "workspaces");
9789
+ return join5(configDir, "workspaces");
9525
9790
  }
9526
9791
  function keptMarkerPath(workspace) {
9527
- return join4(workspace, "kept.json");
9792
+ return join5(workspace, "kept.json");
9528
9793
  }
9529
9794
  function writeKeptMarker(workspace, marker) {
9530
9795
  writeJsonFile(keptMarkerPath(workspace), marker);
@@ -9546,7 +9811,7 @@ function listKeptWorkspaces(configDir) {
9546
9811
  }
9547
9812
  const kept = [];
9548
9813
  for (const name2 of names) {
9549
- const path2 = join4(root, name2);
9814
+ const path2 = join5(root, name2);
9550
9815
  const marker = readKeptMarker(path2);
9551
9816
  if (marker) kept.push({ ...marker, path: path2 });
9552
9817
  }
@@ -9583,7 +9848,7 @@ function directorySizeBytes(path2) {
9583
9848
  return 0;
9584
9849
  }
9585
9850
  for (const entry of entries) {
9586
- const child = join4(path2, entry.name);
9851
+ const child = join5(path2, entry.name);
9587
9852
  if (entry.isDirectory()) total += directorySizeBytes(child);
9588
9853
  else if (entry.isFile()) {
9589
9854
  try {
@@ -9636,7 +9901,7 @@ async function uploadRawLog(run2) {
9636
9901
  if (!path2 || !run2.rawUpload) return;
9637
9902
  run2.rawSpoolPath = void 0;
9638
9903
  try {
9639
- await new Promise((resolve) => run2.rawSpool?.end(resolve) ?? resolve());
9904
+ await new Promise((resolve2) => run2.rawSpool?.end(resolve2) ?? resolve2());
9640
9905
  const size = statSync4(path2).size;
9641
9906
  if (size > 0) {
9642
9907
  let body = readFileSync9(path2);
@@ -9661,7 +9926,7 @@ async function uploadRawLog(run2) {
9661
9926
  }
9662
9927
  }
9663
9928
  var log = (message3) => console.log(`[${(/* @__PURE__ */ new Date()).toISOString().slice(11, 19)}] ${message3}`);
9664
- var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
9929
+ var sleep = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
9665
9930
  function killTree(pid, signal) {
9666
9931
  try {
9667
9932
  process.kill(-pid, signal);
@@ -9741,7 +10006,7 @@ async function runDaemon(opts) {
9741
10006
  const selfUpdate = opts.selfUpdate && opts.cliRefresh && managedInstall;
9742
10007
  if (opts.selfUpdate && opts.cliRefresh) {
9743
10008
  log(
9744
- managedInstall ? `self-update: on \u2014 this daemon (tines ${DAEMON_VERSION}) runs from ${prefix} and will restart once idle after a newer release is installed there` : `self-update: off \u2014 this daemon (tines ${DAEMON_VERSION}) runs from ${selfPath ?? process.argv[1] ?? "?"}, not ${prefix}; launch it from ${join5(prefix, "node_modules", ".bin", "tines")} to have refreshes apply on restart \u2014 \`tines runner install --name ${opts.name} --harness ${opts.harness.replaceAll("_", "-")}\` sets that up as a service (docs/runner-daemon.md)`
10009
+ managedInstall ? `self-update: on \u2014 this daemon (tines ${DAEMON_VERSION}) runs from ${prefix} and will restart once idle after a newer release is installed there` : `self-update: off \u2014 this daemon (tines ${DAEMON_VERSION}) runs from ${selfPath ?? process.argv[1] ?? "?"}, not ${prefix}; launch it from ${join6(prefix, "node_modules", ".bin", "tines")} to have refreshes apply on restart \u2014 \`tines runner install --name ${opts.name} --harness ${opts.harness.replaceAll("_", "-")}\` sets that up as a service (docs/runner-daemon.md)`
9745
10010
  );
9746
10011
  }
9747
10012
  let pendingUpdate = null;
@@ -9763,11 +10028,49 @@ async function runDaemon(opts) {
9763
10028
  {
9764
10029
  finish: async (run2, status, error, judgment) => {
9765
10030
  const summary = run2.renderer?.summary();
10031
+ if (summary?.pricingEvidence && opts.harness === "codex") {
10032
+ const raw = summary.pricingEvidence.raw_usage;
10033
+ const completeRaw = raw && [
10034
+ "input_tokens",
10035
+ "cached_input_tokens",
10036
+ "cache_write_input_tokens",
10037
+ "output_tokens"
10038
+ ].every((field) => raw[field] !== void 0);
10039
+ if (status === "completed" && run2.pricingSessionMode === "cold" && summary.pricingEvidence.measurement_status === "complete" && completeRaw && summary.providerSessionId && run2.codexHome && run2.spawnedAt) {
10040
+ summary.pricingEvidence.request_context = await collectCodexRequestContext({
10041
+ codexHome: run2.codexHome,
10042
+ threadId: summary.providerSessionId,
10043
+ model: run2.pricingModel ?? null,
10044
+ startedAt: run2.spawnedAt,
10045
+ endedAt: Date.now(),
10046
+ terminalUsage: raw
10047
+ });
10048
+ if ("reason" in summary.pricingEvidence.request_context && summary.pricingEvidence.request_context.reason === "model_mismatch")
10049
+ summary.pricingEvidence.model_rerouted = true;
10050
+ } else {
10051
+ summary.pricingEvidence.request_context = {
10052
+ version: 1,
10053
+ normalization: "codex-rollout-delta-v1",
10054
+ status: "unavailable",
10055
+ reason: "not_applicable"
10056
+ };
10057
+ }
10058
+ }
10059
+ const accounting = {
10060
+ usage: summary?.usage ?? { cost_source: "none" },
10061
+ ...summary?.pricingEvidence ? { pricing_evidence: summary.pricingEvidence } : {},
10062
+ ...summary?.providerSessionId ? { provider_session_id: summary.providerSessionId } : {},
10063
+ daemon_version: DAEMON_VERSION,
10064
+ status
10065
+ };
10066
+ run2.batcher.append(`[usage] ${JSON.stringify(accounting)}
10067
+ `);
10068
+ await run2.batcher.flush();
9766
10069
  const ended = await client2.finishRun(run2.runId, {
9767
10070
  status,
9768
10071
  ...error ? { error } : {},
9769
10072
  ...judgment,
9770
- usage: summary?.usage ?? { cost_source: "none" },
10073
+ usage: accounting.usage,
9771
10074
  ...summary?.pricingEvidence ? {
9772
10075
  pricing_evidence: {
9773
10076
  ...summary.pricingEvidence,
@@ -9868,7 +10171,7 @@ async function runDaemon(opts) {
9868
10171
  `run ${runId}: resume workspace ${assignment.resume.workspace_path} is gone; launching fresh`
9869
10172
  );
9870
10173
  }
9871
- const workspace = resume ? resume.workspace_path : join5(workspacesDir(opts.configDir), runId);
10174
+ const workspace = resume ? resume.workspace_path : join6(workspacesDir(opts.configDir), runId);
9872
10175
  const issueLabel = assignment.run.issue_ref ? `${assignment.run.issue_ref.project_name}/${assignment.run.issue_ref.number}` : void 0;
9873
10176
  const run2 = {
9874
10177
  runId,
@@ -9896,21 +10199,21 @@ async function runDaemon(opts) {
9896
10199
  rmSync3(workspace, { recursive: true, force: true });
9897
10200
  mkdirSync4(workspace, { recursive: true });
9898
10201
  } else {
9899
- rmSync3(join5(workspace, "kept.json"), { force: true });
10202
+ rmSync3(join6(workspace, "kept.json"), { force: true });
9900
10203
  }
9901
- writeFileSync3(join5(workspace, "prompt.md"), `${assignment.prompt}
10204
+ writeFileSync3(join6(workspace, "prompt.md"), `${assignment.prompt}
9902
10205
  `);
9903
10206
  if (!resume)
9904
10207
  for (const skill of assignment.bundle.skills) {
9905
10208
  for (const file of skill.files) {
9906
- const target = join5(workspace, "skills", skill.name, file.path);
10209
+ const target = join6(workspace, "skills", skill.name, file.path);
9907
10210
  mkdirSync4(dirname4(target), { recursive: true });
9908
10211
  writeFileSync3(target, file.content);
9909
10212
  }
9910
10213
  }
9911
10214
  if (!resume)
9912
10215
  writeFileSync3(
9913
- join5(workspace, "repos.json"),
10216
+ join6(workspace, "repos.json"),
9914
10217
  `${JSON.stringify(assignment.bundle.repos, null, 2)}
9915
10218
  `
9916
10219
  );
@@ -9944,7 +10247,7 @@ async function runDaemon(opts) {
9944
10247
  );
9945
10248
  const harnessInput = {
9946
10249
  workspace,
9947
- promptFile: join5(workspace, "prompt.md"),
10250
+ promptFile: join6(workspace, "prompt.md"),
9948
10251
  prompt: assignment.prompt,
9949
10252
  model: assignment.run.model,
9950
10253
  ...resume ? { resumeSessionId: resume.provider_session_id } : {}
@@ -9965,13 +10268,15 @@ async function runDaemon(opts) {
9965
10268
  ...resume ? { resumedFromRunId: resume.previous_run_id } : {}
9966
10269
  })
9967
10270
  );
10271
+ const spawnEnv = buildSpawnEnv(process.env, {
10272
+ binDir: cli.binDir,
10273
+ apiKey: assignment.run_key,
10274
+ apiUrl: baseUrl
10275
+ });
10276
+ if (opts.harness === "codex") run2.codexHome = resolveCodexHome(spawnEnv, workspace);
9968
10277
  const child = spawn2(invocation.file, invocation.args, {
9969
10278
  cwd: workspace,
9970
- env: buildSpawnEnv(process.env, {
9971
- binDir: cli.binDir,
9972
- apiKey: assignment.run_key,
9973
- apiUrl: baseUrl
9974
- }),
10279
+ env: spawnEnv,
9975
10280
  stdio: ["ignore", "pipe", "pipe"],
9976
10281
  detached: true
9977
10282
  });
@@ -9987,12 +10292,12 @@ async function runDaemon(opts) {
9987
10292
  (event) => limiter.noteStreamEvent(event)
9988
10293
  );
9989
10294
  run2.renderer = renderer;
9990
- const spoolPath = join5(opts.configDir, "rawlogs", `${runId}.ndjson`);
10295
+ const spoolPath = join6(opts.configDir, "rawlogs", `${runId}.ndjson`);
9991
10296
  mkdirSync4(dirname4(spoolPath), { recursive: true });
9992
10297
  run2.rawSpoolPath = spoolPath;
9993
10298
  run2.rawSpool = createWriteStream(spoolPath);
9994
10299
  run2.rawUpload = (body) => client2.putRunLogRaw(runId, body);
9995
- const decoder = new StringDecoder("utf8");
10300
+ const decoder = new StringDecoder2("utf8");
9996
10301
  run2.drain = () => {
9997
10302
  const trailing = decoder.end();
9998
10303
  if (trailing) renderer.write(trailing);
@@ -10004,7 +10309,7 @@ async function runDaemon(opts) {
10004
10309
  });
10005
10310
  } else if (opts.harness === "codex") {
10006
10311
  const renderer = new CodexStreamRenderer((line) => run2.batcher.append(line));
10007
- const decoder = new StringDecoder("utf8");
10312
+ const decoder = new StringDecoder2("utf8");
10008
10313
  run2.renderer = renderer;
10009
10314
  run2.drain = () => {
10010
10315
  const trailing = decoder.end();
@@ -10173,12 +10478,12 @@ function realpathOrNull(path2) {
10173
10478
  }
10174
10479
  }
10175
10480
  function runGit(args, cwd, batcher) {
10176
- return new Promise((resolve) => {
10481
+ return new Promise((resolve2) => {
10177
10482
  const child = spawn2("git", args, { cwd, stdio: ["ignore", "pipe", "pipe"] });
10178
10483
  child.stdout?.on("data", (data) => batcher.append(data.toString("utf8")));
10179
10484
  child.stderr?.on("data", (data) => batcher.append(data.toString("utf8")));
10180
- child.on("error", () => resolve(127));
10181
- child.on("exit", (code) => resolve(code ?? 1));
10485
+ child.on("error", () => resolve2(127));
10486
+ child.on("exit", (code) => resolve2(code ?? 1));
10182
10487
  });
10183
10488
  }
10184
10489
 
@@ -10252,13 +10557,13 @@ function harnessFlag(harness) {
10252
10557
  // src/commands/runner-service.ts
10253
10558
  import { execFile } from "node:child_process";
10254
10559
  import { existsSync as existsSync7, mkdirSync as mkdirSync5, readFileSync as readFileSync10, rmSync as rmSync4, statSync as statSync6, writeFileSync as writeFileSync4 } from "node:fs";
10255
- import { homedir as homedir2, hostname as hostname3, userInfo } from "node:os";
10560
+ import { homedir as homedir3, hostname as hostname3, userInfo } from "node:os";
10256
10561
  import { dirname as dirname6 } from "node:path";
10257
10562
  import { promisify } from "node:util";
10258
10563
 
10259
10564
  // src/daemon/service.ts
10260
10565
  import { existsSync as existsSync6, statSync as statSync5 } from "node:fs";
10261
- import { delimiter as delimiter2, dirname as dirname5, join as join6, sep as sep2 } from "node:path";
10566
+ import { delimiter as delimiter2, dirname as dirname5, join as join7, sep as sep3 } from "node:path";
10262
10567
  function defaultServiceManager(platform2 = process.platform) {
10263
10568
  if (platform2 === "darwin") return "launchd";
10264
10569
  if (platform2 === "linux") return "systemd";
@@ -10269,13 +10574,13 @@ function serviceLabel(name2, kind) {
10269
10574
  }
10270
10575
  function unitPath(name2, kind, home) {
10271
10576
  const label = serviceLabel(name2, kind);
10272
- return kind === "launchd" ? join6(home, "Library", "LaunchAgents", `${label}.plist`) : join6(home, ".config", "systemd", "user", `${label}.service`);
10577
+ return kind === "launchd" ? join7(home, "Library", "LaunchAgents", `${label}.plist`) : join7(home, ".config", "systemd", "user", `${label}.service`);
10273
10578
  }
10274
10579
  function serviceLogPath(configDir, name2) {
10275
- return join6(configDir, "logs", `runner-${name2}.log`);
10580
+ return join7(configDir, "logs", `runner-${name2}.log`);
10276
10581
  }
10277
10582
  function managedBinary(prefix) {
10278
- return join6(prefix, "node_modules", ".bin", "tines");
10583
+ return join7(prefix, "node_modules", ".bin", "tines");
10279
10584
  }
10280
10585
  function daemonArgs(input2) {
10281
10586
  const args = [
@@ -10303,7 +10608,7 @@ function daemonArgs(input2) {
10303
10608
  function findOnPath(name2, envPath) {
10304
10609
  for (const dir of (envPath ?? "").split(delimiter2)) {
10305
10610
  if (!dir) continue;
10306
- const candidate = join6(dir, name2);
10611
+ const candidate = join7(dir, name2);
10307
10612
  try {
10308
10613
  if (statSync5(candidate).isFile()) return candidate;
10309
10614
  } catch {
@@ -10435,7 +10740,7 @@ function matchDaemonProcesses(psOutput, query2) {
10435
10740
  else if (w.startsWith("--name=")) name2 = w.slice("--name=".length);
10436
10741
  }
10437
10742
  if ((name2 ?? query2.hostname) !== query2.name) continue;
10438
- const root = query2.prefix.endsWith(sep2) ? query2.prefix : query2.prefix + sep2;
10743
+ const root = query2.prefix.endsWith(sep3) ? query2.prefix : query2.prefix + sep3;
10439
10744
  matches.push({ pid, args, managed: args.includes(root) });
10440
10745
  }
10441
10746
  return matches;
@@ -10500,12 +10805,12 @@ async function waitForStart(logPath, offset, name2) {
10500
10805
  const content = readFileSync10(logPath, "utf8").slice(offset);
10501
10806
  if (pattern.test(content)) return true;
10502
10807
  }
10503
- await new Promise((resolve) => setTimeout(resolve, 500));
10808
+ await new Promise((resolve2) => setTimeout(resolve2, 500));
10504
10809
  }
10505
10810
  return false;
10506
10811
  }
10507
10812
  function serviceTarget(name2, kind) {
10508
- return { kind, name: name2, unitPath: unitPath(name2, kind, homedir2()), uid: userInfo().uid };
10813
+ return { kind, name: name2, unitPath: unitPath(name2, kind, homedir3()), uid: userInfo().uid };
10509
10814
  }
10510
10815
  function registerServiceCommands(runnerCmd) {
10511
10816
  withCommon(
@@ -11138,6 +11443,16 @@ function register8(program3) {
11138
11443
  console.log(` exact estimated USD: ${b.cost_usd_exact}`);
11139
11444
  console.log(" Standard API list-price estimate; not an invoice or subscription usage.");
11140
11445
  }
11446
+ const proof = pricing?.evidence?.request_context;
11447
+ if (proof?.status === "complete") {
11448
+ console.log(
11449
+ `request context: ${proof.request_count.toLocaleString()} verified \xB7 largest input ${proof.max_request_input_tokens.toLocaleString()} \xB7 Codex ${proof.harness_version} \xB7 ${proof.normalization}`
11450
+ );
11451
+ } else if (proof) {
11452
+ console.log(
11453
+ `request context: ${proof.status} (${proof.reason})${proof.harness_version ? ` \xB7 Codex ${proof.harness_version}` : ""} \xB7 ${proof.normalization}`
11454
+ );
11455
+ }
11141
11456
  }
11142
11457
  if (run2.provider_session_id) console.log(`provider session: ${run2.provider_session_id}`);
11143
11458
  if (run2.provider_url) console.log(`provider console: ${run2.provider_url}`);
@@ -11551,12 +11866,12 @@ function register10(program3) {
11551
11866
  const api = client(opts);
11552
11867
  const overrides = {};
11553
11868
  for (const spec of opts.state) {
11554
- const sep3 = spec.lastIndexOf("=");
11555
- if (sep3 < 1 || sep3 === spec.length - 1) {
11869
+ const sep4 = spec.lastIndexOf("=");
11870
+ if (sep4 < 1 || sep4 === spec.length - 1) {
11556
11871
  die(`--state must look like <workflow>/<state>=<n>, got "${spec}"`);
11557
11872
  }
11558
- const limit = Number.parseInt(spec.slice(sep3 + 1), 10);
11559
- const { state } = await resolveStateFlag(api, spec.slice(0, sep3));
11873
+ const limit = Number.parseInt(spec.slice(sep4 + 1), 10);
11874
+ const { state } = await resolveStateFlag(api, spec.slice(0, sep4));
11560
11875
  overrides[state.id] = limit;
11561
11876
  }
11562
11877
  const settings = await api.updateSupervisorSettings({
@@ -12043,9 +12358,9 @@ async function resolveStateBases(states, library) {
12043
12358
  }
12044
12359
  }
12045
12360
  function resolveBasePair(lib, pair, stateName) {
12046
- const sep3 = pair.indexOf("/");
12047
- const workflowRef = pair.slice(0, sep3).trim();
12048
- const stateRef2 = pair.slice(sep3 + 1).trim();
12361
+ const sep4 = pair.indexOf("/");
12362
+ const workflowRef = pair.slice(0, sep4).trim();
12363
+ const stateRef2 = pair.slice(sep4 + 1).trim();
12049
12364
  const where = `state "${stateName}" inherits from "${pair}"`;
12050
12365
  if (!workflowRef || !stateRef2) {
12051
12366
  die(`${where}, which is not a <workflow>/<state> pair`);
@@ -12339,8 +12654,8 @@ function registerPackageCommands(workflows) {
12339
12654
  else {
12340
12655
  console.log(`installed workflow package (${receipt.id})`);
12341
12656
  console.log(`plan: ${receipt.plan_digest}`);
12342
- for (const object3 of receipt.objects)
12343
- console.log(` ${object3.kind}: ${object3.name} \u2014 ${object3.href}`);
12657
+ for (const object4 of receipt.objects)
12658
+ console.log(` ${object4.kind}: ${object4.name} \u2014 ${object4.href}`);
12344
12659
  }
12345
12660
  }
12346
12661
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tines",
3
- "version": "0.0.204",
3
+ "version": "0.0.206",
4
4
  "description": "CLI for Tines, an orchestration layer for AI agents",
5
5
  "repository": {
6
6
  "type": "git",