pi-ptc-subagents 1.5.1 → 2.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 +145 -2
- package/README.md +58 -64
- package/dist/index.d.ts +157 -96
- package/dist/index.js +47 -49
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,9 +5,152 @@ 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
|
-
## [
|
|
8
|
+
## [2.0.0] - 2026-10-10
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **`ptc_run_code` and `ptc_workflow` reach the line where pi's `codemode` orchestrates.** A
|
|
13
|
+
session on the `subagents` surface used to hold `ptc_subagent` and the lifecycle face with no
|
|
14
|
+
program behind them: pi's `codemode` was composing tool calls, and the one capability its
|
|
15
|
+
QuickJS sandbox cannot provide — spawning a process — was unreachable, because `pi.dispatch`,
|
|
16
|
+
background tasks and the frozen six-name environment all live inside the PTC worker. Both tools
|
|
17
|
+
are now registered there at `codemode` reach, which makes them **callable from a `codemode`
|
|
18
|
+
script without being declared to the model**: `AgentSession._isDeclarable` admits `direct` and
|
|
19
|
+
`model-only` only, so the request pi sends still carries exactly one orchestrator and it is
|
|
20
|
+
pi's. Verified end to end on a real pi 1.1.0 session — a `codemode` script enumerates all six
|
|
21
|
+
`ptc_*` tools in `ALL_TOOLS` and successfully calls `await tools.ptc_run_code({ code: … })`,
|
|
22
|
+
while the payload carries only the subagent face
|
|
23
|
+
([ADR-0025](./docs/adr/0025-extension-surface-is-a-setting.md) §3 as amended).
|
|
24
|
+
|
|
25
|
+
**A pi older than 0.99.0 is unaffected.** `ToolExposure` does not exist there — `grep -r
|
|
26
|
+
exposure` over `pi-coding-agent@0.86.1`'s `dist/` returns nothing, and so does
|
|
27
|
+
`AgentSession._getCallableTools` — so the field is ignored and the tools are declared to the
|
|
28
|
+
model, which is correct: such a pi ships no `codemode`, resolves to `full` anyway, and has
|
|
29
|
+
nothing that could call a `codemode`-reach tool. Measured across 0.86.1 / 0.87.1 / 0.99.0 /
|
|
30
|
+
0.99.1 / 0.99.2 / 1.0.0 / 1.0.4 / 1.1.0.
|
|
31
|
+
|
|
32
|
+
**Naming either tool in `--tools` or `defaultTools` overrides this.** A tool named there is
|
|
33
|
+
recorded in pi's `toolsAdded`, which the prompt projection filters only against `hidden` and
|
|
34
|
+
never against `codemode` — so it is declared to the model regardless of its exposure. That is
|
|
35
|
+
a user's explicit choice and is left alone; it is recorded here because the exposure field does
|
|
36
|
+
not survive it.
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
|
|
40
|
+
- **Surface detection asks pi for the loadout instead of reconstructing it.** The third question —
|
|
41
|
+
will `codemode` be **active**, i.e. callable by the model — used to be answered by parsing
|
|
42
|
+
`--tools` / `--exclude-tools` / `--no-tools` / `--no-builtin-tools` out of `process.argv`,
|
|
43
|
+
merging `defaultTools` across the user-scope and project-scope settings files, and replaying pi's
|
|
44
|
+
precedence over the result. That is deleted. At `session_start` — the first moment pi's runtime is
|
|
45
|
+
bound — `getActiveTools()` answers directly, and pi has already applied both the command line and
|
|
46
|
+
its project-trust decision to what it returns. Registration moves to the same event, where pi
|
|
47
|
+
adds a tool from it and refreshes its own registry; the command-line reader, the `defaultTools`
|
|
48
|
+
merge, the precedence replay and the differential test that held them honest all go with it
|
|
49
|
+
([ADR-0035](./docs/adr/0035-ask-pi-for-the-loadout.md)).
|
|
50
|
+
|
|
51
|
+
**What this fixes.** A project's `defaultTools` was read off disk with no trust check, while pi
|
|
52
|
+
drops project settings for any project it has not been told to trust. An untrusted project could
|
|
53
|
+
therefore name `codemode` and put the session on the `subagents` surface — whose
|
|
54
|
+
`ptc_run_code` and `ptc_workflow` are registered at `codemode` reach, so with no `codemode`
|
|
55
|
+
running they are reachable from nowhere (#131). A trusted project that configures `codemode` that
|
|
56
|
+
way keeps the `subagents` surface, exactly as before.
|
|
57
|
+
|
|
58
|
+
**What does not change.** The MCP auto-enable evidence stays a file-side read, because pi
|
|
59
|
+
activates `codemode` from inside its own `session_start` handler and extension order is not ours
|
|
60
|
+
to choose — measured across pi 0.86.1 → 1.1.0, a read from ours is too early to see it, and the
|
|
61
|
+
existing cross-check catches it when it lands. The **codemode switch** axis also stays as it is;
|
|
62
|
+
it may also be collapsible into the live registry, but that loses the distinction between "not
|
|
63
|
+
shipped" and "not loaded", and it is a separate decision. Behaviour is otherwise unchanged on
|
|
64
|
+
every pi this package supports, verified from 0.86.1 upward under both trust decisions.
|
|
65
|
+
|
|
66
|
+
- **BREAKING: the `surfaceMode` setting is removed, and the surface is detected only.** Which
|
|
67
|
+
model-facing tools this package registers is now a pure function of what pi is — three probes
|
|
68
|
+
(does this pi ship `codemode`, will pi load it, can the model call it), with `full` as the
|
|
69
|
+
fallback for every case a probe cannot answer
|
|
70
|
+
([ADR-0034](./docs/adr/0034-surface-is-detected-not-set.md)).
|
|
71
|
+
|
|
72
|
+
**What is gone:**
|
|
73
|
+
|
|
74
|
+
- the `surfaceMode` key in `~/.pi/agent/ptc.json` (`off` / `subagents` / `full`);
|
|
75
|
+
- the `off` value — a session that wants none of this package's tools no longer has a way to say
|
|
76
|
+
so here;
|
|
77
|
+
- the `/ptc surface [off|subagents|full]` subcommand. **`/ptc off` is unaffected** — it turns PTC
|
|
78
|
+
_mode_ off, which was never the same thing as the extension surface;
|
|
79
|
+
- the `surfaceModeConflict` notice about a pinned value disagreeing with detection.
|
|
80
|
+
|
|
81
|
+
**Migrating: use pi, not this package.** Run `pi config` and disable this package's extensions
|
|
82
|
+
there — measured on pi 1.1.0 against this package's own `dist/index.js`, a `packages` entry whose
|
|
83
|
+
`extensions` is `[]` or `["!dist/index.js"]` is not loaded at all, while `["+dist/index.js"]` and
|
|
84
|
+
an omitted key are. This is strictly better than any value of a key this package reads, because
|
|
85
|
+
pi honours it **without loading the extension**: none of this package runs, rather than running
|
|
86
|
+
and then deciding to register nothing. In a project-level `.pi/settings.json` write
|
|
87
|
+
`["!dist/index.js"]` rather than `[]` — pi resolves the two scopes with two different functions
|
|
88
|
+
(`package-manager.js:1850`), where an empty project delta means "no change".
|
|
89
|
+
|
|
90
|
+
**Expect one warning on upgrade if you had the key set.** A `ptc.json` carrying `surfaceMode` is
|
|
91
|
+
reported at session start and the key is **not** honoured — deliberately, including for `"off"`,
|
|
92
|
+
which is why this package comes back after being switched off. The warning names the file, quotes
|
|
93
|
+
the value, and points at `pi config`; deleting the key silences it.
|
|
94
|
+
|
|
95
|
+
- **ADR-0025 decision 3 is amended.** `subagents` does register the programming pair now. What
|
|
96
|
+
the decision protected — the model being offered one orchestration surface, not two — is
|
|
97
|
+
unchanged and is now enforced by exposure rather than by an absent tool. `CONTEXT.md`'s
|
|
98
|
+
_orchestration surface_ and _subagent surface_ entries and the README's surface list say so
|
|
99
|
+
too.
|
|
100
|
+
|
|
101
|
+
- **The `codemode` activation probe now reads every CLI flag that can remove the tool.** It reads
|
|
102
|
+
`--exclude-tools` / `-xt` and `--no-tools` / `-nt` in addition to `--tools` / `-t`, and it applies
|
|
103
|
+
them in pi's own order: `-t` decides the list and beats `-nt`, while `-xt` vetoes whatever list
|
|
104
|
+
won. That last one was a real misreading — pi builds the active set as
|
|
105
|
+
`(tools ?? configured).filter(name => !excluded.has(name))` (`sdk.js:148`), so **exclusion beats
|
|
106
|
+
inclusion**, and `-t codemode -xt codemode` was previously read as `active`. The direction was the
|
|
107
|
+
harmful one: under `subagents`, `ptc_run_code` / `ptc_workflow` are at `codemode` reach, so an
|
|
108
|
+
orchestrator believed to be present but absent is an orchestrator nobody can call.
|
|
109
|
+
`--no-builtin-tools` is deliberately still not read: it maps to `noTools: "builtin"` and
|
|
110
|
+
`codemode` is not one of pi's built-in tools, so reading it would be a guess about a flag that
|
|
111
|
+
cannot move it.
|
|
112
|
+
|
|
113
|
+
[2.0.0]: https://github.com/a1121611810/pi-ptc-subagents/compare/v1.6.0...v2.0.0
|
|
114
|
+
|
|
115
|
+
## [1.6.0] - 2026-10-08
|
|
116
|
+
|
|
117
|
+
### Fixed
|
|
118
|
+
|
|
119
|
+
- **On pi 1.0, a session with MCP servers was offered two orchestration tools at once.** pi's MCP
|
|
120
|
+
extension activates pi's own `codemode` tool by itself — MCP tools default to `codemode`
|
|
121
|
+
exposure so that they are reachable only from scripts — and it does that with a
|
|
122
|
+
`pi.setActiveTools` call that no settings file records. This package's surface detection
|
|
123
|
+
([ADR-0025](./docs/adr/0025-extension-surface-is-a-setting.md)) asked whether `codemode` would
|
|
124
|
+
be _active_ by mirroring pi's loadout resolution alone ([ADR-0029](./docs/adr/0029-surface-follows-codemode-activation.md)),
|
|
125
|
+
so on exactly the sessions pi 1.0 is built around it answered _not active_, registered
|
|
126
|
+
`ptc_run_code` + `ptc_workflow` as well, and handed the model two ways to compose tools. Detection
|
|
127
|
+
now reads pi's MCP configuration (`<agentDir>/mcp.json`, then `<cwd>/.pi/mcp.json`) as a second
|
|
128
|
+
evidence source and unions the two, so those sessions resolve `subagents`: `codemode` for
|
|
129
|
+
orchestration, `ptc_subagent` and the task lifecycle for fan-out.
|
|
130
|
+
[ADR-0033](./docs/adr/0033-mcp-auto-enable-evidence.md) records the mirror, what it deliberately
|
|
131
|
+
does not mirror, and the one under-report path that stays open (a server registered through
|
|
132
|
+
`pi.registerMcpServer()`, which no file records — the drift notice below is what covers it).
|
|
133
|
+
|
|
134
|
+
### Added
|
|
135
|
+
|
|
136
|
+
- **A session start warning for an active `codemode` the probes did not predict.** Once per
|
|
137
|
+
session, and only on a detected surface: if nothing in `settings.json` or a readable `mcp.json`
|
|
138
|
+
said codemode would be active, the surface defaulted to `full`, and pi's real tool loadout
|
|
139
|
+
contains `codemode` anyway, the session is now told it is carrying two orchestration surfaces and
|
|
140
|
+
which setting picks one. Checked at session start and again on the first turn, because
|
|
141
|
+
pi's MCP extension may activate codemode after this package's own `session_start` runs. It is
|
|
142
|
+
`TUI`-only, like every other notice in this package.
|
|
143
|
+
- **A named report for an `mcp.json` this package could not read.** A file that is absent is
|
|
144
|
+
silent, matching pi; a file that exists and cannot be parsed or read is named at session start
|
|
145
|
+
with its path, and when both files are broken both are named in the one line.
|
|
146
|
+
|
|
147
|
+
### Changed
|
|
148
|
+
|
|
149
|
+
- **`CONTEXT.md` gains a `codemode activation` entry** defining the question surface detection asks
|
|
150
|
+
and its two evidence classes, so "is codemode active" no longer has to be reconstructed from an
|
|
151
|
+
ADR.
|
|
152
|
+
- ADR-0029 carries an amendment: its under-reporting bound still holds, but the premise it rested
|
|
153
|
+
on — that the loadout is the only way pi activates codemode — did not.
|
|
11
154
|
|
|
12
155
|
## [1.5.1] - 2026-10-08
|
|
13
156
|
|
package/README.md
CHANGED
|
@@ -225,37 +225,40 @@ the session. The mode's rationale and rejected alternatives are in [ADR-0010](./
|
|
|
225
225
|
{ "defaultMode": false }
|
|
226
226
|
```
|
|
227
227
|
|
|
228
|
-
**Choosing the surface.** `defaultMode` decides whether the session _enters_ PTC mode
|
|
229
|
-
|
|
228
|
+
**Choosing the surface.** `defaultMode` decides whether the session _enters_ PTC mode. Which
|
|
229
|
+
model-facing tools this package registers is **detected, not configured** — there is no setting for
|
|
230
|
+
it ([ADR-0034](./docs/adr/0034-surface-is-detected-not-set.md)):
|
|
230
231
|
|
|
231
|
-
```
|
|
232
|
-
/ptc surface # report the current surface and where it came from
|
|
233
|
-
/ptc surface subagents # write the key and reload so it applies now
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
```jsonc
|
|
237
|
-
// ~/.pi/agent/ptc.json
|
|
238
|
-
{ "surfaceMode": "subagents" }
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
- `off` — a stock pi session: no tool, no `/ptc` command, no briefing.
|
|
242
232
|
- `subagents` — `ptc_subagent` plus the three `ptc_task_*` tools, with pi's own `codemode`
|
|
243
|
-
doing the orchestration; warns at startup when `codemode` is not in the active tool set
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
233
|
+
doing the orchestration; warns at startup when `codemode` is not in the active tool set and
|
|
234
|
+
`ptc_run_code` is not declared to the model either (which on a pi below 0.99.0 it is, since
|
|
235
|
+
`exposure` does not exist there and the pair falls back to being model-visible).
|
|
236
|
+
`ptc_run_code` / `ptc_workflow` are registered here too, but at `codemode` reach: a `codemode`
|
|
237
|
+
script can call them, and the model is not shown them. That is what puts `pi.dispatch` and
|
|
238
|
+
background tasks underneath `codemode`, whose sandbox cannot spawn a process itself.
|
|
239
|
+
- `full` — the rest: `ptc_run_code` / `ptc_workflow` plus the three `ptc_task_*` tools. Also the
|
|
240
|
+
answer to every "the probe could not tell" case.
|
|
241
|
+
|
|
242
|
+
**To keep this package out of your sessions, use pi, not this package.** Run `pi config` and
|
|
243
|
+
disable this package's extensions there. Measured on pi 1.1.0 against this package's own
|
|
244
|
+
`dist/index.js`: a `packages` entry whose `extensions` is `[]` or `["!dist/index.js"]` is not
|
|
245
|
+
loaded at all, while `["+dist/index.js"]` and an omitted key are. pi does this **without loading
|
|
246
|
+
the extension**, which no value of a key this package reads could achieve — reading the key
|
|
247
|
+
requires having run the code that reads it.
|
|
248
|
+
|
|
249
|
+
> In the **project-level** `.pi/settings.json`, write `"extensions": ["!dist/index.js"]` rather than
|
|
250
|
+
> `"extensions": []`. The two settings files are resolved by two different functions in pi
|
|
251
|
+
> (`package-manager.js:1850`): the personal-level path reads `[]` as "load nothing", the
|
|
252
|
+
> project-level path reads it as an empty delta, which means "no change".
|
|
253
|
+
|
|
254
|
+
**If you had `surfaceMode` in `ptc.json`, it is no longer read** — including `"off"`, so upgrading
|
|
255
|
+
brings this package back. At session start you get one `warning` naming the file and pointing here.
|
|
256
|
+
Delete the key to silence it.
|
|
257
|
+
|
|
258
|
+
**The surface is detected, and it follows three questions, not one**
|
|
256
259
|
([ADR-0026](./docs/adr/0026-surface-default-is-detected.md),
|
|
257
260
|
[ADR-0027](./docs/adr/0027-codemode-switch-decides-surface.md),
|
|
258
|
-
[ADR-0029](./docs/adr/0029-surface-follows-codemode-activation.md))
|
|
261
|
+
[ADR-0029](./docs/adr/0029-surface-follows-codemode-activation.md)):
|
|
259
262
|
|
|
260
263
|
| does this pi ship `codemode`? | will pi load it? | can the model call it? | surface |
|
|
261
264
|
| ----------------------------- | ---------------------------------------------- | --------------------------------------------- | ----------- |
|
|
@@ -264,15 +267,15 @@ retyping the value you already have costs you in-flight state for nothing. Switc
|
|
|
264
267
|
| yes | no (`-builtin:codemode`, or `--no-extensions`) | — | `full` |
|
|
265
268
|
| no | — | — | `full` |
|
|
266
269
|
|
|
267
|
-
The third column is the one that decides most sessions, and it is why the
|
|
270
|
+
The third column is the one that decides most sessions, and it is why the answer is `full` on a pi
|
|
268
271
|
that has never been configured. pi ships `codemode` and loads it by default, but registers it
|
|
269
272
|
**inactive** (`defaultActive: false`) — it joins the model's tool list only when a loadout names it.
|
|
270
273
|
Handing orchestration to a tool the model cannot call is the failure this avoids, so `subagents` is
|
|
271
274
|
chosen only on positive evidence.
|
|
272
275
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
+
A probe that cannot answer falls back to `full` — the safe direction, since `subagents` as a
|
|
277
|
+
failure mode would take away the orchestration tool the session was relying on. There is no key
|
|
278
|
+
that overrides this, by design ([ADR-0034](./docs/adr/0034-surface-is-detected-not-set.md)).
|
|
276
279
|
|
|
277
280
|
> **To use the `subagents` surface, put `codemode` in your tool list.** Without that you get
|
|
278
281
|
> `ptc_run_code` / `ptc_workflow` and no startup warning, which is the correct answer for a session
|
|
@@ -284,54 +287,45 @@ on.
|
|
|
284
287
|
> ```
|
|
285
288
|
>
|
|
286
289
|
> or per launch, `pi --tools read,bash,edit,write,codemode`. A list made only of modifiers starts
|
|
287
|
-
> from pi's four defaults, so `{ "defaultTools": ["+codemode"] }` means the same thing.
|
|
288
|
-
> rather pin the surface regardless of what pi is doing, set `{ "surfaceMode": "subagents" }` —
|
|
289
|
-
> and note that pinning it does not activate `codemode`, so a pinned `subagents` on a session that
|
|
290
|
-
> never configured it still warns, by design ([ADR-0025](./docs/adr/0025-extension-surface-is-a-setting.md)
|
|
291
|
-
> decision 4).
|
|
290
|
+
> from pi's four defaults, so `{ "defaultTools": ["+codemode"] }` means the same thing.
|
|
292
291
|
|
|
293
292
|
> Turning pi's `codemode` **off** — `"extensions": ["-builtin:codemode"]`, or launching with
|
|
294
293
|
> `--no-extensions` — brings the PTC surfaces back on its own. Before ADR-0027 it did not: the
|
|
295
294
|
> detection asked only whether the extension directory exists, so a pi told not to load it still
|
|
296
295
|
> counted as an orchestrator and you got `ptc_subagent` with nothing to compose with. The switch is
|
|
297
296
|
> read from the same three places pi reads it — the command line, `<cwd>/.pi/settings.json`, and
|
|
298
|
-
> `<agentDir>/settings.json` — in the same order
|
|
299
|
-
>
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
**A detection you cannot see is the failure this design has**, so the result is reported.
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
renders, so that is an unmeasured end to end rather than a broken one. No test in this repository
|
|
317
|
-
observes a notice through a real TUI. If you are relying on the notice rather than on your own
|
|
318
|
-
`surfaceMode` key, verify it once.
|
|
297
|
+
> `<agentDir>/settings.json` — in the same order. The activation probe does **not** read the
|
|
298
|
+
> settings at all: it asks pi for its own tool loadout at session start, by which time pi has
|
|
299
|
+
> already applied the command line _and_ its project-trust decision. That matters for a project
|
|
300
|
+
> you have not approved — its `defaultTools` is not evidence of anything, because pi is not
|
|
301
|
+
> reading it either ([ADR-0035](./docs/adr/0035-ask-pi-for-the-loadout.md)).
|
|
302
|
+
|
|
303
|
+
**A detection you cannot see is the failure this design has**, so the result is reported. The
|
|
304
|
+
outcome is issued through the TUI notification channel at session start — how the probe came out
|
|
305
|
+
and which surface therefore is — but only when the probe could not answer. A pi that ships
|
|
306
|
+
`codemode`, loads it, and has it in the tool list is the expected case and says nothing. A second
|
|
307
|
+
notice is issued when the probe and pi's own tool registry disagree, which is the case the probe
|
|
308
|
+
structurally cannot see: it walks the filesystem, so under `--exclude-tools codemode` it answers
|
|
309
|
+
`present` for a tool this session does not have (and the mirror: a restructured `dist` answers
|
|
310
|
+
`not-found` for one pi plainly registers). A third notice covers ADR-0027: a settings file that
|
|
311
|
+
could not be read. What is **not** established is that either line actually paints in a real pi
|
|
312
|
+
TUI: a pty capture at review time showed neither the notice nor a control marker, and a TUI quits
|
|
313
|
+
on stdin EOF before a toast renders, so that is an unmeasured end to end rather than a broken one.
|
|
314
|
+
No test in this repository observes a notice through a real TUI.
|
|
319
315
|
|
|
320
316
|
**On a `--print` session, none of it prints.** `ui.notify` is the TUI channel; measured across
|
|
321
317
|
three `--print` runs that each emit one of these notices, stdout and stderr received **0 bytes**
|
|
322
318
|
each. That makes this page the only channel on which a `--print` user learns why they got the
|
|
323
|
-
surface they got
|
|
324
|
-
one line of JSON: set `surfaceMode` yourself and the detection no longer matters.
|
|
319
|
+
surface they got.
|
|
325
320
|
|
|
326
321
|
**Where it does not run.** Print / JSON / RPC sessions are left exactly as launched, and so is a
|
|
327
322
|
session started with an explicit tool restriction (`--tools`, `--exclude-tools`,
|
|
328
323
|
`--no-builtin-tools`, `--no-extensions`) — the extension does not override what you asked for.
|
|
329
324
|
`--no-extensions` does, however, change the **detected surface**: pi's own `codemode` is a built-in
|
|
330
|
-
extension, so turning extensions off means it will not load, and ADR-0027's table resolves
|
|
331
|
-
|
|
332
|
-
nothing to compose with. If
|
|
333
|
-
|
|
334
|
-
tells you.
|
|
325
|
+
extension, so turning extensions off means it will not load, and ADR-0027's table resolves to
|
|
326
|
+
`full` — you keep `ptc_run_code` / `ptc_workflow` rather than a `ptc_subagent` with
|
|
327
|
+
nothing to compose with. If another extension changes the tool set while the mode is on, the mode
|
|
328
|
+
yields and tells you.
|
|
335
329
|
|
|
336
330
|
**The important consequence:** in a TUI session, bindings come from the loadout recorded _before_
|
|
337
331
|
the mode narrowed it. That is what keeps `tools.read(…)` working — and it is why a `--tools`
|