@opvs-ai/cli 0.26.0 → 0.27.1

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.
@@ -0,0 +1,306 @@
1
+ /**
2
+ * opvs engines — switch the build engines on and off (REAS-217).
3
+ *
4
+ * The route is `GET / PUT / DELETE /api/v1/factory/engines-off/{harness}` (built
5
+ * by REAS-216, the switch route that owns the authz and storage). This command
6
+ * is the CLI face of that surface — and only that surface; it does not invent
7
+ * any state the route does not already advertise.
8
+ *
9
+ * OFF has three visible states on screen:
10
+ * - until is null → "OFF" (off until switched on)
11
+ * - until in future → "off until <local>" (timed pause)
12
+ * - until in past → "expired" (a timed pause whose clock ran out;
13
+ * the route drops it on the next call,
14
+ * and the list shows it before that)
15
+ *
16
+ * `--until` accepts four forms. `--reason` is required for `off` because the route
17
+ * records it as the reason the next operator will read.
18
+ */
19
+ import { createClient } from "@opvs-ai/core";
20
+ import { printJson } from "../lib/format.js";
21
+ /**
22
+ * The list of harness identifiers the route accepts (REAS-216 enumerates them
23
+ * on the server). Help text only — the route is the authority, a typo is a 422
24
+ * with the canonical list it returned, and pinning it on the CLI as a second
25
+ * source of truth invites the two to drift.
26
+ *
27
+ * ⚠️ Two existing CLI commands spell this vocabulary with HYPHENS because their
28
+ * upstream enum (`agentboard BuildProvider`) does. This one is a `factory`
29
+ * harness, and REAS-216's enum is underscored (`claude_code`, `opencode`,
30
+ * `codex`, `pi`, `grok`, `agy`, `cursor`, `openhands`). The two do NOT match —
31
+ * mixing them is the 422 a reader of `--help` should not have to discover.
32
+ */
33
+ export const HARNESSES = [
34
+ "claude_code",
35
+ "openhands",
36
+ "codex",
37
+ "opencode",
38
+ "pi",
39
+ "grok",
40
+ "agy",
41
+ "cursor",
42
+ ];
43
+ const UNTIL_HELP = "When the off-switch flips back on. ISO-8601 (e.g. 2026-10-12T18:00:00Z) is sent as-is. " +
44
+ "+Nh / +Nm is RELATIVE TO NOW (a fixed clock in tests). " +
45
+ "HH:MM is the next such LOCAL time; the CLI sends UTC. " +
46
+ "Omit for off until switched on.";
47
+ const REASON_HELP = 'Free text recorded by the route; the next operator sees it. e.g. "GPT outage, retrying at 18:00Z".';
48
+ const ADMIN_MESSAGE = "Only a human admin of this workspace can switch engines.";
49
+ /** Standardised access to "now". The action handler calls this with no args,
50
+ * the parser accepts an explicit one — letting tests pin the clock. */
51
+ export function now() {
52
+ return new Date();
53
+ }
54
+ /**
55
+ * Parse the four `--until` forms into an ISO-8601 UTC string the server stores
56
+ * verbatim. Pure on purpose: the only input is `(raw, now)`; the only output is
57
+ * the ISO string or `null` when `--until` was omitted, or an `Error` on bad
58
+ * input. Pure functions are why the test can fix the clock without standing up
59
+ * the rest of the action.
60
+ *
61
+ * - undefined → null (off until switched on)
62
+ * - "+Nh" | "+Nm" → raw minutes/hours from now
63
+ * - "HH:MM" (24h, local time) → the next such local time; tomorrow if today's HH:MM already passed
64
+ * - ISO-8601 already → passed through (any timezone accepted; we re-emit UTC if it parses)
65
+ */
66
+ export function parseUntil(raw, nowArg) {
67
+ if (raw === undefined)
68
+ return null;
69
+ const s = raw.trim();
70
+ // Relative: "+2h", "+30m", "+90m", etc. Lowercase only; uppercase is reserved
71
+ // for absolute time forms so a "+2H" typo is caught, not silently applied.
72
+ const rel = /^([+]?)(\d+)([hm])$/.exec(s);
73
+ if (rel) {
74
+ const n = Number(rel[2]);
75
+ const unit = rel[3];
76
+ const ms = unit === "h" ? n * 60 * 60 * 1000 : n * 60 * 1000;
77
+ return new Date(nowArg.getTime() + ms).toISOString();
78
+ }
79
+ // HH:MM in local time — next occurrence. A 25:00 or 12:60 is not a time, and
80
+ // the route does the same validation server-side; the CLI's job here is to
81
+ // exit with a clear message instead of a 422 round-trip.
82
+ const clock = /^(\d{1,2}):(\d{2})$/.exec(s);
83
+ if (clock) {
84
+ const hh = Number(clock[1]);
85
+ const mm = Number(clock[2]);
86
+ if (hh > 23 || mm > 59) {
87
+ throw new Error(`--until '${raw}' is not a valid HH:MM time (got ${hh}:${mm.toString().padStart(2, "0")})`);
88
+ }
89
+ const target = new Date(nowArg);
90
+ target.setHours(hh, mm, 0, 0);
91
+ if (target.getTime() <= nowArg.getTime()) {
92
+ target.setDate(target.getDate() + 1);
93
+ }
94
+ return target.toISOString();
95
+ }
96
+ // ISO-8601 passthrough. `Date` accepts a wide grammar (Z, +02:00, with/without
97
+ // fractional seconds); a string Date rejects with NaN, which we surface.
98
+ const parsed = new Date(s);
99
+ if (Number.isNaN(parsed.getTime())) {
100
+ throw new Error(`--until '${raw}' is not ISO-8601, +Nh/+Nm, or HH:MM. Pass one of those forms.`);
101
+ }
102
+ return parsed.toISOString();
103
+ }
104
+ /**
105
+ * Render the GET reply as a human table.
106
+ *
107
+ * The route's reply carries two lists. `engines_off` is the OFF-ledger: every
108
+ * off-switch the route still remembers, including expired ones (the route drops
109
+ * them on the next call, the table shows them here). `active` is the SUBSET of
110
+ * `engines_off` whose off-switch is in force now (`until` is null or in the
111
+ * future) — so `active` ⊆ harnesses-of(`engines_off`). It is NOT a list of
112
+ * engines that are on. The on-state is the absence of an off-entry.
113
+ *
114
+ * Rows are the union of `HARNESSES` and the harnesses that appear in
115
+ * `engines_off` (a name the CLI does not know about still gets a row).
116
+ * State for a harness that has an `engines_off` entry comes from that entry;
117
+ * otherwise the harness is `ON`. `active` is not consulted — reading it as
118
+ * "currently on" produces duplicate rows (every `active` harness already has an
119
+ * off-row), and the only thing being read off it is the subset relationship the
120
+ * route already encoded in `engines_off`.
121
+ */
122
+ function renderEnginesTable(data, nowArg) {
123
+ const rows = [];
124
+ const offByHarness = new Map();
125
+ for (const entry of data.engines_off) {
126
+ offByHarness.set(entry.harness, entry);
127
+ }
128
+ const harnesses = new Set([...HARNESSES, ...offByHarness.keys()]);
129
+ for (const harness of [...harnesses].sort((a, b) => a.localeCompare(b))) {
130
+ const entry = offByHarness.get(harness);
131
+ if (entry) {
132
+ rows.push({
133
+ harness,
134
+ state: formatState(entry.until, nowArg),
135
+ reason: entry.reason ?? "",
136
+ setBy: entry.set_by ?? "",
137
+ });
138
+ }
139
+ else {
140
+ rows.push({ harness, state: "ON", reason: "", setBy: "" });
141
+ }
142
+ }
143
+ if (rows.length === 0) {
144
+ console.log("(no engines configured)");
145
+ return;
146
+ }
147
+ const wHarness = Math.max("harness".length, ...rows.map((r) => r.harness.length));
148
+ const wState = Math.max("state".length, ...rows.map((r) => r.state.length));
149
+ const wReason = Math.max("reason".length, ...rows.map((r) => r.reason.length));
150
+ const wSetBy = Math.max("set by".length, ...rows.map((r) => r.setBy.length));
151
+ const header = [
152
+ "harness".padEnd(wHarness),
153
+ "state".padEnd(wState),
154
+ "reason".padEnd(wReason),
155
+ "set by".padEnd(wSetBy),
156
+ ].join(" ");
157
+ const sep = [
158
+ "-".repeat(wHarness),
159
+ "-".repeat(wState),
160
+ "-".repeat(wReason),
161
+ "-".repeat(wSetBy),
162
+ ].join(" ");
163
+ console.log(header);
164
+ console.log(sep);
165
+ for (const r of rows) {
166
+ console.log([
167
+ r.harness.padEnd(wHarness),
168
+ r.state.padEnd(wState),
169
+ r.reason.padEnd(wReason),
170
+ r.setBy.padEnd(wSetBy),
171
+ ].join(" "));
172
+ }
173
+ }
174
+ function formatState(until, nowArg) {
175
+ if (until === null)
176
+ return "OFF";
177
+ const t = new Date(until);
178
+ if (Number.isNaN(t.getTime()))
179
+ return "OFF";
180
+ if (t.getTime() <= nowArg.getTime())
181
+ return "expired";
182
+ return `off until ${t.toLocaleString(undefined, { hour12: false })}`;
183
+ }
184
+ /**
185
+ * Translate an error thrown by the client into the human message this command
186
+ * emits. The route says a 403 is "only an admin can switch engines" — that is
187
+ * the wording every other client reads, so the CLI carries it verbatim rather
188
+ * than rephrasing. A 422 is the route's own message; the CLI never invents its
189
+ * own vocabulary for a server-side refusal.
190
+ */
191
+ function describeApiError(err) {
192
+ if (!err || typeof err !== "object")
193
+ return null;
194
+ const e = err;
195
+ if (e.status === 403) {
196
+ return { message: ADMIN_MESSAGE, exitCode: 1 };
197
+ }
198
+ if (typeof e.detail === "string" && e.detail) {
199
+ return { message: e.detail, exitCode: 1 };
200
+ }
201
+ return null;
202
+ }
203
+ export function registerEnginesCommands(program) {
204
+ const engines = program
205
+ .command("engines")
206
+ .description("Switch build engines on and off for this workspace");
207
+ engines
208
+ .command("list")
209
+ .description("Show which engines are on, off, expired, or timed")
210
+ .option("--json", "Print the raw JSON from /api/v1/factory/engines-off instead of the table")
211
+ .action(async (opts) => {
212
+ const wsSlug = program.opts().workspace;
213
+ try {
214
+ const client = createClient(wsSlug);
215
+ const res = await client.get("/api/v1/factory/engines-off");
216
+ const data = (await res.json());
217
+ if (opts.json) {
218
+ printJson(data);
219
+ return;
220
+ }
221
+ renderEnginesTable(data, now());
222
+ }
223
+ catch (err) {
224
+ const described = describeApiError(err);
225
+ if (described) {
226
+ console.error(described.message);
227
+ process.exit(described.exitCode);
228
+ }
229
+ const e = err;
230
+ console.error(`Error: ${e.detail || "Failed to list engines"}`);
231
+ process.exit(1);
232
+ }
233
+ });
234
+ engines
235
+ .command("off <harness>")
236
+ .description("Switch an engine off. --reason is required; --until defaults to 'until switched on'.")
237
+ .requiredOption("--reason <text>", REASON_HELP)
238
+ .option("--until <when>", UNTIL_HELP)
239
+ .action(async (harness, opts) => {
240
+ const wsSlug = program.opts().workspace;
241
+ let untilIso;
242
+ try {
243
+ untilIso = parseUntil(opts.until, now());
244
+ }
245
+ catch (e) {
246
+ const msg = e instanceof Error ? e.message : String(e);
247
+ console.error(msg);
248
+ process.exit(1);
249
+ return;
250
+ }
251
+ try {
252
+ const client = createClient(wsSlug);
253
+ const res = await client.put(`/api/v1/factory/engines-off/${encodeURIComponent(harness)}`, {
254
+ until: untilIso,
255
+ reason: opts.reason,
256
+ });
257
+ const data = (await res.json());
258
+ if (opts.until === undefined || (opts.until && opts.until.trim() === "")) {
259
+ // No --until (or empty): just confirm in one line. Re-printing the
260
+ // whole table is what `--json` is for.
261
+ const entry = data.engines_off.find((e) => e.harness === harness);
262
+ console.log(`${harness}: OFF (${entry?.reason ?? opts.reason}) until ${entry && entry.until ? entry.until : "switched on"}`);
263
+ }
264
+ else {
265
+ renderEnginesTable(data, now());
266
+ }
267
+ }
268
+ catch (err) {
269
+ const described = describeApiError(err);
270
+ if (described) {
271
+ console.error(described.message);
272
+ process.exit(described.exitCode);
273
+ }
274
+ const e = err;
275
+ console.error(`Error: ${e.detail || "Failed to switch engine off"}`);
276
+ process.exit(1);
277
+ }
278
+ });
279
+ engines
280
+ .command("on <harness>")
281
+ .description("Switch an engine back on (DELETE on /api/v1/factory/engines-off/{harness})")
282
+ .action(async (harness) => {
283
+ const wsSlug = program.opts().workspace;
284
+ try {
285
+ const client = createClient(wsSlug);
286
+ await client.delete(`/api/v1/factory/engines-off/${encodeURIComponent(harness)}`);
287
+ console.log(`${harness}: ON`);
288
+ }
289
+ catch (err) {
290
+ const described = describeApiError(err);
291
+ if (described) {
292
+ console.error(described.message);
293
+ process.exit(described.exitCode);
294
+ }
295
+ const e = err;
296
+ console.error(`Error: ${e.detail || "Failed to switch engine on"}`);
297
+ process.exit(1);
298
+ }
299
+ });
300
+ // Engine group help: list valid harnesses once. The route does not change
301
+ // often, and a fixed list keeps `--help` honest without putting a copy in
302
+ // every subcommand.
303
+ engines.addHelpText("after", `\nValid harnesses: ${HARNESSES.join(", ")}.\n` +
304
+ `Note: claude_code, opencode, and codex use UNDERSCORES — the route's enum, not the --provider values elsewhere in this CLI.`);
305
+ }
306
+ //# sourceMappingURL=engines.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engines.js","sourceRoot":"","sources":["../../src/commands/engines.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -21,6 +21,7 @@ import { registerSessionCommands } from "./commands/session.js";
21
21
  import { registerBoardCommands } from "./commands/boards.js";
