@bacnh85/pi-advisor 0.2.3 → 0.2.4
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 +16 -0
- package/README.md +5 -4
- package/extensions/commands/advisor.ts +1 -3
- package/extensions/index.ts +0 -5
- package/extensions/lib/config.ts +13 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.4 (2026-09-12)
|
|
4
|
+
|
|
5
|
+
### Removed
|
|
6
|
+
|
|
7
|
+
- Dead `AdvisorState.getThinking` knob (sole impl returned `undefined`; the
|
|
8
|
+
value flowed nowhere meaningful).
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- `saveModels` / `migrateLegacyAdvisorModel` no longer leave a `*.tmp-*` file
|
|
13
|
+
behind when the final rename throws (best-effort unlink, error re-thrown).
|
|
14
|
+
|
|
15
|
+
### Documentation
|
|
16
|
+
|
|
17
|
+
- README: added `/advisor watch-off` to the command list.
|
|
18
|
+
|
|
3
19
|
## 0.2.3 (2026-09-11)
|
|
4
20
|
|
|
5
21
|
- **Fix 20–30s+ TUI freeze after every settled turn**: pi core awaits
|
package/README.md
CHANGED
|
@@ -14,10 +14,10 @@ consult tool. Inspired by the advisor subsystem in
|
|
|
14
14
|
turn during the post-steer calm-down window. The severity sets the note's
|
|
15
15
|
authority wording (“nit — consider” vs “concern — address this” vs
|
|
16
16
|
“blocker — fix before continuing”).
|
|
17
|
-
- Post-steer cooldown: after a note steers,
|
|
18
|
-
|
|
19
|
-
instead of waking the agent again — bounds ping-pong.
|
|
20
|
-
steer immediately.
|
|
17
|
+
- Post-steer cooldown: after a note steers, nit notes within the next
|
|
18
|
+
`immuneTurns` settled turns are deferred (LLM-visible next turn)
|
|
19
|
+
instead of waking the agent again — bounds ping-pong. Concerns and
|
|
20
|
+
blockers always steer immediately.
|
|
21
21
|
- **Emission guard** (noise control): content-free phrases ("lgtm", "done", …)
|
|
22
22
|
are dropped, identical notes are deduped (severity escalation still passes),
|
|
23
23
|
and at most one note is delivered per review cycle.
|
|
@@ -47,6 +47,7 @@ npm install -g @bacnh85/pi-advisor
|
|
|
47
47
|
/advisor models # edit the full model chain (TUI panel; non-TUI prints it)
|
|
48
48
|
/advisor status # model chain, watch state, counters
|
|
49
49
|
/advisor on # enable watch for this session (also clears a pause)
|
|
50
|
+
/advisor watch-off # disable background watch for this session
|
|
50
51
|
/advisor off # clear the chain (disables tool + watch)
|
|
51
52
|
```
|
|
52
53
|
|
|
@@ -19,7 +19,6 @@ export function parseChainArgument(raw: string): string[] {
|
|
|
19
19
|
export interface AdvisorState {
|
|
20
20
|
getModels(): string[];
|
|
21
21
|
setModels(models: string[]): Promise<void> | void;
|
|
22
|
-
getThinking(): string | undefined;
|
|
23
22
|
getRuntime(): WatcherRuntime | undefined;
|
|
24
23
|
isWatchEnabled(): boolean;
|
|
25
24
|
setWatchEnabled(value: boolean): void;
|
|
@@ -100,7 +99,6 @@ export function registerAdvisor(pi: ExtensionAPI, state: AdvisorState): void {
|
|
|
100
99
|
const transcriptEvidence = buildEvidence(ctx, models, transcript.messages, SYSTEM);
|
|
101
100
|
const chain = models.join(" → ");
|
|
102
101
|
onUpdate?.({ content: [{ type: "text", text: `Consulting ${chain}…` }], details: { models } });
|
|
103
|
-
const reasoning = state.getThinking();
|
|
104
102
|
// Progressive display resets per attempt: a candidate that dies mid-stream
|
|
105
103
|
// must not leave its partial output above the next candidate's response.
|
|
106
104
|
let output = "";
|
|
@@ -116,7 +114,7 @@ export function registerAdvisor(pi: ExtensionAPI, state: AdvisorState): void {
|
|
|
116
114
|
if (forAttempt !== attempt) { attempt = forAttempt; output = ""; }
|
|
117
115
|
output += delta;
|
|
118
116
|
onUpdate?.({ content: [{ type: "text", text: output }], details: { models } });
|
|
119
|
-
}, signal
|
|
117
|
+
}, signal);
|
|
120
118
|
return {
|
|
121
119
|
content: [{ type: "text", text: `Advice from ${result.model}:\n${result.text}` }],
|
|
122
120
|
details: { models, served: result.model },
|
package/extensions/index.ts
CHANGED
|
@@ -94,10 +94,6 @@ export default function piAdvisor(pi: ExtensionAPI): void {
|
|
|
94
94
|
if (legacy) {
|
|
95
95
|
models = [legacy];
|
|
96
96
|
ctx.ui.notify(`Advisor model migrated from pi-plan: ${legacy}`, "info");
|
|
97
|
-
// If we migrated on top of a pi-plan that had legacyMigrated:true already,
|
|
98
|
-
// the user config may still lack migrationVersion. Backfill it idempotently
|
|
99
|
-
// so no future manual patch is needed (code writes, agent never touches
|
|
100
|
-
// the real global config directly).
|
|
101
97
|
}
|
|
102
98
|
}
|
|
103
99
|
runtime = createRuntime(config, models);
|
|
@@ -151,7 +147,6 @@ export default function piAdvisor(pi: ExtensionAPI): void {
|
|
|
151
147
|
await saveModels(models);
|
|
152
148
|
if (runtime) runtime.models = models;
|
|
153
149
|
},
|
|
154
|
-
getThinking: () => undefined,
|
|
155
150
|
getRuntime: () => runtime,
|
|
156
151
|
isWatchEnabled: () => watchEnabled,
|
|
157
152
|
setWatchEnabled: (value) => {
|
package/extensions/lib/config.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { readFile, writeFile, mkdir, rename } from "node:fs/promises";
|
|
1
|
+
import { readFile, writeFile, mkdir, rename, unlink } from "node:fs/promises";
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { CONFIG_DIR_NAME, type ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
@@ -94,7 +94,12 @@ export async function saveModels(models: string[]): Promise<void> {
|
|
|
94
94
|
const tmp = `${file}.tmp-${process.pid}`;
|
|
95
95
|
await mkdir(path.dirname(file), { recursive: true });
|
|
96
96
|
await writeFile(tmp, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
97
|
-
|
|
97
|
+
try {
|
|
98
|
+
await rename(tmp, file);
|
|
99
|
+
} catch (e) {
|
|
100
|
+
try { await unlink(tmp); } catch { /* best-effort cleanup */ }
|
|
101
|
+
throw e;
|
|
102
|
+
}
|
|
98
103
|
}
|
|
99
104
|
|
|
100
105
|
export function parseModel(value: string): { provider: string; id: string } | undefined {
|
|
@@ -130,7 +135,12 @@ export async function migrateLegacyAdvisorModel(): Promise<string | undefined> {
|
|
|
130
135
|
const tmp = `${settingsPath}.tmp-${process.pid}`;
|
|
131
136
|
await mkdir(path.dirname(settingsPath), { recursive: true });
|
|
132
137
|
await writeFile(tmp, JSON.stringify({ ...settings, [KEY]: { ...block, model: legacy, migrationVersion: MIGRATION_VERSION } }, null, 2) + "\n", "utf8");
|
|
133
|
-
|
|
138
|
+
try {
|
|
139
|
+
await rename(tmp, settingsPath);
|
|
140
|
+
} catch (e) {
|
|
141
|
+
try { await unlink(tmp); } catch { /* best-effort cleanup */ }
|
|
142
|
+
throw e;
|
|
143
|
+
}
|
|
134
144
|
return legacy;
|
|
135
145
|
} catch { return undefined; }
|
|
136
146
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bacnh85/pi-advisor",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "Pi extension for an automatic advisor: a second model that reviews each settled turn and injects severity-routed notes, plus an on-demand consult tool.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|