@robbeverhelst/do 1.90.0 → 1.91.0
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/do.js +78 -10
- package/package.json +1 -1
package/dist/do.js
CHANGED
|
@@ -25,7 +25,8 @@ var GLOBAL_BOOLEAN_FLAGS = [
|
|
|
25
25
|
"verbose",
|
|
26
26
|
"help",
|
|
27
27
|
"version",
|
|
28
|
-
"allow-destructive"
|
|
28
|
+
"allow-destructive",
|
|
29
|
+
"dry-run"
|
|
29
30
|
];
|
|
30
31
|
var SHORT_ALIASES = {
|
|
31
32
|
h: "help",
|
|
@@ -24136,7 +24137,7 @@ function parseCapture2(input, now) {
|
|
|
24136
24137
|
|
|
24137
24138
|
// src/meta.ts
|
|
24138
24139
|
var CLI_NAME = "do";
|
|
24139
|
-
var VERSION = "1.
|
|
24140
|
+
var VERSION = "1.91.0";
|
|
24140
24141
|
var API_PREFIX = "/api/v1";
|
|
24141
24142
|
var DEFAULT_API_URL = "http://localhost:3001";
|
|
24142
24143
|
|
|
@@ -24551,7 +24552,7 @@ function entityOperations(e) {
|
|
|
24551
24552
|
if (e.write?.updateSchema)
|
|
24552
24553
|
ops.push("update");
|
|
24553
24554
|
if (e.write?.canDelete)
|
|
24554
|
-
ops.push("delete");
|
|
24555
|
+
ops.push("delete", "archive");
|
|
24555
24556
|
return ops;
|
|
24556
24557
|
}
|
|
24557
24558
|
|
|
@@ -24589,6 +24590,11 @@ var GLOBAL_FLAGS = [
|
|
|
24589
24590
|
name: "allow-destructive",
|
|
24590
24591
|
type: "boolean",
|
|
24591
24592
|
description: "Permit a destructive verb (delete/revoke/remove-member). Off by default \u2014 a guardrail for autonomous agents."
|
|
24593
|
+
},
|
|
24594
|
+
{
|
|
24595
|
+
name: "dry-run",
|
|
24596
|
+
type: "boolean",
|
|
24597
|
+
description: "Preview a create/update/delete/archive (prints before/after) without writing \u2014 for agent-driven cleanup."
|
|
24592
24598
|
}
|
|
24593
24599
|
];
|
|
24594
24600
|
var COMMAND_SPECS = [
|
|
@@ -25367,6 +25373,19 @@ function shortDate(iso) {
|
|
|
25367
25373
|
|
|
25368
25374
|
// src/today.ts
|
|
25369
25375
|
var OPEN_STATUSES = new Set(["todo", "in_progress"]);
|
|
25376
|
+
function isTaskLike(value) {
|
|
25377
|
+
return typeof value === "object" && value !== null && typeof value.id === "string";
|
|
25378
|
+
}
|
|
25379
|
+
function normalizeTasks(response) {
|
|
25380
|
+
if (Array.isArray(response))
|
|
25381
|
+
return response.filter(isTaskLike);
|
|
25382
|
+
if (response && typeof response === "object") {
|
|
25383
|
+
const data = response.data;
|
|
25384
|
+
if (Array.isArray(data))
|
|
25385
|
+
return data.filter(isTaskLike);
|
|
25386
|
+
}
|
|
25387
|
+
return [];
|
|
25388
|
+
}
|
|
25370
25389
|
function toDate(value) {
|
|
25371
25390
|
if (value == null)
|
|
25372
25391
|
return null;
|
|
@@ -25383,7 +25402,7 @@ var pad = (n) => String(n).padStart(2, "0");
|
|
|
25383
25402
|
function selectToday(tasks3, now) {
|
|
25384
25403
|
const { start, end, label } = localDayBounds(now);
|
|
25385
25404
|
const items = [];
|
|
25386
|
-
for (const task of tasks3) {
|
|
25405
|
+
for (const task of normalizeTasks(tasks3)) {
|
|
25387
25406
|
if (!OPEN_STATUSES.has(task.status))
|
|
25388
25407
|
continue;
|
|
25389
25408
|
const scheduled = toDate(task.scheduledAt);
|
|
@@ -25482,11 +25501,18 @@ async function dispatchEntity(entity, rest, flags, requireClient) {
|
|
|
25482
25501
|
const id = requireArg(args, 0, "id");
|
|
25483
25502
|
return { data: await client.get(`${entity.path}/${id}`), render: renderRecord };
|
|
25484
25503
|
}
|
|
25504
|
+
const dryRun = flagBool(flags, "dry-run");
|
|
25485
25505
|
if (op === "create") {
|
|
25486
25506
|
const write = requireWrite(entity, "create");
|
|
25487
25507
|
if (!write.createSchema)
|
|
25488
25508
|
throw usageError(`\`${entity.name}\` cannot be created`);
|
|
25489
25509
|
const body = parseInput(write.createSchema, { id: ulid3(), ...readDataFlag(flags) });
|
|
25510
|
+
if (dryRun) {
|
|
25511
|
+
return {
|
|
25512
|
+
data: { dryRun: true, op: "create", entity: entity.name, after: body },
|
|
25513
|
+
render: renderRecord
|
|
25514
|
+
};
|
|
25515
|
+
}
|
|
25490
25516
|
return { data: await client.post(entity.path, body), render: renderRecord };
|
|
25491
25517
|
}
|
|
25492
25518
|
if (op === "update") {
|
|
@@ -25495,16 +25521,42 @@ async function dispatchEntity(entity, rest, flags, requireClient) {
|
|
|
25495
25521
|
throw usageError(`\`${entity.name}\` cannot be updated`);
|
|
25496
25522
|
const id = requireArg(args, 0, "id");
|
|
25497
25523
|
const body = parseInput(write.updateSchema, readDataFlag(flags));
|
|
25524
|
+
if (dryRun) {
|
|
25525
|
+
const before = entity.canGet ? await client.get(`${entity.path}/${id}`) : null;
|
|
25526
|
+
return {
|
|
25527
|
+
data: {
|
|
25528
|
+
dryRun: true,
|
|
25529
|
+
op: "update",
|
|
25530
|
+
entity: entity.name,
|
|
25531
|
+
id,
|
|
25532
|
+
before,
|
|
25533
|
+
after: mergePreview(before, body),
|
|
25534
|
+
changes: body
|
|
25535
|
+
},
|
|
25536
|
+
render: renderRecord
|
|
25537
|
+
};
|
|
25538
|
+
}
|
|
25498
25539
|
return { data: await client.patch(`${entity.path}/${id}`, body), render: renderRecord };
|
|
25499
25540
|
}
|
|
25500
|
-
if (op === "delete") {
|
|
25501
|
-
const write = requireWrite(entity,
|
|
25541
|
+
if (op === "delete" || op === "archive") {
|
|
25542
|
+
const write = requireWrite(entity, op);
|
|
25502
25543
|
if (!write.canDelete)
|
|
25503
|
-
throw usageError(`\`${entity.name}\` cannot be
|
|
25544
|
+
throw usageError(`\`${entity.name}\` cannot be ${op}d`);
|
|
25504
25545
|
const id = requireArg(args, 0, "id");
|
|
25505
|
-
|
|
25546
|
+
if (dryRun) {
|
|
25547
|
+
const before = entity.canGet ? await client.get(`${entity.path}/${id}`) : null;
|
|
25548
|
+
return {
|
|
25549
|
+
data: { dryRun: true, op, entity: entity.name, id, before, softDelete: true },
|
|
25550
|
+
render: renderRecord
|
|
25551
|
+
};
|
|
25552
|
+
}
|
|
25553
|
+
if (op === "delete")
|
|
25554
|
+
assertDestructiveAllowed(flags, `delete ${entity.name} ${id}`);
|
|
25506
25555
|
await client.delete(`${entity.path}/${id}`);
|
|
25507
|
-
return {
|
|
25556
|
+
return {
|
|
25557
|
+
data: op === "archive" ? { ok: true, archived: id, softDelete: true } : { ok: true, deleted: id, softDelete: true },
|
|
25558
|
+
render: renderRecord
|
|
25559
|
+
};
|
|
25508
25560
|
}
|
|
25509
25561
|
throw usageError(`unknown operation for ${entity.name}: \`${op ?? ""}\` (use ${entityOperations(entity).join(", ")})`);
|
|
25510
25562
|
}
|
|
@@ -25542,7 +25594,16 @@ var HANDLERS = {
|
|
|
25542
25594
|
return { data: task, render: renderTask };
|
|
25543
25595
|
},
|
|
25544
25596
|
today: async ({ io, requireClient }) => {
|
|
25545
|
-
const
|
|
25597
|
+
const client = requireClient();
|
|
25598
|
+
const tasks3 = [];
|
|
25599
|
+
let cursor;
|
|
25600
|
+
do {
|
|
25601
|
+
const page = await client.getPage("/tasks", {
|
|
25602
|
+
query: { filter: "all", cursor }
|
|
25603
|
+
});
|
|
25604
|
+
tasks3.push(...page.data);
|
|
25605
|
+
cursor = page.nextCursor ?? undefined;
|
|
25606
|
+
} while (cursor);
|
|
25546
25607
|
return {
|
|
25547
25608
|
data: selectToday(tasks3, io.now()),
|
|
25548
25609
|
render: renderToday
|
|
@@ -25949,6 +26010,13 @@ function requireWrite(entity, op) {
|
|
|
25949
26010
|
}
|
|
25950
26011
|
return entity.write;
|
|
25951
26012
|
}
|
|
26013
|
+
function mergePreview(before, changes) {
|
|
26014
|
+
const patch = changes && typeof changes === "object" && !Array.isArray(changes) ? changes : {};
|
|
26015
|
+
if (before && typeof before === "object" && !Array.isArray(before)) {
|
|
26016
|
+
return { ...before, ...patch };
|
|
26017
|
+
}
|
|
26018
|
+
return changes;
|
|
26019
|
+
}
|
|
25952
26020
|
function readDataFlag(flags) {
|
|
25953
26021
|
const raw = flagString(flags, "data");
|
|
25954
26022
|
if (raw === undefined)
|