tines 0.0.178 → 0.0.180

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 +420 -133
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1006,8 +1006,8 @@ var DualOptions = class {
1006
1006
  valueFromOption(value, option) {
1007
1007
  const optionKey = option.attributeName();
1008
1008
  if (!this.dualOptions.has(optionKey)) return true;
1009
- const preset = this.negativeOptions.get(optionKey).presetArg;
1010
- const negativeValue = preset !== void 0 ? preset : false;
1009
+ const preset2 = this.negativeOptions.get(optionKey).presetArg;
1010
+ const negativeValue = preset2 !== void 0 ? preset2 : false;
1011
1011
  return option.negate === (negativeValue === value);
1012
1012
  }
1013
1013
  };
@@ -3130,9 +3130,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
3130
3130
  helpWidth: context.helpWidth,
3131
3131
  outputHasColors: context.hasColors
3132
3132
  });
3133
- const text3 = helper.formatHelp(this, helper);
3134
- if (context.hasColors) return text3;
3135
- return this._outputConfiguration.stripColor(text3);
3133
+ const text4 = helper.formatHelp(this, helper);
3134
+ if (context.hasColors) return text4;
3135
+ return this._outputConfiguration.stripColor(text4);
3136
3136
  }
3137
3137
  /**
3138
3138
  * @typedef HelpContext
@@ -3292,7 +3292,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
3292
3292
  * @param {(string | Function)} text - string to add, or a function returning a string
3293
3293
  * @return {Command} `this` command for chaining
3294
3294
  */
