@kaiserlich-dev/pi-queue-picker 1.0.0 → 1.0.3
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 +9 -0
- package/extensions/queue-picker.ts +32 -19
- package/package.json +7 -4
package/README.md
CHANGED
|
@@ -23,6 +23,8 @@ When the agent is idle, Enter submits normally. When the agent is busy:
|
|
|
23
23
|
|
|
24
24
|
The picker remembers your last chosen mode as the default.
|
|
25
25
|
|
|
26
|
+
Slash commands (for example `/model`, `/settings`, `/skill:name`, or `/prompt-template`) bypass the picker while busy so interactive command UIs still open normally.
|
|
27
|
+
|
|
26
28
|
### Editing queued messages
|
|
27
29
|
|
|
28
30
|
Queued messages stay in an editable buffer until the agent finishes. To edit them:
|
|
@@ -82,6 +84,13 @@ pi install git:github.com/kaiserlich-dev/pi-queue-picker
|
|
|
82
84
|
|
|
83
85
|
Then restart pi or run `/reload`.
|
|
84
86
|
|
|
87
|
+
## Development
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# Run locally without installing
|
|
91
|
+
pi -e ./extensions/queue-picker.ts
|
|
92
|
+
```
|
|
93
|
+
|
|
85
94
|
## Compatibility
|
|
86
95
|
|
|
87
96
|
Works alongside other extensions that customize the editor (e.g. `pi-powerline-footer`). Uses the `input` event API instead of replacing the editor component.
|
|
@@ -45,6 +45,22 @@ function isLimitedTerminal(): boolean {
|
|
|
45
45
|
return false;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Commands like /model, /settings, /skill:name should bypass the delivery picker.
|
|
50
|
+
* They are interactive control flow, not chat content.
|
|
51
|
+
*/
|
|
52
|
+
export function shouldBypassPicker(text: string): boolean {
|
|
53
|
+
const trimmed = text.trim();
|
|
54
|
+
if (!trimmed.startsWith("/")) return false;
|
|
55
|
+
|
|
56
|
+
const firstToken = trimmed.split(/\s+/, 1)[0];
|
|
57
|
+
if (firstToken === "/") return true;
|
|
58
|
+
|
|
59
|
+
// Commands are one slash-prefixed token without extra slashes, e.g. /model, /skill:name
|
|
60
|
+
if (firstToken.slice(1).includes("/")) return false;
|
|
61
|
+
return /^\/[a-z0-9:_-]+$/i.test(firstToken);
|
|
62
|
+
}
|
|
63
|
+
|
|
48
64
|
const PICKER_WIDTH = 72;
|
|
49
65
|
const BOX_WIDTH = 76;
|
|
50
66
|
|
|
@@ -56,25 +72,23 @@ export default function (pi: ExtensionAPI) {
|
|
|
56
72
|
|
|
57
73
|
// --- Helpers ---
|
|
58
74
|
|
|
59
|
-
function sendToPi(text: string,
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
pi.sendUserMessage(text, { deliverAs: mode });
|
|
64
|
-
}
|
|
75
|
+
function sendToPi(text: string, mode: PickerMode) {
|
|
76
|
+
// Always specify deliverAs for safety — even at agent_end another
|
|
77
|
+
// extension handler may have already started a new turn.
|
|
78
|
+
pi.sendUserMessage(text, { deliverAs: mode });
|
|
65
79
|
}
|
|
66
80
|
|
|
67
|
-
function flushOneQueuedMessage(
|
|
81
|
+
function flushOneQueuedMessage() {
|
|
68
82
|
const next = shiftNext(buffer);
|
|
69
83
|
if (!next) return;
|
|
70
|
-
sendToPi(next.text,
|
|
84
|
+
sendToPi(next.text, next.mode);
|
|
71
85
|
updateWidget(uiRef, buffer);
|
|
72
86
|
}
|
|
73
87
|
|
|
74
88
|
function flushOneSteerWhileBusy() {
|
|
75
89
|
const steerMsg = shiftNextSteer(buffer);
|
|
76
90
|
if (!steerMsg) return;
|
|
77
|
-
sendToPi(steerMsg.text,
|
|
91
|
+
sendToPi(steerMsg.text, "steer");
|
|
78
92
|
updateWidget(uiRef, buffer);
|
|
79
93
|
}
|
|
80
94
|
|
|
@@ -142,7 +156,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
142
156
|
updateWidget(uiRef, buffer);
|
|
143
157
|
|
|
144
158
|
if (ctx.isIdle() && buffer.length > 0) {
|
|
145
|
-
flushOneQueuedMessage(
|
|
159
|
+
flushOneQueuedMessage();
|
|
146
160
|
} else if (!ctx.isIdle()) {
|
|
147
161
|
flushOneSteerWhileBusy();
|
|
148
162
|
}
|
|
@@ -155,14 +169,9 @@ export default function (pi: ExtensionAPI) {
|
|
|
155
169
|
clearBuffer();
|
|
156
170
|
});
|
|
157
171
|
|
|
158
|
-
pi.on("
|
|
159
|
-
uiRef = ctx.ui;
|
|
160
|
-
clearBuffer();
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
pi.on("agent_end", async (_event, ctx) => {
|
|
172
|
+
pi.on("agent_end", async (_event, _ctx) => {
|
|
164
173
|
if (editingQueue || buffer.length === 0) return;
|
|
165
|
-
flushOneQueuedMessage(
|
|
174
|
+
flushOneQueuedMessage();
|
|
166
175
|
});
|
|
167
176
|
|
|
168
177
|
pi.on("input", async (event, ctx) => {
|
|
@@ -174,6 +183,10 @@ export default function (pi: ExtensionAPI) {
|
|
|
174
183
|
return { action: "continue" as const };
|
|
175
184
|
}
|
|
176
185
|
|
|
186
|
+
if (shouldBypassPicker(event.text)) {
|
|
187
|
+
return { action: "continue" as const };
|
|
188
|
+
}
|
|
189
|
+
|
|
177
190
|
if (isLimitedTerminal()) {
|
|
178
191
|
return { action: "continue" as const };
|
|
179
192
|
}
|
|
@@ -224,7 +237,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
224
237
|
lastMode = mode;
|
|
225
238
|
|
|
226
239
|
if (mode === "steer") {
|
|
227
|
-
|
|
240
|
+
sendToPi(event.text, "steer");
|
|
228
241
|
ctx.ui.notify(`Steer: ${event.text}`, "info");
|
|
229
242
|
} else {
|
|
230
243
|
addMessage(buffer, {
|
|
@@ -239,7 +252,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
239
252
|
);
|
|
240
253
|
|
|
241
254
|
if (ctx.isIdle()) {
|
|
242
|
-
flushOneQueuedMessage(
|
|
255
|
+
flushOneQueuedMessage();
|
|
243
256
|
}
|
|
244
257
|
}
|
|
245
258
|
|
package/package.json
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kaiserlich-dev/pi-queue-picker",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "Pick between steering and follow-up when queuing messages in pi",
|
|
5
5
|
"keywords": [
|
|
6
|
-
"pi-package"
|
|
6
|
+
"pi-package",
|
|
7
|
+
"pi-coding-agent",
|
|
8
|
+
"queue",
|
|
9
|
+
"message-buffer"
|
|
7
10
|
],
|
|
8
11
|
"license": "MIT",
|
|
9
12
|
"repository": {
|
|
@@ -26,8 +29,8 @@
|
|
|
26
29
|
"image": "https://raw.githubusercontent.com/kaiserlich-dev/pi-queue-picker/main/assets/preview.png"
|
|
27
30
|
},
|
|
28
31
|
"peerDependencies": {
|
|
29
|
-
"@mariozechner/pi-coding-agent": "
|
|
30
|
-
"@mariozechner/pi-tui": "
|
|
32
|
+
"@mariozechner/pi-coding-agent": "^0.65.0",
|
|
33
|
+
"@mariozechner/pi-tui": "^0.65.0"
|
|
31
34
|
},
|
|
32
35
|
"scripts": {
|
|
33
36
|
"publish:pi": "bash ./scripts/publish.sh",
|