@grrrck/pi-clear 0.4.0 → 0.5.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 +11 -0
- package/README.md +8 -3
- package/index.ts +66 -18
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.5.0] - 2026-11-05
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- A **same-or-pick dialog** after the writer picker: *Same model and thinking level* (first, so Enter re-uses the current settings) or *Pick a model and thinking level…*, which opens the destination pickers.
|
|
13
|
+
- Flag `--same`: skips the same-or-pick dialog and re-uses the current session's model and thinking level, as if the first option was chosen.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- `/hand-off <instructions>` uses the inline steering text as-is: the steering editor only opens when no instructions were typed after the command, so passing steering on the command line no longer adds a dialog to confirm or edit it.
|
|
18
|
+
|
|
8
19
|
## [0.4.0] - 2026-10-30
|
|
9
20
|
|
|
10
21
|
### Added
|
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ pi -e npm:@grrrck/pi-clear
|
|
|
29
29
|
|
|
30
30
|
```text
|
|
31
31
|
/clear
|
|
32
|
-
/hand-off [--fresh | --live] [steering instructions]
|
|
32
|
+
/hand-off [--fresh | --live] [--same] [steering instructions]
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
## `/clear` behavior
|
|
@@ -50,7 +50,7 @@ When `/hand-off` runs, the extension:
|
|
|
50
50
|
|
|
51
51
|
0. **chooses who writes the hand-off prompt** — see [Choosing the writer](#choosing-the-writer). The picker is skipped when `--fresh` or `--live` was passed
|
|
52
52
|
1. waits for the agent to become idle if needed
|
|
53
|
-
2. opens a model picker, then a thinking level picker, then
|
|
53
|
+
2. asks whether the next session keeps the current model and thinking level — the first option, so pressing Enter keeps them — or opens a model picker, then a thinking level picker, then collects steering instructions: text you typed after `/hand-off` (and its flags) is used as-is, and the steering editor only opens when you passed none. `--same` skips the same-or-pick dialog and re-uses the current model and thinking level. The model picker respects your session's model scoping (`--models` / `enabledModels`, the same set `/scoped-models` shows) and offers a Tab toggle between scoped and all models. In non-TUI modes it falls back to plain dialogs: the scoped list when configured, otherwise a two-level provider → model pick so the dialog never floods the screen
|
|
54
54
|
3. writes the hand-off prompt with the chosen writer — the live agent, or a single off-screen model call over a minimal reconstruction of the conversation
|
|
55
55
|
4. prepends a provenance comment naming the source session, starts a new session, applies the model and thinking level you picked, and inserts the prompt into the editor via `ctx.ui.setEditorText()`
|
|
56
56
|
5. stops there: the prompt sits in the editor for you to review, edit, and submit yourself
|
|
@@ -78,6 +78,8 @@ When the writer model supports reasoning, the fresh pass also asks for its **thi
|
|
|
78
78
|
Fresh pass flags and limits:
|
|
79
79
|
|
|
80
80
|
- `--fresh` skips the writer picker and uses the fresh pass; `--live` skips it and uses the current agent. Passing both is refused before any dialog opens.
|
|
81
|
+
- `--same` skips the same-or-pick dialog and re-uses the current session's model and thinking level. It combines freely with `--fresh` / `--live` and inline steering.
|
|
82
|
+
- Flags are only recognized at the front of the command args: `/hand-off --same fix the tests` parses the flag, but `/hand-off fix the tests --same` passes `--same` through as steering text. Anything after the first non-flag token is steering.
|
|
81
83
|
- There is no command-arg model flag: if you want a specific model to write the prompt, set it in the [config file](#configuration) (or pick it from the menu).
|
|
82
84
|
- The source is the post-compaction view of the session, so a compacted conversation is summarized from its summary rather than from nothing.
|
|
83
85
|
- Trimming keeps the opening message, the newest turns, and a contiguous run after the opening message; the middle is replaced by `[... <n> turns omitted — <k> chars ...]` and you get a notification saying how much was dropped. Raise the budget with the settings below if that happens.
|
|
@@ -152,7 +154,10 @@ node --test scripts/minimal-transcript.test.mjs # offline: fresh-pass transcr
|
|
|
152
154
|
node --test scripts/fresh-pass-flow.test.mjs # offline: /hand-off flow, both writers
|
|
153
155
|
```
|
|
154
156
|
|
|
155
|
-
The RPC smoke tests
|
|
157
|
+
The RPC smoke tests need at least two models with configured auth.
|
|
158
|
+
`rpc-handoff-smoke-test.py` makes **real, billed model requests** (the agent
|
|
159
|
+
writes the hand-off prompt); `rpc-smoke-test.py` only drives local RPC state
|
|
160
|
+
and makes none. The `node --test` scripts need neither auth nor a pi process.
|
|
156
161
|
|
|
157
162
|
## Related extensions
|
|
158
163
|
|
package/index.ts
CHANGED
|
@@ -13,13 +13,17 @@
|
|
|
13
13
|
* `/clear` starts an equally fresh session, then restores the model and
|
|
14
14
|
* thinking level that were active when you cleared.
|
|
15
15
|
*
|
|
16
|
-
* `/hand-off`: hand the conversation to another model
|
|
16
|
+
* `/hand-off`: hand the conversation to another model (or back to the same
|
|
17
|
+
* one, with `--same`).
|
|
17
18
|
*
|
|
18
19
|
* 1. The user runs `/hand-off`, optionally with `--fresh` or `--live` and
|
|
19
20
|
* steering text after them.
|
|
20
|
-
* 2. A dialog flow asks who writes the hand-off prompt, then
|
|
21
|
-
*
|
|
22
|
-
*
|
|
21
|
+
* 2. A dialog flow asks who writes the hand-off prompt, then asks whether the
|
|
22
|
+
* next session keeps the current model and thinking level (first option,
|
|
23
|
+
* so Enter keeps them) or opens the destination pickers — `--same` skips
|
|
24
|
+
* that dialog and re-uses the current values. Then steering instructions:
|
|
25
|
+
* text typed inline after `/hand-off` is used as-is, and an editor opens
|
|
26
|
+
* only when no inline steering was passed.
|
|
23
27
|
* 3. The hand-off prompt is written by one of two writers:
|
|
24
28
|
* - the **live agent** (default, first in the picker): the extension sends
|
|
25
29
|
* the current agent a custom message asking it to write its next message
|
|
@@ -170,6 +174,24 @@ async function selectModel(
|
|
|
170
174
|
return index === -1 ? undefined : ordered[index];
|
|
171
175
|
}
|
|
172
176
|
|
|
177
|
+
/**
|
|
178
|
+
* Same-or-pick picker between the writer and destination dialogs. The first
|
|
179
|
+
* option re-uses the current session's model and thinking level in one Enter
|
|
180
|
+
* press; the second opens the destination pickers. Without a current model
|
|
181
|
+
* there is nothing to re-use, so the destination pickers open directly.
|
|
182
|
+
*/
|
|
183
|
+
async function chooseSameOrPick(ctx: ExtensionContext): Promise<"same" | "pick" | undefined> {
|
|
184
|
+
if (!ctx.model) return "pick";
|
|
185
|
+
const labels = [
|
|
186
|
+
`${SAME_SETTINGS_LABEL} (${ctx.model.provider}/${ctx.model.id}${ctx.thinkingLevel ? ` · ${ctx.thinkingLevel}` : ""})`,
|
|
187
|
+
PICK_SETTINGS_LABEL,
|
|
188
|
+
];
|
|
189
|
+
const chosen = await ctx.ui.select("Model for the next session", labels);
|
|
190
|
+
if (chosen === undefined) return undefined;
|
|
191
|
+
const index = labelIndex(chosen, labels);
|
|
192
|
+
return index === 0 ? "same" : index === 1 ? "pick" : undefined;
|
|
193
|
+
}
|
|
194
|
+
|
|
173
195
|
/**
|
|
174
196
|
* Thinking level picker with the active level preselected, so Enter accepts
|
|
175
197
|
* the current setting.
|
|
@@ -913,6 +935,8 @@ async function generateFreshPassPrompt(
|
|
|
913
935
|
|
|
914
936
|
interface ParsedHandoffArgs {
|
|
915
937
|
writer?: "live" | "fresh";
|
|
938
|
+
/** `--same`: skip the destination pickers and reuse the current session's model and thinking level. */
|
|
939
|
+
same?: boolean;
|
|
916
940
|
/** Everything after the leading flags: the steering-editor prefill. */
|
|
917
941
|
steering: string;
|
|
918
942
|
error?: string;
|
|
@@ -934,6 +958,10 @@ export function parseHandoffArgs(args: string): ParsedHandoffArgs {
|
|
|
934
958
|
parsed.writer = writer;
|
|
935
959
|
continue;
|
|
936
960
|
}
|
|
961
|
+
if (token === "--same") {
|
|
962
|
+
parsed.same = true;
|
|
963
|
+
continue;
|
|
964
|
+
}
|
|
937
965
|
break;
|
|
938
966
|
}
|
|
939
967
|
|
|
@@ -1057,6 +1085,8 @@ interface WriterOptions {
|
|
|
1057
1085
|
|
|
1058
1086
|
const WRITER_LIVE_LABEL = "This agent — full context and tools";
|
|
1059
1087
|
const WRITER_FRESH_OTHER_LABEL = "Fresh pass — another model…";
|
|
1088
|
+
const SAME_SETTINGS_LABEL = "Same model and thinking level";
|
|
1089
|
+
const PICK_SETTINGS_LABEL = "Pick a model and thinking level…";
|
|
1060
1090
|
|
|
1061
1091
|
/** Pick the hand-off writer: the live agent, or a fresh pass with a chosen model. */
|
|
1062
1092
|
async function chooseWriter(ctx: ExtensionContext, options: WriterOptions): Promise<WriterChoice | undefined> {
|
|
@@ -1314,21 +1344,39 @@ export default function (pi: ExtensionAPI) {
|
|
|
1314
1344
|
writerReasoning = chosen.reasoning;
|
|
1315
1345
|
}
|
|
1316
1346
|
|
|
1317
|
-
// 2.
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1347
|
+
// 2–3. Destination model and thinking level. The same-or-pick picker's
|
|
1348
|
+
// first option re-uses the current session's values in one Enter press;
|
|
1349
|
+
// `--same` skips that dialog. On the picked-model path a scoped
|
|
1350
|
+
// `model:level` entry pins the level.
|
|
1351
|
+
const reuse = parsed.same ? "same" : await chooseSameOrPick(ctx);
|
|
1352
|
+
if (!reuse) return;
|
|
1353
|
+
let target: PickedModel | undefined;
|
|
1354
|
+
let level: ThinkingLevel | undefined;
|
|
1355
|
+
if (reuse === "same") {
|
|
1356
|
+
if (!ctx.model) {
|
|
1357
|
+
ctx.ui.notify("--same: the current session has no model to reuse", "error");
|
|
1358
|
+
return;
|
|
1359
|
+
}
|
|
1360
|
+
target = { model: ctx.model };
|
|
1361
|
+
level = ctx.thinkingLevel;
|
|
1362
|
+
} else {
|
|
1363
|
+
target = await pickTargetModel(ctx);
|
|
1364
|
+
if (!target) return;
|
|
1365
|
+
level = target.thinkingLevel ?? (await selectThinkingLevel(ctx));
|
|
1366
|
+
if (level === undefined) return;
|
|
1367
|
+
}
|
|
1324
1368
|
|
|
1325
|
-
// 4.
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1369
|
+
// 4. Steering instructions: when passed inline as `/hand-off <instructions>`
|
|
1370
|
+
// they are used as-is; only an empty steering text opens the editor.
|
|
1371
|
+
const inlineSteering = parsed.steering.trim();
|
|
1372
|
+
const steering =
|
|
1373
|
+
inlineSteering ||
|
|
1374
|
+
(await ctx.ui.editor(
|
|
1375
|
+
writer.kind === "live"
|
|
1376
|
+
? "Steering for the hand-off prompt (sent to the current agent)"
|
|
1377
|
+
: "Steering for the hand-off prompt (sent to the hand-off writer)",
|
|
1378
|
+
"",
|
|
1379
|
+
));
|
|
1332
1380
|
if (steering === undefined) return;
|
|
1333
1381
|
|
|
1334
1382
|
// 5. Write the hand-off prompt with the chosen writer.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@grrrck/pi-clear",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Pi extension that starts a fresh session with /clear while keeping your current model and thinking level, and hands conversations off between models with /hand-off",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|