tines 0.0.86 → 0.0.87
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 +135 -61
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3928,6 +3928,39 @@ var PLACEHOLDER_DESCRIPTIONS = {
|
|
|
3928
3928
|
};
|
|
3929
3929
|
var TEMPLATE_PLACEHOLDERS = Object.keys(PLACEHOLDER_DESCRIPTIONS).map((key) => ({ key, description: PLACEHOLDER_DESCRIPTIONS[key] }));
|
|
3930
3930
|
|
|
3931
|
+
// ../shared/src/paginate.ts
|
|
3932
|
+
var MAX_PAGE_SIZE = 100;
|
|
3933
|
+
var MAX_ALL_PAGES_ITEMS = 1e4;
|
|
3934
|
+
async function* listPages(fetchPage, opts = {}) {
|
|
3935
|
+
const pageSize = opts.pageSize ?? MAX_PAGE_SIZE;
|
|
3936
|
+
const maxItems = opts.maxItems ?? MAX_ALL_PAGES_ITEMS;
|
|
3937
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3938
|
+
const seenCursors = /* @__PURE__ */ new Set();
|
|
3939
|
+
let cursor;
|
|
3940
|
+
for (; ; ) {
|
|
3941
|
+
const res = await fetchPage({ limit: pageSize, cursor });
|
|
3942
|
+
const fresh = res.items.filter((item) => !seen.has(item.id));
|
|
3943
|
+
for (const item of fresh) seen.add(item.id);
|
|
3944
|
+
if (seen.size > maxItems) {
|
|
3945
|
+
throw new Error(
|
|
3946
|
+
`list has more than ${maxItems} items \u2014 narrow it with filters, or page manually with --cursor`
|
|
3947
|
+
);
|
|
3948
|
+
}
|
|
3949
|
+
yield fresh;
|
|
3950
|
+
if (res.next_cursor === null) return;
|
|
3951
|
+
if (seenCursors.has(res.next_cursor)) {
|
|
3952
|
+
throw new Error(`pagination cursor did not advance past "${cursor}" (server bug?)`);
|
|
3953
|
+
}
|
|
3954
|
+
seenCursors.add(res.next_cursor);
|
|
3955
|
+
cursor = res.next_cursor;
|
|
3956
|
+
}
|
|
3957
|
+
}
|
|
3958
|
+
async function listAll(fetchPage, opts = {}) {
|
|
3959
|
+
const items = [];
|
|
3960
|
+
for await (const page of listPages(fetchPage, opts)) items.push(...page);
|
|
3961
|
+
return items;
|
|
3962
|
+
}
|
|
3963
|
+
|
|
3931
3964
|
// src/format.ts
|
|
3932
3965
|
function timestamp(ms) {
|
|
3933
3966
|
return new Date(ms).toISOString().replace("T", " ").slice(0, 19);
|
|
@@ -4128,7 +4161,16 @@ function withCommon(cmd, { baseUrlFlag = true } = {}) {
|
|
|
4128
4161
|
}
|
|
4129
4162
|
function withList(cmd) {
|
|
4130
4163
|
return withCommon(
|
|
4131
|
-
cmd.option(
|
|
4164
|
+
cmd.option(
|
|
4165
|
+
"--limit <n>",
|
|
4166
|
+
"maximum items to return (page size under --all-pages)",
|
|
4167
|
+
(v) => Number.parseInt(v, 10)
|
|
4168
|
+
).option("--cursor <cursor>", "resume from the next_cursor of a previous page").addOption(
|
|
4169
|
+
new Option(
|
|
4170
|
+
"--all-pages",
|
|
4171
|
+
"fetch every page, not just the first (slower on large lists)"
|
|
4172
|
+
).conflicts("cursor")
|
|
4173
|
+
)
|
|
4132
4174
|
);
|
|
4133
4175
|
}
|
|
4134
4176
|
function resolveUrl(opts) {
|
|
@@ -4177,8 +4219,24 @@ function printJson(value) {
|
|
|
4177
4219
|
function printList(res, opts, render) {
|
|
4178
4220
|
if (opts.json) return printJson(res);
|
|
4179
4221
|
render(res.items);
|
|
4180
|
-
if (res.next_cursor)
|
|
4181
|
-
|
|
4222
|
+
if (res.next_cursor) {
|
|
4223
|
+
console.log(
|
|
4224
|
+
`
|
|
4225
|
+
more results: rerun with --all-pages, or resume with --cursor ${res.next_cursor}`
|
|
4226
|
+
);
|
|
4227
|
+
}
|
|
4228
|
+
}
|
|
4229
|
+
async function fetchList(opts, fetchPage) {
|
|
4230
|
+
if (opts.allPages) {
|
|
4231
|
+
return { items: await listAll(fetchPage, { pageSize: opts.limit }), next_cursor: null };
|
|
4232
|
+
}
|
|
4233
|
+
const res = await fetchPage({ limit: opts.limit, cursor: opts.cursor });
|
|
4234
|
+
if (res.next_cursor && opts.json && !opts.cursor) {
|
|
4235
|
+
console.error(
|
|
4236
|
+
"warning: more items exist beyond this page \u2014 rerun with --all-pages for all of them"
|
|
4237
|
+
);
|
|
4238
|
+
}
|
|
4239
|
+
return res;
|
|
4182
4240
|
}
|
|
4183
4241
|
function table(rows) {
|
|
4184
4242
|
if (rows.length === 0) return;
|
|
@@ -4289,16 +4347,18 @@ function register(program3) {
|
|
|
4289
4347
|
).action(async (opts) => {
|
|
4290
4348
|
const api = client(opts);
|
|
4291
4349
|
const scope = await resolveScopeFlags(api, opts);
|
|
4292
|
-
const res = await
|
|
4293
|
-
|
|
4294
|
-
|
|
4295
|
-
|
|
4296
|
-
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4350
|
+
const res = await fetchList(
|
|
4351
|
+
opts,
|
|
4352
|
+
(page) => api.listContext({
|
|
4353
|
+
kind: opts.kind,
|
|
4354
|
+
project: scope.project_id ?? void 0,
|
|
4355
|
+
state: scope.workflow_state_id ?? void 0,
|
|
4356
|
+
issue: scope.issue_id ?? void 0,
|
|
4357
|
+
q: opts.search,
|
|
4358
|
+
exact: opts.exact ? true : void 0,
|
|
4359
|
+
...page
|
|
4360
|
+
})
|
|
4361
|
+
);
|
|
4302
4362
|
printList(res, opts, (items) => {
|
|
4303
4363
|
if (items.length === 0) return console.log("no context items");
|
|
4304
4364
|
table([
|
|
@@ -4413,7 +4473,7 @@ function register(program3) {
|
|
|
4413
4473
|
context.command("init").description('Seed the global "agent-guidelines" prompt (a no-op if it already exists)')
|
|
4414
4474
|
).action(async (opts) => {
|
|
4415
4475
|
const api = client(opts);
|
|
4416
|
-
const
|
|
4476
|
+
const items = await listAll((page) => api.listContext({ kind: "prompt", exact: true, ...page }));
|
|
4417
4477
|
const existing = items.find((i) => i.name === AGENT_GUIDELINES_NAME);
|
|
4418
4478
|
if (existing) {
|
|
4419
4479
|
if (opts.json) return printJson(existing);
|
|
@@ -4616,17 +4676,20 @@ function register2(program3) {
|
|
|
4616
4676
|
issues.command("list").description("List issues across projects (hides done issues unless --all)").option("-p, --project <name>", "filter by project name or id").option("-s, --state <name>", "filter by state name or id").option("-c, --category <cat>", "filter by state category").option("-w, --workflow <id-or-name>", "filter by workflow").option("-a, --all", "include issues in done states").option("--ready", "only issues that are actionable now (not done, not a duplicate, no open blockers)").option("-q, --search <text>", "search titles and descriptions")
|
|
4617
4677
|
).action(
|
|
4618
4678
|
async (opts) => {
|
|
4619
|
-
const
|
|
4620
|
-
|
|
4621
|
-
|
|
4622
|
-
|
|
4623
|
-
|
|
4624
|
-
|
|
4625
|
-
|
|
4626
|
-
|
|
4627
|
-
|
|
4628
|
-
|
|
4629
|
-
|
|
4679
|
+
const api = client(opts);
|
|
4680
|
+
const res = await fetchList(
|
|
4681
|
+
opts,
|
|
4682
|
+
(page) => api.listIssues({
|
|
4683
|
+
project: opts.project,
|
|
4684
|
+
state: opts.state,
|
|
4685
|
+
category: opts.category,
|
|
4686
|
+
workflow: opts.workflow,
|
|
4687
|
+
hide_done: !opts.all,
|
|
4688
|
+
ready: opts.ready,
|
|
4689
|
+
q: opts.search,
|
|
4690
|
+
...page
|
|
4691
|
+
})
|
|
4692
|
+
);
|
|
4630
4693
|
printList(res, opts, (items) => {
|
|
4631
4694
|
if (items.length === 0) return console.log(opts.ready ? "no ready issues" : "no issues");
|
|
4632
4695
|
table([
|
|
@@ -5129,13 +5192,15 @@ files (v${artifact.current_version.version}):`);
|
|
|
5129
5192
|
// src/commands/journal.ts
|
|
5130
5193
|
var STATE_FLAG_HELP = "target this state's journal instead of your run's launch stage (options go BEFORE <ref>)";
|
|
5131
5194
|
async function journalItemAt(api, scope) {
|
|
5132
|
-
const
|
|
5133
|
-
|
|
5134
|
-
|
|
5135
|
-
|
|
5136
|
-
|
|
5137
|
-
|
|
5138
|
-
|
|
5195
|
+
const items = await listAll(
|
|
5196
|
+
(page) => api.listContext({
|
|
5197
|
+
kind: "prompt",
|
|
5198
|
+
project: scope.project_id ?? void 0,
|
|
5199
|
+
state: scope.workflow_state_id ?? void 0,
|
|
5200
|
+
exact: true,
|
|
5201
|
+
...page
|
|
5202
|
+
})
|
|
5203
|
+
);
|
|
5139
5204
|
return items.find((i) => i.name === JOURNAL_NAME) ?? null;
|
|
5140
5205
|
}
|
|
5141
5206
|
function stateScope(issue, state, workflow) {
|
|
@@ -5261,13 +5326,15 @@ function registerEvents(program3) {
|
|
|
5261
5326
|
).action(async (opts) => {
|
|
5262
5327
|
const api = client(opts);
|
|
5263
5328
|
const issueId = opts.issue ? (await resolveIssue(api, opts.issue)).id : void 0;
|
|
5264
|
-
const res = await
|
|
5265
|
-
|
|
5266
|
-
|
|
5267
|
-
|
|
5268
|
-
|
|
5269
|
-
|
|
5270
|
-
|
|
5329
|
+
const res = await fetchList(
|
|
5330
|
+
opts,
|
|
5331
|
+
(page) => api.listEvents({
|
|
5332
|
+
issue: issueId,
|
|
5333
|
+
project: opts.project,
|
|
5334
|
+
type: opts.type,
|
|
5335
|
+
...page
|
|
5336
|
+
})
|
|
5337
|
+
);
|
|
5271
5338
|
printList(res, opts, (items) => {
|
|
5272
5339
|
if (items.length === 0) return console.log("no events");
|
|
5273
5340
|
table([
|
|
@@ -5282,7 +5349,8 @@ function registerEvents(program3) {
|
|
|
5282
5349
|
function register4(program3) {
|
|
5283
5350
|
const projects = program3.command("projects").description("Manage projects");
|
|
5284
5351
|
withList(projects.command("list").description("List projects")).action(async (opts) => {
|
|
5285
|
-
const
|
|
5352
|
+
const api = client(opts);
|
|
5353
|
+
const res = await fetchList(opts, (page) => api.listProjects(page));
|
|
5286
5354
|
printList(res, opts, (items) => {
|
|
5287
5355
|
if (items.length === 0) return console.log("no projects");
|
|
5288
5356
|
table([
|
|
@@ -6484,13 +6552,15 @@ function register6(program3) {
|
|
|
6484
6552
|
const api = client(opts);
|
|
6485
6553
|
const issueId = opts.issue ? (await resolveIssue(api, opts.issue)).id : void 0;
|
|
6486
6554
|
const runnerId = opts.runner ? (await resolveRunner(api, opts.runner)).id : void 0;
|
|
6487
|
-
const res = await
|
|
6488
|
-
|
|
6489
|
-
|
|
6490
|
-
|
|
6491
|
-
|
|
6492
|
-
|
|
6493
|
-
|
|
6555
|
+
const res = await fetchList(
|
|
6556
|
+
opts,
|
|
6557
|
+
(page) => api.listRuns({
|
|
6558
|
+
issue: issueId,
|
|
6559
|
+
runner: runnerId,
|
|
6560
|
+
active: opts.active ? true : void 0,
|
|
6561
|
+
...page
|
|
6562
|
+
})
|
|
6563
|
+
);
|
|
6494
6564
|
printList(res, opts, (items) => {
|
|
6495
6565
|
if (items.length === 0) return console.log(opts.active ? "no active runs" : "no runs");
|
|
6496
6566
|
table([["ID", "ISSUE", "RUNNER", "TIER", "STATUS", "DURATION", "COST", "CREATED"], ...items.map(runRow)]);
|
|
@@ -6565,7 +6635,7 @@ import { createInterface } from "node:readline/promises";
|
|
|
6565
6635
|
async function resolveSchedule(api, ref) {
|
|
6566
6636
|
const { project, name: name2 } = parseScheduleRef(ref);
|
|
6567
6637
|
const proj = await resolveProject(api, project);
|
|
6568
|
-
const
|
|
6638
|
+
const items = await listAll((page) => api.listProjectSchedules(proj.id, page));
|
|
6569
6639
|
const found = items.find((s) => s.name === name2) ?? items.find((s) => s.id === name2);
|
|
6570
6640
|
if (!found) {
|
|
6571
6641
|
die(
|
|
@@ -6595,12 +6665,15 @@ function register7(program3) {
|
|
|
6595
6665
|
withList(
|
|
6596
6666
|
schedules.command("list").description("List scheduled tasks (hides paused schedules unless --all)").option("-p, --project <name>", "filter by project name or id").option("-a, --all", "include paused schedules")
|
|
6597
6667
|
).action(async (opts) => {
|
|
6598
|
-
const
|
|
6599
|
-
|
|
6600
|
-
|
|
6601
|
-
|
|
6602
|
-
|
|
6603
|
-
|
|
6668
|
+
const api = client(opts);
|
|
6669
|
+
const res = await fetchList(
|
|
6670
|
+
opts,
|
|
6671
|
+
(page) => api.listSchedules({
|
|
6672
|
+
project: opts.project,
|
|
6673
|
+
enabled: opts.all ? void 0 : true,
|
|
6674
|
+
...page
|
|
6675
|
+
})
|
|
6676
|
+
);
|
|
6604
6677
|
printList(res, opts, (items) => {
|
|
6605
6678
|
if (items.length === 0) return console.log("no schedules");
|
|
6606
6679
|
table([
|
|
@@ -6729,14 +6802,14 @@ function register8(program3) {
|
|
|
6729
6802
|
withCommon(supervisor.command("status").description("One-screen overview: kill switch, quota, utilization, runners")).action(
|
|
6730
6803
|
async (opts) => {
|
|
6731
6804
|
const api = client(opts);
|
|
6732
|
-
const [settings, runnersRes, workflows,
|
|
6805
|
+
const [settings, runnersRes, workflows, activeRunItems] = await Promise.all([
|
|
6733
6806
|
api.getSupervisorSettings(),
|
|
6734
6807
|
api.listRunners(),
|
|
6735
|
-
api.listWorkflows(
|
|
6736
|
-
api.listRuns({ active: true,
|
|
6808
|
+
api.listWorkflows(),
|
|
6809
|
+
listAll((page) => api.listRuns({ active: true, ...page }))
|
|
6737
6810
|
]);
|
|
6738
6811
|
if (opts.json) {
|
|
6739
|
-
return printJson({ settings, runners: runnersRes.items, active_runs:
|
|
6812
|
+
return printJson({ settings, runners: runnersRes.items, active_runs: activeRunItems });
|
|
6740
6813
|
}
|
|
6741
6814
|
const stateNames = /* @__PURE__ */ new Map();
|
|
6742
6815
|
for (const wf of workflows.items) {
|
|
@@ -6744,7 +6817,7 @@ function register8(program3) {
|
|
|
6744
6817
|
}
|
|
6745
6818
|
console.log(`automation: ${settings.enabled ? "ON" : "OFF (kill switch \u2014 nothing dispatches)"}`);
|
|
6746
6819
|
console.log(quotaLabel(settings.quota, (id) => stateNames.get(id) ?? id));
|
|
6747
|
-
console.log(`utilization: ${utilizationLabel(settings.quota,
|
|
6820
|
+
console.log(`utilization: ${utilizationLabel(settings.quota, activeRunItems, (id) => stateNames.get(id) ?? id)}`);
|
|
6748
6821
|
console.log(`attempt limit: ${settings.attempt_limit} strikes, then the issue parks`);
|
|
6749
6822
|
if (runnersRes.items.length === 0) {
|
|
6750
6823
|
console.log("runners: none");
|
|
@@ -6809,7 +6882,7 @@ function register8(program3) {
|
|
|
6809
6882
|
quota: { type: "state_roster", default_limit: opts.default, overrides }
|
|
6810
6883
|
});
|
|
6811
6884
|
if (opts.json) return printJson(settings);
|
|
6812
|
-
const workflows = await api.listWorkflows(
|
|
6885
|
+
const workflows = await api.listWorkflows();
|
|
6813
6886
|
const stateNames = /* @__PURE__ */ new Map();
|
|
6814
6887
|
for (const wf of workflows.items) {
|
|
6815
6888
|
for (const s of wf.states) stateNames.set(s.id, `${wf.name}/${s.name}`);
|
|
@@ -6915,7 +6988,8 @@ function register9(program3) {
|
|
|
6915
6988
|
const workflows = program3.command("workflows").description("Manage the workflow library");
|
|
6916
6989
|
withList(workflows.command("list").description("List the workflow library")).action(
|
|
6917
6990
|
async (opts) => {
|
|
6918
|
-
const
|
|
6991
|
+
const api = client(opts);
|
|
6992
|
+
const res = await fetchList(opts, (page) => api.listWorkflows(page));
|
|
6919
6993
|
printList(res, opts, (items) => {
|
|
6920
6994
|
if (items.length === 0) return console.log("no workflows");
|
|
6921
6995
|
table([
|