Skip to content

Merge main into personal with combined replace-mode builtin filtering - #1

Merged
pfurini merged 2 commits into
personalfrom
merge/main-into-personal
Aug 27, 2026
Merged

Merge main into personal with combined replace-mode builtin filtering#1
pfurini merged 2 commits into
personalfrom
merge/main-into-personal

Conversation

@pfurini

@pfurini pfurini commented Aug 27, 2026

Copy link
Copy Markdown
Owner

Operation

Merge main (2678616, = upstream/main) into personal (4ff62a2, = origin/personal) on the dedicated branch merge/main-into-personal. Merge base: 782953d.

Conflicts

4 files, 8 hunks, all tracing to one foundational semantic decision plus one small dependent one. No purely mechanical conflicts.

File Hunks
packages/pi-hypa/extensions/index.ts 2
packages/pi-hypa/test/replace-mode.test.ts 3
packages/pi-hypa/README.md 2
docs/guides/pi.md 1

policy.ts, types.ts and policy.test.ts merged clean, so the disabledBuiltins config plumbing survived untouched.

Semantic decision 1 — filter semantics

The two intents. personal made which builtins get stripped configurable (disabledBuiltins), motivated by keeping Pi's read for pi-hashline-edit-pro. main changed the criterion: strip a builtin only when its paired hypa_* tool is active, so subagent/--tools allowlists that get bash/read without hypa_* are not left with only edit/write.

Key finding: main's fix does not subsume the fork feature. The extension registers all five hypa_* tools, so in a normal parent session hypa_read is active and main's pairing rule still strips readpi-hashline-edit-pro would stay broken.

Resolution (approved): AND-combine both conditions. A builtin is stripped only when it is in the configured disabledBuiltins set and its paired hypa_* 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 main intended. 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 local ReplaceableBuiltin export duplicated the one personal added to types.ts, so index.ts now imports the types.ts definition and constrains REPLACE_MODE_BUILTIN_REPLACEMENTS to Record<ReplaceableBuiltin, string>tsc now enforces that the map and the union stay in sync.

Semantic decision 2 — before_agent_start hook

Kept main's guard that skips setActiveTools when the filter removed nothing, combined with personal's disabledBuiltins argument. Sound because the filter only ever removes, so a length comparison cannot miss a change; it also matters more under the fork feature, since disabledBuiltins: [] makes the filter a permanent no-op and the guard turns that into zero writes per turn.

Consequent resolutions

  • HYPA_PI_MODE rows in both docs now state both conditions in one sentence, keeping main's fail-open wording and the fork's table-separator fixes.
  • README tool table uses main's 3-column form with the Replaces column; prose names both conditions.
  • The fork's disabledBuiltins docs gained one sentence each clarifying that listing a builtin makes it eligible for removal, not unconditionally removed.
  • replace-mode.test.ts rebuilt 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 lacking hypa_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 — that read survives 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-bridge 6/6, policy 17/17, replace-mode 21/21, tool-call-integration 3/3, tools 22/22.

Known unrelated failures

test/rewrite-client.test.ts fails 3 of 27:

  • resolveBundledHypaBinary prefers native over bin.js when both exist
  • resolveHypaBinary prefers native over PATH JS entry when PATH hits a .js launcher
  • resolveHypaBinary on Windows prefers bundled native binary over PATH .cmd shim

Verified pre-existing: the same 3 fail identically on personal (4ff62a2) and on main (2678616) in clean worktrees. Binary-resolution behavior, untouched by this merge, and not fixed here.

matt-gribben and others added 2 commits August 13, 2026 11:15
…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.
@pfurini pfurini added the enhancement New feature or request label Aug 27, 2026
@pfurini
pfurini merged commit 2725657 into personal Aug 27, 2026
@pfurini
pfurini deleted the merge/main-into-personal branch August 27, 2026 21:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pi-hypa: HYPA_PI_MODE=replace strips built-in tools in subagent sessions, leaving only edit/write

2 participants