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,168 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Command Context Resolver
|
|
3
|
-
*
|
|
4
|
-
* Replaces 4 hardcoded command lists in prompt-builder with config-driven lookups.
|
|
5
|
-
* Falls back to LLM classification for unknown commands (Phase 2).
|
|
6
|
-
* Auto-learns after repeated classifications (Phase 3).
|
|
7
|
-
*
|
|
8
|
-
* @see PRJ-298
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import fs from 'node:fs/promises'
|
|
12
|
-
import path from 'node:path'
|
|
13
|
-
import {
|
|
14
|
-
type CommandContextConfig,
|
|
15
|
-
CommandContextConfigSchema,
|
|
16
|
-
type CommandContextEntry,
|
|
17
|
-
} from '../schemas/command-context'
|
|
18
|
-
import type { Template } from '../types'
|
|
19
|
-
import { PACKAGE_ROOT } from '../utils/version'
|
|
20
|
-
import { classifyCommand } from './command-classifier'
|
|
21
|
-
|
|
22
|
-
const CONFIG_PATH = path.join(PACKAGE_ROOT, 'core/config/command-context.config.json')
|
|
23
|
-
|
|
24
|
-
let cachedConfig: CommandContextConfig | null = null
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Load and validate the command context config.
|
|
28
|
-
* Cached after first load for the process lifetime.
|
|
29
|
-
*/
|
|
30
|
-
export async function loadCommandContextConfig(): Promise<CommandContextConfig> {
|
|
31
|
-
if (cachedConfig) return cachedConfig
|
|
32
|
-
|
|
33
|
-
const raw = await fs.readFile(CONFIG_PATH, 'utf-8')
|
|
34
|
-
const parsed = JSON.parse(raw)
|
|
35
|
-
cachedConfig = CommandContextConfigSchema.parse(parsed)
|
|
36
|
-
return cachedConfig
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Get context config for a command.
|
|
41
|
-
* Returns the command's config if explicitly defined, otherwise falls back to wildcard '*'.
|
|
42
|
-
*/
|
|
43
|
-
export function resolveCommandContext(
|
|
44
|
-
config: CommandContextConfig,
|
|
45
|
-
commandName: string
|
|
46
|
-
): CommandContextEntry {
|
|
47
|
-
return config.commands[commandName] ?? config.commands['*']
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// =============================================================================
|
|
51
|
-
// LLM Classification Cache (Phase 2)
|
|
52
|
-
// =============================================================================
|
|
53
|
-
|
|
54
|
-
const classificationCache = new Map<string, CommandContextEntry>()
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Get a cached LLM classification result for a command.
|
|
58
|
-
*/
|
|
59
|
-
export function getCachedClassification(commandName: string): CommandContextEntry | undefined {
|
|
60
|
-
return classificationCache.get(commandName)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Cache an LLM classification result for a command.
|
|
65
|
-
*/
|
|
66
|
-
export function cacheClassification(commandName: string, entry: CommandContextEntry): void {
|
|
67
|
-
classificationCache.set(commandName, entry)
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// =============================================================================
|
|
71
|
-
// Auto-Learn Tracking (Phase 3)
|
|
72
|
-
// =============================================================================
|
|
73
|
-
|
|
74
|
-
const classificationHistory = new Map<string, { entry: CommandContextEntry; count: number }>()
|
|
75
|
-
|
|
76
|
-
const AUTO_LEARN_THRESHOLD = 3
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Track a classification result. Returns true if the threshold is reached
|
|
80
|
-
* and the classification should be persisted to config.
|
|
81
|
-
*/
|
|
82
|
-
export function trackClassification(commandName: string, entry: CommandContextEntry): boolean {
|
|
83
|
-
const key = commandName
|
|
84
|
-
const existing = classificationHistory.get(key)
|
|
85
|
-
|
|
86
|
-
if (existing && isSameEntry(existing.entry, entry)) {
|
|
87
|
-
existing.count++
|
|
88
|
-
return existing.count >= AUTO_LEARN_THRESHOLD
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
classificationHistory.set(key, { entry, count: 1 })
|
|
92
|
-
return false
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Persist a learned classification to the config file.
|
|
97
|
-
*/
|
|
98
|
-
export async function persistClassification(
|
|
99
|
-
commandName: string,
|
|
100
|
-
entry: CommandContextEntry
|
|
101
|
-
): Promise<void> {
|
|
102
|
-
const raw = await fs.readFile(CONFIG_PATH, 'utf-8')
|
|
103
|
-
const config = JSON.parse(raw) as CommandContextConfig
|
|
104
|
-
|
|
105
|
-
config.commands[commandName] = entry
|
|
106
|
-
await fs.writeFile(CONFIG_PATH, `${JSON.stringify(config, null, 2)}\n`, 'utf-8')
|
|
107
|
-
|
|
108
|
-
// Invalidate cache so next load picks up the change
|
|
109
|
-
cachedConfig = null
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
function isSameEntry(a: CommandContextEntry, b: CommandContextEntry): boolean {
|
|
113
|
-
return (
|
|
114
|
-
a.agents === b.agents &&
|
|
115
|
-
a.patterns === b.patterns &&
|
|
116
|
-
a.checklist === b.checklist &&
|
|
117
|
-
a.modules.length === b.modules.length &&
|
|
118
|
-
a.modules.every((m, i) => m === b.modules[i])
|
|
119
|
-
)
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// =============================================================================
|
|
123
|
-
// Convenience: resolve with all fallbacks
|
|
124
|
-
// =============================================================================
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Resolve command context with full fallback chain:
|
|
128
|
-
* 1. Config lookup (instant)
|
|
129
|
-
* 2. Classification cache (instant)
|
|
130
|
-
* 3. Template heuristic classification (instant) — caches result + tracks for auto-learn
|
|
131
|
-
* 4. Wildcard default (instant)
|
|
132
|
-
*
|
|
133
|
-
* Returns { entry, source } where source indicates how it was resolved.
|
|
134
|
-
*/
|
|
135
|
-
export function resolveCommandContextFull(
|
|
136
|
-
config: CommandContextConfig,
|
|
137
|
-
commandName: string,
|
|
138
|
-
template?: Template
|
|
139
|
-
): { entry: CommandContextEntry; source: 'config' | 'classified' | 'cache' | 'wildcard' } {
|
|
140
|
-
// 1. Explicit config match
|
|
141
|
-
if (commandName in config.commands && commandName !== '*') {
|
|
142
|
-
return { entry: config.commands[commandName], source: 'config' }
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// 2. Classification cache
|
|
146
|
-
const cached = getCachedClassification(commandName)
|
|
147
|
-
if (cached) {
|
|
148
|
-
return { entry: cached, source: 'cache' }
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// 3. Template heuristic classification
|
|
152
|
-
if (template) {
|
|
153
|
-
const classified = classifyCommand(commandName, template)
|
|
154
|
-
cacheClassification(commandName, classified)
|
|
155
|
-
|
|
156
|
-
// Track for auto-learn (Phase 3)
|
|
157
|
-
const shouldPersist = trackClassification(commandName, classified)
|
|
158
|
-
if (shouldPersist) {
|
|
159
|
-
// Fire-and-forget persist — don't block prompt building
|
|
160
|
-
persistClassification(commandName, classified).catch(() => {})
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
return { entry: classified, source: 'classified' }
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// 4. Wildcard default
|
|
167
|
-
return { entry: config.commands['*'], source: 'wildcard' }
|
|
168
|
-
}
|
|
@@ -1,471 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Command Executor
|
|
3
|
-
* Orchestrates command execution with agentic delegation.
|
|
4
|
-
*
|
|
5
|
-
* @module agentic/command-executor
|
|
6
|
-
* @version 3.4
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import fs from 'node:fs/promises'
|
|
10
|
-
import os from 'node:os'
|
|
11
|
-
import path from 'node:path'
|
|
12
|
-
import type {
|
|
13
|
-
ApprovalContext,
|
|
14
|
-
ExecutionResult,
|
|
15
|
-
ExecutionToolsFn,
|
|
16
|
-
OrchestratorContext,
|
|
17
|
-
PromptContext,
|
|
18
|
-
SimpleExecutionResult,
|
|
19
|
-
} from '../types'
|
|
20
|
-
import { getErrorMessage } from '../types/fs'
|
|
21
|
-
import { agentStream } from '../utils/agent-stream'
|
|
22
|
-
import { fileExists } from '../utils/fs-helpers'
|
|
23
|
-
import { printSubtaskProgress, type SubtaskDisplay } from '../utils/subtask-table'
|
|
24
|
-
import chainOfThought from './chain-of-thought'
|
|
25
|
-
import contextBuilder from './context-builder'
|
|
26
|
-
import groundTruth from './ground-truth'
|
|
27
|
-
import loopDetector from './loop-detector'
|
|
28
|
-
import memorySystem from './memory-system'
|
|
29
|
-
import orchestratorExecutor from './orchestrator-executor'
|
|
30
|
-
import planMode from './plan-mode'
|
|
31
|
-
import promptBuilder from './prompt-builder'
|
|
32
|
-
import templateExecutor from './template-executor'
|
|
33
|
-
import templateLoader from './template-loader'
|
|
34
|
-
import toolRegistry from './tool-registry'
|
|
35
|
-
|
|
36
|
-
// =============================================================================
|
|
37
|
-
// Status Signal
|
|
38
|
-
// =============================================================================
|
|
39
|
-
|
|
40
|
-
const RUNNING_FILE = path.join(os.homedir(), '.prjct-cli', '.running')
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Signal that a command is running (for status line)
|
|
44
|
-
*/
|
|
45
|
-
export async function signalStart(commandName: string): Promise<void> {
|
|
46
|
-
try {
|
|
47
|
-
const dir = path.dirname(RUNNING_FILE)
|
|
48
|
-
if (!(await fileExists(dir))) {
|
|
49
|
-
await fs.mkdir(dir, { recursive: true })
|
|
50
|
-
}
|
|
51
|
-
await fs.writeFile(RUNNING_FILE, `/p:${commandName}`)
|
|
52
|
-
} catch (_error) {
|
|
53
|
-
// Silently ignore - status line is optional
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Signal that command has finished (for status line)
|
|
59
|
-
*/
|
|
60
|
-
export async function signalEnd(): Promise<void> {
|
|
61
|
-
try {
|
|
62
|
-
if (await fileExists(RUNNING_FILE)) {
|
|
63
|
-
await fs.unlink(RUNNING_FILE)
|
|
64
|
-
}
|
|
65
|
-
} catch (_error) {
|
|
66
|
-
// Silently ignore - status line is optional
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// =============================================================================
|
|
71
|
-
// Command Executor Class
|
|
72
|
-
// =============================================================================
|
|
73
|
-
|
|
74
|
-
export class CommandExecutor {
|
|
75
|
-
/**
|
|
76
|
-
* Signal that a command is running (for status line)
|
|
77
|
-
*/
|
|
78
|
-
async signalStart(commandName: string): Promise<void> {
|
|
79
|
-
await signalStart(commandName)
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Signal that command has finished (for status line)
|
|
84
|
-
*/
|
|
85
|
-
async signalEnd(): Promise<void> {
|
|
86
|
-
await signalEnd()
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Execute a prjct command with full agentic delegation
|
|
91
|
-
*/
|
|
92
|
-
async execute(
|
|
93
|
-
commandName: string,
|
|
94
|
-
params: Record<string, unknown>,
|
|
95
|
-
projectPath: string
|
|
96
|
-
): Promise<ExecutionResult> {
|
|
97
|
-
// Signal start for status line
|
|
98
|
-
await this.signalStart(commandName)
|
|
99
|
-
|
|
100
|
-
// Context for loop detection
|
|
101
|
-
const loopContext = (params.task as string) || (params.description as string) || ''
|
|
102
|
-
|
|
103
|
-
// Check if we're in a loop BEFORE attempting
|
|
104
|
-
if (loopDetector.shouldEscalate(commandName, loopContext)) {
|
|
105
|
-
const escalation = loopDetector.getEscalationInfo(commandName, loopContext)
|
|
106
|
-
await this.signalEnd()
|
|
107
|
-
return {
|
|
108
|
-
success: false,
|
|
109
|
-
error: escalation?.message,
|
|
110
|
-
escalation,
|
|
111
|
-
isLoopDetected: true,
|
|
112
|
-
suggestion: escalation?.suggestion,
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
try {
|
|
117
|
-
// 1. Load template
|
|
118
|
-
const template = await templateLoader.load(commandName)
|
|
119
|
-
|
|
120
|
-
// 2. Build METADATA context only (lazy loading - no file reads yet)
|
|
121
|
-
const metadataContext = await contextBuilder.build(projectPath, params)
|
|
122
|
-
|
|
123
|
-
// 2.55. P3.4 PLAN MODE: Check if command requires planning
|
|
124
|
-
const requiresPlanning = planMode.requiresPlanning(commandName)
|
|
125
|
-
const isDestructive = planMode.isDestructive(commandName)
|
|
126
|
-
const isInPlanningMode = planMode.isInPlanningMode(metadataContext.projectId!)
|
|
127
|
-
|
|
128
|
-
// Start planning mode if required and not already in it
|
|
129
|
-
let activePlan = null
|
|
130
|
-
if (requiresPlanning && !isInPlanningMode && !params.skipPlanning) {
|
|
131
|
-
activePlan = planMode.startPlanning(metadataContext.projectId!, commandName, params)
|
|
132
|
-
} else if (isInPlanningMode) {
|
|
133
|
-
activePlan = planMode.getActivePlan(metadataContext.projectId!)
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// 2.6. GROUND TRUTH: Verify actual state before critical operations
|
|
137
|
-
let groundTruthResult = null
|
|
138
|
-
if (groundTruth.requiresVerification(commandName)) {
|
|
139
|
-
const preState = await contextBuilder.loadStateForCommand(metadataContext, commandName)
|
|
140
|
-
groundTruthResult = await groundTruth.verify(commandName, metadataContext, preState)
|
|
141
|
-
|
|
142
|
-
// Log warnings but don't block (user can override)
|
|
143
|
-
if (!groundTruthResult.verified && groundTruthResult.warnings.length > 0) {
|
|
144
|
-
console.log(groundTruth.formatWarnings(groundTruthResult))
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// 2.8. CHAIN OF THOUGHT: Reasoning for critical commands
|
|
149
|
-
let reasoning = null
|
|
150
|
-
if (chainOfThought.requiresReasoning(commandName)) {
|
|
151
|
-
const reasoningState = await contextBuilder.loadStateForCommand(
|
|
152
|
-
metadataContext,
|
|
153
|
-
commandName
|
|
154
|
-
)
|
|
155
|
-
reasoning = await chainOfThought.reason(commandName, metadataContext, reasoningState)
|
|
156
|
-
|
|
157
|
-
// If reasoning shows critical issues, warn but continue
|
|
158
|
-
if (reasoning.reasoning && !reasoning.reasoning.allPassed) {
|
|
159
|
-
console.log('⚠️ Chain of Thought detected issues:')
|
|
160
|
-
console.log(chainOfThought.formatPlan(reasoning))
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// 3. AGENTIC: Template-first execution
|
|
165
|
-
// Claude decides agent assignment via templates - no hardcoded routing
|
|
166
|
-
const taskDescription = (params.task as string) || (params.description as string) || ''
|
|
167
|
-
const agenticExecContext = await templateExecutor.buildContext(
|
|
168
|
-
commandName,
|
|
169
|
-
taskDescription,
|
|
170
|
-
projectPath
|
|
171
|
-
)
|
|
172
|
-
const agenticInfo = templateExecutor.buildAgenticPrompt(agenticExecContext)
|
|
173
|
-
|
|
174
|
-
// 3.5. ORCHESTRATOR: Execute orchestration for commands that require it
|
|
175
|
-
let orchestratorContext: OrchestratorContext | null = null
|
|
176
|
-
if (templateExecutor.requiresOrchestration(commandName) && taskDescription) {
|
|
177
|
-
try {
|
|
178
|
-
orchestratorContext = await orchestratorExecutor.execute(
|
|
179
|
-
commandName,
|
|
180
|
-
taskDescription,
|
|
181
|
-
projectPath
|
|
182
|
-
)
|
|
183
|
-
|
|
184
|
-
// Show orchestration with agent stream
|
|
185
|
-
if (orchestratorContext.detectedDomains.length > 0) {
|
|
186
|
-
agentStream.orchestrate(orchestratorContext.detectedDomains)
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
// Show each agent being activated
|
|
190
|
-
for (const agent of orchestratorContext.agents) {
|
|
191
|
-
const domain = agent.domain || agent.name.replace('.md', '')
|
|
192
|
-
agentStream.startAgent(agent.name, domain, `Loading ${domain} specialist...`)
|
|
193
|
-
agentStream.endAgent(true)
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
// Show subtasks if fragmented
|
|
197
|
-
if (orchestratorContext.requiresFragmentation && orchestratorContext.subtasks) {
|
|
198
|
-
const subtaskDisplay: SubtaskDisplay[] = orchestratorContext.subtasks.map((s) => ({
|
|
199
|
-
id: s.id,
|
|
200
|
-
domain: s.domain,
|
|
201
|
-
description: s.description,
|
|
202
|
-
status: s.status,
|
|
203
|
-
}))
|
|
204
|
-
printSubtaskProgress(subtaskDisplay)
|
|
205
|
-
}
|
|
206
|
-
} catch (error) {
|
|
207
|
-
// Orchestration failed - log warning but continue without it
|
|
208
|
-
console.warn(`⚠️ Orchestrator warning: ${getErrorMessage(error)}`)
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
// Build context with agent routing info for Claude delegation
|
|
213
|
-
const context: PromptContext = {
|
|
214
|
-
...metadataContext,
|
|
215
|
-
agentsPath: agenticExecContext.paths.agentsDir,
|
|
216
|
-
agentRoutingPath: agenticExecContext.paths.agentRouting,
|
|
217
|
-
orchestratorPath: agenticExecContext.paths.orchestrator,
|
|
218
|
-
taskFragmentationPath: agenticExecContext.paths.taskFragmentation,
|
|
219
|
-
agenticDelegation: true,
|
|
220
|
-
agenticMode: true,
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// 6. Load state with filtered context
|
|
224
|
-
const state = await contextBuilder.loadState(metadataContext)
|
|
225
|
-
|
|
226
|
-
// 7. MEMORY: Load learned patterns AND relevant memories for this command
|
|
227
|
-
let learnedPatterns = null
|
|
228
|
-
let relevantMemories = null
|
|
229
|
-
if (metadataContext.projectId) {
|
|
230
|
-
learnedPatterns = {
|
|
231
|
-
commit_footer: await memorySystem.getSmartDecision(
|
|
232
|
-
metadataContext.projectId,
|
|
233
|
-
'commit_footer'
|
|
234
|
-
),
|
|
235
|
-
branch_naming: await memorySystem.getSmartDecision(
|
|
236
|
-
metadataContext.projectId,
|
|
237
|
-
'branch_naming'
|
|
238
|
-
),
|
|
239
|
-
test_before_ship: await memorySystem.getSmartDecision(
|
|
240
|
-
metadataContext.projectId,
|
|
241
|
-
'test_before_ship'
|
|
242
|
-
),
|
|
243
|
-
preferred_agent: await memorySystem.getSmartDecision(
|
|
244
|
-
metadataContext.projectId,
|
|
245
|
-
`preferred_agent_${commandName}`
|
|
246
|
-
),
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// P3.3: Get relevant memories for context
|
|
250
|
-
relevantMemories = await memorySystem.getRelevantMemories(
|
|
251
|
-
metadataContext.projectId,
|
|
252
|
-
{ commandName, params },
|
|
253
|
-
5
|
|
254
|
-
)
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
// 9. Build prompt - NO agent assignment here, Claude decides via templates
|
|
258
|
-
const planInfo = {
|
|
259
|
-
isPlanning: requiresPlanning || isInPlanningMode,
|
|
260
|
-
requiresApproval: isDestructive && !params.approved,
|
|
261
|
-
active: activePlan,
|
|
262
|
-
allowedTools: planMode.getAllowedTools(
|
|
263
|
-
isInPlanningMode,
|
|
264
|
-
template.frontmatter['allowed-tools'] || []
|
|
265
|
-
),
|
|
266
|
-
}
|
|
267
|
-
// Agent is null - Claude assigns via Task tool using agent-routing.md
|
|
268
|
-
// Pass orchestratorContext for domain/agent/subtask injection
|
|
269
|
-
const prompt = await promptBuilder.build(
|
|
270
|
-
template,
|
|
271
|
-
context,
|
|
272
|
-
state,
|
|
273
|
-
null,
|
|
274
|
-
learnedPatterns,
|
|
275
|
-
null,
|
|
276
|
-
relevantMemories,
|
|
277
|
-
planInfo,
|
|
278
|
-
orchestratorContext
|
|
279
|
-
)
|
|
280
|
-
|
|
281
|
-
// Log agentic mode
|
|
282
|
-
console.log(`🤖 Template-first execution: Claude reads templates and decides`)
|
|
283
|
-
if (agenticInfo.requiresOrchestration) {
|
|
284
|
-
console.log(` → Orchestration: ${agenticExecContext.paths.orchestrator}`)
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
// Record successful attempt
|
|
288
|
-
loopDetector.recordSuccess(commandName, loopContext)
|
|
289
|
-
|
|
290
|
-
// Signal end for status line
|
|
291
|
-
await this.signalEnd()
|
|
292
|
-
|
|
293
|
-
return {
|
|
294
|
-
success: true,
|
|
295
|
-
template,
|
|
296
|
-
context,
|
|
297
|
-
state,
|
|
298
|
-
prompt,
|
|
299
|
-
agenticDelegation: true,
|
|
300
|
-
agenticMode: true,
|
|
301
|
-
agenticExecContext,
|
|
302
|
-
agenticPrompt: agenticInfo.prompt,
|
|
303
|
-
requiresOrchestration: agenticInfo.requiresOrchestration,
|
|
304
|
-
agentsPath: context.agentsPath as string,
|
|
305
|
-
agentRoutingPath: context.agentRoutingPath as string,
|
|
306
|
-
orchestratorPath: agenticExecContext.paths.orchestrator,
|
|
307
|
-
taskFragmentationPath: agenticExecContext.paths.taskFragmentation,
|
|
308
|
-
reasoning,
|
|
309
|
-
groundTruth: groundTruthResult,
|
|
310
|
-
learnedPatterns,
|
|
311
|
-
relevantMemories,
|
|
312
|
-
orchestratorContext,
|
|
313
|
-
memory: {
|
|
314
|
-
create: (memory: unknown) =>
|
|
315
|
-
memorySystem.createMemory(
|
|
316
|
-
metadataContext.projectId!,
|
|
317
|
-
memory as Parameters<typeof memorySystem.createMemory>[1]
|
|
318
|
-
),
|
|
319
|
-
autoRemember: (type: string, value: string, ctx?: string) =>
|
|
320
|
-
memorySystem.autoRemember(metadataContext.projectId!, type, value, ctx),
|
|
321
|
-
search: (query: string) => memorySystem.searchMemories(metadataContext.projectId!, query),
|
|
322
|
-
findByTags: (tags: string[]) => memorySystem.findByTags(metadataContext.projectId!, tags),
|
|
323
|
-
getStats: () => memorySystem.getMemoryStats(metadataContext.projectId!),
|
|
324
|
-
},
|
|
325
|
-
plan: {
|
|
326
|
-
active: activePlan,
|
|
327
|
-
isPlanning: requiresPlanning || isInPlanningMode,
|
|
328
|
-
isDestructive,
|
|
329
|
-
requiresApproval: isDestructive && !params.approved,
|
|
330
|
-
recordInfo: (info: unknown) =>
|
|
331
|
-
planMode.recordGatheredInfo(
|
|
332
|
-
metadataContext.projectId!,
|
|
333
|
-
info as Parameters<typeof planMode.recordGatheredInfo>[1]
|
|
334
|
-
),
|
|
335
|
-
setAnalysis: (analysis: unknown) =>
|
|
336
|
-
planMode.setAnalysis(
|
|
337
|
-
metadataContext.projectId!,
|
|
338
|
-
analysis as Parameters<typeof planMode.setAnalysis>[1]
|
|
339
|
-
),
|
|
340
|
-
propose: (plan: unknown) =>
|
|
341
|
-
planMode.proposePlan(
|
|
342
|
-
metadataContext.projectId!,
|
|
343
|
-
plan as Parameters<typeof planMode.proposePlan>[1]
|
|
344
|
-
),
|
|
345
|
-
approve: (feedback?: string | null) =>
|
|
346
|
-
planMode.approvePlan(metadataContext.projectId!, feedback),
|
|
347
|
-
reject: (reason?: string | null) =>
|
|
348
|
-
planMode.rejectPlan(metadataContext.projectId!, reason),
|
|
349
|
-
getApprovalPrompt: () =>
|
|
350
|
-
planMode.generateApprovalPrompt(commandName, {
|
|
351
|
-
// Reason: `context` here is the command execution context, not the plan-mode ApprovalContext.
|
|
352
|
-
// Provide required fields with safe defaults to avoid unsafe casting.
|
|
353
|
-
changedFiles: [],
|
|
354
|
-
filesToDelete: [],
|
|
355
|
-
operation: ((): ApprovalContext['operation'] => {
|
|
356
|
-
if (commandName === 'ship') return 'git_push'
|
|
357
|
-
if (commandName === 'cleanup') return 'delete_files'
|
|
358
|
-
return 'run_command'
|
|
359
|
-
})(),
|
|
360
|
-
warnings: [],
|
|
361
|
-
} satisfies ApprovalContext),
|
|
362
|
-
startExecution: () => planMode.startExecution(metadataContext.projectId!),
|
|
363
|
-
getNextStep: () => planMode.getNextStep(metadataContext.projectId!),
|
|
364
|
-
completeStep: (result?: unknown) =>
|
|
365
|
-
planMode.completeStep(
|
|
366
|
-
metadataContext.projectId!,
|
|
367
|
-
result as Parameters<typeof planMode.completeStep>[1]
|
|
368
|
-
),
|
|
369
|
-
failStep: (error: string) => planMode.failStep(metadataContext.projectId!, error),
|
|
370
|
-
abort: (reason?: string) => planMode.abortPlan(metadataContext.projectId!, reason),
|
|
371
|
-
getStatus: () => planMode.formatStatus(metadataContext.projectId!),
|
|
372
|
-
getAllowedTools: () =>
|
|
373
|
-
planMode.getAllowedTools(isInPlanningMode, template.frontmatter['allowed-tools'] || []),
|
|
374
|
-
},
|
|
375
|
-
}
|
|
376
|
-
} catch (error) {
|
|
377
|
-
// Signal end for status line
|
|
378
|
-
await this.signalEnd()
|
|
379
|
-
|
|
380
|
-
// Record failed attempt for loop detection
|
|
381
|
-
const attemptInfo = loopDetector.recordAttempt(commandName, loopContext, {
|
|
382
|
-
success: false,
|
|
383
|
-
error: getErrorMessage(error),
|
|
384
|
-
})
|
|
385
|
-
|
|
386
|
-
// Check if we should escalate after this failure
|
|
387
|
-
if (attemptInfo.shouldEscalate) {
|
|
388
|
-
const escalation = loopDetector.getEscalationInfo(commandName, loopContext)
|
|
389
|
-
return {
|
|
390
|
-
success: false,
|
|
391
|
-
error: escalation?.message,
|
|
392
|
-
escalation,
|
|
393
|
-
isLoopDetected: true,
|
|
394
|
-
suggestion: escalation?.suggestion,
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
return {
|
|
399
|
-
success: false,
|
|
400
|
-
error: getErrorMessage(error),
|
|
401
|
-
attemptNumber: attemptInfo.attemptNumber,
|
|
402
|
-
isLooping: attemptInfo.isLooping,
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
/**
|
|
408
|
-
* Execute tool with permission check
|
|
409
|
-
*/
|
|
410
|
-
async executeTool(toolName: string, args: unknown[], allowedTools: string[]): Promise<unknown> {
|
|
411
|
-
// Check if tool is allowed
|
|
412
|
-
if (!toolRegistry.isAllowed(toolName, allowedTools)) {
|
|
413
|
-
throw new Error(`Tool ${toolName} not allowed for this command`)
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
// Get tool function
|
|
417
|
-
const tool = toolRegistry.get(toolName)
|
|
418
|
-
if (!tool) {
|
|
419
|
-
throw new Error(`Tool ${toolName} not found`)
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
// Execute tool
|
|
423
|
-
return await tool(...args)
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
/**
|
|
427
|
-
* Simple execution for direct tool access (legacy migration helper)
|
|
428
|
-
*/
|
|
429
|
-
async executeSimple(
|
|
430
|
-
commandName: string,
|
|
431
|
-
executionFn: ExecutionToolsFn,
|
|
432
|
-
projectPath: string
|
|
433
|
-
): Promise<SimpleExecutionResult> {
|
|
434
|
-
try {
|
|
435
|
-
// Load template to get allowed tools
|
|
436
|
-
const template = await templateLoader.load(commandName)
|
|
437
|
-
const allowedTools = template.frontmatter['allowed-tools'] || []
|
|
438
|
-
|
|
439
|
-
// Build context
|
|
440
|
-
const context = await contextBuilder.build(projectPath)
|
|
441
|
-
|
|
442
|
-
// Create tools proxy that checks permissions
|
|
443
|
-
const tools = {
|
|
444
|
-
read: async (filePath: string) => this.executeTool('Read', [filePath], allowedTools),
|
|
445
|
-
write: async (filePath: string, content: string) =>
|
|
446
|
-
this.executeTool('Write', [filePath, content], allowedTools),
|
|
447
|
-
bash: async (command: string) => this.executeTool('Bash', [command], allowedTools),
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
// Execute user function with tools
|
|
451
|
-
const result = await executionFn(tools, context)
|
|
452
|
-
|
|
453
|
-
return {
|
|
454
|
-
success: true,
|
|
455
|
-
result,
|
|
456
|
-
}
|
|
457
|
-
} catch (error) {
|
|
458
|
-
return {
|
|
459
|
-
success: false,
|
|
460
|
-
error: getErrorMessage(error),
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
// =============================================================================
|
|
467
|
-
// Default Export
|
|
468
|
-
// =============================================================================
|
|
469
|
-
|
|
470
|
-
const commandExecutor = new CommandExecutor()
|
|
471
|
-
export default commandExecutor
|