@opvs-ai/cli 0.27.0 → 0.27.2
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/README.md +49 -0
- package/dist/.build-stamp.json +4 -4
- package/dist/commands/calendar.d.ts +3 -0
- package/dist/commands/calendar.js +294 -0
- package/dist/commands/calendar.js.map +1 -0
- package/dist/commands/code.js +229 -3
- package/dist/commands/code.js.map +1 -1
- package/dist/commands/tasks.js +117 -10
- package/dist/commands/tasks.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/calendar-spec.d.ts +62 -0
- package/dist/lib/calendar-spec.js +199 -0
- package/dist/lib/calendar-spec.js.map +1 -0
- package/dist/lib/card-anchors.d.ts +12 -0
- package/dist/lib/card-anchors.js +67 -0
- package/dist/lib/card-anchors.js.map +1 -0
- package/package.json +1 -1
|
@@ -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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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Pure extraction of repo anchors from a draft card. */
|
|
2
|
+
export declare const CARD_ANCHOR_LIMIT = 50;
|
|
3
|
+
export declare const BRIEF_GATE_HEADING = "# The gate block \u2014 the last section of every builder brief";
|
|
4
|
+
export type CardAnchor = {
|
|
5
|
+
anchor: string;
|
|
6
|
+
declaredNew: boolean;
|
|
7
|
+
};
|
|
8
|
+
export type CardAnchors = {
|
|
9
|
+
anchors: CardAnchor[];
|
|
10
|
+
leftOut: number;
|
|
11
|
+
};
|
|
12
|
+
export declare function extractCardAnchors(markdown: string): CardAnchors;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/** Pure extraction of repo anchors from a draft card. */
|
|
2
|
+
export const CARD_ANCHOR_LIMIT = 50;
|
|
3
|
+
export const BRIEF_GATE_HEADING = "# The gate block — the last section of every builder brief";
|
|
4
|
+
const FENCE_RE = /^\s{0,3}(`{3,}|~{3,})/;
|
|
5
|
+
const INLINE_CODE_RE = /(?<!`)`([^`\r\n]+)`(?!`)/g;
|
|
6
|
+
export function extractCardAnchors(markdown) {
|
|
7
|
+
const anchors = [];
|
|
8
|
+
const seen = new Set();
|
|
9
|
+
let leftOut = 0;
|
|
10
|
+
let fence = null;
|
|
11
|
+
for (const line of markdown.split(/\r?\n/)) {
|
|
12
|
+
if (line.trim() === BRIEF_GATE_HEADING)
|
|
13
|
+
break;
|
|
14
|
+
const fenceMatch = line.match(FENCE_RE);
|
|
15
|
+
if (fenceMatch) {
|
|
16
|
+
const run = fenceMatch[1];
|
|
17
|
+
const marker = run[0];
|
|
18
|
+
if (!fence) {
|
|
19
|
+
fence = { marker, length: run.length };
|
|
20
|
+
}
|
|
21
|
+
else if (marker === fence.marker && run.length >= fence.length) {
|
|
22
|
+
fence = null;
|
|
23
|
+
}
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
if (fence)
|
|
27
|
+
continue;
|
|
28
|
+
const declaredNew = declaresNewFile(line);
|
|
29
|
+
for (const match of line.matchAll(INLINE_CODE_RE)) {
|
|
30
|
+
const anchor = normaliseAnchor(match[1].trim());
|
|
31
|
+
if (!anchor || seen.has(anchor))
|
|
32
|
+
continue;
|
|
33
|
+
seen.add(anchor);
|
|
34
|
+
if (anchors.length < CARD_ANCHOR_LIMIT) {
|
|
35
|
+
anchors.push({ anchor, declaredNew });
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
leftOut += 1;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return { anchors, leftOut };
|
|
43
|
+
}
|
|
44
|
+
function declaresNewFile(line) {
|
|
45
|
+
return /\bcreate\b/i.test(line) || /\bNEW\b/.test(line) || /\bnew file\b/i.test(line);
|
|
46
|
+
}
|
|
47
|
+
function normaliseAnchor(token) {
|
|
48
|
+
if (!token.includes("/") || token.includes("*") || /^(?:https?|ftp):\/\//i.test(token)) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
if (/\s/.test(token))
|
|
52
|
+
return null;
|
|
53
|
+
const withoutLine = token.replace(/:\d+(?:-\d+)?$/, "");
|
|
54
|
+
const separatorIndex = withoutLine.includes("::")
|
|
55
|
+
? withoutLine.indexOf("::")
|
|
56
|
+
: withoutLine.indexOf("#");
|
|
57
|
+
const path = separatorIndex >= 0
|
|
58
|
+
? withoutLine.slice(0, separatorIndex)
|
|
59
|
+
: withoutLine;
|
|
60
|
+
if (!path || path.startsWith("/") || path.includes("//"))
|
|
61
|
+
return null;
|
|
62
|
+
const isDirectory = path.endsWith("/");
|
|
63
|
+
const fileName = path.split("/").at(-1) ?? "";
|
|
64
|
+
const hasExtension = /\.[A-Za-z0-9][A-Za-z0-9._-]*$/.test(fileName);
|
|
65
|
+
return isDirectory || hasExtension ? withoutLine : null;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=card-anchors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"card-anchors.js","sourceRoot":"","sources":["../../src/lib/card-anchors.ts"],"names":[],"mappings":"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"}
|