pi-delegation-policy 0.1.2 → 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 +11 -0
- package/README.md +9 -8
- package/SECURITY.md +1 -1
- package/examples/global.json +1 -0
- package/package.json +1 -1
- package/schema/delegation-policy.schema.json +1 -0
- package/src/config.ts +16 -5
- package/src/index.ts +10 -5
- package/src/types.ts +4 -3
- package/src/ui.ts +9 -5
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.2.0 - 2026-08-26
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added optional global intensity with session-branch overrides and a built-in `off` fallback.
|
|
10
|
+
- Added **Use global default** to the intensity selector.
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- Replaced the terminal-ambiguous `Ctrl+Shift+D` shortcut with `Ctrl+Alt+D`.
|
|
15
|
+
|
|
5
16
|
## 0.1.2 - 2026-08-26
|
|
6
17
|
|
|
7
18
|
### Fixed
|
package/README.md
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
A local Pi extension that lets you choose delegation intensity and exact model references for Small, Medium, Large, and an optional UI Design role. It guides the main agent; it does not run, route, or enforce delegated work.
|
|
4
4
|
|
|
5
|
-
> **Status:** Version 0.
|
|
5
|
+
> **Status:** Version 0.2.0 is available from npm.
|
|
6
6
|
>
|
|
7
7
|
> **Documentation:** Read the [documentation site](https://yivas.github.io/pi-delegation-policy/).
|
|
8
8
|
|
|
9
9
|
## What it does
|
|
10
10
|
|
|
11
|
-
- Sets delegation intensity to `off`, `normal`, or `aggressive` for the current session branch.
|
|
12
|
-
- Keeps global defaults for model references, preference, and the optional UI Design role.
|
|
11
|
+
- Sets delegation intensity to `off`, `normal`, or `aggressive` globally or for the current session branch.
|
|
12
|
+
- Keeps global defaults for intensity, model references, preference, and the optional UI Design role.
|
|
13
13
|
- Stores session changes in Pi's session branch, so they survive reload, resume, and tree navigation.
|
|
14
14
|
- Uses Pi's scoped models when configured, otherwise its available authenticated models.
|
|
15
15
|
- Injects one policy block through Pi's public `before_agent_start` event when the active configuration is valid.
|
|
@@ -39,7 +39,7 @@ It supports Pi `0.84.1`. Restart Pi or run `/reload` after installation. To inst
|
|
|
39
39
|
/delegate reset Reset this session branch to off
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
-
`Ctrl+
|
|
42
|
+
`Ctrl+Alt+D` opens the selector when the shortcut is available. There is no separate off shortcut; use `/delegate off` or choose `off` in the selector. Changes apply to the next agent run. An agent already running keeps the system prompt it started with.
|
|
43
43
|
|
|
44
44
|
The footer shows `D:OFF`, `D:NORM`, `D:AGG`, or `D:ERR` without replacing Pi's own status.
|
|
45
45
|
|
|
@@ -51,11 +51,12 @@ Global defaults live at:
|
|
|
51
51
|
~/.pi/agent/delegation-policy.json
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
They use schema version 2. The file stores model references, preference, and an optional UI Design model. It never stores
|
|
54
|
+
They use schema version 2. The file stores optional intensity, model references, preference, and an optional UI Design model. It never stores thinking.
|
|
55
55
|
|
|
56
56
|
```json
|
|
57
57
|
{
|
|
58
58
|
"schemaVersion": 2,
|
|
59
|
+
"intensity": "normal",
|
|
59
60
|
"preference": "standard",
|
|
60
61
|
"small": {
|
|
61
62
|
"provider": "example-provider",
|
|
@@ -82,9 +83,9 @@ Schema version 1 is inactive and is not migrated automatically. Open `/delegate`
|
|
|
82
83
|
|
|
83
84
|
### Global defaults and session branches
|
|
84
85
|
|
|
85
|
-
A
|
|
86
|
+
A session branch inherits global intensity, model references, preference, and UI Design until it records matching overrides. If global intensity is absent, the built-in default is `off`. A fork restores the latest valid delegation entry in its active history. The intensity selector can return a branch to **Use global default**.
|
|
86
87
|
|
|
87
|
-
`/delegate reset` writes a
|
|
88
|
+
Selecting **Save effective configuration as defaults** copies the complete effective configuration, including intensity, to the global file. `/delegate reset` remains an explicit safety action: it writes a branch state with `off` and returns every other field to its global default.
|
|
88
89
|
|
|
89
90
|
### Intensity
|
|
90
91
|
|
|
@@ -117,7 +118,7 @@ UI Design is optional. When configured, it is limited to visual design direction
|
|
|
117
118
|
|
|
118
119
|
## Security and privacy
|
|
119
120
|
|
|
120
|
-
The extension stores
|
|
121
|
+
The extension stores intensity, preference, and provider/model identifiers in local configuration and session entries. It does not store credentials, send telemetry, or make network requests. Review configuration before using it and remove credentials, prompts, personal paths, session files, and unredacted logs from reports.
|
|
121
122
|
|
|
122
123
|
Read [`SECURITY.md`](SECURITY.md) for reporting guidance.
|
|
123
124
|
|
package/SECURITY.md
CHANGED
|
@@ -14,4 +14,4 @@ Include the affected version or commit, operating system, Pi version, reproducti
|
|
|
14
14
|
|
|
15
15
|
## Supported versions
|
|
16
16
|
|
|
17
|
-
Only the latest published version is supported. Version 0.
|
|
17
|
+
Only the latest published version is supported. Version 0.2.0 is the current supported release.
|
package/examples/global.json
CHANGED
package/package.json
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
"required": ["schemaVersion"],
|
|
7
7
|
"properties": {
|
|
8
8
|
"schemaVersion": { "const": 2 },
|
|
9
|
+
"intensity": { "enum": ["off", "normal", "aggressive"] },
|
|
9
10
|
"preference": { "enum": ["efficient", "standard", "intensive"] },
|
|
10
11
|
"small": { "$ref": "#/$defs/modelRef" },
|
|
11
12
|
"medium": { "$ref": "#/$defs/modelRef" },
|
package/src/config.ts
CHANGED
|
@@ -67,8 +67,17 @@ function copyModelRef(value: ModelRef | undefined): ModelRef | undefined {
|
|
|
67
67
|
export function parseConfig(value: unknown): GlobalDefaults | undefined {
|
|
68
68
|
if (
|
|
69
69
|
!isRecord(value) ||
|
|
70
|
-
!hasOnlyKeys(value, [
|
|
70
|
+
!hasOnlyKeys(value, [
|
|
71
|
+
"schemaVersion",
|
|
72
|
+
"intensity",
|
|
73
|
+
"preference",
|
|
74
|
+
"small",
|
|
75
|
+
"medium",
|
|
76
|
+
"large",
|
|
77
|
+
"uiDesign",
|
|
78
|
+
]) ||
|
|
71
79
|
value.schemaVersion !== 2 ||
|
|
80
|
+
(value.intensity !== undefined && !isIntensity(value.intensity)) ||
|
|
72
81
|
(value.preference !== undefined && !isPreference(value.preference))
|
|
73
82
|
)
|
|
74
83
|
return undefined;
|
|
@@ -88,6 +97,7 @@ export function parseConfig(value: unknown): GlobalDefaults | undefined {
|
|
|
88
97
|
|
|
89
98
|
return {
|
|
90
99
|
schemaVersion: 2,
|
|
100
|
+
...(value.intensity ? { intensity: value.intensity } : {}),
|
|
91
101
|
...(value.preference ? { preference: value.preference } : {}),
|
|
92
102
|
...(small ? { small } : {}),
|
|
93
103
|
...(medium ? { medium } : {}),
|
|
@@ -109,7 +119,7 @@ export function parseSessionState(value: unknown): SessionDelegateState | undefi
|
|
|
109
119
|
"uiDesign",
|
|
110
120
|
]) ||
|
|
111
121
|
value.schemaVersion !== 2 ||
|
|
112
|
-
!isIntensity(value.intensity) ||
|
|
122
|
+
(value.intensity !== undefined && !isIntensity(value.intensity)) ||
|
|
113
123
|
(value.preference !== undefined && !isPreference(value.preference))
|
|
114
124
|
)
|
|
115
125
|
return undefined;
|
|
@@ -132,7 +142,7 @@ export function parseSessionState(value: unknown): SessionDelegateState | undefi
|
|
|
132
142
|
|
|
133
143
|
return {
|
|
134
144
|
schemaVersion: 2,
|
|
135
|
-
intensity: value.intensity,
|
|
145
|
+
...(value.intensity ? { intensity: value.intensity } : {}),
|
|
136
146
|
...(value.preference ? { preference: value.preference } : {}),
|
|
137
147
|
...(small ? { small } : {}),
|
|
138
148
|
...(medium ? { medium } : {}),
|
|
@@ -218,14 +228,14 @@ export function resolveDelegateState(
|
|
|
218
228
|
: copyModelRef(session.uiDesign);
|
|
219
229
|
|
|
220
230
|
return {
|
|
221
|
-
intensity: session.intensity,
|
|
231
|
+
intensity: session.intensity ?? defaults.intensity ?? "off",
|
|
222
232
|
preference: session.preference ?? defaults.preference ?? "standard",
|
|
223
233
|
small: copyModelRef(session.small ?? defaults.small),
|
|
224
234
|
medium: copyModelRef(session.medium ?? defaults.medium),
|
|
225
235
|
large: copyModelRef(session.large ?? defaults.large),
|
|
226
236
|
...(uiDesign ? { uiDesign } : {}),
|
|
227
237
|
source: {
|
|
228
|
-
intensity:
|
|
238
|
+
intensity: sourceFor(session.intensity, defaults.intensity),
|
|
229
239
|
preference: sourceFor(session.preference, defaults.preference),
|
|
230
240
|
small: sourceFor(session.small, defaults.small),
|
|
231
241
|
medium: sourceFor(session.medium, defaults.medium),
|
|
@@ -238,6 +248,7 @@ export function resolveDelegateState(
|
|
|
238
248
|
export function defaultsFromEffectiveState(state: EffectiveDelegateState): GlobalDefaults {
|
|
239
249
|
return {
|
|
240
250
|
schemaVersion: 2,
|
|
251
|
+
intensity: state.intensity,
|
|
241
252
|
preference: state.preference,
|
|
242
253
|
...(state.small ? { small: { ...state.small } } : {}),
|
|
243
254
|
...(state.medium ? { medium: { ...state.medium } } : {}),
|
package/src/index.ts
CHANGED
|
@@ -49,14 +49,19 @@ function updateStatus(ctx: ExtensionContext, state: RuntimeState): void {
|
|
|
49
49
|
ctx.ui.setStatus(STATUS_KEY, ctx.ui.theme.fg("dim", statusLabel(state)));
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
async function openEditor(pi: ExtensionAPI, ctx: ExtensionContext): Promise<void> {
|
|
53
|
+
await openDelegateEditor(ctx, pi);
|
|
54
|
+
updateStatus(ctx, await refresh(ctx));
|
|
55
|
+
}
|
|
56
|
+
|
|
52
57
|
function configuredLabel(value: unknown): string {
|
|
53
58
|
return value ? "configured" : "unset";
|
|
54
59
|
}
|
|
55
60
|
|
|
56
|
-
function statusText(state: RuntimeState): string {
|
|
61
|
+
export function statusText(state: RuntimeState): string {
|
|
57
62
|
const { effective } = state;
|
|
58
63
|
const details = [
|
|
59
|
-
`${statusLabel(state)} intensity=${effective.intensity}`,
|
|
64
|
+
`${statusLabel(state)} intensity=${effective.intensity} (${effective.source.intensity})`,
|
|
60
65
|
`preference=${effective.preference} (${effective.source.preference})`,
|
|
61
66
|
`small=${configuredLabel(effective.small)} (${effective.source.small})`,
|
|
62
67
|
`medium=${configuredLabel(effective.medium)} (${effective.source.medium})`,
|
|
@@ -99,7 +104,7 @@ export default function piDelegationPolicy(pi: ExtensionAPI): void {
|
|
|
99
104
|
handler: async (args, ctx) => {
|
|
100
105
|
const action = parseCommand(args);
|
|
101
106
|
if (action.kind === "open") {
|
|
102
|
-
await
|
|
107
|
+
await openEditor(pi, ctx);
|
|
103
108
|
return;
|
|
104
109
|
}
|
|
105
110
|
if (action.kind === "status") {
|
|
@@ -120,9 +125,9 @@ export default function piDelegationPolicy(pi: ExtensionAPI): void {
|
|
|
120
125
|
},
|
|
121
126
|
});
|
|
122
127
|
|
|
123
|
-
pi.registerShortcut("ctrl+
|
|
128
|
+
pi.registerShortcut("ctrl+alt+d", {
|
|
124
129
|
description: "Open delegation policy",
|
|
125
|
-
handler: async (ctx) =>
|
|
130
|
+
handler: async (ctx) => openEditor(pi, ctx),
|
|
126
131
|
});
|
|
127
132
|
|
|
128
133
|
pi.on("session_start", async (_event, ctx) => {
|
package/src/types.ts
CHANGED
|
@@ -24,6 +24,7 @@ export type ModelRef = {
|
|
|
24
24
|
|
|
25
25
|
export type GlobalDefaults = {
|
|
26
26
|
schemaVersion: 2;
|
|
27
|
+
intensity?: Intensity;
|
|
27
28
|
preference?: Preference;
|
|
28
29
|
small?: ModelRef;
|
|
29
30
|
medium?: ModelRef;
|
|
@@ -33,7 +34,7 @@ export type GlobalDefaults = {
|
|
|
33
34
|
|
|
34
35
|
export type SessionDelegateState = {
|
|
35
36
|
schemaVersion: 2;
|
|
36
|
-
intensity
|
|
37
|
+
intensity?: Intensity;
|
|
37
38
|
preference?: Preference;
|
|
38
39
|
small?: ModelRef;
|
|
39
40
|
medium?: ModelRef;
|
|
@@ -52,7 +53,7 @@ export type EffectiveDelegateState = {
|
|
|
52
53
|
large?: ModelRef;
|
|
53
54
|
uiDesign?: ModelRef;
|
|
54
55
|
source: {
|
|
55
|
-
intensity:
|
|
56
|
+
intensity: ValueSource;
|
|
56
57
|
preference: ValueSource;
|
|
57
58
|
small: ValueSource;
|
|
58
59
|
medium: ValueSource;
|
|
@@ -73,5 +74,5 @@ export function emptyGlobalDefaults(): GlobalDefaults {
|
|
|
73
74
|
}
|
|
74
75
|
|
|
75
76
|
export function emptySessionState(): SessionDelegateState {
|
|
76
|
-
return { schemaVersion: 2
|
|
77
|
+
return { schemaVersion: 2 };
|
|
77
78
|
}
|
package/src/ui.ts
CHANGED
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
type RuntimeState,
|
|
14
14
|
} from "./runtime.ts";
|
|
15
15
|
import {
|
|
16
|
-
emptySessionState,
|
|
17
16
|
INTENSITIES,
|
|
18
17
|
MODEL_ROLES,
|
|
19
18
|
PREFERENCES,
|
|
@@ -109,8 +108,13 @@ async function selectUiDesign(ctx: ExtensionContext, draft: SessionDelegateState
|
|
|
109
108
|
}
|
|
110
109
|
|
|
111
110
|
async function selectIntensity(ctx: ExtensionContext, draft: SessionDelegateState): Promise<void> {
|
|
112
|
-
const selected = await selectOrCancel(ctx, "Delegation intensity", [
|
|
113
|
-
|
|
111
|
+
const selected = await selectOrCancel(ctx, "Delegation intensity", [
|
|
112
|
+
USE_GLOBAL_DEFAULT,
|
|
113
|
+
...INTENSITIES,
|
|
114
|
+
]);
|
|
115
|
+
if (!selected) return;
|
|
116
|
+
if (selected === USE_GLOBAL_DEFAULT) delete draft.intensity;
|
|
117
|
+
else draft.intensity = selected as Intensity;
|
|
114
118
|
}
|
|
115
119
|
|
|
116
120
|
async function selectPreference(ctx: ExtensionContext, draft: SessionDelegateState): Promise<void> {
|
|
@@ -194,7 +198,7 @@ export async function openDelegateEditor(ctx: ExtensionContext, pi: ExtensionAPI
|
|
|
194
198
|
await writeConfig(getGlobalConfigPath(), defaults);
|
|
195
199
|
state.global = defaults;
|
|
196
200
|
state.diagnostics = [];
|
|
197
|
-
ctx.ui.notify("Saved effective
|
|
201
|
+
ctx.ui.notify("Saved effective delegation settings as global defaults.", "info");
|
|
198
202
|
} catch {
|
|
199
203
|
ctx.ui.notify(
|
|
200
204
|
"Could not save global defaults. Session settings were not changed.",
|
|
@@ -203,7 +207,7 @@ export async function openDelegateEditor(ctx: ExtensionContext, pi: ExtensionAPI
|
|
|
203
207
|
}
|
|
204
208
|
}
|
|
205
209
|
if (selected === RESET_SESSION) {
|
|
206
|
-
draft =
|
|
210
|
+
draft = { schemaVersion: 2, intensity: "off" };
|
|
207
211
|
}
|
|
208
212
|
}
|
|
209
213
|
}
|