@gotgenes/pi-subagents 14.0.1 → 15.0.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
CHANGED
|
@@ -5,6 +5,22 @@ 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.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [15.0.0](https://github.com/gotgenes/pi-packages/compare/pi-subagents-v14.0.1...pi-subagents-v15.0.0) (2026-06-09)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### ⚠ BREAKING CHANGES
|
|
12
|
+
|
|
13
|
+
* **pi-subagents:** Custom agents in .pi/agents/*.md that omit the prompt_mode frontmatter key now default to append instead of replace, so they inherit the parent system prompt (AGENTS.md / CLAUDE.md / skills). Add `prompt_mode: replace` explicitly to restore the previous standalone-prompt behavior.
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* **pi-subagents:** default custom agents to append prompt mode ([#360](https://github.com/gotgenes/pi-packages/issues/360)) ([e3a3c96](https://github.com/gotgenes/pi-packages/commit/e3a3c9623eb0448a005f436c7c8a98504ceaf6e9))
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Documentation
|
|
21
|
+
|
|
22
|
+
* **pi-subagents:** note custom agents default to append prompt mode ([#360](https://github.com/gotgenes/pi-packages/issues/360)) ([9d6038c](https://github.com/gotgenes/pi-packages/commit/9d6038c515dd1b6681bf47d9cbff090da70cf014))
|
|
23
|
+
|
|
8
24
|
## [14.0.1](https://github.com/gotgenes/pi-packages/compare/pi-subagents-v14.0.0...pi-subagents-v14.0.1) (2026-06-03)
|
|
9
25
|
|
|
10
26
|
|
package/README.md
CHANGED
|
@@ -184,7 +184,7 @@ All fields are optional — sensible defaults for everything.
|
|
|
184
184
|
| `model` | inherit parent | Model — `provider/modelId` or fuzzy name (`"haiku"`, `"sonnet"`) |
|
|
185
185
|
| `thinking` | inherit | off, minimal, low, medium, high, xhigh |
|
|
186
186
|
| `max_turns` | unlimited | Max agentic turns before graceful shutdown. `0` or omit for unlimited |
|
|
187
|
-
| `prompt_mode` | `
|
|
187
|
+
| `prompt_mode` | `append` | `replace`: body is the full system prompt (no AGENTS.md / CLAUDE.md inheritance). `append`: body appended to parent's prompt (agent acts as a "parent twin" — inherits parent's AGENTS.md / CLAUDE.md) |
|
|
188
188
|
| `inherit_context` | `false` | Fork parent conversation into agent |
|
|
189
189
|
| `run_in_background` | `false` | Run in background by default |
|
|
190
190
|
| `isolated` | `false` | No extension/MCP tools, only built-in |
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
---
|
|
2
|
+
issue: 360
|
|
3
|
+
issue_title: "fix(pi-subagents): custom agents default to replace mode instead of append"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Custom agents default to append prompt mode
|
|
7
|
+
|
|
8
|
+
## Problem Statement
|
|
9
|
+
|
|
10
|
+
Custom agents loaded from `.pi/agents/*.md` (and the global agents directory) default to `replace` prompt mode when no `prompt_mode` frontmatter key is present, while built-in agents default to `append`.
|
|
11
|
+
This asymmetry surprises users: a custom agent with no explicit `prompt_mode` silently drops the parent system prompt (AGENTS.md, skills, project conventions) and instead shows the bare replace-mode header. @jeffutter reported this in [#180 (comment)](https://github.com/gotgenes/pi-packages/issues/180#issuecomment-4644369646) — their `researcher` agent rendered `"You are a pi coding agent sub-agent."` instead of inheriting the parent prompt.
|
|
12
|
+
|
|
13
|
+
The root cause is the ternary in `src/config/custom-agents.ts` line 65:
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
promptMode: fm.prompt_mode === "append" ? "append" : "replace",
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Any value other than the literal `"append"` — including `undefined` (key omitted) — falls through to `replace`.
|
|
20
|
+
|
|
21
|
+
## Goals
|
|
22
|
+
|
|
23
|
+
- Custom agents without an explicit `prompt_mode` frontmatter key default to `append`, matching the built-in default in `agent-types.ts`.
|
|
24
|
+
- Only `prompt_mode: replace` (explicit opt-in) selects replace mode.
|
|
25
|
+
- Update tests and user-facing documentation to reflect the new default.
|
|
26
|
+
|
|
27
|
+
This is a **breaking change**: any existing `.pi/agents/*.md` that omits `prompt_mode` flips from `replace` to `append` on upgrade, so those agents begin inheriting the parent system prompt (AGENTS.md / CLAUDE.md / skills) where they previously did not.
|
|
28
|
+
The behavior change is triggered purely by upgrading, with no config edit — it warrants a `fix!:` commit and a `BREAKING CHANGE:` footer so release-please cuts a major version.
|
|
29
|
+
Users who relied on the old implicit-`replace` behavior must add `prompt_mode: replace` explicitly to restore it.
|
|
30
|
+
|
|
31
|
+
## Non-Goals
|
|
32
|
+
|
|
33
|
+
- No change to built-in agents (`default-agents.ts`): `Explore` and `Plan` keep their explicit `promptMode: "replace"`, `general-purpose` keeps `append`.
|
|
34
|
+
- No change to the prompt-assembly logic in `src/session/prompts.ts` — only the default a custom agent resolves to changes.
|
|
35
|
+
- No change to other frontmatter field defaults or parsers.
|
|
36
|
+
|
|
37
|
+
## Background
|
|
38
|
+
|
|
39
|
+
- `src/config/custom-agents.ts` — `loadFromDir` parses each `.md` file's frontmatter into an `AgentConfig`.
|
|
40
|
+
Line 65 is the only place a custom agent's `promptMode` is decided.
|
|
41
|
+
- `src/config/agent-types.ts:118` — the built-in absolute-fallback config uses `promptMode: "append"`.
|
|
42
|
+
- `src/session/prompts.ts:36` — `buildAgentPrompt` branches on `config.promptMode === "append"`; append mode threads the parent system prompt (AGENTS.md / CLAUDE.md) into the child, replace mode does not.
|
|
43
|
+
- The field-parser convention documented at the top of the parser section of `custom-agents.ts` is "omitted → default, none/empty → nothing, value → exact".
|
|
44
|
+
Today `prompt_mode` violates the spirit of "omitted → default" by mapping omitted to `replace` rather than the system default `append`.
|
|
45
|
+
This fix aligns it.
|
|
46
|
+
|
|
47
|
+
Constraint from AGENTS.md: this is the `pi-subagents` package — Biome handles formatting, the upstream vitest suite is a regression canary, and all tests must pass before publishing.
|
|
48
|
+
|
|
49
|
+
## Design Overview
|
|
50
|
+
|
|
51
|
+
Flip the ternary so `replace` requires an explicit opt-in and everything else (including omitted) defaults to `append`:
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
promptMode: fm.prompt_mode === "replace" ? "replace" : "append",
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Decision table for the resolved `promptMode`:
|
|
58
|
+
|
|
59
|
+
| `prompt_mode` frontmatter value | Before | After |
|
|
60
|
+
| ------------------------------- | ------- | ------- |
|
|
61
|
+
| omitted / `undefined` | replace | append |
|
|
62
|
+
| `replace` | replace | replace |
|
|
63
|
+
| `append` | append | append |
|
|
64
|
+
| unknown (e.g. `merge`) | replace | append |
|
|
65
|
+
|
|
66
|
+
Unknown values now resolve to `append` rather than `replace`.
|
|
67
|
+
This is the safer fallback: an append-mode agent inherits the parent prompt (a superset), so a typo degrades to "inherits everything" rather than "silently drops project context".
|
|
68
|
+
|
|
69
|
+
No type shape changes — `promptMode` remains `"replace" | "append"` (`src/types.ts`).
|
|
70
|
+
|
|
71
|
+
## Module-Level Changes
|
|
72
|
+
|
|
73
|
+
- `src/config/custom-agents.ts` (line 65) — flip the ternary to `fm.prompt_mode === "replace" ? "replace" : "append"`.
|
|
74
|
+
- `src/ui/agent-creation-wizard.ts` (line 106) — update the inline frontmatter doc comment: `Default: replace` → `Default: append` for `prompt_mode`.
|
|
75
|
+
The surrounding guidelines (lines 117–118) already describe both modes correctly and need no change.
|
|
76
|
+
- `README.md` (line 187) — change the `prompt_mode` default column from `` `replace` `` to `` `append` ``.
|
|
77
|
+
Keep the cell's behavioral description of `replace`/`append` unchanged.
|
|
78
|
+
- `test/config/custom-agents.test.ts` — update the two tests that assert the old default (see TDD Order).
|
|
79
|
+
|
|
80
|
+
No architecture-doc references to the default value were found (`docs/architecture/` describes module layout, not field defaults). `CHANGELOG.md` is owned by release-please and is not edited.
|
|
81
|
+
|
|
82
|
+
## Test Impact Analysis
|
|
83
|
+
|
|
84
|
+
This is a behavior fix, not an extraction, so no new test layers are enabled and no tests become redundant.
|
|
85
|
+
Existing tests in `test/config/custom-agents.test.ts` directly exercise the changed line and must be updated to assert the new default:
|
|
86
|
+
|
|
87
|
+
1. `"uses sensible defaults when frontmatter is empty"` — empty frontmatter currently asserts `promptMode` is `"replace"`; must become `"append"`.
|
|
88
|
+
2. `"defaults unknown prompt_mode to replace"` — feeds `prompt_mode: merge` and asserts `"replace"`; must be renamed to `"defaults unknown prompt_mode to append"` and assert `"append"`.
|
|
89
|
+
3. `"loads a basic agent with all frontmatter fields"` (explicit `prompt_mode: replace`) and `"handles prompt_mode: append"` — both pass an explicit value and stay as-is; they pin the explicit-opt-in behavior.
|
|
90
|
+
4. `"uses sensible defaults when no frontmatter at all"` (the `bare` agent) does not currently assert `promptMode` — add an assertion that it resolves to `"append"` to lock the no-frontmatter path.
|
|
91
|
+
|
|
92
|
+
## TDD Order
|
|
93
|
+
|
|
94
|
+
1. Red → Green: update default-mode tests in `test/config/custom-agents.test.ts`.
|
|
95
|
+
- Change the empty-frontmatter test to expect `promptMode` `"append"`.
|
|
96
|
+
- Rename the unknown-mode test to `"defaults unknown prompt_mode to append"` and expect `"append"`.
|
|
97
|
+
- Add a `promptMode` assertion (`"append"`) to the no-frontmatter (`bare`) test.
|
|
98
|
+
- These fail against the current line 65, then pass after the source fix.
|
|
99
|
+
- Apply the one-line fix in `src/config/custom-agents.ts` in the same cycle (the test file and source are coupled — the type checker and assertions move together).
|
|
100
|
+
- Commit (breaking — include the footer):
|
|
101
|
+
|
|
102
|
+
```text
|
|
103
|
+
fix(pi-subagents)!: default custom agents to append prompt mode (#360)
|
|
104
|
+
|
|
105
|
+
BREAKING CHANGE: Custom agents in .pi/agents/*.md that omit the
|
|
106
|
+
prompt_mode frontmatter key now default to append instead of replace,
|
|
107
|
+
so they inherit the parent system prompt (AGENTS.md / CLAUDE.md /
|
|
108
|
+
skills). Add `prompt_mode: replace` explicitly to restore the previous
|
|
109
|
+
standalone-prompt behavior.
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
2. Docs: update user-facing default documentation.
|
|
113
|
+
- `src/ui/agent-creation-wizard.ts` — `prompt_mode` `Default: replace` → `Default: append`.
|
|
114
|
+
- `README.md` — `prompt_mode` default cell → `` `append` ``.
|
|
115
|
+
- Commit: `docs(pi-subagents): note custom agents default to append prompt mode (#360)`.
|
|
116
|
+
|
|
117
|
+
(Optional: steps 1 and 2 may be combined into a single `fix!:` commit since the doc updates are part of the same behavioral correction; keeping them split keeps the source/test change isolated from prose.
|
|
118
|
+
If combined, the `BREAKING CHANGE:` footer lives on the single commit.)
|
|
119
|
+
|
|
120
|
+
## Risks and Mitigations
|
|
121
|
+
|
|
122
|
+
- Risk: existing users rely on the old implicit-`replace` behavior for custom agents that omit `prompt_mode`.
|
|
123
|
+
Mitigation: append mode is a superset (it inherits the parent prompt plus the agent body); the worst case is an agent that now sees more context than before, not less.
|
|
124
|
+
Users who genuinely want a standalone prompt can add `prompt_mode: replace` explicitly.
|
|
125
|
+
The issue frames the old behavior as a bug, and the maintainer authored it.
|
|
126
|
+
- Risk: the upstream vitest regression canary asserts the old default somewhere.
|
|
127
|
+
Mitigation: `grep` confirms the only default-asserting tests are in `test/config/custom-agents.test.ts`; run `pnpm --filter @gotgenes/pi-subagents run test` to confirm the full suite stays green.
|
|
128
|
+
|
|
129
|
+
## Open Questions
|
|
130
|
+
|
|
131
|
+
None.
|
|
132
|
+
The issue's proposed fix is unambiguous and the change surface is fully enumerated above.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
issue: 360
|
|
3
|
+
issue_title: "fix(pi-subagents): custom agents default to replace mode instead of append"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Retro: #360 — fix(pi-subagents): custom agents default to replace mode instead of append
|
|
7
|
+
|
|
8
|
+
## Stage: Planning (2026-06-09T02:42:19Z)
|
|
9
|
+
|
|
10
|
+
### Session summary
|
|
11
|
+
|
|
12
|
+
Planned the one-line fix flipping the `promptMode` ternary in `custom-agents.ts` so custom agents without an explicit `prompt_mode` default to `append` (matching the built-in default) instead of `replace`.
|
|
13
|
+
Enumerated the full change surface: the source line, two existing tests in `test/config/custom-agents.test.ts`, the wizard frontmatter doc comment, and the `README.md` defaults table.
|
|
14
|
+
|
|
15
|
+
### Observations
|
|
16
|
+
|
|
17
|
+
- The issue's proposed fix is unambiguous, so no `ask_user` round was needed.
|
|
18
|
+
- `grep` confirmed the only default-asserting tests live in `test/config/custom-agents.test.ts`; the broader upstream regression suite uses explicit `promptMode` values and is unaffected.
|
|
19
|
+
- Unknown `prompt_mode` values (e.g. `merge`) now resolve to `append` rather than `replace` — flagged as the safer fallback (inheriting a superset of context rather than silently dropping project context).
|
|
20
|
+
- Source fix and test updates are coupled into one TDD cycle because the assertions and the changed line move together; docs split into a separate `docs:` commit.
|
|
21
|
+
- **Breaking change**: flipping the default alters the runtime behavior of existing `.pi/agents/*.md` files that omit `prompt_mode` (they switch from `replace` to `append` on upgrade with no config edit).
|
|
22
|
+
The plan was corrected mid-session to use `fix!:` with a `BREAKING CHANGE:` footer so release-please cuts a major — the initial draft incorrectly used a plain `fix:`.
|
|
23
|
+
- No `docs/architecture/` references to the default value exist; `CHANGELOG.md` is release-please-owned and untouched.
|
|
24
|
+
|
|
25
|
+
## Stage: Implementation — TDD (2026-06-09T02:48:38Z)
|
|
26
|
+
|
|
27
|
+
### Session summary
|
|
28
|
+
|
|
29
|
+
Completed both TDD cycles from the plan in a single session.
|
|
30
|
+
Step 1 flipped the ternary in `src/config/custom-agents.ts` and updated three assertions in `test/config/custom-agents.test.ts` (empty-frontmatter default, no-frontmatter assertion added, unknown-mode renamed and flipped).
|
|
31
|
+
Step 2 updated the inline doc comment in `src/ui/agent-creation-wizard.ts` and the `README.md` defaults table.
|
|
32
|
+
Test count: 973 (unchanged — no new tests added, three assertions updated in-place).
|
|
33
|
+
|
|
34
|
+
### Observations
|
|
35
|
+
|
|
36
|
+
- No deviations from the plan; all three test mutations landed exactly as specified.
|
|
37
|
+
- Full suite (59 test files, 973 tests) stayed green after the source change — the planning analysis that the broader upstream regression suite uses explicit `promptMode` values was confirmed correct.
|
|
38
|
+
- `pnpm fallow dead-code` and `pnpm run check` both passed with no findings.
|
|
39
|
+
- Pre-completion reviewer verdict: **PASS** — no warnings or findings raised.
|
package/package.json
CHANGED
|
@@ -62,7 +62,7 @@ function loadFromDir(dir: string, agents: Map<string, AgentConfig>, source: "pro
|
|
|
62
62
|
thinking: str(fm.thinking) as ThinkingLevel | undefined,
|
|
63
63
|
maxTurns: nonNegativeInt(fm.max_turns),
|
|
64
64
|
systemPrompt: body.trim(),
|
|
65
|
-
promptMode: fm.prompt_mode === "
|
|
65
|
+
promptMode: fm.prompt_mode === "replace" ? "replace" : "append",
|
|
66
66
|
inheritContext: fm.inherit_context != null ? fm.inherit_context === true : undefined,
|
|
67
67
|
runInBackground: fm.run_in_background != null ? fm.run_in_background === true : undefined,
|
|
68
68
|
enabled: fm.enabled !== false, // default true; explicitly false disables
|
|
@@ -103,7 +103,7 @@ tools: <comma-separated built-in tools: read, bash, edit, write, grep, find, ls.
|
|
|
103
103
|
model: <optional model as "provider/modelId", e.g. "anthropic/claude-haiku-4-5-20251001". Omit to inherit parent model>
|
|
104
104
|
thinking: <optional thinking level: off, minimal, low, medium, high, xhigh. Omit to inherit>
|
|
105
105
|
max_turns: <optional max agentic turns. 0 or omit for unlimited (default)>
|
|
106
|
-
prompt_mode: <"replace" (body IS the full system prompt) or "append" (body is appended to default prompt). Default:
|
|
106
|
+
prompt_mode: <"replace" (body IS the full system prompt) or "append" (body is appended to default prompt). Default: append>
|
|
107
107
|
inherit_context: <true to fork parent conversation into agent so it sees chat history. Default: false>
|
|
108
108
|
run_in_background: <true to run in background by default. Default: false>
|
|
109
109
|
---
|