@vs4vijay/piverse 0.1.0 → 0.6.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/.agents/skills/pi-extension/SKILL.md +229 -0
- package/.github/workflows/ci.yml +18 -0
- package/.github/workflows/release.yml +106 -0
- package/LICENSE +21 -0
- package/README.md +70 -27
- package/extensions/pi-notes/README.md +152 -0
- package/extensions/pi-notes/package.json +31 -0
- package/extensions/pi-notes/plan.md +151 -0
- package/extensions/pi-notes/src/index.ts +369 -0
- package/extensions/pi-notes/src/store.ts +229 -0
- package/extensions/pi-notes/src/tui.ts +426 -0
- package/extensions/pi-notes/src/types.ts +60 -0
- package/extensions/pi-queue/README.md +178 -0
- package/extensions/pi-queue/package.json +14 -1
- package/extensions/pi-queue/plan.md +79 -0
- package/extensions/pi-queue/src/index.ts +136 -28
- package/package.json +21 -5
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# @vs4vijay/pi-queue
|
|
2
|
+
|
|
3
|
+
Queue messages to run after the current Pi agent turn settles.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
Install from npm, then add it to your pi config:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
pi install npm:@vs4vijay/pi-queue
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
In your pi config, reference the package as an extension:
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"pi": {
|
|
18
|
+
"extensions": ["@vs4vijay/pi-queue"]
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Or, when developing in this repo, reference the extension path directly:
|
|
24
|
+
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"pi": {
|
|
28
|
+
"extensions": ["./extensions/pi-queue/src/index.ts"]
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Commands
|
|
34
|
+
|
|
35
|
+
All commands are available as both `/queue-*` and `/q-*`.
|
|
36
|
+
|
|
37
|
+
| Command | Alias | Description |
|
|
38
|
+
|---------|-------|-------------|
|
|
39
|
+
| `/queue <message>` | `/q <message>` | Add a message to the queue |
|
|
40
|
+
| `/queue` | `/q` | Show pending messages with index numbers |
|
|
41
|
+
| `/queue-clear` | `/q-clear` | Clear all queued messages |
|
|
42
|
+
| `/queue-pause` | `/q-pause` | Pause auto-firing (queue stays intact) |
|
|
43
|
+
| `/queue-resume` | `/q-resume` | Resume auto-firing and fire next immediately |
|
|
44
|
+
| `/queue-flush` | `/q-flush` | Drain all remaining messages, one per turn, ignoring pause / error stop |
|
|
45
|
+
| `/queue-rm <index>` | `/q-rm <index>` | Remove item at position (1-based) |
|
|
46
|
+
| `/queue-next <msg>` | `/q-next <msg>` | Insert message at front (fires next) |
|
|
47
|
+
| `/queue-file <path>` | `/q-file <path>` | Queue lines from a file (skips `#` comments) |
|
|
48
|
+
|
|
49
|
+
## How It Works
|
|
50
|
+
|
|
51
|
+
Queued messages are intentionally delivered **after** the current turn settles. The extension listens for the `agent_settled` event and only then fires the next message as a new user message — so follow-ups you queue mid-run never interrupt the turn in progress. They execute cleanly afterwards, one at a time.
|
|
52
|
+
|
|
53
|
+
1. You `/q` one or more messages while the agent is working (or idle).
|
|
54
|
+
2. The extension listens for the `agent_settled` event — fired when the agent fully settles.
|
|
55
|
+
3. On settle, the next queued message fires as a new user message via `pi.sendUserMessage()`.
|
|
56
|
+
4. Messages execute one at a time, in FIFO order.
|
|
57
|
+
5. Slash commands (messages starting with `/`) are dispatched through the command system automatically.
|
|
58
|
+
|
|
59
|
+
## Example usage
|
|
60
|
+
|
|
61
|
+
Queue follow-ups while the agent is working:
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
> /queue refactor the auth module next
|
|
65
|
+
Queued #1: "refactor the auth module next"
|
|
66
|
+
|
|
67
|
+
> /queue run the test suite
|
|
68
|
+
Queued #2: "run the test suite"
|
|
69
|
+
|
|
70
|
+
> /queue
|
|
71
|
+
Queued (2):
|
|
72
|
+
1. refactor the auth module next
|
|
73
|
+
2. run the test suite
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Once the current turn settles, the queued messages fire one at a time as new user messages:
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
→ Queue: running 1/2 # "refactor the auth module next" is sent
|
|
80
|
+
→ Queue: running 2/2 # "run the test suite" is sent
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Changed your mind? Clear the queue instead:
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
> /queue-clear
|
|
87
|
+
Cleared 2 queued message(s)
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
With nothing queued:
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
> /queue
|
|
94
|
+
Queue is empty. /queue <message> to add.
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
If the queue is paused and empty:
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
> /queue-pause
|
|
101
|
+
Queue paused.
|
|
102
|
+
|
|
103
|
+
> /queue
|
|
104
|
+
Queue is empty and paused. /queue <message> to add.
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Features
|
|
108
|
+
|
|
109
|
+
### Stop on Error
|
|
110
|
+
|
|
111
|
+
If a tool error occurs during a turn, the queue auto-pauses and notifies you. Use `/q-resume` to continue, or `/q-rm` to skip the problematic next item.
|
|
112
|
+
|
|
113
|
+
### Progress
|
|
114
|
+
|
|
115
|
+
During a drain sequence, you'll see: `Queue: running 2/5` — showing which item is firing out of the total batch.
|
|
116
|
+
|
|
117
|
+
### Queue from File
|
|
118
|
+
|
|
119
|
+
Load a batch of messages from a file:
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
# tasks.txt
|
|
123
|
+
add error handling to the auth module
|
|
124
|
+
write tests for it
|
|
125
|
+
# this line is skipped
|
|
126
|
+
update the README
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
/q-file tasks.txt
|
|
131
|
+
→ Queued 3 item(s) from tasks.txt
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Flush
|
|
135
|
+
|
|
136
|
+
`/q-flush` drains **all** remaining queued messages back-to-back, one per turn — overriding both a manual pause and the stop-on-error behavior. Useful when you want the whole backlog fired off at once regardless of a mid-batch error.
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
> /q-flush
|
|
140
|
+
Flush armed — firing all 3 remaining, one per turn.
|
|
141
|
+
→ Queue: running 1/3
|
|
142
|
+
→ Queue: running 2/3
|
|
143
|
+
→ Queue: running 3/3
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Running `/q-flush` on an empty queue reports `Queue already empty.`
|
|
147
|
+
|
|
148
|
+
## Persistence
|
|
149
|
+
|
|
150
|
+
Queue state and pause flag persist across `/reload` and session restarts via `session_shutdown`/`session_start` hooks.
|
|
151
|
+
|
|
152
|
+
## Example
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
> /q add error handling to the auth module
|
|
156
|
+
Queued #1: "add error handling to the auth module"
|
|
157
|
+
|
|
158
|
+
> /q write tests for it
|
|
159
|
+
Queued #2: "write tests for it"
|
|
160
|
+
|
|
161
|
+
> /q
|
|
162
|
+
Queued (2):
|
|
163
|
+
1. add error handling to the auth module
|
|
164
|
+
2. write tests for it
|
|
165
|
+
|
|
166
|
+
> /q-next fix the lint errors first
|
|
167
|
+
Inserted at #1: "fix the lint errors first" (3 total)
|
|
168
|
+
|
|
169
|
+
> /q-pause
|
|
170
|
+
Queue paused.
|
|
171
|
+
|
|
172
|
+
> /q-rm 3
|
|
173
|
+
Removed #3: "write tests for it" (2 remaining)
|
|
174
|
+
|
|
175
|
+
> /q-resume
|
|
176
|
+
Queue resumed. Firing next (2 remaining).
|
|
177
|
+
→ Queue: running 1/2
|
|
178
|
+
```
|
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vs4vijay/pi-queue",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Queue messages to run after the current Pi session turn settles",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": ["pi-package"],
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/vs4vijay/piverse.git"
|
|
11
|
+
},
|
|
12
|
+
"author": "vs4vijay",
|
|
13
|
+
"homepage": "https://github.com/vs4vijay/piverse",
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/vs4vijay/piverse/issues"
|
|
16
|
+
},
|
|
7
17
|
"pi": {
|
|
8
18
|
"extensions": ["./src/index.ts"]
|
|
9
19
|
},
|
|
@@ -12,5 +22,8 @@
|
|
|
12
22
|
},
|
|
13
23
|
"peerDependencies": {
|
|
14
24
|
"@earendil-works/pi-coding-agent": "*"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"typescript": "^5.0.0"
|
|
15
28
|
}
|
|
16
29
|
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# pi-queue — Feature Plan
|
|
2
|
+
|
|
3
|
+
## Current State
|
|
4
|
+
|
|
5
|
+
FIFO message queue that fires after each agent turn settles. Commands: `/queue <msg>`, `/queue` (show), `/queue-clear`, `/queue-pause`, `/queue-resume`, `/queue-flush`, `/queue-rm`, `/queue-next`, `/queue-file`. Persists across session restarts. Auto-pauses on tool error; flushes override both pause and error stop.
|
|
6
|
+
|
|
7
|
+
All planned features below are implemented.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Planned Features
|
|
12
|
+
|
|
13
|
+
### 1. Alias: `/q`
|
|
14
|
+
|
|
15
|
+
- Register `/q` as an alias for `/queue` (same handler).
|
|
16
|
+
- Similarly `/q-pause`, `/q-resume`, `/q-rm`, `/q-next`, `/q-file`, `/q-clear`.
|
|
17
|
+
- Shorter to type during fast workflows.
|
|
18
|
+
- **Done.**
|
|
19
|
+
|
|
20
|
+
### 2. Pause / Resume
|
|
21
|
+
|
|
22
|
+
- `/queue-pause` — stops auto-firing on `agent_settled`. Queue stays intact.
|
|
23
|
+
- `/queue-resume` — re-enables auto-firing and immediately fires next if agent is idle.
|
|
24
|
+
- Show paused state in `/queue` output (e.g., `"Queued (3, PAUSED)"`); when paused and empty, show a combined empty+paused message.
|
|
25
|
+
- **Done.**
|
|
26
|
+
|
|
27
|
+
### 3. Remove / Priority Insert
|
|
28
|
+
|
|
29
|
+
- `/queue-rm <index>` — remove item at position (1-based).
|
|
30
|
+
- `/queue-next <message>` — insert at position 1 (fire next).
|
|
31
|
+
- **Done.**
|
|
32
|
+
|
|
33
|
+
### 4. Stop on Error
|
|
34
|
+
|
|
35
|
+
- If the agent's previous turn produced an error (tool failure, error event), auto-pause the queue.
|
|
36
|
+
- Notify: `"Queue paused — previous turn had errors. /queue-resume to continue."`.
|
|
37
|
+
- Error detection: watch `tool_result` events for `isError`.
|
|
38
|
+
- **Done.**
|
|
39
|
+
|
|
40
|
+
### 5. Progress Notification
|
|
41
|
+
|
|
42
|
+
- On each `agent_settled` drain, notify: `"Queue: running 2/5"`.
|
|
43
|
+
- Track total at start of drain batch vs remaining.
|
|
44
|
+
- Reset counter when queue empties or new items are added after drain completes.
|
|
45
|
+
- **Done.**
|
|
46
|
+
|
|
47
|
+
### 6. Queue from File
|
|
48
|
+
|
|
49
|
+
- `/queue-file <path>` — read file, each non-empty line becomes a queued message.
|
|
50
|
+
- Skip lines starting with `#` (comments).
|
|
51
|
+
- Report count added.
|
|
52
|
+
- **Done.**
|
|
53
|
+
|
|
54
|
+
### 7. Flush
|
|
55
|
+
|
|
56
|
+
- `/queue-flush` — arm a drain that fires **all** remaining messages, one per `agent_settled`, ignoring both the manual pause and the stop-on-error pause, until the queue is empty.
|
|
57
|
+
- Repeatedly sending `pi.sendUserMessage` one per turn keeps the extension's "fire after settle, one at a time" model intact and lets each message complete cleanly.
|
|
58
|
+
- **Done.**
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Implementation Order
|
|
63
|
+
|
|
64
|
+
| Phase | Features | Reason |
|
|
65
|
+
|-------|----------|--------|
|
|
66
|
+
| 1 | Alias, Pause/Resume, Remove, Queue-next | Steer a running queue |
|
|
67
|
+
| 2 | Stop on Error, Progress | Safety + visibility |
|
|
68
|
+
| 3 | Queue from File | Batch input |
|
|
69
|
+
| 4 | Flush | Drain the whole backlog on demand |
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Notes
|
|
74
|
+
|
|
75
|
+
- All commands register via `pi.registerCommand`. Each command gets both `/queue-*` and `/q-*` variants.
|
|
76
|
+
- State additions (pause flag, progress counter) persist via existing `session_shutdown`/`session_start` pattern. The transient `flushing` flag resets on empty and on session start.
|
|
77
|
+
- The queue sends messages as-is — shell commands ("run npm test") work because the agent interprets them like any user message.
|
|
78
|
+
- Slash commands (e.g., `/review src/index.ts`, `/commit`) are supported: when a queued message starts with `/`, pass `{ expandPromptTemplates: true }` to `pi.sendUserMessage()` so it routes through the command dispatcher instead of going to the agent as plain text.
|
|
79
|
+
- Handlers type their context as `ExtensionCommandContext` from `@earendil-works/pi-coding-agent`.
|
|
@@ -1,52 +1,160 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import type { ExtensionAPI, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
2
4
|
|
|
3
5
|
export default function (pi: ExtensionAPI) {
|
|
4
6
|
let queue: string[] = [];
|
|
7
|
+
let paused = false;
|
|
8
|
+
let lastTurnHadError = false;
|
|
9
|
+
let drainTotal = 0;
|
|
10
|
+
let flushing = false;
|
|
5
11
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
// Register command under both /queue-* and /q-* names
|
|
13
|
+
function cmd(name: string, description: string, handler: (args: string, ctx: ExtensionCommandContext) => Promise<void>) {
|
|
14
|
+
const opts = { description, handler };
|
|
15
|
+
pi.registerCommand(`queue${name}`, opts);
|
|
16
|
+
pi.registerCommand(`q${name}`, opts);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
cmd("", "Queue a message to send after the current turn settles. No args = show queue.", async (args, ctx) => {
|
|
20
|
+
if (!args.trim()) {
|
|
21
|
+
if (queue.length === 0) {
|
|
22
|
+
ctx.ui.notify(
|
|
23
|
+
paused
|
|
24
|
+
? "Queue is empty and paused. /queue <message> to add."
|
|
25
|
+
: "Queue is empty. /queue <message> to add.",
|
|
26
|
+
"info"
|
|
27
|
+
);
|
|
28
|
+
} else {
|
|
29
|
+
const label = paused ? `Queued (${queue.length}, PAUSED)` : `Queued (${queue.length})`;
|
|
30
|
+
const display = queue.map((m, i) => `${i + 1}. ${m}`).join("\n");
|
|
31
|
+
ctx.ui.notify(`${label}:\n${display}`, "info");
|
|
17
32
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
queue.push(args.trim());
|
|
36
|
+
ctx.ui.notify(`Queued #${queue.length}: "${args.trim()}"`, "info");
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
cmd("-clear", "Clear all queued messages", async (_args, ctx) => {
|
|
40
|
+
const count = queue.length;
|
|
41
|
+
queue = [];
|
|
42
|
+
ctx.ui.notify(count ? `Cleared ${count} queued message(s)` : "Queue already empty", "info");
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
cmd("-pause", "Pause queue auto-firing", async (_args, ctx) => {
|
|
46
|
+
paused = true;
|
|
47
|
+
ctx.ui.notify("Queue paused.", "info");
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
cmd("-resume", "Resume queue auto-firing", async (_args, ctx) => {
|
|
51
|
+
paused = false;
|
|
52
|
+
if (queue.length > 0) {
|
|
53
|
+
ctx.ui.notify(`Queue resumed. Firing next (${queue.length} remaining).`, "info");
|
|
54
|
+
const next = queue.shift()!;
|
|
55
|
+
const opts = next.startsWith("/") ? { expandPromptTemplates: true } : {};
|
|
56
|
+
pi.sendUserMessage(next, opts);
|
|
57
|
+
} else {
|
|
58
|
+
ctx.ui.notify("Queue resumed (empty).", "info");
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
cmd("-flush", "Drain all remaining queued messages, one per turn, ignoring pause/error stop", async (_args, ctx) => {
|
|
63
|
+
if (queue.length === 0) {
|
|
64
|
+
ctx.ui.notify("Queue already empty.", "info");
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
flushing = true;
|
|
68
|
+
paused = false;
|
|
69
|
+
ctx.ui.notify(`Flush armed — firing all ${queue.length} remaining, one per turn.`, "info");
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
cmd("-rm", "Remove a queued item by index (1-based)", async (args, ctx) => {
|
|
73
|
+
const idx = parseInt(args.trim(), 10);
|
|
74
|
+
if (isNaN(idx) || idx < 1 || idx > queue.length) {
|
|
75
|
+
ctx.ui.notify(`Invalid index. Use 1-${queue.length}.`, "warning");
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const [removed] = queue.splice(idx - 1, 1);
|
|
79
|
+
ctx.ui.notify(`Removed #${idx}: "${removed}" (${queue.length} remaining)`, "info");
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
cmd("-next", "Insert a message at the front of the queue (fires next)", async (args, ctx) => {
|
|
83
|
+
const msg = args.trim();
|
|
84
|
+
if (!msg) {
|
|
85
|
+
ctx.ui.notify("Usage: /queue-next <message>", "warning");
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
queue.unshift(msg);
|
|
89
|
+
ctx.ui.notify(`Inserted at #1: "${msg}" (${queue.length} total)`, "info");
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
cmd("-file", "Queue messages from a file (one per line, # comments skipped)", async (args, ctx) => {
|
|
93
|
+
const filePath = args.trim();
|
|
94
|
+
if (!filePath) {
|
|
95
|
+
ctx.ui.notify("Usage: /queue-file <path>", "warning");
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const resolved = resolve(process.cwd(), filePath);
|
|
99
|
+
let content: string;
|
|
100
|
+
try {
|
|
101
|
+
content = readFileSync(resolved, "utf-8");
|
|
102
|
+
} catch {
|
|
103
|
+
ctx.ui.notify(`Cannot read file: ${resolved}`, "error");
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const lines = content.split("\n").filter((l) => l.trim() && !l.trim().startsWith("#"));
|
|
107
|
+
for (const line of lines) queue.push(line.trim());
|
|
108
|
+
ctx.ui.notify(`Queued ${lines.length} item(s) from ${filePath}`, "info");
|
|
21
109
|
});
|
|
22
110
|
|
|
23
|
-
pi.
|
|
24
|
-
|
|
25
|
-
handler: async (_args, ctx) => {
|
|
26
|
-
const count = queue.length;
|
|
27
|
-
queue = [];
|
|
28
|
-
ctx.ui.notify(count ? `Cleared ${count} queued message(s)` : "Queue already empty", "info");
|
|
29
|
-
},
|
|
111
|
+
pi.on("tool_result", async (event) => {
|
|
112
|
+
if (event.isError) lastTurnHadError = true;
|
|
30
113
|
});
|
|
31
114
|
|
|
32
|
-
pi.on("agent_settled", async () => {
|
|
33
|
-
if (queue.length === 0)
|
|
115
|
+
pi.on("agent_settled", async (_event, ctx) => {
|
|
116
|
+
if (queue.length === 0) {
|
|
117
|
+
drainTotal = 0;
|
|
118
|
+
flushing = false;
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
if (!flushing) {
|
|
122
|
+
if (lastTurnHadError) {
|
|
123
|
+
paused = true;
|
|
124
|
+
lastTurnHadError = false;
|
|
125
|
+
ctx.ui.notify("Queue paused — previous turn had errors. /queue-resume to continue.", "warning");
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
if (paused) return;
|
|
129
|
+
}
|
|
130
|
+
lastTurnHadError = false;
|
|
131
|
+
|
|
132
|
+
// Track progress
|
|
133
|
+
if (drainTotal === 0) drainTotal = queue.length;
|
|
134
|
+
const current = drainTotal - queue.length + 1;
|
|
135
|
+
ctx.ui.notify(`Queue: running ${current}/${drainTotal}`, "info");
|
|
136
|
+
|
|
34
137
|
const next = queue.shift()!;
|
|
35
|
-
|
|
138
|
+
const opts = next.startsWith("/") ? { expandPromptTemplates: true } : {};
|
|
139
|
+
pi.sendUserMessage(next, opts);
|
|
36
140
|
});
|
|
37
141
|
|
|
38
142
|
pi.on("session_start", async (_event, ctx) => {
|
|
39
143
|
queue = [];
|
|
144
|
+
paused = false;
|
|
145
|
+
flushing = false;
|
|
40
146
|
for (const entry of ctx.sessionManager.getEntries()) {
|
|
41
147
|
if (entry.type === "custom" && entry.customType === "piverse-queue-state") {
|
|
42
|
-
|
|
148
|
+
const data = entry.data as { queue: string[]; paused?: boolean };
|
|
149
|
+
queue = data.queue ?? [];
|
|
150
|
+
paused = data.paused ?? false;
|
|
43
151
|
}
|
|
44
152
|
}
|
|
45
153
|
});
|
|
46
154
|
|
|
47
155
|
pi.on("session_shutdown", async () => {
|
|
48
|
-
if (queue.length > 0) {
|
|
49
|
-
pi.appendEntry("piverse-queue-state", { queue });
|
|
156
|
+
if (queue.length > 0 || paused) {
|
|
157
|
+
pi.appendEntry("piverse-queue-state", { queue, paused });
|
|
50
158
|
}
|
|
51
159
|
});
|
|
52
160
|
}
|
package/package.json
CHANGED
|
@@ -1,17 +1,33 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vs4vijay/piverse",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "A multi-extension ecosystem for the Pi coding agent",
|
|
5
|
-
"keywords": [
|
|
3
|
+
"version": "0.6.0",
|
|
4
|
+
"description": "A multi-extension ecosystem for the Pi coding agent — message queueing (/queue) and project notes (/notes) extensions",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"pi-package"
|
|
7
|
+
],
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/vs4vijay/piverse.git"
|
|
12
|
+
},
|
|
13
|
+
"author": "vs4vijay",
|
|
14
|
+
"homepage": "https://github.com/vs4vijay/piverse",
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/vs4vijay/piverse/issues"
|
|
17
|
+
},
|
|
6
18
|
"type": "module",
|
|
7
19
|
"pi": {
|
|
8
|
-
"extensions": [
|
|
20
|
+
"extensions": [
|
|
21
|
+
"./extensions/pi-queue/src/index.ts",
|
|
22
|
+
"./extensions/pi-notes/src/index.ts"
|
|
23
|
+
]
|
|
9
24
|
},
|
|
10
25
|
"scripts": {
|
|
11
26
|
"typecheck": "tsc --noEmit"
|
|
12
27
|
},
|
|
13
28
|
"peerDependencies": {
|
|
14
|
-
"@earendil-works/pi-coding-agent": "
|
|
29
|
+
"@earendil-works/pi-coding-agent": "^0.84.2",
|
|
30
|
+
"@earendil-works/pi-tui": "^0.84.2",
|
|
15
31
|
"typebox": "*"
|
|
16
32
|
},
|
|
17
33
|
"devDependencies": {
|