tines 0.0.212 → 0.0.214

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 +100 -3
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -4160,6 +4160,7 @@ function createApiClient(options) {
4160
4160
  ),
4161
4161
  getUsage: (filters = {}) => get(`/api/v1/usage${query(filters)}`),
4162
4162
  getIssueUsage: (issue) => get(`/api/v1/usage${query({ mode: "issue", issue })}`),
4163
+ getCohortUsage: (filters) => get(`/api/v1/usage${query({ mode: "cohort", ...filters })}`),
4163
4164
  getUsageScope: (scope) => get(`/api/v1/usage${query({ scope })}`),
4164
4165
  getUsageEvidence: (filters) => get(`/api/v1/usage/evidence${query(filters)}`),
4165
4166
  getRun: (id2) => get(`/api/v1/runs/${id2}`),
@@ -12891,6 +12892,7 @@ function normalizeUrl(value) {
12891
12892
  }
12892
12893
 
12893
12894
  // src/commands/usage.ts
12895
+ var collect3 = (value, previous = []) => [...previous, value];
12894
12896
  function printEvidence(page) {
12895
12897
  console.log(
12896
12898
  `Usage evidence \xB7 ${page.kind} \xB7 ${page.population} \xB7 ${page.total_count} total \xB7 ${page.sort} ${page.direction}`
@@ -12905,6 +12907,17 @@ function printEvidence(page) {
12905
12907
  String(item.attempt_count)
12906
12908
  ])
12907
12909
  ]);
12910
+ else if (page.kind === "entries")
12911
+ table([
12912
+ ["EVENT", "ISSUE", "STATE", "AT", "EVIDENCE"],
12913
+ ...page.items.map((item) => [
12914
+ item.event_id,
12915
+ item.issue_id ?? "Unavailable issue",
12916
+ item.state_name ?? item.state_id ?? "Unclassifiable",
12917
+ new Date(item.created_at).toISOString(),
12918
+ item.chosen ? "Chosen completion" : item.reopening_relevant ? "Reopening witness" : item.qualifies ? "Qualifying entry" : item.unavailable_reason ?? "Excluded"
12919
+ ])
12920
+ ]);
12908
12921
  else
