tines 0.0.178 → 0.0.179

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 +412 -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,109 @@ 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
+ validateLibrary: (body) => request(
4181
+ "POST",
4182
+ "/api/v1/library/validate",
4183
+ body
4184
+ ),
4165
4185
  // Library export / import (workflows + context; no tracker data, no secrets)
4166
- exportLibrary: (opts = {}) => get(`/api/v1/export${opts.journals === false ? "?journals=false" : ""}`),
4186
+ exportLibrary: (opts = {}) => get(
4187
+ `/api/v1/export${query(opts)}`
4188
+ ),
4167
4189
  /** Plan-then-apply; `dry_run: true` returns the preview the apply follows. */
4168
4190
  importLibrary: (body) => request("POST", "/api/v1/import", body)
4169
4191
  };
4170
4192
  }
4171
4193
 
4172
4194
  // ../shared/src/schedule.ts
4195
+ var ScheduleInputError = class extends Error {
4196
+ constructor(message3) {
4197
+ super(message3);
4198
+ this.name = "ScheduleInputError";
4199
+ }
4200
+ };
4201
+ function parseField(spec, fieldName, min, max, normalize = (n) => n) {
4202
+ const values = /* @__PURE__ */ new Set();
4203
+ let restricted = false;
4204
+ const fail = (why) => {
4205
+ throw new ScheduleInputError(`Invalid cron ${fieldName} field "${spec}": ${why}`);
4206
+ };
4207
+ for (const item of spec.split(",")) {
4208
+ const match = item.match(/^(\*|\d+|\d+-\d+)(?:\/(\d+))?$/);
4209
+ if (!match) fail(`"${item}" is not a number, range, "*", or step`);
4210
+ const [, base, stepRaw] = match;
4211
+ const step = stepRaw === void 0 ? 1 : Number.parseInt(stepRaw, 10);
4212
+ if (step < 1) fail("step must be at least 1");
4213
+ let lo;
4214
+ let hi;
4215
+ if (base === "*") {
4216
+ lo = min;
4217
+ hi = max;
4218
+ if (stepRaw !== void 0) restricted = true;
4219
+ } else if (base.includes("-")) {
4220
+ const [a, b] = base.split("-").map((n) => Number.parseInt(n, 10));
4221
+ lo = a;
4222
+ hi = b;
4223
+ restricted = true;
4224
+ } else {
4225
+ lo = hi = Number.parseInt(base, 10);
4226
+ restricted = true;
4227
+ if (stepRaw !== void 0) fail('a step needs a range or "*" before the "/"');
4228
+ }
4229
+ if (lo < min || hi > max) fail(`values must be between ${min} and ${max}`);
4230
+ if (lo > hi) fail(`range ${lo}-${hi} is backwards`);
4231
+ for (let v = lo; v <= hi; v += step) values.add(normalize(v));
4232
+ }
4233
+ return { values, restricted };
4234
+ }
4235
+ function parseCron(expr) {
4236
+ const fields = expr.trim().split(/\s+/);
4237
+ if (fields.length !== 5) {
4238
+ throw new ScheduleInputError(
4239
+ `Cron expression "${expr.trim()}" must have 5 fields (minute hour day-of-month month day-of-week), got ${fields.length}`
4240
+ );
4241
+ }
4242
+ const [m, h, dom, mon, dow] = fields;
4243
+ const minutes = parseField(m, "minute", 0, 59);
4244
+ const hours = parseField(h, "hour", 0, 23);
4245
+ const days = parseField(dom, "day-of-month", 1, 31);
4246
+ const months = parseField(mon, "month", 1, 12);
4247
+ const weekdays = parseField(dow, "day-of-week", 0, 7, (n) => n % 7);
4248
+ return {
4249
+ minutes: minutes.values,
4250
+ hours: hours.values,
4251
+ days: days.values,
4252
+ months: months.values,
4253
+ weekdays: weekdays.values,
4254
+ dayRestricted: days.restricted,
4255
+ weekdayRestricted: weekdays.restricted
4256
+ };
4257
+ }
4258
+ function validateScheduleCron(expr) {
4259
+ const parsed = parseCron(expr);
4260
+ if (parsed.minutes.size > 1) {
4261
+ throw new ScheduleInputError(
4262
+ `Cron expression "${expr.trim()}" would fire more often than once per hour; the minute field must be a single value`
4263
+ );
4264
+ }
4265
+ return parsed;
4266
+ }
4173
4267
  var WEEKDAY_NAMES = [
4174
4268
  "Sunday",
4175
4269
  "Monday",
@@ -4179,24 +4273,79 @@ var WEEKDAY_NAMES = [
4179
4273
  "Friday",
4180
4274
  "Saturday"
4181
4275
  ];
4182
- function describeRecurrence(preset, cron) {
4183
- if (preset) {
4184
- switch (preset.kind) {
4276
+ function parseTimeOfDay(time) {
4277
+ const match = typeof time === "string" ? time.match(/^(\d{1,2}):(\d{2})$/) : null;
4278
+ if (match) {
4279
+ const hour = Number.parseInt(match[1], 10);
4280
+ const minute = Number.parseInt(match[2], 10);
4281
+ if (hour <= 23 && minute <= 59) return { hour, minute };
4282
+ }
4283
+ throw new ScheduleInputError(`Preset time must be "HH:MM" (24-hour), got "${String(time)}"`);
4284
+ }
4285
+ function compilePreset(preset2) {
4286
+ if (preset2.kind === "hourly") {
4287
+ const every = preset2.every_hours;
4288
+ if (typeof every !== "number" || !Number.isInteger(every) || every < 1 || every > 23) {
4289
+ throw new ScheduleInputError("Hourly preset needs an every_hours between 1 and 23");
4290
+ }
4291
+ const minute2 = preset2.minute ?? 0;
4292
+ if (typeof minute2 !== "number" || !Number.isInteger(minute2) || minute2 < 0 || minute2 > 59) {
4293
+ throw new ScheduleInputError("Hourly preset minute must be between 0 and 59");
4294
+ }
4295
+ return every === 1 ? `${minute2} * * * *` : `${minute2} */${every} * * *`;
4296
+ }
4297
+ const { hour, minute } = parseTimeOfDay(preset2.time);
4298
+ switch (preset2.kind) {
4299
+ case "daily":
4300
+ return `${minute} ${hour} * * *`;
4301
+ case "weekly": {
4302
+ const weekday = preset2.weekday;
4303
+ if (typeof weekday !== "number" || !Number.isInteger(weekday) || weekday < 0 || weekday > 6) {
4304
+ throw new ScheduleInputError(
4305
+ "Weekly preset needs a weekday between 0 (Sunday) and 6 (Saturday)"
4306
+ );
4307
+ }
4308
+ return `${minute} ${hour} * * ${weekday}`;
4309
+ }
4310
+ case "monthly": {
4311
+ const day = preset2.day_of_month;
4312
+ if (typeof day !== "number" || !Number.isInteger(day) || day < 1 || day > 31) {
4313
+ throw new ScheduleInputError("Monthly preset needs a day_of_month between 1 and 31");
4314
+ }
4315
+ return `${minute} ${hour} ${day} * *`;
4316
+ }
4317
+ default:
4318
+ throw new ScheduleInputError(
4319
+ `Unknown preset kind "${String(preset2.kind)}"; expected hourly, daily, weekly, or monthly`
4320
+ );
4321
+ }
4322
+ }
4323
+ function describeRecurrence(preset2, cron) {
4324
+ if (preset2) {
4325
+ switch (preset2.kind) {
4185
4326
  case "hourly": {
4186
- const every = preset.every_hours ?? 1;
4187
- const at = preset.minute ? ` at :${String(preset.minute).padStart(2, "0")}` : "";
4327
+ const every = preset2.every_hours ?? 1;
4328
+ const at = preset2.minute ? ` at :${String(preset2.minute).padStart(2, "0")}` : "";
4188
4329
  return every === 1 ? `Every hour${at}` : `Every ${every} hours${at}`;
4189
4330
  }
4190
4331
  case "daily":
4191
- return `Every day at ${preset.time}`;
4332
+ return `Every day at ${preset2.time}`;
4192
4333
  case "weekly":
4193
- return `Every ${WEEKDAY_NAMES[preset.weekday ?? 0]} at ${preset.time}`;
4334
+ return `Every ${WEEKDAY_NAMES[preset2.weekday ?? 0]} at ${preset2.time}`;
4194
4335
  case "monthly":
4195
- return `Monthly on day ${preset.day_of_month} at ${preset.time}`;
4336
+ return `Monthly on day ${preset2.day_of_month} at ${preset2.time}`;
4196
4337
  }
4197
4338
  }
4198
4339
  return `Cron \u201C${cron}\u201D`;
4199
4340
  }
4341
+ function validateTimezone(tz) {
4342
+ try {
4343
+ new Intl.DateTimeFormat("en-US", { timeZone: tz });
4344
+ return tz;
4345
+ } catch {
4346
+ throw new ScheduleInputError(`Unknown timezone "${tz}"; use an IANA name like "Europe/London"`);
4347
+ }
4348
+ }
4200
4349
  var PLACEHOLDER_DESCRIPTIONS = {
4201
4350
  date: "run date, e.g. 2026-08-23",
4202
4351
  time: "run time, e.g. 09:30",
@@ -4242,6 +4391,136 @@ async function listAll(fetchPage, opts = {}) {
4242
4391
  // ../shared/src/routing.ts
4243
4392
  var INHERIT_RUNNER_ID = "*";
4244
4393
 
4394
+ // ../shared/src/library/types.ts
4395
+ var LibraryValidationError = class extends Error {
4396
+ constructor(diagnostics) {
4397
+ super(diagnostics[0]?.message ?? "Invalid library document");
4398
+ this.diagnostics = diagnostics;
4399
+ this.name = "LibraryValidationError";
4400
+ }
4401
+ diagnostics;
4402
+ };
4403
+
4404
+ // ../shared/src/library/schema.ts
4405
+ var pointer = (path2, key) => `${path2}/${String(key).replaceAll("~", "~0").replaceAll("/", "~1")}`;
4406
+ function invalid(path2, code, message3) {
4407
+ throw new LibraryValidationError([{ path: path2, code, message: message3 }]);
4408
+ }
4409
+ function validateUnicode(value, path2) {
4410
+ for (let i = 0; i < value.length; i++) {
4411
+ const unit = value.charCodeAt(i);
4412
+ if (unit >= 55296 && unit <= 56319) {
4413
+ const next = value.charCodeAt(++i);
4414
+ if (!(next >= 56320 && next <= 57343))
4415
+ invalid(path2, "invalid_unicode", "Lone UTF-16 surrogate is not allowed");
4416
+ } else if (unit >= 56320 && unit <= 57343)
4417
+ invalid(path2, "invalid_unicode", "Lone UTF-16 surrogate is not allowed");
4418
+ }
4419
+ }
4420
+ var text2 = (max, nonempty = false) => (v, p) => {
4421
+ if (typeof v !== "string") invalid(p, "invalid_type", "Expected a string");
4422
+ validateUnicode(v, p);
4423
+ if (v.length > max || nonempty && !v.trim())
4424
+ invalid(
4425
+ p,
4426
+ "invalid_field",
4427
+ `Expected ${nonempty ? "non-empty " : ""}text of at most ${max} characters`
4428
+ );
4429
+ };
4430
+ var bool = (v, p) => {
4431
+ if (typeof v !== "boolean") invalid(p, "invalid_type", "Expected a boolean");
4432
+ };
4433
+ var integer = (v, p) => {
4434
+ if (!Number.isSafeInteger(v) || v < 0)
4435
+ invalid(p, "invalid_integer", "Expected a non-negative safe integer");
4436
+ };
4437
+ var oneOf = (values) => (v, p) => {
4438
+ if (!values.includes(v)) invalid(p, "invalid_value", `Expected one of ${values.join(", ")}`);
4439
+ };
4440
+ var nullable = (check) => (v, p) => {
4441
+ if (v !== null) check(v, p);
4442
+ };
4443
+ function object(v, p) {
4444
+ if (!v || typeof v !== "object" || Array.isArray(v) || ![null, Object.prototype].includes(Object.getPrototypeOf(v)))
4445
+ invalid(p, "invalid_type", "Expected a plain object");
4446
+ return v;
4447
+ }
4448
+ var shape = (required, optional = {}) => (v, p) => {
4449
+ const o = object(v, p);
4450
+ for (const key of Object.keys(o)) {
4451
+ validateUnicode(key, pointer(p, key));
4452
+ if (!Object.hasOwn(required, key) && !Object.hasOwn(optional, key))
4453
+ invalid(pointer(p, key), "unknown_field", `Unknown field ${key}`);
4454
+ }
4455
+ for (const [key, check] of Object.entries(required)) {
4456
+ if (!Object.hasOwn(o, key))
4457
+ invalid(pointer(p, key), "missing_field", `Missing required field ${key}`);
4458
+ check(o[key], pointer(p, key));
4459
+ }
4460
+ for (const [key, check] of Object.entries(optional))
4461
+ if (Object.hasOwn(o, key)) check(o[key], pointer(p, key));
4462
+ };
4463
+ var discriminated = (key, variants) => (v, p) => {
4464
+ const o = object(v, p);
4465
+ if (typeof o[key] !== "string" || !Object.hasOwn(variants, o[key]))
4466
+ invalid(pointer(p, key), "invalid_discriminator", `Unknown ${key}`);
4467
+ variants[o[key]](v, p);
4468
+ };
4469
+ var id = (v, p) => {
4470
+ text2(80, true)(v, p);
4471
+ if (!/^[A-Za-z0-9:_-]{1,80}$/.test(v))
4472
+ invalid(p, "invalid_local_id", "Invalid document-local ID");
4473
+ };
4474
+ var bundledState = shape({ kind: oneOf(["bundled_state"]), state_id: id });
4475
+ var systemState = shape({
4476
+ kind: oneOf(["system_state"]),
4477
+ workflow: oneOf(["Standard"]),
4478
+ state_name: text2(100, true)
4479
+ });
4480
+ var bundledWorkflow = shape({ kind: oneOf(["bundled_workflow"]), workflow_id: id });
4481
+ var projectRef = shape({ kind: oneOf(["input_project"]), input_id: id });
4482
+ var preset = discriminated("kind", {
4483
+ hourly: shape({ kind: oneOf(["hourly"]), every_hours: integer }, { minute: integer }),
4484
+ daily: shape({ kind: oneOf(["daily"]), time: text2(5, true) }),
4485
+ weekly: shape({ kind: oneOf(["weekly"]), time: text2(5, true), weekday: integer }),
4486
+ monthly: shape({ kind: oneOf(["monthly"]), time: text2(5, true), day_of_month: integer })
4487
+ });
4488
+ var recurrence = (v, p) => {
4489
+ discriminated("kind", {
4490
+ preset: shape({ kind: oneOf(["preset"]), preset }),
4491
+ cron: shape({ kind: oneOf(["cron"]), cron: text2(100, true) })
4492
+ })(v, p);
4493
+ const o = v;
4494
+ try {
4495
+ validateScheduleCron(o.kind === "preset" ? compilePreset(o.preset) : o.cron);
4496
+ } catch (e) {
4497
+ invalid(p, "invalid_recurrence", e.message);
4498
+ }
4499
+ };
4500
+ var timezone = (v, p) => {
4501
+ text2(100, true)(v, p);
4502
+ try {
4503
+ validateTimezone(v);
4504
+ } catch (e) {
4505
+ invalid(p, "invalid_timezone", e.message);
4506
+ }
4507
+ };
4508
+ var schedule = shape({
4509
+ id,
4510
+ workflow: bundledWorkflow,
4511
+ project: projectRef,
4512
+ name: text2(200, true),
4513
+ title_template: text2(500, true),
4514
+ description_template: text2(1e5),
4515
+ recurrence,
4516
+ timezone,
4517
+ require_all_closed: bool,
4518
+ start_state: nullable(bundledState)
4519
+ });
4520
+
4521
+ // ../shared/src/library/choices.ts
4522
+ var PACKAGE_CHOICES_MAX_BYTES = 512 * 1024;
4523
+
4245
4524
  // src/format.ts
4246
4525
  function timestamp(ms) {
4247
4526
  return new Date(ms).toISOString().replace("T", " ").slice(0, 19);
@@ -4258,8 +4537,8 @@ function contextItemSummary(item) {
4258
4537
  return item.artifact_type ?? "artifact";
4259
4538
  }
4260
4539
  }
4261
- function recurrenceLabel(schedule) {
4262
- return `${describeRecurrence(schedule.preset, schedule.cron)}, ${schedule.timezone}`;
4540
+ function recurrenceLabel(schedule2) {
4541
+ return `${describeRecurrence(schedule2.preset, schedule2.cron)}, ${schedule2.timezone}`;
4263
4542
  }
4264
4543
  function issueRef(ref) {
4265
4544
  return `${ref.project_name}/${ref.number}`;
@@ -4365,7 +4644,7 @@ function ruleTargetsLabel(rule) {
4365
4644
  function quotaLabel(quota, stateName) {
4366
4645
  if (quota.type === "global_cap") return `global cap: at most ${quota.limit} concurrent runs`;
4367
4646
  const overrides = Object.entries(quota.overrides).map(
4368
- ([id, limit]) => `${stateName ? stateName(id) : id}=${limit}`
4647
+ ([id2, limit]) => `${stateName ? stateName(id2) : id2}=${limit}`
4369
4648
  );
4370
4649
  return `state roster: default ${quota.default_limit} per state${overrides.length > 0 ? `, overrides: ${overrides.join(", ")}` : ""}`;
4371
4650
  }
@@ -4899,8 +5178,8 @@ function register(program3) {
4899
5178
  );
4900
5179
  withCommon(
4901
5180
  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);
5181
+ ).action(async (id2, opts) => {
5182
+ const item = await client(opts).getContextItem(id2);
4904
5183
  if (opts.json) return printJson(item);
4905
5184
  printContextItem(item);
4906
5185
  });
@@ -4954,7 +5233,7 @@ function register(program3) {
4954
5233
  )
4955
5234
  )
4956
5235
  ).action(
4957
- async (id, opts) => {
5236
+ async (id2, opts) => {
4958
5237
  const api = client(opts);
4959
5238
  const body = {};
4960
5239
  if (opts.expectVersion !== void 0) body.expected_version = opts.expectVersion;
@@ -4971,7 +5250,7 @@ function register(program3) {
4971
5250
  }
4972
5251
  if (opts.body !== void 0) body.body = readBodyValue(opts.body);
4973
5252
  if (opts.file.length > 0 || opts.removeFile.length > 0) {
4974
- const current = await api.getContextItem(id);
5253
+ const current = await api.getContextItem(id2);
4975
5254
  if (current.kind !== "skill")
4976
5255
  die(`--file/--remove-file only apply to skills (this is a ${current.kind})`);
4977
5256
  if (body.expected_version === void 0) body.expected_version = current.version;
@@ -4997,16 +5276,16 @@ function register(program3) {
4997
5276
  "nothing to update: pass payload flags, --name/--description, scope flags, and/or --unset"
4998
5277
  );
4999
5278
  }
5000
- const item = await api.updateContextItem(id, body);
5279
+ const item = await api.updateContextItem(id2, body);
5001
5280
  if (opts.json) return printJson(item);
5002
5281
  console.log(`updated ${item.kind} "${item.name}" (${item.id}) \u2014 scope: ${item.scope.label}`);
5003
5282
  }
5004
5283
  );
5005
5284
  withCommon(context.command("delete <id>").description("Delete a context item")).action(
5006
- async (id, opts) => {
5285
+ async (id2, opts) => {
5007
5286
  const api = client(opts);
5008
- const item = await api.getContextItem(id);
5009
- await api.deleteContextItem(id);
5287
+ const item = await api.getContextItem(id2);
5288
+ await api.deleteContextItem(id2);
5010
5289
  console.log(`deleted ${item.kind} "${item.name}" (${item.id}) \u2014 scope: ${item.scope.label}`);
5011
5290
  }
5012
5291
  );
@@ -5145,9 +5424,9 @@ function conflictLines(preview) {
5145
5424
  ]) {
5146
5425
  if (!context.conflicts.length) lines.push(`${label}: none`);
5147
5426
  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;
5427
+ const participants = conflict.item_ids.map((id2) => {
5428
+ const repo = context.repos.find((item) => item.item_id === id2);
5429
+ return repo ? `${repo.name} (${repo.scope.label})` : id2;
5151
5430
  }).join(", ");
5152
5431
  lines.push(`${label}: ${conflict.dir} \u2014 ${participants}`);
5153
5432
  }
@@ -5920,17 +6199,17 @@ function register2(program3) {
5920
6199
  []
5921
6200
  )
5922
6201
  ).action(
5923
- async (projectRef, opts) => {
6202
+ async (projectRef2, opts) => {
5924
6203
  const description = opts.description !== void 0 ? readBodyValue(opts.description) : void 0;
5925
6204
  const api = client(opts);
5926
- const project = await resolveProject(api, projectRef);
6205
+ const project = await resolveProject(api, projectRef2);
5927
6206
  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)) {
6207
+ const recurrence2 = buildRecurrence(opts);
6208
+ if (!recurrence2 && (opts.ifClosed !== void 0 || opts.scheduleName !== void 0)) {
5930
6209
  die('--if-closed/--schedule-name need a recurrence: add --every \u2026 or --cron "<expr>"');
5931
6210
  }
5932
- const schedule = recurrence ? {
5933
- ...recurrence,
6211
+ const schedule2 = recurrence2 ? {
6212
+ ...recurrence2,
5934
6213
  name: opts.scheduleName,
5935
6214
  timezone: opts.tz ?? systemTimezone(),
5936
6215
  require_all_closed: opts.ifClosed ?? false
@@ -5940,7 +6219,7 @@ function register2(program3) {
5940
6219
  description,
5941
6220
  workflow_id: workflowId,
5942
6221
  state: opts.state,
5943
- schedule,
6222
+ schedule: schedule2,
5944
6223
  labels: opts.label
5945
6224
  });
5946
6225
  if (opts.json) return printJson(issue);
@@ -6014,9 +6293,9 @@ function register2(program3) {
6014
6293
  const destination = await resolveProject(api, opts.project);
6015
6294
  let preview = await api.previewIssueTransfer(issue.id, destination.id);
6016
6295
  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);
6296
+ const text4 = formatTransferItem(preview, Number(opts.inspect));
6297
+ if (opts.json) return printJson({ ...preview, inspected: text4 });
6298
+ return console.log(text4);
6020
6299
  }
6021
6300
  if (opts.dryRun) {
6022
6301
  if (opts.json) return printJson(preview);
@@ -6047,7 +6326,7 @@ function register2(program3) {
6047
6326
  }
6048
6327
  const rl = interactive ? createInterface({ input: process.stdin, output: process.stderr }) : null;
6049
6328
  const terminal = {
6050
- write: (text3) => process.stderr.write(text3),
6329
+ write: (text4) => process.stderr.write(text4),
6051
6330
  ask: (question) => rl.question(question).catch(() => null)
6052
6331
  };
6053
6332
  try {
@@ -6719,12 +6998,12 @@ start one: tines journal append ${issue.project_name}/${issue.number} "- <date>:
6719
6998
  ).action(
6720
6999
  async (ref, markdown, opts, command) => {
6721
7000
  if (helpGuard(command, markdown)) return;
6722
- const text3 = readBodyValue(markdown);
7001
+ const text4 = readBodyValue(markdown);
6723
7002
  const api = client(opts);
6724
7003
  const { scope, note, item } = await resolveJournal(api, ref, opts.state);
6725
7004
  printNote(note);
6726
7005
  if (item) {
6727
- const updated = await api.appendContextItem(item.id, { text: text3 });
7006
+ const updated = await api.appendContextItem(item.id, { text: text4 });
6728
7007
  if (opts.json) return printJson(updated);
6729
7008
  return console.log(`appended to the ${scope.label} journal (now v${updated.version})`);
6730
7009
  }
@@ -6734,7 +7013,7 @@ start one: tines journal append ${issue.project_name}/${issue.number} "- <date>:
6734
7013
  name: JOURNAL_NAME,
6735
7014
  project_id: scope.project_id ?? void 0,
6736
7015
  workflow_state_id: scope.workflow_state_id ?? void 0,
6737
- body: text3.trim()
7016
+ body: text4.trim()
6738
7017
  });
6739
7018
  if (opts.json) return printJson(created);
6740
7019
  console.log(`started the ${scope.label} journal (${created.id})`);
@@ -6742,7 +7021,7 @@ start one: tines journal append ${issue.project_name}/${issue.number} "- <date>:
6742
7021
  if (!(err instanceof ApiError) || err.code !== "duplicate_context_name") throw err;
6743
7022
  const { item: fresh } = await resolveJournal(api, ref, opts.state);
6744
7023
  if (!fresh) throw err;
6745
- const updated = await api.appendContextItem(fresh.id, { text: text3 });
7024
+ const updated = await api.appendContextItem(fresh.id, { text: text4 });
6746
7025
  if (opts.json) return printJson(updated);
6747
7026
  console.log(`appended to the ${scope.label} journal (now v${updated.version})`);
6748
7027
  }
@@ -7462,10 +7741,10 @@ var ClaudeStreamRenderer = class {
7462
7741
  };
7463
7742
 
7464
7743
  // src/daemon/codex-stream.ts
7465
- function object(value) {
7744
+ function object2(value) {
7466
7745
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
7467
7746
  }
7468
- function text2(value) {
7747
+ function text3(value) {
7469
7748
  return typeof value === "string" && value.trim() ? value.trim() : void 0;
7470
7749
  }
7471
7750
  function renderCodexEvent(event) {
@@ -7474,35 +7753,35 @@ function renderCodexEvent(event) {
7474
7753
  if (type === "turn.started") return ["[session] turn started"];
7475
7754
  if (type === "turn.completed") return ["[session] turn completed"];
7476
7755
  if (type === "turn.failed") {
7477
- const error = object(event.error);
7478
- return [`[error] ${clip(text2(error?.message) ?? text2(event.message) ?? "turn failed", 2e3)}`];
7756
+ const error = object2(event.error);
7757
+ return [`[error] ${clip(text3(error?.message) ?? text3(event.message) ?? "turn failed", 2e3)}`];
7479
7758
  }
7480
- if (type === "error") return [`[error] ${clip(text2(event.message) ?? "unknown error", 2e3)}`];
7759
+ if (type === "error") return [`[error] ${clip(text3(event.message) ?? "unknown error", 2e3)}`];
7481
7760
  if (type !== "item.completed") return [];
7482
- const item = object(event.item);
7761
+ const item = object2(event.item);
7483
7762
  if (!item) return [];
7484
7763
  switch (item.type) {
7485
7764
  case "agent_message":
7486
- return text2(item.text) ? [`[agent] ${clip(text2(item.text), 2e3)}`] : [];
7765
+ return text3(item.text) ? [`[agent] ${clip(text3(item.text), 2e3)}`] : [];
7487
7766
  case "command_execution": {
7488
- const command = text2(item.command) ?? "command";
7767
+ const command = text3(item.command) ?? "command";
7489
7768
  const failed = validMetric(item.exit_code) && item.exit_code !== 0;
7490
- const output = failed ? text2(item.aggregated_output) : void 0;
7769
+ const output = failed ? text3(item.aggregated_output) : void 0;
7491
7770
  return [
7492
7771
  `[tool] ${clip(command, 300)}${failed ? ` (exit ${item.exit_code}${output ? `: ${clip(output, 300)}` : ""})` : ""}`
7493
7772
  ];
7494
7773
  }
7495
7774
  case "file_change": {
7496
7775
  const changes = Array.isArray(item.changes) ? item.changes : [];
7497
- const paths = changes.map((change) => text2(object(change)?.path)).filter((path2) => Boolean(path2));
7776
+ const paths = changes.map((change) => text3(object2(change)?.path)).filter((path2) => Boolean(path2));
7498
7777
  return [`[tool] file change${paths.length ? `: ${clip(paths.join(", "), 300)}` : ""}`];
7499
7778
  }
7500
7779
  case "mcp_tool_call":
7501
7780
  return [
7502
- `[tool] ${clip([text2(item.server), text2(item.tool)].filter(Boolean).join("/") || "MCP call", 300)}`
7781
+ `[tool] ${clip([text3(item.server), text3(item.tool)].filter(Boolean).join("/") || "MCP call", 300)}`
7503
7782
  ];
7504
7783
  case "web_search":
7505
- return [`[tool] web search${text2(item.query) ? `: ${clip(text2(item.query), 300)}` : ""}`];
7784
+ return [`[tool] web search${text3(item.query) ? `: ${clip(text3(item.query), 300)}` : ""}`];
7506
7785
  default:
7507
7786
  return [];
7508
7787
  }
@@ -7539,7 +7818,7 @@ var CodexStreamRenderer = class {
7539
7818
  let event;
7540
7819
  try {
7541
7820
  const parsed = JSON.parse(trimmed);
7542
- const parsedObject = object(parsed);
7821
+ const parsedObject = object2(parsed);
7543
7822
  if (!parsedObject) return;
7544
7823
  event = parsedObject;
7545
7824
  } catch {
@@ -7556,7 +7835,7 @@ var CodexStreamRenderer = class {
7556
7835
  this.collected.providerSessionId = event.thread_id;
7557
7836
  }
7558
7837
  if (event.type !== "turn.completed") return;
7559
- const raw = object(event.usage);
7838
+ const raw = object2(event.usage);
7560
7839
  if (!raw) return;
7561
7840
  const totalInput = validMetric(raw.input_tokens) ? raw.input_tokens : void 0;
7562
7841
  const rawCached = validMetric(raw.cached_input_tokens) ? raw.cached_input_tokens : void 0;
@@ -7673,8 +7952,8 @@ function zonedDate(zone, at) {
7673
7952
  return { y: get("year"), m: get("month") - 1, d: get("day") };
7674
7953
  }
7675
7954
  var DURATION = /(\d+)\s*([dhms])/g;
7676
- function parseResetTime(text3, now) {
7677
- const raw = text3.trim();
7955
+ function parseResetTime(text4, now) {
7956
+ const raw = text4.trim();
7678
7957
  if (!raw) return null;
7679
7958
  const relative = raw.match(/^in\s+(.+)$/i);
7680
7959
  if (relative) {
@@ -7954,9 +8233,9 @@ var LogBatcher = class {
7954
8233
  seq = 0;
7955
8234
  /** Chunks awaiting a successful send, oldest first. */
7956
8235
  pending = [];
7957
- append(text3) {
7958
- if (!text3) return;
7959
- this.buffer += text3;
8236
+ append(text4) {
8237
+ if (!text4) return;
8238
+ this.buffer += text4;
7960
8239
  if (Buffer.byteLength(this.buffer, "utf8") >= (this.opts.maxBytes ?? 32 * 1024)) {
7961
8240
  void this.flush();
7962
8241
  } else if (!this.timer) {
@@ -8688,9 +8967,9 @@ async function runDaemon(opts) {
8688
8967
  child.stdout?.on("data", (data) => run.batcher.append(data.toString("utf8")));
8689
8968
  }
8690
8969
  child.stderr?.on("data", (data) => {
8691
- const text3 = data.toString("utf8");
8692
- run.batcher.append(text3);
8693
- run.limiter?.noteStderr(text3);
8970
+ const text4 = data.toString("utf8");
8971
+ run.batcher.append(text4);
8972
+ run.limiter?.noteStderr(text4);
8694
8973
  });
8695
8974
  run.timeout = setTimeout(() => {
8696
8975
  if (run.settled) return;
@@ -9280,9 +9559,9 @@ function register8(program3) {
9280
9559
  withCommon(
9281
9560
  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
9561
  ).action(
9283
- async (id, opts) => {
9562
+ async (id2, opts) => {
9284
9563
  const api = client(opts);
9285
- const run = await api.getRun(id);
9564
+ const run = await api.getRun(id2);
9286
9565
  if (opts.json) return printJson(run);
9287
9566
  console.log(
9288
9567
  `${run.id} ${run.status} on ${run.runner_name}${run.resumed_from_run_id ? ` \xB7 resumed run ${run.resumed_from_run_id}` : ""}`
@@ -9314,7 +9593,7 @@ function register8(program3) {
9314
9593
  if (opts.logs) {
9315
9594
  console.log("");
9316
9595
  if (opts.full || opts.raw) {
9317
- const res = await api.getRunLogFull(id, { raw: opts.raw });
9596
+ const res = await api.getRunLogFull(id2, { raw: opts.raw });
9318
9597
  const body = res.body;
9319
9598
  if (!body) return;
9320
9599
  const reader = body.getReader();
@@ -9338,9 +9617,9 @@ function register8(program3) {
9338
9617
  );
9339
9618
  withCommon(
9340
9619
  runsCmd.command("cancel <id>").description("Cancel a run (judged like any other end: usually a strike)")
9341
- ).action(async (id, opts) => {
9620
+ ).action(async (id2, opts) => {
9342
9621
  const api = client(opts);
9343
- const run = await api.cancelRun(id);
9622
+ const run = await api.cancelRun(id2);
9344
9623
  if (opts.json) return printJson(run);
9345
9624
  console.log(
9346
9625
  `canceled ${run.id}${run.issue_ref ? ` on ${issueRef(run.issue_ref)}` : ""} (was on ${run.runner_name})`
@@ -9411,10 +9690,10 @@ function register9(program3) {
9411
9690
  schedules.command("show <ref>").description("Show a schedule (<project>/<name>): config, next/last run, recent instances")
9412
9691
  ).action(async (ref, opts) => {
9413
9692
  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 });
9693
+ const schedule2 = await resolveSchedule(api, ref);
9694
+ if (opts.json) return printJson(schedule2);
9695
+ printScheduleDetail(schedule2);
9696
+ const { items } = await api.listIssues({ schedule: schedule2.id, limit: 10 });
9418
9697
  if (items.length > 0) {
9419
9698
  console.log(`
9420
9699
  recent instances:`);
@@ -9451,16 +9730,16 @@ recent instances:`);
9451
9730
  async (ref, opts) => {
9452
9731
  const descriptionTemplate = opts.description !== void 0 ? readBodyValue(opts.description) : void 0;
9453
9732
  const api = client(opts);
9454
- const schedule = await resolveSchedule(api, ref);
9733
+ const schedule2 = await resolveSchedule(api, ref);
9455
9734
  const body = {};
9456
9735
  if (opts.title !== void 0) body.title_template = opts.title;
9457
9736
  if (descriptionTemplate !== void 0) body.description_template = descriptionTemplate;
9458
9737
  if (opts.workflow !== void 0)
9459
9738
  body.workflow_id = (await resolveWorkflow(api, opts.workflow)).id;
9460
9739
  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;
9740
+ const recurrence2 = buildRecurrence(opts);
9741
+ if (recurrence2?.preset) body.preset = recurrence2.preset;
9742
+ if (recurrence2?.cron !== void 0) body.cron = recurrence2.cron;
9464
9743
  if (opts.tz !== void 0) body.timezone = opts.tz;
9465
9744
  if (opts.ifClosed !== void 0) body.require_all_closed = opts.ifClosed;
9466
9745
  if (opts.name !== void 0) body.name = opts.name;
@@ -9469,7 +9748,7 @@ recent instances:`);
9469
9748
  "nothing to update: pass --title, --description, --workflow, --state, --every/--at/--on, --cron, --tz, --[no-]if-closed, and/or --name"
9470
9749
  );
9471
9750
  }
9472
- const updated = await api.updateSchedule(schedule.id, body);
9751
+ const updated = await api.updateSchedule(schedule2.id, body);
9473
9752
  if (opts.json) return printJson(updated);
9474
9753
  console.log(`updated schedule "${scheduleRef(updated)}"
9475
9754
  `);
@@ -9480,8 +9759,8 @@ recent instances:`);
9480
9759
  schedules.command("pause <ref>").description("Pause a schedule (keeps config and history)")
9481
9760
  ).action(async (ref, opts) => {
9482
9761
  const api = client(opts);
9483
- const schedule = await resolveSchedule(api, ref);
9484
- const updated = await api.updateSchedule(schedule.id, { enabled: false });
9762
+ const schedule2 = await resolveSchedule(api, ref);
9763
+ const updated = await api.updateSchedule(schedule2.id, { enabled: false });
9485
9764
  if (opts.json) return printJson(updated);
9486
9765
  console.log(`paused schedule "${scheduleRef(updated)}"`);
9487
9766
  });
@@ -9489,8 +9768,8 @@ recent instances:`);
9489
9768
  schedules.command("resume <ref>").description("Resume a paused schedule (recomputes the next occurrence from now)")
9490
9769
  ).action(async (ref, opts) => {
9491
9770
  const api = client(opts);
9492
- const schedule = await resolveSchedule(api, ref);
9493
- const updated = await api.updateSchedule(schedule.id, { enabled: true });
9771
+ const schedule2 = await resolveSchedule(api, ref);
9772
+ const updated = await api.updateSchedule(schedule2.id, { enabled: true });
9494
9773
  if (opts.json) return printJson(updated);
9495
9774
  console.log(
9496
9775
  `resumed schedule "${scheduleRef(updated)}" \u2014 next run ${timestamp(updated.next_run_at)}`
@@ -9500,8 +9779,8 @@ recent instances:`);
9500
9779
  schedules.command("run <ref>").description("Create an instance now (respects the only-when-closed gate)")
9501
9780
  ).action(async (ref, opts) => {
9502
9781
  const api = client(opts);
9503
- const schedule = await resolveSchedule(api, ref);
9504
- const issue = await api.runSchedule(schedule.id);
9782
+ const schedule2 = await resolveSchedule(api, ref);
9783
+ const issue = await api.runSchedule(schedule2.id);
9505
9784
  if (opts.json) return printJson(issue);
9506
9785
  console.log(
9507
9786
  `created ${issue.project_name}/#${issue.number} "${issue.title}" in state "${issue.state.name}"`
@@ -9511,17 +9790,17 @@ recent instances:`);
9511
9790
  schedules.command("delete <ref>").description("Delete a schedule (existing issues are kept)").option("-y, --yes", "skip the confirmation prompt")
9512
9791
  ).action(async (ref, opts) => {
9513
9792
  const api = client(opts);
9514
- const schedule = await resolveSchedule(api, ref);
9793
+ const schedule2 = await resolveSchedule(api, ref);
9515
9794
  if (!opts.yes) {
9516
9795
  const rl = createInterface3({ input: process.stdin, output: process.stdout });
9517
9796
  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] `
9797
+ `Delete schedule "${scheduleRef(schedule2)}"? Its ${schedule2.run_count} existing issue${schedule2.run_count === 1 ? "" : "s"} will be kept. [y/N] `
9519
9798
  );
9520
9799
  rl.close();
9521
9800
  if (!/^y(es)?$/i.test(answer.trim())) die("aborted");
9522
9801
  }
9523
- await api.deleteSchedule(schedule.id);
9524
- console.log(`deleted schedule "${scheduleRef(schedule)}" (issues kept)`);
9802
+ await api.deleteSchedule(schedule2.id);
9803
+ console.log(`deleted schedule "${scheduleRef(schedule2)}" (issues kept)`);
9525
9804
  });
9526
9805
  }
9527
9806
 
@@ -9640,9 +9919,9 @@ function register10(program3) {
9640
9919
  console.log(
9641
9920
  `automation: ${settings.enabled ? "ON" : "OFF (kill switch \u2014 nothing dispatches)"}`
9642
9921
  );
9643
- console.log(quotaLabel(settings.quota, (id) => stateNames.get(id) ?? id));
9922
+ console.log(quotaLabel(settings.quota, (id2) => stateNames.get(id2) ?? id2));
9644
9923
  console.log(
9645
- `utilization: ${utilizationLabel(settings.quota, activeRunItems, (id) => stateNames.get(id) ?? id)}`
9924
+ `utilization: ${utilizationLabel(settings.quota, activeRunItems, (id2) => stateNames.get(id2) ?? id2)}`
9646
9925
  );
9647
9926
  console.log(`attempt limit: ${settings.attempt_limit} strikes, then the issue parks`);
9648
9927
  if (queue.waiting === 0) {
@@ -9737,7 +10016,7 @@ function register10(program3) {
9737
10016
  for (const wf of workflows.items) {
9738
10017
  for (const s of wf.states) stateNames.set(s.id, `${wf.name}/${s.name}`);
9739
10018
  }
9740
- console.log(quotaLabel(settings.quota, (id) => stateNames.get(id) ?? id));
10019
+ console.log(quotaLabel(settings.quota, (id2) => stateNames.get(id2) ?? id2));
9741
10020
  });
9742
10021
  }
9743
10022
 
@@ -9838,9 +10117,9 @@ async function loadLibrary(api) {
9838
10117
  return { workflows, states, children };
9839
10118
  }
9840
10119
  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;
10120
+ function stateLabel(lib, id2) {
10121
+ const entry = lib.states.get(id2);
10122
+ return entry ? qualify(entry) : id2;
9844
10123
  }
9845
10124
  function inheritanceLines(lib, state) {
9846
10125
  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.179",
4
4
  "description": "CLI for Tines, an orchestration layer for AI agents",
5
5
  "repository": {
6
6
  "type": "git",