task-o-matic-core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +646 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +46 -0
- package/dist/lib/ai-service/ai-operations.d.ts +45 -0
- package/dist/lib/ai-service/ai-operations.d.ts.map +1 -0
- package/dist/lib/ai-service/ai-operations.js +60 -0
- package/dist/lib/ai-service/base-operations.d.ts +43 -0
- package/dist/lib/ai-service/base-operations.d.ts.map +1 -0
- package/dist/lib/ai-service/base-operations.js +119 -0
- package/dist/lib/ai-service/documentation-operations.d.ts +18 -0
- package/dist/lib/ai-service/documentation-operations.d.ts.map +1 -0
- package/dist/lib/ai-service/documentation-operations.js +308 -0
- package/dist/lib/ai-service/filesystem-tools.d.ts +69 -0
- package/dist/lib/ai-service/filesystem-tools.d.ts.map +1 -0
- package/dist/lib/ai-service/filesystem-tools.js +70 -0
- package/dist/lib/ai-service/json-parser.d.ts +34 -0
- package/dist/lib/ai-service/json-parser.d.ts.map +1 -0
- package/dist/lib/ai-service/json-parser.js +177 -0
- package/dist/lib/ai-service/mcp-client.d.ts +9 -0
- package/dist/lib/ai-service/mcp-client.d.ts.map +1 -0
- package/dist/lib/ai-service/mcp-client.js +48 -0
- package/dist/lib/ai-service/model-provider.d.ts +12 -0
- package/dist/lib/ai-service/model-provider.d.ts.map +1 -0
- package/dist/lib/ai-service/model-provider.js +146 -0
- package/dist/lib/ai-service/prd-operations.d.ts +25 -0
- package/dist/lib/ai-service/prd-operations.d.ts.map +1 -0
- package/dist/lib/ai-service/prd-operations.js +592 -0
- package/dist/lib/ai-service/research-tools.d.ts +4 -0
- package/dist/lib/ai-service/research-tools.d.ts.map +1 -0
- package/dist/lib/ai-service/research-tools.js +8 -0
- package/dist/lib/ai-service/retry-handler.d.ts +8 -0
- package/dist/lib/ai-service/retry-handler.d.ts.map +1 -0
- package/dist/lib/ai-service/retry-handler.js +63 -0
- package/dist/lib/ai-service/task-operations.d.ts +13 -0
- package/dist/lib/ai-service/task-operations.d.ts.map +1 -0
- package/dist/lib/ai-service/task-operations.js +220 -0
- package/dist/lib/benchmark/registry.d.ts +11 -0
- package/dist/lib/benchmark/registry.d.ts.map +1 -0
- package/dist/lib/benchmark/registry.js +212 -0
- package/dist/lib/benchmark/runner.d.ts +6 -0
- package/dist/lib/benchmark/runner.d.ts.map +1 -0
- package/dist/lib/benchmark/runner.js +150 -0
- package/dist/lib/benchmark/storage.d.ts +13 -0
- package/dist/lib/benchmark/storage.d.ts.map +1 -0
- package/dist/lib/benchmark/storage.js +100 -0
- package/dist/lib/benchmark/types.d.ts +104 -0
- package/dist/lib/benchmark/types.d.ts.map +1 -0
- package/dist/lib/benchmark/types.js +2 -0
- package/dist/lib/better-t-stack-cli.d.ts +50 -0
- package/dist/lib/better-t-stack-cli.d.ts.map +1 -0
- package/dist/lib/better-t-stack-cli.js +428 -0
- package/dist/lib/bootstrap/cli-bootstrap.d.ts +14 -0
- package/dist/lib/bootstrap/cli-bootstrap.d.ts.map +1 -0
- package/dist/lib/bootstrap/cli-bootstrap.js +322 -0
- package/dist/lib/bootstrap/index.d.ts +3 -0
- package/dist/lib/bootstrap/index.d.ts.map +1 -0
- package/dist/lib/bootstrap/index.js +18 -0
- package/dist/lib/bootstrap/medusa-bootstrap.d.ts +14 -0
- package/dist/lib/bootstrap/medusa-bootstrap.d.ts.map +1 -0
- package/dist/lib/bootstrap/medusa-bootstrap.js +215 -0
- package/dist/lib/config-validation.d.ts +215 -0
- package/dist/lib/config-validation.d.ts.map +1 -0
- package/dist/lib/config-validation.js +254 -0
- package/dist/lib/config.d.ts +55 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +351 -0
- package/dist/lib/context-builder.d.ts +66 -0
- package/dist/lib/context-builder.d.ts.map +1 -0
- package/dist/lib/context-builder.js +322 -0
- package/dist/lib/executors/claude-code-executor.d.ts +9 -0
- package/dist/lib/executors/claude-code-executor.d.ts.map +1 -0
- package/dist/lib/executors/claude-code-executor.js +69 -0
- package/dist/lib/executors/codex-executor.d.ts +9 -0
- package/dist/lib/executors/codex-executor.d.ts.map +1 -0
- package/dist/lib/executors/codex-executor.js +73 -0
- package/dist/lib/executors/executor-factory.d.ts +5 -0
- package/dist/lib/executors/executor-factory.d.ts.map +1 -0
- package/dist/lib/executors/executor-factory.js +27 -0
- package/dist/lib/executors/gemini-executor.d.ts +9 -0
- package/dist/lib/executors/gemini-executor.d.ts.map +1 -0
- package/dist/lib/executors/gemini-executor.js +67 -0
- package/dist/lib/executors/kilo-executor.d.ts +9 -0
- package/dist/lib/executors/kilo-executor.d.ts.map +1 -0
- package/dist/lib/executors/kilo-executor.js +69 -0
- package/dist/lib/executors/opencode-executor.d.ts +9 -0
- package/dist/lib/executors/opencode-executor.d.ts.map +1 -0
- package/dist/lib/executors/opencode-executor.js +67 -0
- package/dist/lib/git-utils.d.ts +88 -0
- package/dist/lib/git-utils.d.ts.map +1 -0
- package/dist/lib/git-utils.js +242 -0
- package/dist/lib/hooks.d.ts +73 -0
- package/dist/lib/hooks.d.ts.map +1 -0
- package/dist/lib/hooks.js +62 -0
- package/dist/lib/index.d.ts +100 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +143 -0
- package/dist/lib/logger.d.ts +20 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +32 -0
- package/dist/lib/notifications.d.ts +7 -0
- package/dist/lib/notifications.d.ts.map +1 -0
- package/dist/lib/notifications.js +81 -0
- package/dist/lib/prompt-builder.d.ts +70 -0
- package/dist/lib/prompt-builder.d.ts.map +1 -0
- package/dist/lib/prompt-builder.js +344 -0
- package/dist/lib/prompt-registry.d.ts +22 -0
- package/dist/lib/prompt-registry.d.ts.map +1 -0
- package/dist/lib/prompt-registry.js +409 -0
- package/dist/lib/provider-defaults.json +32 -0
- package/dist/lib/storage/file-system.d.ts +57 -0
- package/dist/lib/storage/file-system.d.ts.map +1 -0
- package/dist/lib/storage/file-system.js +638 -0
- package/dist/lib/storage/storage-callbacks.d.ts +17 -0
- package/dist/lib/storage/storage-callbacks.d.ts.map +1 -0
- package/dist/lib/storage/storage-callbacks.js +94 -0
- package/dist/lib/storage/types.d.ts +43 -0
- package/dist/lib/storage/types.d.ts.map +1 -0
- package/dist/lib/storage/types.js +2 -0
- package/dist/lib/task-execution-core.d.ts +7 -0
- package/dist/lib/task-execution-core.d.ts.map +1 -0
- package/dist/lib/task-execution-core.js +381 -0
- package/dist/lib/task-execution.d.ts +7 -0
- package/dist/lib/task-execution.d.ts.map +1 -0
- package/dist/lib/task-execution.js +40 -0
- package/dist/lib/task-loop-execution.d.ts +7 -0
- package/dist/lib/task-loop-execution.d.ts.map +1 -0
- package/dist/lib/task-loop-execution.js +156 -0
- package/dist/lib/task-planning.d.ts +29 -0
- package/dist/lib/task-planning.d.ts.map +1 -0
- package/dist/lib/task-planning.js +103 -0
- package/dist/lib/task-review.d.ts +27 -0
- package/dist/lib/task-review.d.ts.map +1 -0
- package/dist/lib/task-review.js +103 -0
- package/dist/lib/validation.d.ts +26 -0
- package/dist/lib/validation.d.ts.map +1 -0
- package/dist/lib/validation.js +98 -0
- package/dist/prompts/documentation-detection.d.ts +2 -0
- package/dist/prompts/documentation-detection.d.ts.map +1 -0
- package/dist/prompts/documentation-detection.js +24 -0
- package/dist/prompts/documentation-recap.d.ts +3 -0
- package/dist/prompts/documentation-recap.d.ts.map +1 -0
- package/dist/prompts/documentation-recap.js +13 -0
- package/dist/prompts/index.d.ts +15 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +30 -0
- package/dist/prompts/prd-combination.d.ts +2 -0
- package/dist/prompts/prd-combination.d.ts.map +1 -0
- package/dist/prompts/prd-combination.js +35 -0
- package/dist/prompts/prd-generation.d.ts +2 -0
- package/dist/prompts/prd-generation.d.ts.map +1 -0
- package/dist/prompts/prd-generation.js +49 -0
- package/dist/prompts/prd-parsing.d.ts +3 -0
- package/dist/prompts/prd-parsing.d.ts.map +1 -0
- package/dist/prompts/prd-parsing.js +172 -0
- package/dist/prompts/prd-question-answer.d.ts +3 -0
- package/dist/prompts/prd-question-answer.d.ts.map +1 -0
- package/dist/prompts/prd-question-answer.js +27 -0
- package/dist/prompts/prd-question.d.ts +3 -0
- package/dist/prompts/prd-question.d.ts.map +1 -0
- package/dist/prompts/prd-question.js +40 -0
- package/dist/prompts/prd-rework.d.ts +3 -0
- package/dist/prompts/prd-rework.d.ts.map +1 -0
- package/dist/prompts/prd-rework.js +81 -0
- package/dist/prompts/prd-suggest-stack.d.ts +3 -0
- package/dist/prompts/prd-suggest-stack.d.ts.map +1 -0
- package/dist/prompts/prd-suggest-stack.js +99 -0
- package/dist/prompts/task-breakdown.d.ts +3 -0
- package/dist/prompts/task-breakdown.d.ts.map +1 -0
- package/dist/prompts/task-breakdown.js +151 -0
- package/dist/prompts/task-enhancement.d.ts +3 -0
- package/dist/prompts/task-enhancement.d.ts.map +1 -0
- package/dist/prompts/task-enhancement.js +140 -0
- package/dist/prompts/task-execution.d.ts +3 -0
- package/dist/prompts/task-execution.d.ts.map +1 -0
- package/dist/prompts/task-execution.js +24 -0
- package/dist/prompts/task-planning.d.ts +3 -0
- package/dist/prompts/task-planning.d.ts.map +1 -0
- package/dist/prompts/task-planning.js +66 -0
- package/dist/prompts/workflow-assistance.d.ts +32 -0
- package/dist/prompts/workflow-assistance.d.ts.map +1 -0
- package/dist/prompts/workflow-assistance.js +130 -0
- package/dist/prompts/workflow-prompts.d.ts +9 -0
- package/dist/prompts/workflow-prompts.d.ts.map +1 -0
- package/dist/prompts/workflow-prompts.js +93 -0
- package/dist/services/benchmark.d.ts +26 -0
- package/dist/services/benchmark.d.ts.map +1 -0
- package/dist/services/benchmark.js +343 -0
- package/dist/services/prd.d.ts +136 -0
- package/dist/services/prd.d.ts.map +1 -0
- package/dist/services/prd.js +550 -0
- package/dist/services/tasks.d.ts +388 -0
- package/dist/services/tasks.d.ts.map +1 -0
- package/dist/services/tasks.js +1150 -0
- package/dist/services/workflow-ai-assistant.d.ts +74 -0
- package/dist/services/workflow-ai-assistant.d.ts.map +1 -0
- package/dist/services/workflow-ai-assistant.js +175 -0
- package/dist/services/workflow-benchmark.d.ts +34 -0
- package/dist/services/workflow-benchmark.d.ts.map +1 -0
- package/dist/services/workflow-benchmark.js +318 -0
- package/dist/services/workflow.d.ts +107 -0
- package/dist/services/workflow.d.ts.map +1 -0
- package/dist/services/workflow.js +580 -0
- package/dist/test/hooks.test.d.ts +2 -0
- package/dist/test/hooks.test.d.ts.map +1 -0
- package/dist/test/hooks.test.js +67 -0
- package/dist/test/integration/callbacks.test.d.ts +2 -0
- package/dist/test/integration/callbacks.test.d.ts.map +1 -0
- package/dist/test/integration/callbacks.test.js +64 -0
- package/dist/test/lib/ai-service/task-operations.test.d.ts +2 -0
- package/dist/test/lib/ai-service/task-operations.test.d.ts.map +1 -0
- package/dist/test/lib/ai-service/task-operations.test.js +362 -0
- package/dist/test/lib/config.test.d.ts +2 -0
- package/dist/test/lib/config.test.d.ts.map +1 -0
- package/dist/test/lib/config.test.js +128 -0
- package/dist/test/lib/git-utils.test.d.ts +2 -0
- package/dist/test/lib/git-utils.test.d.ts.map +1 -0
- package/dist/test/lib/git-utils.test.js +168 -0
- package/dist/test/mocks/mock-ai-operations.d.ts +15 -0
- package/dist/test/mocks/mock-ai-operations.d.ts.map +1 -0
- package/dist/test/mocks/mock-ai-operations.js +107 -0
- package/dist/test/mocks/mock-context-builder.d.ts +10 -0
- package/dist/test/mocks/mock-context-builder.d.ts.map +1 -0
- package/dist/test/mocks/mock-context-builder.js +81 -0
- package/dist/test/mocks/mock-model-provider.d.ts +7 -0
- package/dist/test/mocks/mock-model-provider.d.ts.map +1 -0
- package/dist/test/mocks/mock-model-provider.js +21 -0
- package/dist/test/mocks/mock-service-factory.d.ts +11 -0
- package/dist/test/mocks/mock-service-factory.d.ts.map +1 -0
- package/dist/test/mocks/mock-service-factory.js +61 -0
- package/dist/test/mocks/mock-storage.d.ts +50 -0
- package/dist/test/mocks/mock-storage.d.ts.map +1 -0
- package/dist/test/mocks/mock-storage.js +145 -0
- package/dist/test/model-parsing.test.d.ts +2 -0
- package/dist/test/model-parsing.test.d.ts.map +1 -0
- package/dist/test/model-parsing.test.js +73 -0
- package/dist/test/services/task-service.test.d.ts +2 -0
- package/dist/test/services/task-service.test.d.ts.map +1 -0
- package/dist/test/services/task-service.test.js +459 -0
- package/dist/test/storage.test.d.ts +2 -0
- package/dist/test/storage.test.d.ts.map +1 -0
- package/dist/test/storage.test.js +207 -0
- package/dist/test/task-loop-git.test.d.ts +2 -0
- package/dist/test/task-loop-git.test.d.ts.map +1 -0
- package/dist/test/task-loop-git.test.js +95 -0
- package/dist/test/test-mock-setup.d.ts +26 -0
- package/dist/test/test-mock-setup.d.ts.map +1 -0
- package/dist/test/test-mock-setup.js +41 -0
- package/dist/test/test-setup.d.ts +9 -0
- package/dist/test/test-setup.d.ts.map +1 -0
- package/dist/test/test-setup.js +44 -0
- package/dist/test/test-utils.d.ts +22 -0
- package/dist/test/test-utils.d.ts.map +1 -0
- package/dist/test/test-utils.js +37 -0
- package/dist/test/utils/ai-operation-utility.test.d.ts +2 -0
- package/dist/test/utils/ai-operation-utility.test.d.ts.map +1 -0
- package/dist/test/utils/ai-operation-utility.test.js +290 -0
- package/dist/test/utils/error-handling.test.d.ts +2 -0
- package/dist/test/utils/error-handling.test.d.ts.map +1 -0
- package/dist/test/utils/error-handling.test.js +231 -0
- package/dist/test/utils/file-utils.test.d.ts +2 -0
- package/dist/test/utils/file-utils.test.d.ts.map +1 -0
- package/dist/test/utils/file-utils.test.js +76 -0
- package/dist/test/utils/id-generator.test.d.ts +2 -0
- package/dist/test/utils/id-generator.test.d.ts.map +1 -0
- package/dist/test/utils/id-generator.test.js +41 -0
- package/dist/test/utils/model-parser.test.d.ts +2 -0
- package/dist/test/utils/model-parser.test.d.ts.map +1 -0
- package/dist/test/utils/model-parser.test.js +65 -0
- package/dist/test/validation.test.d.ts +2 -0
- package/dist/test/validation.test.d.ts.map +1 -0
- package/dist/test/validation.test.js +22 -0
- package/dist/types/callbacks.d.ts +30 -0
- package/dist/types/callbacks.d.ts.map +1 -0
- package/dist/types/callbacks.js +2 -0
- package/dist/types/index.d.ts +435 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +30 -0
- package/dist/types/mcp.d.ts +3 -0
- package/dist/types/mcp.d.ts.map +1 -0
- package/dist/types/mcp.js +3 -0
- package/dist/types/options.d.ts +112 -0
- package/dist/types/options.d.ts.map +1 -0
- package/dist/types/options.js +2 -0
- package/dist/types/results.d.ts +200 -0
- package/dist/types/results.d.ts.map +1 -0
- package/dist/types/results.js +2 -0
- package/dist/types/workflow-options.d.ts +82 -0
- package/dist/types/workflow-options.d.ts.map +1 -0
- package/dist/types/workflow-options.js +2 -0
- package/dist/types/workflow-results.d.ts +82 -0
- package/dist/types/workflow-results.d.ts.map +1 -0
- package/dist/types/workflow-results.js +2 -0
- package/dist/utils/ai-config-builder.d.ts +14 -0
- package/dist/utils/ai-config-builder.d.ts.map +1 -0
- package/dist/utils/ai-config-builder.js +22 -0
- package/dist/utils/ai-operation-utility.d.ts +142 -0
- package/dist/utils/ai-operation-utility.d.ts.map +1 -0
- package/dist/utils/ai-operation-utility.js +303 -0
- package/dist/utils/ai-service-factory.d.ts +34 -0
- package/dist/utils/ai-service-factory.d.ts.map +1 -0
- package/dist/utils/ai-service-factory.js +99 -0
- package/dist/utils/error-utils.d.ts +70 -0
- package/dist/utils/error-utils.d.ts.map +1 -0
- package/dist/utils/error-utils.js +104 -0
- package/dist/utils/file-utils.d.ts +107 -0
- package/dist/utils/file-utils.d.ts.map +1 -0
- package/dist/utils/file-utils.js +171 -0
- package/dist/utils/id-generator.d.ts +92 -0
- package/dist/utils/id-generator.d.ts.map +1 -0
- package/dist/utils/id-generator.js +146 -0
- package/dist/utils/metadata-utils.d.ts +40 -0
- package/dist/utils/metadata-utils.d.ts.map +1 -0
- package/dist/utils/metadata-utils.js +43 -0
- package/dist/utils/model-executor-parser.d.ts +38 -0
- package/dist/utils/model-executor-parser.d.ts.map +1 -0
- package/dist/utils/model-executor-parser.js +69 -0
- package/dist/utils/model-parser.d.ts +6 -0
- package/dist/utils/model-parser.d.ts.map +1 -0
- package/dist/utils/model-parser.js +49 -0
- package/dist/utils/stack-formatter.d.ts +12 -0
- package/dist/utils/stack-formatter.d.ts.map +1 -0
- package/dist/utils/stack-formatter.js +36 -0
- package/dist/utils/storage-utils.d.ts +49 -0
- package/dist/utils/storage-utils.d.ts.map +1 -0
- package/dist/utils/storage-utils.js +80 -0
- package/dist/utils/streaming-utils.d.ts +38 -0
- package/dist/utils/streaming-utils.d.ts.map +1 -0
- package/dist/utils/streaming-utils.js +64 -0
- package/dist/utils/task-o-matic-error.d.ts +206 -0
- package/dist/utils/task-o-matic-error.d.ts.map +1 -0
- package/dist/utils/task-o-matic-error.js +304 -0
- package/package.json +40 -0
- package/src/index.ts +36 -0
- package/src/lib/ai-service/ai-operations.ts +310 -0
- package/src/lib/ai-service/base-operations.ts +139 -0
- package/src/lib/ai-service/documentation-operations.ts +438 -0
- package/src/lib/ai-service/filesystem-tools.ts +73 -0
- package/src/lib/ai-service/gemini-proxy.ts.bak +52 -0
- package/src/lib/ai-service/json-parser.ts +203 -0
- package/src/lib/ai-service/mcp-client.ts +54 -0
- package/src/lib/ai-service/model-provider.ts +192 -0
- package/src/lib/ai-service/prd-operations.ts +854 -0
- package/src/lib/ai-service/research-tools.ts +207 -0
- package/src/lib/ai-service/retry-handler.ts +89 -0
- package/src/lib/ai-service/task-operations.ts +342 -0
- package/src/lib/benchmark/registry.ts +307 -0
- package/src/lib/benchmark/runner.ts +190 -0
- package/src/lib/benchmark/storage.ts +140 -0
- package/src/lib/benchmark/types.ts +121 -0
- package/src/lib/better-t-stack-cli.ts +524 -0
- package/src/lib/bootstrap/cli-bootstrap.ts +397 -0
- package/src/lib/bootstrap/index.ts +2 -0
- package/src/lib/bootstrap/medusa-bootstrap.ts +261 -0
- package/src/lib/config-validation.ts +278 -0
- package/src/lib/config.ts +435 -0
- package/src/lib/context-builder.ts +383 -0
- package/src/lib/executors/claude-code-executor.ts +83 -0
- package/src/lib/executors/codex-executor.ts +85 -0
- package/src/lib/executors/executor-factory.ts +28 -0
- package/src/lib/executors/gemini-executor.ts +80 -0
- package/src/lib/executors/kilo-executor.ts +83 -0
- package/src/lib/executors/opencode-executor.ts +81 -0
- package/src/lib/git-utils.ts +334 -0
- package/src/lib/hooks.ts +121 -0
- package/src/lib/index.ts +166 -0
- package/src/lib/logger.ts +43 -0
- package/src/lib/notifications.ts +103 -0
- package/src/lib/prompt-builder.ts +471 -0
- package/src/lib/prompt-registry.ts +491 -0
- package/src/lib/provider-defaults.json +32 -0
- package/src/lib/storage/file-system.ts +864 -0
- package/src/lib/storage/storage-callbacks.ts +120 -0
- package/src/lib/storage/types.ts +58 -0
- package/src/lib/task-execution-core.ts +591 -0
- package/src/lib/task-execution.ts +59 -0
- package/src/lib/task-loop-execution.ts +214 -0
- package/src/lib/task-planning.ts +157 -0
- package/src/lib/task-review.ts +138 -0
- package/src/lib/validation.ts +140 -0
- package/src/prompts/documentation-detection.ts +21 -0
- package/src/prompts/documentation-recap.ts +11 -0
- package/src/prompts/index.ts +14 -0
- package/src/prompts/prd-combination.ts +32 -0
- package/src/prompts/prd-generation.ts +46 -0
- package/src/prompts/prd-parsing.ts +170 -0
- package/src/prompts/prd-question-answer.ts +25 -0
- package/src/prompts/prd-question.ts +38 -0
- package/src/prompts/prd-rework.ts +79 -0
- package/src/prompts/prd-suggest-stack.ts +97 -0
- package/src/prompts/task-breakdown.ts +149 -0
- package/src/prompts/task-enhancement.ts +138 -0
- package/src/prompts/task-execution.ts +22 -0
- package/src/prompts/task-planning.ts +64 -0
- package/src/prompts/workflow-assistance.ts +151 -0
- package/src/prompts/workflow-prompts.ts +97 -0
- package/src/services/benchmark.ts +433 -0
- package/src/services/prd.ts +845 -0
- package/src/services/tasks.ts +1515 -0
- package/src/services/workflow-ai-assistant.ts +298 -0
- package/src/services/workflow-benchmark.ts +339 -0
- package/src/services/workflow.ts +779 -0
- package/src/test/hooks.test.ts +77 -0
- package/src/test/integration/callbacks.test.ts +39 -0
- package/src/test/lib/ai-service/task-operations.test.ts +430 -0
- package/src/test/lib/config.test.ts +150 -0
- package/src/test/lib/git-utils.test.ts +198 -0
- package/src/test/mocks/mock-ai-operations.ts +205 -0
- package/src/test/mocks/mock-context-builder.ts +84 -0
- package/src/test/mocks/mock-model-provider.ts +21 -0
- package/src/test/mocks/mock-service-factory.ts +64 -0
- package/src/test/mocks/mock-storage.ts +204 -0
- package/src/test/model-parsing.test.ts +78 -0
- package/src/test/services/task-service.test.ts +551 -0
- package/src/test/storage.test.ts +206 -0
- package/src/test/task-loop-git.test.ts +142 -0
- package/src/test/test-mock-setup.ts +46 -0
- package/src/test/test-setup.ts +48 -0
- package/src/test/test-utils.ts +45 -0
- package/src/test/utils/ai-operation-utility.test.ts +306 -0
- package/src/test/utils/error-handling.test.ts +241 -0
- package/src/test/utils/file-utils.test.ts +80 -0
- package/src/test/utils/id-generator.test.ts +44 -0
- package/src/test/utils/model-parser.test.ts +67 -0
- package/src/test/validation.test.ts +19 -0
- package/src/types/callbacks.ts +14 -0
- package/src/types/index.ts +628 -0
- package/src/types/mcp.ts +5 -0
- package/src/types/options.ts +165 -0
- package/src/types/results.ts +216 -0
- package/src/types/workflow-options.ts +113 -0
- package/src/types/workflow-results.ts +87 -0
- package/src/utils/ai-config-builder.ts +33 -0
- package/src/utils/ai-operation-utility.ts +380 -0
- package/src/utils/ai-service-factory.ts +125 -0
- package/src/utils/error-utils.ts +124 -0
- package/src/utils/file-utils.ts +197 -0
- package/src/utils/id-generator.ts +168 -0
- package/src/utils/metadata-utils.ts +48 -0
- package/src/utils/model-executor-parser.ts +80 -0
- package/src/utils/model-parser.ts +58 -0
- package/src/utils/stack-formatter.ts +53 -0
- package/src/utils/storage-utils.ts +94 -0
- package/src/utils/streaming-utils.ts +91 -0
- package/src/utils/task-o-matic-error.ts +393 -0
- package/tsconfig.json +20 -0
- package/tsconfig.tsbuildinfo +1 -0
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ExecuteLoopOptions,
|
|
3
|
+
ExecuteLoopResult,
|
|
4
|
+
Task,
|
|
5
|
+
TaskExecutionConfig,
|
|
6
|
+
} from "../types";
|
|
7
|
+
import { logger } from "./logger";
|
|
8
|
+
import { sendNotifications } from "./notifications";
|
|
9
|
+
import { taskService } from "../services/tasks";
|
|
10
|
+
import { executeTaskCore } from "./task-execution-core";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Execute multiple tasks in a loop with retry and verification
|
|
14
|
+
* This delegates to the unified executeTaskCore for each task
|
|
15
|
+
*/
|
|
16
|
+
export async function executeTaskLoop(
|
|
17
|
+
options: ExecuteLoopOptions
|
|
18
|
+
): Promise<ExecuteLoopResult> {
|
|
19
|
+
const startTime = Date.now();
|
|
20
|
+
const { filters = {}, tool = "opencode", config = {}, dry = false } = options;
|
|
21
|
+
|
|
22
|
+
const {
|
|
23
|
+
maxRetries = 3,
|
|
24
|
+
verificationCommands = [],
|
|
25
|
+
autoCommit = false,
|
|
26
|
+
tryModels,
|
|
27
|
+
plan,
|
|
28
|
+
planModel,
|
|
29
|
+
reviewPlan,
|
|
30
|
+
review,
|
|
31
|
+
reviewModel,
|
|
32
|
+
customMessage,
|
|
33
|
+
continueSession,
|
|
34
|
+
model,
|
|
35
|
+
includeCompleted = false,
|
|
36
|
+
includePrd = false,
|
|
37
|
+
notifyTargets,
|
|
38
|
+
} = config;
|
|
39
|
+
|
|
40
|
+
logger.info("\n๐ Starting Task Loop Execution\n");
|
|
41
|
+
logger.progress(`Executor Tool: ${tool}`);
|
|
42
|
+
if (model) logger.progress(`Executor Model: ${model}`);
|
|
43
|
+
logger.progress(`Max Retries per Task: ${maxRetries}`);
|
|
44
|
+
logger.progress(
|
|
45
|
+
`Verification Commands: ${
|
|
46
|
+
verificationCommands.length > 0
|
|
47
|
+
? verificationCommands.join(", ")
|
|
48
|
+
: "None"
|
|
49
|
+
}`
|
|
50
|
+
);
|
|
51
|
+
logger.progress(`Auto Commit: ${autoCommit ? "Yes" : "No"}`);
|
|
52
|
+
logger.progress(`Dry Run: ${dry ? "Yes" : "No"}\n`);
|
|
53
|
+
|
|
54
|
+
// Get tasks to execute
|
|
55
|
+
let tasksToExecute: Task[] = [];
|
|
56
|
+
|
|
57
|
+
if (filters.taskIds && filters.taskIds.length > 0) {
|
|
58
|
+
// Execute specific tasks by ID
|
|
59
|
+
for (const taskId of filters.taskIds) {
|
|
60
|
+
const task = await taskService.getTask(taskId);
|
|
61
|
+
if (task) {
|
|
62
|
+
tasksToExecute.push(task);
|
|
63
|
+
} else {
|
|
64
|
+
logger.warn(`โ ๏ธ Task ${taskId} not found, skipping`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
} else {
|
|
68
|
+
// Get all tasks matching filters
|
|
69
|
+
tasksToExecute = await taskService.listTasks({
|
|
70
|
+
status: filters.status,
|
|
71
|
+
tag: filters.tag,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Filter out completed tasks unless includeCompleted is set
|
|
76
|
+
if (!includeCompleted) {
|
|
77
|
+
const beforeCount = tasksToExecute.length;
|
|
78
|
+
tasksToExecute = tasksToExecute.filter((t) => t.status !== "completed");
|
|
79
|
+
const filtered = beforeCount - tasksToExecute.length;
|
|
80
|
+
if (filtered > 0) {
|
|
81
|
+
logger.info(` (Skipped ${filtered} already-completed task(s))\n`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (tasksToExecute.length === 0) {
|
|
86
|
+
logger.warn("โ ๏ธ No tasks to execute (all may be completed)");
|
|
87
|
+
const emptyResult: ExecuteLoopResult = {
|
|
88
|
+
totalTasks: 0,
|
|
89
|
+
completedTasks: 0,
|
|
90
|
+
failedTasks: 0,
|
|
91
|
+
taskResults: [],
|
|
92
|
+
duration: Date.now() - startTime,
|
|
93
|
+
};
|
|
94
|
+
if (notifyTargets?.length)
|
|
95
|
+
await sendNotifications(notifyTargets, emptyResult);
|
|
96
|
+
return emptyResult;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
logger.info(`๐ Found ${tasksToExecute.length} task(s) to execute\n`);
|
|
100
|
+
|
|
101
|
+
const taskResults: ExecuteLoopResult["taskResults"] = [];
|
|
102
|
+
let completedTasks = 0;
|
|
103
|
+
let failedTasks = 0;
|
|
104
|
+
|
|
105
|
+
// Execute tasks sequentially
|
|
106
|
+
for (let i = 0; i < tasksToExecute.length; i++) {
|
|
107
|
+
const task = tasksToExecute[i];
|
|
108
|
+
|
|
109
|
+
logger.info(
|
|
110
|
+
`\n${"=".repeat(60)}\n๐ Task ${i + 1}/${tasksToExecute.length}: ${
|
|
111
|
+
task.title
|
|
112
|
+
} (${task.id})\n${"=".repeat(60)}\n`
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
// Build unified task execution config
|
|
116
|
+
const taskConfig: TaskExecutionConfig = {
|
|
117
|
+
tool,
|
|
118
|
+
customMessage, // NEW: Support custom message override
|
|
119
|
+
executorConfig: {
|
|
120
|
+
continueLastSession: continueSession, // NEW: Support session continuation
|
|
121
|
+
model, // NEW: Pass model to executor
|
|
122
|
+
},
|
|
123
|
+
verificationCommands,
|
|
124
|
+
enableRetry: true, // Always enable retry in loop
|
|
125
|
+
maxRetries,
|
|
126
|
+
tryModels,
|
|
127
|
+
enablePlanPhase: plan,
|
|
128
|
+
planModel,
|
|
129
|
+
reviewPlan,
|
|
130
|
+
enableReviewPhase: review,
|
|
131
|
+
reviewModel,
|
|
132
|
+
autoCommit,
|
|
133
|
+
executeSubtasks: true, // Now supports subtasks!
|
|
134
|
+
includeCompleted, // Pass through to subtask execution
|
|
135
|
+
includePrd, // Pass through to execution core
|
|
136
|
+
dry,
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
try {
|
|
140
|
+
// Execute task using unified core
|
|
141
|
+
const result = await executeTaskCore(task.id, taskConfig);
|
|
142
|
+
|
|
143
|
+
// Check if task succeeded
|
|
144
|
+
const succeeded = result.success;
|
|
145
|
+
|
|
146
|
+
if (succeeded) {
|
|
147
|
+
completedTasks++;
|
|
148
|
+
logger.success(
|
|
149
|
+
`\nโ
Task ${task.title} completed successfully after ${result.attempts.length} attempt(s)\n`
|
|
150
|
+
);
|
|
151
|
+
} else {
|
|
152
|
+
failedTasks++;
|
|
153
|
+
logger.error(
|
|
154
|
+
`\nโ Task ${task.title} failed after ${result.attempts.length} attempt(s)\n`
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
taskResults.push({
|
|
159
|
+
taskId: task.id,
|
|
160
|
+
taskTitle: task.title,
|
|
161
|
+
attempts: result.attempts,
|
|
162
|
+
finalStatus: succeeded ? "completed" : "failed",
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
// Stop the loop on first failure
|
|
166
|
+
if (!succeeded) {
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
} catch (error) {
|
|
170
|
+
failedTasks++;
|
|
171
|
+
logger.error(
|
|
172
|
+
`\nโ Task ${task.title} failed with error: ${
|
|
173
|
+
error instanceof Error ? error.message : "Unknown error"
|
|
174
|
+
}\n`
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
taskResults.push({
|
|
178
|
+
taskId: task.id,
|
|
179
|
+
taskTitle: task.title,
|
|
180
|
+
attempts: [],
|
|
181
|
+
finalStatus: "failed",
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// Stop the loop on error
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const duration = Date.now() - startTime;
|
|
190
|
+
|
|
191
|
+
// Print summary
|
|
192
|
+
logger.info(
|
|
193
|
+
`\n${"=".repeat(60)}\n๐ Execution Summary\n${"=".repeat(60)}`
|
|
194
|
+
);
|
|
195
|
+
logger.progress(`Total Tasks: ${tasksToExecute.length}`);
|
|
196
|
+
logger.success(`โ
Completed: ${completedTasks}`);
|
|
197
|
+
logger.error(`โ Failed: ${failedTasks}`);
|
|
198
|
+
logger.progress(`โฑ Duration: ${(duration / 1000).toFixed(2)} seconds\n`);
|
|
199
|
+
|
|
200
|
+
const result: ExecuteLoopResult = {
|
|
201
|
+
totalTasks: tasksToExecute.length,
|
|
202
|
+
completedTasks,
|
|
203
|
+
failedTasks,
|
|
204
|
+
taskResults,
|
|
205
|
+
duration,
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
// Send notifications if configured
|
|
209
|
+
if (notifyTargets?.length) {
|
|
210
|
+
await sendNotifications(notifyTargets, result);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return result;
|
|
214
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { logger } from "./logger";
|
|
2
|
+
import { ExecutorFactory } from "./executors/executor-factory";
|
|
3
|
+
import { ExecutorConfig, ExecutorTool, Task } from "../types";
|
|
4
|
+
import { existsSync, readFileSync } from "fs";
|
|
5
|
+
|
|
6
|
+
import { exec } from "child_process";
|
|
7
|
+
import { promisify } from "util";
|
|
8
|
+
import { commitFile } from "./git-utils";
|
|
9
|
+
|
|
10
|
+
const execAsync = promisify(exec);
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Planning phase configuration
|
|
14
|
+
*/
|
|
15
|
+
export interface PlanningConfig {
|
|
16
|
+
planModel?: string; // Format: "executor:model" or just "model"
|
|
17
|
+
reviewPlan?: boolean; // Enable human review loop
|
|
18
|
+
autoCommit?: boolean; // Auto-commit the plan file
|
|
19
|
+
dry?: boolean; // Dry run mode
|
|
20
|
+
onPlanReview?: (planFile: string) => Promise<string | undefined>; // Callback for review
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Planning phase result
|
|
25
|
+
*/
|
|
26
|
+
export interface PlanningResult {
|
|
27
|
+
planContent?: string;
|
|
28
|
+
planFileName?: string;
|
|
29
|
+
success: boolean;
|
|
30
|
+
error?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Execute planning phase for a task
|
|
35
|
+
* Creates an AI-generated implementation plan with optional human review
|
|
36
|
+
*/
|
|
37
|
+
export async function executePlanningPhase(
|
|
38
|
+
task: Task,
|
|
39
|
+
defaultTool: ExecutorTool,
|
|
40
|
+
config: PlanningConfig,
|
|
41
|
+
execFn: (
|
|
42
|
+
command: string
|
|
43
|
+
) => Promise<{ stdout: string; stderr: string }> = execAsync
|
|
44
|
+
): Promise<PlanningResult> {
|
|
45
|
+
const { planModel, reviewPlan, autoCommit, dry, onPlanReview } = config;
|
|
46
|
+
|
|
47
|
+
logger.info(`\n๐ง Starting Planning Phase for Task: ${task.title}`);
|
|
48
|
+
|
|
49
|
+
const planFileName = `task-${task.id}-plan.md`;
|
|
50
|
+
|
|
51
|
+
// Parse executor and model from planModel string
|
|
52
|
+
const planExecutor = planModel
|
|
53
|
+
? (planModel.split(":")[0] as ExecutorTool)
|
|
54
|
+
: defaultTool;
|
|
55
|
+
const planModelName = planModel ? planModel.split(":")[1] : undefined;
|
|
56
|
+
|
|
57
|
+
let planningPrompt = `You are a senior software architect. Analyze the following task and create a detailed implementation plan.
|
|
58
|
+
|
|
59
|
+
Task: ${task.title}
|
|
60
|
+
Description: ${task.description || "No description provided."}
|
|
61
|
+
|
|
62
|
+
Requirements:
|
|
63
|
+
1. Analyze the task requirements.
|
|
64
|
+
2. Create a detailed step-by-step implementation plan.
|
|
65
|
+
3. Identify necessary file changes.
|
|
66
|
+
4. Write this plan to a file named "${planFileName}" in the current directory.
|
|
67
|
+
5. Do NOT implement the code yet, just create the plan file.
|
|
68
|
+
|
|
69
|
+
Please create the "${planFileName}" file now.`;
|
|
70
|
+
|
|
71
|
+
logger.progress(
|
|
72
|
+
` Using executor for planning: ${planExecutor}${
|
|
73
|
+
planModelName ? ` (${planModelName})` : ""
|
|
74
|
+
}`
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
// Create executor for planning
|
|
78
|
+
const planningConfig: ExecutorConfig = {
|
|
79
|
+
model: planModelName,
|
|
80
|
+
continueLastSession: false,
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const executor = ExecutorFactory.create(planExecutor, planningConfig);
|
|
84
|
+
|
|
85
|
+
try {
|
|
86
|
+
let planningComplete = false;
|
|
87
|
+
let planContent: string | undefined;
|
|
88
|
+
|
|
89
|
+
while (!planningComplete) {
|
|
90
|
+
await executor.execute(planningPrompt, dry, planningConfig);
|
|
91
|
+
|
|
92
|
+
if (!dry) {
|
|
93
|
+
// Verify plan file exists and read it
|
|
94
|
+
if (existsSync(planFileName)) {
|
|
95
|
+
planContent = readFileSync(planFileName, "utf-8");
|
|
96
|
+
logger.success(`โ
Plan created successfully: ${planFileName}`);
|
|
97
|
+
|
|
98
|
+
// Human Review Loop
|
|
99
|
+
if (reviewPlan) {
|
|
100
|
+
if (onPlanReview) {
|
|
101
|
+
logger.warn(
|
|
102
|
+
`\n๐ Pausing for Human Review of the Plan: ${planFileName}`
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
const feedback = await onPlanReview(planFileName);
|
|
106
|
+
|
|
107
|
+
if (feedback && feedback.trim() !== "") {
|
|
108
|
+
logger.info("๐ Refining plan based on feedback...");
|
|
109
|
+
planningPrompt = `The user provided the following feedback on the plan you just created:
|
|
110
|
+
|
|
111
|
+
"${feedback}"
|
|
112
|
+
|
|
113
|
+
Please update the plan file "${planFileName}" to incorporate this feedback.`;
|
|
114
|
+
// Continue loop to regenerate plan
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
} else {
|
|
118
|
+
logger.warn("Review requested but no review callback provided.");
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Auto-commit plan if enabled (only after approval)
|
|
123
|
+
if (autoCommit) {
|
|
124
|
+
await commitFile(
|
|
125
|
+
planFileName,
|
|
126
|
+
`docs: create implementation plan for task ${task.id}`,
|
|
127
|
+
execFn
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
planningComplete = true;
|
|
132
|
+
} else {
|
|
133
|
+
logger.warn(
|
|
134
|
+
`โ ๏ธ Plan file ${planFileName} was not created by the executor.`
|
|
135
|
+
);
|
|
136
|
+
planningComplete = true; // Exit loop to avoid infinite retry if file not created
|
|
137
|
+
}
|
|
138
|
+
} else {
|
|
139
|
+
planningComplete = true; // Dry run
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return {
|
|
144
|
+
planContent,
|
|
145
|
+
planFileName,
|
|
146
|
+
success: true,
|
|
147
|
+
};
|
|
148
|
+
} catch (error) {
|
|
149
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
150
|
+
logger.error(`โ Planning phase failed: ${errorMessage}`);
|
|
151
|
+
|
|
152
|
+
return {
|
|
153
|
+
success: false,
|
|
154
|
+
error: errorMessage,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { logger } from "./logger";
|
|
2
|
+
import { ExecutorTool, Task } from "../types";
|
|
3
|
+
import { getAIOperations } from "../utils/ai-service-factory";
|
|
4
|
+
import { exec } from "child_process";
|
|
5
|
+
import { promisify } from "util";
|
|
6
|
+
|
|
7
|
+
const execAsync = promisify(exec);
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Review phase configuration
|
|
11
|
+
*/
|
|
12
|
+
export interface ReviewConfig {
|
|
13
|
+
reviewModel?: string; // Format: "executor:model" or just "model"
|
|
14
|
+
planContent?: string; // Plan content to include in review context
|
|
15
|
+
dry?: boolean; // Dry run mode
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Review phase result
|
|
20
|
+
*/
|
|
21
|
+
export interface ReviewResult {
|
|
22
|
+
approved: boolean;
|
|
23
|
+
feedback: string;
|
|
24
|
+
success: boolean;
|
|
25
|
+
error?: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Execute AI review phase for task execution
|
|
30
|
+
* Reviews code changes and provides feedback
|
|
31
|
+
*/
|
|
32
|
+
export async function executeReviewPhase(
|
|
33
|
+
task: Task,
|
|
34
|
+
config: ReviewConfig,
|
|
35
|
+
execFn: (
|
|
36
|
+
command: string
|
|
37
|
+
) => Promise<{ stdout: string; stderr: string }> = execAsync
|
|
38
|
+
): Promise<ReviewResult> {
|
|
39
|
+
const { reviewModel, planContent, dry } = config;
|
|
40
|
+
|
|
41
|
+
logger.info("\n๐ต๏ธ Starting AI Review Phase...");
|
|
42
|
+
|
|
43
|
+
if (dry) {
|
|
44
|
+
logger.warn("๐ DRY RUN - Review phase skipped");
|
|
45
|
+
return {
|
|
46
|
+
approved: true,
|
|
47
|
+
feedback: "Dry run - review skipped",
|
|
48
|
+
success: true,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
// Get git diff
|
|
54
|
+
const { stdout: diff } = await execFn("git diff HEAD");
|
|
55
|
+
|
|
56
|
+
if (!diff.trim()) {
|
|
57
|
+
logger.warn("โ ๏ธ No changes detected to review.");
|
|
58
|
+
return {
|
|
59
|
+
approved: true,
|
|
60
|
+
feedback: "No changes to review",
|
|
61
|
+
success: true,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Parse executor and model from reviewModel string
|
|
66
|
+
const reviewExecutor = reviewModel
|
|
67
|
+
? (reviewModel.split(":")[0] as ExecutorTool)
|
|
68
|
+
: undefined;
|
|
69
|
+
const reviewModelName = reviewModel ? reviewModel.split(":")[1] : undefined;
|
|
70
|
+
|
|
71
|
+
if (reviewExecutor && reviewModelName) {
|
|
72
|
+
logger.progress(
|
|
73
|
+
` Using executor for review: ${reviewExecutor} (${reviewModelName})`
|
|
74
|
+
);
|
|
75
|
+
} else {
|
|
76
|
+
logger.progress(" Using default AI provider for review");
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const reviewPrompt = `You are a strict code reviewer. Review the following changes for the task.
|
|
80
|
+
|
|
81
|
+
Task: ${task.title}
|
|
82
|
+
${planContent ? `Plan: ${planContent}` : "Plan: No plan provided."}
|
|
83
|
+
|
|
84
|
+
Git Diff:
|
|
85
|
+
${diff.substring(0, 10000)}
|
|
86
|
+
|
|
87
|
+
Analyze the changes for:
|
|
88
|
+
1. Correctness (does it solve the task?)
|
|
89
|
+
2. Code Quality (clean code, best practices)
|
|
90
|
+
3. Potential Bugs
|
|
91
|
+
|
|
92
|
+
Return a JSON object:
|
|
93
|
+
{
|
|
94
|
+
"approved": boolean,
|
|
95
|
+
"feedback": "Detailed feedback explaining why it was rejected or approved"
|
|
96
|
+
}
|
|
97
|
+
`;
|
|
98
|
+
|
|
99
|
+
// Use AI operations to get review response
|
|
100
|
+
const aiOps = getAIOperations();
|
|
101
|
+
const aiResponse = await aiOps.streamText(reviewPrompt);
|
|
102
|
+
const jsonMatch = aiResponse.match(/\{[\s\S]*\}/);
|
|
103
|
+
|
|
104
|
+
if (jsonMatch) {
|
|
105
|
+
const reviewResult = JSON.parse(jsonMatch[0]);
|
|
106
|
+
|
|
107
|
+
if (!reviewResult.approved) {
|
|
108
|
+
logger.error(`โ AI Review Rejected Changes: ${reviewResult.feedback}`);
|
|
109
|
+
} else {
|
|
110
|
+
logger.success(`โ
AI Review Approved: ${reviewResult.feedback}`);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return {
|
|
114
|
+
approved: reviewResult.approved,
|
|
115
|
+
feedback: reviewResult.feedback,
|
|
116
|
+
success: true,
|
|
117
|
+
};
|
|
118
|
+
} else {
|
|
119
|
+
logger.warn("โ ๏ธ Could not parse AI review response. Assuming approval.");
|
|
120
|
+
return {
|
|
121
|
+
approved: true,
|
|
122
|
+
feedback: "Could not parse review response, assuming approval",
|
|
123
|
+
success: true,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
} catch (error) {
|
|
127
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
128
|
+
logger.error(`โ AI Review failed: ${errorMessage}`);
|
|
129
|
+
|
|
130
|
+
// If review crashes, warn but don't fail the task
|
|
131
|
+
return {
|
|
132
|
+
approved: true,
|
|
133
|
+
feedback: `Review failed: ${errorMessage}`,
|
|
134
|
+
success: false,
|
|
135
|
+
error: errorMessage,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { exec } from "child_process";
|
|
2
|
+
import { promisify } from "util";
|
|
3
|
+
import { logger } from "./logger";
|
|
4
|
+
import { AIConfig } from "../types";
|
|
5
|
+
|
|
6
|
+
const execAsync = promisify(exec);
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Validation/Verification result for a single command
|
|
10
|
+
*/
|
|
11
|
+
export interface ValidationResult {
|
|
12
|
+
command: string;
|
|
13
|
+
success: boolean;
|
|
14
|
+
output?: string;
|
|
15
|
+
error?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Format verification error for AI feedback
|
|
20
|
+
* Produces a structured message that AI can easily parse and act upon
|
|
21
|
+
*/
|
|
22
|
+
export function formatVerificationError(result: ValidationResult): string {
|
|
23
|
+
return `## Verification Failed: ${result.command}
|
|
24
|
+
|
|
25
|
+
**Error Output**:
|
|
26
|
+
\`\`\`
|
|
27
|
+
${result.error || "No error output captured"}
|
|
28
|
+
\`\`\`
|
|
29
|
+
|
|
30
|
+
Please analyze this error carefully and fix the issue. Common causes include:
|
|
31
|
+
- Syntax errors in the code
|
|
32
|
+
- Type errors (missing types, wrong types)
|
|
33
|
+
- Missing imports or dependencies
|
|
34
|
+
- Logic errors or incorrect implementations
|
|
35
|
+
- Build configuration issues`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function isValidAIProvider(
|
|
39
|
+
provider: string
|
|
40
|
+
): provider is NonNullable<AIConfig["provider"]> {
|
|
41
|
+
return ["openrouter", "openai", "anthropic", "custom"].includes(provider);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Run validation/verification commands and return results
|
|
46
|
+
* Supports both --validate and --verify as aliases
|
|
47
|
+
* Returns detailed results for each command
|
|
48
|
+
*/
|
|
49
|
+
export async function runValidations(
|
|
50
|
+
validations: string[],
|
|
51
|
+
dry: boolean,
|
|
52
|
+
execFn: (
|
|
53
|
+
command: string
|
|
54
|
+
) => Promise<{ stdout: string; stderr: string }> = execAsync
|
|
55
|
+
): Promise<ValidationResult[]> {
|
|
56
|
+
const results: ValidationResult[] = [];
|
|
57
|
+
|
|
58
|
+
if (validations.length === 0) {
|
|
59
|
+
return results;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (dry) {
|
|
63
|
+
logger.warn(
|
|
64
|
+
"๐ DRY RUN - Validation/verification commands that would run:"
|
|
65
|
+
);
|
|
66
|
+
validations.forEach((cmd) => {
|
|
67
|
+
logger.progress(` ${cmd}`);
|
|
68
|
+
results.push({
|
|
69
|
+
command: cmd,
|
|
70
|
+
success: true,
|
|
71
|
+
output: "DRY RUN - not executed",
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
return results;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
logger.info(
|
|
78
|
+
`๐งช Running ${validations.length} validation/verification command${
|
|
79
|
+
validations.length > 1 ? "s" : ""
|
|
80
|
+
}...`
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
for (let i = 0; i < validations.length; i++) {
|
|
84
|
+
const validation = validations[i];
|
|
85
|
+
logger.info(
|
|
86
|
+
`๐งช Running validation [${i + 1}/${validations.length}]: ${validation}`
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
const { stdout, stderr } = await execFn(validation);
|
|
91
|
+
logger.success(`โ
Validation passed: ${validation}`);
|
|
92
|
+
|
|
93
|
+
// Show stdout if there's any output
|
|
94
|
+
if (stdout && stdout.trim()) {
|
|
95
|
+
logger.progress(` Output: ${stdout.trim()}`);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
results.push({
|
|
99
|
+
command: validation,
|
|
100
|
+
success: true,
|
|
101
|
+
output: stdout.trim(),
|
|
102
|
+
});
|
|
103
|
+
} catch (error: any) {
|
|
104
|
+
logger.error(`โ Validation failed: ${validation}`);
|
|
105
|
+
|
|
106
|
+
const errorOutput = error.stderr || error.stdout || error.message;
|
|
107
|
+
|
|
108
|
+
// Show error details
|
|
109
|
+
if (error.stdout && error.stdout.trim()) {
|
|
110
|
+
logger.warn(` stdout: ${error.stdout.trim()}`);
|
|
111
|
+
}
|
|
112
|
+
if (error.stderr && error.stderr.trim()) {
|
|
113
|
+
logger.error(` stderr: ${error.stderr.trim()}`);
|
|
114
|
+
}
|
|
115
|
+
if (error.message) {
|
|
116
|
+
logger.error(` Error: ${error.message}`);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
results.push({
|
|
120
|
+
command: validation,
|
|
121
|
+
success: false,
|
|
122
|
+
error: errorOutput,
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// Return early on first failure
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const allPassed = results.every((r) => r.success);
|
|
131
|
+
if (allPassed) {
|
|
132
|
+
logger.success(
|
|
133
|
+
`๐ All ${validations.length} validation${
|
|
134
|
+
validations.length > 1 ? "s" : ""
|
|
135
|
+
} passed!`
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return results;
|
|
140
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export const DOCUMENTATION_DETECTION_PROMPT = `You are an expert developer. Your job is to analyze a task and fetch relevant documentation using Context7 and create a dedicated documentation for the task.
|
|
2
|
+
|
|
3
|
+
Do not create a plan, i want a documentation for the actual task using the knowledge you gained from the research.
|
|
4
|
+
|
|
5
|
+
## Task:
|
|
6
|
+
**Title**: {TASK_TITLE}
|
|
7
|
+
**Description**: {TASK_DESCRIPTION}
|
|
8
|
+
|
|
9
|
+
## Current Stack:
|
|
10
|
+
{STACK_INFO}
|
|
11
|
+
|
|
12
|
+
## Already Researched:
|
|
13
|
+
{EXISTING_RESEARCH}
|
|
14
|
+
|
|
15
|
+
## Instructions:
|
|
16
|
+
1. Identify technologies/libraries mentioned in the task that need documentation
|
|
17
|
+
2. Skip anything already covered in existing research
|
|
18
|
+
3. Use Context7 to resolve library names and fetch documentation
|
|
19
|
+
4. Create a focused documentation only on what's actually needed for this specific task
|
|
20
|
+
|
|
21
|
+
Get the documentation libraries needed for this task.`;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export const DOCUMENTATION_RECAP_PROMPT = `Create a concise recap of the documentation fetched for these libraries:
|
|
2
|
+
|
|
3
|
+
Libraries:
|
|
4
|
+
{LIBRARIES_LIST}
|
|
5
|
+
|
|
6
|
+
Documentation Contents:
|
|
7
|
+
{DOCUMENTATION_CONTENTS}
|
|
8
|
+
|
|
9
|
+
Please provide a 2-3 sentence summary of what documentation is available and how it relates to the task.`;
|
|
10
|
+
|
|
11
|
+
export const DOCUMENTATION_RECAP_SYSTEM_PROMPT = `You are a technical writer who creates concise summaries of documentation collections.`;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export * from "./prd-parsing";
|
|
2
|
+
export * from "./task-breakdown";
|
|
3
|
+
export * from "./task-enhancement";
|
|
4
|
+
export * from "./prd-rework";
|
|
5
|
+
export * from "./documentation-detection";
|
|
6
|
+
export * from "./task-planning";
|
|
7
|
+
export * from "./task-execution";
|
|
8
|
+
export * from "./prd-question";
|
|
9
|
+
export * from "./prd-generation";
|
|
10
|
+
export * from "./prd-combination";
|
|
11
|
+
export * from "./documentation-recap";
|
|
12
|
+
export * from "./prd-question-answer";
|
|
13
|
+
export * from "./workflow-prompts";
|
|
14
|
+
export * from "./prd-suggest-stack";
|