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/dist/index.d.ts
CHANGED
|
@@ -662,14 +662,16 @@ interface DefaultModeConfig {
|
|
|
662
662
|
export declare function readDefaultModeConfig(agentDir: string): DefaultModeConfig;
|
|
663
663
|
/**
|
|
664
664
|
* Which model-facing tools this package registers, independent of PTC mode (which decides
|
|
665
|
-
* which registered tools are *active*).
|
|
666
|
-
* {@link readDefaultModeConfig}, beside the `defaultMode` key. ADR-0025.
|
|
665
|
+
* which registered tools are *active*).
|
|
667
666
|
*
|
|
668
|
-
*
|
|
669
|
-
*
|
|
670
|
-
*
|
|
667
|
+
* These are DETECTED values, not settings. The list is two long because detection is the only
|
|
668
|
+
* thing that produces them: `subagents` keeps the subagent face and lets pi's `codemode`
|
|
669
|
+
* orchestrate, `full` keeps the whole set. There was a third, `off`, and a `surfaceMode` key
|
|
670
|
+
* that could pin any of the three (ADR-0025); both are gone, and
|
|
671
|
+
* {@link detectSurfaceMode} is now a pure function of what pi is — see its doc for why the
|
|
672
|
+
* escape hatch the setting provided is not one this package can replace.
|
|
671
673
|
*/
|
|
672
|
-
|
|
674
|
+
declare const SURFACE_MODES: readonly ["subagents", "full"];
|
|
673
675
|
type SurfaceMode = (typeof SURFACE_MODES)[number];
|
|
674
676
|
/**
|
|
675
677
|
* Whether the pi that launched us will actually LOAD its `codemode` extension.
|
|
@@ -719,43 +721,98 @@ export declare function readCodemodeSwitch(agentDir: string, cwd: string, argv?:
|
|
|
719
721
|
* Whether `codemode` will be CALLABLE, as a third question distinct from whether pi ships the
|
|
720
722
|
* directory (ADR-0026) and whether it will load the extension (ADR-0027).
|
|
721
723
|
*
|
|
722
|
-
* - `"active"` — a loadout names it
|
|
723
|
-
*
|
|
724
|
-
*
|
|
724
|
+
* - `"active"` — a loadout names it OR pi's MCP extension will auto-enable it from `mcp.json`
|
|
725
|
+
* (ADR-0033), so the model can call it.
|
|
726
|
+
* - `"inactive"` — nothing names it and nothing auto-enables it, which on a real install is the
|
|
727
|
+
* DEFAULT: pi registers `codemode` with `defaultActive: false`
|
|
728
|
+
* (`dist/extensions/codemode/index.js:26`).
|
|
725
729
|
*
|
|
726
730
|
* `"inactive"` is what every failure of this probe on the positive side resolves to, and that is
|
|
727
731
|
* the design rather than a fallback: `subagents` is chosen only on positive evidence that the tool
|
|
728
732
|
* is callable. See ADR-0029, "The bound that makes the weaker guarantee sufficient".
|
|
729
733
|
*/
|
|
730
734
|
type CodemodeActivation = "active" | "inactive";
|
|
731
|
-
/**
|
|
732
|
-
|
|
735
|
+
/**
|
|
736
|
+
* How the answer was decided, so a test can tell a configured answer from pi's default.
|
|
737
|
+
*
|
|
738
|
+
* `"loadout"` is pi's own live tool set — the answer is read, not reconstructed, so there is no
|
|
739
|
+
* provenance left to name: whatever put `codemode` there is pi's business and not something this
|
|
740
|
+
* package can see. `"mcp"` is ADR-0033: the live loadout said `inactive` and the MCP auto-enable
|
|
741
|
+
* evidence said pi will activate `codemode` anyway, because pi's MCP extension does that from its
|
|
742
|
+
* own `session_start` handler and a read from ours can be too early to see it.
|
|
743
|
+
*/
|
|
744
|
+
type CodemodeActivationSource = "loadout" | "invalid" | "mcp";
|
|
733
745
|
/** The answer plus enough provenance to explain it in a notice. */
|
|
734
746
|
interface CodemodeActivationResolution {
|
|
735
747
|
activation: CodemodeActivation;
|
|
736
748
|
source: CodemodeActivationSource;
|
|
737
749
|
/** Set when a settings file could not be read as a JSON object; the answer still resolves. */
|
|
738
750
|
error?: string;
|
|
751
|
+
/**
|
|
752
|
+
* Set when an `mcp.json` could not be read as a JSON object (ADR-0033); that file contributed
|
|
753
|
+
* nothing to the answer, and the answer still resolves.
|
|
754
|
+
*/
|
|
755
|
+
mcpError?: string;
|
|
739
756
|
}
|
|
740
757
|
/**
|
|
741
|
-
*
|
|
742
|
-
*
|
|
758
|
+
* Everything the loadout side of this probe used to need, deleted with the probe.
|
|
759
|
+
*
|
|
760
|
+
* `PI_DEFAULT_TOOL_NAMES`, `isToolModifier`, `stringEntries`, `mergeDefaultTools` and
|
|
761
|
+
* `resolveDefaultTools` were a second implementation of pi's `defaultTools` resolution — the merge
|
|
762
|
+
* direction, the modifier grammar, the "a list of only modifiers starts from pi's four defaults"
|
|
763
|
+
* rule. It existed because the factory had to know the answer before pi would let this package ask,
|
|
764
|
+
* and reimplementing the rule was the only way to know it in advance.
|
|
765
|
+
*
|
|
766
|
+
* The answer is now read from pi instead, so there is nothing left for these to be right about. A
|
|
767
|
+
* second implementation of a rule the host owns is a defect waiting for the host to change the rule,
|
|
768
|
+
* which is how #131 happened: a project's `defaultTools` was honoured here whether or not pi would
|
|
769
|
+
* ever read it.
|
|
770
|
+
*/
|
|
771
|
+
/**
|
|
772
|
+
* The command-line reader is gone with the reconstruction it existed for.
|
|
773
|
+
*
|
|
774
|
+
* `splitCliToolList`, `PI_VALUE_CONSUMING_FLAGS`, `PI_CONDITIONALLY_CONSUMING_FLAGS`,
|
|
775
|
+
* `piPrintConsumesNext`, `CliToolFlags` and `cliToolFlags` parsed `process.argv` to work out
|
|
776
|
+
* which tools pi would activate: `--tools` as an allowlist, `--exclude-tools` as a denylist,
|
|
777
|
+
* `--no-tools` and `--no-builtin-tools` as the two ways of emptying the list, plus the value-
|
|
778
|
+
* consuming grammar those flags live in, because a value that looks like a flag must not be
|
|
779
|
+
* re-read as one.
|
|
743
780
|
*
|
|
744
|
-
*
|
|
745
|
-
*
|
|
746
|
-
*
|
|
747
|
-
*
|
|
781
|
+
* It was careful — a 294-case differential against pi's own parser found no disagreement once it
|
|
782
|
+
* was made to agree, and every divergence before that had been argued away as pointing in a safe
|
|
783
|
+
* direction. That argument is what this deletion is about rather than the code: it was wrong.
|
|
784
|
+
* Reading the command line correctly is not the same as knowing what pi will do with it, and the
|
|
785
|
+
* settings half had already shown how that goes wrong — #131 is this reader's sibling, with the
|
|
786
|
+
* same shape of mistake on the file side.
|
|
787
|
+
*
|
|
788
|
+
* The reader's replacement is one call, and it is the host's own answer rather than a second
|
|
789
|
+
* opinion on it. See {@link readCodemodeActivation}.
|
|
748
790
|
*/
|
|
749
|
-
export declare function resolveCodemodeActivation(argv: readonly string[], projectSettings: unknown, userSettings: unknown): CodemodeActivationResolution;
|
|
750
791
|
/**
|
|
751
|
-
* Whether
|
|
792
|
+
* Whether `codemode` is in pi's active tool set, as pi reports it.
|
|
793
|
+
*
|
|
794
|
+
* This is the ADR-0029 loadout mirror with the mirror taken out. It used to resolve the same
|
|
795
|
+
* question by parsing the command line and merging the two `defaultTools` files, replaying pi's
|
|
796
|
+
* precedence over them:
|
|
797
|
+
*
|
|
798
|
+
* 1. `--tools` decides the list, and it beats `--no-tools`.
|
|
799
|
+
* 2. `--exclude-tools` vetoes whichever list won, because the denylist is a `.filter` over that
|
|
800
|
+
* list rather than another source.
|
|
801
|
+
* 3. `--no-tools` and `--no-builtin-tools` with no allowlist empty the list, so `codemode` is not
|
|
802
|
+
* active whatever `defaultTools` says.
|
|
803
|
+
* 4. Otherwise `defaultTools` decides, vetoed by the denylist exactly as in (2).
|
|
752
804
|
*
|
|
753
|
-
*
|
|
754
|
-
*
|
|
755
|
-
*
|
|
756
|
-
*
|
|
805
|
+
* All four are still true, and none of them is restated here. pi has already applied them, along
|
|
806
|
+
* with the project-trust decision, by the time an extension can read its loadout at
|
|
807
|
+
* `session_start`; asking it is both shorter and correct in the case that a second implementation
|
|
808
|
+
* cannot be, which is when the two disagree about something pi changed.
|
|
809
|
+
*
|
|
810
|
+
* Absence still means `inactive`, and that is unchanged rather than defaulted: pi registers
|
|
811
|
+
* `codemode` with `defaultActive: false`, so a session that configured nothing does not get it, and
|
|
812
|
+
* delegating orchestration to a tool the model cannot call is the failure this whole probe exists
|
|
813
|
+
* to prevent.
|
|
757
814
|
*/
|
|
758
|
-
export declare function
|
|
815
|
+
export declare function resolveCodemodeActivation(activeToolNames: readonly string[]): CodemodeActivationResolution;
|
|
759
816
|
/**
|
|
760
817
|
* Whether the pi that launched us ships its own `codemode` orchestration tool.
|
|
761
818
|
*
|
|
@@ -785,80 +842,75 @@ interface CodemodePresence {
|
|
|
785
842
|
/** How the answer was reached, so a test can tell a measured yes from a failed probe. */
|
|
786
843
|
how: "found" | "not-found" | "no-entry" | "unresolvable-entry";
|
|
787
844
|
}
|
|
788
|
-
/**
|
|
789
|
-
interface
|
|
845
|
+
/** The detected surface, plus every probe result `session_start` reports on. */
|
|
846
|
+
interface DetectedSurface {
|
|
847
|
+
/** What this package registers. Decided by {@link detectedSurfaceMode}; never configured. */
|
|
790
848
|
surfaceMode: SurfaceMode;
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
/**
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
*/
|
|
798
|
-
codemode?: CodemodePresence;
|
|
799
|
-
/**
|
|
800
|
-
* Whether pi will actually load its own codemode (ADR-0027). Absent for the same reason as
|
|
801
|
-
* {@link codemode}: an explicit key short-circuits the probe, so there is nothing to report.
|
|
802
|
-
*/
|
|
803
|
-
codemodeSwitch?: CodemodeSwitchResolution;
|
|
804
|
-
/**
|
|
805
|
-
* Whether `codemode` will be in the model's tool list (ADR-0029), the third axis of the
|
|
806
|
-
* detected table. Absent for the same reason as {@link codemodeSwitch}.
|
|
807
|
-
*/
|
|
808
|
-
codemodeActivation?: CodemodeActivationResolution;
|
|
809
|
-
/**
|
|
810
|
-
* What the four-case table decided, carried even when an explicit key overrode it — that
|
|
811
|
-
* difference is exactly what {@link surfaceModeConflict} reports on.
|
|
812
|
-
*/
|
|
813
|
-
detected?: SurfaceMode;
|
|
849
|
+
/** Whether this pi ships a `codemode` at all. */
|
|
850
|
+
codemode: CodemodePresence;
|
|
851
|
+
/** Whether pi will load it (ADR-0027). */
|
|
852
|
+
codemodeSwitch: CodemodeSwitchResolution;
|
|
853
|
+
/** Whether the model will be able to call it (ADR-0029), the third axis of the table. */
|
|
854
|
+
codemodeActivation: CodemodeActivationResolution;
|
|
814
855
|
}
|
|
815
856
|
/**
|
|
816
|
-
*
|
|
857
|
+
* Decide the surface by asking the pi. A pure function of the three probes and nothing else.
|
|
858
|
+
*
|
|
859
|
+
* This used to read a `surfaceMode` key first and only fall back to the probes, and the argument
|
|
860
|
+
* for that was an escape hatch: pi has `registerTool` but no `unregisterTool`, so a surface chosen
|
|
861
|
+
* wrongly cannot be corrected once the factory has returned — a session that got the wrong answer
|
|
862
|
+
* keeps it until it restarts. That argument is real, and it is also why the hatch is gone rather
|
|
863
|
+
* than merely narrowed:
|
|
817
864
|
*
|
|
818
|
-
*
|
|
819
|
-
*
|
|
820
|
-
*
|
|
821
|
-
*
|
|
822
|
-
*
|
|
865
|
+
* - **The wrong answer is now reported rather than prevented.** `session_start` measures the live
|
|
866
|
+
* registry against all three probes and says so when they disagree (ADR-0029), which a pinned
|
|
867
|
+
* value used to suppress.
|
|
868
|
+
* - **The direction that actually hurts is not reachable by a setting anyway.** A pin can only
|
|
869
|
+
* make the surface *more* capable than detection, never less: every way the probes come back
|
|
870
|
+
* wrong (`subagents` chosen for a `codemode` that cannot run) resolves to `full`, and no value
|
|
871
|
+
* the file could hold would have produced a better outcome than the one already chosen.
|
|
872
|
+
* - **Disabling is pi's job now.** The `off` value existed because a package that cannot be
|
|
873
|
+
* switched off is a package that stays loaded forever. `pi config` turns a package's extensions
|
|
874
|
+
* off without loading them — measured, not assumed: on pi 1.1.0 a `packages` entry whose
|
|
875
|
+
* `extensions` is `[]` or `["!dist/index.js"]` does not load the extension at all, while
|
|
876
|
+
* `["+dist/index.js"]` and an absent key both do. That is a channel this package cannot offer
|
|
877
|
+
* for itself, because the switch that uses it is pi's.
|
|
823
878
|
*
|
|
824
|
-
* The `presence` and `codemodeSwitch` arguments
|
|
825
|
-
* can state the pi it is reasoning about instead of depending on the machine it runs on.
|
|
826
|
-
*
|
|
827
|
-
*
|
|
828
|
-
*
|
|
829
|
-
*
|
|
830
|
-
*
|
|
879
|
+
* The `presence` and `codemodeSwitch` arguments stay parameters rather than hidden calls, so a
|
|
880
|
+
* test can state the pi it is reasoning about instead of depending on the machine it runs on.
|
|
881
|
+
*
|
|
882
|
+
* The probes are resolved here rather than in default parameters, so every call pays for all
|
|
883
|
+
* three — the shortcut that used to exist (`a default parameter is evaluated on EVERY call`)
|
|
884
|
+
* saved real work only when a key short-circuited the probes entirely, and there is no key left.
|
|
885
|
+
* The cost, named rather than rounded: each of the two settings-reading probes reads the SAME two
|
|
886
|
+
* files, so one detection is four settings reads over two files plus the two `mcp.json` reads
|
|
887
|
+
* ADR-0033 added. The duplication is pre-existing and deliberate — each probe is copied from pi
|
|
888
|
+
* whole and kept self-contained — so the number is recorded, not optimised.
|
|
831
889
|
*/
|
|
832
|
-
export declare function
|
|
833
|
-
/**
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
path: string;
|
|
837
|
-
/** The value already in the file, or `undefined` when there was none. */
|
|
838
|
-
previous: SurfaceMode | undefined;
|
|
839
|
-
/** False when the file already said this, in which case NOTHING was written. */
|
|
840
|
-
changed: boolean;
|
|
841
|
-
} | {
|
|
842
|
-
ok: false;
|
|
890
|
+
export declare function detectSurfaceMode(agentDir: string, activeToolNames: readonly string[], presence?: CodemodePresence, codemodeSwitch?: CodemodeSwitchResolution, codemodeActivation?: CodemodeActivationResolution, cwd?: string): DetectedSurface;
|
|
891
|
+
/** A `surfaceMode` left in `ptc.json` by a release that still had the key. */
|
|
892
|
+
interface LegacySurfaceKey {
|
|
893
|
+
/** The path it was found in, or `undefined` when there was no file to look in. */
|
|
843
894
|
path: string;
|
|
844
|
-
|
|
845
|
-
|
|
895
|
+
/** The value that was there, or the JSON rendering when it was not a string. */
|
|
896
|
+
value: unknown;
|
|
897
|
+
}
|
|
846
898
|
/**
|
|
847
|
-
*
|
|
899
|
+
* Read a `surfaceMode` key that this package no longer acts on, so `session_start` can say so.
|
|
848
900
|
*
|
|
849
|
-
*
|
|
901
|
+
* The key shipped in v1.6.0 and the three values it took are gone, which means a user who set
|
|
902
|
+
* `"off"` to keep this package out of their sessions would find it back on the next upgrade with
|
|
903
|
+
* nothing to explain why. Nothing here restores the behaviour: the returned value is only ever
|
|
904
|
+
* turned into a notice that names the replacement. The alternative — honouring `off` forever as a
|
|
905
|
+
* compatibility shim — is the switch this change exists to delete, and it would leave the package
|
|
906
|
+
* carrying two ways to be disabled, one of which silently does nothing.
|
|
850
907
|
*
|
|
851
|
-
*
|
|
852
|
-
*
|
|
853
|
-
*
|
|
854
|
-
*
|
|
855
|
-
* - **Other keys survive.** `defaultMode` lives in the same file (ADR-0010), and a command that
|
|
856
|
-
* wrote `{"surfaceMode": …}` wholesale would silently reset the user's mode preference.
|
|
857
|
-
* - **An unchanged value writes nothing.** `/ptc surface full` on a session already at `full`
|
|
858
|
-
* should not touch the file's mtime, and — more to the point — should not trigger the reload
|
|
859
|
-
* that would follow, since a reload replaces every extension instance for no reason.
|
|
908
|
+
* Returns `undefined` for an absent file, an absent key, and for a file this cannot parse or that
|
|
909
|
+
* is not an object. Those last two are NOT reported here: a `ptc.json` too broken to read has no
|
|
910
|
+
* `surfaceMode` to be stale about, and the parse failure belongs to whoever owns that file
|
|
911
|
+
* (`defaultMode` still lives there, and {@link readDefaultModeConfig} is what reports it).
|
|
860
912
|
*/
|
|
861
|
-
export declare function
|
|
913
|
+
export declare function readLegacySurfaceKey(agentDir: string): LegacySurfaceKey | undefined;
|
|
862
914
|
/** Why the mode declined to turn on. Surfaced in the entry notification / debug logs. */
|
|
863
915
|
type ModeBlockReason = "not-tui" | "config-off" | "tools-unavailable" | "restricted-session";
|
|
864
916
|
/** Either the loadout to apply, or the reason the mode stayed off. */
|
|
@@ -1520,16 +1572,9 @@ export declare class TurnPools {
|
|
|
1520
1572
|
export interface PtcSubagentsOptions {
|
|
1521
1573
|
/** Use this session-scoped background runtime instead of constructing one. */
|
|
1522
1574
|
backgroundRuntime?: BackgroundTaskRuntime;
|
|
1523
|
-
/**
|
|
1524
|
-
* Test seam for ADR-0025's surface mode. When set it wins over the agent-dir `ptc.json`,
|
|
1525
|
-
* so a test never reads the developer's real settings -- and the four test files that all
|
|
1526
|
-
* build this factory through one stub would otherwise inherit whatever the machine happens
|
|
1527
|
-
* to have. Undefined in production, where the file is the only source.
|
|
1528
|
-
*/
|
|
1529
|
-
surfaceMode?: SurfaceMode;
|
|
1530
1575
|
/**
|
|
1531
1576
|
* ADR-0026 test seam: what the codemode probe found. Undefined in production, where the
|
|
1532
|
-
* probe really runs. A test that exercises the DETECTED
|
|
1577
|
+
* probe really runs. A test that exercises the DETECTED surface states the pi it
|
|
1533
1578
|
* assumes rather than inheriting whatever process.argv the test runner happens to have,
|
|
1534
1579
|
* which is how the previous version of that test passed for the wrong reason.
|
|
1535
1580
|
*/
|
|
@@ -1541,8 +1586,24 @@ export interface PtcSubagentsOptions {
|
|
|
1541
1586
|
* and that is the case this seam exists to state.
|
|
1542
1587
|
*/
|
|
1543
1588
|
codemodeSwitch?: CodemodeSwitchResolution;
|
|
1589
|
+
/**
|
|
1590
|
+
* ADR-0029 test seam: whether `codemode` will be in the model's tool list. Undefined in
|
|
1591
|
+
* production, where `readCodemodeActivation` reads pi's own active tool set and the MCP
|
|
1592
|
+
* evidence — no settings file and no `argv` on this axis any more (ADR-0035).
|
|
1593
|
+
*
|
|
1594
|
+
* This seam exists because the `surfaceMode` pin it replaced did. That pin was there to keep a
|
|
1595
|
+
* test off the developer's machine: the probe it fed read a settings file out of the developer's
|
|
1596
|
+
* own agent dir, so a test file that pinned nothing decided its own surface by however the
|
|
1597
|
+
* machine running it happened to be configured. Removing the pin without adding this would have
|
|
1598
|
+
* moved that failure back in, silently, to every stub-built factory.
|
|
1599
|
+
*
|
|
1600
|
+
* The machine-dependence is gone — the loadout is handed in rather than read off disk — but the
|
|
1601
|
+
* seam stays, because a test whose subject IS the axis needs to state an answer pi would not
|
|
1602
|
+
* produce on its own (`null` runs the real probe; see `tests/helpers/ptc.ts`).
|
|
1603
|
+
*/
|
|
1604
|
+
codemodeActivation?: CodemodeActivationResolution;
|
|
1544
1605
|
}
|
|
1545
1606
|
export default function ptcSubagents(pi: ExtensionAPI, options?: PtcSubagentsOptions): void;
|
|
1546
1607
|
//#endregion
|
|
1547
|
-
export type { Binding, BindingContext, BindingTable, CodemodePresence, CodemodeSwitch, CodemodeSwitchResolution, CodemodeSwitchSource, CreateBuiltinBindingsOptions, DefaultModeConfig, ModeBlockReason, ModeEntryDecision, ModeEntryInput, ModeHideStrategy, PersistedModeState, PtcConfig, PtcErrorKind, PtcErrorShape, PtcImage, PtcJsonValue, PtcModeState, PtcRunOutcome, PtcSurface, RunPtcProgramOptions,
|
|
1608
|
+
export type { Binding, BindingContext, BindingTable, CodemodePresence, CodemodeSwitch, CodemodeSwitchResolution, CodemodeSwitchSource, CreateBuiltinBindingsOptions, DefaultModeConfig, DetectedSurface, LegacySurfaceKey, ModeBlockReason, ModeEntryDecision, ModeEntryInput, ModeHideStrategy, PersistedModeState, PtcConfig, PtcErrorKind, PtcErrorShape, PtcImage, PtcJsonValue, PtcModeState, PtcRunOutcome, PtcSurface, RunPtcProgramOptions, TurnPoolsOptions, WorkerPoolOptions, WorkerPoolStats, WorkerPoolWorkerOptions };
|
|
1548
1609
|
//# sourceMappingURL=index.d.ts.map
|