prjct-cli 1.22.0 → 1.24.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 +230 -0
- package/bin/prjct +30 -13
- package/dist/bin/prjct-core.mjs +1748 -0
- package/dist/bin/prjct.mjs +17 -36672
- package/dist/cli/linear.mjs +14 -0
- package/dist/daemon/entry.mjs +1429 -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
|
@@ -1,385 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AgentGenerator - Domain and workflow agent generation
|
|
3
|
-
*
|
|
4
|
-
* Extracted from sync-service.ts for single responsibility.
|
|
5
|
-
* Generates agent markdown files based on project stack.
|
|
6
|
-
*
|
|
7
|
-
* @version 1.0.0
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import fs from 'node:fs/promises'
|
|
11
|
-
import path from 'node:path'
|
|
12
|
-
import {
|
|
13
|
-
hasPreservedSections,
|
|
14
|
-
mergePreservedSections,
|
|
15
|
-
validatePreserveBlocks,
|
|
16
|
-
} from '../utils/preserve-sections'
|
|
17
|
-
import { defaultToolRetryPolicy } from '../utils/retry'
|
|
18
|
-
import type { StackDetection } from './stack-detector'
|
|
19
|
-
|
|
20
|
-
// ============================================================================
|
|
21
|
-
// TYPES
|
|
22
|
-
// ============================================================================
|
|
23
|
-
|
|
24
|
-
export interface AgentInfo {
|
|
25
|
-
name: string
|
|
26
|
-
type: 'workflow' | 'domain'
|
|
27
|
-
skill?: string
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export interface ProjectStats {
|
|
31
|
-
fileCount: number
|
|
32
|
-
version: string
|
|
33
|
-
name: string
|
|
34
|
-
ecosystem: string
|
|
35
|
-
projectType: string
|
|
36
|
-
languages: string[]
|
|
37
|
-
frameworks: string[]
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/** Aggregated task feedback for agent generation (PRJ-272) */
|
|
41
|
-
export interface TaskFeedbackContext {
|
|
42
|
-
patternsDiscovered: string[]
|
|
43
|
-
knownGotchas: string[]
|
|
44
|
-
agentAccuracy: Array<{ agent: string; rating: string; note?: string }>
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// ============================================================================
|
|
48
|
-
// AGENT GENERATOR CLASS
|
|
49
|
-
// ============================================================================
|
|
50
|
-
|
|
51
|
-
export class AgentGenerator {
|
|
52
|
-
private agentsPath: string
|
|
53
|
-
private templatesPath: string
|
|
54
|
-
|
|
55
|
-
constructor(agentsPath: string, templatesPath?: string) {
|
|
56
|
-
this.agentsPath = agentsPath
|
|
57
|
-
this.templatesPath = templatesPath || path.join(__dirname, '..', '..', 'templates', 'subagents')
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/** Task feedback context for agent generation (PRJ-272) */
|
|
61
|
-
private feedbackContext?: TaskFeedbackContext
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Generate all agents based on stack detection
|
|
65
|
-
* Optionally accepts task feedback to influence agent content (PRJ-272)
|
|
66
|
-
*/
|
|
67
|
-
async generate(
|
|
68
|
-
stack: StackDetection,
|
|
69
|
-
stats: ProjectStats,
|
|
70
|
-
feedbackContext?: TaskFeedbackContext
|
|
71
|
-
): Promise<AgentInfo[]> {
|
|
72
|
-
const agents: AgentInfo[] = []
|
|
73
|
-
this.feedbackContext = feedbackContext
|
|
74
|
-
|
|
75
|
-
// Purge old agents
|
|
76
|
-
await this.purgeOldAgents()
|
|
77
|
-
|
|
78
|
-
// Workflow agents (always generated) - IN PARALLEL
|
|
79
|
-
const workflowAgents = await this.generateWorkflowAgents()
|
|
80
|
-
agents.push(...workflowAgents)
|
|
81
|
-
|
|
82
|
-
// Domain agents (based on stack) - IN PARALLEL
|
|
83
|
-
const domainAgents = await this.generateDomainAgents(stack, stats)
|
|
84
|
-
agents.push(...domainAgents)
|
|
85
|
-
|
|
86
|
-
return agents
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Cache of existing agent content (for preserving user sections)
|
|
91
|
-
*/
|
|
92
|
-
private existingAgents: Map<string, string> = new Map()
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Read existing agents and cache their content for preservation
|
|
96
|
-
* Then remove the files (they'll be regenerated with preserved sections)
|
|
97
|
-
*/
|
|
98
|
-
private async purgeOldAgents(): Promise<void> {
|
|
99
|
-
this.existingAgents.clear()
|
|
100
|
-
|
|
101
|
-
try {
|
|
102
|
-
const files = await fs.readdir(this.agentsPath)
|
|
103
|
-
const mdFiles = files.filter((file) => file.endsWith('.md'))
|
|
104
|
-
|
|
105
|
-
// Read all existing agent files BEFORE deleting
|
|
106
|
-
await Promise.all(
|
|
107
|
-
mdFiles.map(async (file) => {
|
|
108
|
-
const filePath = path.join(this.agentsPath, file)
|
|
109
|
-
try {
|
|
110
|
-
const content = await fs.readFile(filePath, 'utf-8')
|
|
111
|
-
// Only cache if it has user-preserved sections
|
|
112
|
-
if (hasPreservedSections(content)) {
|
|
113
|
-
this.existingAgents.set(file, content)
|
|
114
|
-
}
|
|
115
|
-
} catch {
|
|
116
|
-
// File read failed, skip
|
|
117
|
-
}
|
|
118
|
-
})
|
|
119
|
-
)
|
|
120
|
-
|
|
121
|
-
// Now delete the files
|
|
122
|
-
await Promise.all(mdFiles.map((file) => fs.unlink(path.join(this.agentsPath, file))))
|
|
123
|
-
} catch {
|
|
124
|
-
// Directory might not exist yet
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Write agent file, preserving user sections from previous version
|
|
130
|
-
*/
|
|
131
|
-
private async writeAgentWithPreservation(filename: string, content: string): Promise<void> {
|
|
132
|
-
const existingContent = this.existingAgents.get(filename)
|
|
133
|
-
|
|
134
|
-
let finalContent = content
|
|
135
|
-
if (existingContent) {
|
|
136
|
-
// Validate existing preserved blocks
|
|
137
|
-
const validation = validatePreserveBlocks(existingContent)
|
|
138
|
-
if (!validation.valid) {
|
|
139
|
-
console.warn(`⚠️ Agent ${filename} has invalid preserve blocks:`)
|
|
140
|
-
for (const error of validation.errors) {
|
|
141
|
-
console.warn(` ${error}`)
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// Merge preserved sections from old content
|
|
146
|
-
finalContent = mergePreservedSections(content, existingContent)
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
await fs.writeFile(path.join(this.agentsPath, filename), finalContent, 'utf-8')
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Generate workflow agents (always included)
|
|
154
|
-
*/
|
|
155
|
-
private async generateWorkflowAgents(): Promise<AgentInfo[]> {
|
|
156
|
-
const workflowAgentNames = ['prjct-workflow', 'prjct-planner', 'prjct-shipper']
|
|
157
|
-
|
|
158
|
-
await Promise.all(workflowAgentNames.map((name) => this.generateWorkflowAgent(name)))
|
|
159
|
-
|
|
160
|
-
return workflowAgentNames.map((name) => ({ name, type: 'workflow' as const }))
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Generate domain agents based on stack
|
|
165
|
-
*/
|
|
166
|
-
private async generateDomainAgents(
|
|
167
|
-
stack: StackDetection,
|
|
168
|
-
stats: ProjectStats
|
|
169
|
-
): Promise<AgentInfo[]> {
|
|
170
|
-
const agentsToGenerate: { name: string; skill?: string }[] = []
|
|
171
|
-
|
|
172
|
-
if (stack.hasFrontend) {
|
|
173
|
-
agentsToGenerate.push({ name: 'frontend', skill: 'javascript-typescript' })
|
|
174
|
-
agentsToGenerate.push({ name: 'uxui', skill: 'frontend-design' })
|
|
175
|
-
}
|
|
176
|
-
if (stack.hasBackend) {
|
|
177
|
-
agentsToGenerate.push({ name: 'backend', skill: 'javascript-typescript' })
|
|
178
|
-
}
|
|
179
|
-
if (stack.hasDatabase) {
|
|
180
|
-
agentsToGenerate.push({ name: 'database' })
|
|
181
|
-
}
|
|
182
|
-
if (stack.hasTesting) {
|
|
183
|
-
agentsToGenerate.push({ name: 'testing', skill: 'developer-kit' })
|
|
184
|
-
}
|
|
185
|
-
if (stack.hasDocker) {
|
|
186
|
-
agentsToGenerate.push({ name: 'devops', skill: 'developer-kit' })
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
// Generate all domain agents IN PARALLEL with individual retry
|
|
190
|
-
// Using Promise.allSettled() so one failure doesn't block others
|
|
191
|
-
const results = await Promise.allSettled(
|
|
192
|
-
agentsToGenerate.map((agent) =>
|
|
193
|
-
defaultToolRetryPolicy.execute(
|
|
194
|
-
async () => await this.generateDomainAgent(agent.name, stats, stack),
|
|
195
|
-
`generate-agent-${agent.name}`
|
|
196
|
-
)
|
|
197
|
-
)
|
|
198
|
-
)
|
|
199
|
-
|
|
200
|
-
// Track which agents succeeded and which failed
|
|
201
|
-
const successfulAgents: AgentInfo[] = []
|
|
202
|
-
const failedAgents: string[] = []
|
|
203
|
-
|
|
204
|
-
for (let i = 0; i < results.length; i++) {
|
|
205
|
-
const result = results[i]
|
|
206
|
-
const agent = agentsToGenerate[i]
|
|
207
|
-
|
|
208
|
-
if (result.status === 'fulfilled') {
|
|
209
|
-
successfulAgents.push({
|
|
210
|
-
name: agent.name,
|
|
211
|
-
type: 'domain' as const,
|
|
212
|
-
skill: agent.skill,
|
|
213
|
-
})
|
|
214
|
-
} else {
|
|
215
|
-
failedAgents.push(agent.name)
|
|
216
|
-
// Log failure but continue (don't throw)
|
|
217
|
-
console.warn(`[prjct] Warning: Failed to generate agent: ${agent.name}`)
|
|
218
|
-
if (result.reason) {
|
|
219
|
-
console.warn(`[prjct] Reason: ${result.reason.message || result.reason}`)
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
return successfulAgents
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* Generate a single workflow agent
|
|
229
|
-
*/
|
|
230
|
-
private async generateWorkflowAgent(name: string): Promise<void> {
|
|
231
|
-
let content = ''
|
|
232
|
-
|
|
233
|
-
try {
|
|
234
|
-
const templatePath = path.join(this.templatesPath, 'workflow', `${name}.md`)
|
|
235
|
-
content = await fs.readFile(templatePath, 'utf-8')
|
|
236
|
-
} catch {
|
|
237
|
-
// Generate minimal agent
|
|
238
|
-
content = this.generateMinimalWorkflowAgent(name)
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
await this.writeAgentWithPreservation(`${name}.md`, content)
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* Generate a single domain agent
|
|
246
|
-
* Injects task feedback learnings when available (PRJ-272)
|
|
247
|
-
*/
|
|
248
|
-
private async generateDomainAgent(
|
|
249
|
-
name: string,
|
|
250
|
-
stats: ProjectStats,
|
|
251
|
-
stack: StackDetection
|
|
252
|
-
): Promise<void> {
|
|
253
|
-
let content = ''
|
|
254
|
-
|
|
255
|
-
try {
|
|
256
|
-
const templatePath = path.join(this.templatesPath, 'domain', `${name}.md`)
|
|
257
|
-
content = await fs.readFile(templatePath, 'utf-8')
|
|
258
|
-
|
|
259
|
-
// Inject project-specific context
|
|
260
|
-
content = content.replace('{projectName}', stats.name)
|
|
261
|
-
content = content.replace('{frameworks}', stack.frameworks.join(', ') || 'None detected')
|
|
262
|
-
content = content.replace('{ecosystem}', stats.ecosystem)
|
|
263
|
-
} catch {
|
|
264
|
-
// Generate minimal agent
|
|
265
|
-
content = this.generateMinimalDomainAgent(name, stats, stack)
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
// Inject task feedback learnings (PRJ-272)
|
|
269
|
-
content = this.injectFeedbackSection(content, name)
|
|
270
|
-
|
|
271
|
-
await this.writeAgentWithPreservation(`${name}.md`, content)
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
/**
|
|
275
|
-
* Inject a "Recent Learnings" section into agent content from task feedback (PRJ-272)
|
|
276
|
-
* Only injects if there are relevant patterns, gotchas, or agent accuracy notes
|
|
277
|
-
*/
|
|
278
|
-
private injectFeedbackSection(content: string, agentName: string): string {
|
|
279
|
-
if (!this.feedbackContext) return content
|
|
280
|
-
|
|
281
|
-
const { patternsDiscovered, knownGotchas, agentAccuracy } = this.feedbackContext
|
|
282
|
-
|
|
283
|
-
// Filter agent accuracy notes relevant to this agent
|
|
284
|
-
const agentNotes = agentAccuracy.filter(
|
|
285
|
-
(a) => a.agent === `${agentName}.md` || a.agent === agentName
|
|
286
|
-
)
|
|
287
|
-
|
|
288
|
-
const hasContent =
|
|
289
|
-
patternsDiscovered.length > 0 || knownGotchas.length > 0 || agentNotes.length > 0
|
|
290
|
-
|
|
291
|
-
if (!hasContent) return content
|
|
292
|
-
|
|
293
|
-
const lines: string[] = ['\n## Recent Learnings (from completed tasks)\n']
|
|
294
|
-
|
|
295
|
-
if (patternsDiscovered.length > 0) {
|
|
296
|
-
lines.push('### Discovered Patterns')
|
|
297
|
-
for (const pattern of patternsDiscovered) {
|
|
298
|
-
lines.push(`- ${pattern}`)
|
|
299
|
-
}
|
|
300
|
-
lines.push('')
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
if (knownGotchas.length > 0) {
|
|
304
|
-
lines.push('### Known Gotchas')
|
|
305
|
-
for (const gotcha of knownGotchas) {
|
|
306
|
-
lines.push(`- ${gotcha}`)
|
|
307
|
-
}
|
|
308
|
-
lines.push('')
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
if (agentNotes.length > 0) {
|
|
312
|
-
lines.push('### Agent Accuracy Notes')
|
|
313
|
-
for (const note of agentNotes) {
|
|
314
|
-
const desc = note.note ? ` — ${note.note}` : ''
|
|
315
|
-
lines.push(`- ${note.rating}${desc}`)
|
|
316
|
-
}
|
|
317
|
-
lines.push('')
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
return content + lines.join('\n')
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* Generate minimal workflow agent content
|
|
325
|
-
*/
|
|
326
|
-
private generateMinimalWorkflowAgent(name: string): string {
|
|
327
|
-
const descriptions: Record<string, string> = {
|
|
328
|
-
'prjct-workflow': 'Task lifecycle: now, done, pause, resume',
|
|
329
|
-
'prjct-planner': 'Planning: task, prd, spec, bug',
|
|
330
|
-
'prjct-shipper': 'Shipping: ship, merge, review',
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
return `---
|
|
334
|
-
name: ${name}
|
|
335
|
-
description: ${descriptions[name] || 'Workflow agent'}
|
|
336
|
-
tools: Read, Write, Glob
|
|
337
|
-
---
|
|
338
|
-
|
|
339
|
-
# ${name.toUpperCase()}
|
|
340
|
-
|
|
341
|
-
Workflow agent for prjct operations.
|
|
342
|
-
|
|
343
|
-
## Project Context
|
|
344
|
-
|
|
345
|
-
When invoked:
|
|
346
|
-
1. Read \`.prjct/prjct.config.json\` → extract \`projectId\`
|
|
347
|
-
2. Read \`~/.prjct-cli/projects/{projectId}/storage/state.json\`
|
|
348
|
-
3. Execute requested operation
|
|
349
|
-
`
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
/**
|
|
353
|
-
* Generate minimal domain agent content
|
|
354
|
-
*/
|
|
355
|
-
private generateMinimalDomainAgent(
|
|
356
|
-
name: string,
|
|
357
|
-
stats: ProjectStats,
|
|
358
|
-
stack: StackDetection
|
|
359
|
-
): string {
|
|
360
|
-
return `---
|
|
361
|
-
name: ${name}
|
|
362
|
-
description: ${name.charAt(0).toUpperCase() + name.slice(1)} specialist for ${stats.name}
|
|
363
|
-
tools: Read, Write, Glob, Grep
|
|
364
|
-
skills: []
|
|
365
|
-
---
|
|
366
|
-
|
|
367
|
-
# ${name.toUpperCase()} AGENT
|
|
368
|
-
|
|
369
|
-
Domain specialist for ${name} tasks.
|
|
370
|
-
|
|
371
|
-
## Project Context
|
|
372
|
-
|
|
373
|
-
- **Project**: ${stats.name}
|
|
374
|
-
- **Ecosystem**: ${stats.ecosystem}
|
|
375
|
-
- **Frameworks**: ${stack.frameworks.join(', ') || 'None detected'}
|
|
376
|
-
|
|
377
|
-
## Your Role
|
|
378
|
-
|
|
379
|
-
You are the ${name} expert for this project. Apply best practices for the detected stack.
|
|
380
|
-
`
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
export const createAgentGenerator = (agentsPath: string) => new AgentGenerator(agentsPath)
|
|
385
|
-
export default AgentGenerator
|
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AgentService - Agent initialization and task assignment
|
|
3
|
-
*
|
|
4
|
-
* Handles agent detection, initialization, and routing tasks to appropriate agents.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import AgentRouter from '../agentic/agent-router'
|
|
8
|
-
import { AgentError } from '../errors'
|
|
9
|
-
import * as agentDetector from '../infrastructure/agent-detector'
|
|
10
|
-
import type { AgentAssignmentResult, AgentInfo, ProjectContext } from '../types'
|
|
11
|
-
import { defaultAgentRetryPolicy } from '../utils/retry'
|
|
12
|
-
|
|
13
|
-
// Valid agent types - whitelist for security (prevents path traversal)
|
|
14
|
-
const VALID_AGENT_TYPES = ['claude'] as const
|
|
15
|
-
type ValidAgentType = (typeof VALID_AGENT_TYPES)[number]
|
|
16
|
-
|
|
17
|
-
export class AgentService {
|
|
18
|
-
private agent: unknown = null
|
|
19
|
-
private agentInfo: AgentInfo | null = null
|
|
20
|
-
private agentRouter: AgentRouter
|
|
21
|
-
|
|
22
|
-
constructor() {
|
|
23
|
-
this.agentRouter = new AgentRouter()
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Initialize agent (Claude Code, Desktop, or Terminal)
|
|
28
|
-
* Wrapped with retry policy to handle transient failures
|
|
29
|
-
*/
|
|
30
|
-
async initialize(): Promise<unknown> {
|
|
31
|
-
if (this.agent) return this.agent
|
|
32
|
-
|
|
33
|
-
// Wrap initialization with retry policy (3 attempts, exponential backoff)
|
|
34
|
-
return await defaultAgentRetryPolicy.execute(async () => {
|
|
35
|
-
this.agentInfo = await agentDetector.detect()
|
|
36
|
-
|
|
37
|
-
if (!this.agentInfo?.isSupported) {
|
|
38
|
-
throw AgentError.notSupported(this.agentInfo?.type ?? 'unknown')
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// Security: validate agent type against whitelist to prevent path traversal
|
|
42
|
-
const agentType = this.agentInfo.type as ValidAgentType
|
|
43
|
-
if (!agentType || !VALID_AGENT_TYPES.includes(agentType)) {
|
|
44
|
-
throw AgentError.notSupported(this.agentInfo?.type ?? 'unknown')
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const { default: Agent } = await import(`../infrastructure/${agentType}-agent`)
|
|
48
|
-
this.agent = new Agent()
|
|
49
|
-
|
|
50
|
-
return this.agent
|
|
51
|
-
}, 'agent-initialization')
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Get current agent info
|
|
56
|
-
*/
|
|
57
|
-
getInfo(): AgentInfo | null {
|
|
58
|
-
return this.agentInfo
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Get initialized agent
|
|
63
|
-
*/
|
|
64
|
-
getAgent(): unknown {
|
|
65
|
-
return this.agent
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Check if agent is initialized
|
|
70
|
-
*/
|
|
71
|
-
isInitialized(): boolean {
|
|
72
|
-
return this.agent !== null
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Assign agent for a task - AGENTIC APPROACH
|
|
77
|
-
*
|
|
78
|
-
* NO keyword matching. Returns available agents and context
|
|
79
|
-
* for Claude to make the decision via templates/orchestrator.md
|
|
80
|
-
*
|
|
81
|
-
* The agents in {agentsDir} are already project-specific
|
|
82
|
-
* (generated during p. sync with real technologies)
|
|
83
|
-
*/
|
|
84
|
-
async assignForTask(
|
|
85
|
-
task: string,
|
|
86
|
-
projectPath: string,
|
|
87
|
-
_context: ProjectContext
|
|
88
|
-
): Promise<AgentAssignmentResult> {
|
|
89
|
-
try {
|
|
90
|
-
await this.agentRouter.initialize(projectPath)
|
|
91
|
-
const agents = await this.agentRouter.getAgentNames()
|
|
92
|
-
|
|
93
|
-
if (agents.length === 0) {
|
|
94
|
-
// No agents available - suggest running sync
|
|
95
|
-
return {
|
|
96
|
-
agent: null, // Claude decides - don't default to generalist
|
|
97
|
-
routing: {
|
|
98
|
-
confidence: 0,
|
|
99
|
-
reason: 'No specialized agents available. Run "p. sync" to generate agents.',
|
|
100
|
-
availableAgents: [],
|
|
101
|
-
},
|
|
102
|
-
_agenticNote: 'AGENTIC: Claude reads orchestrator.md and decides how to proceed',
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// AGENTIC: No keyword matching here
|
|
107
|
-
// Claude reads the orchestrator template and decides based on:
|
|
108
|
-
// 1. Task analysis (what domains are involved)
|
|
109
|
-
// 2. Available agents (from agents directory)
|
|
110
|
-
// 3. Whether to fragment into subtasks
|
|
111
|
-
//
|
|
112
|
-
// The TypeScript code just provides the list of available agents
|
|
113
|
-
|
|
114
|
-
return {
|
|
115
|
-
agent: null, // Claude decides via templates
|
|
116
|
-
routing: {
|
|
117
|
-
confidence: 0, // Claude determines confidence
|
|
118
|
-
reason: 'AGENTIC: Claude will analyze task and select appropriate specialist agents',
|
|
119
|
-
availableAgents: agents,
|
|
120
|
-
},
|
|
121
|
-
_agenticNote: `
|
|
122
|
-
AGENTIC EXECUTION:
|
|
123
|
-
- Read: templates/agentic/orchestrator.md
|
|
124
|
-
- Analyze task: "${task}"
|
|
125
|
-
- Available specialists: ${agents.join(', ')}
|
|
126
|
-
- Claude decides which agent(s) to use
|
|
127
|
-
- Always prefer specialists over generalist
|
|
128
|
-
- Fragment complex tasks into subtasks
|
|
129
|
-
`,
|
|
130
|
-
}
|
|
131
|
-
} catch (_error) {
|
|
132
|
-
// Agent routing unavailable - expected for new projects
|
|
133
|
-
return {
|
|
134
|
-
agent: null,
|
|
135
|
-
routing: {
|
|
136
|
-
confidence: 0,
|
|
137
|
-
reason: 'Agent routing unavailable - run "p. sync" first',
|
|
138
|
-
availableAgents: [],
|
|
139
|
-
},
|
|
140
|
-
_agenticNote: 'AGENTIC: Suggest running p. sync to generate agents',
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Get available agent names
|
|
147
|
-
*/
|
|
148
|
-
async getAvailableAgents(projectPath: string): Promise<string[]> {
|
|
149
|
-
try {
|
|
150
|
-
await this.agentRouter.initialize(projectPath)
|
|
151
|
-
return await this.agentRouter.getAgentNames()
|
|
152
|
-
} catch (_error) {
|
|
153
|
-
// Agent router unavailable - expected for new projects
|
|
154
|
-
return []
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Reset agent state (useful for tests)
|
|
160
|
-
*/
|
|
161
|
-
reset(): void {
|
|
162
|
-
this.agent = null
|
|
163
|
-
this.agentInfo = null
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
export const agentService = new AgentService()
|
|
168
|
-
export default agentService
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* BreakdownService - Feature and bug analysis
|
|
3
|
-
*
|
|
4
|
-
* Handles task breakdown, severity detection, and complexity estimation.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type { ComplexityEstimate, Severity } from '../types'
|
|
8
|
-
|
|
9
|
-
export class BreakdownService {
|
|
10
|
-
/**
|
|
11
|
-
* Break down a feature into implementation tasks
|
|
12
|
-
*/
|
|
13
|
-
breakdownFeature(description: string): string[] {
|
|
14
|
-
// Basic breakdown - could be enhanced with AI analysis
|
|
15
|
-
return [
|
|
16
|
-
`Analyze and plan: ${description}`,
|
|
17
|
-
'Implement core functionality',
|
|
18
|
-
'Test and validate',
|
|
19
|
-
'Document changes',
|
|
20
|
-
]
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Detect bug severity from description
|
|
25
|
-
*/
|
|
26
|
-
detectBugSeverity(description: string): Severity {
|
|
27
|
-
const descLower = description.toLowerCase()
|
|
28
|
-
|
|
29
|
-
// Critical indicators
|
|
30
|
-
if (
|
|
31
|
-
descLower.includes('crash') ||
|
|
32
|
-
descLower.includes('data loss') ||
|
|
33
|
-
descLower.includes('security') ||
|
|
34
|
-
descLower.includes('production down')
|
|
35
|
-
) {
|
|
36
|
-
return 'critical'
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// High indicators
|
|
40
|
-
if (
|
|
41
|
-
descLower.includes('broken') ||
|
|
42
|
-
descLower.includes('not working') ||
|
|
43
|
-
descLower.includes('error') ||
|
|
44
|
-
descLower.includes('blocking')
|
|
45
|
-
) {
|
|
46
|
-
return 'high'
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Low indicators
|
|
50
|
-
if (
|
|
51
|
-
descLower.includes('minor') ||
|
|
52
|
-
descLower.includes('cosmetic') ||
|
|
53
|
-
descLower.includes('typo') ||
|
|
54
|
-
descLower.includes('polish')
|
|
55
|
-
) {
|
|
56
|
-
return 'low'
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
return 'medium'
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Estimate complexity for a task
|
|
64
|
-
*/
|
|
65
|
-
estimateComplexity(description: string): ComplexityEstimate {
|
|
66
|
-
const wordCount = description.split(/\s+/).length
|
|
67
|
-
|
|
68
|
-
// Complex keywords
|
|
69
|
-
const complexKeywords = [
|
|
70
|
-
'refactor',
|
|
71
|
-
'migrate',
|
|
72
|
-
'redesign',
|
|
73
|
-
'overhaul',
|
|
74
|
-
'rewrite',
|
|
75
|
-
'integration',
|
|
76
|
-
'authentication',
|
|
77
|
-
'authorization',
|
|
78
|
-
]
|
|
79
|
-
|
|
80
|
-
const hasComplexKeyword = complexKeywords.some((kw) => description.toLowerCase().includes(kw))
|
|
81
|
-
|
|
82
|
-
if (hasComplexKeyword || wordCount > 30) {
|
|
83
|
-
return { level: 'high', hours: 8 }
|
|
84
|
-
} else if (wordCount > 10) {
|
|
85
|
-
return { level: 'medium', hours: 4 }
|
|
86
|
-
} else {
|
|
87
|
-
return { level: 'low', hours: 1 }
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Detect task type from description
|
|
93
|
-
*/
|
|
94
|
-
detectTaskType(description: string): 'feature' | 'bug' | 'improvement' | 'chore' {
|
|
95
|
-
const descLower = description.toLowerCase()
|
|
96
|
-
|
|
97
|
-
if (descLower.includes('bug') || descLower.includes('fix') || descLower.includes('error')) {
|
|
98
|
-
return 'bug'
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (
|
|
102
|
-
descLower.includes('refactor') ||
|
|
103
|
-
descLower.includes('improve') ||
|
|
104
|
-
descLower.includes('optimize') ||
|
|
105
|
-
descLower.includes('cleanup')
|
|
106
|
-
) {
|
|
107
|
-
return 'improvement'
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
if (
|
|
111
|
-
descLower.includes('update') ||
|
|
112
|
-
descLower.includes('deps') ||
|
|
113
|
-
descLower.includes('config') ||
|
|
114
|
-
descLower.includes('chore')
|
|
115
|
-
) {
|
|
116
|
-
return 'chore'
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
return 'feature'
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
export const breakdownService = new BreakdownService()
|
|
124
|
-
export default breakdownService
|