Skip to content

feat(package): isolate project doctor diagnostics - #479

Merged
unbraind merged 1 commit into
mainfrom
package-doctor-isolated-sdk-contracts
Jul 7, 2026
Merged

unbraind merged 1 commit into
mainfrom
package-doctor-isolated-sdk-contracts

Conversation

@unbraind

@unbraind unbraind commented Jul 7, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • add --isolated / --ignore-global support for project-scoped package and extension doctor diagnostics
  • surface isolation metadata, vocabulary-specific rerun commands, and global-state remediation in doctor output
  • advertise the new flags through help, completions, SDK flag/action/tool contracts, and package-author docs
  • refactor extension API registration into a bound registrar to clear CodeFactor-parity complexity without breaking destructured package activators
  • close/release pm-6abs and link the slice to pm-usfg, pm-w89s, pm-cbwg, and pm-x6jf

Verification

  • pnpm build
  • node scripts/run-tests.mjs test -- tests/unit/extensions/extension-command.spec.ts tests/unit/sdk/action-schema-parity.spec.ts tests/unit/sdk/tool-option-contracts.spec.ts tests/unit/sdk/sdk-index.spec.ts tests/unit/scripts/release/docs-skills-gate.spec.ts
  • PM_AUTHOR=codex-agent pm test pm-6abs --run --progress
  • node scripts/run-tests.mjs coverage (5450 tests, 100/100/100/100)
  • temp-dir package init/install/doctor --project --isolated --detail deep --trace dogfood loaded only project:pm-temp-smoke
  • pnpm changelog:pm && pnpm changelog:pm:check (pm-changelog 2026.7.6)
  • pm health --check-only --summary --json
  • pm validate --check-resolution --check-history-drift --json (ok; existing validate_resolution_missing_fields:269 warning only)
  • pnpm audit --audit-level moderate
  • GitHub Dependabot alerts: []
  • GitHub code-scanning alerts: []
  • greptile review --branch origin/main --agent (initial comments fixed; rerun clean, no review comments)

Notes

  • Static quality gate CodeFactor-parity complexity is clear. The remaining repo-wide docstring coverage gate failure is tracked by open pm-4ak1 and is outside this completed pm-6abs slice.

Summary by cubic

Adds --isolated/--ignore-global to pm package|extension doctor so project diagnostics ignore global registrations, enabling hermetic smoke tests and closing GH-467. Also hardens the extension registrar and policy rendering for safer activation and clearer diagnostics.

  • New Features

    • pm package|extension doctor --project --isolated (alias --ignore-global) skips global registrations; doctor output shows isolation metadata and rerun hints.
    • Help, zsh completions, and docs/SDK.md document isolation and PM_GLOBAL_PATH; SDK flag contracts, tool schema, and parameter tables include the flags; CLI threads the option to the loader via ignoreGlobalExtensions.
  • Refactors

    • Registrar internals moved to private fields with bound public methods; activators cannot observe internal registries; improved registerCommand validation traces and guarded malformed policy override names.
    • Enforces schema.flags policy for inline flag registrations.

Written for commit 1ec1bcf. Summary will update on new commits.

Review in cubic

@sourcery-ai sourcery-ai 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.

Sorry @unbraind, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@unbraind

unbraind commented Jul 7, 2026

Copy link
Copy Markdown
Owner Author

@greptileai review

Please review the current head for package/extension doctor isolation, SDK contract exposure, and the extension API registrar refactor.

@unbraind

unbraind commented Jul 7, 2026

Copy link
Copy Markdown
Owner Author

/gemini review

Please review the current head for package/extension doctor isolation behavior, test coverage, and SDK/API compatibility.

@unbraind

unbraind commented Jul 7, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

Please run a full review of the current head, especially the doctor isolation payloads and extension API registrar refactor.

@coderabbitai

coderabbitai Bot commented Jul 7, 2026 •

Copy link
Copy Markdown

@unbraind: Got it — I'll run a full review of the current head, paying particular attention to:

  • The doctor isolation payloads (--isolated / --ignore-global behavior, isolation metadata, vocabulary-specific rerun commands, and global-state remediation output).
  • The extension API registrar refactor (bound registrar pattern) to confirm destructured package activators still work correctly and CodeFactor-parity complexity concerns are resolved.

I'll post detailed comments on anything found.

✅ Action performed

Full review finished.


Your plan includes PR reviews subject to rate limits. More reviews will be available in 59 minutes.

@coderabbitai

coderabbitai Bot commented Jul 7, 2026 •

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

No new commits to review since the last review.

⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: 1e132d45-7b7d-44a8-919d-97a374e93106

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds isolated doctor flags and related wiring for package and extension diagnostics, skips global extension discovery when requested, and updates the CLI, SDK contracts, tests, docs, and PM tracking records. It also refactors extension API registration into a class-based registrar.

Changes

Isolated doctor diagnostics

