Skip to content

fix(plugins): harden imported extension dependencies - #329

Merged
vastsa merged 3 commits into
mainfrom
fix/pr300-followup
Sep 13, 2026
Merged

fix(plugins): harden imported extension dependencies#329
vastsa merged 3 commits into
mainfrom
fix/pr300-followup

Conversation

@vastsa

@vastsa vastsa commented Sep 13, 2026

Copy link
Copy Markdown
Owner

Follow-up to merged PR #300.

Review findings fixed

  • Validate production, optional, dev, peer, override, nested lockfile, and lockfile path sources.
  • Run real npm through a loopback registry-only proxy; disable git resolution and lifecycle scripts; isolate npm config/cache.
  • Kill dependency process trees on timeout and clean partial node_modules/cache/lockfiles on failure.
  • Make imported plugin directories atomic and plugin ids unique across repeated imports.
  • Exclude credential/repository metadata files from copied sources.
  • Split npm installer/proxy responsibilities into focused modules.
  • Synchronize EN/ZH docs, E2E expectations, README prerequisites, and add ADR 0244.

Validation

  • pnpm build:js
  • pnpm lint
  • pnpm docs:check (77 pairs)
  • pnpm -r --if-present test (1603 passed)
  • cargo fmt --check
  • cargo test -p host-core --locked (378 passed)
  • cargo clippy -p host-core --all-targets --locked
  • pnpm test:e2e (18/18 passed; 2 live-model cases skipped without PI_DESKTOP_TEST_API_KEY)
  • Real registry install with left-pad passed and removed temporary cache.

Copilot AI 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.

🟡 Changes recommended

Critical dependency-validation and credential-boundary issues remain unresolved.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

This PR hardens imported extension dependency installation and source copying with registry-only npm execution, cleanup, unique plugin IDs, sensitive-file filtering, tests, and documentation updates.

Changes:

  • Adds isolated npm installation, validation, timeout handling, and cleanup.
  • Makes imported plugins atomic and uniquely identified.
  • Updates tests, E2E expectations, English/Chinese documentation, and ADR 0244.
File summaries
File Reviewed changes
README.zh-CN.md Documents npm prerequisites.
README.md Documents npm prerequisites and registry-only behavior.
docs/zh-CN/spec/07-plugins/16-trusted-extensions.md Updates Chinese import and dependency behavior; ADR 0244 status needs synchronization (Nit, 1 vote).
docs/zh-CN/spec/07-plugins/06-plugin-packaging.md Documents the import exception.
docs/zh-CN/spec/06-delivery/04-e2e-test-plan.md Updates dependency-install E2E expectations.
docs/zh-CN/plugin-development.md Documents dependency installation; restore the omitted supported-members continuation (Nit, 1 vote).
docs/spec/07-plugins/16-trusted-extensions.md Defines the hardened boundary; remove the duplicate heading (Nit, 3 votes) and synchronize the Chinese ADR status (Nit, 1 vote).
docs/spec/07-plugins/06-plugin-packaging.md Documents the import exception.
docs/spec/06-delivery/04-e2e-test-plan.md Updates E2E expectations.
docs/plugin-development.md Documents dependency installation.
docs/adr/README.md Registers ADR 0244; add its Chinese index row (Nit, 2 votes).
docs/adr/0244-imported-extension-dependency-boundary.md Records the dependency-boundary decision.
docs/adr/0215-agent-extensions-as-plugin-contribution.md Clarifies validation scope.
apps/desktop/test/agent-extensions.test.mjs Adds boundary and cleanup tests; remove the unused rmSync import (Nit, 1 vote).
apps/desktop/electron/main/npm-registry-proxy.ts Implements registry-only loopback proxying.
apps/desktop/electron/main/npm-installer.ts Implements validation and isolated installation; address npm v1 requires maps (Critical, 2 votes) and pre-resolution transitive non-registry dependencies (Critical, 1 vote).
apps/desktop/electron/main/agent-extensions.ts Implements atomic imports and unique IDs; expand credential filtering for .key, id_ed25519, .crt, and .cer files (Critical, 3 votes).
Review details

