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,139 @@
|
|
|
1
|
+
import { streamText, type LanguageModel } from "ai";
|
|
2
|
+
import { AIConfig, StreamingOptions, RetryConfig } from "../../types";
|
|
3
|
+
import { JSONParser } from "./json-parser";
|
|
4
|
+
import { Context7Client } from "./mcp-client";
|
|
5
|
+
import { RetryHandler } from "./retry-handler";
|
|
6
|
+
import { ModelProvider } from "./model-provider";
|
|
7
|
+
|
|
8
|
+
export class BaseOperations {
|
|
9
|
+
protected jsonParser = new JSONParser();
|
|
10
|
+
protected context7Client = new Context7Client();
|
|
11
|
+
protected retryHandler = new RetryHandler();
|
|
12
|
+
protected modelProvider = new ModelProvider();
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Merges AI configuration with proper precedence.
|
|
16
|
+
*
|
|
17
|
+
* Configuration precedence (highest to lowest):
|
|
18
|
+
* 1. Method parameter `config` (operation-specific overrides)
|
|
19
|
+
* 2. ConfigManager global config (project-level settings)
|
|
20
|
+
* 3. Environment variables (OPENAI_API_KEY, etc.)
|
|
21
|
+
* 4. Provider defaults (defined in config.ts)
|
|
22
|
+
*
|
|
23
|
+
* @param config - Optional operation-specific config overrides
|
|
24
|
+
* @returns Merged AIConfig with all precedence levels applied
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* // Override just the model for this operation
|
|
29
|
+
* const finalConfig = this.mergeAIConfig({ model: "gpt-4o" });
|
|
30
|
+
*
|
|
31
|
+
* // Use default config (from ConfigManager + env vars)
|
|
32
|
+
* const finalConfig = this.mergeAIConfig();
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
protected mergeAIConfig(config?: Partial<AIConfig>): AIConfig {
|
|
36
|
+
// Get base config (includes ConfigManager + env vars + defaults)
|
|
37
|
+
const baseConfig = this.modelProvider.getAIConfig();
|
|
38
|
+
|
|
39
|
+
// Apply operation-specific overrides (highest priority)
|
|
40
|
+
return { ...baseConfig, ...config };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Handles Context7 tool results by caching documentation.
|
|
45
|
+
* Extracts and saves documentation from get-library-docs tool results.
|
|
46
|
+
*
|
|
47
|
+
* @param chunk - The chunk to check for Context7 tool results
|
|
48
|
+
* @protected
|
|
49
|
+
*/
|
|
50
|
+
protected handleContext7ToolResult(chunk: any): void {
|
|
51
|
+
if (chunk.type === "tool-result" && chunk.toolName === "get-library-docs") {
|
|
52
|
+
const docs = chunk.output;
|
|
53
|
+
const libraryID = chunk.input?.context7CompatibleLibraryID || "unknown";
|
|
54
|
+
const topic = chunk.input?.topic || "general";
|
|
55
|
+
|
|
56
|
+
if (docs && typeof docs === "object" && "content" in docs) {
|
|
57
|
+
this.context7Client.saveContext7Documentation(
|
|
58
|
+
libraryID,
|
|
59
|
+
docs.content,
|
|
60
|
+
topic
|
|
61
|
+
);
|
|
62
|
+
} else if (docs && typeof docs === "string") {
|
|
63
|
+
this.context7Client.saveContext7Documentation(libraryID, docs, topic);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async streamText(
|
|
69
|
+
prompt: string,
|
|
70
|
+
config?: Partial<AIConfig>,
|
|
71
|
+
systemPrompt?: string,
|
|
72
|
+
userMessage?: string,
|
|
73
|
+
streamingOptions?: StreamingOptions,
|
|
74
|
+
retryConfig?: Partial<RetryConfig>
|
|
75
|
+
): Promise<string> {
|
|
76
|
+
// Merge config with proper precedence (Bug fix 2.9)
|
|
77
|
+
const aiConfig = this.mergeAIConfig(config);
|
|
78
|
+
|
|
79
|
+
return this.retryHandler.executeWithRetry(
|
|
80
|
+
async () => {
|
|
81
|
+
const model = this.modelProvider.getModel(aiConfig);
|
|
82
|
+
|
|
83
|
+
const result = streamText({
|
|
84
|
+
model,
|
|
85
|
+
system: systemPrompt,
|
|
86
|
+
messages: [{ role: "user", content: userMessage || prompt }],
|
|
87
|
+
maxRetries: 0,
|
|
88
|
+
onError: ({ error }) => {
|
|
89
|
+
streamingOptions?.onError?.(error);
|
|
90
|
+
throw error;
|
|
91
|
+
},
|
|
92
|
+
onChunk: streamingOptions?.onChunk
|
|
93
|
+
? ({ chunk }) => {
|
|
94
|
+
if (chunk.type === "text-delta") {
|
|
95
|
+
streamingOptions.onChunk!(chunk.text);
|
|
96
|
+
} else if (chunk.type === "reasoning-delta") {
|
|
97
|
+
streamingOptions.onReasoning?.(chunk.text);
|
|
98
|
+
}
|
|
99
|
+
// Handle Context7 tool result caching
|
|
100
|
+
this.handleContext7ToolResult(chunk);
|
|
101
|
+
}
|
|
102
|
+
: undefined,
|
|
103
|
+
onFinish: streamingOptions?.onFinish
|
|
104
|
+
? ({ text, finishReason, usage }) => {
|
|
105
|
+
streamingOptions.onFinish!({
|
|
106
|
+
text,
|
|
107
|
+
finishReason,
|
|
108
|
+
usage,
|
|
109
|
+
isAborted: false,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
: undefined,
|
|
113
|
+
...(aiConfig.provider === "openrouter" &&
|
|
114
|
+
aiConfig.reasoning &&
|
|
115
|
+
aiConfig.reasoning.maxTokens
|
|
116
|
+
? {
|
|
117
|
+
providerOptions: {
|
|
118
|
+
openrouter: {
|
|
119
|
+
reasoning: {
|
|
120
|
+
max_tokens: aiConfig.reasoning.maxTokens,
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
}
|
|
125
|
+
: {}),
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
let fullText = "";
|
|
129
|
+
for await (const textPart of result.textStream) {
|
|
130
|
+
fullText += textPart;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return fullText;
|
|
134
|
+
},
|
|
135
|
+
retryConfig,
|
|
136
|
+
"AI streaming"
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
import { streamText, stepCountIs } from "ai";
|
|
2
|
+
import type { ToolSet } from "ai";
|
|
3
|
+
import {
|
|
4
|
+
AIConfig,
|
|
5
|
+
DocumentationDetection,
|
|
6
|
+
StreamingOptions,
|
|
7
|
+
RetryConfig,
|
|
8
|
+
TaskDocumentation,
|
|
9
|
+
} from "../../types";
|
|
10
|
+
import { PromptBuilder } from "../prompt-builder";
|
|
11
|
+
import { TASK_ENHANCEMENT_SYSTEM_PROMPT } from "../../prompts";
|
|
12
|
+
import { getContextBuilder, getStorage } from "../../utils/ai-service-factory";
|
|
13
|
+
import { filesystemTools } from "./filesystem-tools";
|
|
14
|
+
import { BaseOperations } from "./base-operations";
|
|
15
|
+
import { logger } from "../logger";
|
|
16
|
+
|
|
17
|
+
export class DocumentationOperations extends BaseOperations {
|
|
18
|
+
async enhanceTaskWithDocumentation(
|
|
19
|
+
taskId: string,
|
|
20
|
+
taskTitle: string,
|
|
21
|
+
taskDescription: string,
|
|
22
|
+
stackInfo?: string,
|
|
23
|
+
streamingOptions?: StreamingOptions,
|
|
24
|
+
retryConfig?: Partial<RetryConfig>,
|
|
25
|
+
config?: Partial<AIConfig>,
|
|
26
|
+
existingResearch?: Record<string, Array<{ query: string; doc: string }>>,
|
|
27
|
+
enableFilesystemTools?: boolean
|
|
28
|
+
): Promise<string> {
|
|
29
|
+
return this.retryHandler
|
|
30
|
+
.executeWithRetry(
|
|
31
|
+
async () => {
|
|
32
|
+
const mcpTools = await this.context7Client.getMCPTools();
|
|
33
|
+
const defaultAIConfig = this.modelProvider.getAIConfig();
|
|
34
|
+
const aiConfig = config
|
|
35
|
+
? { ...defaultAIConfig, ...config }
|
|
36
|
+
: defaultAIConfig;
|
|
37
|
+
const model = this.modelProvider.getModel(aiConfig);
|
|
38
|
+
|
|
39
|
+
const contextBuilder = getContextBuilder();
|
|
40
|
+
const builtContext = await contextBuilder.buildContext("1.1");
|
|
41
|
+
|
|
42
|
+
const existingResearchContext = existingResearch
|
|
43
|
+
? Object.entries(existingResearch)
|
|
44
|
+
.map(
|
|
45
|
+
([lib, entries]) =>
|
|
46
|
+
`### ${lib}\n${entries
|
|
47
|
+
.map((e) => `- Query: "${e.query}"`)
|
|
48
|
+
.join("\n")}`
|
|
49
|
+
)
|
|
50
|
+
.join("\n\n")
|
|
51
|
+
: "No existing research available.";
|
|
52
|
+
|
|
53
|
+
const promptResult = PromptBuilder.buildPrompt({
|
|
54
|
+
name: "task-enhancement",
|
|
55
|
+
type: "user",
|
|
56
|
+
variables: {
|
|
57
|
+
TASK_TITLE: taskTitle,
|
|
58
|
+
TASK_DESCRIPTION: taskDescription,
|
|
59
|
+
CONTEXT_INFO: `Technology stack: ${stackInfo || "Not specified"}`,
|
|
60
|
+
EXISTING_RESEARCH: existingResearchContext,
|
|
61
|
+
PRD_CONTENT:
|
|
62
|
+
builtContext.prdContent || "No PRD content available",
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
if (!promptResult.success) {
|
|
67
|
+
throw new Error(
|
|
68
|
+
`Failed to build task enhancement prompt: ${promptResult.error}`
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const prompt = promptResult.prompt!;
|
|
73
|
+
|
|
74
|
+
const allTools = {
|
|
75
|
+
...(mcpTools as ToolSet),
|
|
76
|
+
...(enableFilesystemTools ? filesystemTools : {}),
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const result = await streamText({
|
|
80
|
+
model,
|
|
81
|
+
tools: allTools,
|
|
82
|
+
system:
|
|
83
|
+
TASK_ENHANCEMENT_SYSTEM_PROMPT +
|
|
84
|
+
`
|
|
85
|
+
|
|
86
|
+
You have access to Context7 documentation tools${
|
|
87
|
+
enableFilesystemTools ? " and filesystem tools" : ""
|
|
88
|
+
}.
|
|
89
|
+
|
|
90
|
+
## Available Tools:
|
|
91
|
+
- Context7 MCP tools (context7_resolve_library_id, context7_get_library_docs) for library documentation
|
|
92
|
+
${
|
|
93
|
+
enableFilesystemTools
|
|
94
|
+
? `- readFile: Read the contents of any file in the project
|
|
95
|
+
- listDirectory: List contents of directories`
|
|
96
|
+
: ""
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
## Research Strategy:
|
|
100
|
+
1. Use Context7 MCP tools for library documentation research
|
|
101
|
+
${
|
|
102
|
+
enableFilesystemTools
|
|
103
|
+
? `2. Use filesystem tools to understand project structure, existing code, and dependencies`
|
|
104
|
+
: ""
|
|
105
|
+
}
|
|
106
|
+
${
|
|
107
|
+
enableFilesystemTools ? "3" : "2"
|
|
108
|
+
}. Synthesize information from all sources to enhance the task
|
|
109
|
+
|
|
110
|
+
Technology stack context: ${stackInfo || "Not specified"}
|
|
111
|
+
|
|
112
|
+
## Available Cached Research:
|
|
113
|
+
${existingResearchContext}`,
|
|
114
|
+
messages: [
|
|
115
|
+
{
|
|
116
|
+
role: "user",
|
|
117
|
+
content: prompt,
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
maxRetries: 0,
|
|
121
|
+
stopWhen: stepCountIs(8),
|
|
122
|
+
onError: ({ error }) => {
|
|
123
|
+
streamingOptions?.onError?.(error);
|
|
124
|
+
throw error;
|
|
125
|
+
},
|
|
126
|
+
onChunk: streamingOptions?.onChunk
|
|
127
|
+
? ({ chunk }) => {
|
|
128
|
+
if (chunk.type === "text-delta") {
|
|
129
|
+
streamingOptions.onChunk!(chunk.text);
|
|
130
|
+
} else if (chunk.type === "reasoning-delta") {
|
|
131
|
+
streamingOptions.onReasoning?.(chunk.text);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
: undefined,
|
|
135
|
+
onFinish: streamingOptions?.onFinish
|
|
136
|
+
? ({ text, finishReason, usage }) => {
|
|
137
|
+
streamingOptions.onFinish!({
|
|
138
|
+
text,
|
|
139
|
+
finishReason,
|
|
140
|
+
usage,
|
|
141
|
+
isAborted: false,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
: undefined,
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
const toolCalls = await result.toolCalls;
|
|
148
|
+
const toolResults = await result.toolResults;
|
|
149
|
+
|
|
150
|
+
if (toolCalls.length > 0) {
|
|
151
|
+
logger.info(
|
|
152
|
+
`AI made tool calls: ${JSON.stringify(toolCalls.map((tc) => ({ tool: tc?.toolName, input: tc?.input })))}`
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (toolResults.length > 0) {
|
|
157
|
+
logger.info(
|
|
158
|
+
`Tool results received: ${JSON.stringify(toolResults.map((tr) => ({
|
|
159
|
+
tool: tr?.toolName,
|
|
160
|
+
output: tr?.output,
|
|
161
|
+
})))}`
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
let fullText = "";
|
|
166
|
+
for await (const textPart of result.textStream) {
|
|
167
|
+
fullText += textPart;
|
|
168
|
+
if (streamingOptions?.onChunk) {
|
|
169
|
+
streamingOptions.onChunk(textPart);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return fullText;
|
|
174
|
+
},
|
|
175
|
+
retryConfig,
|
|
176
|
+
"Task enhancement with documentation"
|
|
177
|
+
)
|
|
178
|
+
.finally(async () => {
|
|
179
|
+
await this.context7Client.closeMCPConnection();
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
async analyzeDocumentationNeeds(
|
|
184
|
+
taskId: string,
|
|
185
|
+
taskTitle: string,
|
|
186
|
+
taskDescription: string,
|
|
187
|
+
stackInfo?: string,
|
|
188
|
+
streamingOptions?: StreamingOptions,
|
|
189
|
+
retryConfig?: Partial<RetryConfig>,
|
|
190
|
+
config?: Partial<AIConfig>,
|
|
191
|
+
existingResearch?: (TaskDocumentation | undefined)[],
|
|
192
|
+
enableFilesystemTools?: boolean
|
|
193
|
+
): Promise<DocumentationDetection> {
|
|
194
|
+
// @ts-expect-error tool result type discrepency i cant be bothered with (that will probably bite me later...)
|
|
195
|
+
return this.retryHandler
|
|
196
|
+
.executeWithRetry(
|
|
197
|
+
async () => {
|
|
198
|
+
const mcpTools = await this.context7Client.getMCPTools();
|
|
199
|
+
const defaultAIConfig = this.modelProvider.getAIConfig();
|
|
200
|
+
const aiConfig = config
|
|
201
|
+
? { ...defaultAIConfig, ...config }
|
|
202
|
+
: defaultAIConfig;
|
|
203
|
+
const model = this.modelProvider.getModel(aiConfig);
|
|
204
|
+
|
|
205
|
+
const existingResearchContext = existingResearch
|
|
206
|
+
? "## Existing research\n" +
|
|
207
|
+
existingResearch
|
|
208
|
+
.map(
|
|
209
|
+
(rs) =>
|
|
210
|
+
rs &&
|
|
211
|
+
`${rs.recap}\n#### librairies\n${rs.libraries.join(
|
|
212
|
+
`- \n`
|
|
213
|
+
)}\n\n#### files:\n${rs.libraries.join(`- \n`)}`
|
|
214
|
+
)
|
|
215
|
+
.join("\n\n")
|
|
216
|
+
: "No existing research available.";
|
|
217
|
+
|
|
218
|
+
const promptResult = PromptBuilder.buildPrompt({
|
|
219
|
+
name: "documentation-detection",
|
|
220
|
+
type: "user",
|
|
221
|
+
variables: {
|
|
222
|
+
TASK_TITLE: taskTitle,
|
|
223
|
+
TASK_DESCRIPTION: taskDescription,
|
|
224
|
+
STACK_INFO: stackInfo || "Not specified",
|
|
225
|
+
EXISTING_RESEARCH: existingResearchContext,
|
|
226
|
+
},
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
if (!promptResult.success) {
|
|
230
|
+
throw new Error(
|
|
231
|
+
`Failed to build documentation detection prompt: ${promptResult.error}`
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const prompt = promptResult.prompt!;
|
|
236
|
+
|
|
237
|
+
const libraries: Array<{
|
|
238
|
+
name: string;
|
|
239
|
+
context7Id: string;
|
|
240
|
+
reason: string;
|
|
241
|
+
searchQuery: string;
|
|
242
|
+
}> = [];
|
|
243
|
+
const files: string[] = [];
|
|
244
|
+
|
|
245
|
+
const allTools = {
|
|
246
|
+
...(mcpTools as ToolSet),
|
|
247
|
+
...(enableFilesystemTools ? filesystemTools : {}),
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
const result = await streamText({
|
|
251
|
+
model,
|
|
252
|
+
tools: allTools,
|
|
253
|
+
system: `You are an expert developer.\nYou have access to Context7 MCP tools for documentation research.\nFetch documentation relevant to the task in the project context and create a document giving that knowledge to the AI assistant that will implement the task.`,
|
|
254
|
+
messages: [{ role: "user", content: prompt }],
|
|
255
|
+
maxRetries: 0,
|
|
256
|
+
stopWhen: stepCountIs(8),
|
|
257
|
+
onError: ({ error }) => {
|
|
258
|
+
streamingOptions?.onError?.(error);
|
|
259
|
+
throw error;
|
|
260
|
+
},
|
|
261
|
+
onChunk: streamingOptions?.onChunk
|
|
262
|
+
? ({ chunk }) => {
|
|
263
|
+
if (chunk.type === "text-delta") {
|
|
264
|
+
streamingOptions.onChunk!(chunk.text);
|
|
265
|
+
} else if (chunk.type === "reasoning-delta") {
|
|
266
|
+
streamingOptions.onReasoning?.(chunk.text);
|
|
267
|
+
} else if (chunk.type === "tool-result") {
|
|
268
|
+
if (chunk.toolName === "get-library-docs" && chunk.output) {
|
|
269
|
+
(async () => {
|
|
270
|
+
try {
|
|
271
|
+
const input = chunk.input as {
|
|
272
|
+
context7CompatibleLibraryID: string;
|
|
273
|
+
tokens?: number;
|
|
274
|
+
topic?: string;
|
|
275
|
+
};
|
|
276
|
+
const libraryId = input.context7CompatibleLibraryID;
|
|
277
|
+
const libraryName =
|
|
278
|
+
libraryId.split("/").pop() || "unknown";
|
|
279
|
+
const timestamp = Date.now();
|
|
280
|
+
const filename =
|
|
281
|
+
input.topic ?? `${libraryName}-${timestamp}`;
|
|
282
|
+
|
|
283
|
+
let content = "";
|
|
284
|
+
if (
|
|
285
|
+
chunk.output &&
|
|
286
|
+
typeof chunk.output === "object"
|
|
287
|
+
) {
|
|
288
|
+
if ("content" in chunk.output) {
|
|
289
|
+
const contentArray = chunk.output
|
|
290
|
+
.content as Array<{
|
|
291
|
+
type: string;
|
|
292
|
+
text: string;
|
|
293
|
+
}>;
|
|
294
|
+
if (Array.isArray(contentArray)) {
|
|
295
|
+
content = contentArray
|
|
296
|
+
.map((item) => item.text || "")
|
|
297
|
+
.join("\n");
|
|
298
|
+
} else {
|
|
299
|
+
content = String(contentArray);
|
|
300
|
+
}
|
|
301
|
+
} else if ("text" in chunk.output) {
|
|
302
|
+
content = chunk.output.text as string;
|
|
303
|
+
}
|
|
304
|
+
} else if (typeof chunk.output === "string") {
|
|
305
|
+
content = chunk.output;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if (content) {
|
|
309
|
+
const docFile =
|
|
310
|
+
await this.context7Client.saveContext7Documentation(
|
|
311
|
+
libraryName,
|
|
312
|
+
filename,
|
|
313
|
+
content
|
|
314
|
+
);
|
|
315
|
+
|
|
316
|
+
libraries.push({
|
|
317
|
+
name: libraryName,
|
|
318
|
+
context7Id: libraryId,
|
|
319
|
+
reason:
|
|
320
|
+
"Documentation fetched for task implementation",
|
|
321
|
+
searchQuery: filename,
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
files.push(docFile);
|
|
325
|
+
}
|
|
326
|
+
} catch (error) {
|
|
327
|
+
logger.error(
|
|
328
|
+
`Failed to save Context7 documentation: ${error}`
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
})();
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
: undefined,
|
|
336
|
+
onFinish: streamingOptions?.onFinish
|
|
337
|
+
? ({ text, finishReason, usage }) => {
|
|
338
|
+
streamingOptions.onFinish!({
|
|
339
|
+
text,
|
|
340
|
+
finishReason,
|
|
341
|
+
usage,
|
|
342
|
+
isAborted: false,
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
: undefined,
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
let fullText = "";
|
|
349
|
+
for await (const textPart of result.textStream) {
|
|
350
|
+
fullText += textPart;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
const toolResults = await result.toolResults;
|
|
354
|
+
const toolCalls = await result.toolCalls;
|
|
355
|
+
|
|
356
|
+
if (fullText.trim()) {
|
|
357
|
+
try {
|
|
358
|
+
const storage = getStorage();
|
|
359
|
+
const taskDocFile = await storage.saveTaskDocumentation(
|
|
360
|
+
taskId,
|
|
361
|
+
fullText
|
|
362
|
+
);
|
|
363
|
+
files.push(taskDocFile);
|
|
364
|
+
} catch (error) {
|
|
365
|
+
logger.error(`Failed to save task documentation: ${error}`);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
return {
|
|
370
|
+
libraries,
|
|
371
|
+
confidence: libraries.length > 0 ? 0.8 : 0.3,
|
|
372
|
+
toolResults: toolResults.map((tr) => ({
|
|
373
|
+
toolName: tr?.toolName,
|
|
374
|
+
output: tr?.output,
|
|
375
|
+
})),
|
|
376
|
+
files,
|
|
377
|
+
};
|
|
378
|
+
},
|
|
379
|
+
retryConfig,
|
|
380
|
+
"Documentation needs analysis"
|
|
381
|
+
)
|
|
382
|
+
.finally(async () => {
|
|
383
|
+
await this.context7Client.closeMCPConnection();
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
async generateDocumentationRecap(
|
|
388
|
+
libraries: Array<{ name: string; context7Id: string; reason: string }>,
|
|
389
|
+
documentContents: Array<{ library: string; content: string }>,
|
|
390
|
+
streamingOptions?: StreamingOptions,
|
|
391
|
+
retryConfig?: Partial<RetryConfig>
|
|
392
|
+
): Promise<string> {
|
|
393
|
+
// Build variables for PromptBuilder
|
|
394
|
+
const librariesList = libraries
|
|
395
|
+
.map((lib) => `- ${lib.name} (${lib.context7Id}): ${lib.reason}`)
|
|
396
|
+
.join("\n");
|
|
397
|
+
|
|
398
|
+
const documentationContents = documentContents
|
|
399
|
+
.map((doc) => `## ${doc.library}\n${doc.content.substring(0, 500)}...`)
|
|
400
|
+
.join("\n\n");
|
|
401
|
+
|
|
402
|
+
const promptResult = PromptBuilder.buildPrompt({
|
|
403
|
+
name: "documentation-recap",
|
|
404
|
+
type: "user",
|
|
405
|
+
variables: {
|
|
406
|
+
LIBRARIES_LIST: librariesList,
|
|
407
|
+
DOCUMENTATION_CONTENTS: documentationContents,
|
|
408
|
+
},
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
if (!promptResult.success) {
|
|
412
|
+
throw new Error(
|
|
413
|
+
`Failed to build documentation recap prompt: ${promptResult.error}`
|
|
414
|
+
);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
const systemPromptResult = PromptBuilder.buildPrompt({
|
|
418
|
+
name: "documentation-recap",
|
|
419
|
+
type: "system",
|
|
420
|
+
variables: {},
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
return this.retryHandler.executeWithRetry(
|
|
424
|
+
async () => {
|
|
425
|
+
return this.streamText(
|
|
426
|
+
promptResult.prompt!,
|
|
427
|
+
undefined,
|
|
428
|
+
systemPromptResult.prompt!,
|
|
429
|
+
undefined,
|
|
430
|
+
streamingOptions,
|
|
431
|
+
{ maxAttempts: 1 }
|
|
432
|
+
);
|
|
433
|
+
},
|
|
434
|
+
retryConfig,
|
|
435
|
+
"Documentation recap generation"
|
|
436
|
+
);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { tool } from "ai";
|
|
2
|
+
import { z } from "zod/v3";
|
|
3
|
+
import { readFile, readdir, stat } from "fs/promises";
|
|
4
|
+
import { resolve, relative, join } from "path";
|
|
5
|
+
|
|
6
|
+
export const readFileTool = tool({
|
|
7
|
+
description: "Read the contents of a file",
|
|
8
|
+
inputSchema: z.object({
|
|
9
|
+
filePath: z.string().describe("Path to the file to read"),
|
|
10
|
+
}),
|
|
11
|
+
execute: async ({ filePath }) => {
|
|
12
|
+
try {
|
|
13
|
+
const resolvedPath = resolve(filePath);
|
|
14
|
+
const content = await readFile(resolvedPath, "utf-8");
|
|
15
|
+
const stats = await stat(resolvedPath);
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
success: true,
|
|
19
|
+
content,
|
|
20
|
+
path: relative(process.cwd(), resolvedPath),
|
|
21
|
+
size: stats.size,
|
|
22
|
+
};
|
|
23
|
+
} catch (error) {
|
|
24
|
+
return {
|
|
25
|
+
success: false,
|
|
26
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
export const listDirectoryTool = tool({
|
|
33
|
+
description: "List contents of a directory",
|
|
34
|
+
inputSchema: z.object({
|
|
35
|
+
dirPath: z.string().describe("Directory path to list"),
|
|
36
|
+
}),
|
|
37
|
+
execute: async ({ dirPath }) => {
|
|
38
|
+
try {
|
|
39
|
+
const resolvedPath = resolve(dirPath);
|
|
40
|
+
const entries = await readdir(resolvedPath, { withFileTypes: true });
|
|
41
|
+
|
|
42
|
+
const contents = await Promise.all(
|
|
43
|
+
entries.map(async (entry) => {
|
|
44
|
+
const fullPath = join(resolvedPath, entry.name);
|
|
45
|
+
const stats = await stat(fullPath);
|
|
46
|
+
return {
|
|
47
|
+
name: entry.name,
|
|
48
|
+
type: entry.isDirectory() ? "directory" : "file",
|
|
49
|
+
path: relative(process.cwd(), fullPath),
|
|
50
|
+
size: entry.isFile() ? stats.size : undefined,
|
|
51
|
+
};
|
|
52
|
+
})
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
success: true,
|
|
57
|
+
contents,
|
|
58
|
+
directory: relative(process.cwd(), resolvedPath),
|
|
59
|
+
};
|
|
60
|
+
} catch (error) {
|
|
61
|
+
return {
|
|
62
|
+
success: false,
|
|
63
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
64
|
+
contents: [],
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
export const filesystemTools = {
|
|
71
|
+
readFile: readFileTool,
|
|
72
|
+
listDirectory: listDirectoryTool,
|
|
73
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { LanguageModelV2 } from "@ai-sdk/provider";
|
|
2
|
+
|
|
3
|
+
let _createGeminiProvider: any = null;
|
|
4
|
+
|
|
5
|
+
function getCreateGeminiProvider() {
|
|
6
|
+
if (_createGeminiProvider) return _createGeminiProvider;
|
|
7
|
+
|
|
8
|
+
if (typeof window !== "undefined") {
|
|
9
|
+
throw new Error(
|
|
10
|
+
"GeminiProviderProxy is only available in Node.js CLI environments."
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
15
|
+
_createGeminiProvider =
|
|
16
|
+
require("ai-sdk-provider-gemini-cli").createGeminiProvider;
|
|
17
|
+
return _createGeminiProvider;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export class GeminiProviderProxy implements LanguageModelV2 {
|
|
21
|
+
readonly specificationVersion = "v2";
|
|
22
|
+
readonly provider = "gemini";
|
|
23
|
+
readonly modelId: string;
|
|
24
|
+
readonly defaultObjectGenerationMode = "json";
|
|
25
|
+
readonly supportedUrls: Record<string, RegExp[]> = {};
|
|
26
|
+
private readonly config: any;
|
|
27
|
+
private realModel: LanguageModelV2 | null = null;
|
|
28
|
+
|
|
29
|
+
constructor(modelId: string, config: any) {
|
|
30
|
+
this.modelId = modelId;
|
|
31
|
+
this.config = config;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
private getRealModel(): LanguageModelV2 {
|
|
35
|
+
if (!this.realModel) {
|
|
36
|
+
const createGeminiProvider = getCreateGeminiProvider();
|
|
37
|
+
const provider = createGeminiProvider(this.config);
|
|
38
|
+
this.realModel = provider(this.modelId);
|
|
39
|
+
}
|
|
40
|
+
return this.realModel!;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async doGenerate(options: any): Promise<any> {
|
|
44
|
+
const model = this.getRealModel();
|
|
45
|
+
return model.doGenerate(options);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async doStream(options: any): Promise<any> {
|
|
49
|
+
const model = this.getRealModel();
|
|
50
|
+
return model.doStream(options);
|
|
51
|
+
}
|
|
52
|
+
}
|