22
22
  import { registerProjectCommands } from "./commands/projects.js";
23
23
  import { registerScheduledRunCommands } from "./commands/scheduled-runs.js";
24
+ import { registerCalendarCommands } from "./commands/calendar.js";
24
25
  import { registerTaskCommands } from "./commands/tasks.js";
25
26
  import { registerCommentCommands } from "./commands/comments.js";
26
27
  import { registerDocsCommands } from "./commands/docs.js";
@@ -50,6 +51,7 @@ import { registerCodeCommands } from "./commands/code.js";
50
51
  import { registerCodeGraphCommand } from "./commands/code-graph.js";
51
52
  import { registerEnvCommands } from "./commands/env.js";
52
53
  import { registerMemoryCommands } from "./commands/memory.js";
54
+ import { registerEnginesCommands } from "./commands/engines.js";
53
55
  const __dirname = dirname(fileURLToPath(import.meta.url));
54
56
  const pkg = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf8"));
55
57
  const program = new Command();
@@ -65,6 +67,7 @@ registerSessionCommands(program);
65
67
  registerBoardCommands(program);
66
68
  registerProjectCommands(program);
67
69
  registerScheduledRunCommands(program);
70
+ registerCalendarCommands(program);
68
71
  registerTaskCommands(program);
69
72
  registerCommentCommands(program);