Layer / File(s) Summary
Discovery and API registrar
src/core/extensions/extension-types.ts, src/core/extensions/loader.ts
Adds ignoreGlobalExtensions to discovery options, skips global scans when set, and rewrites extension API construction into ExtensionApiRegistrar.
Doctor isolation behavior and output
src/cli/commands/extension.ts
Adds isolated/ignoreGlobal options, validates scope, computes isolation hints, and includes isolation metadata in doctor output.
CLI wiring and SDK contracts
src/cli/register-setup.ts, src/cli/commands/completion.ts, src/cli/help-content.ts, src/sdk/cli-contracts/*, .agents/pm/extensions/.managed-extensions.json
Registers the new flags in parsing, completions, help text, SDK flag/schema contracts, and updates managed-extension metadata timestamps.
Tests, docs, and changelog
tests/unit/extensions/extension-command.spec.ts, tests/unit/extensions/extension-loader-internal.spec.ts, tests/unit/extensions/extension-loader.spec.ts, tests/unit/sdk/sdk-index.spec.ts, CHANGELOG.md, docs/EXTENSIONS.md, docs/SDK.md
Adds coverage for isolated doctor behavior, policy enforcement, contract assertions, and documents the workflow.
PM tracker records
.agents/pm/*
Updates epic, feature, history, and story records with status, dependency, comment, evidence, and test-run changes.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related issues

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
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.
Title check ✅ Passed The title clearly summarizes the main change: isolating project doctor diagnostics for package workflows.
Description check ✅ Passed The description is directly related to the changeset and accurately covers the main implementation areas.

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.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request implements isolated package and extension diagnostics by introducing an --isolated (or --ignore-global) flag for the pm package doctor and pm extension doctor commands. This allows for hermetic smoke tests by excluding global extension registrations from project-scoped diagnostics. The changes include updates to CLI flag parsing, help content, SDK contracts, and the extension loader, along with regression tests to verify the isolation behavior. I have reviewed the implementation and found a potential runtime error in src/cli/commands/extension.ts where override.name is accessed without validation, which is addressed by the provided suggestion.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/cli/commands/extension.ts Resolved
@greptile-apps

greptile-apps Bot commented Jul 7, 2026 •

Copy link
Copy Markdown

Greptile Summary

This PR adds isolated project doctor diagnostics for package and extension workflows. The main changes are:

  • New --isolated and --ignore-global doctor flags for project-scoped diagnostics.
  • Loader support to skip global extension discovery during isolated doctor runs.
  • Doctor output with isolation metadata, rerun commands, and PM_GLOBAL_PATH remediation guidance.
  • Updated CLI help, completions, SDK contracts, tool schemas, docs, fixtures, and tests.
  • Extension registrar hardening with private internals, bound public methods, and policy-aware inline flag registration.

Confidence Score: 5/5

Safe to merge with low risk.

The core behavior is narrowly scoped to doctor diagnostics and extension discovery options. The global-scan bypass is explicit and limited to project-scope doctor runs. The changed contracts are reflected in fixtures and tests. No blocking correctness or security issues were identified.

No files require special attention.

T-Rex T-Rex Logs

What T-Rex did

  • Ran a non-isolated project doctor run and captured its output, which included the global-pm-temp-smoke indicator, emitted global override warnings, and a status report showing isolated: false, global_extensions_included: true, global_diagnostics_present: true, plus the rerun guidance.
  • Ran an isolated extension doctor and a package doctor with --ignore-global, which loaded only the project extension and reported isolated: true, global_extensions_included: false, global_diagnostics_present: false, then exited with code 0.
  • Collected and inspected the related artifacts to verify the two runs, including the non-isolated log, the shell-script used for the isolated run, and the isolated run log.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
src/cli/commands/extension.ts Adds doctor isolation validation, loader threading, metadata/remediation output, and defensive policy rendering.
src/core/extensions/loader.ts Skips global extension scanning when requested and hardens/binds extension API registration methods.
src/core/extensions/extension-types.ts Adds ignoreGlobalExtensions to the loader/discovery option contract.
src/cli/register-setup.ts Normalizes --isolated and --ignore-global options for extension/package lifecycle commands.
src/cli/commands/completion.ts Extends shell completion flag sources so lifecycle doctor commands advertise isolation flags.
src/sdk/cli-contracts/tool-schema.ts Includes isolated and ignoreGlobal in lifecycle action schema option keys.
src/sdk/cli-contracts/flag-contracts.ts Adds isolation flags to SDK flag contracts for package/extension doctor actions.
tests/unit/extensions/extension-command.spec.ts Adds tests for project/global doctor isolation metadata, hints, and policy detail rendering.
tests/unit/extensions/extension-loader.spec.ts Adds tests for bound registrar behavior and inline command flag policy enforcement.
docs/SDK.md Documents the new isolated doctor flags and package-author workflow.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant User
participant CLI as pm package/extension doctor
participant Setup as register-setup
participant Doctor as extension.ts doctor action
participant Loader as loadExtensions/discoverExtensions
participant Global as Global extension layer
participant Project as Project extension layer

User->>CLI: doctor --project --isolated/--ignore-global
CLI->>Setup: normalize lifecycle options
Setup->>Doctor: "isolated=true, scope=project"
Doctor->>Loader: "loadExtensions(ignoreGlobalExtensions=true)"
alt isolated project diagnostics
    Loader--xGlobal: skip global scan
else normal project diagnostics
    Loader->>Global: scan global extensions
end
Loader->>Project: scan project extensions
Loader-->>Doctor: loaded/failed/warnings/policy
Doctor-->>CLI: summary + isolation metadata + remediation
CLI-->>User: JSON/TOON/text doctor output
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant User
participant CLI as pm package/extension doctor
participant Setup as register-setup
participant Doctor as extension.ts doctor action
participant Loader as loadExtensions/discoverExtensions
participant Global as Global extension layer
participant Project as Project extension layer

User->>CLI: doctor --project --isolated/--ignore-global
CLI->>Setup: normalize lifecycle options
Setup->>Doctor: "isolated=true, scope=project"
Doctor->>Loader: "loadExtensions(ignoreGlobalExtensions=true)"
alt isolated project diagnostics
    Loader--xGlobal: skip global scan
else normal project diagnostics
    Loader->>Global: scan global extensions
end
Loader->>Project: scan project extensions
Loader-->>Doctor: loaded/failed/warnings/policy
Doctor-->>CLI: summary + isolation metadata + remediation
CLI-->>User: JSON/TOON/text doctor output
Loading

Reviews (13): Last reviewed commit: "feat(package): isolate project doctor di..." | Re-trigger Greptile

@greptile-apps

greptile-apps Bot commented Jul 7, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds isolated package and extension doctor diagnostics for project-scoped smoke tests. The main changes are:

  • New --isolated and --ignore-global doctor flags across CLI parsing, help, completions, SDK contracts, and MCP tool schemas.
  • Loader support for skipping global extension discovery during isolated project doctor runs.
  • Doctor output with isolation metadata, vocabulary-specific rerun commands, and PM_GLOBAL_PATH fallback guidance.
  • Bound extension API registration so destructured package activator methods continue to work.
  • Updated package-author docs, changelog notes, work-item records, and tests for global leakage and isolation behavior.

Confidence Score: 5/5

Safe to merge with minimal risk.

The runtime change is narrowly scoped to doctor diagnostics, contract surfaces are kept in sync, and tests cover isolated and non-isolated behavior.

No files require special attention.

T-Rex T-Rex Logs

What T-Rex did

  • Before the run, the doctor was non-isolated with global_extensions_included: true.
  • After the run, the doctor is isolated with global_extensions_included: false and exit code 0.
  • An alias run using --ignore-global maps to isolated diagnostics.
  • Help artifacts were provided to help reviewers inspect the doctor isolation behavior.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
.agents/pm/features/pm-6abs.toon Closes the feature item with implementation evidence, verification records, linked files, docs, and tests for isolated doctor diagnostics.
docs/EXTENSIONS.md Documents package smoke-test isolation guidance and the PM_GLOBAL_PATH fallback for package authors.
docs/SDK.md Updates SDK/package-author documentation to mention isolated doctor runs and hermetic diagnostics.
src/cli/commands/extension.ts Implements doctor isolation behavior, isolation metadata/remediation, and scope validation for the new flags.
src/cli/register-setup.ts Registers --isolated/--ignore-global on lifecycle and doctor subcommands and normalizes option aliases.
src/core/extensions/loader.ts Skips global extension layer scanning when requested and refactors extension API registration into a bound registrar.
src/sdk/cli-contracts/flag-contracts.ts Adds the new doctor isolation flags to extension/package CLI flag contracts and doctor subcommand contracts.
src/sdk/cli-contracts/tool-schema.ts Includes isolated and ignoreGlobal in managed extension/package action schema parameter sets.
tests/unit/extensions/extension-command.spec.ts Adds tests for global diagnostic leakage, isolated project doctor output, and bound API activation.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
  participant User
  participant CLI as pm package/extension doctor
  participant Run as runExtensionDoctorAction
  participant Loader as loadExtensions
  participant Activator as activateExtensions
  participant Output as doctor summary/remediation

  User->>CLI: "doctor --project [--isolated|--ignore-global]"
  CLI->>Run: normalized options + vocabulary
  Run->>Run: validate doctor scope/detail/trace
  Run->>Loader: "ignoreGlobalExtensions = isolated"
  alt isolated project doctor
    Loader->>Loader: skip global extension layer scan
  else non-isolated project doctor
    Loader->>Loader: scan global + project extension layers
  end
  Loader-->>Run: load result + policy/warnings
  Run->>Activator: activate loaded extensions
  Activator-->>Run: registrations and activation warnings
  Run->>Output: build isolation metadata, warning codes, rerun command, PM_GLOBAL_PATH recipe
  Output-->>User: doctor diagnostics
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
  participant User
  participant CLI as pm package/extension doctor
  participant Run as runExtensionDoctorAction
  participant Loader as loadExtensions
  participant Activator as activateExtensions
  participant Output as doctor summary/remediation

  User->>CLI: "doctor --project [--isolated|--ignore-global]"
  CLI->>Run: normalized options + vocabulary
  Run->>Run: validate doctor scope/detail/trace
  Run->>Loader: "ignoreGlobalExtensions = isolated"
  alt isolated project doctor
    Loader->>Loader: skip global extension layer scan
  else non-isolated project doctor
    Loader->>Loader: scan global + project extension layers
  end
  Loader-->>Run: load result + policy/warnings
  Run->>Activator: activate loaded extensions
  Activator-->>Run: registrations and activation warnings
  Run->>Output: build isolation metadata, warning codes, rerun command, PM_GLOBAL_PATH recipe
  Output-->>User: doctor diagnostics
Loading

Reviews (1): Last reviewed commit: "feat(package): isolate project doctor di..." | Re-trigger Greptile

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request implements isolated package and extension diagnostics for the doctor command (addressing GH-467). It introduces the --isolated (alias --ignore-global) flag to run diagnostics against project-scope extensions/packages only, preventing global registrations from leaking into hermetic project smoke tests. The extension loader has been updated to skip global scans when requested, and the extension API creation has been refactored into a bound ExtensionApiRegistrar class to ensure destructured API methods remain safe. Additionally, the PR updates shell completions, help content, SDK contracts, MCP schemas, documentation, and adds regression tests. As there are no review comments, no feedback is provided.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@codecov

codecov Bot commented Jul 7, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

@unbraind
unbraind force-pushed the package-doctor-isolated-sdk-contracts branch from 1505e52 to bc88af7 Compare July 7, 2026 10:18
@unbraind

unbraind commented Jul 7, 2026

Copy link
Copy Markdown
Owner Author

Review request for updated head bc88af7 after CI contract snapshot fix.

@greptileai review
/gemini review
@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 7, 2026 •

Copy link
Copy Markdown

@unbraind: Got it — I'll run a full review of the current head (bc88af7) now that the CI contract snapshot fix is in, with continued focus on:

  • Package/extension doctor isolation payloads (--isolated / --ignore-global, isolation metadata, vocabulary-specific rerun commands, and global-state remediation).
  • SDK contract exposure (flag contracts, tool parameter tables, tool schema).
  • The extension API registrar refactor (bound registrar pattern) for destructured package activator compatibility.

I'll post detailed comments on anything found.

✅ Action performed

Full review finished.


Your plan includes PR reviews subject to rate limits. More reviews will be available in 46 minutes.

@cubic-dev-ai cubic-dev-ai 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.

2 issues found and verified against the latest diff

You’re at about 91% of the monthly reviewed-line limit. You may want to disable incremental reviews to conserve quota. Reviews will continue until that limit is exceeded. If you need help avoiding interruptions, please contact contact@cubic.dev.

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread src/core/extensions/loader.ts Resolved
Comment thread src/cli/commands/extension.ts Resolved

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request implements isolated package and extension diagnostics for the pm CLI, addressing issues where global extension registrations leak into project-scoped diagnostics. It introduces --isolated (and --ignore-global) flags for pm package doctor and pm extension doctor, updates CLI contracts, help content, and documentation, and adds regression tests to verify hermetic behavior. I have reviewed the implementation and identified two type-safety improvements regarding the loadResult parameter type definition in src/cli/commands/extension.ts.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/cli/commands/extension.ts Resolved
Comment thread src/cli/commands/extension.ts Resolved
@unbraind
unbraind force-pushed the package-doctor-isolated-sdk-contracts branch from bc88af7 to 56d84cb Compare July 7, 2026 10:50
@unbraind

unbraind commented Jul 7, 2026

Copy link
Copy Markdown
Owner Author

Review request for updated head 56d84cb after Greptile P1 fix and final full coverage.

@greptileai review
/gemini review
@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 7, 2026 •

Copy link
Copy Markdown

@unbraind: Got it — I'll run a full review of the current head (56d84cb) now that the Greptile P1 fix is in, continuing to focus on:

  • Package/extension doctor isolation payloads (--isolated / --ignore-global, isolation metadata, vocabulary-specific rerun commands, and global-state remediation).
  • SDK contract exposure (flag contracts, tool parameter tables, tool schema).
  • The extension API registrar refactor (bound registrar pattern) for destructured package activator compatibility.

I'll post detailed comments on anything found.

✅ Action performed

Full review finished.


Your plan includes PR reviews subject to rate limits. More reviews will be available in 14 minutes.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request implements isolated package and extension diagnostics (GH-467) by introducing the --isolated (alias --ignore-global) flag to the doctor commands, allowing hermetic project-scoped runs that ignore global registrations. The changes span CLI flag parsing, shell completions, SDK contracts, MCP schemas, documentation, and a refactoring of the extension loader to use a bound ExtensionApiRegistrar class. The review feedback highlights several opportunities in src/core/extensions/loader.ts to improve diagnostic trace output by passing the omitted received and hint arguments (such as the invalid overrides, definitions, or error reasons) to registerCommandTrace calls.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/core/extensions/loader.ts Resolved
Comment thread src/core/extensions/loader.ts Resolved
Comment thread src/core/extensions/loader.ts Resolved
Comment thread src/core/extensions/loader.ts Resolved
@unbraind
unbraind force-pushed the package-doctor-isolated-sdk-contracts branch from 56d84cb to 1244994 Compare July 7, 2026 11:29
@unbraind

unbraind commented Jul 7, 2026

Copy link
Copy Markdown
Owner Author

Updated head: 1244994

This repush addresses the fresh review feedback:

  • Cubic P1: ExtensionApiRegistrar internals are now ECMAScript private fields with regression coverage for non-exposed legacy field names.
  • Gemini trace suggestions: registerCommand validation traces now include the invalid override/run-handler values and metadata validation reasons.
  • Gemini override-name guard: malformed policy override names are filtered safely with coverage.

Local verification on this exact head:

  • node scripts/run-tests.mjs test -- tests/unit/extensions/extension-loader-internal.spec.ts
  • node scripts/run-tests.mjs test -- tests/unit/extensions/extension-command.spec.ts tests/unit/extensions/extension-loader.spec.ts
  • pnpm quality:static
  • node scripts/run-tests.mjs coverage (5450 tests, 100/100/100/100)
  • greptile review --agent (review b5c75b05-89c7-4235-b816-240838b9a526, confidence 5/5, no comments)

@greptileai review
/gemini review
@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 7, 2026 •

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the ExtensionApiRegistrar class for private field usage
ast-grep outline src/core/extensions/loader.ts --items all --type class --match 'ExtensionApiRegistrar' | head -100

echo "----"
rg -n 'class ExtensionApiRegistrar' -A 30 src/core/extensions/loader.ts

echo "---- private fields ----"
rg -n '#[a-zA-Z]' src/core/extensions/loader.ts | head -60

echo "---- legacy field name test ----"
rg -n 'legacy' -i tests/unit/extensions/*.spec.ts

echo "---- registerCommand validation trace ----"
rg -n 'registerCommand' -A 20 src/core/extensions/loader.ts | head -120

Length of output: 20895


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- override-name guard ----"
rg -n 'override' -i src/core/extensions/loader.ts | rg -i 'name' | head -40

echo "---- extension_overrides sanitization ----"
rg -n 'extension_overrides' -A 15 src/cli/commands/extension.ts | head -80

echo "---- buildDoctorIsolationHint ----"
rg -n 'buildDoctorIsolationHint|hasGlobalLayerDiagnostics' -A 25 src/cli/commands/extension.ts | head -150

echo "---- isolated flag validation ----"
rg -n 'isolated|ignoreGlobal' -n src/cli/commands/extension.ts | head -60

Length of output: 11481


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- package.ts isolation wiring ----"
rg -n 'isolated|ignoreGlobal|buildDoctorIsolationHint|buildDoctorIsolationMetadata' src/cli/commands/package.ts | head -60

echo "---- sdk-index.spec.ts doctor flags ----"
rg -n 'isolated' -A5 -B5 tests/unit/sdk/sdk-index.spec.ts

Length of output: 719


🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n 'isolated' -A5 -B5 tests/unit/sdk/sdk-index.spec.ts

Length of output: 1414


All checks confirm the fixes described in the update are correctly implemented in this head.

@unbraind: Full review complete on head 1244994. I verified all three points from the repush notes directly against the code:

  • ECMAScript private fields: src/cli/commands/../src/core/extensions/loader.ts ExtensionApiRegistrar (Line 1810) now declares all internal state as true private fields (#loadedExtension, #extensionRef, #hookRegistry, #commandRegistry, #parserRegistry, #preflightRegistry, #serviceRegistry, #rendererRegistry, #registrationRegistry, #activationWarnings, #policy), so legacy field names are structurally inaccessible rather than just conventionally private. Method bindings (Lines 1849–1862) correctly rebind the public surface for destructured package activator usage.
  • Trace details for registerCommand validation: registerCommandTrace (Line 1892) and its call sites (e.g., Lines 1909–1919) build ExtensionActivationFailureTrace objects that include command, expected_schema, sanitized received value, and a hint — covering the invalid override/run-handler and metadata validation cases Gemini flagged.
  • Override-name guard: buildExtensionPolicyOverrideDetails (Lines 413–418) trims and rejects empty/malformed override.name values by returning null, and the caller (Lines 441–444) filters those null entries out before sorting extension_overrides — so malformed policy override names can't propagate into the doctor payload.

I additionally spot-checked the isolation feature itself:

  • hasGlobalLayerDiagnostics / buildDoctorIsolationHint / buildDoctorIsolationMetadata (Lines 2207–2268) correctly gate on scope === "project" and only surface global-state remediation/rerun-command guidance when appropriate, with vocabulary-aware (package/extension) command text.
  • runExtensionDoctorAction (Lines 2270–2310) correctly rejects --isolated/--ignore-global in global scope (Lines 2276–2277) and wires ignoreGlobalExtensions: isolated into loadExtensions.
  • tests/unit/sdk/sdk-index.spec.ts (Line 853) confirms the packages doctor flag contract snapshot now includes --isolated alongside --strict-exit and --trace, matching the CI contract snapshot fix mentioned.

No issues found — the fixes match what's described in the repush notes and the isolation/registrar work looks solid.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request implements isolated package and extension diagnostics for pm package doctor and pm extension doctor to support hermetic project-scoped smoke tests. It introduces the --isolated (alias --ignore-global) flag across CLI commands, shell completions, help content, and SDK/MCP schemas, allowing global registrations to be skipped. Additionally, it refactors the extension API creation to use a private-field-based ExtensionApiRegistrar class to prevent internal properties from leaking. The review feedback highlights potential runtime TypeError exceptions in src/cli/commands/extension.ts if the optional policy configuration block is undefined or null, recommending defensive guards to default it to an empty object.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/cli/commands/extension.ts Resolved
Comment thread src/cli/commands/extension.ts Resolved

@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: 2

🤖 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`:
- Line 7: The CHANGELOG entry includes a private `.agents/pm/...` link, which
should not appear in public docs. Update the changelog bullet to remove the
internal tracker path and replace it with a public issue/PR reference or a
neutral label, keeping the `GH-467` entry and its descriptive text intact.

In `@src/core/extensions/loader.ts`:
- Around line 2031-2040: `registerCommand` currently allows inline `flags`
registration after only the schema capability assertion, so enforce-mode
policies can be bypassed. Update the `definition.flags` branch in `loader.ts` to
also use the same `allowRegistration("schema.flags", ...)` gate used by
`registerFlags()` and the importer/exporter metadata path before pushing into
`#registrationRegistry.flags`, while keeping the existing
`assertExtensionCapability` and normalization logic in place.
🪄 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: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: a9cc5b83-b9cf-43a3-b7bb-8751801f9c50

📥 Commits

Reviewing files that changed from the base of the PR and between 1505e52 and 1244994.

📒 Files selected for processing (26)
  • .agents/pm/epics/pm-usfg.toon
  • .agents/pm/features/pm-6abs.toon
  • .agents/pm/features/pm-cbwg.toon
  • .agents/pm/features/pm-x6jf.toon
  • .agents/pm/history/pm-6abs.jsonl
  • .agents/pm/history/pm-cbwg.jsonl
  • .agents/pm/history/pm-usfg.jsonl
  • .agents/pm/history/pm-w89s.jsonl
  • .agents/pm/history/pm-x6jf.jsonl
  • .agents/pm/stories/pm-w89s.toon
  • CHANGELOG.md
  • docs/EXTENSIONS.md
  • docs/SDK.md
  • src/cli/commands/completion.ts
  • src/cli/commands/extension.ts
  • src/cli/help-content.ts
  • src/cli/register-setup.ts
  • src/core/extensions/extension-types.ts
  • src/core/extensions/loader.ts
  • src/sdk/cli-contracts/flag-contracts.ts
  • src/sdk/cli-contracts/tool-parameter-tables.ts
  • src/sdk/cli-contracts/tool-schema.ts
  • tests/fixtures/contracts/full.json
  • tests/unit/extensions/extension-command.spec.ts
  • tests/unit/extensions/extension-loader-internal.spec.ts
  • tests/unit/sdk/sdk-index.spec.ts

Comment thread CHANGELOG.md Resolved
Comment thread src/core/extensions/loader.ts Resolved
@unbraind
unbraind force-pushed the package-doctor-isolated-sdk-contracts branch from 1244994 to 03700d1 Compare July 7, 2026 12:02
@unbraind

unbraind commented Jul 7, 2026

Copy link
Copy Markdown
Owner Author

Updated head: 03700d1

This repush addresses the fresh CodeRabbit/Gemini feedback:

Local verification on this exact head:

  • node scripts/run-tests.mjs test -- tests/unit/extensions/extension-command.spec.ts tests/unit/extensions/extension-loader.spec.ts (225 passed)
  • pnpm quality:static
  • node scripts/run-tests.mjs coverage (5451 tests, 100/100/100/100)
  • greptile review --agent (review 045f951c-3bae-4bbf-8449-410879b317c6, confidence 5/5, no comments)

@greptileai review
/gemini review
@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 7, 2026 •

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- CHANGELOG.md GH-467 link ----"
rg -n 'GH-467|467' CHANGELOG.md | head -20

echo "---- inline registerCommand flags policy gate ----"
rg -n 'registerCommand' -A 40 src/core/extensions/loader.ts | rg -n 'flags|allowRegistration' | head -40

echo "---- schema.flags gate usage ----"
rg -n 'schema.flags' src/core/extensions/loader.ts

echo "---- doctor policy detail rendering null/undefined ----"
rg -n 'buildExtensionPolicyDetails|policy\?\.|policy &&' src/cli/commands/extension.ts | head -40

Length of output: 4590


@unbraind Full review complete on head 03700d1d14e07e02cb95d41af68e62960a1bbc02. I verified all three points from the repush notes directly against the code:

  • CHANGELOG.md public link: Line 7 now reads GH-467: isolated package/extension diagnostics — project-scoped doctor and smoke tests without global pm state leaking in ([Make package diagnostics easy to isolate from global pm extensions #467](https://github.com/unbraind/pm-cli/issues/467)) — pointing at the public issue rather than .agents/pm.
  • Inline registerCommand({ flags }) policy gate: In src/core/extensions/loader.ts, the inline flags branch (Line 2032) now calls assertExtensionCapability(this.#loadedExtension, "schema", "registerCommand flags") and gates on this.allowRegistration("schema.flags", "registerCommand flags", "schema") (Line 2033) — the exact same schema.flags gate used by registerFlags (Line 2160) and the importer/exporter metadata path (Line 2278).
  • Defensive doctor policy detail rendering: buildExtensionPolicyDetails (Line 460) now accepts policy: PmSettings["extensions"]["policy"] | null | undefined, handling null/undefined blocks without pulling in any new private core import.

No issues found — the fixes match what's described in the repush notes.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request implements isolated package and extension diagnostics by introducing the --isolated (alias --ignore-global) flag for the doctor command, resolving GH-467. This ensures hermetic project-scoped diagnostics by ignoring global registrations. The changes span CLI flag parsing, shell completions, help content, SDK contracts, and MCP schemas. Additionally, the extension API registration is refactored into a dedicated ExtensionApiRegistrar class to safely bind methods and protect internal fields. The review feedback correctly identifies a potential issue where partial policy objects could lead to undefined mode or trust_mode values, and suggests using nullish coalescing to fall back to safe defaults.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/cli/commands/extension.ts Resolved
@unbraind
unbraind force-pushed the package-doctor-isolated-sdk-contracts branch from 03700d1 to 8e4e75e Compare July 7, 2026 12:20
@unbraind

unbraind commented Jul 7, 2026

Copy link
Copy Markdown
Owner Author

Follow-up review request for head 8e4e75e.

Changes since the prior bot round restore CHANGELOG.md to the package-owned pm-changelog generated link so pnpm changelog:pm:check passes. Local verification on this head: pnpm changelog:pm:check, pnpm quality:static, and greptile review --agent (a1ea5074-0949-43ee-b721-8dac29265c4b) clean with confidence 5/5 and no comments.

@greptileai review
/gemini review
@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 7, 2026 •

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- CHANGELOG.md GH-467 entry ----"
rg -n '467' CHANGELOG.md | head -20

echo "---- changelog:pm:check script ----"
rg -n 'changelog:pm:check' package.json -A2 -B2

echo "---- pm-changelog generated link pattern elsewhere in changelog ----"
rg -n 'pm-changelog|GH-' CHANGELOG.md | head -30

Length of output: 7425


@unbraind Full review complete on head 8e4e75e4f49060ec7fd1f3ca39935748aebea146. I verified the CHANGELOG.md restoration directly:

  • CHANGELOG.md: Line 7 now reads GH-467: isolated package/extension diagnostics — project-scoped doctor and smoke tests without global pm state leaking in ([pm-6abs](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/features/pm-6abs.toon)), matching the package-owned pm-changelog generated link scheme (--item-url-base https://github.com/unbraind/pm-cli/blob/main/.agents/pm in the changelog:pm/changelog:pm:check scripts, package.json Lines 94-96) and consistent with every other entry in the file (e.g. Line 8, Line 12).

This change is isolated to CHANGELOG.md generation and doesn't touch the doctor isolation payloads, SDK contract exposure, or the extension API registrar refactor — all of which were already verified clean in the prior full-review rounds on this PR. No issues found on this head.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request implements isolated package and extension doctor diagnostics (GH-467). It introduces --isolated and --ignore-global flags to allow running doctor diagnostics hermetically, excluding global-scope registrations. The changes include updates to CLI command parsing, SDK contracts, MCP/tool schemas, and extensive regression testing. Additionally, the ExtensionApiRegistrar was refactored to use private fields for improved encapsulation. I have no feedback to provide.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Add project-scoped doctor isolation for package and extension diagnostics so temporary package smoke tests can skip machine-local global extension state. Thread the isolated/ignore-global flag through CLI help, completions, contracts, SDK tool schemas, and doctor metadata while preserving default behavior for existing callers.

Harden the extension API registrar follow-up from PR review by keeping registrar internals in ECMAScript private fields, binding the public API methods, and adding regression coverage that extension activators cannot observe legacy internal registry fields. Improve registerCommand validation traces with the offending override/run-handler values and metadata failure reasons, and guard malformed policy override names in doctor policy rendering.

Document the lane in pm-6abs with linked files, comments, coverage, static quality, temp-dir dogfood evidence, and review-feedback verification across related pm items pm-usfg, pm-w89s, pm-cbwg, pm-x6jf, and pm-qt5d.
@unbraind
unbraind force-pushed the package-doctor-isolated-sdk-contracts branch from 8e4e75e to 1ec1bcf Compare July 7, 2026 12:44
@unbraind

unbraind commented Jul 7, 2026

Copy link
Copy Markdown
Owner Author

Follow-up review request for head 1ec1bcf.

This repush addresses Gemini partial-policy fallback feedback: buildExtensionPolicyDetails now defaults missing mode / trust_mode scalar values when extensions.policy is partial, with regression coverage for mode-only and trust-mode-only policy objects. Local verification on this head: focused helper test passed, full extension command/loader slice passed (225 tests), pnpm quality:static, pnpm changelog:pm:check, full node scripts/run-tests.mjs coverage passed with 5451 tests and 100/100/100/100, and greptile review --agent (10622896-b744-439f-b113-a9995c15581e) was clean with confidence 5/5.

@greptileai review
/gemini review
@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 7, 2026 •

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- buildExtensionPolicyDetails mode/trust_mode defaults ----"
rg -n 'buildExtensionPolicyDetails' -A 60 src/cli/commands/extension.ts | head -120

echo "---- mode / trust_mode default constants ----"
rg -n 'trust_mode|mode\s*:' src/cli/commands/extension.ts | head -40

echo "---- regression tests for mode-only/trust-mode-only ----"
rg -n 'mode-only|trust-mode-only|trust_mode' tests/unit/extensions/extension-command.spec.ts | head -40

Length of output: 7179


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '480,560p' tests/unit/extensions/extension-command.spec.ts

Length of output: 2910


Verified. This matches the described fix precisely.

@unbraind Full review complete on head 1ec1bcff59b344bea1877bab24a636ae77dd2632. I confirmed the partial-policy fallback fix directly:

  • buildExtensionPolicyDetails defaults (src/cli/commands/extension.ts, Line 460): the function now accepts policy: PmSettings["extensions"]["policy"] | null | undefined, and at Line 468–469 defaults mode and trust_mode independently via safePolicy.mode ?? DEFAULT_EXTENSION_POLICY_DETAILS.mode / safePolicy.trust_mode ?? DEFAULT_EXTENSION_POLICY_DETAILS.trust_mode (both defaulting to "off", Lines 348–349). This correctly handles a partial policy object where only one of the two scalars is present, rather than assuming both are set together.
  • Regression coverage (tests/unit/extensions/extension-command.spec.ts, "covers extension helper fallback and lock edge branches" test, Lines 494–533): explicitly exercises both the mode-only case ({ mode: "enforce" } → mode: "enforce", trust_mode: "off") and the trust-mode-only case ({ trust_mode: "warn" } → mode: "off", trust_mode: "warn"), confirming each scalar defaults independently rather than falling back together.

This is isolated to the policy-detail rendering helper and doesn't touch the doctor isolation payloads, SDK contract exposure, or the registrar refactor — all previously verified clean on earlier heads of this PR. No issues found on this head.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request implements isolated package and extension diagnostics (GH-467) by introducing the --isolated (alias --ignore-global) flag to the doctor commands. This allows running hermetic project-scoped diagnostics without global extension registrations leaking in. The changes span CLI options, shell completions, help content, SDK contracts, and MCP schemas. Additionally, the extension loader is refactored to use a private-field-backed ExtensionApiRegistrar class to safely bind registration methods and hide internal fields from extension activators, and inline command flag registrations are now subject to schema.flags policy enforcement. Comprehensive unit and integration tests have been added to verify the isolation behavior, private field encapsulation, and policy enforcement. I have no feedback to provide as there are no review comments.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@unbraind
unbraind merged commit 4469b47 into main Jul 7, 2026
24 checks passed
@unbraind
unbraind deleted the package-doctor-isolated-sdk-contracts branch July 7, 2026 12:55
This was referenced Jul 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant