Skip to content

fix(pi): use pi list --approve in e2e roundtrip for pi ≥0.80 project trust#491

Merged
NiveditJain merged 3 commits into
mainfrom
fix/pi-list-approve-pi080
Jul 13, 2026
Merged

fix(pi): use pi list --approve in e2e roundtrip for pi ≥0.80 project trust#491
NiveditJain merged 3 commits into
mainfrom
fix/pi-list-approve-pi080

Conversation

@chhhee10

@chhhee10 chhhee10 commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

What

The live Pi e2e roundtrip tests installed to --scope project, then ran a bare
pi list to assert the package showed up (install test) and disappeared
(uninstall test).

pi-coding-agent ≥0.80 no longer trusts a project-local .pi/settings.json
by default
pi list needs --approve to opt into reading project
packages. Without it, pi list prints "No packages installed."
unconditionally, which:

  • failed the install roundtrip — the package we just wrote was never listed, and
  • passed the uninstall roundtrip vacuously — the negative assertion was
    true for the wrong reason.

Fix

Pass --approve to pi list in both the install and uninstall roundtrips so
Pi reads the project-local settings we wrote.

Why CI stayed green

These tests are gated behind piIsAvailable (describePi), so they only run
where the real pi binary is installed. GitHub CI has no pi, so the failure
was invisible there — only pi-equipped reviewers hit it.

Changes

  • __tests__/e2e/hooks/pi-integration.e2e.test.tspi listpi list --approve in both roundtrips, with explaining comments.
  • CLAUDE.md — note the pi ≥0.80 project-trust model.
  • CHANGELOG.md — entry under 0.0.13-beta.3.

Test

Runs only where pi is installed; verified locally against pi-coding-agent ≥0.80.

Summary by CodeRabbit

  • Bug Fixes

    • Fixed live Pi pi list install/uninstall end-to-end roundtrips so project-local packages are correctly recognized on newer Pi versions by running pi list --approve when Pi is available.
  • Documentation

    • Documented Pi v0.80.3+ behavior: project-local .pi/settings.json isn’t trusted by default, and pi list requires --approve to display project-scoped packages.
    • Updated the expected pi list workflow accordingly.

…t trust

pi-coding-agent ≥0.80 no longer trusts project-local .pi/settings.json by
default; `pi list` needs --approve to include project packages. The live
roundtrip tests installed --scope project then ran bare `pi list`, so pi
reported "No packages installed." — failing the install roundtrip and making
the uninstall roundtrip pass vacuously. Pass --approve in both. Only runs
where pi is installed (piIsAvailable gate), which is why GitHub CI stayed
green while pi-equipped reviewers saw the failure.

Docs: note the pi ≥0.80 project-trust model in CLAUDE.md. Changelog entry
added under a new 0.0.13-beta.3 section (PR number TBD — set on PR open).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@chhhee10 chhhee10 added the bug Something isn't working label Jul 13, 2026
@chhhee10 chhhee10 self-assigned this Jul 13, 2026
@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

An error occurred during the review process. Please try again later.

📝 Walkthrough

Walkthrough

Pi integration roundtrip tests now invoke pi list --approve to inspect project-local packages. Documentation and the changelog describe Pi’s trust behavior and the corresponding test fix.

Changes

Pi project package approval

Layer / File(s) Summary
Approve project-local packages
__tests__/e2e/hooks/pi-integration.e2e.test.ts, CLAUDE.md, CHANGELOG.md
Live install and uninstall assertions use pi list --approve; documentation and the changelog describe the project-local trust requirement.

Estimated code review effort: 2 (Simple) | ~10 minutes

Poem

A rabbit found packages tucked out of sight,
And whispered, “Approve them to make things right.”
The Pi list now sees each installed little thing,
Then notices absence when uninstalling.
Tests hop forward with a cheerful spring!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main fix: using pi list --approve for Pi >=0.80 project trust in e2e roundtrips.
Description check ✅ Passed The description is substantive and on-topic, covering the bug, fix, rationale, changes, and test context.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

__tests__/e2e/hooks/pi-integration.e2e.test.ts

