@howlil/ez-agents 3.5.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +735 -537
- package/agents/ez-architect-agent.md +267 -0
- package/agents/ez-backend-agent.md +303 -0
- package/agents/ez-chief-strategist.md +271 -0
- package/agents/ez-codebase-mapper.md +770 -770
- package/agents/ez-context-manager.md +319 -0
- package/agents/ez-debugger.md +1255 -1255
- package/agents/ez-design-expert.md +347 -0
- package/agents/ez-devops-agent.md +331 -0
- package/agents/ez-executor.md +487 -487
- package/agents/ez-frontend-agent.md +322 -0
- package/agents/ez-phase-researcher.md +553 -553
- package/agents/ez-planner.md +1307 -1307
- package/agents/ez-product-engineer.md +435 -0
- package/agents/ez-project-researcher.md +629 -629
- package/agents/ez-qa-agent.md +320 -0
- package/agents/ez-release-agent.md +333 -333
- package/agents/ez-requirements-agent.md +377 -377
- package/agents/ez-roadmapper.md +650 -650
- package/agents/ez-technical-writer.md +551 -0
- package/agents/ez-ux-expert.md +393 -0
- package/agents/ez-verifier.md +579 -579
- package/bin/guards/autonomy-guard.cjs +346 -0
- package/bin/guards/context-budget-guard.cjs +278 -0
- package/bin/guards/hallucination-guard.cjs +380 -0
- package/bin/guards/hidden-state-guard.cjs +182 -0
- package/bin/guards/team-overhead-guard.cjs +266 -0
- package/bin/guards/tool-sprawl-guard.cjs +271 -0
- package/bin/lib/analytics/analytics-collector.cjs +86 -0
- package/bin/lib/analytics/analytics-reporter.cjs +130 -0
- package/bin/lib/analytics/cohort-analyzer.cjs +138 -0
- package/bin/lib/analytics/funnel-analyzer.cjs +147 -0
- package/bin/lib/analytics/nps-tracker.cjs +147 -0
- package/bin/lib/archetype-detector.cjs +289 -0
- package/bin/lib/assistant-adapter.cjs +361 -0
- package/bin/lib/audit-exec.cjs +175 -0
- package/bin/lib/auth.cjs +176 -0
- package/bin/lib/backup-service.cjs +422 -0
- package/bin/lib/bdd-validator.cjs +622 -0
- package/bin/lib/business-flow-mapper.cjs +429 -0
- package/bin/lib/circuit-breaker.cjs +276 -0
- package/bin/lib/code-complexity-analyzer.cjs +360 -0
- package/bin/lib/codebase-analyzer.cjs +241 -0
- package/bin/lib/commands.cjs +691 -0
- package/bin/lib/config.cjs +236 -0
- package/bin/lib/constraint-extractor.cjs +526 -0
- package/bin/lib/content-scanner.cjs +238 -0
- package/bin/lib/context-cache.cjs +154 -0
- package/bin/lib/context-compressor.cjs +102 -0
- package/bin/lib/context-deduplicator.cjs +105 -0
- package/bin/lib/context-errors.cjs +78 -0
- package/bin/lib/context-manager.cjs +338 -0
- package/bin/lib/context-metadata-tracker.cjs +140 -0
- package/bin/lib/context-relevance-scorer.cjs +99 -0
- package/bin/lib/core.cjs +507 -0
- package/bin/lib/cost-alerts.cjs +174 -0
- package/bin/lib/cost-tracker.cjs +275 -0
- package/bin/lib/crash-recovery.cjs +220 -0
- package/bin/lib/dependency-graph.cjs +319 -0
- package/bin/lib/deploy/deploy-audit-log.cjs +76 -0
- package/bin/lib/deploy/deploy-detector.cjs +69 -0
- package/bin/lib/deploy/deploy-env-manager.cjs +109 -0
- package/bin/lib/deploy/deploy-health-check.cjs +88 -0
- package/bin/lib/deploy/deploy-pre-flight.cjs +57 -0
- package/bin/lib/deploy/deploy-rollback.cjs +72 -0
- package/bin/lib/deploy/deploy-runner.cjs +97 -0
- package/bin/lib/deploy/deploy-status.cjs +74 -0
- package/bin/lib/discussion-synthesizer.cjs +439 -0
- package/bin/lib/error-cache.cjs +114 -0
- package/bin/lib/error-registry.cjs +177 -0
- package/bin/lib/file-access.cjs +207 -0
- package/bin/lib/file-lock.cjs +236 -0
- package/bin/lib/finops/budget-enforcer.cjs +126 -0
- package/bin/lib/finops/cost-reporter.cjs +132 -0
- package/bin/lib/finops/finops-analyzer.cjs +112 -0
- package/bin/lib/finops/spot-manager.cjs +118 -0
- package/bin/lib/framework-detector.cjs +396 -0
- package/bin/lib/frontmatter.cjs +313 -0
- package/bin/lib/fs-utils.cjs +153 -0
- package/bin/lib/gate-executor.cjs +272 -0
- package/bin/lib/gates/README.md +374 -0
- package/bin/lib/gates/gate-01-requirement.cjs +303 -0
- package/bin/lib/gates/gate-02-architecture.cjs +555 -0
- package/bin/lib/gates/gate-03-code.cjs +635 -0
- package/bin/lib/gates/gate-04-security.cjs +829 -0
- package/bin/lib/git-errors.cjs +83 -0
- package/bin/lib/git-utils.cjs +321 -0
- package/bin/lib/git-workflow-engine.cjs +1157 -0
- package/bin/lib/health-check.cjs +227 -0
- package/bin/lib/index.cjs +279 -0
- package/bin/lib/init.cjs +725 -0
- package/bin/lib/lock-logger.cjs +194 -0
- package/bin/lib/lock-state.cjs +263 -0
- package/bin/lib/lockfile-validator.cjs +227 -0
- package/bin/lib/log-rotation.cjs +71 -0
- package/bin/lib/logger.cjs +125 -0
- package/bin/lib/memory-compression.cjs +256 -0
- package/bin/lib/milestone.cjs +247 -0
- package/bin/lib/model-provider.cjs +241 -0
- package/bin/lib/package-manager-detector.cjs +203 -0
- package/bin/lib/package-manager-executor.cjs +385 -0
- package/bin/lib/package-manager-service.cjs +216 -0
- package/bin/lib/perf/api-monitor.cjs +88 -0
- package/bin/lib/perf/db-optimizer.cjs +78 -0
- package/bin/lib/perf/frontend-performance.cjs +56 -0
- package/bin/lib/perf/perf-analyzer.cjs +77 -0
- package/bin/lib/perf/perf-baseline.cjs +102 -0
- package/bin/lib/perf/perf-reporter.cjs +117 -0
- package/bin/lib/perf/regression-detector.cjs +92 -0
- package/bin/lib/phase.cjs +963 -0
- package/bin/lib/planning-write.cjs +123 -0
- package/bin/lib/project-reporter.cjs +565 -0
- package/bin/lib/quality-gate.cjs +332 -0
- package/bin/lib/quality-metrics.cjs +324 -0
- package/bin/lib/recovery-manager.cjs +98 -0
- package/bin/lib/release-validator.cjs +617 -0
- package/bin/lib/retry.cjs +119 -0
- package/bin/lib/roadmap.cjs +309 -0
- package/bin/lib/safe-exec.cjs +173 -0
- package/bin/lib/safe-path.cjs +130 -0
- package/bin/lib/security-errors.cjs +62 -0
- package/bin/lib/session-chain.cjs +304 -0
- package/bin/lib/session-errors.cjs +81 -0
- package/bin/lib/session-export.cjs +251 -0
- package/bin/lib/session-import.cjs +262 -0
- package/bin/lib/session-manager.cjs +280 -0
- package/bin/lib/skill-context.cjs +148 -0
- package/bin/lib/skill-matcher.cjs +236 -0
- package/bin/lib/skill-registry.cjs +360 -0
- package/bin/lib/skill-resolver.cjs +449 -0
- package/bin/lib/skill-triggers.cjs +90 -0
- package/bin/lib/skill-validator.cjs +270 -0
- package/bin/lib/skill-versioning.cjs +355 -0
- package/bin/lib/stack-detector.cjs +399 -0
- package/bin/lib/state.cjs +736 -0
- package/bin/lib/tech-debt-analyzer.cjs +309 -0
- package/bin/lib/temp-file.cjs +239 -0
- package/bin/lib/template.cjs +223 -0
- package/bin/lib/test-file-lock.cjs +112 -0
- package/bin/lib/test-graceful.cjs +93 -0
- package/bin/lib/test-logger.cjs +60 -0
- package/bin/lib/test-safe-exec.cjs +38 -0
- package/bin/lib/test-safe-path.cjs +33 -0
- package/bin/lib/test-temp-file.cjs +125 -0
- package/bin/lib/tier-manager.cjs +428 -0
- package/bin/lib/timeout-exec.cjs +63 -0
- package/bin/lib/tradeoff-analyzer.cjs +284 -0
- package/bin/lib/url-fetch.cjs +170 -0
- package/bin/lib/verify.cjs +863 -0
- package/bin/update.js +217 -214
- package/commands/deploy.cjs +53 -0
- package/commands/ez/add-tests.md +41 -41
- package/commands/ez/audit-milestone.md +36 -36
- package/commands/ez/complete-milestone.md +136 -136
- package/commands/ez/discuss-phase.md +90 -90
- package/commands/ez/execute-phase.md +52 -52
- package/commands/ez/help.md +22 -22
- package/commands/ez/map-codebase.md +71 -71
- package/commands/ez/new-milestone.md +44 -44
- package/commands/ez/new-project.md +51 -42
- package/commands/ez/plan-phase.md +53 -53
- package/commands/ez/progress.md +36 -36
- package/commands/ez/quick.md +45 -45
- package/commands/ez/resume-work.md +40 -40
- package/commands/ez/run-phase.md +580 -0
- package/commands/ez/settings.md +36 -36
- package/commands/ez/update.md +37 -37
- package/commands/ez/verify-work.md +402 -38
- package/commands/health-check.cjs +44 -0
- package/commands/rollback.cjs +47 -0
- package/ez-agents/bin/ez-tools.cjs +599 -2
- package/ez-agents/bin/guards/autonomy-guard.cjs +346 -0
- package/ez-agents/bin/guards/context-budget-guard.cjs +247 -0
- package/ez-agents/bin/guards/hallucination-guard.cjs +271 -0
- package/ez-agents/bin/guards/hidden-state-guard.cjs +182 -0
- package/ez-agents/bin/guards/team-overhead-guard.cjs +266 -0
- package/ez-agents/bin/guards/tool-sprawl-guard.cjs +271 -0
- package/ez-agents/bin/lib/analytics/analytics-collector.cjs +86 -0
- package/ez-agents/bin/lib/analytics/analytics-reporter.cjs +130 -0
- package/ez-agents/bin/lib/analytics/cohort-analyzer.cjs +138 -0
- package/ez-agents/bin/lib/analytics/funnel-analyzer.cjs +147 -0
- package/ez-agents/bin/lib/analytics/nps-tracker.cjs +147 -0
- package/ez-agents/bin/lib/archetype-detector.cjs +289 -0
- package/ez-agents/bin/lib/audit-exec.cjs +166 -167
- package/ez-agents/bin/lib/auth.cjs +176 -176
- package/ez-agents/bin/lib/backup-service.cjs +422 -0
- package/ez-agents/bin/lib/bdd-validator.cjs +622 -622
- package/ez-agents/bin/lib/business-flow-mapper.cjs +429 -0
- package/ez-agents/bin/lib/code-complexity-analyzer.cjs +360 -0
- package/ez-agents/bin/lib/codebase-analyzer.cjs +241 -0
- package/ez-agents/bin/lib/commands.cjs +685 -685
- package/ez-agents/bin/lib/config.cjs +41 -1
- package/ez-agents/bin/lib/constraint-extractor.cjs +526 -0
- package/ez-agents/bin/lib/content-scanner.cjs +238 -238
- package/ez-agents/bin/lib/context-cache.cjs +154 -154
- package/ez-agents/bin/lib/context-errors.cjs +71 -71
- package/ez-agents/bin/lib/context-manager.cjs +220 -220
- package/ez-agents/bin/lib/core.cjs +507 -512
- package/ez-agents/bin/lib/cost-tracker.cjs +243 -0
- package/ez-agents/bin/lib/crash-recovery.cjs +172 -0
- package/ez-agents/bin/lib/dependency-graph.cjs +319 -0
- package/ez-agents/bin/lib/deploy/deploy-audit-log.cjs +76 -0
- package/ez-agents/bin/lib/deploy/deploy-detector.cjs +69 -0
- package/ez-agents/bin/lib/deploy/deploy-env-manager.cjs +109 -0
- package/ez-agents/bin/lib/deploy/deploy-health-check.cjs +88 -0
- package/ez-agents/bin/lib/deploy/deploy-pre-flight.cjs +57 -0
- package/ez-agents/bin/lib/deploy/deploy-rollback.cjs +72 -0
- package/ez-agents/bin/lib/deploy/deploy-runner.cjs +97 -0
- package/ez-agents/bin/lib/deploy/deploy-status.cjs +74 -0
- package/ez-agents/bin/lib/file-access.cjs +207 -207
- package/ez-agents/bin/lib/finops/budget-enforcer.cjs +126 -0
- package/ez-agents/bin/lib/finops/cost-reporter.cjs +132 -0
- package/ez-agents/bin/lib/finops/finops-analyzer.cjs +112 -0
- package/ez-agents/bin/lib/finops/spot-manager.cjs +118 -0
- package/ez-agents/bin/lib/framework-detector.cjs +396 -0
- package/ez-agents/bin/lib/frontmatter.cjs +3 -1
- package/ez-agents/bin/lib/gates/README.md +374 -0
- package/ez-agents/bin/lib/gates/gate-01-requirement.cjs +303 -0
- package/ez-agents/bin/lib/gates/gate-02-architecture.cjs +555 -0
- package/ez-agents/bin/lib/gates/gate-03-code.cjs +635 -0
- package/ez-agents/bin/lib/gates/gate-04-security.cjs +829 -0
- package/ez-agents/bin/lib/git-errors.cjs +83 -83
- package/ez-agents/bin/lib/git-utils.cjs +321 -321
- package/ez-agents/bin/lib/git-workflow-engine.cjs +1157 -1157
- package/ez-agents/bin/lib/health-check.cjs +162 -162
- package/ez-agents/bin/lib/index.cjs +2 -8
- package/ez-agents/bin/lib/init.cjs +0 -2
- package/ez-agents/bin/lib/lockfile-validator.cjs +227 -227
- package/ez-agents/bin/lib/log-rotation.cjs +71 -0
- package/ez-agents/bin/lib/logger.cjs +22 -47
- package/ez-agents/bin/lib/memory-compression.cjs +256 -256
- package/ez-agents/bin/lib/package-manager-detector.cjs +203 -203
- package/ez-agents/bin/lib/package-manager-executor.cjs +385 -385
- package/ez-agents/bin/lib/package-manager-service.cjs +216 -216
- package/ez-agents/bin/lib/perf/api-monitor.cjs +88 -0
- package/ez-agents/bin/lib/perf/db-optimizer.cjs +78 -0
- package/ez-agents/bin/lib/perf/frontend-performance.cjs +56 -0
- package/ez-agents/bin/lib/perf/perf-analyzer.cjs +77 -0
- package/ez-agents/bin/lib/perf/perf-baseline.cjs +102 -0
- package/ez-agents/bin/lib/perf/perf-reporter.cjs +117 -0
- package/ez-agents/bin/lib/perf/regression-detector.cjs +92 -0
- package/ez-agents/bin/lib/project-reporter.cjs +502 -0
- package/ez-agents/bin/lib/quality-gate.cjs +332 -0
- package/ez-agents/bin/lib/recovery-manager.cjs +98 -0
- package/ez-agents/bin/lib/release-validator.cjs +617 -614
- package/ez-agents/bin/lib/security-errors.cjs +62 -0
- package/ez-agents/bin/lib/session-chain.cjs +304 -304
- package/ez-agents/bin/lib/session-errors.cjs +81 -81
- package/ez-agents/bin/lib/session-export.cjs +251 -251
- package/ez-agents/bin/lib/session-import.cjs +262 -262
- package/ez-agents/bin/lib/session-manager.cjs +280 -280
- package/ez-agents/bin/lib/skill-context.cjs +148 -0
- package/ez-agents/bin/lib/skill-matcher.cjs +236 -0
- package/ez-agents/bin/lib/skill-registry.cjs +341 -0
- package/ez-agents/bin/lib/skill-resolver.cjs +449 -0
- package/ez-agents/bin/lib/skill-triggers.cjs +90 -0
- package/ez-agents/bin/lib/skill-validator.cjs +270 -0
- package/ez-agents/bin/lib/skill-versioning.cjs +355 -0
- package/ez-agents/bin/lib/stack-detector.cjs +399 -0
- package/ez-agents/bin/lib/tech-debt-analyzer.cjs +309 -0
- package/ez-agents/bin/lib/tier-manager.cjs +428 -428
- package/ez-agents/bin/lib/tradeoff-analyzer.cjs +284 -0
- package/ez-agents/bin/lib/url-fetch.cjs +170 -170
- package/ez-agents/bin/lib/verify.cjs +863 -863
- package/ez-agents/references/decimal-phase-calculation.md +65 -65
- package/ez-agents/references/git-integration.md +248 -248
- package/ez-agents/references/git-planning-commit.md +38 -38
- package/ez-agents/references/metrics-schema.md +118 -118
- package/ez-agents/references/model-profile-resolution.md +34 -34
- package/ez-agents/references/model-profiles.md +93 -93
- package/ez-agents/references/phase-argument-parsing.md +61 -61
- package/ez-agents/references/planning-config.md +340 -340
- package/ez-agents/references/tier-strategy.md +103 -103
- package/ez-agents/references/ui-brand.md +160 -160
- package/ez-agents/references/verification-patterns.md +612 -612
- package/ez-agents/templates/DEBUG.md +164 -164
- package/ez-agents/templates/UAT.md +247 -247
- package/ez-agents/templates/agent-output-format.md +404 -0
- package/ez-agents/templates/bdd-feature.md +173 -173
- package/ez-agents/templates/codebase/architecture.md +255 -255
- package/ez-agents/templates/codebase/structure.md +285 -285
- package/ez-agents/templates/copilot-instructions.md +7 -7
- package/ez-agents/templates/debug-subagent-prompt.md +91 -91
- package/ez-agents/templates/discovery.md +146 -146
- package/ez-agents/templates/discussion.md +68 -68
- package/ez-agents/templates/handoff-protocol.md +294 -0
- package/ez-agents/templates/incident-runbook.md +205 -205
- package/ez-agents/templates/mode-workflow-templates.md +301 -0
- package/ez-agents/templates/phase-prompt.md +610 -610
- package/ez-agents/templates/planner-subagent-prompt.md +117 -117
- package/ez-agents/templates/project.md +184 -184
- package/ez-agents/templates/release-checklist.md +136 -133
- package/ez-agents/templates/research.md +552 -552
- package/ez-agents/templates/rollback-plan.md +201 -201
- package/ez-agents/templates/security-user-setup.md +244 -0
- package/ez-agents/templates/skill-validation-rules.md +476 -0
- package/ez-agents/templates/state.md +180 -176
- package/ez-agents/templates/summary-complex.md +59 -59
- package/ez-agents/tests/gates/gate-01-02.test.cjs +812 -0
- package/ez-agents/tests/gates/gate-03-04.test.cjs +762 -0
- package/ez-agents/tests/gates/gate-05-validator.test.cjs +145 -0
- package/ez-agents/tests/gates/gate-06-docs-validator.test.cjs +244 -0
- package/ez-agents/tests/gates/gate-07-release-validator.test.cjs +219 -0
- package/ez-agents/tests/guards/context-budget-guard.test.cjs +145 -0
- package/ez-agents/tests/guards/edge-case-guards.test.cjs +238 -0
- package/ez-agents/tests/guards/hallucination-guard.test.cjs +124 -0
- package/ez-agents/workflows/audit-milestone.md +1 -1
- package/ez-agents/workflows/autonomous.md +844 -844
- package/ez-agents/workflows/complete-milestone.md +1 -1
- package/ez-agents/workflows/discuss-phase.md +1 -1
- package/ez-agents/workflows/execute-phase.md +124 -3
- package/ez-agents/workflows/help.md +42 -181
- package/ez-agents/workflows/hotfix.md +291 -291
- package/ez-agents/workflows/new-milestone.md +713 -713
- package/ez-agents/workflows/new-project.md +1089 -1107
- package/ez-agents/workflows/plan-phase.md +0 -40
- package/ez-agents/workflows/release.md +253 -253
- package/ez-agents/workflows/resume-session.md +215 -215
- package/ez-agents/workflows/run-phase.md +531 -0
- package/ez-agents/workflows/settings.md +2 -35
- package/hooks/dist/ez-check-update.js +81 -81
- package/hooks/dist/ez-context-monitor.js +148 -141
- package/hooks/dist/ez-statusline.js +115 -115
- package/package.json +78 -71
- package/scripts/fix-qwen-installation.js +144 -144
- package/agents/ez-integration-checker.md +0 -443
- package/agents/ez-nyquist-auditor.md +0 -176
- package/agents/ez-observer-agent.md +0 -260
- package/agents/ez-plan-checker.md +0 -706
- package/agents/ez-research-synthesizer.md +0 -247
- package/agents/ez-scrum-master-agent.md +0 -242
- package/agents/ez-tech-lead-agent.md +0 -267
- package/agents/ez-ui-auditor.md +0 -439
- package/agents/ez-ui-checker.md +0 -300
- package/agents/ez-ui-researcher.md +0 -353
- package/commands/ez/add-phase.md +0 -43
- package/commands/ez/add-todo.md +0 -47
- package/commands/ez/arch-review.md +0 -102
- package/commands/ez/auth.md +0 -87
- package/commands/ez/autonomous.md +0 -41
- package/commands/ez/check-todos.md +0 -45
- package/commands/ez/cleanup.md +0 -18
- package/commands/ez/debug.md +0 -168
- package/commands/ez/export-session.md +0 -79
- package/commands/ez/gather-requirements.md +0 -117
- package/commands/ez/git-workflow.md +0 -72
- package/commands/ez/health.md +0 -22
- package/commands/ez/hotfix.md +0 -120
- package/commands/ez/import-session.md +0 -82
- package/commands/ez/insert-phase.md +0 -32
- package/commands/ez/join-discord.md +0 -18
- package/commands/ez/list-phase-assumptions.md +0 -46
- package/commands/ez/list-sessions.md +0 -96
- package/commands/ez/package-manager.md +0 -316
- package/commands/ez/pause-work.md +0 -38
- package/commands/ez/plan-milestone-gaps.md +0 -34
- package/commands/ez/preflight.md +0 -79
- package/commands/ez/reapply-patches.md +0 -124
- package/commands/ez/release.md +0 -153
- package/commands/ez/remove-phase.md +0 -31
- package/commands/ez/research-phase.md +0 -190
- package/commands/ez/resume.md +0 -107
- package/commands/ez/set-profile.md +0 -34
- package/commands/ez/standup.md +0 -85
- package/commands/ez/stats.md +0 -18
- package/commands/ez/ui-phase.md +0 -34
- package/commands/ez/ui-review.md +0 -32
- package/commands/ez/validate-phase.md +0 -35
- package/ez-agents/bin/lib/metrics-tracker.cjs +0 -406
- package/ez-agents/templates/UI-SPEC.md +0 -100
- package/ez-agents/templates/VALIDATION.md +0 -76
- package/ez-agents/templates/context.md +0 -352
- package/ez-agents/templates/verification-report.md +0 -322
- package/ez-agents/workflows/arch-review.md +0 -54
- package/ez-agents/workflows/export-session.md +0 -255
- package/ez-agents/workflows/gather-requirements.md +0 -206
- package/ez-agents/workflows/import-session.md +0 -303
- package/ez-agents/workflows/research-phase.md +0 -74
- package/ez-agents/workflows/standup.md +0 -64
- package/ez-agents/workflows/ui-phase.md +0 -290
- package/ez-agents/workflows/ui-review.md +0 -157
- package/ez-agents/workflows/validate-phase.md +0 -167
|
@@ -1,385 +1,385 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Package Manager Executor — Execute package manager commands
|
|
5
|
-
*
|
|
6
|
-
* Provides unified interface for npm, yarn, and pnpm operations:
|
|
7
|
-
* - install: Install dependencies from lockfile
|
|
8
|
-
* - add: Add new package(s) to project
|
|
9
|
-
* - remove: Remove package(s) from project
|
|
10
|
-
*
|
|
11
|
-
* Cross-platform execution using execFile (not exec) for security
|
|
12
|
-
* and consistent behavior across Windows, macOS, and Linux.
|
|
13
|
-
*
|
|
14
|
-
* Usage:
|
|
15
|
-
* const PackageManagerExecutor = require('./package-manager-executor.cjs');
|
|
16
|
-
* const executor = new PackageManagerExecutor('npm', cwd);
|
|
17
|
-
* await executor.install({ production: false, frozenLockfile: true });
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
const { execFile } = require('child_process');
|
|
21
|
-
const { promisify } = require('util');
|
|
22
|
-
const path = require('path');
|
|
23
|
-
const Logger = require('./logger.cjs');
|
|
24
|
-
|
|
25
|
-
const execFileAsync = promisify(execFile);
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Custom error class for package manager operations
|
|
29
|
-
*/
|
|
30
|
-
class PackageManagerError extends Error {
|
|
31
|
-
constructor({ manager, cmd, args, error, stderr, stdout }) {
|
|
32
|
-
const message = `[${manager}] ${cmd} ${args.join(' ')} failed: ${error}${stderr ? `\n${stderr}` : ''}`;
|
|
33
|
-
super(message);
|
|
34
|
-
this.name = 'PackageManagerError';
|
|
35
|
-
this.manager = manager;
|
|
36
|
-
this.cmd = cmd;
|
|
37
|
-
this.args = args;
|
|
38
|
-
this.stderr = stderr;
|
|
39
|
-
this.stdout = stdout;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Package Manager Executor class
|
|
45
|
-
* Executes package manager commands with cross-platform compatibility
|
|
46
|
-
*/
|
|
47
|
-
class PackageManagerExecutor {
|
|
48
|
-
/**
|
|
49
|
-
* Create a PackageManagerExecutor instance
|
|
50
|
-
* @param {string} manager - Package manager name ('npm', 'yarn', or 'pnpm')
|
|
51
|
-
* @param {string} cwd - Working directory (default: process.cwd())
|
|
52
|
-
*/
|
|
53
|
-
constructor(manager, cwd = process.cwd()) {
|
|
54
|
-
if (!['npm', 'yarn', 'pnpm'].includes(manager)) {
|
|
55
|
-
throw new Error(`Unknown package manager: ${manager}. Must be 'npm', 'yarn', or 'pnpm'`);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
this.manager = manager;
|
|
59
|
-
this.cwd = cwd;
|
|
60
|
-
this.logger = new Logger();
|
|
61
|
-
this.timeout = 300000; // 5 minutes
|
|
62
|
-
this.maxBuffer = 10 * 1024 * 1024; // 10MB buffer
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Execute install command
|
|
67
|
-
* @param {Object} options - Install options
|
|
68
|
-
* @param {boolean} [options.production] - Production install (exclude devDependencies)
|
|
69
|
-
* @param {boolean} [options.frozenLockfile] - Use frozen lockfile (CI/CD safe)
|
|
70
|
-
* @param {boolean} [options.preferOffline] - Prefer offline cache
|
|
71
|
-
* @returns {Promise<string>} Command output
|
|
72
|
-
*/
|
|
73
|
-
async install(options = {}) {
|
|
74
|
-
const { production, frozenLockfile, preferOffline } = options;
|
|
75
|
-
|
|
76
|
-
const args = this._buildInstallArgs({ production, frozenLockfile, preferOffline });
|
|
77
|
-
|
|
78
|
-
this.logger.info('Package manager install', {
|
|
79
|
-
manager: this.manager,
|
|
80
|
-
args: args.join(' '),
|
|
81
|
-
cwd: this.cwd
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
return await this._execute(this.manager, args);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Add package(s) to project
|
|
89
|
-
* @param {string[]} packages - Package names to add
|
|
90
|
-
* @param {Object} options - Add options
|
|
91
|
-
* @param {boolean} [options.dev] - Add as devDependency
|
|
92
|
-
* @param {boolean} [options.peer] - Add as peerDependency
|
|
93
|
-
* @param {boolean} [options.optional] - Add as optionalDependency
|
|
94
|
-
* @param {boolean} [options.global] - Install globally
|
|
95
|
-
* @returns {Promise<string>} Command output
|
|
96
|
-
*/
|
|
97
|
-
async add(packages, options = {}) {
|
|
98
|
-
const { dev, peer, optional, global } = options;
|
|
99
|
-
|
|
100
|
-
const args = this._buildAddArgs(packages, { dev, peer, optional, global });
|
|
101
|
-
|
|
102
|
-
this.logger.info('Package manager add', {
|
|
103
|
-
manager: this.manager,
|
|
104
|
-
packages,
|
|
105
|
-
args: args.join(' '),
|
|
106
|
-
cwd: this.cwd
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
return await this._execute(this.manager, args);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Remove package(s) from project
|
|
114
|
-
* @param {string[]} packages - Package names to remove
|
|
115
|
-
* @param {Object} options - Remove options
|
|
116
|
-
* @param {boolean} [options.global] - Remove from global install
|
|
117
|
-
* @returns {Promise<string>} Command output
|
|
118
|
-
*/
|
|
119
|
-
async remove(packages, options = {}) {
|
|
120
|
-
const { global } = options;
|
|
121
|
-
|
|
122
|
-
const args = this._buildRemoveArgs(packages, { global });
|
|
123
|
-
|
|
124
|
-
this.logger.info('Package manager remove', {
|
|
125
|
-
manager: this.manager,
|
|
126
|
-
packages,
|
|
127
|
-
args: args.join(' '),
|
|
128
|
-
cwd: this.cwd
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
return await this._execute(this.manager, args);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Build install arguments for specific package manager
|
|
136
|
-
* @private
|
|
137
|
-
* @param {Object} options - Install options
|
|
138
|
-
* @returns {string[]} Command arguments
|
|
139
|
-
*/
|
|
140
|
-
_buildInstallArgs(options = {}) {
|
|
141
|
-
const { production, frozenLockfile, preferOffline } = options;
|
|
142
|
-
|
|
143
|
-
switch (this.manager) {
|
|
144
|
-
case 'npm':
|
|
145
|
-
return this._buildNpmInstallArgs({ production, frozenLockfile, preferOffline });
|
|
146
|
-
case 'yarn':
|
|
147
|
-
return this._buildYarnInstallArgs({ production, frozenLockfile, preferOffline });
|
|
148
|
-
case 'pnpm':
|
|
149
|
-
return this._buildPnpmInstallArgs({ production, frozenLockfile, preferOffline });
|
|
150
|
-
default:
|
|
151
|
-
throw new Error(`Unknown package manager: ${this.manager}`);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Build npm install arguments
|
|
157
|
-
* @private
|
|
158
|
-
*/
|
|
159
|
-
_buildNpmInstallArgs(options = {}) {
|
|
160
|
-
const { production, frozenLockfile, preferOffline } = options;
|
|
161
|
-
const args = ['install'];
|
|
162
|
-
|
|
163
|
-
if (production) args.push('--production');
|
|
164
|
-
if (frozenLockfile) args.push('--frozen-lockfile');
|
|
165
|
-
if (preferOffline) args.push('--prefer-offline');
|
|
166
|
-
|
|
167
|
-
return args.filter(Boolean);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Build yarn install arguments
|
|
172
|
-
* @private
|
|
173
|
-
*/
|
|
174
|
-
_buildYarnInstallArgs(options = {}) {
|
|
175
|
-
const { production, frozenLockfile, preferOffline } = options;
|
|
176
|
-
const args = ['install'];
|
|
177
|
-
|
|
178
|
-
if (production) args.push('--production');
|
|
179
|
-
if (frozenLockfile) args.push('--frozen-lockfile');
|
|
180
|
-
if (preferOffline) args.push('--prefer-offline');
|
|
181
|
-
|
|
182
|
-
return args.filter(Boolean);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* Build pnpm install arguments
|
|
187
|
-
* @private
|
|
188
|
-
*/
|
|
189
|
-
_buildPnpmInstallArgs(options = {}) {
|
|
190
|
-
const { production, frozenLockfile, preferOffline } = options;
|
|
191
|
-
const args = ['install'];
|
|
192
|
-
|
|
193
|
-
if (production) args.push('--prod');
|
|
194
|
-
if (frozenLockfile) args.push('--frozen-lockfile');
|
|
195
|
-
if (preferOffline) args.push('--prefer-offline');
|
|
196
|
-
|
|
197
|
-
return args.filter(Boolean);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Build add arguments for specific package manager
|
|
202
|
-
* @private
|
|
203
|
-
* @param {string[]} packages - Package names
|
|
204
|
-
* @param {Object} options - Add options
|
|
205
|
-
* @returns {string[]} Command arguments
|
|
206
|
-
*/
|
|
207
|
-
_buildAddArgs(packages, options = {}) {
|
|
208
|
-
switch (this.manager) {
|
|
209
|
-
case 'npm':
|
|
210
|
-
return this._buildNpmAddArgs(packages, options);
|
|
211
|
-
case 'yarn':
|
|
212
|
-
return this._buildYarnAddArgs(packages, options);
|
|
213
|
-
case 'pnpm':
|
|
214
|
-
return this._buildPnpmAddArgs(packages, options);
|
|
215
|
-
default:
|
|
216
|
-
throw new Error(`Unknown package manager: ${this.manager}`);
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Build npm add arguments
|
|
222
|
-
* @private
|
|
223
|
-
*/
|
|
224
|
-
_buildNpmAddArgs(packages, options = {}) {
|
|
225
|
-
const { dev, peer, optional, global } = options;
|
|
226
|
-
const args = ['install'];
|
|
227
|
-
|
|
228
|
-
if (global) args.push('-g');
|
|
229
|
-
if (dev) args.push('--save-dev');
|
|
230
|
-
if (peer) args.push('--save-peer');
|
|
231
|
-
if (optional) args.push('--save-optional');
|
|
232
|
-
|
|
233
|
-
return [...args, ...packages];
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* Build yarn add arguments
|
|
238
|
-
* @private
|
|
239
|
-
*/
|
|
240
|
-
_buildYarnAddArgs(packages, options = {}) {
|
|
241
|
-
const { dev, peer, optional, global } = options;
|
|
242
|
-
const args = ['add'];
|
|
243
|
-
|
|
244
|
-
if (global) args.push('global');
|
|
245
|
-
if (dev) args.push('--dev');
|
|
246
|
-
if (peer) args.push('--peer');
|
|
247
|
-
if (optional) args.push('--optional');
|
|
248
|
-
|
|
249
|
-
return [...args, ...packages];
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
* Build pnpm add arguments
|
|
254
|
-
* @private
|
|
255
|
-
*/
|
|
256
|
-
_buildPnpmAddArgs(packages, options = {}) {
|
|
257
|
-
const { dev, peer, optional, global } = options;
|
|
258
|
-
const args = ['add'];
|
|
259
|
-
|
|
260
|
-
if (global) args.push('-g');
|
|
261
|
-
if (dev) args.push('--save-dev');
|
|
262
|
-
if (peer) args.push('--save-peer');
|
|
263
|
-
if (optional) args.push('--save-optional');
|
|
264
|
-
|
|
265
|
-
return [...args, ...packages];
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
/**
|
|
269
|
-
* Build remove arguments for specific package manager
|
|
270
|
-
* @private
|
|
271
|
-
* @param {string[]} packages - Package names
|
|
272
|
-
* @param {Object} options - Remove options
|
|
273
|
-
* @returns {string[]} Command arguments
|
|
274
|
-
*/
|
|
275
|
-
_buildRemoveArgs(packages, options = {}) {
|
|
276
|
-
switch (this.manager) {
|
|
277
|
-
case 'npm':
|
|
278
|
-
return this._buildNpmRemoveArgs(packages, options);
|
|
279
|
-
case 'yarn':
|
|
280
|
-
return this._buildYarnRemoveArgs(packages, options);
|
|
281
|
-
case 'pnpm':
|
|
282
|
-
return this._buildPnpmRemoveArgs(packages, options);
|
|
283
|
-
default:
|
|
284
|
-
throw new Error(`Unknown package manager: ${this.manager}`);
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
* Build npm remove arguments
|
|
290
|
-
* @private
|
|
291
|
-
*/
|
|
292
|
-
_buildNpmRemoveArgs(packages, options = {}) {
|
|
293
|
-
const { global } = options;
|
|
294
|
-
const args = ['uninstall'];
|
|
295
|
-
|
|
296
|
-
if (global) args.push('-g');
|
|
297
|
-
|
|
298
|
-
return [...args, ...packages];
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Build yarn remove arguments
|
|
303
|
-
* @private
|
|
304
|
-
*/
|
|
305
|
-
_buildYarnRemoveArgs(packages, options = {}) {
|
|
306
|
-
const { global } = options;
|
|
307
|
-
const args = ['remove'];
|
|
308
|
-
|
|
309
|
-
if (global) args.push('global');
|
|
310
|
-
|
|
311
|
-
return [...args, ...packages];
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
/**
|
|
315
|
-
* Build pnpm remove arguments
|
|
316
|
-
* @private
|
|
317
|
-
*/
|
|
318
|
-
_buildPnpmRemoveArgs(packages, options = {}) {
|
|
319
|
-
const { global } = options;
|
|
320
|
-
const args = ['remove'];
|
|
321
|
-
|
|
322
|
-
if (global) args.push('-g');
|
|
323
|
-
|
|
324
|
-
return [...args, ...packages];
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
/**
|
|
328
|
-
* Execute command with cross-platform compatibility
|
|
329
|
-
* @private
|
|
330
|
-
* @param {string} cmd - Command to execute
|
|
331
|
-
* @param {string[]} args - Command arguments
|
|
332
|
-
* @returns {Promise<string>} Command output
|
|
333
|
-
*/
|
|
334
|
-
async _execute(cmd, args) {
|
|
335
|
-
const startTime = Date.now();
|
|
336
|
-
|
|
337
|
-
this.logger.debug('Package manager command start', {
|
|
338
|
-
manager: this.manager,
|
|
339
|
-
cmd,
|
|
340
|
-
args: args.join(' '),
|
|
341
|
-
cwd: this.cwd
|
|
342
|
-
});
|
|
343
|
-
|
|
344
|
-
try {
|
|
345
|
-
const result = await execFileAsync(cmd, args, {
|
|
346
|
-
cwd: this.cwd,
|
|
347
|
-
shell: false, // Use execFile for security (no shell injection)
|
|
348
|
-
maxBuffer: this.maxBuffer,
|
|
349
|
-
timeout: this.timeout
|
|
350
|
-
});
|
|
351
|
-
|
|
352
|
-
const duration = Date.now() - startTime;
|
|
353
|
-
this.logger.debug('Package manager command completed', {
|
|
354
|
-
manager: this.manager,
|
|
355
|
-
duration,
|
|
356
|
-
stdout_length: result.stdout?.length || 0
|
|
357
|
-
});
|
|
358
|
-
|
|
359
|
-
return result.stdout.trim();
|
|
360
|
-
} catch (err) {
|
|
361
|
-
const duration = Date.now() - startTime;
|
|
362
|
-
this.logger.error('Package manager command failed', {
|
|
363
|
-
manager: this.manager,
|
|
364
|
-
cmd,
|
|
365
|
-
args: args.join(' '),
|
|
366
|
-
duration,
|
|
367
|
-
error: err.message,
|
|
368
|
-
stderr: err.stderr?.trim(),
|
|
369
|
-
stdout: err.stdout?.trim()
|
|
370
|
-
});
|
|
371
|
-
|
|
372
|
-
throw new PackageManagerError({
|
|
373
|
-
manager: this.manager,
|
|
374
|
-
cmd,
|
|
375
|
-
args,
|
|
376
|
-
error: err.message,
|
|
377
|
-
stderr: err.stderr?.trim(),
|
|
378
|
-
stdout: err.stdout?.trim()
|
|
379
|
-
});
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
module.exports = PackageManagerExecutor;
|
|
385
|
-
module.exports.PackageManagerError = PackageManagerError;
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Package Manager Executor — Execute package manager commands
|
|
5
|
+
*
|
|
6
|
+
* Provides unified interface for npm, yarn, and pnpm operations:
|
|
7
|
+
* - install: Install dependencies from lockfile
|
|
8
|
+
* - add: Add new package(s) to project
|
|
9
|
+
* - remove: Remove package(s) from project
|
|
10
|
+
*
|
|
11
|
+
* Cross-platform execution using execFile (not exec) for security
|
|
12
|
+
* and consistent behavior across Windows, macOS, and Linux.
|
|
13
|
+
*
|
|
14
|
+
* Usage:
|
|
15
|
+
* const PackageManagerExecutor = require('./package-manager-executor.cjs');
|
|
16
|
+
* const executor = new PackageManagerExecutor('npm', cwd);
|
|
17
|
+
* await executor.install({ production: false, frozenLockfile: true });
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
const { execFile } = require('child_process');
|
|
21
|
+
const { promisify } = require('util');
|
|
22
|
+
const path = require('path');
|
|
23
|
+
const Logger = require('./logger.cjs');
|
|
24
|
+
|
|
25
|
+
const execFileAsync = promisify(execFile);
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Custom error class for package manager operations
|
|
29
|
+
*/
|
|
30
|
+
class PackageManagerError extends Error {
|
|
31
|
+
constructor({ manager, cmd, args, error, stderr, stdout }) {
|
|
32
|
+
const message = `[${manager}] ${cmd} ${args.join(' ')} failed: ${error}${stderr ? `\n${stderr}` : ''}`;
|
|
33
|
+
super(message);
|
|
34
|
+
this.name = 'PackageManagerError';
|
|
35
|
+
this.manager = manager;
|
|
36
|
+
this.cmd = cmd;
|
|
37
|
+
this.args = args;
|
|
38
|
+
this.stderr = stderr;
|
|
39
|
+
this.stdout = stdout;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Package Manager Executor class
|
|
45
|
+
* Executes package manager commands with cross-platform compatibility
|
|
46
|
+
*/
|
|
47
|
+
class PackageManagerExecutor {
|
|
48
|
+
/**
|
|
49
|
+
* Create a PackageManagerExecutor instance
|
|
50
|
+
* @param {string} manager - Package manager name ('npm', 'yarn', or 'pnpm')
|
|
51
|
+
* @param {string} cwd - Working directory (default: process.cwd())
|
|
52
|
+
*/
|
|
53
|
+
constructor(manager, cwd = process.cwd()) {
|
|
54
|
+
if (!['npm', 'yarn', 'pnpm'].includes(manager)) {
|
|
55
|
+
throw new Error(`Unknown package manager: ${manager}. Must be 'npm', 'yarn', or 'pnpm'`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
this.manager = manager;
|
|
59
|
+
this.cwd = cwd;
|
|
60
|
+
this.logger = new Logger();
|
|
61
|
+
this.timeout = 300000; // 5 minutes
|
|
62
|
+
this.maxBuffer = 10 * 1024 * 1024; // 10MB buffer
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Execute install command
|
|
67
|
+
* @param {Object} options - Install options
|
|
68
|
+
* @param {boolean} [options.production] - Production install (exclude devDependencies)
|
|
69
|
+
* @param {boolean} [options.frozenLockfile] - Use frozen lockfile (CI/CD safe)
|
|
70
|
+
* @param {boolean} [options.preferOffline] - Prefer offline cache
|
|
71
|
+
* @returns {Promise<string>} Command output
|
|
72
|
+
*/
|
|
73
|
+
async install(options = {}) {
|
|
74
|
+
const { production, frozenLockfile, preferOffline } = options;
|
|
75
|
+
|
|
76
|
+
const args = this._buildInstallArgs({ production, frozenLockfile, preferOffline });
|
|
77
|
+
|
|
78
|
+
this.logger.info('Package manager install', {
|
|
79
|
+
manager: this.manager,
|
|
80
|
+
args: args.join(' '),
|
|
81
|
+
cwd: this.cwd
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
return await this._execute(this.manager, args);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Add package(s) to project
|
|
89
|
+
* @param {string[]} packages - Package names to add
|
|
90
|
+
* @param {Object} options - Add options
|
|
91
|
+
* @param {boolean} [options.dev] - Add as devDependency
|
|
92
|
+
* @param {boolean} [options.peer] - Add as peerDependency
|
|
93
|
+
* @param {boolean} [options.optional] - Add as optionalDependency
|
|
94
|
+
* @param {boolean} [options.global] - Install globally
|
|
95
|
+
* @returns {Promise<string>} Command output
|
|
96
|
+
*/
|
|
97
|
+
async add(packages, options = {}) {
|
|
98
|
+
const { dev, peer, optional, global } = options;
|
|
99
|
+
|
|
100
|
+
const args = this._buildAddArgs(packages, { dev, peer, optional, global });
|
|
101
|
+
|
|
102
|
+
this.logger.info('Package manager add', {
|
|
103
|
+
manager: this.manager,
|
|
104
|
+
packages,
|
|
105
|
+
args: args.join(' '),
|
|
106
|
+
cwd: this.cwd
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
return await this._execute(this.manager, args);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Remove package(s) from project
|
|
114
|
+
* @param {string[]} packages - Package names to remove
|
|
115
|
+
* @param {Object} options - Remove options
|
|
116
|
+
* @param {boolean} [options.global] - Remove from global install
|
|
117
|
+
* @returns {Promise<string>} Command output
|
|
118
|
+
*/
|
|
119
|
+
async remove(packages, options = {}) {
|
|
120
|
+
const { global } = options;
|
|
121
|
+
|
|
122
|
+
const args = this._buildRemoveArgs(packages, { global });
|
|
123
|
+
|
|
124
|
+
this.logger.info('Package manager remove', {
|
|
125
|
+
manager: this.manager,
|
|
126
|
+
packages,
|
|
127
|
+
args: args.join(' '),
|
|
128
|
+
cwd: this.cwd
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
return await this._execute(this.manager, args);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Build install arguments for specific package manager
|
|
136
|
+
* @private
|
|
137
|
+
* @param {Object} options - Install options
|
|
138
|
+
* @returns {string[]} Command arguments
|
|
139
|
+
*/
|
|
140
|
+
_buildInstallArgs(options = {}) {
|
|
141
|
+
const { production, frozenLockfile, preferOffline } = options;
|
|
142
|
+
|
|
143
|
+
switch (this.manager) {
|
|
144
|
+
case 'npm':
|
|
145
|
+
return this._buildNpmInstallArgs({ production, frozenLockfile, preferOffline });
|
|
146
|
+
case 'yarn':
|
|
147
|
+
return this._buildYarnInstallArgs({ production, frozenLockfile, preferOffline });
|
|
148
|
+
case 'pnpm':
|
|
149
|
+
return this._buildPnpmInstallArgs({ production, frozenLockfile, preferOffline });
|
|
150
|
+
default:
|
|
151
|
+
throw new Error(`Unknown package manager: ${this.manager}`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Build npm install arguments
|
|
157
|
+
* @private
|
|
158
|
+
*/
|
|
159
|
+
_buildNpmInstallArgs(options = {}) {
|
|
160
|
+
const { production, frozenLockfile, preferOffline } = options;
|
|
161
|
+
const args = ['install'];
|
|
162
|
+
|
|
163
|
+
if (production) args.push('--production');
|
|
164
|
+
if (frozenLockfile) args.push('--frozen-lockfile');
|
|
165
|
+
if (preferOffline) args.push('--prefer-offline');
|
|
166
|
+
|
|
167
|
+
return args.filter(Boolean);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Build yarn install arguments
|
|
172
|
+
* @private
|
|
173
|
+
*/
|
|
174
|
+
_buildYarnInstallArgs(options = {}) {
|
|
175
|
+
const { production, frozenLockfile, preferOffline } = options;
|
|
176
|
+
const args = ['install'];
|
|
177
|
+
|
|
178
|
+
if (production) args.push('--production');
|
|
179
|
+
if (frozenLockfile) args.push('--frozen-lockfile');
|
|
180
|
+
if (preferOffline) args.push('--prefer-offline');
|
|
181
|
+
|
|
182
|
+
return args.filter(Boolean);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Build pnpm install arguments
|
|
187
|
+
* @private
|
|
188
|
+
*/
|
|
189
|
+
_buildPnpmInstallArgs(options = {}) {
|
|
190
|
+
const { production, frozenLockfile, preferOffline } = options;
|
|
191
|
+
const args = ['install'];
|
|
192
|
+
|
|
193
|
+
if (production) args.push('--prod');
|
|
194
|
+
if (frozenLockfile) args.push('--frozen-lockfile');
|
|
195
|
+
if (preferOffline) args.push('--prefer-offline');
|
|
196
|
+
|
|
197
|
+
return args.filter(Boolean);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Build add arguments for specific package manager
|
|
202
|
+
* @private
|
|
203
|
+
* @param {string[]} packages - Package names
|
|
204
|
+
* @param {Object} options - Add options
|
|
205
|
+
* @returns {string[]} Command arguments
|
|
206
|
+
*/
|
|
207
|
+
_buildAddArgs(packages, options = {}) {
|
|
208
|
+
switch (this.manager) {
|
|
209
|
+
case 'npm':
|
|
210
|
+
return this._buildNpmAddArgs(packages, options);
|
|
211
|
+
case 'yarn':
|
|
212
|
+
return this._buildYarnAddArgs(packages, options);
|
|
213
|
+
case 'pnpm':
|
|
214
|
+
return this._buildPnpmAddArgs(packages, options);
|
|
215
|
+
default:
|
|
216
|
+
throw new Error(`Unknown package manager: ${this.manager}`);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Build npm add arguments
|
|
222
|
+
* @private
|
|
223
|
+
*/
|
|
224
|
+
_buildNpmAddArgs(packages, options = {}) {
|
|
225
|
+
const { dev, peer, optional, global } = options;
|
|
226
|
+
const args = ['install'];
|
|
227
|
+
|
|
228
|
+
if (global) args.push('-g');
|
|
229
|
+
if (dev) args.push('--save-dev');
|
|
230
|
+
if (peer) args.push('--save-peer');
|
|
231
|
+
if (optional) args.push('--save-optional');
|
|
232
|
+
|
|
233
|
+
return [...args, ...packages];
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Build yarn add arguments
|
|
238
|
+
* @private
|
|
239
|
+
*/
|
|
240
|
+
_buildYarnAddArgs(packages, options = {}) {
|
|
241
|
+
const { dev, peer, optional, global } = options;
|
|
242
|
+
const args = ['add'];
|
|
243
|
+
|
|
244
|
+
if (global) args.push('global');
|
|
245
|
+
if (dev) args.push('--dev');
|
|
246
|
+
if (peer) args.push('--peer');
|
|
247
|
+
if (optional) args.push('--optional');
|
|
248
|
+
|
|
249
|
+
return [...args, ...packages];
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Build pnpm add arguments
|
|
254
|
+
* @private
|
|
255
|
+
*/
|
|
256
|
+
_buildPnpmAddArgs(packages, options = {}) {
|
|
257
|
+
const { dev, peer, optional, global } = options;
|
|
258
|
+
const args = ['add'];
|
|
259
|
+
|
|
260
|
+
if (global) args.push('-g');
|
|
261
|
+
if (dev) args.push('--save-dev');
|
|
262
|
+
if (peer) args.push('--save-peer');
|
|
263
|
+
if (optional) args.push('--save-optional');
|
|
264
|
+
|
|
265
|
+
return [...args, ...packages];
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Build remove arguments for specific package manager
|
|
270
|
+
* @private
|
|
271
|
+
* @param {string[]} packages - Package names
|
|
272
|
+
* @param {Object} options - Remove options
|
|
273
|
+
* @returns {string[]} Command arguments
|
|
274
|
+
*/
|
|
275
|
+
_buildRemoveArgs(packages, options = {}) {
|
|
276
|
+
switch (this.manager) {
|
|
277
|
+
case 'npm':
|
|
278
|
+
return this._buildNpmRemoveArgs(packages, options);
|
|
279
|
+
case 'yarn':
|
|
280
|
+
return this._buildYarnRemoveArgs(packages, options);
|
|
281
|
+
case 'pnpm':
|
|
282
|
+
return this._buildPnpmRemoveArgs(packages, options);
|
|
283
|
+
default:
|
|
284
|
+
throw new Error(`Unknown package manager: ${this.manager}`);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Build npm remove arguments
|
|
290
|
+
* @private
|
|
291
|
+
*/
|
|
292
|
+
_buildNpmRemoveArgs(packages, options = {}) {
|
|
293
|
+
const { global } = options;
|
|
294
|
+
const args = ['uninstall'];
|
|
295
|
+
|
|
296
|
+
if (global) args.push('-g');
|
|
297
|
+
|
|
298
|
+
return [...args, ...packages];
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Build yarn remove arguments
|
|
303
|
+
* @private
|
|
304
|
+
*/
|
|
305
|
+
_buildYarnRemoveArgs(packages, options = {}) {
|
|
306
|
+
const { global } = options;
|
|
307
|
+
const args = ['remove'];
|
|
308
|
+
|
|
309
|
+
if (global) args.push('global');
|
|
310
|
+
|
|
311
|
+
return [...args, ...packages];
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Build pnpm remove arguments
|
|
316
|
+
* @private
|
|
317
|
+
*/
|
|
318
|
+
_buildPnpmRemoveArgs(packages, options = {}) {
|
|
319
|
+
const { global } = options;
|
|
320
|
+
const args = ['remove'];
|
|
321
|
+
|
|
322
|
+
if (global) args.push('-g');
|
|
323
|
+
|
|
324
|
+
return [...args, ...packages];
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Execute command with cross-platform compatibility
|
|
329
|
+
* @private
|
|
330
|
+
* @param {string} cmd - Command to execute
|
|
331
|
+
* @param {string[]} args - Command arguments
|
|
332
|
+
* @returns {Promise<string>} Command output
|
|
333
|
+
*/
|
|
334
|
+
async _execute(cmd, args) {
|
|
335
|
+
const startTime = Date.now();
|
|
336
|
+
|
|
337
|
+
this.logger.debug('Package manager command start', {
|
|
338
|
+
manager: this.manager,
|
|
339
|
+
cmd,
|
|
340
|
+
args: args.join(' '),
|
|
341
|
+
cwd: this.cwd
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
try {
|
|
345
|
+
const result = await execFileAsync(cmd, args, {
|
|
346
|
+
cwd: this.cwd,
|
|
347
|
+
shell: false, // Use execFile for security (no shell injection)
|
|
348
|
+
maxBuffer: this.maxBuffer,
|
|
349
|
+
timeout: this.timeout
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
const duration = Date.now() - startTime;
|
|
353
|
+
this.logger.debug('Package manager command completed', {
|
|
354
|
+
manager: this.manager,
|
|
355
|
+
duration,
|
|
356
|
+
stdout_length: result.stdout?.length || 0
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
return result.stdout.trim();
|
|
360
|
+
} catch (err) {
|
|
361
|
+
const duration = Date.now() - startTime;
|
|
362
|
+
this.logger.error('Package manager command failed', {
|
|
363
|
+
manager: this.manager,
|
|
364
|
+
cmd,
|
|
365
|
+
args: args.join(' '),
|
|
366
|
+
duration,
|
|
367
|
+
error: err.message,
|
|
368
|
+
stderr: err.stderr?.trim(),
|
|
369
|
+
stdout: err.stdout?.trim()
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
throw new PackageManagerError({
|
|
373
|
+
manager: this.manager,
|
|
374
|
+
cmd,
|
|
375
|
+
args,
|
|
376
|
+
error: err.message,
|
|
377
|
+
stderr: err.stderr?.trim(),
|
|
378
|
+
stdout: err.stdout?.trim()
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
module.exports = PackageManagerExecutor;
|
|
385
|
+
module.exports.PackageManagerError = PackageManagerError;
|