Merge main into personal with combined replace-mode builtin filtering - #1
Merged
Conversation
…olic#95) Strip a Pi builtin only when its paired hypa_* tool is active in the same session. Subagent allowlists that omit hypa_* keep bash/read/grep/find/ls instead of being left with only edit/write. Closes Hypabolic#93
Combine upstream Hypabolic#95 (strip a Pi builtin only when its paired hypa_* tool is active) with the fork's configurable disabledBuiltins: a builtin is removed only when it is configured as disabled AND its pair is active. Neither change subsumes the other, since hypa_read is registered in normal sessions and would otherwise still strip read. Keep the 3-arg applyReplaceModeFilter signature with the default set, so upstream call sites and tests are unaffected. Drop the duplicate ReplaceableBuiltin from index.ts in favour of the one in types.ts and constrain the replacement map to it. Keep upstream's guard that skips setActiveTools when the filter removed nothing. Merge both test suites; the fork's re-run test gains the missing hypa_grep/hypa_find/hypa_ls in its input so its assertion still exercises read survival under the pairing rule.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Operation
Merge
main(2678616, =upstream/main) intopersonal(4ff62a2, =origin/personal) on the dedicated branchmerge/main-into-personal. Merge base:782953d.main:2678616"Preserve Pi builtins in replace mode without hypa replacements (Preserve Pi builtins in replace mode without hypa replacements Hypabolic/Hypa#95)" (closes pi-hypa: HYPA_PI_MODE=replace strips built-in tools in subagent sessions, leaving only edit/write Hypabolic/Hypa#93).personal:815ce9f"Add configurable disabled built-ins to Pi replace mode",c8095d8,4ff62a2.Conflicts
4 files, 8 hunks, all tracing to one foundational semantic decision plus one small dependent one. No purely mechanical conflicts.
packages/pi-hypa/extensions/index.tspackages/pi-hypa/test/replace-mode.test.tspackages/pi-hypa/README.mddocs/guides/pi.mdpolicy.ts,types.tsandpolicy.test.tsmerged clean, so thedisabledBuiltinsconfig plumbing survived untouched.Semantic decision 1 — filter semantics
The two intents.
personalmade which builtins get stripped configurable (disabledBuiltins), motivated by keeping Pi'sreadforpi-hashline-edit-pro.mainchanged the criterion: strip a builtin only when its pairedhypa_*tool is active, so subagent/--toolsallowlists that getbash/readwithouthypa_*are not left with onlyedit/write.Key finding:
main's fix does not subsume the fork feature. The extension registers all fivehypa_*tools, so in a normal parent sessionhypa_readis active andmain's pairing rule still stripsread—pi-hashline-edit-prowould stay broken.Resolution (approved): AND-combine both conditions. A builtin is stripped only when it is in the configured
disabledBuiltinsset and its pairedhypa_*tool is active.The 3-arg signature is kept with the default set (all five), so every upstream call site and test that passes two arguments behaves exactly as
mainintended. Trade-off: the fork keeps a delta against upstream, but it is now a single additive parameter rather than a competing implementation of the same function, which should make future syncs conflict-free in this area.Also folded in:
main's localReplaceableBuiltinexport duplicated the onepersonaladded totypes.ts, soindex.tsnow imports thetypes.tsdefinition and constrainsREPLACE_MODE_BUILTIN_REPLACEMENTStoRecord<ReplaceableBuiltin, string>—tscnow enforces that the map and the union stay in sync.Semantic decision 2 —
before_agent_starthookKept
main's guard that skipssetActiveToolswhen the filter removed nothing, combined withpersonal'sdisabledBuiltinsargument. Sound because the filter only ever removes, so a length comparison cannot miss a change; it also matters more under the fork feature, sincedisabledBuiltins: []makes the filter a permanent no-op and the guard turns that into zero writes per turn.Consequent resolutions
HYPA_PI_MODErows in both docs now state both conditions in one sentence, keepingmain's fail-open wording and the fork's table-separator fixes.main's 3-column form with theReplacescolumn; prose names both conditions.disabledBuiltinsdocs gained one sentence each clarifying that listing a builtin makes it eligible for removal, not unconditionally removed.replace-mode.test.tsrebuilt as the union of both suites (21 tests). No test was deleted.One fixture change:
"replace mode filter re-runs on subsequent turns and preserves read"previously fed a list lackinghypa_grep/hypa_find/hypa_ls; under the merged semantics those builtins would survive for want of a pair. The input now uses the full parent list so the test still asserts what it was written to assert — thatreadsurvives while the rest are replaced. The assertion was strengthened, not weakened.Validation
Run locally in
packages/pi-hypa(npm):npm run build(tsc --noEmit) — clean.npm test:mcp-proxy-bridge6/6,policy17/17,replace-mode21/21,tool-call-integration3/3,tools22/22.Known unrelated failures
test/rewrite-client.test.tsfails 3 of 27:resolveBundledHypaBinary prefers native over bin.js when both existresolveHypaBinary prefers native over PATH JS entry when PATH hits a .js launcherresolveHypaBinary on Windows prefers bundled native binary over PATH .cmd shimVerified pre-existing: the same 3 fail identically on
personal(4ff62a2) and onmain(2678616) in clean worktrees. Binary-resolution behavior, untouched by this merge, and not fixed here.