prjct-cli 1.22.0 → 1.23.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/CHANGELOG.md +147 -0
- package/bin/prjct +30 -13
- package/dist/bin/prjct.mjs +917 -35845
- package/dist/bin/prjct.mjs.map +7 -0
- package/dist/cli/linear.mjs +16 -0
- package/dist/cli/linear.mjs.map +7 -0
- package/dist/templates.json +1 -0
- package/package.json +4 -5
- package/bin/prjct.ts +0 -342
- package/core/__tests__/agentic/analysis-injection.test.ts +0 -377
- package/core/__tests__/agentic/cache-eviction.test.ts +0 -294
- package/core/__tests__/agentic/command-context.test.ts +0 -281
- package/core/__tests__/agentic/command-executor.test.ts +0 -659
- package/core/__tests__/agentic/domain-classifier.test.ts +0 -330
- package/core/__tests__/agentic/injection-validator.test.ts +0 -255
- package/core/__tests__/agentic/memory-system.test.ts +0 -281
- package/core/__tests__/agentic/plan-mode.test.ts +0 -386
- package/core/__tests__/agentic/prompt-assembly.test.ts +0 -298
- package/core/__tests__/agentic/prompt-builder.test.ts +0 -243
- package/core/__tests__/agentic/response-validator.test.ts +0 -263
- package/core/__tests__/agentic/semantic-matching.test.ts +0 -131
- package/core/__tests__/agentic/smart-context.test.ts +0 -372
- package/core/__tests__/agentic/tech-normalizer.test.ts +0 -136
- package/core/__tests__/agentic/token-budget.test.ts +0 -294
- package/core/__tests__/ai-tools/formatters.test.ts +0 -476
- package/core/__tests__/domain/bm25.test.ts +0 -225
- package/core/__tests__/domain/change-propagator.test.ts +0 -100
- package/core/__tests__/domain/fibonacci.test.ts +0 -113
- package/core/__tests__/domain/file-hasher.test.ts +0 -146
- package/core/__tests__/domain/file-ranker.test.ts +0 -169
- package/core/__tests__/domain/git-cochange.test.ts +0 -121
- package/core/__tests__/domain/import-graph.test.ts +0 -156
- package/core/__tests__/domain/velocity.test.ts +0 -623
- package/core/__tests__/infrastructure/performance-tracker.test.ts +0 -328
- package/core/__tests__/schemas/model.test.ts +0 -272
- package/core/__tests__/services/dependency-validator.test.ts +0 -175
- package/core/__tests__/services/hierarchical-agent-resolver.test.ts +0 -359
- package/core/__tests__/services/nested-context-resolver.test.ts +0 -443
- package/core/__tests__/services/project-index.test.ts +0 -355
- package/core/__tests__/services/staleness-checker.test.ts +0 -204
- package/core/__tests__/storage/analysis-storage.test.ts +0 -641
- package/core/__tests__/storage/archive-storage.test.ts +0 -455
- package/core/__tests__/storage/safe-reader.test.ts +0 -262
- package/core/__tests__/storage/sqlite-migration.test.ts +0 -1016
- package/core/__tests__/storage/state-storage-feedback.test.ts +0 -463
- package/core/__tests__/storage/state-storage-history.test.ts +0 -469
- package/core/__tests__/storage/storage-manager.test.ts +0 -383
- package/core/__tests__/storage/subtask-handoff.test.ts +0 -237
- package/core/__tests__/types/fs.test.ts +0 -125
- package/core/__tests__/utils/date-helper.test.ts +0 -449
- package/core/__tests__/utils/output.test.ts +0 -278
- package/core/__tests__/utils/preserve-sections.test.ts +0 -216
- package/core/__tests__/utils/project-commands.test.ts +0 -71
- package/core/__tests__/utils/retry.test.ts +0 -381
- package/core/__tests__/workflow/state-machine.test.ts +0 -216
- package/core/agentic/agent-router.ts +0 -150
- package/core/agentic/anti-hallucination.ts +0 -141
- package/core/agentic/chain-of-thought.ts +0 -234
- package/core/agentic/command-classifier.ts +0 -141
- package/core/agentic/command-context.ts +0 -168
- package/core/agentic/command-executor.ts +0 -471
- package/core/agentic/context-builder.ts +0 -285
- package/core/agentic/domain-classifier.ts +0 -525
- package/core/agentic/environment-block.ts +0 -102
- package/core/agentic/ground-truth.ts +0 -706
- package/core/agentic/index.ts +0 -193
- package/core/agentic/injection-validator.ts +0 -208
- package/core/agentic/loop-detector.ts +0 -451
- package/core/agentic/memory-system.ts +0 -1547
- package/core/agentic/orchestrator-executor.ts +0 -579
- package/core/agentic/plan-mode.ts +0 -525
- package/core/agentic/prompt-builder.ts +0 -1069
- package/core/agentic/response-validator.ts +0 -98
- package/core/agentic/services.ts +0 -167
- package/core/agentic/skill-loader.ts +0 -106
- package/core/agentic/smart-context.ts +0 -393
- package/core/agentic/tech-normalizer.ts +0 -167
- package/core/agentic/template-executor.ts +0 -272
- package/core/agentic/template-loader.ts +0 -109
- package/core/agentic/token-budget.ts +0 -226
- package/core/agentic/tool-registry.ts +0 -146
- package/core/agents/index.ts +0 -28
- package/core/agents/performance.ts +0 -429
- package/core/ai-tools/formatters.ts +0 -341
- package/core/ai-tools/generator.ts +0 -144
- package/core/ai-tools/index.ts +0 -15
- package/core/ai-tools/registry.ts +0 -201
- package/core/bus/bus.ts +0 -314
- package/core/bus/index.ts +0 -8
- package/core/cli/linear.ts +0 -500
- package/core/cli/lint-meta-commentary.ts +0 -177
- package/core/cli/start.ts +0 -386
- package/core/commands/analysis.ts +0 -1274
- package/core/commands/analytics.ts +0 -342
- package/core/commands/base.ts +0 -118
- package/core/commands/cleanup.ts +0 -157
- package/core/commands/command-data.ts +0 -463
- package/core/commands/commands.ts +0 -306
- package/core/commands/context.ts +0 -238
- package/core/commands/design.ts +0 -77
- package/core/commands/index.ts +0 -19
- package/core/commands/maintenance.ts +0 -77
- package/core/commands/performance.ts +0 -114
- package/core/commands/planning.ts +0 -662
- package/core/commands/register.ts +0 -127
- package/core/commands/registry.ts +0 -444
- package/core/commands/setup.ts +0 -280
- package/core/commands/shipping.ts +0 -267
- package/core/commands/snapshots.ts +0 -297
- package/core/commands/uninstall.ts +0 -542
- package/core/commands/velocity.ts +0 -149
- package/core/commands/workflow.ts +0 -505
- package/core/config/command-context.config.json +0 -66
- package/core/constants/index.ts +0 -379
- package/core/context/generator.ts +0 -368
- package/core/context-tools/files-tool.ts +0 -577
- package/core/context-tools/imports-tool.ts +0 -400
- package/core/context-tools/index.ts +0 -434
- package/core/context-tools/recent-tool.ts +0 -301
- package/core/context-tools/signatures-tool.ts +0 -495
- package/core/context-tools/summary-tool.ts +0 -301
- package/core/context-tools/token-counter.ts +0 -273
- package/core/context-tools/types.ts +0 -253
- package/core/domain/agent-generator.ts +0 -186
- package/core/domain/agent-loader.ts +0 -419
- package/core/domain/analyzer.ts +0 -387
- package/core/domain/architecture-generator.ts +0 -108
- package/core/domain/bm25.ts +0 -525
- package/core/domain/change-propagator.ts +0 -162
- package/core/domain/context-estimator.ts +0 -175
- package/core/domain/fibonacci.ts +0 -128
- package/core/domain/file-hasher.ts +0 -296
- package/core/domain/file-ranker.ts +0 -151
- package/core/domain/git-cochange.ts +0 -250
- package/core/domain/import-graph.ts +0 -315
- package/core/domain/snapshot-manager.ts +0 -415
- package/core/domain/task-stack.ts +0 -578
- package/core/domain/velocity.ts +0 -470
- package/core/errors.ts +0 -335
- package/core/events/events.ts +0 -85
- package/core/events/index.ts +0 -8
- package/core/index.ts +0 -481
- package/core/infrastructure/agent-detector.ts +0 -135
- package/core/infrastructure/ai-provider.ts +0 -578
- package/core/infrastructure/author-detector.ts +0 -133
- package/core/infrastructure/capability-installer.ts +0 -76
- package/core/infrastructure/claude-agent.ts +0 -297
- package/core/infrastructure/command-installer.ts +0 -752
- package/core/infrastructure/config-manager.ts +0 -364
- package/core/infrastructure/editors-config.ts +0 -172
- package/core/infrastructure/path-manager.ts +0 -571
- package/core/infrastructure/performance-tracker.ts +0 -326
- package/core/infrastructure/permission-manager.ts +0 -289
- package/core/infrastructure/setup.ts +0 -1061
- package/core/infrastructure/update-checker.ts +0 -246
- package/core/integrations/issue-tracker/enricher.ts +0 -271
- package/core/integrations/issue-tracker/index.ts +0 -8
- package/core/integrations/issue-tracker/manager.ts +0 -286
- package/core/integrations/issue-tracker/types.ts +0 -310
- package/core/integrations/jira/cache.ts +0 -57
- package/core/integrations/jira/client.ts +0 -688
- package/core/integrations/jira/index.ts +0 -23
- package/core/integrations/jira/service.ts +0 -244
- package/core/integrations/linear/cache.ts +0 -68
- package/core/integrations/linear/client.ts +0 -436
- package/core/integrations/linear/index.ts +0 -20
- package/core/integrations/linear/service.ts +0 -260
- package/core/integrations/linear/sync.ts +0 -314
- package/core/outcomes/analyzer.ts +0 -286
- package/core/outcomes/index.ts +0 -34
- package/core/outcomes/recorder.ts +0 -195
- package/core/plugin/builtin/webhook.ts +0 -148
- package/core/plugin/hooks.ts +0 -315
- package/core/plugin/index.ts +0 -50
- package/core/plugin/loader.ts +0 -354
- package/core/plugin/registry.ts +0 -326
- package/core/schemas/agents.ts +0 -27
- package/core/schemas/analysis.ts +0 -530
- package/core/schemas/classification.ts +0 -91
- package/core/schemas/command-context.ts +0 -29
- package/core/schemas/enriched-task.ts +0 -291
- package/core/schemas/ideas.ts +0 -114
- package/core/schemas/index.ts +0 -53
- package/core/schemas/issues.ts +0 -159
- package/core/schemas/llm-output.ts +0 -170
- package/core/schemas/metrics.ts +0 -143
- package/core/schemas/model.ts +0 -153
- package/core/schemas/outcomes.ts +0 -487
- package/core/schemas/performance.ts +0 -128
- package/core/schemas/permissions.ts +0 -180
- package/core/schemas/prd.ts +0 -450
- package/core/schemas/project.ts +0 -57
- package/core/schemas/roadmap.ts +0 -322
- package/core/schemas/schemas.ts +0 -38
- package/core/schemas/shipped.ts +0 -109
- package/core/schemas/state.ts +0 -284
- package/core/schemas/velocity.ts +0 -103
- package/core/server/index.ts +0 -21
- package/core/server/routes-extended.ts +0 -566
- package/core/server/routes.ts +0 -176
- package/core/server/server.ts +0 -149
- package/core/server/sse.ts +0 -192
- package/core/services/agent-generator.ts +0 -385
- package/core/services/agent-service.ts +0 -168
- package/core/services/breakdown-service.ts +0 -124
- package/core/services/context-generator.ts +0 -445
- package/core/services/context-selector.ts +0 -429
- package/core/services/dependency-validator.ts +0 -318
- package/core/services/diff-generator.ts +0 -313
- package/core/services/doctor-service.ts +0 -423
- package/core/services/file-categorizer.ts +0 -448
- package/core/services/file-scorer.ts +0 -270
- package/core/services/git-analyzer.ts +0 -293
- package/core/services/hierarchical-agent-resolver.ts +0 -236
- package/core/services/hooks-service.ts +0 -685
- package/core/services/index.ts +0 -46
- package/core/services/local-state-generator.ts +0 -158
- package/core/services/memory-service.ts +0 -181
- package/core/services/nested-context-resolver.ts +0 -842
- package/core/services/project-index.ts +0 -911
- package/core/services/project-service.ts +0 -155
- package/core/services/session-tracker.ts +0 -287
- package/core/services/skill-installer.ts +0 -447
- package/core/services/skill-lock.ts +0 -132
- package/core/services/skill-service.ts +0 -306
- package/core/services/stack-detector.ts +0 -229
- package/core/services/staleness-checker.ts +0 -327
- package/core/services/sync-service.ts +0 -1515
- package/core/services/sync-verifier.ts +0 -253
- package/core/services/watch-service.ts +0 -312
- package/core/session/compaction.ts +0 -248
- package/core/session/index.ts +0 -35
- package/core/session/log-migration.ts +0 -88
- package/core/session/metrics.ts +0 -323
- package/core/session/session-log-manager.ts +0 -307
- package/core/session/task-session-manager.ts +0 -404
- package/core/session/utils.ts +0 -51
- package/core/storage/analysis-storage.ts +0 -373
- package/core/storage/archive-storage.ts +0 -205
- package/core/storage/database.ts +0 -575
- package/core/storage/ideas-storage.ts +0 -298
- package/core/storage/index-storage.ts +0 -523
- package/core/storage/index.ts +0 -79
- package/core/storage/metrics-storage.ts +0 -321
- package/core/storage/migrate-json.ts +0 -720
- package/core/storage/queue-storage.ts +0 -336
- package/core/storage/safe-reader.ts +0 -105
- package/core/storage/shipped-storage.ts +0 -253
- package/core/storage/state-storage.ts +0 -1035
- package/core/storage/storage-manager.ts +0 -205
- package/core/storage/storage.ts +0 -177
- package/core/storage/velocity-storage.ts +0 -149
- package/core/sync/auth-config.ts +0 -138
- package/core/sync/index.ts +0 -31
- package/core/sync/oauth-handler.ts +0 -143
- package/core/sync/sync-client.ts +0 -251
- package/core/sync/sync-manager.ts +0 -327
- package/core/tsconfig.json +0 -22
- package/core/types/agentic.ts +0 -760
- package/core/types/agents.ts +0 -150
- package/core/types/bus.ts +0 -193
- package/core/types/citations.ts +0 -22
- package/core/types/commands.ts +0 -399
- package/core/types/config.ts +0 -92
- package/core/types/core.ts +0 -96
- package/core/types/diff.ts +0 -41
- package/core/types/domain.ts +0 -71
- package/core/types/errors.ts +0 -111
- package/core/types/events.ts +0 -42
- package/core/types/fs.ts +0 -72
- package/core/types/index.ts +0 -510
- package/core/types/infrastructure.ts +0 -210
- package/core/types/integrations.ts +0 -31
- package/core/types/jira.ts +0 -51
- package/core/types/logger.ts +0 -17
- package/core/types/memory.ts +0 -313
- package/core/types/outcomes.ts +0 -190
- package/core/types/output.ts +0 -47
- package/core/types/plugin.ts +0 -25
- package/core/types/project-sync.ts +0 -129
- package/core/types/provider.ts +0 -163
- package/core/types/server.ts +0 -71
- package/core/types/services.ts +0 -84
- package/core/types/session.ts +0 -135
- package/core/types/stack.ts +0 -19
- package/core/types/storage.ts +0 -318
- package/core/types/sync-verifier.ts +0 -33
- package/core/types/sync.ts +0 -121
- package/core/types/task.ts +0 -72
- package/core/types/template.ts +0 -24
- package/core/types/utils.ts +0 -92
- package/core/types/workflow.ts +0 -23
- package/core/utils/agent-stream.ts +0 -140
- package/core/utils/animations.ts +0 -251
- package/core/utils/branding.ts +0 -88
- package/core/utils/cache.ts +0 -187
- package/core/utils/citations.ts +0 -39
- package/core/utils/collection-filters.ts +0 -209
- package/core/utils/date-helper.ts +0 -176
- package/core/utils/error-messages.ts +0 -38
- package/core/utils/file-helper.ts +0 -277
- package/core/utils/fs-helpers.ts +0 -14
- package/core/utils/help.ts +0 -314
- package/core/utils/jsonl-helper.ts +0 -290
- package/core/utils/keychain.ts +0 -127
- package/core/utils/logger.ts +0 -77
- package/core/utils/markdown-builder.ts +0 -280
- package/core/utils/next-steps.ts +0 -95
- package/core/utils/output.ts +0 -403
- package/core/utils/preserve-sections.ts +0 -218
- package/core/utils/project-commands.ts +0 -126
- package/core/utils/project-credentials.ts +0 -143
- package/core/utils/provider-cache.ts +0 -49
- package/core/utils/retry.ts +0 -318
- package/core/utils/runtime.ts +0 -108
- package/core/utils/session-helper.ts +0 -278
- package/core/utils/subtask-table.ts +0 -227
- package/core/utils/version.ts +0 -128
- package/core/wizard/index.ts +0 -13
- package/core/wizard/onboarding.ts +0 -633
- package/core/workflow/index.ts +0 -7
- package/core/workflow/state-machine.ts +0 -198
- package/core/workflow/workflow-preferences.ts +0 -294
- package/dist/core/infrastructure/command-installer.js +0 -1141
- package/dist/core/infrastructure/editors-config.js +0 -177
- package/dist/core/infrastructure/setup.js +0 -2244
- package/dist/core/utils/version.js +0 -141
- package/templates/agentic/agent-routing.md +0 -45
- package/templates/agentic/agents/uxui.md +0 -63
- package/templates/agentic/checklist-routing.md +0 -98
- package/templates/agentic/orchestrator.md +0 -68
- package/templates/agentic/task-fragmentation.md +0 -89
- package/templates/agents/AGENTS.md +0 -68
- package/templates/analysis/analyze.md +0 -84
- package/templates/analysis/patterns.md +0 -60
- package/templates/antigravity/SKILL.md +0 -39
- package/templates/architect/discovery.md +0 -67
- package/templates/architect/phases.md +0 -59
- package/templates/checklists/architecture.md +0 -28
- package/templates/checklists/code-quality.md +0 -28
- package/templates/checklists/data.md +0 -33
- package/templates/checklists/documentation.md +0 -33
- package/templates/checklists/infrastructure.md +0 -33
- package/templates/checklists/performance.md +0 -33
- package/templates/checklists/security.md +0 -33
- package/templates/checklists/testing.md +0 -33
- package/templates/checklists/ux-ui.md +0 -37
- package/templates/commands/analyze.md +0 -56
- package/templates/commands/auth.md +0 -234
- package/templates/commands/bug.md +0 -163
- package/templates/commands/cleanup.md +0 -19
- package/templates/commands/dash.md +0 -99
- package/templates/commands/design.md +0 -15
- package/templates/commands/done.md +0 -291
- package/templates/commands/enrich.md +0 -174
- package/templates/commands/git.md +0 -295
- package/templates/commands/history.md +0 -389
- package/templates/commands/idea.md +0 -88
- package/templates/commands/impact.md +0 -864
- package/templates/commands/init.md +0 -54
- package/templates/commands/jira.md +0 -278
- package/templates/commands/linear.md +0 -288
- package/templates/commands/merge.md +0 -206
- package/templates/commands/next.md +0 -80
- package/templates/commands/p.md +0 -67
- package/templates/commands/p.toml +0 -37
- package/templates/commands/pause.md +0 -136
- package/templates/commands/plan.md +0 -696
- package/templates/commands/prd.md +0 -356
- package/templates/commands/resume.md +0 -171
- package/templates/commands/review.md +0 -276
- package/templates/commands/serve.md +0 -118
- package/templates/commands/setup.md +0 -91
- package/templates/commands/ship.md +0 -475
- package/templates/commands/skill.md +0 -259
- package/templates/commands/spec.md +0 -218
- package/templates/commands/status.md +0 -207
- package/templates/commands/sync.md +0 -104
- package/templates/commands/task.md +0 -312
- package/templates/commands/test.md +0 -93
- package/templates/commands/update.md +0 -63
- package/templates/commands/verify.md +0 -204
- package/templates/commands/workflow.md +0 -150
- package/templates/config/skill-mappings.json +0 -82
- package/templates/context/dashboard.md +0 -256
- package/templates/context/roadmap.md +0 -221
- package/templates/cursor/commands/bug.md +0 -8
- package/templates/cursor/commands/done.md +0 -4
- package/templates/cursor/commands/pause.md +0 -6
- package/templates/cursor/commands/resume.md +0 -4
- package/templates/cursor/commands/ship.md +0 -8
- package/templates/cursor/commands/sync.md +0 -4
- package/templates/cursor/commands/task.md +0 -8
- package/templates/cursor/p.md +0 -29
- package/templates/cursor/router.mdc +0 -28
- package/templates/design/api.md +0 -95
- package/templates/design/architecture.md +0 -77
- package/templates/design/component.md +0 -89
- package/templates/design/database.md +0 -78
- package/templates/design/flow.md +0 -94
- package/templates/global/ANTIGRAVITY.md +0 -254
- package/templates/global/CLAUDE.md +0 -497
- package/templates/global/CURSOR.mdc +0 -266
- package/templates/global/GEMINI.md +0 -293
- package/templates/global/STORAGE-SPEC.md +0 -391
- package/templates/global/WINDSURF.md +0 -266
- package/templates/global/modules/CLAUDE-commands.md +0 -70
- package/templates/global/modules/CLAUDE-core.md +0 -105
- package/templates/global/modules/CLAUDE-git.md +0 -50
- package/templates/global/modules/CLAUDE-intelligence.md +0 -92
- package/templates/global/modules/CLAUDE-storage.md +0 -50
- package/templates/global/modules/module-config.json +0 -36
- package/templates/mcp-config.json +0 -19
- package/templates/permissions/default.jsonc +0 -60
- package/templates/permissions/permissive.jsonc +0 -49
- package/templates/permissions/strict.jsonc +0 -58
- package/templates/planning-methodology.md +0 -195
- package/templates/skills/code-review.md +0 -47
- package/templates/skills/debug.md +0 -61
- package/templates/skills/refactor.md +0 -47
- package/templates/subagents/agent-base.md +0 -20
- package/templates/subagents/domain/backend.md +0 -109
- package/templates/subagents/domain/database.md +0 -121
- package/templates/subagents/domain/devops.md +0 -152
- package/templates/subagents/domain/frontend.md +0 -103
- package/templates/subagents/domain/testing.md +0 -169
- package/templates/subagents/pm-expert.md +0 -366
- package/templates/subagents/workflow/chief-architect.md +0 -657
- package/templates/subagents/workflow/prjct-planner.md +0 -159
- package/templates/subagents/workflow/prjct-shipper.md +0 -188
- package/templates/subagents/workflow/prjct-workflow.md +0 -98
- package/templates/tools/bash.txt +0 -22
- package/templates/tools/edit.txt +0 -18
- package/templates/tools/glob.txt +0 -19
- package/templates/tools/grep.txt +0 -21
- package/templates/tools/read.txt +0 -14
- package/templates/tools/task.txt +0 -20
- package/templates/tools/webfetch.txt +0 -16
- package/templates/tools/websearch.txt +0 -18
- package/templates/tools/write.txt +0 -17
- package/templates/windsurf/router.md +0 -28
- package/templates/windsurf/workflows/bug.md +0 -8
- package/templates/windsurf/workflows/done.md +0 -4
- package/templates/windsurf/workflows/pause.md +0 -4
- package/templates/windsurf/workflows/resume.md +0 -4
- package/templates/windsurf/workflows/ship.md +0 -8
- package/templates/windsurf/workflows/sync.md +0 -4
- package/templates/windsurf/workflows/task.md +0 -8
package/core/commands/setup.ts
DELETED
|
@@ -1,280 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Setup Commands: start, setup, installStatusLine, showAsciiArt
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import fs from 'node:fs/promises'
|
|
6
|
-
import path from 'node:path'
|
|
7
|
-
import chalk from 'chalk'
|
|
8
|
-
import commandInstaller from '../infrastructure/command-installer'
|
|
9
|
-
import pathManager from '../infrastructure/path-manager'
|
|
10
|
-
import type { CommandResult, SetupOptions } from '../types'
|
|
11
|
-
import { getErrorMessage } from '../types/fs'
|
|
12
|
-
import { fileExists } from '../utils/fs-helpers'
|
|
13
|
-
import { VERSION } from '../utils/version'
|
|
14
|
-
import { PrjctCommandsBase } from './base'
|
|
15
|
-
|
|
16
|
-
export class SetupCommands extends PrjctCommandsBase {
|
|
17
|
-
/**
|
|
18
|
-
* First-time setup - Install commands to editors
|
|
19
|
-
*/
|
|
20
|
-
async start(): Promise<CommandResult> {
|
|
21
|
-
const aiProvider = require('../infrastructure/ai-provider')
|
|
22
|
-
const activeProvider = await aiProvider.getActiveProvider()
|
|
23
|
-
|
|
24
|
-
console.log(`🚀 Setting up prjct for ${activeProvider.displayName}...\n`)
|
|
25
|
-
|
|
26
|
-
const status = await commandInstaller.checkInstallation()
|
|
27
|
-
|
|
28
|
-
if (!status.claudeDetected) {
|
|
29
|
-
// Note: variable name is legacy, checks active provider
|
|
30
|
-
return {
|
|
31
|
-
success: false,
|
|
32
|
-
message:
|
|
33
|
-
`❌ ${activeProvider.displayName} not detected.\n\nPlease install it first:\n` +
|
|
34
|
-
` - ${activeProvider.displayName}: ${activeProvider.docsUrl}`,
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
console.log('📦 Installing /p:* commands...')
|
|
39
|
-
const result = await commandInstaller.installCommands()
|
|
40
|
-
|
|
41
|
-
if (!result.success) {
|
|
42
|
-
return {
|
|
43
|
-
success: false,
|
|
44
|
-
message: `❌ Installation failed: ${result.error}`,
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
console.log(
|
|
49
|
-
`\n✅ Installed ${result.installed?.length ?? 0} commands to:\n ${pathManager.getDisplayPath(result.path || '')}`
|
|
50
|
-
)
|
|
51
|
-
|
|
52
|
-
if ((result.errors?.length ?? 0) > 0) {
|
|
53
|
-
console.log(`\n⚠️ ${result.errors?.length ?? 0} errors:`)
|
|
54
|
-
for (const e of result.errors ?? []) {
|
|
55
|
-
console.log(` - ${e.file}: ${e.error}`)
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
console.log('\n🎉 Setup complete!')
|
|
60
|
-
console.log('\nNext steps:')
|
|
61
|
-
console.log(` 1. Open ${activeProvider.displayName}`)
|
|
62
|
-
console.log(' 2. Navigate to your project')
|
|
63
|
-
console.log(' 3. Run: /p:init') // This might need adjustment for Gemini (p init) but /p:init is likely fine for now or we can make it dynamic
|
|
64
|
-
|
|
65
|
-
return {
|
|
66
|
-
success: true,
|
|
67
|
-
message: '',
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Reconfigure editor installations
|
|
73
|
-
*/
|
|
74
|
-
async setup(options: SetupOptions = {}): Promise<CommandResult> {
|
|
75
|
-
console.log('🔧 Reconfiguring prjct...\n')
|
|
76
|
-
|
|
77
|
-
if (options.force) {
|
|
78
|
-
console.log('🗑️ Removing existing installation...')
|
|
79
|
-
await commandInstaller.uninstallCommands()
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
console.log('📦 Installing /p:* commands...')
|
|
83
|
-
const result = await commandInstaller.updateCommands()
|
|
84
|
-
|
|
85
|
-
if (!result.success) {
|
|
86
|
-
return {
|
|
87
|
-
success: false,
|
|
88
|
-
message: `❌ Setup failed: ${result.error}`,
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
console.log(`\n✅ Installed ${result.installed?.length ?? 0} commands`)
|
|
93
|
-
|
|
94
|
-
if ((result.errors?.length ?? 0) > 0) {
|
|
95
|
-
console.log(`\n⚠️ ${result.errors?.length ?? 0} errors:`)
|
|
96
|
-
for (const e of result.errors ?? []) {
|
|
97
|
-
console.log(` - ${e.file}: ${e.error}`)
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
console.log('\n📝 Installing global configuration...')
|
|
102
|
-
const configResult = await commandInstaller.installGlobalConfig()
|
|
103
|
-
const displayPath = configResult.path
|
|
104
|
-
? pathManager.getDisplayPath(configResult.path)
|
|
105
|
-
: 'global config'
|
|
106
|
-
|
|
107
|
-
if (configResult.success) {
|
|
108
|
-
if (configResult.action === 'created') {
|
|
109
|
-
console.log(`✅ Created ${displayPath}`)
|
|
110
|
-
} else if (configResult.action === 'updated') {
|
|
111
|
-
console.log(`✅ Updated ${displayPath}`)
|
|
112
|
-
} else if (configResult.action === 'appended') {
|
|
113
|
-
console.log(`✅ Added prjct config to ${displayPath}`)
|
|
114
|
-
}
|
|
115
|
-
} else {
|
|
116
|
-
console.log(`⚠️ ${configResult.error}`)
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
const aiProvider = require('../infrastructure/ai-provider')
|
|
120
|
-
const activeProvider = await aiProvider.getActiveProvider()
|
|
121
|
-
|
|
122
|
-
// Status line is currently Claude-only
|
|
123
|
-
if (activeProvider.name === 'claude') {
|
|
124
|
-
console.log('\n⚡ Installing status line...')
|
|
125
|
-
const statusLineResult = await this.installStatusLine()
|
|
126
|
-
if (statusLineResult.success) {
|
|
127
|
-
console.log('✅ Status line configured')
|
|
128
|
-
} else {
|
|
129
|
-
console.log(`⚠️ ${statusLineResult.error}`)
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
console.log('\n🎉 Setup complete!\n')
|
|
134
|
-
|
|
135
|
-
this.showAsciiArt()
|
|
136
|
-
|
|
137
|
-
return {
|
|
138
|
-
success: true,
|
|
139
|
-
message: '',
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Install status line script and configure settings.json
|
|
145
|
-
*/
|
|
146
|
-
async installStatusLine(): Promise<{ success: boolean; error?: string }> {
|
|
147
|
-
try {
|
|
148
|
-
// Note: This method is currently Claude-specific
|
|
149
|
-
const claudeDir = pathManager.getClaudeDir()
|
|
150
|
-
const settingsPath = pathManager.getClaudeSettingsPath()
|
|
151
|
-
const statusLinePath = path.join(claudeDir, 'prjct-statusline.sh')
|
|
152
|
-
|
|
153
|
-
// Version is embedded at install time
|
|
154
|
-
const scriptContent = `#!/bin/bash
|
|
155
|
-
# prjct Status Line for Claude Code
|
|
156
|
-
# Shows version update notifications and current task
|
|
157
|
-
|
|
158
|
-
# Current CLI version (embedded at install time)
|
|
159
|
-
CLI_VERSION="${VERSION}"
|
|
160
|
-
|
|
161
|
-
# Read JSON context from stdin (provided by Claude Code)
|
|
162
|
-
read -r json
|
|
163
|
-
|
|
164
|
-
# Extract cwd from JSON
|
|
165
|
-
CWD=$(echo "$json" | grep -o '"cwd"[[:space:]]*:[[:space:]]*"[^"]*"' | sed 's/.*"cwd"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/')
|
|
166
|
-
|
|
167
|
-
# Check if this is a prjct project
|
|
168
|
-
CONFIG="$CWD/.prjct/prjct.config.json"
|
|
169
|
-
if [[ -f "$CONFIG" ]]; then
|
|
170
|
-
# Extract projectId
|
|
171
|
-
PROJECT_ID=$(grep -o '"projectId"[[:space:]]*:[[:space:]]*"[^"]*"' "$CONFIG" | sed 's/.*"projectId"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/')
|
|
172
|
-
|
|
173
|
-
if [[ -n "$PROJECT_ID" ]]; then
|
|
174
|
-
PROJECT_JSON="$HOME/.prjct-cli/projects/$PROJECT_ID/project.json"
|
|
175
|
-
|
|
176
|
-
# Check version mismatch
|
|
177
|
-
if [[ -f "$PROJECT_JSON" ]]; then
|
|
178
|
-
PROJECT_VERSION=$(grep -o '"cliVersion"[[:space:]]*:[[:space:]]*"[^"]*"' "$PROJECT_JSON" | sed 's/.*"cliVersion"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/')
|
|
179
|
-
|
|
180
|
-
# If no cliVersion or different version, show update notice
|
|
181
|
-
if [[ -z "$PROJECT_VERSION" ]] || [[ "$PROJECT_VERSION" != "$CLI_VERSION" ]]; then
|
|
182
|
-
echo "⚠️ prjct v$CLI_VERSION available! Run /p:sync"
|
|
183
|
-
exit 0
|
|
184
|
-
fi
|
|
185
|
-
else
|
|
186
|
-
# No project.json means project needs sync
|
|
187
|
-
echo "⚠️ prjct v$CLI_VERSION available! Run /p:sync"
|
|
188
|
-
exit 0
|
|
189
|
-
fi
|
|
190
|
-
|
|
191
|
-
# Show current task if exists
|
|
192
|
-
STATE="$HOME/.prjct-cli/projects/$PROJECT_ID/storage/state.json"
|
|
193
|
-
if [[ -f "$STATE" ]]; then
|
|
194
|
-
TASK=$(grep -o '"description"[[:space:]]*:[[:space:]]*"[^"]*"' "$STATE" | head -1 | sed 's/.*"description"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/')
|
|
195
|
-
STATUS=$(grep -o '"status"[[:space:]]*:[[:space:]]*"[^"]*"' "$STATE" | head -1 | sed 's/.*"status"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/')
|
|
196
|
-
|
|
197
|
-
if [[ -n "$TASK" ]] && [[ "$STATUS" == "active" ]]; then
|
|
198
|
-
# Truncate task to 40 chars
|
|
199
|
-
TASK_SHORT="\${TASK:0:40}"
|
|
200
|
-
[[ \${#TASK} -gt 40 ]] && TASK_SHORT="$TASK_SHORT..."
|
|
201
|
-
echo "🎯 $TASK_SHORT"
|
|
202
|
-
exit 0
|
|
203
|
-
fi
|
|
204
|
-
fi
|
|
205
|
-
fi
|
|
206
|
-
fi
|
|
207
|
-
|
|
208
|
-
# Default: show prjct branding
|
|
209
|
-
echo "⚡ prjct"
|
|
210
|
-
`
|
|
211
|
-
await fs.writeFile(statusLinePath, scriptContent, { mode: 0o755 })
|
|
212
|
-
|
|
213
|
-
let settings: Record<string, unknown> = {}
|
|
214
|
-
if (await fileExists(settingsPath)) {
|
|
215
|
-
try {
|
|
216
|
-
settings = JSON.parse(await fs.readFile(settingsPath, 'utf8'))
|
|
217
|
-
} catch (_error) {
|
|
218
|
-
// Invalid JSON, start fresh
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
settings.statusLine = {
|
|
223
|
-
type: 'command',
|
|
224
|
-
command: statusLinePath,
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
await fs.writeFile(settingsPath, JSON.stringify(settings, null, 2))
|
|
228
|
-
|
|
229
|
-
return { success: true }
|
|
230
|
-
} catch (error) {
|
|
231
|
-
return { success: false, error: getErrorMessage(error) }
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
/**
|
|
236
|
-
* Show beautiful ASCII art with quick start
|
|
237
|
-
*/
|
|
238
|
-
showAsciiArt(): void {
|
|
239
|
-
console.log(chalk.cyan('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'))
|
|
240
|
-
console.log('')
|
|
241
|
-
console.log(chalk.bold.cyan(' ██████╗ ██████╗ ██╗ ██████╗████████╗'))
|
|
242
|
-
console.log(chalk.bold.cyan(' ██╔══██╗██╔══██╗ ██║██╔════╝╚══██╔══╝'))
|
|
243
|
-
console.log(chalk.bold.cyan(' ██████╔╝██████╔╝ ██║██║ ██║'))
|
|
244
|
-
console.log(chalk.bold.cyan(' ██╔═══╝ ██╔══██╗██ ██║██║ ██║'))
|
|
245
|
-
console.log(chalk.bold.cyan(' ██║ ██║ ██║╚█████╔╝╚██████╗ ██║'))
|
|
246
|
-
console.log(chalk.bold.cyan(' ╚═╝ ╚═╝ ╚═╝ ╚════╝ ╚═════╝ ╚═╝'))
|
|
247
|
-
console.log('')
|
|
248
|
-
console.log(
|
|
249
|
-
` ${chalk.bold.cyan('prjct')}${chalk.magenta('/')}${chalk.green('cli')} ${chalk.dim.white(`v${VERSION} installed`)}`
|
|
250
|
-
)
|
|
251
|
-
console.log('')
|
|
252
|
-
console.log(` ${chalk.yellow('⚡')} Ship faster with zero friction`)
|
|
253
|
-
console.log(` ${chalk.green('📝')} From idea to technical tasks in minutes`)
|
|
254
|
-
console.log(` ${chalk.cyan('🤖')} Perfect context for AI agents`)
|
|
255
|
-
console.log('')
|
|
256
|
-
console.log(chalk.cyan('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'))
|
|
257
|
-
console.log('')
|
|
258
|
-
console.log(chalk.bold.cyan('🚀 Quick Start'))
|
|
259
|
-
console.log(chalk.dim('─────────────────────────────────────────────────'))
|
|
260
|
-
console.log('')
|
|
261
|
-
console.log(` ${chalk.bold('1.')} Initialize your project:`)
|
|
262
|
-
console.log(` ${chalk.green('cd your-project && prjct init')}`)
|
|
263
|
-
console.log('')
|
|
264
|
-
console.log(` ${chalk.bold('2.')} Start your first task:`)
|
|
265
|
-
console.log(` ${chalk.green('prjct task "build auth"')}`)
|
|
266
|
-
console.log('')
|
|
267
|
-
console.log(` ${chalk.bold('3.')} Ship & celebrate:`)
|
|
268
|
-
console.log(` ${chalk.green('prjct ship "user login"')}`)
|
|
269
|
-
console.log('')
|
|
270
|
-
console.log(chalk.dim('─────────────────────────────────────────────────'))
|
|
271
|
-
console.log('')
|
|
272
|
-
console.log(` ${chalk.dim('Documentation:')} ${chalk.cyan('https://prjct.app')}`)
|
|
273
|
-
console.log(
|
|
274
|
-
` ${chalk.dim('Report issues:')} ${chalk.cyan('https://github.com/jlopezlira/prjct-cli/issues')}`
|
|
275
|
-
)
|
|
276
|
-
console.log('')
|
|
277
|
-
console.log(chalk.bold.magenta('Happy shipping! 🚀'))
|
|
278
|
-
console.log('')
|
|
279
|
-
}
|
|
280
|
-
}
|
|
@@ -1,267 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shipping Commands: ship and related helpers
|
|
3
|
-
* Write-Through Architecture: JSON → MD → Event
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import path from 'node:path'
|
|
7
|
-
import memorySystem from '../agentic/memory-system'
|
|
8
|
-
import { shippedStorage, stateStorage } from '../storage'
|
|
9
|
-
import type { CommandResult } from '../types'
|
|
10
|
-
import { getErrorMessage, isNotFoundError } from '../types/fs'
|
|
11
|
-
import { showNextSteps } from '../utils/next-steps'
|
|
12
|
-
import { detectProjectCommands } from '../utils/project-commands'
|
|
13
|
-
import { runWorkflowHooks } from '../workflow/workflow-preferences'
|
|
14
|
-
import { configManager, dateHelper, fileHelper, out, PrjctCommandsBase, toolRegistry } from './base'
|
|
15
|
-
|
|
16
|
-
export class ShippingCommands extends PrjctCommandsBase {
|
|
17
|
-
/**
|
|
18
|
-
* Run a command and capture exit code without throwing.
|
|
19
|
-
*
|
|
20
|
-
* Reason: `toolRegistry.Bash` swallows non-zero exits into stderr; we still want a reliable success flag.
|
|
21
|
-
*/
|
|
22
|
-
private async _runWithExitCode(command: string): Promise<{ exitCode: number; output: string }> {
|
|
23
|
-
const bash = toolRegistry.get('Bash')!
|
|
24
|
-
const escaped = command.replace(/"/g, '\\"')
|
|
25
|
-
const wrapped = `bash -lc "set +e; ${escaped} 2>&1; echo __EXIT:$?"`
|
|
26
|
-
const result = (await bash(wrapped)) as { stdout: string; stderr: string }
|
|
27
|
-
const output = `${result.stdout}\n${result.stderr}`.trim()
|
|
28
|
-
|
|
29
|
-
const lines = output.split('\n')
|
|
30
|
-
let marker: string | undefined
|
|
31
|
-
for (let i = lines.length - 1; i >= 0; i--) {
|
|
32
|
-
if (lines[i].startsWith('__EXIT:')) {
|
|
33
|
-
marker = lines[i]
|
|
34
|
-
break
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
const exitCode = marker ? Number(marker.replace('__EXIT:', '').trim()) : 1
|
|
38
|
-
|
|
39
|
-
// Remove marker from output for cleaner logs
|
|
40
|
-
const cleaned = output
|
|
41
|
-
.split('\n')
|
|
42
|
-
.filter((line) => !line.startsWith('__EXIT:'))
|
|
43
|
-
.join('\n')
|
|
44
|
-
.trim()
|
|
45
|
-
|
|
46
|
-
return { exitCode: Number.isFinite(exitCode) ? exitCode : 1, output: cleaned }
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* /p:ship - Ship feature with complete automated workflow
|
|
51
|
-
*/
|
|
52
|
-
async ship(
|
|
53
|
-
feature: string | null,
|
|
54
|
-
projectPath: string = process.cwd(),
|
|
55
|
-
options: { skipHooks?: boolean } = {}
|
|
56
|
-
): Promise<CommandResult> {
|
|
57
|
-
try {
|
|
58
|
-
const initResult = await this.ensureProjectInit(projectPath)
|
|
59
|
-
if (!initResult.success) return initResult
|
|
60
|
-
|
|
61
|
-
const projectId = await configManager.getProjectId(projectPath)
|
|
62
|
-
if (!projectId) {
|
|
63
|
-
out.failWithHint('NO_PROJECT_ID')
|
|
64
|
-
return { success: false, error: 'No project ID found' }
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
let featureName = feature
|
|
68
|
-
if (!featureName) {
|
|
69
|
-
// Read from storage (JSON is source of truth)
|
|
70
|
-
const currentTask = await stateStorage.getCurrentTask(projectId)
|
|
71
|
-
featureName = currentTask?.description || 'current work'
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Run before_ship hooks (using memory-based preferences)
|
|
75
|
-
const beforeResult = await runWorkflowHooks(projectId, 'before', 'ship', {
|
|
76
|
-
projectPath,
|
|
77
|
-
skipHooks: options.skipHooks,
|
|
78
|
-
})
|
|
79
|
-
if (!beforeResult.success) {
|
|
80
|
-
return { success: false, error: `Hook failed: ${beforeResult.failed}` }
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Ship steps with progress indicator
|
|
84
|
-
out.step(1, 5, `Linting ${featureName}...`)
|
|
85
|
-
const lintResult = await this._runLint(projectPath)
|
|
86
|
-
|
|
87
|
-
out.step(2, 5, 'Running tests...')
|
|
88
|
-
const testResult = await this._runTests(projectPath)
|
|
89
|
-
|
|
90
|
-
out.step(3, 5, 'Updating version...')
|
|
91
|
-
const newVersion = await this._bumpVersion(projectPath)
|
|
92
|
-
await this._updateChangelog(featureName, newVersion, projectPath)
|
|
93
|
-
|
|
94
|
-
out.step(4, 5, 'Committing...')
|
|
95
|
-
const commitResult = await this._createShipCommit(featureName, projectPath)
|
|
96
|
-
|
|
97
|
-
if (commitResult.success) {
|
|
98
|
-
out.step(5, 5, 'Pushing...')
|
|
99
|
-
await this._gitPush(projectPath)
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// Write-through: Record shipped feature (JSON → MD → Event)
|
|
103
|
-
await shippedStorage.addShipped(projectId, {
|
|
104
|
-
name: featureName,
|
|
105
|
-
version: newVersion,
|
|
106
|
-
})
|
|
107
|
-
|
|
108
|
-
await this.logToMemory(projectPath, 'feature_shipped', {
|
|
109
|
-
feature: featureName,
|
|
110
|
-
version: newVersion,
|
|
111
|
-
timestamp: dateHelper.getTimestamp(),
|
|
112
|
-
})
|
|
113
|
-
|
|
114
|
-
await memorySystem.learnDecision(projectId, 'commit_footer', 'prjct', 'ship')
|
|
115
|
-
|
|
116
|
-
if (testResult.success) {
|
|
117
|
-
await memorySystem.recordDecision(projectId, 'test_before_ship', 'true', 'ship')
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
const isQuickShip = !lintResult.success || !testResult.success
|
|
121
|
-
if (isQuickShip) {
|
|
122
|
-
await memorySystem.recordWorkflow(projectId, 'quick_ship', {
|
|
123
|
-
description: 'Ship without full checks',
|
|
124
|
-
feature_type: featureName.toLowerCase().includes('doc') ? 'docs' : 'other',
|
|
125
|
-
})
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// Run after_ship hooks
|
|
129
|
-
await runWorkflowHooks(projectId, 'after', 'ship', {
|
|
130
|
-
projectPath,
|
|
131
|
-
skipHooks: options.skipHooks,
|
|
132
|
-
})
|
|
133
|
-
|
|
134
|
-
out.done(`v${newVersion} shipped`)
|
|
135
|
-
showNextSteps('ship')
|
|
136
|
-
|
|
137
|
-
return { success: true, feature: featureName, version: newVersion }
|
|
138
|
-
} catch (error) {
|
|
139
|
-
out.fail(getErrorMessage(error))
|
|
140
|
-
return { success: false, error: getErrorMessage(error) }
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Run lint checks
|
|
146
|
-
*/
|
|
147
|
-
async _runLint(projectPath: string): Promise<{ success: boolean; message: string }> {
|
|
148
|
-
try {
|
|
149
|
-
const detected = await detectProjectCommands(projectPath)
|
|
150
|
-
if (!detected.lint) return { success: true, message: 'skipped (no lint detected)' }
|
|
151
|
-
|
|
152
|
-
const { exitCode } = await this._runWithExitCode(detected.lint.command)
|
|
153
|
-
return { success: exitCode === 0, message: exitCode === 0 ? 'passed' : 'failed' }
|
|
154
|
-
} catch (error) {
|
|
155
|
-
// Lint detection/execution failed - skip gracefully
|
|
156
|
-
if (isNotFoundError(error)) {
|
|
157
|
-
return { success: true, message: 'skipped (lint not found)' }
|
|
158
|
-
}
|
|
159
|
-
return { success: true, message: 'skipped (lint detection failed)' }
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Run tests
|
|
165
|
-
*/
|
|
166
|
-
async _runTests(projectPath: string): Promise<{ success: boolean; message: string }> {
|
|
167
|
-
try {
|
|
168
|
-
const detected = await detectProjectCommands(projectPath)
|
|
169
|
-
if (!detected.test) return { success: true, message: 'skipped (no tests detected)' }
|
|
170
|
-
|
|
171
|
-
const { exitCode } = await this._runWithExitCode(detected.test.command)
|
|
172
|
-
return { success: exitCode === 0, message: exitCode === 0 ? 'passed' : 'failed' }
|
|
173
|
-
} catch (error) {
|
|
174
|
-
// Test detection/execution failed - skip gracefully
|
|
175
|
-
if (isNotFoundError(error)) {
|
|
176
|
-
return { success: true, message: 'skipped (tests not found)' }
|
|
177
|
-
}
|
|
178
|
-
return { success: true, message: 'skipped (test detection failed)' }
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Bump version
|
|
184
|
-
*/
|
|
185
|
-
async _bumpVersion(projectPath: string): Promise<string> {
|
|
186
|
-
try {
|
|
187
|
-
const pkgPath = path.join(projectPath, 'package.json')
|
|
188
|
-
const pkg = await fileHelper.readJson<{ version?: string }>(pkgPath, { version: '0.0.0' })
|
|
189
|
-
const oldVersion = pkg?.version || '0.0.0'
|
|
190
|
-
const [major, minor, patch] = oldVersion.split('.').map(Number)
|
|
191
|
-
const newVersion = `${major}.${minor}.${patch + 1}`
|
|
192
|
-
if (pkg) {
|
|
193
|
-
pkg.version = newVersion
|
|
194
|
-
await fileHelper.writeJson(pkgPath, pkg)
|
|
195
|
-
}
|
|
196
|
-
return newVersion
|
|
197
|
-
} catch (error) {
|
|
198
|
-
// No package.json or parse error - return default version
|
|
199
|
-
if (isNotFoundError(error) || error instanceof SyntaxError) {
|
|
200
|
-
return '0.0.1'
|
|
201
|
-
}
|
|
202
|
-
throw error
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Update CHANGELOG
|
|
208
|
-
*/
|
|
209
|
-
async _updateChangelog(feature: string, version: string, projectPath: string): Promise<void> {
|
|
210
|
-
try {
|
|
211
|
-
const changelogPath = path.join(projectPath, 'CHANGELOG.md')
|
|
212
|
-
const changelog = await fileHelper.readFile(changelogPath, '# Changelog\n\n')
|
|
213
|
-
|
|
214
|
-
const entry = `## [${version}] - ${dateHelper.formatDate(new Date())}\n\n### Added\n- ${feature}\n\n`
|
|
215
|
-
const updated = changelog.replace('# Changelog\n\n', `# Changelog\n\n${entry}`)
|
|
216
|
-
|
|
217
|
-
await fileHelper.writeFile(changelogPath, updated)
|
|
218
|
-
} catch (error) {
|
|
219
|
-
// CHANGELOG doesn't exist or can't be written - warn but continue
|
|
220
|
-
if (isNotFoundError(error)) {
|
|
221
|
-
console.error(' Warning: CHANGELOG.md not found')
|
|
222
|
-
} else {
|
|
223
|
-
console.error(' Warning: Could not update CHANGELOG')
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* Create git commit for ship
|
|
230
|
-
*/
|
|
231
|
-
async _createShipCommit(
|
|
232
|
-
feature: string,
|
|
233
|
-
_projectPath: string
|
|
234
|
-
): Promise<{ success: boolean; message: string }> {
|
|
235
|
-
try {
|
|
236
|
-
await toolRegistry.get('Bash')!('git add .')
|
|
237
|
-
|
|
238
|
-
const commitMsg = `feat: ${feature}\n\nGenerated with [p/](https://www.prjct.app/)`
|
|
239
|
-
|
|
240
|
-
await toolRegistry.get('Bash')!(`git commit -m "${commitMsg.replace(/"/g, '\\"')}"`)
|
|
241
|
-
|
|
242
|
-
return { success: true, message: 'Committed' }
|
|
243
|
-
} catch (error) {
|
|
244
|
-
// Git commit failed - likely no changes or not a repo
|
|
245
|
-
if (isNotFoundError(error)) {
|
|
246
|
-
return { success: false, message: 'Git not found' }
|
|
247
|
-
}
|
|
248
|
-
return { success: false, message: 'No changes to commit' }
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
* Push to remote
|
|
254
|
-
*/
|
|
255
|
-
async _gitPush(_projectPath: string): Promise<{ success: boolean; message: string }> {
|
|
256
|
-
try {
|
|
257
|
-
await toolRegistry.get('Bash')!('git push')
|
|
258
|
-
return { success: true, message: 'Pushed to remote' }
|
|
259
|
-
} catch (error) {
|
|
260
|
-
// Git push failed - no remote, auth issue, or git not found
|
|
261
|
-
if (isNotFoundError(error)) {
|
|
262
|
-
return { success: false, message: 'Git not found' }
|
|
263
|
-
}
|
|
264
|
-
return { success: false, message: 'Push failed (no remote or auth issue)' }
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
}
|