12909
12922
  table([
12910
12923
  ["RUN", "ISSUE", "SPEND", "AT"],
@@ -12931,6 +12944,18 @@ function printEvidence(page) {
12931
12944
  console.log(
12932
12945
  `Matching total: ${money(page.matching_total.cost_usd)} \xB7 ${page.attempt_count} attempts \xB7 ${page.pending_count} pending`
12933
12946
  );
12947
+ if (page.counters && page.history && page.from !== void 0 && page.to !== void 0 && page.observed_through !== void 0) {
12948
+ console.log(
12949
+ `Cohort selection: ${page.counters.distinct_issue_count} completed \xB7 ${page.counters.attempt_count} attempts \xB7 ${page.counters.pending_count} pending`
12950
+ );
12951
+ console.log(
12952
+ `Entries [${new Date(page.from).toISOString()}, ${new Date(page.to).toISOString()}) \xB7 history ${page.history.status} \xB7 observed through ${new Date(page.observed_through).toISOString()}`
12953
+ );
12954
+ if (page.parent_counters)
12955
+ console.log(
12956
+ `Parent cohort: ${page.parent_counters.distinct_issue_count} completed \xB7 ${money(page.parent_matching_total?.cost_usd ?? null)}`
12957
+ );
12958
+ }
12934
12959
  if (page.next_cursor) console.log(`Next cursor: ${page.next_cursor}`);
12935
12960
  }
12936
12961
  function printIssueReport(report) {
@@ -12947,6 +12972,35 @@ function printIssueReport(report) {
12947
12972
  for (const line of usageAggregateLines("Lifetime", issue.aggregate)) console.log(line);
12948
12973
  }
12949
12974
  }
12975
+ function printCohortReport(report) {
12976
+ console.log(`Completed issues \xB7 ${report.workflow.name}`);
12977
+ console.log(
12978
+ `${new Date(report.from).toISOString()} \u2014 ${new Date(report.to).toISOString()} \xB7 costs through exclusive cutoff`
12979
+ );
12980
+ console.log(
12981
+ `Terminal states: ${report.selected_states.map((state) => state.name).join(", ") || "None available"}`
12982
+ );
12983
+ console.log("Completed-issue costs are not additive to period spend.");
12984
+ console.log(
12985
+ `${report.counters.distinct_issue_count} issues \xB7 ${report.counters.attempt_count}/${report.counters.distinct_issue_count} attempts/all issues \xB7 ${money(report.counters.known_cost_per_issue.value_usd)} known USD/all issues`
12986
+ );
12987
+ console.log(
12988
+ `${report.counters.priced_run_coverage.numerator}/${report.counters.priced_run_coverage.denominator} priced finalized runs \xB7 ${report.counters.fully_priced_issue_count}/${report.counters.distinct_issue_count} fully priced issues \xB7 ${report.counters.pending_count} pending \xB7 ${report.counters.zero_run_issue_count} no-run`
12989
+ );
12990
+ console.log(
12991
+ `${report.counters.reopened_issue_count} reopened \xB7 ${report.counters.reopening_history_unavailable_issue_count} reopening unknown \xB7 observed through ${new Date(report.observed_through).toISOString()}`
12992
+ );
12993
+ console.log(
12994
+ `History: ${report.history.status} \xB7 ${report.history.qualifying_fact_count} qualifying entries`
12995
+ );
12996
+ for (const state of report.terminal_states)
12997
+ console.log(
12998
+ `${state.state.name}: ${state.counters.distinct_issue_count} completed \xB7 ${money(state.aggregate.cost_usd)} known`
12999
+ );
13000
+ if (report.counters.distinct_issue_count === 0)
13001
+ console.log("No completed issues in available history");
13002
+ if (report.scope) console.log(`Scope: ${report.scope}`);
13003
+ }
12950
13004
  var money = (value) => usageCostLabel(value);
12951
13005
  function printReport(report) {
12952
13006
  console.log(`Usage \xB7 ${report.filters.project ?? "All projects"} \xB7 ${report.by}`);
@@ -13005,8 +13059,15 @@ function register12(program3) {
13005
13059
  withCommon(
13006
13060
  program3.command("usage").description("Compare finalized run spend for a period").addOption(
13007
13061
  new Option("--window <window>", "today, 7d, or 30d").choices(["today", "7d", "30d"])
13008
- ).option("--from <bound>", "custom inclusive start (date or offset timestamp)").option("--to <bound>", "custom exclusive end (date or offset timestamp)").option("--issue <ref>", "direct issue lifetime through now").option("--scope <token>", "replay a frozen usage scope").addOption(new Option("--evidence <kind>", "list evidence").choices(["issues", "runs"])).option("--member <issue-id>", "narrow run evidence to one contributing issue").addOption(
13009
- new Option("--population <population>", "finalized or pending").choices([
13062
+ ).option("--from <bound>", "custom inclusive start (date or offset timestamp)").option("--to <bound>", "custom exclusive end (date or offset timestamp)").option("--issue <ref>", "direct issue lifetime through now").option("--cohort", "report issues completed in the selected workflow and window").option(
13063
+ "--done-state <id>",
13064
+ "terminal state id (repeatable; defaults to all done states)",
13065
+ collect3
13066
+ ).option("--scope <token>", "replay a frozen usage scope").addOption(
13067
+ new Option("--evidence <kind>", "list evidence").choices(["issues", "runs", "entries"])
13068
+ ).option("--member <issue-id>", "narrow run evidence to one contributing issue").addOption(
13069
+ new Option("--population <population>", "all, finalized, or pending").choices([
13070
+ "all",
13010
13071
  "finalized",
13011
13072
  "pending"
13012
13073
  ])
@@ -13044,6 +13105,8 @@ function register12(program3) {
13044
13105
  if (opts.scope) {
13045
13106
  const reportFlags = [
13046
13107
  opts.issue,
13108
+ opts.cohort,
13109
+ opts.doneState,
13047
13110
  opts.window,
13048
13111
  opts.from,
13049
13112
  opts.to,
@@ -13063,6 +13126,7 @@ function register12(program3) {
13063
13126
  const report2 = await api2.getUsageScope(opts.scope);
13064
13127
  if (opts.json) return printJson(report2);
13065
13128
  if (report2.mode === "issue") printIssueReport(report2);
13129
+ else if (report2.mode === "cohort") printCohortReport(report2);
13066
13130
  else printReport(report2);
13067
13131
  return;
13068
13132
  }
@@ -13085,7 +13149,7 @@ function register12(program3) {
13085
13149
  cursor
13086
13150
  });
13087
13151
  for (const item of page.items) {
13088
- const id2 = "id" in item ? item.id : item.issue_id ?? "unknown";
13152
+ const id2 = "event_id" in item ? item.event_id : "id" in item ? item.id : item.issue_id ?? "unknown";
13089
13153
  if (seenIds.has(id2)) throw new Error(`Evidence pagination repeated ${id2}`);
13090
13154
  seenIds.add(id2);
13091
13155
  }
@@ -13099,6 +13163,8 @@ function register12(program3) {
13099
13163
  }
13100
13164
  if (opts.issue) {
13101
13165
  const contradictions = [
13166
+ opts.cohort,
13167
+ opts.doneState,
13102
13168
  opts.window,
13103
13169
  opts.from,
13104
13170
  opts.to,
@@ -13120,6 +13186,37 @@ function register12(program3) {
13120
13186
  printIssueReport(report2);
13121
13187
  return;
13122
13188
  }
13189
+ if (opts.doneState?.length && !opts.cohort) throw new Error("--done-state requires --cohort");
13190
+ if (opts.cohort) {
13191
+ if (!opts.workflow) throw new Error("--cohort requires --workflow");
13192
+ if ([
13193
+ opts.issue,
13194
+ opts.scope,
13195
+ opts.state,
13196
+ opts.runner,
13197
+ opts.tier,
13198
+ opts.outcome,
13199
+ opts.accountingStatus
13200
+ ].some((value) => value !== void 0) || command.getOptionValueSource("by") === "cli")
13201
+ throw new Error("--cohort cannot be combined with issue, scope, grouping, or run filters");
13202
+ if (opts.from === void 0 !== (opts.to === void 0))
13203
+ throw new Error("--from and --to are required together");
13204
+ if (opts.window && opts.from) throw new Error("--window cannot be combined with --from/--to");
13205
+ const api2 = client(opts);
13206
+ const project2 = opts.project && !isUsageIdentity(opts.project, "prj") ? (await resolveProject(api2, opts.project)).id : opts.project;
13207
+ const workflow3 = !isUsageIdentity(opts.workflow, "wf") ? (await resolveWorkflow(api2, opts.workflow)).id : opts.workflow;
13208
+ const report2 = await api2.getCohortUsage({
13209
+ workflow: workflow3,
13210
+ project: project2,
13211
+ window: opts.window,
13212
+ from: opts.from,
13213
+ to: opts.to,
13214
+ done_state: opts.doneState
13215
+ });
13216
+ if (opts.json) return printJson(report2);
13217
+ printCohortReport(report2);
13218
+ return;
13219
+ }
13123
13220
  if (opts.from === void 0 !== (opts.to === void 0))
13124
13221
  throw new Error("--from and --to are required together");
13125
13222
  if (opts.window && opts.from) throw new Error("--window cannot be combined with --from/--to");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tines",
3
- "version": "0.0.212",
3
+ "version": "0.0.214",
4
4
  "description": "CLI for Tines, an orchestration layer for AI agents",
5
5
  "repository": {
6
6
  "type": "git",