3295
- addHelpText(position, text3) {
3295
+ addHelpText(position, text4) {
3296
3296
  const allowedValues = ["beforeAll", "before", "after", "afterAll"];
3297
3297
  if (!allowedValues.includes(position)) {
3298
3298
  throw new Error(`Unexpected value for position to addHelpText.
@@ -3301,10 +3301,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
3301
3301
  const helpEvent = `${position}Help`;
3302
3302
  this.on(helpEvent, (context) => {
3303
3303
  let helpStr;
3304
- if (typeof text3 === "function") {
3305
- helpStr = text3({ error: context.error, command: context.command });
3304
+ if (typeof text4 === "function") {
3305
+ helpStr = text4({ error: context.error, command: context.command });
3306
3306
  } else {
3307
- helpStr = text3;
3307
+ helpStr = text4;
3308
3308
  }
3309
3309
  if (helpStr) {
3310
3310
  context.write(`${helpStr}
@@ -3534,7 +3534,7 @@ function runCostLabel(run) {
3534
3534
  const tokens = (usage.input_tokens ?? 0) + (usage.output_tokens ?? 0) + (usage.cache_read_tokens ?? 0) + (usage.cache_write_tokens ?? 0);
3535
3535
  return tokens > 0 ? `${tokens.toLocaleString()} tok` : null;
3536
3536
  }
3537
- function utilizationLabel(quota, activeRuns, stateName = (id) => id) {
3537
+ function utilizationLabel(quota, activeRuns, stateName = (id2) => id2) {
3538
3538
  if (quota.type === "global_cap") {
3539
3539
  return `${activeRuns.length}/${quota.limit} global slot${quota.limit === 1 ? "" : "s"} in use`;
3540
3540
  }
@@ -3978,17 +3978,17 @@ function createApiClient(options) {
3978
3978
  listProjects: (params = {}) => get(`/api/v1/projects${query(params)}`),
3979
3979
  createProject: (body) => request("POST", "/api/v1/projects", body),
3980
3980
  listStarters: () => get("/api/v1/projects/starters"),
3981
- getProject: (id) => get(`/api/v1/projects/${id}`),
3982
- updateProject: (id, body) => request("PATCH", `/api/v1/projects/${id}`, body),
3983
- deleteProject: (id, body) => request("DELETE", `/api/v1/projects/${id}`, body),
3984
- archiveProject: (id) => request("POST", `/api/v1/projects/${id}/archive`),
3985
- unarchiveProject: (id) => request("POST", `/api/v1/projects/${id}/unarchive`),
3981
+ getProject: (id2) => get(`/api/v1/projects/${id2}`),
3982
+ updateProject: (id2, body) => request("PATCH", `/api/v1/projects/${id2}`, body),
3983
+ deleteProject: (id2, body) => request("DELETE", `/api/v1/projects/${id2}`, body),
3984
+ archiveProject: (id2) => request("POST", `/api/v1/projects/${id2}/archive`),
3985
+ unarchiveProject: (id2) => request("POST", `/api/v1/projects/${id2}/unarchive`),
3986
3986
  // Workflows
3987
3987
  listWorkflows: (page = {}) => get(`/api/v1/workflows${query(page)}`),
3988
3988
  createWorkflow: (body) => request("POST", "/api/v1/workflows", body),
3989
- getWorkflow: (id) => get(`/api/v1/workflows/${id}`),
3990
- updateWorkflow: (id, body) => request("PATCH", `/api/v1/workflows/${id}`, body),
3991
- deleteWorkflow: (id, body) => request("DELETE", `/api/v1/workflows/${id}`, body),
3989
+ getWorkflow: (id2) => get(`/api/v1/workflows/${id2}`),
3990
+ updateWorkflow: (id2, body) => request("PATCH", `/api/v1/workflows/${id2}`, body),
3991
+ deleteWorkflow: (id2, body) => request("DELETE", `/api/v1/workflows/${id2}`, body),
3992
3992
  // Issues
3993
3993
  listIssues: (filters = {}) => get(`/api/v1/issues${query(filters)}`),
3994
3994
  listLabels: () => get("/api/v1/labels"),
@@ -4003,14 +4003,14 @@ function createApiClient(options) {
4003
4003
  removeIssueLabel: (issueId, labelRef) => request("DELETE", `/api/v1/issues/${issueId}/labels/${encodeURIComponent(labelRef)}`),
4004
4004
  listProjectIssues: (projectId, filters = {}) => get(`/api/v1/projects/${projectId}/issues${query(filters)}`),
4005
4005
  createIssue: (projectId, body) => request("POST", `/api/v1/projects/${projectId}/issues`, body),
4006
- getIssue: (id) => get(`/api/v1/issues/${id}`),
4006
+ getIssue: (id2) => get(`/api/v1/issues/${id2}`),
4007
4007
  getIssueByNumber: (projectId, number) => get(`/api/v1/projects/${projectId}/issues/${number}`),
4008
- updateIssue: (id, body) => request("PATCH", `/api/v1/issues/${id}`, body),
4009
- transitionIssue: (id, body) => request("POST", `/api/v1/issues/${id}/transition`, body),
4008
+ updateIssue: (id2, body) => request("PATCH", `/api/v1/issues/${id2}`, body),
4009
+ transitionIssue: (id2, body) => request("POST", `/api/v1/issues/${id2}/transition`, body),
4010
4010
  /** Un-park: clears needs_attention, resets the attempt count. */
4011
- resumeIssue: (id) => request("POST", `/api/v1/issues/${id}/resume`),
4011
+ resumeIssue: (id2) => request("POST", `/api/v1/issues/${id2}/resume`),
4012
4012
  /** The dispatch explainer: "why isn't this running?". */
4013
- getIssueDispatch: (id) => get(`/api/v1/issues/${id}/dispatch`),
4013
+ getIssueDispatch: (id2) => get(`/api/v1/issues/${id2}/dispatch`),
4014
4014
  // Issue links (dependencies & duplicates)
4015
4015
  addIssueLink: (issueId, body) => request("POST", `/api/v1/issues/${issueId}/links`, body),
4016
4016
  removeIssueLink: (issueId, linkId) => request("DELETE", `/api/v1/issues/${issueId}/links/${linkId}`),
@@ -4022,19 +4022,19 @@ function createApiClient(options) {
4022
4022
  // Scheduled tasks
4023
4023
  listSchedules: (filters = {}) => get(`/api/v1/schedules${query(filters)}`),
4024
4024
  listProjectSchedules: (projectId, page = {}) => get(`/api/v1/projects/${projectId}/schedules${query(page)}`),
4025
- getSchedule: (id) => get(`/api/v1/schedules/${id}`),
4026
- updateSchedule: (id, body) => request("PATCH", `/api/v1/schedules/${id}`, body),
4027
- deleteSchedule: (id) => request("DELETE", `/api/v1/schedules/${id}`),
4025
+ getSchedule: (id2) => get(`/api/v1/schedules/${id2}`),
4026
+ updateSchedule: (id2, body) => request("PATCH", `/api/v1/schedules/${id2}`, body),
4027
+ deleteSchedule: (id2) => request("DELETE", `/api/v1/schedules/${id2}`),
4028
4028
  /** Run now: creates an instance immediately (gate-respecting; 422 when blocked). */
4029
- runSchedule: (id) => request("POST", `/api/v1/schedules/${id}/run`),
4029
+ runSchedule: (id2) => request("POST", `/api/v1/schedules/${id2}/run`),
4030
4030
  // Context items
4031
4031
  listContext: (filters = {}) => get(`/api/v1/context${query(filters)}`),
4032
4032
  createContextItem: (body) => request("POST", "/api/v1/context", body),
4033
- getContextItem: (id) => get(`/api/v1/context/${id}`),
4034
- updateContextItem: (id, body) => request("PATCH", `/api/v1/context/${id}`, body),
4035
- deleteContextItem: (id) => request("DELETE", `/api/v1/context/${id}`),
4033
+ getContextItem: (id2) => get(`/api/v1/context/${id2}`),
4034
+ updateContextItem: (id2, body) => request("PATCH", `/api/v1/context/${id2}`, body),
4035
+ deleteContextItem: (id2) => request("DELETE", `/api/v1/context/${id2}`),
4036
4036
  /** Atomic append to a prompt item's body (blank-line separated). */
4037
- appendContextItem: (id, body) => request("POST", `/api/v1/context/${id}/append`, body),
4037
+ appendContextItem: (id2, body) => request("POST", `/api/v1/context/${id2}/append`, body),
4038
4038
  /** Effective context for an issue: the assembled bundle. */
4039
4039
  getIssueContext: (issueId) => get(`/api/v1/issues/${issueId}/context`),
4040
4040
  /**
@@ -4114,44 +4114,44 @@ function createApiClient(options) {
4114
4114
  // Runners
4115
4115
  listRunners: () => get("/api/v1/runners"),
4116
4116
  createRunner: (body) => request("POST", "/api/v1/runners", body),
4117
- getRunner: (id) => get(`/api/v1/runners/${id}`),
4118
- updateRunner: (id, body) => request("PATCH", `/api/v1/runners/${id}`, body),
4117
+ getRunner: (id2) => get(`/api/v1/runners/${id2}`),
4118
+ updateRunner: (id2, body) => request("PATCH", `/api/v1/runners/${id2}`, body),
4119
4119
  /** Reject-by-default: 422 names referencing rules/pins unless `force`. */
4120
- deleteRunner: (id, body) => request("DELETE", `/api/v1/runners/${id}`, body),
4120
+ deleteRunner: (id2, body) => request("DELETE", `/api/v1/runners/${id2}`, body),
4121
4121
  /** Create/reconnect a local runner; the response's token is shown once. */
4122
4122
  registerRunner: (body) => request("POST", "/api/v1/runners/register", body),
4123
4123
  /** Invalidate the runner token and mint a fresh one (shown once). */
4124
- rotateRunnerToken: (id) => request("POST", `/api/v1/runners/${id}/rotate-token`),
4124
+ rotateRunnerToken: (id2) => request("POST", `/api/v1/runners/${id2}/rotate-token`),
4125
4125
  // Local runner protocol (runner-token auth: construct the client with
4126
4126
  // the runner token as `apiKey`)
4127
- pollRunner: (id, body) => request("POST", `/api/v1/runners/${id}/poll`, body),
4127
+ pollRunner: (id2, body) => request("POST", `/api/v1/runners/${id2}/poll`, body),
4128
4128
  appendRunLog: (runId, body) => request("POST", `/api/v1/runs/${runId}/logs`, body),
4129
4129
  finishRun: (runId, body) => request("POST", `/api/v1/runs/${runId}/finish`, body),
4130
4130
  // Agent runs
4131
4131
  listRuns: (filters = {}) => get(`/api/v1/runs${query(filters)}`),
4132
- getRun: (id) => get(`/api/v1/runs/${id}`),
4132
+ getRun: (id2) => get(`/api/v1/runs/${id2}`),
4133
4133
  /**
4134
4134
  * The run's complete log (not the 256 KB tail `getRun` returns) as a
4135
4135
  * streamed Response, so a multi-megabyte log never has to be held in
4136
4136
  * memory. `raw` asks for the unrendered harness stream instead.
4137
4137
  */
4138
- getRunLogFull: (id, opts = {}) => raw("GET", `/api/v1/runs/${id}/log${opts.raw ? "?raw=1" : ""}`, {
4138
+ getRunLogFull: (id2, opts = {}) => raw("GET", `/api/v1/runs/${id2}/log${opts.raw ? "?raw=1" : ""}`, {
4139
4139
  headers: { accept: "text/plain" }
4140
4140
  }),
4141
4141
  /** Daemon-only: uploads the raw harness stream for a settled run. */
4142
- putRunLogRaw: (id, body) => raw("PUT", `/api/v1/runs/${id}/log/raw`, {
4142
+ putRunLogRaw: (id2, body) => raw("PUT", `/api/v1/runs/${id2}/log/raw`, {
4143
4143
  body,
4144
4144
  headers: {
4145
4145
  "content-type": "application/x-ndjson",
4146
4146
  "content-length": String(body.byteLength)
4147
4147
  }
4148
4148
  }),
4149
- cancelRun: (id) => request("POST", `/api/v1/runs/${id}/cancel`),
4149
+ cancelRun: (id2) => request("POST", `/api/v1/runs/${id2}/cancel`),
4150
4150
  // Routing rules (one per exact scope; responses carry shadow hints)
4151
4151
  listRoutingRules: () => get("/api/v1/routing-rules"),
4152
4152
  createRoutingRule: (body) => request("POST", "/api/v1/routing-rules", body),
4153
- updateRoutingRule: (id, body) => request("PATCH", `/api/v1/routing-rules/${id}`, body),
4154
- deleteRoutingRule: (id) => request("DELETE", `/api/v1/routing-rules/${id}`),
4153
+ updateRoutingRule: (id2, body) => request("PATCH", `/api/v1/routing-rules/${id2}`, body),
4154
+ deleteRoutingRule: (id2) => request("DELETE", `/api/v1/routing-rules/${id2}`),
4155
4155
  // Supervisor settings
4156
4156
  getPreferences: () => get("/api/v1/preferences"),
4157
4157
  updatePreferences: (body) => request("PATCH", "/api/v1/preferences", body),
@@ -4161,15 +4161,117 @@ function createApiClient(options) {
4161
4161
  // API keys (create/revoke require a browser session, not a key)
4162
4162
  listApiKeys: (filters = {}) => get(`/api/v1/api-keys${query(filters)}`),
4163
4163
  createApiKey: (body) => request("POST", "/api/v1/api-keys", body),
4164
- revokeApiKey: (id) => request("DELETE", `/api/v1/api-keys/${id}`),
4164
+ revokeApiKey: (id2) => request("DELETE", `/api/v1/api-keys/${id2}`),
4165
+ exportWorkflowPackage: (id2, opts = {}) => {
4166
+ const params = new URLSearchParams();
4167
+ if (opts.source_project_id) params.set("source_project_id", opts.source_project_id);
4168
+ for (const id3 of opts.schedule_ids ?? []) params.append("schedule_id", id3);
4169
+ for (const tier of opts.tiers ?? []) params.append("tier", JSON.stringify(tier));
4170
+ if (opts.authoring) params.set("authoring", JSON.stringify(opts.authoring));
4171
+ return get(
4172
+ `/api/v1/workflows/${encodeURIComponent(id2)}/export${params.size ? "?" + params : ""}`
4173
+ );
4174
+ },
4175
+ prepareWorkflowPackage: (body) => request(
4176
+ "POST",
4177
+ "/api/v1/library/prepare",
4178
+ body
4179
+ ),
4180
+ installWorkflowPackage: (body) => request(
4181
+ "POST",
4182
+ "/api/v1/library/install",
4183
+ body
4184
+ ),
4185
+ getWorkflowPackageReceipt: (planId) => get(
4186
+ `/api/v1/library/installs/${encodeURIComponent(planId)}`
4187
+ ),
4188
+ validateLibrary: (body) => request(
4189
+ "POST",
4190
+ "/api/v1/library/validate",
4191
+ body
4192
+ ),
4165
4193
  // Library export / import (workflows + context; no tracker data, no secrets)
4166
- exportLibrary: (opts = {}) => get(`/api/v1/export${opts.journals === false ? "?journals=false" : ""}`),
4194
+ exportLibrary: (opts = {}) => get(
4195
+ `/api/v1/export${query(opts)}`
4196
+ ),
4167
4197
  /** Plan-then-apply; `dry_run: true` returns the preview the apply follows. */
4168
4198
  importLibrary: (body) => request("POST", "/api/v1/import", body)
4169
4199
  };
4170
4200
  }
4171
4201
 
4172
4202
  // ../shared/src/schedule.ts
4203
+ var ScheduleInputError = class extends Error {
4204
+ constructor(message3) {
4205
+ super(message3);
4206
+ this.name = "ScheduleInputError";
4207
+ }
4208
+ };
4209
+ function parseField(spec, fieldName, min, max, normalize = (n) => n) {
4210
+ const values = /* @__PURE__ */ new Set();
4211
+ let restricted = false;
4212
+ const fail = (why) => {
4213
+ throw new ScheduleInputError(`Invalid cron ${fieldName} field "${spec}": ${why}`);
4214
+ };
4215
+ for (const item of spec.split(",")) {
4216
+ const match = item.match(/^(\*|\d+|\d+-\d+)(?:\/(\d+))?$/);
4217
+ if (!match) fail(`"${item}" is not a number, range, "*", or step`);
4218
+ const [, base, stepRaw] = match;
4219
+ const step = stepRaw === void 0 ? 1 : Number.parseInt(stepRaw, 10);
4220
+ if (step < 1) fail("step must be at least 1");
4221
+ let lo;
4222
+ let hi;
4223
+ if (base === "*") {
4224
+ lo = min;
4225
+ hi = max;
4226
+ if (stepRaw !== void 0) restricted = true;
4227
+ } else if (base.includes("-")) {
4228
+ const [a, b] = base.split("-").map((n) => Number.parseInt(n, 10));
4229
+ lo = a;
4230
+ hi = b;
4231
+ restricted = true;
4232
+ } else {
4233
+ lo = hi = Number.parseInt(base, 10);
4234
+ restricted = true;
4235
+ if (stepRaw !== void 0) fail('a step needs a range or "*" before the "/"');
4236
+ }
4237
+ if (lo < min || hi > max) fail(`values must be between ${min} and ${max}`);
4238
+ if (lo > hi) fail(`range ${lo}-${hi} is backwards`);
4239
+ for (let v = lo; v <= hi; v += step) values.add(normalize(v));
4240
+ }
4241
+ return { values, restricted };
4242
+ }
4243
+ function parseCron(expr) {
4244
+ const fields = expr.trim().split(/\s+/);
4245
+ if (fields.length !== 5) {
4246
+ throw new ScheduleInputError(
4247
+ `Cron expression "${expr.trim()}" must have 5 fields (minute hour day-of-month month day-of-week), got ${fields.length}`
4248
+ );
4249
+ }
4250
+ const [m, h, dom, mon, dow] = fields;
4251
+ const minutes = parseField(m, "minute", 0, 59);
4252
+ const hours = parseField(h, "hour", 0, 23);
4253
+ const days = parseField(dom, "day-of-month", 1, 31);
4254
+ const months = parseField(mon, "month", 1, 12);
4255
+ const weekdays = parseField(dow, "day-of-week", 0, 7, (n) => n % 7);
4256
+ return {
4257
+ minutes: minutes.values,
4258
+ hours: hours.values,
4259
+ days: days.values,
4260
+ months: months.values,
4261
+ weekdays: weekdays.values,
4262
+ dayRestricted: days.restricted,
4263
+ weekdayRestricted: weekdays.restricted
4264
+ };
4265
+ }
4266
+ function validateScheduleCron(expr) {
4267
+ const parsed = parseCron(expr);
4268
+ if (parsed.minutes.size > 1) {
4269
+ throw new ScheduleInputError(
4270
+ `Cron expression "${expr.trim()}" would fire more often than once per hour; the minute field must be a single value`
4271
+ );
4272
+ }
4273
+ return parsed;
4274
+ }
4173
4275
  var WEEKDAY_NAMES = [
4174
4276
  "Sunday",
4175
4277
  "Monday",
@@ -4179,24 +4281,79 @@ var WEEKDAY_NAMES = [
4179
4281
  "Friday",
4180
4282
  "Saturday"
4181
4283
  ];
4182
- function describeRecurrence(preset, cron) {
4183
- if (preset) {
4184
- switch (preset.kind) {
4284
+ function parseTimeOfDay(time) {
4285
+ const match = typeof time === "string" ? time.match(/^(\d{1,2}):(\d{2})$/) : null;
4286
+ if (match) {
4287
+ const hour = Number.parseInt(match[1], 10);
4288
+ const minute = Number.parseInt(match[2], 10);
4289
+ if (hour <= 23 && minute <= 59) return { hour, minute };
4290
+ }
4291
+ throw new ScheduleInputError(`Preset time must be "HH:MM" (24-hour), got "${String(time)}"`);
4292
+ }
4293
+ function compilePreset(preset2) {
4294
+ if (preset2.kind === "hourly") {
4295
+ const every = preset2.every_hours;
4296
+ if (typeof every !== "number" || !Number.isInteger(every) || every < 1 || every > 23) {
4297
+ throw new ScheduleInputError("Hourly preset needs an every_hours between 1 and 23");
4298
+ }
4299
+ const minute2 = preset2.minute ?? 0;
4300
+ if (typeof minute2 !== "number" || !Number.isInteger(minute2) || minute2 < 0 || minute2 > 59) {
4301
+ throw new ScheduleInputError("Hourly preset minute must be between 0 and 59");
4302
+ }
4303
+ return every === 1 ? `${minute2} * * * *` : `${minute2} */${every} * * *`;
4304
+ }
4305
+ const { hour, minute } = parseTimeOfDay(preset2.time);
4306
+ switch (preset2.kind) {
4307
+ case "daily":
4308
+ return `${minute} ${hour} * * *`;
4309
+ case "weekly": {
4310
+ const weekday = preset2.weekday;
4311
+ if (typeof weekday !== "number" || !Number.isInteger(weekday) || weekday < 0 || weekday > 6) {
4312
+ throw new ScheduleInputError(
4313
+ "Weekly preset needs a weekday between 0 (Sunday) and 6 (Saturday)"
4314
+ );
4315
+ }
4316
+ return `${minute} ${hour} * * ${weekday}`;
4317
+ }
4318
+ case "monthly": {
4319
+ const day = preset2.day_of_month;
4320
+ if (typeof day !== "number" || !Number.isInteger(day) || day < 1 || day > 31) {
4321
+ throw new ScheduleInputError("Monthly preset needs a day_of_month between 1 and 31");
4322
+ }
4323
+ return `${minute} ${hour} ${day} * *`;
4324
+ }
4325
+ default:
4326
+ throw new ScheduleInputError(
4327
+ `Unknown preset kind "${String(preset2.kind)}"; expected hourly, daily, weekly, or monthly`
4328
+ );
4329
+ }
4330
+ }
4331
+ function describeRecurrence(preset2, cron) {
4332
+ if (preset2) {
4333
+ switch (preset2.kind) {
4185
4334
  case "hourly": {
4186
- const every = preset.every_hours ?? 1;
4187
- const at = preset.minute ? ` at :${String(preset.minute).padStart(2, "0")}` : "";
4335
+ const every = preset2.every_hours ?? 1;
4336
+ const at = preset2.minute ? ` at :${String(preset2.minute).padStart(2, "0")}` : "";
4188
4337
  return every === 1 ? `Every hour${at}` : `Every ${every} hours${at}`;
4189
4338
  }
4190
4339
  case "daily":
4191
- return `Every day at ${preset.time}`;
4340
+ return `Every day at ${preset2.time}`;
4192
4341
  case "weekly":
4193
- return `Every ${WEEKDAY_NAMES[preset.weekday ?? 0]} at ${preset.time}`;
4342
+ return `Every ${WEEKDAY_NAMES[preset2.weekday ?? 0]} at ${preset2.time}`;
4194
4343
  case "monthly":
4195
- return `Monthly on day ${preset.day_of_month} at ${preset.time}`;
4344
+ return `Monthly on day ${preset2.day_of_month} at ${preset2.time}`;
4196
4345
  }
4197
4346
  }
4198
4347
  return `Cron \u201C${cron}\u201D`;
4199
4348
  }
4349
+ function validateTimezone(tz) {
4350
+ try {
4351
+ new Intl.DateTimeFormat("en-US", { timeZone: tz });
4352
+ return tz;
4353
+ } catch {
4354
+ throw new ScheduleInputError(`Unknown timezone "${tz}"; use an IANA name like "Europe/London"`);
4355
+ }
4356
+ }
4200
4357
  var PLACEHOLDER_DESCRIPTIONS = {
4201
4358
  date: "run date, e.g. 2026-08-23",
4202
4359
  time: "run time, e.g. 09:30",
@@ -4242,6 +4399,136 @@ async function listAll(fetchPage, opts = {}) {
4242
4399
  // ../shared/src/routing.ts
4243
4400
  var INHERIT_RUNNER_ID = "*";
4244
4401
 
4402
+ // ../shared/src/library/types.ts
4403
+ var LibraryValidationError = class extends Error {
4404
+ constructor(diagnostics) {
4405
+ super(diagnostics[0]?.message ?? "Invalid library document");
4406
+ this.diagnostics = diagnostics;
4407
+ this.name = "LibraryValidationError";
4408
+ }
4409
+ diagnostics;
4410
+ };
4411
+
4412
+ // ../shared/src/library/schema.ts
4413
+ var pointer = (path2, key) => `${path2}/${String(key).replaceAll("~", "~0").replaceAll("/", "~1")}`;
4414
+ function invalid(path2, code, message3) {
4415
+ throw new LibraryValidationError([{ path: path2, code, message: message3 }]);
4416
+ }
4417
+ function validateUnicode(value, path2) {
4418
+ for (let i = 0; i < value.length; i++) {
4419
+ const unit = value.charCodeAt(i);
4420
+ if (unit >= 55296 && unit <= 56319) {
4421
+ const next = value.charCodeAt(++i);
4422
+ if (!(next >= 56320 && next <= 57343))
4423
+ invalid(path2, "invalid_unicode", "Lone UTF-16 surrogate is not allowed");
4424
+ } else if (unit >= 56320 && unit <= 57343)
4425
+ invalid(path2, "invalid_unicode", "Lone UTF-16 surrogate is not allowed");
4426
+ }
4427
+ }
4428
+ var text2 = (max, nonempty = false) => (v, p) => {
4429
+ if (typeof v !== "string") invalid(p, "invalid_type", "Expected a string");
4430
+ validateUnicode(v, p);
4431
+ if (v.length > max || nonempty && !v.trim())
4432
+ invalid(
4433
+ p,
4434
+ "invalid_field",
4435
+ `Expected ${nonempty ? "non-empty " : ""}text of at most ${max} characters`
4436
+ );
4437
+ };
4438
+ var bool = (v, p) => {
4439
+ if (typeof v !== "boolean") invalid(p, "invalid_type", "Expected a boolean");
4440
+ };
4441
+ var integer = (v, p) => {
4442
+ if (!Number.isSafeInteger(v) || v < 0)
4443
+ invalid(p, "invalid_integer", "Expected a non-negative safe integer");
4444
+ };
4445
+ var oneOf = (values) => (v, p) => {
4446
+ if (!values.includes(v)) invalid(p, "invalid_value", `Expected one of ${values.join(", ")}`);
4447
+ };
4448
+ var nullable = (check) => (v, p) => {
4449
+ if (v !== null) check(v, p);
4450
+ };
4451
+ function object(v, p) {
4452
+ if (!v || typeof v !== "object" || Array.isArray(v) || ![null, Object.prototype].includes(Object.getPrototypeOf(v)))
4453
+ invalid(p, "invalid_type", "Expected a plain object");
4454
+ return v;
4455
+ }
4456
+ var shape = (required, optional = {}) => (v, p) => {
4457
+ const o = object(v, p);
4458
+ for (const key of Object.keys(o)) {
4459
+ validateUnicode(key, pointer(p, key));
4460
+ if (!Object.hasOwn(required, key) && !Object.hasOwn(optional, key))
4461
+ invalid(pointer(p, key), "unknown_field", `Unknown field ${key}`);
4462
+ }
4463
+ for (const [key, check] of Object.entries(required)) {
4464
+ if (!Object.hasOwn(o, key))
4465
+ invalid(pointer(p, key), "missing_field", `Missing required field ${key}`);
4466
+ check(o[key], pointer(p, key));
4467
+ }
4468
+ for (const [key, check] of Object.entries(optional))
4469
+ if (Object.hasOwn(o, key)) check(o[key], pointer(p, key));
4470
+ };
4471
+ var discriminated = (key, variants) => (v, p) => {
4472
+ const o = object(v, p);
4473
+ if (typeof o[key] !== "string" || !Object.hasOwn(variants, o[key]))
4474
+ invalid(pointer(p, key), "invalid_discriminator", `Unknown ${key}`);
4475
+ variants[o[key]](v, p);
4476
+ };
4477
+ var id = (v, p) => {
4478
+ text2(80, true)(v, p);
4479
+ if (!/^[A-Za-z0-9:_-]{1,80}$/.test(v))
4480
+ invalid(p, "invalid_local_id", "Invalid document-local ID");
4481
+ };
4482
+ var bundledState = shape({ kind: oneOf(["bundled_state"]), state_id: id });
4483
+ var systemState = shape({
4484
+ kind: oneOf(["system_state"]),
4485
+ workflow: oneOf(["Standard"]),
4486
+ state_name: text2(100, true)
4487
+ });
4488
+ var bundledWorkflow = shape({ kind: oneOf(["bundled_workflow"]), workflow_id: id });
4489
+ var projectRef = shape({ kind: oneOf(["input_project"]), input_id: id });
4490
+ var preset = discriminated("kind", {
4491
+ hourly: shape({ kind: oneOf(["hourly"]), every_hours: integer }, { minute: integer }),
4492
+ daily: shape({ kind: oneOf(["daily"]), time: text2(5, true) }),
4493
+ weekly: shape({ kind: oneOf(["weekly"]), time: text2(5, true), weekday: integer }),
4494
+ monthly: shape({ kind: oneOf(["monthly"]), time: text2(5, true), day_of_month: integer })
4495
+ });
4496
+ var recurrence = (v, p) => {
4497
+ discriminated("kind", {
4498
+ preset: shape({ kind: oneOf(["preset"]), preset }),
4499
+ cron: shape({ kind: oneOf(["cron"]), cron: text2(100, true) })
4500
+ })(v, p);
4501
+ const o = v;
4502
+ try {
4503
+ validateScheduleCron(o.kind === "preset" ? compilePreset(o.preset) : o.cron);
4504
+ } catch (e) {
4505
+ invalid(p, "invalid_recurrence", e.message);
4506
+ }
4507
+ };
4508
+ var timezone = (v, p) => {
4509
+ text2(100, true)(v, p);
4510
+ try {
4511
+ validateTimezone(v);
4512
+ } catch (e) {
4513
+ invalid(p, "invalid_timezone", e.message);
4514
+ }
4515
+ };
4516
+ var schedule = shape({
4517
+ id,
4518
+ workflow: bundledWorkflow,
4519
+ project: projectRef,
4520
+ name: text2(200, true),
4521
+ title_template: text2(500, true),
4522
+ description_template: text2(1e5),
4523
+ recurrence,
4524
+ timezone,
4525
+ require_all_closed: bool,
4526
+ start_state: nullable(bundledState)
4527
+ });
4528
+
4529
+ // ../shared/src/library/choices.ts
4530
+ var PACKAGE_CHOICES_MAX_BYTES = 512 * 1024;
4531
+
4245
4532
  // src/format.ts
4246
4533
  function timestamp(ms) {
4247
4534
  return new Date(ms).toISOString().replace("T", " ").slice(0, 19);
@@ -4258,8 +4545,8 @@ function contextItemSummary(item) {
4258
4545
  return item.artifact_type ?? "artifact";
4259
4546
  }
4260
4547
  }
4261
- function recurrenceLabel(schedule) {
4262
- return `${describeRecurrence(schedule.preset, schedule.cron)}, ${schedule.timezone}`;
4548
+ function recurrenceLabel(schedule2) {
4549
+ return `${describeRecurrence(schedule2.preset, schedule2.cron)}, ${schedule2.timezone}`;
4263
4550
  }
4264
4551
  function issueRef(ref) {
4265
4552
  return `${ref.project_name}/${ref.number}`;
@@ -4365,7 +4652,7 @@ function ruleTargetsLabel(rule) {
4365
4652
  function quotaLabel(quota, stateName) {
4366
4653
  if (quota.type === "global_cap") return `global cap: at most ${quota.limit} concurrent runs`;
4367
4654
  const overrides = Object.entries(quota.overrides).map(
4368
- ([id, limit]) => `${stateName ? stateName(id) : id}=${limit}`
4655
+ ([id2, limit]) => `${stateName ? stateName(id2) : id2}=${limit}`
4369
4656
  );
4370
4657
  return `state roster: default ${quota.default_limit} per state${overrides.length > 0 ? `, overrides: ${overrides.join(", ")}` : ""}`;
4371
4658
  }
@@ -4899,8 +5186,8 @@ function register(program3) {
4899
5186
  );
4900
5187
  withCommon(
4901
5188
  context.command("show <id>").description("Show a context item (skills include their files)")
4902
- ).action(async (id, opts) => {
4903
- const item = await client(opts).getContextItem(id);
5189
+ ).action(async (id2, opts) => {
5190
+ const item = await client(opts).getContextItem(id2);
4904
5191
  if (opts.json) return printJson(item);
4905
5192
  printContextItem(item);
4906
5193
  });
@@ -4954,7 +5241,7 @@ function register(program3) {
4954
5241
  )
4955
5242
  )
4956
5243
  ).action(
4957
- async (id, opts) => {
5244
+ async (id2, opts) => {
4958
5245
  const api = client(opts);
4959
5246
  const body = {};
4960
5247
  if (opts.expectVersion !== void 0) body.expected_version = opts.expectVersion;
@@ -4971,7 +5258,7 @@ function register(program3) {
4971
5258
  }
4972
5259
  if (opts.body !== void 0) body.body = readBodyValue(opts.body);
4973
5260
  if (opts.file.length > 0 || opts.removeFile.length > 0) {
4974
- const current = await api.getContextItem(id);
5261
+ const current = await api.getContextItem(id2);
4975
5262
  if (current.kind !== "skill")
4976
5263
  die(`--file/--remove-file only apply to skills (this is a ${current.kind})`);
4977
5264
  if (body.expected_version === void 0) body.expected_version = current.version;
@@ -4997,16 +5284,16 @@ function register(program3) {
4997
5284
  "nothing to update: pass payload flags, --name/--description, scope flags, and/or --unset"
4998
5285
  );
4999
5286
  }
5000
- const item = await api.updateContextItem(id, body);
5287
+ const item = await api.updateContextItem(id2, body);
5001
5288
  if (opts.json) return printJson(item);
5002
5289
  console.log(`updated ${item.kind} "${item.name}" (${item.id}) \u2014 scope: ${item.scope.label}`);
5003
5290
  }
5004
5291
  );
5005
5292
  withCommon(context.command("delete <id>").description("Delete a context item")).action(
5006
- async (id, opts) => {
5293
+ async (id2, opts) => {
5007
5294
  const api = client(opts);
5008
- const item = await api.getContextItem(id);
5009
- await api.deleteContextItem(id);
5295
+ const item = await api.getContextItem(id2);
5296
+ await api.deleteContextItem(id2);
5010
5297
  console.log(`deleted ${item.kind} "${item.name}" (${item.id}) \u2014 scope: ${item.scope.label}`);
5011
5298
  }
5012
5299
  );
@@ -5145,9 +5432,9 @@ function conflictLines(preview) {
5145
5432
  ]) {
5146
5433
  if (!context.conflicts.length) lines.push(`${label}: none`);
5147
5434
  for (const conflict of context.conflicts) {
5148
- const participants = conflict.item_ids.map((id) => {
5149
- const repo = context.repos.find((item) => item.item_id === id);
5150
- return repo ? `${repo.name} (${repo.scope.label})` : id;
5435
+ const participants = conflict.item_ids.map((id2) => {
5436
+ const repo = context.repos.find((item) => item.item_id === id2);
5437
+ return repo ? `${repo.name} (${repo.scope.label})` : id2;
5151
5438
  }).join(", ");
5152
5439
  lines.push(`${label}: ${conflict.dir} \u2014 ${participants}`);
5153
5440
  }
@@ -5920,17 +6207,17 @@ function register2(program3) {
5920
6207
  []
5921
6208
  )
5922
6209
  ).action(
5923
- async (projectRef, opts) => {
6210
+ async (projectRef2, opts) => {
5924
6211
  const description = opts.description !== void 0 ? readBodyValue(opts.description) : void 0;
5925
6212
  const api = client(opts);
5926
- const project = await resolveProject(api, projectRef);
6213
+ const project = await resolveProject(api, projectRef2);
5927
6214
  const workflowId = opts.workflow ? (await resolveWorkflow(api, opts.workflow)).id : void 0;
5928
- const recurrence = buildRecurrence(opts);
5929
- if (!recurrence && (opts.ifClosed !== void 0 || opts.scheduleName !== void 0)) {
6215
+ const recurrence2 = buildRecurrence(opts);
6216
+ if (!recurrence2 && (opts.ifClosed !== void 0 || opts.scheduleName !== void 0)) {
5930
6217
  die('--if-closed/--schedule-name need a recurrence: add --every \u2026 or --cron "<expr>"');
5931
6218
  }
5932
- const schedule = recurrence ? {
5933
- ...recurrence,
6219
+ const schedule2 = recurrence2 ? {
6220
+ ...recurrence2,
5934
6221
  name: opts.scheduleName,
5935
6222
  timezone: opts.tz ?? systemTimezone(),
5936
6223
  require_all_closed: opts.ifClosed ?? false
@@ -5940,7 +6227,7 @@ function register2(program3) {
5940
6227
  description,
5941
6228
  workflow_id: workflowId,
5942
6229
  state: opts.state,
5943
- schedule,
6230
+ schedule: schedule2,
5944
6231
  labels: opts.label
5945
6232
  });
5946
6233
  if (opts.json) return printJson(issue);
@@ -6014,9 +6301,9 @@ function register2(program3) {
6014
6301
  const destination = await resolveProject(api, opts.project);
6015
6302
  let preview = await api.previewIssueTransfer(issue.id, destination.id);
6016
6303
  if (opts.inspect !== void 0) {
6017
- const text3 = formatTransferItem(preview, Number(opts.inspect));
6018
- if (opts.json) return printJson({ ...preview, inspected: text3 });
6019
- return console.log(text3);
6304
+ const text4 = formatTransferItem(preview, Number(opts.inspect));
6305
+ if (opts.json) return printJson({ ...preview, inspected: text4 });
6306
+ return console.log(text4);
6020
6307
  }
6021
6308
  if (opts.dryRun) {
6022
6309
  if (opts.json) return printJson(preview);
@@ -6047,7 +6334,7 @@ function register2(program3) {
6047
6334
  }
6048
6335
  const rl = interactive ? createInterface({ input: process.stdin, output: process.stderr }) : null;
6049
6336
  const terminal = {
6050
- write: (text3) => process.stderr.write(text3),
6337
+ write: (text4) => process.stderr.write(text4),
6051
6338
  ask: (question) => rl.question(question).catch(() => null)
6052
6339
  };
6053
6340
  try {
@@ -6719,12 +7006,12 @@ start one: tines journal append ${issue.project_name}/${issue.number} "- <date>:
6719
7006
  ).action(
6720
7007
  async (ref, markdown, opts, command) => {
6721
7008
  if (helpGuard(command, markdown)) return;
6722
- const text3 = readBodyValue(markdown);
7009
+ const text4 = readBodyValue(markdown);
6723
7010
  const api = client(opts);
6724
7011
  const { scope, note, item } = await resolveJournal(api, ref, opts.state);
6725
7012
  printNote(note);
6726
7013
  if (item) {
6727
- const updated = await api.appendContextItem(item.id, { text: text3 });
7014
+ const updated = await api.appendContextItem(item.id, { text: text4 });
6728
7015
  if (opts.json) return printJson(updated);
6729
7016
  return console.log(`appended to the ${scope.label} journal (now v${updated.version})`);
6730
7017
  }
@@ -6734,7 +7021,7 @@ start one: tines journal append ${issue.project_name}/${issue.number} "- <date>:
6734
7021
  name: JOURNAL_NAME,
6735
7022
  project_id: scope.project_id ?? void 0,
6736
7023
  workflow_state_id: scope.workflow_state_id ?? void 0,
6737
- body: text3.trim()
7024
+ body: text4.trim()
6738
7025
  });
6739
7026
  if (opts.json) return printJson(created);
6740
7027
  console.log(`started the ${scope.label} journal (${created.id})`);
@@ -6742,7 +7029,7 @@ start one: tines journal append ${issue.project_name}/${issue.number} "- <date>:
6742
7029
  if (!(err instanceof ApiError) || err.code !== "duplicate_context_name") throw err;
6743
7030
  const { item: fresh } = await resolveJournal(api, ref, opts.state);
6744
7031
  if (!fresh) throw err;
6745
- const updated = await api.appendContextItem(fresh.id, { text: text3 });
7032
+ const updated = await api.appendContextItem(fresh.id, { text: text4 });
6746
7033
  if (opts.json) return printJson(updated);
6747
7034
  console.log(`appended to the ${scope.label} journal (now v${updated.version})`);
6748
7035
  }
@@ -7462,10 +7749,10 @@ var ClaudeStreamRenderer = class {
7462
7749
  };
7463
7750
 
7464
7751
  // src/daemon/codex-stream.ts
7465
- function object(value) {
7752
+ function object2(value) {
7466
7753
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
7467
7754
  }
7468
- function text2(value) {
7755
+ function text3(value) {
7469
7756
  return typeof value === "string" && value.trim() ? value.trim() : void 0;
7470
7757
  }
7471
7758
  function renderCodexEvent(event) {
@@ -7474,35 +7761,35 @@ function renderCodexEvent(event) {
7474
7761
  if (type === "turn.started") return ["[session] turn started"];
7475
7762
  if (type === "turn.completed") return ["[session] turn completed"];
7476
7763
  if (type === "turn.failed") {
7477
- const error = object(event.error);
7478
- return [`[error] ${clip(text2(error?.message) ?? text2(event.message) ?? "turn failed", 2e3)}`];
7764
+ const error = object2(event.error);
7765
+ return [`[error] ${clip(text3(error?.message) ?? text3(event.message) ?? "turn failed", 2e3)}`];
7479
7766
  }
7480
- if (type === "error") return [`[error] ${clip(text2(event.message) ?? "unknown error", 2e3)}`];
7767
+ if (type === "error") return [`[error] ${clip(text3(event.message) ?? "unknown error", 2e3)}`];
7481
7768
  if (type !== "item.completed") return [];
7482
- const item = object(event.item);
7769
+ const item = object2(event.item);
7483
7770
  if (!item) return [];
7484
7771
  switch (item.type) {
7485
7772
  case "agent_message":
7486
- return text2(item.text) ? [`[agent] ${clip(text2(item.text), 2e3)}`] : [];
7773
+ return text3(item.text) ? [`[agent] ${clip(text3(item.text), 2e3)}`] : [];
7487
7774
  case "command_execution": {
7488
- const command = text2(item.command) ?? "command";
7775
+ const command = text3(item.command) ?? "command";
7489
7776
  const failed = validMetric(item.exit_code) && item.exit_code !== 0;
7490
- const output = failed ? text2(item.aggregated_output) : void 0;
7777
+ const output = failed ? text3(item.aggregated_output) : void 0;
7491
7778
  return [
7492
7779
  `[tool] ${clip(command, 300)}${failed ? ` (exit ${item.exit_code}${output ? `: ${clip(output, 300)}` : ""})` : ""}`
7493
7780
  ];
7494
7781
  }
7495
7782
  case "file_change": {
7496
7783
  const changes = Array.isArray(item.changes) ? item.changes : [];
7497
- const paths = changes.map((change) => text2(object(change)?.path)).filter((path2) => Boolean(path2));
7784
+ const paths = changes.map((change) => text3(object2(change)?.path)).filter((path2) => Boolean(path2));
7498
7785
  return [`[tool] file change${paths.length ? `: ${clip(paths.join(", "), 300)}` : ""}`];
7499
7786
  }
7500
7787
  case "mcp_tool_call":
7501
7788
  return [
7502
- `[tool] ${clip([text2(item.server), text2(item.tool)].filter(Boolean).join("/") || "MCP call", 300)}`
7789
+ `[tool] ${clip([text3(item.server), text3(item.tool)].filter(Boolean).join("/") || "MCP call", 300)}`
7503
7790
  ];
7504
7791
  case "web_search":
7505
- return [`[tool] web search${text2(item.query) ? `: ${clip(text2(item.query), 300)}` : ""}`];
7792
+ return [`[tool] web search${text3(item.query) ? `: ${clip(text3(item.query), 300)}` : ""}`];
7506
7793
  default:
7507
7794
  return [];
7508
7795
  }
@@ -7539,7 +7826,7 @@ var CodexStreamRenderer = class {
7539
7826
  let event;
7540
7827
  try {
7541
7828
  const parsed = JSON.parse(trimmed);
7542
- const parsedObject = object(parsed);
7829
+ const parsedObject = object2(parsed);
7543
7830
  if (!parsedObject) return;
7544
7831
  event = parsedObject;
7545
7832
  } catch {
@@ -7556,7 +7843,7 @@ var CodexStreamRenderer = class {
7556
7843
  this.collected.providerSessionId = event.thread_id;
7557
7844
  }
7558
7845
  if (event.type !== "turn.completed") return;
7559
- const raw = object(event.usage);
7846
+ const raw = object2(event.usage);
7560
7847
  if (!raw) return;
7561
7848
  const totalInput = validMetric(raw.input_tokens) ? raw.input_tokens : void 0;
7562
7849
  const rawCached = validMetric(raw.cached_input_tokens) ? raw.cached_input_tokens : void 0;
@@ -7673,8 +7960,8 @@ function zonedDate(zone, at) {
7673
7960
  return { y: get("year"), m: get("month") - 1, d: get("day") };
7674
7961
  }
7675
7962
  var DURATION = /(\d+)\s*([dhms])/g;
7676
- function parseResetTime(text3, now) {
7677
- const raw = text3.trim();
7963
+ function parseResetTime(text4, now) {
7964
+ const raw = text4.trim();
7678
7965
  if (!raw) return null;
7679
7966
  const relative = raw.match(/^in\s+(.+)$/i);
7680
7967
  if (relative) {
@@ -7954,9 +8241,9 @@ var LogBatcher = class {
7954
8241
  seq = 0;
7955
8242
  /** Chunks awaiting a successful send, oldest first. */
7956
8243
  pending = [];
7957
- append(text3) {
7958
- if (!text3) return;
7959
- this.buffer += text3;
8244
+ append(text4) {
8245
+ if (!text4) return;
8246
+ this.buffer += text4;
7960
8247
  if (Buffer.byteLength(this.buffer, "utf8") >= (this.opts.maxBytes ?? 32 * 1024)) {
7961
8248
  void this.flush();
7962
8249
  } else if (!this.timer) {
@@ -8688,9 +8975,9 @@ async function runDaemon(opts) {
8688
8975
  child.stdout?.on("data", (data) => run.batcher.append(data.toString("utf8")));
8689
8976
  }
8690
8977
  child.stderr?.on("data", (data) => {
8691
- const text3 = data.toString("utf8");
8692
- run.batcher.append(text3);
8693
- run.limiter?.noteStderr(text3);
8978
+ const text4 = data.toString("utf8");
8979
+ run.batcher.append(text4);
8980
+ run.limiter?.noteStderr(text4);
8694
8981
  });
8695
8982
  run.timeout = setTimeout(() => {
8696
8983
  if (run.settled) return;
@@ -9280,9 +9567,9 @@ function register8(program3) {
9280
9567
  withCommon(
9281
9568
  runsCmd.command("show <id>").description("Show a run; --logs prints the captured log tail, --logs --full the whole log").option("--logs", "print the log tail").option("--full", "with --logs: print the complete log, not the 256 KB tail").option("--raw", "with --logs --full: print the unrendered harness stream instead")
9282
9569
  ).action(
9283
- async (id, opts) => {
9570
+ async (id2, opts) => {
9284
9571
  const api = client(opts);
9285
- const run = await api.getRun(id);
9572
+ const run = await api.getRun(id2);
9286
9573
  if (opts.json) return printJson(run);
9287
9574
  console.log(
9288
9575
  `${run.id} ${run.status} on ${run.runner_name}${run.resumed_from_run_id ? ` \xB7 resumed run ${run.resumed_from_run_id}` : ""}`
@@ -9314,7 +9601,7 @@ function register8(program3) {
9314
9601
  if (opts.logs) {
9315
9602
  console.log("");
9316
9603
  if (opts.full || opts.raw) {
9317
- const res = await api.getRunLogFull(id, { raw: opts.raw });
9604
+ const res = await api.getRunLogFull(id2, { raw: opts.raw });
9318
9605
  const body = res.body;
9319
9606
  if (!body) return;
9320
9607
  const reader = body.getReader();
@@ -9338,9 +9625,9 @@ function register8(program3) {
9338
9625
  );
9339
9626
  withCommon(
9340
9627
  runsCmd.command("cancel <id>").description("Cancel a run (judged like any other end: usually a strike)")
9341
- ).action(async (id, opts) => {
9628
+ ).action(async (id2, opts) => {
9342
9629
  const api = client(opts);
9343
- const run = await api.cancelRun(id);
9630
+ const run = await api.cancelRun(id2);
9344
9631
  if (opts.json) return printJson(run);
9345
9632
  console.log(
9346
9633
  `canceled ${run.id}${run.issue_ref ? ` on ${issueRef(run.issue_ref)}` : ""} (was on ${run.runner_name})`
@@ -9411,10 +9698,10 @@ function register9(program3) {
9411
9698
  schedules.command("show <ref>").description("Show a schedule (<project>/<name>): config, next/last run, recent instances")
9412
9699
  ).action(async (ref, opts) => {
9413
9700
  const api = client(opts);
9414
- const schedule = await resolveSchedule(api, ref);
9415
- if (opts.json) return printJson(schedule);
9416
- printScheduleDetail(schedule);
9417
- const { items } = await api.listIssues({ schedule: schedule.id, limit: 10 });
9701
+ const schedule2 = await resolveSchedule(api, ref);
9702
+ if (opts.json) return printJson(schedule2);
9703
+ printScheduleDetail(schedule2);
9704
+ const { items } = await api.listIssues({ schedule: schedule2.id, limit: 10 });
9418
9705
  if (items.length > 0) {
9419
9706
  console.log(`
9420
9707
  recent instances:`);
@@ -9451,16 +9738,16 @@ recent instances:`);
9451
9738
  async (ref, opts) => {
9452
9739
  const descriptionTemplate = opts.description !== void 0 ? readBodyValue(opts.description) : void 0;
9453
9740
  const api = client(opts);
9454
- const schedule = await resolveSchedule(api, ref);
9741
+ const schedule2 = await resolveSchedule(api, ref);
9455
9742
  const body = {};
9456
9743
  if (opts.title !== void 0) body.title_template = opts.title;
9457
9744
  if (descriptionTemplate !== void 0) body.description_template = descriptionTemplate;
9458
9745
  if (opts.workflow !== void 0)
9459
9746
  body.workflow_id = (await resolveWorkflow(api, opts.workflow)).id;
9460
9747
  if (opts.state !== void 0) body.state = opts.state;
9461
- const recurrence = buildRecurrence(opts);
9462
- if (recurrence?.preset) body.preset = recurrence.preset;
9463
- if (recurrence?.cron !== void 0) body.cron = recurrence.cron;
9748
+ const recurrence2 = buildRecurrence(opts);
9749
+ if (recurrence2?.preset) body.preset = recurrence2.preset;
9750
+ if (recurrence2?.cron !== void 0) body.cron = recurrence2.cron;
9464
9751
  if (opts.tz !== void 0) body.timezone = opts.tz;
9465
9752
  if (opts.ifClosed !== void 0) body.require_all_closed = opts.ifClosed;
9466
9753
  if (opts.name !== void 0) body.name = opts.name;
@@ -9469,7 +9756,7 @@ recent instances:`);
9469
9756
  "nothing to update: pass --title, --description, --workflow, --state, --every/--at/--on, --cron, --tz, --[no-]if-closed, and/or --name"
9470
9757
  );
9471
9758
  }
9472
- const updated = await api.updateSchedule(schedule.id, body);
9759
+ const updated = await api.updateSchedule(schedule2.id, body);
9473
9760
  if (opts.json) return printJson(updated);
9474
9761
  console.log(`updated schedule "${scheduleRef(updated)}"
9475
9762
  `);
@@ -9480,8 +9767,8 @@ recent instances:`);
9480
9767
  schedules.command("pause <ref>").description("Pause a schedule (keeps config and history)")
9481
9768
  ).action(async (ref, opts) => {
9482
9769
  const api = client(opts);
9483
- const schedule = await resolveSchedule(api, ref);
9484
- const updated = await api.updateSchedule(schedule.id, { enabled: false });
9770
+ const schedule2 = await resolveSchedule(api, ref);
9771
+ const updated = await api.updateSchedule(schedule2.id, { enabled: false });
9485
9772
  if (opts.json) return printJson(updated);
9486
9773
  console.log(`paused schedule "${scheduleRef(updated)}"`);
9487
9774
  });
@@ -9489,8 +9776,8 @@ recent instances:`);
9489
9776
  schedules.command("resume <ref>").description("Resume a paused schedule (recomputes the next occurrence from now)")
9490
9777
  ).action(async (ref, opts) => {
9491
9778
  const api = client(opts);
9492
- const schedule = await resolveSchedule(api, ref);
9493
- const updated = await api.updateSchedule(schedule.id, { enabled: true });
9779
+ const schedule2 = await resolveSchedule(api, ref);
9780
+ const updated = await api.updateSchedule(schedule2.id, { enabled: true });
9494
9781
  if (opts.json) return printJson(updated);
9495
9782
  console.log(
9496
9783
  `resumed schedule "${scheduleRef(updated)}" \u2014 next run ${timestamp(updated.next_run_at)}`
@@ -9500,8 +9787,8 @@ recent instances:`);
9500
9787
  schedules.command("run <ref>").description("Create an instance now (respects the only-when-closed gate)")
9501
9788
  ).action(async (ref, opts) => {
9502
9789
  const api = client(opts);
9503
- const schedule = await resolveSchedule(api, ref);
9504
- const issue = await api.runSchedule(schedule.id);
9790
+ const schedule2 = await resolveSchedule(api, ref);
9791
+ const issue = await api.runSchedule(schedule2.id);
9505
9792
  if (opts.json) return printJson(issue);
9506
9793
  console.log(
9507
9794
  `created ${issue.project_name}/#${issue.number} "${issue.title}" in state "${issue.state.name}"`
@@ -9511,17 +9798,17 @@ recent instances:`);
9511
9798
  schedules.command("delete <ref>").description("Delete a schedule (existing issues are kept)").option("-y, --yes", "skip the confirmation prompt")
9512
9799
  ).action(async (ref, opts) => {
9513
9800
  const api = client(opts);
9514
- const schedule = await resolveSchedule(api, ref);
9801
+ const schedule2 = await resolveSchedule(api, ref);
9515
9802
  if (!opts.yes) {
9516
9803
  const rl = createInterface3({ input: process.stdin, output: process.stdout });
9517
9804
  const answer = await rl.question(
9518
- `Delete schedule "${scheduleRef(schedule)}"? Its ${schedule.run_count} existing issue${schedule.run_count === 1 ? "" : "s"} will be kept. [y/N] `
9805
+ `Delete schedule "${scheduleRef(schedule2)}"? Its ${schedule2.run_count} existing issue${schedule2.run_count === 1 ? "" : "s"} will be kept. [y/N] `
9519
9806
  );
9520
9807
  rl.close();
9521
9808
  if (!/^y(es)?$/i.test(answer.trim())) die("aborted");
9522
9809
  }
9523
- await api.deleteSchedule(schedule.id);
9524
- console.log(`deleted schedule "${scheduleRef(schedule)}" (issues kept)`);
9810
+ await api.deleteSchedule(schedule2.id);
9811
+ console.log(`deleted schedule "${scheduleRef(schedule2)}" (issues kept)`);
9525
9812
  });
9526
9813
  }
9527
9814
 
@@ -9640,9 +9927,9 @@ function register10(program3) {
9640
9927
  console.log(
9641
9928
  `automation: ${settings.enabled ? "ON" : "OFF (kill switch \u2014 nothing dispatches)"}`
9642
9929
  );
9643
- console.log(quotaLabel(settings.quota, (id) => stateNames.get(id) ?? id));
9930
+ console.log(quotaLabel(settings.quota, (id2) => stateNames.get(id2) ?? id2));
9644
9931
  console.log(
9645
- `utilization: ${utilizationLabel(settings.quota, activeRunItems, (id) => stateNames.get(id) ?? id)}`
9932
+ `utilization: ${utilizationLabel(settings.quota, activeRunItems, (id2) => stateNames.get(id2) ?? id2)}`
9646
9933
  );
9647
9934
  console.log(`attempt limit: ${settings.attempt_limit} strikes, then the issue parks`);
9648
9935
  if (queue.waiting === 0) {
@@ -9737,7 +10024,7 @@ function register10(program3) {
9737
10024
  for (const wf of workflows.items) {
9738
10025
  for (const s of wf.states) stateNames.set(s.id, `${wf.name}/${s.name}`);
9739
10026
  }
9740
- console.log(quotaLabel(settings.quota, (id) => stateNames.get(id) ?? id));
10027
+ console.log(quotaLabel(settings.quota, (id2) => stateNames.get(id2) ?? id2));
9741
10028
  });
9742
10029
  }
9743
10030
 
@@ -9838,9 +10125,9 @@ async function loadLibrary(api) {
9838
10125
  return { workflows, states, children };
9839
10126
  }
9840
10127
  var qualify = (entry) => `${entry.workflow.name} / ${entry.state.name}`;
9841
- function stateLabel(lib, id) {
9842
- const entry = lib.states.get(id);
9843
- return entry ? qualify(entry) : id;
10128
+ function stateLabel(lib, id2) {
10129
+ const entry = lib.states.get(id2);
10130
+ return entry ? qualify(entry) : id2;
9844
10131
  }
9845
10132
  function inheritanceLines(lib, state) {
9846
10133
  const lines = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tines",
3
- "version": "0.0.178",
3
+ "version": "0.0.180",
4
4
  "description": "CLI for Tines, an orchestration layer for AI agents",
5
5
  "repository": {
6
6
  "type": "git",