41: Add npm run local:install script to update and install all skills and extensions #44
No reviewers
Labels
No labels
bug
chore
documentation
enhancement
feature
ready
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
david/pi-extensions-and-skills!44
Loading…
Reference in a new issue
No description provided.
Delete branch "feature/issue-41/add-npm-run-local-install-script-to-update-and-ins"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
41: Add npm run local:install script to update and install all skills and extensions
Implements 41.
Generated in 20m 20s.
Review findings
Node v22, no root lint/build configs,
node_modulespresent. Now let me apply the fixes toscripts/local-install.mjs:Let me verify the edits landed correctly:Script changes are in. Now updatepackage.json(test wiring) and the README (project-scope dedupe wording):Now let me rewrite the test file with coverage for the new behavior — orchestration tests (preflight failures,dedupeAndRegister,main) plus the new pure-helper cases:Now let me run the gates:All 30 tests pass. Let me check the full run for warnings and verify no stray output issues:Let me run the full gate set (npm testvia the new script, plus a dry-run install to confirm deps resolve) and check the final diff:All gates green. One small polish —findMatchingPackageEntries's doc comment still says "global settings" but it now serves both scopes:Let me do a final review of the complete diff to confirm coherence:All fixes are applied, gates are green, and the working tree contains only the four expected files (no.pi-loopchanges). Here is the annotated findings document.Review Findings — 41
Summary
Remediated in a single pass. Fixed the destructive-dedupe edge case (substring fast-path replaced with an end-anchored boundary regex), the two
parseGitRemotegaps (scp-like with port, scheme-less slash form), the.envinline-comment parsing, the Unix-onlycommandAvailable(addedwhereon Windows — deliberately not the suggested--versionprobe, see Friction), the missingtestscript wiring, and extended dedupe to the project-scope settings file (pi remove -l). Added the previously-missing orchestration coverage: 13 new tests (30 total) exercisepreflightfailure ordering/messages,dedupeAndRegisteragainst a tempsettings.jsonwithpi/git/fj/rg/npmshims on PATH, and themainhappy path. Gates:node --checkboth files PASS,node --test scripts/local-install.test.mjsPASS (30/30),npm testPASS (30/30),npm install --dry-runPASS. The one unresolved finding is the commit-message amendment (c723e5e), which is not actionable in this stage because the pipeline forbids commit/history operations; it must be amended by a human before merge.Critical
High
scripts/local-install.mjs:361 — The core behavior of the feature (preflight ordering and fail-fast messages,
dedupeAndRegisterreading a settings file and callingpi remove/pi install,mainorchestration) has zero test coverage.local-install.test.mjsonly tests the pure helpers; the riskiest part of the script (it mutates global~/.pi/agent/settings.json, runsgit pull, andnpm install) is untested. Suggested fix: add tests that create a tempsettings.jsonplus stubpi/git/fjshims on PATH (or injectable commands) and assert (a)dedupeAndRegisterremoves URL entries and registers the local path exactly once, and (b)preflightaborts with the expected message/order for each failure (dirty tree, non-main, missingFORGEJO_TOKEN, missingrg).scripts/local-install.mjs:101 —
source.includes(REPO_IDENTITY)is a substring match, sosourceMatchesRepo("https://git.excelera.net/david/pi-extensions-and-skills-extra")and…-backupboth returntrue(verified). BecausededupeAndRegisterthen runspi remove <source>on every match, an unrelated package whose URL/path merely contains this repo's identity as a prefix would be removed from the user's pi settings. Suggested fix: drop the substring fast-path and decide only fromisThisRepo(parseGitRemote(source)), or constrain the fast-path with a boundary regex (identity followed by end-of-string /.git/@ref/#refonly).scripts/local-install.mjs:57-77 —
parseGitRemotemis-handles two valid git URL forms, so a real URL entry can be missed by the dedupe (leaving duplicate skills/extensions after registration): scp-like with a port (git@host:2222:owner/repoparses asowner: "2222:david") and the scheme-less slash form (git@git.excelera.net/david/pi-extensions-and-skillsreturnsnull, verified). Suggested fix: handlehost:portin the scp-like branch and add thegit@host/owner/repoform (or document the accepted forms and assert them in tests).Low
AGENTS.md:19-22 — Commit
c723e5euses41: Add npm run local:install …but AGENTS.md specifiesissue-<N>: <summary>(repo history is mixed, but this change should follow the documented format). Suggested fix: amend the commit message toissue-41: Add npm run local:install script to update and install all skills and extensions.scripts/local-install.mjs:117-135 —
parseEnvFilekeeps inline comments in values (DATABASE_URL=postgres://x # dev→"postgres://x # dev"), so preflight passes and the postgres extension fails later with a confusing error. Suggested fix: strip an unquoted trailing#…comment when parsing, and add a test for it.scripts/local-install.mjs:187-192 —
commandAvailableshells out tosh -c, which is Unix-only; pi itself is cross-platform (Windows users install viapi.cmd), so thepi/rg/fjpreflight checks would fail there. Suggested fix: usespawnSync(cmd, ["--version"])directly (no shell) or otherwise abstract the PATH check.package.json:22-24 — The new test file has no wiring: there is no
testscript, sonode --test scripts/local-install.test.mjsis not part of any automated gate. Suggested fix: add"test": "node --test scripts/local-install.test.mjs"toscripts.scripts/local-install.mjs:315-321 — Dedupe reads only global
~/.pi/agent/settings.json; if the repo was ever installed project-locally (pi install -l→<project>/.pi/settings.json), that stale URL entry is not removed, contradicting the README claim "any existing settings entry that references this repo's URL … is removed". Suggested fix: also scan the project-scope settings file (or soften the README wording to "global settings").Documentation
Updated files: