pi-mox 0.1.0 → 0.2.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/CHANGELOG.md +18 -0
- package/README.md +10 -3
- package/package.json +3 -2
- package/src/mox.ts +31 -7
- package/src/wire.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,24 @@ version may add commands and options and a patch version fixes.
|
|
|
5
5
|
|
|
6
6
|
## Unreleased
|
|
7
7
|
|
|
8
|
+
## 0.2.0
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `/mox show <id>` shows one cue with its whole message.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- `/mox list` and the id completions show each message on one line: whitespace and line breaks collapse to
|
|
17
|
+
one space, and a message over 60 characters is cut with `…`. `/mox show <id>` gives the whole message.
|
|
18
|
+
|
|
19
|
+
## 0.1.1
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- A gallery preview image (`pi.image`) in the Roman inscription look, also at the top of the README;
|
|
24
|
+
its source is `assets/preview.html`.
|
|
25
|
+
|
|
8
26
|
## 0.1.0
|
|
9
27
|
|
|
10
28
|
### Added
|
package/README.md
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
# pi-mox
|
|
1
|
+
# ·MOX· pi-mox
|
|
2
|
+
|
|
3
|
+

|
|
2
4
|
|
|
3
5
|
Schedule a message for the agent in [Pi](https://github.com/earendil-works/pi). Say when, say what, and at
|
|
4
6
|
that time the message reaches the agent and starts a turn. *Mox* is Latin for "soon".
|
|
@@ -21,10 +23,11 @@ pi install npm:pi-mox
|
|
|
21
23
|
| Command | What it does |
|
|
22
24
|
| --- | --- |
|
|
23
25
|
| `/mox <time> <message>` | Deliver `<message>` to the agent at `<time>` |
|
|
24
|
-
| `/mox list` (or `/mox`) | Show the pending cues |
|
|
26
|
+
| `/mox list` (or `/mox`) | Show the pending cues, each message on one line cut at 60 characters with `…` |
|
|
27
|
+
| `/mox show <id>` | Show one cue with its whole message |
|
|
25
28
|
| `/mox cancel <id>` | Cancel a cue; the id is Roman (`II`, `ii`) or Arabic (`2`) |
|
|
26
29
|
|
|
27
|
-
`list` and `cancel` are reserved first words.
|
|
30
|
+
`list`, `show` and `cancel` are reserved first words.
|
|
28
31
|
|
|
29
32
|
### Time
|
|
30
33
|
|
|
@@ -48,6 +51,10 @@ Scheduled II for 14:00 (in 5h36m): corre la suite
|
|
|
48
51
|
I 10:30 2h06m continúa con T3
|
|
49
52
|
II 14:00 5h36m corre la suite
|
|
50
53
|
|
|
54
|
+
/mox show I
|
|
55
|
+
I 10:30 2h06m
|
|
56
|
+
continúa con T3
|
|
57
|
+
|
|
51
58
|
/mox cancel II
|
|
52
59
|
Cancelled II (14:00): corre la suite
|
|
53
60
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-mox",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Schedule a message for the agent in Pi: /mox 10:30 <message> delivers it at that time and starts a turn.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "jals1212",
|
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
"pi": {
|
|
23
23
|
"extensions": [
|
|
24
24
|
"./extensions/mox.ts"
|
|
25
|
-
]
|
|
25
|
+
],
|
|
26
|
+
"image": "https://raw.githubusercontent.com/jals1212/pi-mox/main/assets/preview.png"
|
|
26
27
|
},
|
|
27
28
|
"files": [
|
|
28
29
|
"src",
|
package/src/mox.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// pi-mox core: time parsing, Roman numerals, the cue list and its wall-clock scheduler, and the /mox command.
|
|
2
2
|
// No Pi runtime imports here (see src/wire.ts for the wiring), so everything runs under plain `node --test`.
|
|
3
3
|
|
|
4
|
-
export const USAGE = "Usage: /mox <time> <message>, /mox list, /mox cancel <id> (time: 10:30 or +2h15m)";
|
|
4
|
+
export const USAGE = "Usage: /mox <time> <message>, /mox list, /mox show <id>, /mox cancel <id> (time: 10:30 or +2h15m)";
|
|
5
5
|
|
|
6
6
|
/** A pending cue: a message to deliver at `at` (epoch milliseconds). `id` is shown as a Roman numeral. */
|
|
7
7
|
export interface Cue {
|
|
@@ -236,6 +236,16 @@ export function createMox(options: MoxOptions): Mox {
|
|
|
236
236
|
|
|
237
237
|
// --- Command ---
|
|
238
238
|
|
|
239
|
+
const PREVIEW_CHARS = 60;
|
|
240
|
+
|
|
241
|
+
/** One-line preview for lists: whitespace runs collapse to one space; over 60 characters it ends in `…`. */
|
|
242
|
+
export function previewMessage(message: string): string {
|
|
243
|
+
const line = message.replace(/\s+/g, " ").trim();
|
|
244
|
+
return line.length > PREVIEW_CHARS ? `${line.slice(0, PREVIEW_CHARS - 1).trimEnd()}…` : line;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const parseId = (text: string) => (/^\d+$/.test(text) ? Number(text) : fromRoman(text));
|
|
248
|
+
|
|
239
249
|
const dayStart = (ms: number) => new Date(new Date(ms).setHours(0, 0, 0, 0)).getTime();
|
|
240
250
|
|
|
241
251
|
function dayLabel(at: number, now: number): string {
|
|
@@ -265,16 +275,26 @@ export function runMoxCommand(args: string, deps: CommandDeps): void {
|
|
|
265
275
|
return info(
|
|
266
276
|
cues
|
|
267
277
|
.map((cue) => {
|
|
268
|
-
const line = `${formatClock(cue.at)} ${formatRemaining(cue.at - now)} ${cue.message}`;
|
|
278
|
+
const line = `${formatClock(cue.at)} ${formatRemaining(cue.at - now)} ${previewMessage(cue.message)}`;
|
|
269
279
|
return `${paint(BRONZE, toRoman(cue.id).padEnd(width), ctx.hasUI)} ${paint(MARBLE, line, ctx.hasUI)}`;
|
|
270
280
|
})
|
|
271
281
|
.join("\n"),
|
|
272
282
|
);
|
|
273
283
|
}
|
|
274
284
|
|
|
285
|
+
if (word === "show") {
|
|
286
|
+
if (rest === "") return fail("Missing cue id.");
|
|
287
|
+
const id = parseId(rest);
|
|
288
|
+
if (id === undefined || id < 1) return fail(`Invalid cue id "${rest}".`);
|
|
289
|
+
const cue = mox.list().find((candidate) => candidate.id === id);
|
|
290
|
+
if (!cue) return fail(`No pending cue ${toRoman(id)}.`);
|
|
291
|
+
const head = `${toRoman(cue.id)} ${formatClock(cue.at)} ${formatRemaining(cue.at - deps.now())}`;
|
|
292
|
+
return info(`${paint(BRONZE, head, ctx.hasUI)}\n${paint(MARBLE, cue.message, ctx.hasUI)}`);
|
|
293
|
+
}
|
|
294
|
+
|
|
275
295
|
if (word === "cancel") {
|
|
276
296
|
if (rest === "") return fail("Missing cue id.");
|
|
277
|
-
const id =
|
|
297
|
+
const id = parseId(rest);
|
|
278
298
|
if (id === undefined || id < 1) return fail(`Invalid cue id "${rest}".`);
|
|
279
299
|
const cue = mox.cancel(id);
|
|
280
300
|
if (!cue) return fail(`No pending cue ${toRoman(id)}.`);
|
|
@@ -289,20 +309,24 @@ export function runMoxCommand(args: string, deps: CommandDeps): void {
|
|
|
289
309
|
info(`Scheduled ${toRoman(cue.id)} for ${formatClock(at)}${dayLabel(at, now)} (in ${formatRemaining(at - now)}): ${rest}`);
|
|
290
310
|
}
|
|
291
311
|
|
|
292
|
-
/** Autocompletion: `list`, `cancel`, and pending ids after `cancel`. */
|
|
312
|
+
/** Autocompletion: `list`, `show`, `cancel`, and pending ids after `show` or `cancel`. */
|
|
293
313
|
export function completeMoxArgs(prefix: string, mox: Mox): { value: string; label: string }[] | null {
|
|
294
314
|
const words = prefix.split(" ");
|
|
295
315
|
if (words.length === 1) {
|
|
296
|
-
const items = ["list", "cancel"].filter((sub) => sub.startsWith(words[0])).map((sub) => ({ value: sub, label: sub }));
|
|
316
|
+
const items = ["list", "show", "cancel"].filter((sub) => sub.startsWith(words[0])).map((sub) => ({ value: sub, label: sub }));
|
|
297
317
|
return items.length > 0 ? items : null;
|
|
298
318
|
}
|
|
299
|
-
|
|
319
|
+
const sub = words[0];
|
|
320
|
+
if (words.length !== 2 || (sub !== "cancel" && sub !== "show")) return null;
|
|
300
321
|
const typed = words[1].toUpperCase();
|
|
301
322
|
const items = mox
|
|
302
323
|
.list()
|
|
303
324
|
.sort((a, b) => a.id - b.id)
|
|
304
325
|
.filter((cue) => toRoman(cue.id).startsWith(typed) || String(cue.id).startsWith(typed))
|
|
305
|
-
.map((cue) => ({
|
|
326
|
+
.map((cue) => ({
|
|
327
|
+
value: `${sub} ${toRoman(cue.id)}`,
|
|
328
|
+
label: `${toRoman(cue.id)} ${formatClock(cue.at)} ${previewMessage(cue.message)}`,
|
|
329
|
+
}));
|
|
306
330
|
return items.length > 0 ? items : null;
|
|
307
331
|
}
|
|
308
332
|
|
package/src/wire.ts
CHANGED
|
@@ -50,7 +50,7 @@ export function registerMox(pi: ExtensionAPI, options: WireOptions): void {
|
|
|
50
50
|
});
|
|
51
51
|
|
|
52
52
|
pi.registerCommand("mox", {
|
|
53
|
-
description: "Schedule a message for the agent: /mox <10:30|+2h15m> <message>, /mox list, /mox cancel <id>",
|
|
53
|
+
description: "Schedule a message for the agent: /mox <10:30|+2h15m> <message>, /mox list, /mox show <id>, /mox cancel <id>",
|
|
54
54
|
getArgumentCompletions: (prefix) => completeMoxArgs(prefix, mox),
|
|
55
55
|
handler: async (args, ctx) => {
|
|
56
56
|
use(ctx);
|