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.
- package/dist/index.js +412 -133
- 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
|
|
1010
|
-
const negativeValue =
|
|
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
|
|
3134
|
-
if (context.hasColors) return
|
|
3135
|
-
return this._outputConfiguration.stripColor(
|
|
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,
|
|
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
|
|
3305
|
-
helpStr =
|
|
3304
|
+
if (typeof text4 === "function") {
|
|
3305
|
+
helpStr = text4({ error: context.error, command: context.command });
|
|
3306
3306
|
} else {
|
|
3307
|
-
helpStr =
|
|
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 = (
|
|
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: (
|
|
3982
|
-
updateProject: (
|
|
3983
|
-
deleteProject: (
|
|
3984
|
-
archiveProject: (
|
|
3985
|
-
unarchiveProject: (
|
|
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: (
|
|
3990
|
-
updateWorkflow: (
|
|
3991
|
-
deleteWorkflow: (
|
|
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: (
|
|
4006
|
+
getIssue: (id2) => get(`/api/v1/issues/${id2}`),
|
|
4007
4007
|
getIssueByNumber: (projectId, number) => get(`/api/v1/projects/${projectId}/issues/${number}`),
|
|
4008
|
-
updateIssue: (
|
|
4009
|
-
transitionIssue: (
|
|
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: (
|
|
4011
|
+
resumeIssue: (id2) => request("POST", `/api/v1/issues/${id2}/resume`),
|
|
4012
4012
|
/** The dispatch explainer: "why isn't this running?". */
|
|
4013
|
-
getIssueDispatch: (
|
|
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: (
|
|
4026
|
-
updateSchedule: (
|
|
4027
|
-
deleteSchedule: (
|
|
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: (
|
|
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: (
|
|
4034
|
-
updateContextItem: (
|
|
4035
|
-
deleteContextItem: (
|
|
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: (
|
|
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: (
|
|
4118
|
-
updateRunner: (
|
|
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: (
|
|
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: (
|
|
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: (
|
|
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: (
|
|
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: (
|
|
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: (
|
|
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: (
|
|
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: (
|
|
4154
|
-
deleteRoutingRule: (
|
|
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: (
|
|
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(
|
|
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
|
|
4183
|
-
|
|
4184
|
-
|
|
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 =
|
|
4187
|
-
const at =
|
|
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 ${
|
|
4332
|
+
return `Every day at ${preset2.time}`;
|
|
4192
4333
|
case "weekly":
|
|
4193
|
-
return `Every ${WEEKDAY_NAMES[
|
|
4334
|
+
return `Every ${WEEKDAY_NAMES[preset2.weekday ?? 0]} at ${preset2.time}`;
|
|
4194
4335
|
case "monthly":
|
|
4195
|
-
return `Monthly on day ${
|
|
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(
|
|
4262
|
-
return `${describeRecurrence(
|
|
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
|
-
([
|
|
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 (
|
|
4903
|
-
const item = await client(opts).getContextItem(
|
|
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 (
|
|
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(
|
|
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(
|
|
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 (
|
|
5285
|
+
async (id2, opts) => {
|
|
5007
5286
|
const api = client(opts);
|
|
5008
|
-
const item = await api.getContextItem(
|
|
5009
|
-
await api.deleteContextItem(
|
|
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((
|
|
5149
|
-
const repo = context.repos.find((item) => item.item_id ===
|
|
5150
|
-
return repo ? `${repo.name} (${repo.scope.label})` :
|
|
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 (
|
|
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,
|
|
6205
|
+
const project = await resolveProject(api, projectRef2);
|
|
5927
6206
|
const workflowId = opts.workflow ? (await resolveWorkflow(api, opts.workflow)).id : void 0;
|
|
5928
|
-
const
|
|
5929
|
-
if (!
|
|
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
|
|
5933
|
-
...
|
|
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
|
|
6018
|
-
if (opts.json) return printJson({ ...preview, inspected:
|
|
6019
|
-
return console.log(
|
|
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: (
|
|
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
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
7744
|
+
function object2(value) {
|
|
7466
7745
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
7467
7746
|
}
|
|
7468
|
-
function
|
|
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 =
|
|
7478
|
-
return [`[error] ${clip(
|
|
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(
|
|
7759
|
+
if (type === "error") return [`[error] ${clip(text3(event.message) ?? "unknown error", 2e3)}`];
|
|
7481
7760
|
if (type !== "item.completed") return [];
|
|
7482
|
-
const item =
|
|
7761
|
+
const item = object2(event.item);
|
|
7483
7762
|
if (!item) return [];
|
|
7484
7763
|
switch (item.type) {
|
|
7485
7764
|
case "agent_message":
|
|
7486
|
-
return
|
|
7765
|
+
return text3(item.text) ? [`[agent] ${clip(text3(item.text), 2e3)}`] : [];
|
|
7487
7766
|
case "command_execution": {
|
|
7488
|
-
const command =
|
|
7767
|
+
const command = text3(item.command) ?? "command";
|
|
7489
7768
|
const failed = validMetric(item.exit_code) && item.exit_code !== 0;
|
|
7490
|
-
const output = failed ?
|
|
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) =>
|
|
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([
|
|
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${
|
|
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 =
|
|
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 =
|
|
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(
|
|
7677
|
-
const raw =
|
|
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(
|
|
7958
|
-
if (!
|
|
7959
|
-
this.buffer +=
|
|
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
|
|
8692
|
-
run.batcher.append(
|
|
8693
|
-
run.limiter?.noteStderr(
|
|
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 (
|
|
9562
|
+
async (id2, opts) => {
|
|
9284
9563
|
const api = client(opts);
|
|
9285
|
-
const run = await api.getRun(
|
|
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(
|
|
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 (
|
|
9620
|
+
).action(async (id2, opts) => {
|
|
9342
9621
|
const api = client(opts);
|
|
9343
|
-
const run = await api.cancelRun(
|
|
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
|
|
9415
|
-
if (opts.json) return printJson(
|
|
9416
|
-
printScheduleDetail(
|
|
9417
|
-
const { items } = await api.listIssues({ schedule:
|
|
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
|
|
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
|
|
9462
|
-
if (
|
|
9463
|
-
if (
|
|
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(
|
|
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
|
|
9484
|
-
const updated = await api.updateSchedule(
|
|
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
|
|
9493
|
-
const updated = await api.updateSchedule(
|
|
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
|
|
9504
|
-
const issue = await api.runSchedule(
|
|
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
|
|
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(
|
|
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(
|
|
9524
|
-
console.log(`deleted schedule "${scheduleRef(
|
|
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, (
|
|
9922
|
+
console.log(quotaLabel(settings.quota, (id2) => stateNames.get(id2) ?? id2));
|
|
9644
9923
|
console.log(
|
|
9645
|
-
`utilization: ${utilizationLabel(settings.quota, activeRunItems, (
|
|
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, (
|
|
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,
|
|
9842
|
-
const entry = lib.states.get(
|
|
9843
|
-
return entry ? qualify(entry) :
|
|
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 = [];
|