ESLint skipped: missing config or dependency (missing-dependency). The ESLint configuration references a package that is not available in the sandbox.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@hermes-exosphere

Copy link
Copy Markdown
Contributor

🔍 Automated code review started — analyzing [{"additions":5,"deletions":0,"path":"CHANGELOG.md"},{"additions":9,"deletions":0,"path":"CLAUDE.md"},{"additions":9,"deletions":3,"path":"tests/e2e/hooks/pi-integration.e2e.test.ts"}] files, +23/-3...

⏱️ This may take a few minutes. Results will be posted here when complete.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CHANGELOG.md`:
- Around line 3-6: Update the 0.0.13-beta.3 changelog entry to replace the
placeholder “#TBD” with the actual pull request number, preserving the existing
fix description and formatting.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 43be32a2-d88e-42fb-b649-308abc852212

📥 Commits

Reviewing files that changed from the base of the PR and between 83229a7 and aa4384c.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • CLAUDE.md
  • __tests__/e2e/hooks/pi-integration.e2e.test.ts

Comment thread CHANGELOG.md Outdated
@hermes-exosphere

Copy link
Copy Markdown
Contributor

[evidence] Build & verification completefix/pi-list-approve-pi080 @ aa4384c

Scope: docs + one e2e test file only — no src/, no dist/, no package.json logic change.

CHANGELOG.md
CLAUDE.md
__tests__/e2e/hooks/pi-integration.e2e.test.ts   (+9 / -3)

Quality gate (CI quality job) — reproduced locally:

Check Command Result
Type check bunx tsc --noEmit ✅ exit 0
Lint eslint __tests__/e2e/hooks/pi-integration.e2e.test.ts ✅ exit 0
Version consistency root package.json = 0.0.13-beta.3 = CHANGELOG top heading; no packages/* to compare

Modified test file:

vitest run --config vitest.config.e2e.mts __tests__/e2e/hooks/pi-integration.e2e.test.ts
 Test Files  1 passed (1)
      Tests  18 passed | 2 skipped (20)

The 2 skipped are exactly the two changed describePi roundtrips — this runner has no pi binary (pi --version → not found), so they describe.skip as designed. The live pi list --approve path could not be exercised here; its --approve semantics rest on the author's stated verification against pi-coding-agent v0.80.3.

Completeness: grep confirms these two are the only real-pi list invocations in the repo — no sibling call site was missed. (Other "list" hits are gh run list in builtin-policies.ts and unrelated tool-map fixtures.)

Docker: not applicable — no app compose stack in this repo; its Docker usage is clean-install packaging validation, and this diff touches no packaged code (only a test + two markdown docs).

Comment thread CHANGELOG.md Outdated
Comment thread __tests__/e2e/hooks/pi-integration.e2e.test.ts Outdated
@hermes-exosphere

Copy link
Copy Markdown
Contributor

🔍 Automated Code Review

📋 Executive Summary

This PR fixes two live pi list e2e roundtrips for pi-coding-agent ≥0.80, which stopped trusting project-local .pi/settings.json by default. It swaps bare pi list for pi list --approve (per-command project trust) in both the install and uninstall roundtrips, and documents the new trust model in CLAUDE.md + CHANGELOG.md. The fix is correct, complete, and well-scoped — it repairs a genuinely broken assertion (the install roundtrip was failing on ≥0.80, and the uninstall roundtrip was passing vacuously). Only test + docs change; no shipped code is touched. One minor traceability nit to tidy before merge.


📊 Change Architecture

graph TD
    A["policies --install --cli pi --scope project"] -->|writes| B[".pi/settings.json<br/>packages: [pi-extension]"]
    B --> C{pi list}
    C -->|"bare (before): pi ≥0.80 ignores<br/>project-local → 'No packages installed.'"| D["install roundtrip FAILED<br/>uninstall PASSED vacuously"]
    C -->|"pi list --approve (this PR):<br/>trust project-local for THIS command"| E["reads pi-extension entry"]
    E --> F["install roundtrip:<br/>asserts pi-extension present ✅"]
    E --> G["uninstall roundtrip:<br/>asserts pi-extension absent ✅ (non-vacuous)"]
    style E fill:#90EE90
    style D fill:#FFD700
    style A fill:#87CEEB
Loading

Legend: 🟢 New (--approve fix) | 🔵 Existing flow | 🟡 Prior broken behavior


🔴 Breaking Changes

No breaking changes detected. Test + markdown docs only — no src/, dist/, package.json, or public-API surface. Shipped package behavior is unchanged.


⚠️ Issues Found

  1. 🟡 Warning (traceability)CHANGELOG.md:6 — entry ends with (#TBD) instead of the real PR number. Sibling entries all use (#488)/(#487)/(#486), and repo convention (CLAUDE.md → Changelog) requires the PR number. Should be (#491). Otherwise the released changelog permanently carries a placeholder.
  2. 🔵 Info (optional robustness)__tests__/e2e/hooks/pi-integration.e2e.test.ts:55piIsAvailable() gates on pi --version exit code only, not version ≥0.80. On pi <0.80, pi list --approve errors on an unknown flag, so both roundtrips would error rather than skip. Reasonable trade-off (≥0.80 is current), but a version-aware gate would make the failure explicit. Non-blocking.

🔬 Logical / Bug Analysis

  • Correctness of the fix:--approve is documented (and comment-explained) as "Trust project-local files for this command" — a per-command opt-in, so it neither prompts interactively (safe under spawnSync with no TTY) nor persists trust across the isolated per-test fixtures. Exactly the right mechanism.
  • Non-vacuity restored: ✅ With --approve, the uninstall assertion stdout not .toContain("pi-extension") is now meaningful — if uninstall failed to strip the entry, pi list would surface it and the test would correctly fail. Previously it passed regardless.
  • Env isolation: ✅ Both spawnSync("pi", …) calls spread process.env then override HOME → env.home, keeping the fixture off the developer's real ~/.pi/agent/state. The FAILPROOFAI_* vars are (correctly) absent here — they matter only to the failproofai binary, not to pi.
  • Completeness:grep across the repo confirms these are the only two real-pi list call sites; no sibling invocation was left on the old form.
  • Race/leak/null checks: none applicable — no concurrency, resources, or nullable state introduced.

🧪 Evidence — Build & Test Results

Type check + Lint (CI `quality` job)
$ bunx tsc --noEmit
=== tsc EXIT: 0 ===

$ eslint __tests__/e2e/hooks/pi-integration.e2e.test.ts --config eslint.config.mjs
=== eslint EXIT: 0 ===

Version consistency: root package.json = 0.0.13-beta.3 = CHANGELOG top heading; no packages/* dir to compare → passes.

Modified test file (vitest e2e)
$ vitest run --config vitest.config.e2e.mts __tests__/e2e/hooks/pi-integration.e2e.test.ts
 Test Files  1 passed (1)
      Tests  18 passed | 2 skipped (20)

The 2 skips are the two changed describePi roundtrips — no pi binary on this runner, so they describe.skip by design. The live --approve path was not executable here; it rests on the author's stated verification against pi-coding-agent v0.80.3.

No Chrome CDP / UI screenshots — this diff has no UI surface.


🔗 Issue Linkage

⚠️ No issue linked (closingIssuesReferences empty). The PR body is thorough and self-explanatory, but a linked bug issue would improve traceability. Note the CHANGELOG (#TBD) above is the more actionable traceability gap.


💡 Suggestions

  • Replace (#TBD)(#491) in CHANGELOG.md (see inline).
  • (optional) Make piIsAvailable() version-aware so pre-0.80 Pi cleanly skips instead of erroring (see inline).
  • (optional) The changelog line is quite long vs. the one-line example in CLAUDE.md; consider trimming — purely stylistic.

🏆 Verdict

⚠️ APPROVED WITH SUGGESTIONS — The fix is correct, complete, and verified against the quality gate (tsc ✅ / lint ✅ / version-consistency ✅) with the modified test file passing (2 roundtrips skip here only because pi is absent). Nothing blocks merge. Recommended before merging: change the changelog (#TBD)(#491).


Automated code review · 2026-07-13 · reviewed @ aa4384c

@hermes-exosphere hermes-exosphere left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review — ⚠️ Approved with suggestions.

The fix is correct, complete, and well-scoped: pi listpi list --approve in both roundtrips is exactly right for pi-coding-agent ≥0.80's project-local trust model, and it restores non-vacuity to the uninstall assertion. Verified against the CI quality gate locally — tsc --noEmit ✅, lint ✅, version consistency ✅ (package.json 0.0.13-beta.3 = CHANGELOG top) — and the modified e2e file passes (18 passed, 2 roundtrips skip here only because no pi binary is on this runner). Grep confirms these were the only two real-pi list call sites.

Nothing blocks merge. One tidy recommended before merging (non-blocking): update the CHANGELOG entry's trailing (#TBD)(#491) — see inline comment. Optional: make piIsAvailable() version-aware so pre-0.80 Pi skips cleanly instead of erroring on the unknown --approve flag.

Full breakdown, evidence, and architecture diagram in the summary comment above.

Replace the placeholder (#TBD) with the actual PR number in the
0.0.13-beta.3 changelog entry, per the repo changelog convention and the
CodeRabbit review comment on this PR.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@hermes-exosphere

Copy link
Copy Markdown
Contributor

🔍 Automated code review started — analyzing [{"additions":5,"deletions":0,"path":"CHANGELOG.md"},{"additions":9,"deletions":0,"path":"CLAUDE.md"},{"additions":9,"deletions":3,"path":"tests/e2e/hooks/pi-integration.e2e.test.ts"}] files, +23/-3...

⏱️ This may take a few minutes. Results will be posted here when complete.

@chhhee10
chhhee10 requested a review from NiveditJain July 13, 2026 06:27
@hermes-exosphere

Copy link
Copy Markdown
Contributor

🔍 Automated Code Review — Re-review @ ebf681f

📋 Executive Summary

Re-review triggered by the new commit ebf681f since the prior review at aa4384c. That commit does exactly one thing: replaces the (#TBD) placeholder with (#491) in the 0.0.13-beta.3 CHANGELOG entry — resolving the single actionable item from the last review. The full PR (Pi pi list --approve e2e fix + docs) re-checks clean: no new issues, no regressions, quality gate green.


📊 Change Architecture (this re-review)

graph TD
    A["Prior review @ aa4384c<br/>APPROVED w/ suggestions"] -->|"flagged: CHANGELOG (#TBD)"| B["Commit ebf681f"]
    B -->|"CHANGELOG.md:6<br/>(#TBD) → (#491)"| C["Traceability nit resolved"]
    A -.->|"non-blocking, carried forward"| D["piIsAvailable() gates on exit code,<br/>not version ≥0.80 (line 55)"]
    C --> E["Quality gate green<br/>tsc · eslint · version-consistency"]
    E --> F["Verdict: APPROVED"]
    style C fill:#90EE90
    style D fill:#FFD700
    style A fill:#87CEEB
Loading

Legend: 🟢 Resolved this commit | 🔵 Prior state | 🟡 Non-blocking carryover


🔴 Breaking Changes

None. Test + markdown docs only — no src/, dist/, package.json, or public-API surface. Shipped package behavior unchanged.


⚠️ Issues Found

  • ResolvedCHANGELOG.md:6 — the prior review's (#TBD)(#491) suggestion is fixed in ebf681f. No TBD placeholders remain (grep clean).
  • 🔵 Info (non-blocking, carryover)__tests__/e2e/hooks/pi-integration.e2e.test.ts:55piIsAvailable() gates on pi --version exit code only, not version ≥0.80. On pi <0.80, pi list --approve errors on an unknown flag, so the two roundtrips would error rather than skip. Acceptable (pi ≥0.80 is current / dogfooded); a version-aware gate would make the failure explicit. Already noted inline at line 450 in the last review — not re-posting.

No new issues introduced by this commit.


🔬 Logical / Bug Analysis

  • Incremental commit (ebf681f): pure text change ((#TBD)(#491)) — no logic, nothing to break.
  • Full PR still sound: both roundtrips use pi list --approve (pi ≥0.80 per-command project trust — a per-command opt-in, so it neither prompts under spawnSync nor persists trust across fixtures); env isolation preserved (spread process.env, override HOME → env.home); the uninstall negative assertion stdout not .toContain("pi-extension") is now non-vacuous — a failed uninstall would surface the entry and correctly fail the test.
  • Version coherence: CHANGELOG heading 0.0.13-beta.3 matches root package.json; date 2026-07-13 is correct (today).

🧪 Evidence — Build & Test Results

Quality gate (CI quality job) — reproduced locally
bunx tsc --noEmit                    → TSC: PASS (exit 0)
bunx eslint <changed e2e test file>  → ESLINT: PASS (exit 0)
version-consistency (ci.yml)         → no packages/ dir; root package.json = 0.0.13-beta.3 = CHANGELOG heading → PASS
grep -n TBD CHANGELOG.md             → none
Modified e2e test file (vitest)
bunx vitest run --config vitest.config.e2e.mts __tests__/e2e/hooks/pi-integration.e2e.test.ts
 Test Files  1 passed (1)
      Tests  18 passed | 2 skipped (20)

The 2 skips are the two changed describePi roundtrips — this runner has no pi binary (pi --version → not found), so they describe.skip by design. The live pi list --approve path could not be exercised here; its --approve semantics rest on the author's stated verification against pi-coding-agent v0.80.3.

No UI surface → no Chrome CDP screenshots. No Docker app stack — this repo's Docker usage is clean-install packaging validation, and this diff touches no packaged code.


🔗 Issue Linkage

⚠️ No linked issue (labeled bug; PR body is thorough and self-explanatory). Non-blocking.


💡 Suggestions

  • (optional, carryover) Make piIsAvailable() version-aware so pre-0.80 Pi cleanly skips instead of erroring on the unknown --approve flag. Purely defensive; ≥0.80 is current.

🏆 Verdict

APPROVED — The one actionable item from the prior review (CHANGELOG (#TBD)) is resolved in ebf681f. The full PR re-checks clean: quality gate green (tsc ✅ / eslint ✅ / version-consistency ✅), modified e2e passes (18 passed, 2 skipped by design). No new issues, no regressions. Ready to merge — the one open item is an optional, non-blocking robustness nit.


Automated re-review · 2026-07-13 · reviewed @ ebf681f (Δ since aa4384c)

@hermes-exosphere hermes-exosphere left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated re-review @ ebf681f: the prior review's sole actionable item — CHANGELOG (#TBD)(#491) — is resolved in this commit. Full PR re-checks clean: tsc ✅, eslint ✅, version-consistency ✅, modified e2e passes (18 passed, 2 skipped by design — no pi binary on the runner). No new issues, no regressions. The one open item (version-aware piIsAvailable() gate) is optional and non-blocking. ✅

Comment thread __tests__/e2e/hooks/pi-integration.e2e.test.ts Outdated
Review feedback on #491: pass --approve only when the installed Pi
supports it. Older Pi (<0.80) trusts project-local .pi/settings.json
unconditionally and rejects the unknown flag, so the roundtrip now
detects the version via `pi --version` and builds the args accordingly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@hermes-exosphere

Copy link
Copy Markdown
Contributor

🔍 Automated code review started — analyzing [{"additions":5,"deletions":0,"path":"CHANGELOG.md"},{"additions":11,"deletions":0,"path":"CLAUDE.md"},{"additions":24,"deletions":8,"path":"tests/e2e/hooks/pi-integration.e2e.test.ts"}] files, +40/-8...

⏱️ This may take a few minutes. Results will be posted here when complete.

Comment thread __tests__/e2e/hooks/pi-integration.e2e.test.ts
@hermes-exosphere

Copy link
Copy Markdown
Contributor

🔍 Automated Code Review — Re-review @ 9c6a9aa (Δ since ebf681f)

📋 Executive Summary

Re-review triggered by the new commit 9c6a9aa ("Gate pi list --approve on detected Pi version (>=0.80)"). This commit resolves the sole open carryover from the prior two reviews — the version-aware gate for the --approve flag. It replaces the boolean piIsAvailable() with detectPiVersion() (parses pi --version) and a piListArgs() helper that appends --approve only on pi ≥0.80, so older Pi (<0.80, which trusts project-local settings unconditionally and rejects the unknown flag) no longer errors — it cleanly runs pi list. Logic is verified correct across all version edge cases; the quality gate is green and full CI passes. No blocking issues. One optional, non-blocking hardening note (inline).


📊 Change Architecture (this re-review)

graph TD
    A["Prior reviews @ aa4384c / ebf681f<br/>open nit: version-aware gate"] -->|"addressed by"| B["Commit 9c6a9aa"]
    B --> C["piIsAvailable(): boolean<br/>→ detectPiVersion(): string | null"]
    C -->|"parses /\\d+.\\d+.\\d+/ from stdout"| D{"piListArgs(version)"}
    D -->|"major>0 || minor>=80"| E["['list', '--approve']<br/>pi ≥0.80 · per-command project trust"]
    D -->|"else"| F["['list']<br/>pi <0.80 · trusts project unconditionally,<br/>rejects unknown flag"]
    E --> G["Install + uninstall roundtrips<br/>run correct args per version"]
    F --> G
    C -.->|"null → describe.skip"| H["No pi binary → tests skip (by design)"]
    style C fill:#90EE90
    style D fill:#90EE90
    style A fill:#87CEEB
    style H fill:#FFD700
Loading

Legend: 🟢 New this commit | 🔵 Prior state | 🟡 Skip path (no pi)


🔴 Breaking Changes

None. Test helper + markdown docs only — no src/, dist/, package.json, or public-API surface. Shipped package behavior is unchanged.


⚠️ Issues Found

  • Resolved — the prior reviews' carryover suggestion ("make piIsAvailable() version-aware so pre-0.80 Pi skips/handles cleanly instead of erroring on the unknown --approve flag") is implemented in 9c6a9aa via detectPiVersion() + piListArgs().
  • 🔵 Info (optional, non-blocking)pi-integration.e2e.test.ts:59detectPiVersion() matches the version from stdout only; if a future pi --version moves output to stderr, live roundtrips would silently describe.skip on a Pi-equipped machine. Fails safe (skip, never false-pass) and stdout is verified on v0.80.3. One-line hardening posted inline. No new blocking issues introduced.

🔬 Logical / Bug Analysis

  • piListArgs() boundary — verified correct by direct simulation of the exact code:

    version args version args
    0.79.9 ["list"] 0.80.0 ["list","--approve"]
    0.80.3 ["list","--approve"] 0.8.0 ["list"] ✅ (0.8 < 0.80)
    0.100.0 ["list","--approve"] 1.0.0 ["list","--approve"]

    Numeric major/minor comparison (not string) correctly handles the 0.8.0 vs 0.80.0 trap and future majors. The [major = 0, minor = 0] destructuring defaults are defensive-only (the sole caller always passes a 3-part regex match).

  • Version extraction — verified across realistic pi --version shapes ("0.80.3", "pi-coding-agent 0.80.3", "v0.80.3 (build …)" → all "0.80.3"; empty/garbage → null).

  • No null-deref: probe.stdout.match(...) is reached only after status === 0, where (with encoding:"utf8") stdout is a string; the ENOENT/spawn-error path returns early via status !== 0, and the whole body is try/catch.

  • Dead-but-harmless: PI_LIST_ARGS = piVersion ? piListArgs(piVersion) : ["list"] — the : ["list"] branch is unreachable at use-time (when piVersion is null, describePi is skipped so the args are never consumed). Fine.

  • Non-vacuity preserved: the uninstall assertion stdout not .toContain("pi-extension") remains meaningful because --approve is applied on ≥0.80 — a failed uninstall would surface the entry and correctly fail.

  • Rename is complete: grep finds zero dangling piIsAvailable/piPresent references; the two spawnSync("pi", …) call sites are the only real pi list invocations in the repo and both now use PI_LIST_ARGS.

  • Docs consistent: CLAUDE.md and CHANGELOG.md both updated to describe version-detection + detectPiVersion() gating, matching the code.


🧪 Evidence — Build & Test Results

Quality gate (CI quality job) — reproduced locally after bun install
bunx tsc --noEmit                    → PASS (exit 0, no diagnostics)
bunx eslint <changed e2e test file>  → PASS (exit 0, no findings)
version consistency                  → root package.json 0.0.13-beta.3 == CHANGELOG top heading; no packages/* dir → PASS
grep -n 'piIsAvailable|piPresent'    → none (clean rename)
Modified e2e test file (vitest)
bunx vitest run --config vitest.config.e2e.mts __tests__/e2e/hooks/pi-integration.e2e.test.ts
 Test Files  1 passed (1)
      Tests  18 passed | 2 skipped (20)

The 2 skips are the two describePi live roundtrips — this runner has no pi binary (detectPiVersion()null), so they describe.skip by design. The live pi list --approve path could not be exercised here; its ≥0.80 semantics rest on the author's stated verification against pi-coding-agent v0.80.3.

Full CI on HEAD 9c6a9aa
build ✅   docs ✅   quality ✅   test (default) ✅   test (hook-log-file) ✅
test (log-debug) ✅   test-e2e ✅   CodeRabbit ✅   OSV-Scanner ✅   Socket Security ✅

No UI surface → no Chrome CDP screenshots. Docker: N/A — this repo has no app compose stack; its Docker usage is clean-install packaging validation, and this diff touches no packaged code (only a test helper + two markdown docs).


🔗 Issue Linkage

Labeled bug; no linked issue (closingIssuesReferences empty). The PR body is thorough and self-explanatory. Non-blocking.


💡 Suggestions

  • (optional) Harden detectPiVersion() to match against stdout + stderr (inline @ line 59) — purely defensive against a future output-stream change in pi --version.
  • (context) The ≥0.80 cutoff is the best available data point (v0.73.1 = old/trusts-project, v0.80.3 = new/needs---approve); the exact flip version between them is unverified but the round 0.80 boundary is documented and reasonable.

🏆 Verdict

APPROVED — Commit 9c6a9aa cleanly resolves the one open item from the prior reviews (version-aware --approve gating) with logic verified correct across every version boundary. Quality gate green (tsc ✅ / eslint ✅ / version-consistency ✅), modified e2e passes (18 passed, 2 skipped by design), and full CI is green on HEAD. No new issues, no regressions. The single remaining note is an optional, non-blocking robustness nit. Ready to merge.

ℹ️ Note: the PR's current CHANGES_REQUESTED state is a human review by @NiveditJain on the previous commit ebf681f; the feedback it concerned is addressed by 9c6a9aa. A maintainer re-review is needed to clear that decision.


Automated re-review · 2026-07-13 · reviewed @ 9c6a9aa (Δ since ebf681f)

@hermes-exosphere hermes-exosphere left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated re-review @ 9c6a9aa: ✅ Approved.

The new commit implements the version-aware gate that the prior reviews flagged as the one open item. piIsAvailable()detectPiVersion() + piListArgs() appends --approve only on pi ≥0.80, so pre-0.80 Pi (which trusts project-local settings unconditionally and rejects the unknown flag) now runs a bare pi list instead of erroring. I verified the boundary logic by directly simulating the exact code — correct across 0.79.9, 0.80.0, 0.80.3, the 0.8.0-vs-0.80.0 trap, 0.100.0, and 1.0.0 (numeric, not string, comparison). Rename is complete (no dangling piIsAvailable/piPresent), both real pi list call sites use PI_LIST_ARGS, and docs (CLAUDE.md + CHANGELOG.md) match the code.

Quality gate reproduced locally after bun install: tsc --noEmit ✅, eslint on the changed file ✅, version-consistency ✅ (package.json 0.0.13-beta.3 = CHANGELOG heading), modified e2e passes (18 passed, 2 roundtrips skip by design — no pi binary on this runner). Full CI green on HEAD.

One non-blocking inline note: detectPiVersion() reads the version from stdout only — an optional stdout + stderr hardening against a future output-stream change. Not required for merge.

Full breakdown, architecture diagram, and evidence in the summary comment above.

@NiveditJain
NiveditJain merged commit f78f0ae into main Jul 13, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants