@robbeverhelst/do 1.339.1 → 1.340.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.
Files changed (2) hide show
  1. package/dist/do.js +116 -1
  2. package/package.json +1 -1
package/dist/do.js CHANGED
@@ -14418,7 +14418,7 @@ var configError = (message) => new CliError("config", message, EXIT.CONFIG);
14418
14418
 
14419
14419
  // src/meta.ts
14420
14420
  var CLI_NAME = "do";
14421
- var VERSION = "1.339.1";
14421
+ var VERSION = "1.340.0";
14422
14422
  var API_PREFIX = "/api/v1";
14423
14423
  var DEFAULT_API_URL = "http://localhost:3001";
14424
14424
 
@@ -24062,6 +24062,39 @@ var calendarOperations = defineOperations({
24062
24062
  status: 200,
24063
24063
  response: { description: "The event, after.", view: "Event" },
24064
24064
  errors: { 400: true, 404: true }
24065
+ },
24066
+ status: {
24067
+ method: "get",
24068
+ path: "/calendar/status",
24069
+ scopes: ["calendar:read"],
24070
+ tag: "Calendar",
24071
+ summary: "Calendar connection status",
24072
+ description: "Each of the member's calendar connections: its `status` and `health` (`ok` \xB7 `retrying` \xB7 `reconnect` \xB7 `pending`), `lastError`, when do last wrote to its calendar (`lastPushAt`) and last pulled from it (`lastSyncAt`). `retrying` means a passing failure; the background sweep tries again. `reconnect` means the member has to reconnect in Settings. Needs a key that acts for a member.",
24073
+ status: 200,
24074
+ response: { description: "One entry per calendar connection.", list: true },
24075
+ errors: { 400: true }
24076
+ },
24077
+ push: {
24078
+ method: "post",
24079
+ path: "/calendar/push",
24080
+ scopes: ["calendar:write"],
24081
+ tag: "Calendar",
24082
+ summary: "Push to the calendar now",
24083
+ description: "Reconcile do's placements (timed tasks, deadlines, Time blocks, timed routine occurrences) onto do's own calendar in each of the member's usable connections, now rather than at the next sweep. Idempotent: a settled calendar is all `skipped`. A connection that needs reconnecting is left out. Needs a key that acts for a member.",
24084
+ status: 200,
24085
+ response: { description: "One push result per connection.", list: true },
24086
+ errors: { 400: true }
24087
+ },
24088
+ refresh: {
24089
+ method: "post",
24090
+ path: "/calendar/refresh",
24091
+ scopes: ["calendar:write"],
24092
+ tag: "Calendar",
24093
+ summary: "Sync the calendar now",
24094
+ description: "Pull each of the member's calendar connections into do's mirror now (however recently it last synced), then push do's placements out. Returns `{ mirrored, pushed }`. Needs a key that acts for a member.",
24095
+ status: 200,
24096
+ response: { description: "What the pull and the push moved." },
24097
+ errors: { 400: true }
24065
24098
  }
24066
24099
  });
24067
24100
 
@@ -41116,6 +41149,43 @@ function renderEvents(data, mode) {
41116
41149
  return events.map((e) => renderEvent(e, mode)).join(`
41117
41150
  `);
41118
41151
  }
41152
+ var CALENDAR_HEALTH = {
41153
+ ok: "ok",
41154
+ retrying: "retrying (a passing failure; the sweep tries again)",
41155
+ reconnect: "needs reconnecting in Settings",
41156
+ pending: "never finished connecting"
41157
+ };
41158
+ function renderCalendarStatus(data, mode) {
41159
+ const rows = data ?? [];
41160
+ if (rows.length === 0)
41161
+ return paint(mode, "dim", "No calendar connected.");
41162
+ const at = (iso) => iso ? shortDate(iso) : "never";
41163
+ return rows.map((s) => {
41164
+ const health = CALENDAR_HEALTH[s.health ?? ""] ?? s.health ?? "?";
41165
+ const lines = [
41166
+ `${paint(mode, "bold", s.account ?? s.provider ?? "calendar")} \u2014 ${health}`,
41167
+ ` last push ${at(s.lastPushAt)} \xB7 last sync ${at(s.lastSyncAt)}`,
41168
+ ...s.lastError ? [` ${paint(mode, "dim", s.lastError)}`] : [],
41169
+ ` ${paint(mode, "dim", s.connectionId)}`
41170
+ ];
41171
+ return lines.join(`
41172
+ `);
41173
+ }).join(`
41174
+ `);
41175
+ }
41176
+ function renderCalendarPush(data, mode) {
41177
+ const rows = data ?? [];
41178
+ if (rows.length === 0)
41179
+ return paint(mode, "dim", "No calendar to push to.");
41180
+ return rows.map((p) => p.error ? `${p.connectionId}: not pushed \u2014 ${p.error}` : `${p.connectionId}: ${p.created ?? 0} created \xB7 ${p.updated ?? 0} updated \xB7 ${p.deleted ?? 0} removed \xB7 ${p.skipped ?? 0} already in sync${p.failed ? ` \xB7 ${p.failed} failed` : ""}`).join(`
41181
+ `);
41182
+ }
41183
+ function renderCalendarRefresh(data, mode) {
41184
+ const r = data;
41185
+ const pulled = (r.mirrored ?? []).map((m) => `${m.connectionId}: pulled ${m.created ?? 0} new \xB7 ${m.updated ?? 0} changed \xB7 ${m.cancelled ?? 0} cancelled`);
41186
+ return [...pulled, renderCalendarPush(r.pushed ?? [], mode)].join(`
41187
+ `);
41188
+ }
41119
41189
 
41120
41190
  // src/command-helpers.ts
41121
41191
  function applyPageFlags(query, flags) {
@@ -42806,6 +42876,51 @@ var commands5 = [
42806
42876
  render: renderEvent
42807
42877
  };
42808
42878
  }
42879
+ },
42880
+ {
42881
+ spec: {
42882
+ path: ["calendar", "status"],
42883
+ summary: "How each of the member's calendar connections is doing: ok, retrying or needs reconnecting, the last failure, and when do last pushed to and synced from it.",
42884
+ args: [],
42885
+ flags: [],
42886
+ scopes: [...calendarOperations.status.scopes],
42887
+ returns: "CalendarConnectionStatus[]",
42888
+ notes: `${routeOf(calendarOperations.status)}. retrying = a passing failure the sweep retries; reconnect = the member reconnects in Settings. Needs a key that acts for a member.`
42889
+ },
42890
+ run: async ({ requireClient }) => ({
42891
+ data: await requireClient().get(pathOf(calendarOperations.status)),
42892
+ render: renderCalendarStatus
42893
+ })
42894
+ },
42895
+ {
42896
+ spec: {
42897
+ path: ["calendar", "push"],
42898
+ summary: "Push do's timed tasks, deadlines, Time blocks and routines to the member's calendar now. Idempotent.",
42899
+ args: [],
42900
+ flags: [],
42901
+ scopes: [...calendarOperations.push.scopes],
42902
+ returns: "CalendarPushResult[]",
42903
+ notes: `${routeOf(calendarOperations.push)}. A connection that needs reconnecting is left out. Needs a key that acts for a member.`
42904
+ },
42905
+ run: async ({ requireClient }) => ({
42906
+ data: await requireClient().post(pathOf(calendarOperations.push), {}),
42907
+ render: renderCalendarPush
42908
+ })
42909
+ },
42910
+ {
42911
+ spec: {
42912
+ path: ["calendar", "refresh"],
42913
+ summary: "Sync the member's calendar now: pull their calendars into do, then push do's placements out.",
42914
+ args: [],
42915
+ flags: [],
42916
+ scopes: [...calendarOperations.refresh.scopes],
42917
+ returns: "{ mirrored, pushed }",
42918
+ notes: `${routeOf(calendarOperations.refresh)}. Pulls however recently it last synced. Needs a key that acts for a member.`
42919
+ },
42920
+ run: async ({ requireClient }) => ({
42921
+ data: await requireClient().post(pathOf(calendarOperations.refresh), {}),
42922
+ render: renderCalendarRefresh
42923
+ })
42809
42924
  }
42810
42925
  ];
42811
42926
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@robbeverhelst/do",
3
- "version": "1.339.1",
3
+ "version": "1.340.0",
4
4
  "private": false,
5
5
  "description": "do — the agent-drivable CLI over the public /api/v1 surface",
6
6
  "homepage": "https://github.com/robbeverhelst/do/tree/main/apps/cli",