pi-delegation-policy 0.3.0 → 0.3.2

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 CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.3.2 - 2026-08-26
6
+
7
+ ### Documentation
8
+
9
+ - Refreshed the README and wiki with the current package status, safe first-use path, panel behavior, configuration hierarchy, and privacy boundaries.
10
+
11
+ ## 0.3.1 - 2026-08-26
12
+
13
+ ### Fixed
14
+
15
+ - Matched model results to Pi's `/model` presentation: model ID first, `[provider]` last, with no more than ten visible model rows.
16
+
5
17
  ## 0.3.0 - 2026-08-26
6
18
 
7
19
  ### Added
package/README.md CHANGED
@@ -1,130 +1,55 @@
1
1
  # pi-delegation-policy
2
2
 
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.
3
+ A local Pi extension that helps the main agent decide **when delegation is worth it** and which exact models to use for the Small, Medium, Large, and optional UI Design roles. It provides guidance; it is not a subagent runner.
4
4
 
5
- > **Status:** Version 0.3.0 is available from npm.
5
+ > **Status:** Version **0.3.2** is the latest published package. The package accepts Pi `>=0.84.1`; Pi `0.84.1` is the explicitly validated baseline (newer versions are not claimed as tested).
6
6
  >
7
- > **Documentation:** Read the [documentation site](https://yivas.github.io/pi-delegation-policy/).
7
+ > **Docs:** [Read the documentation site](https://yivas.github.io/pi-delegation-policy/).
8
8
 
9
- ## What it does
9
+ ## Value and boundary
10
10
 
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
- - Stores session changes in Pi's session branch, so they survive reload, resume, and tree navigation.
14
- - Uses Pi's scoped models when configured, otherwise its available authenticated models.
15
- - Injects one policy block through Pi's public `before_agent_start` event when the active configuration is valid.
11
+ - Choose `off`, `normal`, or `aggressive` delegation intensity globally or for the current session branch.
12
+ - Configure exact provider/model references for Small, Medium, Large, and optionally UI Design.
13
+ - Keep global defaults and session-branch overrides across reload, resume, and tree navigation.
14
+ - Validate active configurations before injecting one policy block through Pi's public `before_agent_start` event.
16
15
 
17
- ## What it does not do
16
+ The extension guides the main agent. It never creates, launches, routes, supervises, or blocks subagents; changes Pi's main model or thinking; stores credentials; intercepts tools; or makes its own network requests. It has no model fallback, telemetry, project configuration, presets, or external skill loading.
18
17
 
19
- This package does not create, launch, route, supervise, or block subagents. It does not change Pi's main model or thinking level. It has no presets, project configuration, external skill loading, tool interception, model fallback, telemetry, credential storage, or network requests.
18
+ ## Install and start
20
19
 
21
- ## Install
22
-
23
- Install the package in your Pi user settings:
20
+ Install the published package in Pi's user settings, then reload Pi:
24
21
 
25
22
  ```bash
26
23
  pi install npm:pi-delegation-policy
24
+ # restart Pi, or run /reload
27
25
  ```
28
26
 
29
- It supports Pi `0.84.1`. Restart Pi or run `/reload` after installation. To install a local checkout instead, use `pi install ./pi-delegation-policy`.
27
+ 1. Open `/delegate` (or press `Alt+G` in Pi's TUI).
28
+ 2. Configure exact, authenticated Small, Medium, and Large provider/model references. UI Design is optional.
29
+ 3. Select `normal` or `aggressive`, then choose **Apply changes**.
30
+ 4. Run `/delegate status` and inspect the footer for `D:NORM` or `D:AGG`. `D:ERR` means an active required role is invalid; no policy is injected.
31
+ 5. The applied state affects the **next** agent run. An agent already running is not rewritten.
32
+
33
+ See the [end-to-end getting-started guide](https://yivas.github.io/pi-delegation-policy/getting-started/) and [configuration reference](https://yivas.github.io/pi-delegation-policy/configuration/) for details.
30
34
 
31
- ## Commands
35
+ ## Essential commands
32
36
 
33
37
  ```text
34
- /delegate Open the keyboard-first selector
35
- /delegate off Disable policy injection for this session branch
38
+ /delegate Open the editor
39
+ /delegate off Disable policy for this session branch
36
40
  /delegate normal Enable balanced delegation guidance
37
41
  /delegate aggressive Enable delegation-first guidance
38
- /delegate status Show the effective session state
39
- /delegate reset Reset this session branch to off
42
+ /delegate status Show effective session state
43
+ /delegate reset Reset this branch to off and other fields to global defaults
40
44
  ```
41
45
 
42
- `Alt+G` opens the same editor when the shortcut is available. There is no separate off shortcut; use `/delegate off` or choose `off` in the editor. Changes apply to the next agent run. An agent already running keeps the system prompt it started with.
43
-
44
- The interactive editor requires Pi's TUI mode; quick `/delegate` arguments remain available in other modes. The editor is one bounded, keyboard-first panel. It shows the effective value and the built-in, global, and session value for each setting. Model fields open a live fuzzy search over provider, model ID, and display name; long catalogs scroll within the terminal instead of extending past the screen. **Use global default** remains available while searching, and UI Design also offers **Disable for this session**.
45
-
46
- Edits stay in a draft until **Apply changes** is selected or `A` is pressed. **Save effective configuration as defaults** updates the global file without applying the session draft. **Reset draft to off** remains local until Apply. Escape returns from a field editor; closing a modified draft requires explicit discard confirmation.
47
-
48
- The footer shows `D:OFF`, `D:NORM`, `D:AGG`, or `D:ERR` without replacing Pi's own status.
49
-
50
- ## Configuration
51
-
52
- Global defaults live at:
53
-
54
- ```text
55
- ~/.pi/agent/delegation-policy.json
56
- ```
57
-
58
- They use schema version 2. The file stores optional intensity, model references, preference, and an optional UI Design model. It never stores thinking.
59
-
60
- ```json
61
- {
62
- "schemaVersion": 2,
63
- "intensity": "normal",
64
- "preference": "standard",
65
- "small": {
66
- "provider": "example-provider",
67
- "model": "example-small"
68
- },
69
- "medium": {
70
- "provider": "example-provider",
71
- "model": "example-medium"
72
- },
73
- "large": {
74
- "provider": "example-provider",
75
- "model": "example-large"
76
- },
77
- "uiDesign": {
78
- "provider": "example-provider",
79
- "model": "example-ui-design"
80
- }
81
- }
82
- ```
83
-
84
- See [`examples/global.json`](examples/global.json) and the bundled [JSON Schema](schema/delegation-policy.schema.json). The values are fictional.
85
-
86
- Schema version 1 is inactive and is not migrated automatically. Open `/delegate`, configure schema version 2, and save the effective configuration as defaults before using an active intensity.
87
-
88
- ### Global defaults and session branches
46
+ The editor is a bounded, keyboard-first panel. It shows model ID first and `[provider]` last, fuzzy-searches provider, model ID, and display name, and shows at most 10 model rows. Inheritance actions stay pinned while searching. Changes are drafts until **Apply changes**; saving effective configuration as defaults updates the global file without applying the draft, and closing a modified draft requires explicit discard.
89
47
 
90
- 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**.
48
+ ## Configuration and safety
91
49
 
92
- 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.
50
+ Global defaults are stored at `~/.pi/agent/delegation-policy.json` (schema version 2). The file stores optional intensity, preference, exact role references, and an optional UI Design reference; it never stores thinking. A valid active mode requires exact, available, in-scope, authenticated Small, Medium, and Large references. Invalid active configuration fails closed as `D:ERR` with no policy injection; `off` is always `D:OFF`.
93
51
 
94
- ### Intensity
95
-
96
- - `off` injects nothing into the next agent run. Pi rebuilds the system prompt for each run, so a policy injected into an earlier run is absent; an agent already running is not rewritten. Invalid or incomplete defaults still show `D:OFF`.
97
- - `normal` delegates substantial, separable work only when the expected benefit clearly outweighs briefing, supervision, review, and integration. It keeps borderline work with the main agent.
98
- - `aggressive` delegates substantial, separable, independently checkable work by default when it has a clear objective and acceptance criteria. A plausible benefit can be enough, but tightly coupled work or clearly prohibitive overhead stays with the main agent.
99
-
100
- The main agent keeps global strategy, coordination, integration, final review, and work whose essential context is too costly or risky to transfer in every mode.
101
-
102
- ### Model roles and preference
103
-
104
- Active modes require exact `provider` and `model` references for Small, Medium, and Large. Pi must expose each reference in the current scope or available model catalog, and its provider must be authenticated. A missing, out-of-scope, unavailable, or unauthenticated role produces `D:ERR` and injects no policy. The extension never substitutes another model or role.
105
-
106
- The policy chooses a role and thinking together from task demand, difficulty, and quantity. No single factor decides the role:
107
-
108
- - Small is habitual for bounded, planned, and verifiable execution. Difficult but well-defined work can remain Small with higher thinking.
109
- - Medium can be selected directly when the combined demands materially require planning, ambiguity reduction, broad synthesis, several-module tracing, comparison, context coordination, or difficult decisions. Small does not need to fail first.
110
- - Large is exceptional and only unblocks genuinely stuck work, such as persistent failures, severe framework conflicts, or contradictory hypotheses. Reliable prior evidence can justify it without ceremonial failed attempts.
111
- - Large quantities of repetitive, independent work favor multiple Small delegations. Agent type does not determine the model role.
112
-
113
- Preference shifts credible Small/Medium choices; a clearly better task fit overrides it:
114
-
115
- - `efficient` favors Small more strongly and uses Medium when it provides a material advantage.
116
- - `standard` reproduces the canonical policy and chooses Small on a genuine Small/Medium tie.
117
- - `intensive` normally favors Medium for non-trivial bounded work when both roles are credible, while retaining Small for clearly narrow, routine, mechanical, or especially clear Small work.
118
-
119
- All three ordinary roles remain available in every preference. The main agent chooses thinking for each delegated task from task demand, difficulty, quantity, and model capabilities. Thinking is not configured or persisted by this extension.
120
-
121
- UI Design is optional. When configured, it is limited to visual design direction, exploration, and review. It must not implement an interface, write code, or run tests. When it is off, ordinary roles handle design-related work.
122
-
123
- ## Security and privacy
124
-
125
- 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.
126
-
127
- Read [`SECURITY.md`](SECURITY.md) for reporting guidance.
52
+ The extension stores only policy settings and provider/model identifiers in local defaults and session entries. Review local configuration before sharing diagnostics, and remove credentials, prompts, personal paths, session files, and unredacted logs from reports. See the [limits and privacy reference](https://yivas.github.io/pi-delegation-policy/limits-and-privacy/) and [security policy](https://github.com/Yivas/pi-delegation-policy/blob/main/SECURITY.md).
128
53
 
129
54
  ## Development
130
55
 
@@ -138,12 +63,8 @@ npm run build
138
63
  npm run pack:check
139
64
  ```
140
65
 
141
- The tests use local mocks and make no paid model calls or network requests.
142
-
143
- ## Contributing
144
-
145
- Read [`CONTRIBUTING.md`](CONTRIBUTING.md). Contributions must preserve the boundary: this extension guides the main agent and does not become a subagent runner, tool interceptor, credential store, or telemetry client.
66
+ Tests use local mocks and do not make paid model calls or network requests. See [CONTRIBUTING.md](https://github.com/Yivas/pi-delegation-policy/blob/main/CONTRIBUTING.md) for contribution guidance.
146
67
 
147
68
  ## License
148
69
 
149
- MIT. See [`LICENSE`](LICENSE).
70
+ MIT. See [LICENSE](https://github.com/Yivas/pi-delegation-policy/blob/main/LICENSE).
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.3.0 is the current supported release.
17
+ Only the latest published version is supported. Version 0.3.2 is the current supported release.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-delegation-policy",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "private": false,
5
5
  "description": "A Pi extension for configurable delegation intensity and exact subagent role model references.",
6
6
  "type": "module",
@@ -470,22 +470,29 @@ export class DelegatePanel implements Component, Focusable {
470
470
  ),
471
471
  );
472
472
  const dividerRows = budget > pinnedLines.length + 3 ? 1 : 0;
473
- const listBudget = Math.max(0, budget - 2 - pinnedLines.length - dividerRows);
474
- const showDescriptions = listBudget >= 3;
473
+ const selectedChoice = choices[mode.selected];
474
+ const selectedName =
475
+ selectedChoice?.kind === "model" && selectedChoice.description
476
+ ? [` Model Name: ${selectedChoice.description}`]
477
+ : [];
478
+ const detailRows = selectedName.length > 0 && budget > pinnedLines.length + 6 ? 2 : 0;
479
+ const availableListRows = Math.max(
480
+ 0,
481
+ budget - 2 - pinnedLines.length - dividerRows - detailRows,
482
+ );
483
+ const listBudget = Math.min(11, availableListRows);
475
484
  const modelBlocks = models.map((choice, index) => {
476
485
  const combinedIndex = index + pinnedCount;
477
- const lines = [
478
- selectedLine(this.theme, choice.label, width, mode.selected === combinedIndex),
479
- ];
480
- if (showDescriptions && choice.description) {
481
- lines.push(truncateToWidth(this.theme.fg("muted", ` ${choice.description}`), width, ""));
482
- }
483
- return lines;
486
+ const provider = choice.kind === "model" ? choice.reference.provider : "";
487
+ const label = provider
488
+ ? `${choice.label} ${this.theme.fg("muted", `[${provider}]`)}`
489
+ : choice.label;
490
+ return [selectedLine(this.theme, label, width, mode.selected === combinedIndex)];
484
491
  });
485
492
  const modelSelected = Math.max(0, mode.selected - pinnedCount);
486
493
  const modelLines =
487
494
  listBudget > 0 && modelBlocks.length > 0
488
- ? this.renderBlockViewport(modelBlocks, modelSelected, width, listBudget)
495
+ ? this.renderBlockViewport(modelBlocks, modelSelected, width, listBudget, 10)
489
496
  : [];
490
497
  if (models.length === 0 && modelLines.length < listBudget) {
491
498
  modelLines.push(
@@ -505,6 +512,7 @@ export class DelegatePanel implements Component, Focusable {
505
512
  ...pinnedLines,
506
513
  ...(dividerRows ? [this.theme.fg("borderMuted", "─".repeat(width))] : []),
507
514
  ...modelLines,
515
+ ...(detailRows ? ["", ...selectedName.map((line) => this.theme.fg("muted", line))] : []),
508
516
  ].slice(0, budget);
509
517
  }
510
518
 
@@ -523,10 +531,11 @@ export class DelegatePanel implements Component, Focusable {
523
531
  selected: number,
524
532
  width: number,
525
533
  budget: number,
534
+ maxVisibleBlocks = Number.POSITIVE_INFINITY,
526
535
  ): string[] {
527
536
  const totalRows = blocks.reduce((sum, block) => sum + block.length, 0);
528
- const reserveIndicator = totalRows > budget ? 1 : 0;
529
- const contentBudget = Math.max(1, budget - reserveIndicator);
537
+ const reserveIndicator = totalRows > budget || blocks.length > maxVisibleBlocks ? 1 : 0;
538
+ const contentBudget = Math.max(1, Math.min(budget - reserveIndicator, maxVisibleBlocks));
530
539
  const [start, end] = visibleBlockRange(blocks, selected, contentBudget);
531
540
  const lines = blocks
532
541
  .slice(start, end)
@@ -672,7 +681,7 @@ export class DelegatePanel implements Component, Focusable {
672
681
  }
673
682
  const filtered = query
674
683
  ? fuzzyFilter(this.candidates, query, (model) =>
675
- `${model.provider}/${model.id} ${model.name ?? ""}`.trim(),
684
+ `${model.provider} ${model.provider}/${model.id} ${model.provider} ${model.id} ${model.name ?? ""}`.trim(),
676
685
  )
677
686
  : this.candidates;
678
687
  return [
@@ -680,7 +689,7 @@ export class DelegatePanel implements Component, Focusable {
680
689
  ...filtered.map<ModelChoice>((model) => ({
681
690
  kind: "model",
682
691
  key: modelKey({ provider: model.provider, model: model.id }),
683
- label: `${model.provider}/${model.id}`,
692
+ label: model.id,
684
693
  ...(model.name && model.name !== model.id ? { description: model.name } : {}),
685
694
  reference: { provider: model.provider, model: model.id },
686
695
  })),