Suppressed comments (4)

apps/desktop/test/agent-extensions.test.mjs:4

  • rmSync is imported but never referenced anywhere in this test file. Remove the dead import; otherwise a no-unused-import lint configuration will reject the test.
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";

docs/adr/README.md:266

  • The new row duplicates the active-turn-steering entry that already exists on the next line. Remove the duplicate index entry.
| active-turn-steering | Bind Composer steering to the active durable turn | Accepted (active-turn-steering; issue #164) |

docs/spec/07-plugins/16-trusted-extensions.md:3

  • Adding ADR 0244 to the English status requires the corresponding Chinese status line to be updated as well, but docs/zh-CN/spec/07-plugins/16-trusted-extensions.md still lists only ADR 0214/0215. Please synchronize that counterpart so the two specification pages do not describe different decision sets.
> Status: Implemented v1.1 (D387 / D388, ADR 0214 / ADR 0215 / ADR 0244); implementation notes are marked "v1 note"

docs/zh-CN/plugin-development.md:638

  • The Chinese page drops the continuation of the preceding “supported members” bullet, so it now ends at 在插件行 and immediately starts the next bullet. Restore 的详情里报告,绝不抛出。 to keep this locale complete and semantically aligned with the English documentation.
  生成的插件。若目录声明了生产或可选依赖,PI-Desktop 会先运行
  • Files reviewed: 17/17 changed files
  • Comments generated: 5
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +268 to +271
IMPORT_SENSITIVE_FILE_NAMES.has(name) ||
name.startsWith(".env") ||
name.startsWith("id_rsa") ||
/\.(pem|p12|pfx|keystore)$/.test(name)
Comment on lines +30 to +35
const LOCKFILE_DEPENDENCY_FIELDS = new Set([
"dependencies",
"optionalDependencies",
"devDependencies",
"peerDependencies",
]);
Comment on lines +374 to +376
const resolvedLockfiles = sanitizeDependencyLockfiles(pluginDir);
if (resolvedLockfiles.removedUnsafe) {
return failed("npm dependency resolution produced a non-registry lockfile source");
Comment thread docs/adr/README.md
| 0241 | Ship the file view as a vendored, updatable plugin | Accepted (supersedes ADR 0105; issue #304) |
| 0242 | Delta-only coalesced streaming updates | Accepted (amends 0127 / 0130 / 0149 / 0153; issue #299) |
| 0243 | Skill market public-HTTPS catalog fetch | Accepted (amends 0009; issue #287 / PR #290) |
| 0244 | Bound dependency installation for imported extensions | Accepted |
the user's credentials and proxy settings. Importing a package does not promise
that every third-party extension dependency can execute.

## 4. Loading and runtime
@vastsa
vastsa merged commit bce6542 into main Sep 13, 2026
5 checks passed
@vastsa
vastsa deleted the fix/pr300-followup branch September 13, 2026 20:34
@vastsa

vastsa commented Sep 13, 2026

Copy link
Copy Markdown
Owner Author

Merged as bce6542c.

Follow-up review fixes included:

  • registry-only loopback proxy for npm HTTP/HTTPS traffic; git resolver, lifecycle scripts, user/global config, and shared cache are isolated
  • validation for all npm dependency fields, overrides, lockfile sources/paths, and nested dependency specs
  • process-tree timeout cleanup and best-effort removal of partial installs
  • atomic import destination creation, unique repeated-import ids, and credential/repository metadata filtering
  • installer/proxy split into focused modules plus ADR 0244 and synchronized EN/ZH documentation

Validation on the integrated main commit bce6542c: pnpm build:js, pnpm lint, pnpm docs:check, 1603 JS tests, Rust fmt/tests/clippy, and pnpm test:e2e (18/18 passed; 2 live-model cases skipped because PI_DESKTOP_TEST_API_KEY was unavailable). A real registry install also passed and cleaned its temporary cache.

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.

2 participants