70
73
  registerDocsCommands(program);
@@ -92,6 +95,7 @@ registerCodeCommands(program);
92
95
  registerCodeGraphCommand(program);
93
96
  registerEnvCommands(program);
94
97
  registerMemoryCommands(program);
98
+ registerEnginesCommands(program);
95
99
  registerConfigCommands(program);
96
100
  // A config error is a message, not a crash.
97
101
  //
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ /** Pure readers for the calendar flags shared by calendar and task commands. */
2
+ export declare class CalendarSpecError extends Error {
3
+ constructor(message: string);
4
+ }
5
+ type Reminder = {
6
+ who: "self" | "assignee" | "delegator" | "manager" | "owner";
7
+ how: "wake" | "notify";
8
+ anchor: "fire" | "deadline";
9
+ offset_minutes: number;
10
+ };
11
+ type Condition = {
12
+ source: "pr_state" | "ci_state" | "card_status" | "mail" | "box_health";
13
+ key: string;
14
+ op: "eq" | "exists" | "version_gte";
15
+ value: string | boolean;
16
+ };
17
+ type WaitFlags = {
18
+ pr?: string;
19
+ merged?: boolean;
20
+ closed?: boolean;
21
+ green?: boolean;
22
+ card?: string;
23
+ status?: string;
24
+ mail?: boolean;
25
+ mailReply?: string;
26
+ box?: string;
27
+ version?: string;
28
+ };
29
+ type Repeat = {
30
+ interval_minutes: number;
31
+ repeat_ends?: "never" | "on_date" | "after_count";
32
+ repeat_until?: string;
33
+ repeat_count?: number;
34
+ fire_at?: string;
35
+ start_at?: string;
36
+ at?: string;
37
+ };
38
+ /** Read an ISO 8601 timestamp only when it names its zone explicitly. */
39
+ export declare function parseZonedTime(s: string): string;
40
+ /** Turn a compact interval into the calendar's interval column. */
41
+ export declare function parseEvery(s: string): {
42
+ interval_minutes: number;
43
+ };
44
+ /** Read one of the three repeat-ending forms used by the calendar API. */
45
+ export declare function parseEnds(s: string): {
46
+ repeat_ends: "never";
47
+ } | {
48
+ repeat_ends: "on_date";
49
+ repeat_until: string;
50
+ } | {
51
+ repeat_ends: "after_count";
52
+ repeat_count: number;
53
+ };
54
+ /** Read who/how/anchor/offset reminder notation into section 3 JSON. */
55
+ export declare function parseRemind(s: string): Reminder;
56
+ /** Turn exactly one complete wait-flag family into section 4 condition JSON. */
57
+ export declare function conditionFromFlags(o: WaitFlags): Condition;
58
+ /** Describe one reminder in the words printed after registration. */
59
+ export declare function describeReminder(r: Reminder): string;
60
+ /** Describe the repeat fields in the words printed after registration. */
61
+ export declare function describeRepeat(r: Repeat): string;
62
+ export {};
@@ -0,0 +1,199 @@
1
+ /** Pure readers for the calendar flags shared by calendar and task commands. */
2
+ export class CalendarSpecError extends Error {
3
+ constructor(message) {
4
+ super(message);
5
+ this.name = "CalendarSpecError";
6
+ }
7
+ }
8
+ const ZONED_TIME_RE = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{1,9}))?)?(Z|[+-]\d{2}:?\d{2})$/;
9
+ const DATE_RE = /^(\d{4})-(\d{2})-(\d{2})$/;
10
+ const PR_RE = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+#[1-9]\d*$/;
11
+ const CARD_RE = /^[A-Z][A-Z0-9]{0,9}-[1-9]\d*$/;
12
+ const VERSION_RE = /^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/;
13
+ function isValidDate(year, month, day) {
14
+ if (month < 1 || month > 12 || day < 1)
15
+ return false;
16
+ const leap = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
17
+ const days = [31, leap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
18
+ return day <= days[month - 1];
19
+ }
20
+ function zonedTimeError() {
21
+ return new CalendarSpecError("a time needs a zone, for example 2026-10-20T18:00+02:00.");
22
+ }
23
+ /** Read an ISO 8601 timestamp only when it names its zone explicitly. */
24
+ export function parseZonedTime(s) {
25
+ const match = ZONED_TIME_RE.exec(s);
26
+ if (!match)
27
+ throw zonedTimeError();
28
+ const [, year, month, day, hour, minute, second = "0", , zone] = match;
29
+ const validWallTime = isValidDate(Number(year), Number(month), Number(day)) &&
30
+ Number(hour) <= 23 &&
31
+ Number(minute) <= 59 &&
32
+ Number(second) <= 59;
33
+ const offset = zone === "Z" ? null : /([+-])(\d{2}):?(\d{2})/.exec(zone);
34
+ const validOffset = offset === null || (Number(offset[2]) <= 23 && Number(offset[3]) <= 59);
35
+ if (!validWallTime || !validOffset || Number.isNaN(Date.parse(s))) {
36
+ throw zonedTimeError();
37
+ }
38
+ return s;
39
+ }
40
+ /** Turn a compact interval into the calendar's interval column. */
41
+ export function parseEvery(s) {
42
+ const match = /^(\d+)([mhd])$/.exec(s);
43
+ if (!match) {
44
+ throw new CalendarSpecError("a repeat needs a positive number followed by m, h or d, for example 90m.");
45
+ }
46
+ const amount = Number(match[1]);
47
+ const multiplier = match[2] === "d" ? 1440 : match[2] === "h" ? 60 : 1;
48
+ const intervalMinutes = amount * multiplier;
49
+ if (!Number.isSafeInteger(intervalMinutes) || intervalMinutes <= 0) {
50
+ throw new CalendarSpecError("a repeat needs a positive number followed by m, h or d, for example 90m.");
51
+ }
52
+ return { interval_minutes: intervalMinutes };
53
+ }
54
+ /** Read one of the three repeat-ending forms used by the calendar API. */
55
+ export function parseEnds(s) {
56
+ if (s === "never")
57
+ return { repeat_ends: "never" };
58
+ const count = /^([1-9]\d*)x$/.exec(s);
59
+ if (count) {
60
+ const repeatCount = Number(count[1]);
61
+ if (Number.isSafeInteger(repeatCount)) {
62
+ return { repeat_ends: "after_count", repeat_count: repeatCount };
63
+ }
64
+ }
65
+ const date = DATE_RE.exec(s);
66
+ if (date && isValidDate(Number(date[1]), Number(date[2]), Number(date[3]))) {
67
+ return { repeat_ends: "on_date", repeat_until: s };
68
+ }
69
+ throw new CalendarSpecError("an end needs never, a date, or a positive count, for example never, 2026-10-20, or 3x.");
70
+ }
71
+ /** Read who/how/anchor/offset reminder notation into section 3 JSON. */
72
+ export function parseRemind(s) {
73
+ const match = /^([^:]+):([^:]+):([^:]+):([+-]?\d+)$/.exec(s);
74
+ const who = match?.[1];
75
+ const how = match?.[2];
76
+ const anchor = match?.[3];
77
+ const offset = match ? Number(match[4]) : Number.NaN;
78
+ if (!match ||
79
+ !["self", "assignee", "delegator", "manager", "owner"].includes(who) ||
80
+ !["wake", "notify"].includes(how) ||
81
+ !["fire", "deadline"].includes(anchor) ||
82
+ !Number.isSafeInteger(offset)) {
83
+ throw new CalendarSpecError("a reminder needs who:how:anchor:minutes, for example owner:notify:deadline:+1440.");
84
+ }
85
+ return {
86
+ who: who,
87
+ how: how,
88
+ anchor: anchor,
89
+ offset_minutes: offset,
90
+ };
91
+ }
92
+ function conditionError(message) {
93
+ return new CalendarSpecError(message);
94
+ }
95
+ /** Turn exactly one complete wait-flag family into section 4 condition JSON. */
96
+ export function conditionFromFlags(o) {
97
+ const families = [
98
+ o.pr !== undefined || o.merged || o.closed || o.green,
99
+ o.card !== undefined || o.status !== undefined,
100
+ o.mail || o.mailReply !== undefined,
101
+ o.box !== undefined || o.version !== undefined,
102
+ ].filter(Boolean).length;
103
+ if (families !== 1) {
104
+ throw conditionError("a condition needs one complete flag pair, for example --pr owner/repo#12 --merged.");
105
+ }
106
+ if (o.pr !== undefined || o.merged || o.closed || o.green) {
107
+ const states = [o.merged, o.closed, o.green].filter(Boolean).length;
108
+ if (!o.pr || !PR_RE.test(o.pr) || states !== 1) {
109
+ throw conditionError("a pull request condition needs one state, for example --pr owner/repo#12 --merged.");
110
+ }
111
+ if (o.green)
112
+ return { source: "ci_state", key: o.pr, op: "eq", value: "green" };
113
+ return {
114
+ source: "pr_state",
115
+ key: o.pr,
116
+ op: "eq",
117
+ value: o.merged ? "merged" : "closed",
118
+ };
119
+ }
120
+ if (o.card !== undefined || o.status !== undefined) {
121
+ if (!o.card || !CARD_RE.test(o.card) || !o.status) {
122
+ throw conditionError("a card condition needs a card and status, for example --card DAAR-129 --status done.");
123
+ }
124
+ return { source: "card_status", key: o.card, op: "eq", value: o.status };
125
+ }
126
+ if (o.mail || o.mailReply !== undefined) {
127
+ if (Boolean(o.mail) === (o.mailReply !== undefined) || o.mailReply === "") {
128
+ throw conditionError("a mail condition needs one mail target, for example --mail-reply message-123.");
129
+ }
130
+ return {
131
+ source: "mail",
132
+ key: o.mail ? "direct" : `reply:${o.mailReply}`,
133
+ op: "exists",
134
+ value: true,
135
+ };
136
+ }
137
+ if (!o.box || !o.version || !VERSION_RE.test(o.version)) {
138
+ throw conditionError("a box condition needs a box and version, for example --box desk-1 --version 0.2.140.");
139
+ }
140
+ return { source: "box_health", key: o.box, op: "version_gte", value: o.version };
141
+ }
142
+ function durationWords(minutes) {
143
+ const absolute = Math.abs(minutes);
144
+ if (absolute % 1440 === 0) {
145
+ const days = absolute / 1440;
146
+ return `${days} ${days === 1 ? "day" : "days"}`;
147
+ }
148
+ if (absolute % 60 === 0) {
149
+ const hours = absolute / 60;
150
+ return `${hours} ${hours === 1 ? "hour" : "hours"}`;
151
+ }
152
+ return `${absolute} ${absolute === 1 ? "minute" : "minutes"}`;
153
+ }
154
+ /** Describe one reminder in the words printed after registration. */
155
+ export function describeReminder(r) {
156
+ const verb = r.how === "notify" ? "tell" : "wake";
157
+ const who = r.who === "self" ? "me" : `the ${r.who}`;
158
+ const anchor = r.anchor === "fire" ? "time" : "deadline";
159
+ if (r.offset_minutes === 0)
160
+ return `${verb} ${who} at the ${anchor}`;
161
+ const direction = r.offset_minutes < 0 ? "before" : "after";
162
+ return `${verb} ${who} ${durationWords(r.offset_minutes)} ${direction} the ${anchor}`;
163
+ }
164
+ function repeatIntervalWords(minutes) {
165
+ if (minutes % 1440 === 0) {
166
+ const days = minutes / 1440;
167
+ return `${days} ${days === 1 ? "day" : "days"}`;
168
+ }
169
+ if (minutes % 60 === 0) {
170
+ const hours = minutes / 60;
171
+ return `${hours} ${hours === 1 ? "hour" : "hours"}`;
172
+ }
173
+ return `${minutes} ${minutes === 1 ? "minute" : "minutes"}`;
174
+ }
175
+ /** Describe the repeat fields in the words printed after registration. */
176
+ export function describeRepeat(r) {
177
+ if (!Number.isSafeInteger(r.interval_minutes) || r.interval_minutes <= 0) {
178
+ throw new CalendarSpecError("a repeat needs positive interval_minutes, for example 1440 for every day.");
179
+ }
180
+ const rawTime = r.at ?? r.fire_at ?? r.start_at;
181
+ const time = rawTime?.match(/(?:T|^)(\d{2}:\d{2})(?::\d{2})?/)?.[1];
182
+ let description = `every ${repeatIntervalWords(r.interval_minutes)}`;
183
+ if (time)
184
+ description += ` at ${time}`;
185
+ const ends = r.repeat_ends ?? "never";
186
+ if (ends === "never")
187
+ return `${description}, never ends`;
188
+ if (ends === "on_date" && r.repeat_until) {
189
+ return `${description}, ends on ${r.repeat_until.slice(0, 10)}`;
190
+ }
191
+ if (ends === "after_count" &&
192
+ Number.isSafeInteger(r.repeat_count) &&
193
+ (r.repeat_count ?? 0) > 0) {
194
+ const noun = r.repeat_count === 1 ? "time" : "times";
195
+ return `${description}, ends after ${r.repeat_count} ${noun}`;
196
+ }
197
+ throw new CalendarSpecError("a repeat end needs never, a date, or a positive count, for example repeat_count 30.");
198
+ }
199
+ //# sourceMappingURL=calendar-spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar-spec.js","sourceRoot":"","sources":["../../src/lib/calendar-spec.ts"],"names":[],"mappings":"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"}