@ai-coders/context 0.3.1 → 0.5.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 +269 -29
- package/dist/fragments/compose.d.ts +30 -0
- package/dist/fragments/compose.d.ts.map +1 -0
- package/dist/fragments/compose.js +274 -0
- package/dist/fragments/compose.js.map +1 -0
- package/dist/fragments/extractors/index.d.ts +26 -0
- package/dist/fragments/extractors/index.d.ts.map +1 -0
- package/dist/fragments/extractors/index.js +58 -0
- package/dist/fragments/extractors/index.js.map +1 -0
- package/dist/fragments/extractors/module.d.ts +12 -0
- package/dist/fragments/extractors/module.d.ts.map +1 -0
- package/dist/fragments/extractors/module.js +302 -0
- package/dist/fragments/extractors/module.js.map +1 -0
- package/dist/fragments/extractors/project.d.ts +12 -0
- package/dist/fragments/extractors/project.d.ts.map +1 -0
- package/dist/fragments/extractors/project.js +274 -0
- package/dist/fragments/extractors/project.js.map +1 -0
- package/dist/fragments/extractors/semantic.d.ts +12 -0
- package/dist/fragments/extractors/semantic.d.ts.map +1 -0
- package/dist/fragments/extractors/semantic.js +329 -0
- package/dist/fragments/extractors/semantic.js.map +1 -0
- package/dist/fragments/index.d.ts +47 -0
- package/dist/fragments/index.d.ts.map +1 -0
- package/dist/fragments/index.js +75 -0
- package/dist/fragments/index.js.map +1 -0
- package/dist/fragments/query.d.ts +101 -0
- package/dist/fragments/query.d.ts.map +1 -0
- package/dist/fragments/query.js +200 -0
- package/dist/fragments/query.js.map +1 -0
- package/dist/fragments/render/compact.d.ts +15 -0
- package/dist/fragments/render/compact.d.ts.map +1 -0
- package/dist/fragments/render/compact.js +209 -0
- package/dist/fragments/render/compact.js.map +1 -0
- package/dist/fragments/render/index.d.ts +17 -0
- package/dist/fragments/render/index.d.ts.map +1 -0
- package/dist/fragments/render/index.js +40 -0
- package/dist/fragments/render/index.js.map +1 -0
- package/dist/fragments/render/json.d.ts +9 -0
- package/dist/fragments/render/json.d.ts.map +1 -0
- package/dist/fragments/render/json.js +44 -0
- package/dist/fragments/render/json.js.map +1 -0
- package/dist/fragments/render/markdown.d.ts +9 -0
- package/dist/fragments/render/markdown.d.ts.map +1 -0
- package/dist/fragments/render/markdown.js +291 -0
- package/dist/fragments/render/markdown.js.map +1 -0
- package/dist/fragments/store.d.ts +49 -0
- package/dist/fragments/store.d.ts.map +1 -0
- package/dist/fragments/store.js +161 -0
- package/dist/fragments/store.js.map +1 -0
- package/dist/fragments/types.d.ts +241 -0
- package/dist/fragments/types.d.ts.map +1 -0
- package/dist/fragments/types.js +8 -0
- package/dist/fragments/types.js.map +1 -0
- package/dist/generators/agents/agentConfig.d.ts.map +1 -1
- package/dist/generators/agents/agentConfig.js +42 -0
- package/dist/generators/agents/agentConfig.js.map +1 -1
- package/dist/generators/agents/agentGenerator.d.ts +8 -2
- package/dist/generators/agents/agentGenerator.d.ts.map +1 -1
- package/dist/generators/agents/agentGenerator.js +112 -54
- package/dist/generators/agents/agentGenerator.js.map +1 -1
- package/dist/generators/agents/agentTypes.d.ts +1 -1
- package/dist/generators/agents/agentTypes.d.ts.map +1 -1
- package/dist/generators/agents/agentTypes.js +4 -1
- package/dist/generators/agents/agentTypes.js.map +1 -1
- package/dist/generators/agents/templates/indexTemplate.d.ts.map +1 -1
- package/dist/generators/agents/templates/indexTemplate.js +2 -1
- package/dist/generators/agents/templates/indexTemplate.js.map +1 -1
- package/dist/generators/agents/templates/playbookTemplate.d.ts +3 -2
- package/dist/generators/agents/templates/playbookTemplate.d.ts.map +1 -1
- package/dist/generators/agents/templates/playbookTemplate.js +144 -10
- package/dist/generators/agents/templates/playbookTemplate.js.map +1 -1
- package/dist/generators/agents/templates/types.d.ts +9 -1
- package/dist/generators/agents/templates/types.d.ts.map +1 -1
- package/dist/generators/documentation/documentationGenerator.d.ts +5 -1
- package/dist/generators/documentation/documentationGenerator.d.ts.map +1 -1
- package/dist/generators/documentation/documentationGenerator.js +106 -18
- package/dist/generators/documentation/documentationGenerator.js.map +1 -1
- package/dist/generators/documentation/guideRegistry.d.ts.map +1 -1
- package/dist/generators/documentation/guideRegistry.js +0 -8
- package/dist/generators/documentation/guideRegistry.js.map +1 -1
- package/dist/generators/documentation/templates/apiReferenceTemplate.d.ts +2 -0
- package/dist/generators/documentation/templates/apiReferenceTemplate.d.ts.map +1 -0
- package/dist/generators/documentation/templates/apiReferenceTemplate.js +469 -0
- package/dist/generators/documentation/templates/apiReferenceTemplate.js.map +1 -0
- package/dist/generators/documentation/templates/architectureTemplate.d.ts.map +1 -1
- package/dist/generators/documentation/templates/architectureTemplate.js +175 -41
- package/dist/generators/documentation/templates/architectureTemplate.js.map +1 -1
- package/dist/generators/documentation/templates/common.d.ts +28 -1
- package/dist/generators/documentation/templates/common.d.ts.map +1 -1
- package/dist/generators/documentation/templates/common.js +130 -10
- package/dist/generators/documentation/templates/common.js.map +1 -1
- package/dist/generators/documentation/templates/dataFlowTemplate.d.ts.map +1 -1
- package/dist/generators/documentation/templates/dataFlowTemplate.js +98 -33
- package/dist/generators/documentation/templates/dataFlowTemplate.js.map +1 -1
- package/dist/generators/documentation/templates/developmentWorkflowTemplate.d.ts.map +1 -1
- package/dist/generators/documentation/templates/developmentWorkflowTemplate.js +2 -34
- package/dist/generators/documentation/templates/developmentWorkflowTemplate.js.map +1 -1
- package/dist/generators/documentation/templates/glossaryTemplate.d.ts +1 -1
- package/dist/generators/documentation/templates/glossaryTemplate.d.ts.map +1 -1
- package/dist/generators/documentation/templates/glossaryTemplate.js +51 -37
- package/dist/generators/documentation/templates/glossaryTemplate.js.map +1 -1
- package/dist/generators/documentation/templates/index.d.ts +4 -0
- package/dist/generators/documentation/templates/index.d.ts.map +1 -1
- package/dist/generators/documentation/templates/index.js +9 -1
- package/dist/generators/documentation/templates/index.js.map +1 -1
- package/dist/generators/documentation/templates/indexTemplate.d.ts.map +1 -1
- package/dist/generators/documentation/templates/indexTemplate.js +1 -32
- package/dist/generators/documentation/templates/indexTemplate.js.map +1 -1
- package/dist/generators/documentation/templates/migrationTemplate.d.ts +2 -0
- package/dist/generators/documentation/templates/migrationTemplate.d.ts.map +1 -0
- package/dist/generators/documentation/templates/migrationTemplate.js +400 -0
- package/dist/generators/documentation/templates/migrationTemplate.js.map +1 -0
- package/dist/generators/documentation/templates/onboardingTemplate.d.ts +2 -0
- package/dist/generators/documentation/templates/onboardingTemplate.d.ts.map +1 -0
- package/dist/generators/documentation/templates/onboardingTemplate.js +409 -0
- package/dist/generators/documentation/templates/onboardingTemplate.js.map +1 -0
- package/dist/generators/documentation/templates/projectOverviewTemplate.d.ts.map +1 -1
- package/dist/generators/documentation/templates/projectOverviewTemplate.js +97 -38
- package/dist/generators/documentation/templates/projectOverviewTemplate.js.map +1 -1
- package/dist/generators/documentation/templates/securityTemplate.d.ts.map +1 -1
- package/dist/generators/documentation/templates/securityTemplate.js +1 -32
- package/dist/generators/documentation/templates/securityTemplate.js.map +1 -1
- package/dist/generators/documentation/templates/testingTemplate.d.ts.map +1 -1
- package/dist/generators/documentation/templates/testingTemplate.js +1 -33
- package/dist/generators/documentation/templates/testingTemplate.js.map +1 -1
- package/dist/generators/documentation/templates/toolingTemplate.d.ts.map +1 -1
- package/dist/generators/documentation/templates/toolingTemplate.js +2 -33
- package/dist/generators/documentation/templates/toolingTemplate.js.map +1 -1
- package/dist/generators/documentation/templates/troubleshootingTemplate.d.ts +2 -0
- package/dist/generators/documentation/templates/troubleshootingTemplate.d.ts.map +1 -0
- package/dist/generators/documentation/templates/troubleshootingTemplate.js +270 -0
- package/dist/generators/documentation/templates/troubleshootingTemplate.js.map +1 -0
- package/dist/generators/documentation/templates/types.d.ts +2 -1
- package/dist/generators/documentation/templates/types.d.ts.map +1 -1
- package/dist/generators/plans/planGenerator.d.ts +4 -0
- package/dist/generators/plans/planGenerator.d.ts.map +1 -1
- package/dist/generators/plans/planGenerator.js +30 -2
- package/dist/generators/plans/planGenerator.js.map +1 -1
- package/dist/generators/plans/templates/indexTemplate.d.ts.map +1 -1
- package/dist/generators/plans/templates/indexTemplate.js +5 -13
- package/dist/generators/plans/templates/indexTemplate.js.map +1 -1
- package/dist/generators/plans/templates/planTemplate.d.ts.map +1 -1
- package/dist/generators/plans/templates/planTemplate.js +123 -30
- package/dist/generators/plans/templates/planTemplate.js.map +1 -1
- package/dist/generators/plans/templates/types.d.ts +10 -0
- package/dist/generators/plans/templates/types.d.ts.map +1 -1
- package/dist/generators/shared/generatorUtils.d.ts +1 -1
- package/dist/generators/shared/generatorUtils.d.ts.map +1 -1
- package/dist/generators/shared/generatorUtils.js +7 -10
- package/dist/generators/shared/generatorUtils.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +459 -1073
- package/dist/index.js.map +1 -1
- package/dist/prompts/defaults.d.ts +2 -2
- package/dist/prompts/defaults.d.ts.map +1 -1
- package/dist/prompts/defaults.js +26 -56
- package/dist/prompts/defaults.js.map +1 -1
- package/dist/services/ai/agentEvents.d.ts +45 -0
- package/dist/services/ai/agentEvents.d.ts.map +1 -0
- package/dist/services/ai/agentEvents.js +61 -0
- package/dist/services/ai/agentEvents.js.map +1 -0
- package/dist/services/ai/agents/documentationAgent.d.ts +53 -0
- package/dist/services/ai/agents/documentationAgent.d.ts.map +1 -0
- package/dist/services/ai/agents/documentationAgent.js +243 -0
- package/dist/services/ai/agents/documentationAgent.js.map +1 -0
- package/dist/services/ai/agents/index.d.ts +7 -0
- package/dist/services/ai/agents/index.d.ts.map +1 -0
- package/dist/services/ai/agents/index.js +10 -0
- package/dist/services/ai/agents/index.js.map +1 -0
- package/dist/services/ai/agents/planAgent.d.ts +68 -0
- package/dist/services/ai/agents/planAgent.d.ts.map +1 -0
- package/dist/services/ai/agents/planAgent.js +389 -0
- package/dist/services/ai/agents/planAgent.js.map +1 -0
- package/dist/services/ai/agents/playbookAgent.d.ts +54 -0
- package/dist/services/ai/agents/playbookAgent.d.ts.map +1 -0
- package/dist/services/ai/agents/playbookAgent.js +265 -0
- package/dist/services/ai/agents/playbookAgent.js.map +1 -0
- package/dist/services/ai/aiSdkClient.d.ts +67 -0
- package/dist/services/ai/aiSdkClient.d.ts.map +1 -0
- package/dist/services/ai/aiSdkClient.js +143 -0
- package/dist/services/ai/aiSdkClient.js.map +1 -0
- package/dist/services/ai/index.d.ts +7 -0
- package/dist/services/ai/index.d.ts.map +1 -0
- package/dist/services/ai/index.js +49 -0
- package/dist/services/ai/index.js.map +1 -0
- package/dist/services/ai/providerFactory.d.ts +35 -0
- package/dist/services/ai/providerFactory.d.ts.map +1 -0
- package/dist/services/ai/providerFactory.js +107 -0
- package/dist/services/ai/providerFactory.js.map +1 -0
- package/dist/services/ai/schemas.d.ts +331 -0
- package/dist/services/ai/schemas.d.ts.map +1 -0
- package/dist/services/ai/schemas.js +236 -0
- package/dist/services/ai/schemas.js.map +1 -0
- package/dist/services/ai/tools/analyzeSymbolsTool.d.ts +33 -0
- package/dist/services/ai/tools/analyzeSymbolsTool.d.ts.map +1 -0
- package/dist/services/ai/tools/analyzeSymbolsTool.js +57 -0
- package/dist/services/ai/tools/analyzeSymbolsTool.js.map +1 -0
- package/dist/services/ai/tools/checkScaffoldingTool.d.ts +18 -0
- package/dist/services/ai/tools/checkScaffoldingTool.d.ts.map +1 -0
- package/dist/services/ai/tools/checkScaffoldingTool.js +86 -0
- package/dist/services/ai/tools/checkScaffoldingTool.js.map +1 -0
- package/dist/services/ai/tools/fillScaffoldingTool.d.ts +38 -0
- package/dist/services/ai/tools/fillScaffoldingTool.d.ts.map +1 -0
- package/dist/services/ai/tools/fillScaffoldingTool.js +259 -0
- package/dist/services/ai/tools/fillScaffoldingTool.js.map +1 -0
- package/dist/services/ai/tools/getFileStructureTool.d.ts +29 -0
- package/dist/services/ai/tools/getFileStructureTool.d.ts.map +1 -0
- package/dist/services/ai/tools/getFileStructureTool.js +48 -0
- package/dist/services/ai/tools/getFileStructureTool.js.map +1 -0
- package/dist/services/ai/tools/index.d.ts +20 -0
- package/dist/services/ai/tools/index.d.ts.map +1 -0
- package/dist/services/ai/tools/index.js +62 -0
- package/dist/services/ai/tools/index.js.map +1 -0
- package/dist/services/ai/tools/initializeContextTool.d.ts +25 -0
- package/dist/services/ai/tools/initializeContextTool.d.ts.map +1 -0
- package/dist/services/ai/tools/initializeContextTool.js +121 -0
- package/dist/services/ai/tools/initializeContextTool.js.map +1 -0
- package/dist/services/ai/tools/listFilesTool.d.ts +18 -0
- package/dist/services/ai/tools/listFilesTool.d.ts.map +1 -0
- package/dist/services/ai/tools/listFilesTool.js +34 -0
- package/dist/services/ai/tools/listFilesTool.js.map +1 -0
- package/dist/services/ai/tools/readFileTool.d.ts +17 -0
- package/dist/services/ai/tools/readFileTool.d.ts.map +1 -0
- package/dist/services/ai/tools/readFileTool.js +63 -0
- package/dist/services/ai/tools/readFileTool.js.map +1 -0
- package/dist/services/ai/tools/scaffoldPlanTool.d.ts +19 -0
- package/dist/services/ai/tools/scaffoldPlanTool.d.ts.map +1 -0
- package/dist/services/ai/tools/scaffoldPlanTool.js +81 -0
- package/dist/services/ai/tools/scaffoldPlanTool.js.map +1 -0
- package/dist/services/ai/tools/searchCodeTool.d.ts +25 -0
- package/dist/services/ai/tools/searchCodeTool.d.ts.map +1 -0
- package/dist/services/ai/tools/searchCodeTool.js +96 -0
- package/dist/services/ai/tools/searchCodeTool.js.map +1 -0
- package/dist/services/baseLLMClient.d.ts +3 -3
- package/dist/services/baseLLMClient.d.ts.map +1 -1
- package/dist/services/baseLLMClient.js +44 -5
- package/dist/services/baseLLMClient.js.map +1 -1
- package/dist/services/fill/fillService.d.ts +11 -5
- package/dist/services/fill/fillService.d.ts.map +1 -1
- package/dist/services/fill/fillService.js +152 -88
- package/dist/services/fill/fillService.js.map +1 -1
- package/dist/services/init/initService.d.ts +3 -2
- package/dist/services/init/initService.d.ts.map +1 -1
- package/dist/services/init/initService.js +54 -19
- package/dist/services/init/initService.js.map +1 -1
- package/dist/services/llmClientFactory.d.ts +37 -9
- package/dist/services/llmClientFactory.d.ts.map +1 -1
- package/dist/services/llmClientFactory.js +54 -94
- package/dist/services/llmClientFactory.js.map +1 -1
- package/dist/services/mcp/index.d.ts +2 -0
- package/dist/services/mcp/index.d.ts.map +1 -0
- package/dist/services/mcp/index.js +7 -0
- package/dist/services/mcp/index.js.map +1 -0
- package/dist/services/mcp/mcpServer.d.ts +45 -0
- package/dist/services/mcp/mcpServer.d.ts.map +1 -0
- package/dist/services/mcp/mcpServer.js +371 -0
- package/dist/services/mcp/mcpServer.js.map +1 -0
- package/dist/services/openRouterClient.d.ts +0 -3
- package/dist/services/openRouterClient.d.ts.map +1 -1
- package/dist/services/openRouterClient.js +2 -49
- package/dist/services/openRouterClient.js.map +1 -1
- package/dist/services/passthrough/commandRouter.d.ts +53 -0
- package/dist/services/passthrough/commandRouter.d.ts.map +1 -0
- package/dist/services/passthrough/commandRouter.js +349 -0
- package/dist/services/passthrough/commandRouter.js.map +1 -0
- package/dist/services/passthrough/index.d.ts +7 -0
- package/dist/services/passthrough/index.d.ts.map +1 -0
- package/dist/services/passthrough/index.js +23 -0
- package/dist/services/passthrough/index.js.map +1 -0
- package/dist/services/passthrough/protocol.d.ts +269 -0
- package/dist/services/passthrough/protocol.d.ts.map +1 -0
- package/dist/services/passthrough/protocol.js +151 -0
- package/dist/services/passthrough/protocol.js.map +1 -0
- package/dist/services/passthrough/stdinReader.d.ts +42 -0
- package/dist/services/passthrough/stdinReader.d.ts.map +1 -0
- package/dist/services/passthrough/stdinReader.js +111 -0
- package/dist/services/passthrough/stdinReader.js.map +1 -0
- package/dist/services/plan/planService.d.ts +5 -5
- package/dist/services/plan/planService.d.ts.map +1 -1
- package/dist/services/plan/planService.js +52 -53
- package/dist/services/plan/planService.js.map +1 -1
- package/dist/services/semantic/codebaseAnalyzer.d.ts +40 -0
- package/dist/services/semantic/codebaseAnalyzer.d.ts.map +1 -0
- package/dist/services/semantic/codebaseAnalyzer.js +540 -0
- package/dist/services/semantic/codebaseAnalyzer.js.map +1 -0
- package/dist/services/semantic/contextBuilder.d.ts +79 -0
- package/dist/services/semantic/contextBuilder.d.ts.map +1 -0
- package/dist/services/semantic/contextBuilder.js +538 -0
- package/dist/services/semantic/contextBuilder.js.map +1 -0
- package/dist/services/semantic/index.d.ts +12 -0
- package/dist/services/semantic/index.d.ts.map +1 -0
- package/dist/services/semantic/index.js +33 -0
- package/dist/services/semantic/index.js.map +1 -0
- package/dist/services/semantic/lsp/index.d.ts +2 -0
- package/dist/services/semantic/lsp/index.d.ts.map +1 -0
- package/dist/services/semantic/lsp/index.js +6 -0
- package/dist/services/semantic/lsp/index.js.map +1 -0
- package/dist/services/semantic/lsp/lspLayer.d.ts +32 -0
- package/dist/services/semantic/lsp/lspLayer.d.ts.map +1 -0
- package/dist/services/semantic/lsp/lspLayer.js +378 -0
- package/dist/services/semantic/lsp/lspLayer.js.map +1 -0
- package/dist/services/semantic/treeSitter/index.d.ts +2 -0
- package/dist/services/semantic/treeSitter/index.d.ts.map +1 -0
- package/dist/services/semantic/treeSitter/index.js +6 -0
- package/dist/services/semantic/treeSitter/index.js.map +1 -0
- package/dist/services/semantic/treeSitter/treeSitterLayer.d.ts +37 -0
- package/dist/services/semantic/treeSitter/treeSitterLayer.d.ts.map +1 -0
- package/dist/services/semantic/treeSitter/treeSitterLayer.js +518 -0
- package/dist/services/semantic/treeSitter/treeSitterLayer.js.map +1 -0
- package/dist/services/semantic/types.d.ts +122 -0
- package/dist/services/semantic/types.d.ts.map +1 -0
- package/dist/services/semantic/types.js +31 -0
- package/dist/services/semantic/types.js.map +1 -0
- package/dist/services/serve/index.d.ts +2 -0
- package/dist/services/serve/index.d.ts.map +1 -0
- package/dist/services/serve/index.js +6 -0
- package/dist/services/serve/index.js.map +1 -0
- package/dist/services/serve/serveService.d.ts +38 -0
- package/dist/services/serve/serveService.d.ts.map +1 -0
- package/dist/services/serve/serveService.js +99 -0
- package/dist/services/serve/serveService.js.map +1 -0
- package/dist/services/shared/llmConfig.d.ts +19 -3
- package/dist/services/shared/llmConfig.d.ts.map +1 -1
- package/dist/services/shared/llmConfig.js +44 -57
- package/dist/services/shared/llmConfig.js.map +1 -1
- package/dist/services/sync/index.d.ts +6 -0
- package/dist/services/sync/index.d.ts.map +1 -0
- package/dist/services/sync/index.js +16 -0
- package/dist/services/sync/index.js.map +1 -0
- package/dist/services/sync/markdownReferenceHandler.d.ts +3 -0
- package/dist/services/sync/markdownReferenceHandler.d.ts.map +1 -0
- package/dist/services/sync/markdownReferenceHandler.js +133 -0
- package/dist/services/sync/markdownReferenceHandler.js.map +1 -0
- package/dist/services/sync/presets.d.ts +6 -0
- package/dist/services/sync/presets.d.ts.map +1 -0
- package/dist/services/sync/presets.js +49 -0
- package/dist/services/sync/presets.js.map +1 -0
- package/dist/services/sync/symlinkHandler.d.ts +7 -0
- package/dist/services/sync/symlinkHandler.d.ts.map +1 -0
- package/dist/services/sync/symlinkHandler.js +129 -0
- package/dist/services/sync/symlinkHandler.js.map +1 -0
- package/dist/services/sync/syncService.d.ts +15 -0
- package/dist/services/sync/syncService.d.ts.map +1 -0
- package/dist/services/sync/syncService.js +222 -0
- package/dist/services/sync/syncService.js.map +1 -0
- package/dist/services/sync/types.d.ts +62 -0
- package/dist/services/sync/types.d.ts.map +1 -0
- package/dist/services/sync/types.js +3 -0
- package/dist/services/sync/types.js.map +1 -0
- package/dist/types.d.ts +8 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/cliUI.d.ts +33 -0
- package/dist/utils/cliUI.d.ts.map +1 -1
- package/dist/utils/cliUI.js +157 -107
- package/dist/utils/cliUI.js.map +1 -1
- package/dist/utils/contentSanitizer.d.ts +42 -0
- package/dist/utils/contentSanitizer.d.ts.map +1 -0
- package/dist/utils/contentSanitizer.js +238 -0
- package/dist/utils/contentSanitizer.js.map +1 -0
- package/dist/utils/fileMapper.d.ts +1 -1
- package/dist/utils/fileMapper.d.ts.map +1 -1
- package/dist/utils/fileMapper.js +40 -19
- package/dist/utils/fileMapper.js.map +1 -1
- package/dist/utils/gitService.d.ts.map +1 -1
- package/dist/utils/gitService.js +12 -14
- package/dist/utils/gitService.js.map +1 -1
- package/dist/utils/i18n.d.ts +96 -43
- package/dist/utils/i18n.d.ts.map +1 -1
- package/dist/utils/i18n.js +194 -88
- package/dist/utils/i18n.js.map +1 -1
- package/dist/utils/prompts/configSummary.d.ts +7 -0
- package/dist/utils/prompts/configSummary.d.ts.map +1 -0
- package/dist/utils/prompts/configSummary.js +63 -0
- package/dist/utils/prompts/configSummary.js.map +1 -0
- package/dist/utils/prompts/index.d.ts +22 -0
- package/dist/utils/prompts/index.d.ts.map +1 -0
- package/dist/utils/prompts/index.js +122 -0
- package/dist/utils/prompts/index.js.map +1 -0
- package/dist/utils/prompts/llmPrompts.d.ts +11 -0
- package/dist/utils/prompts/llmPrompts.d.ts.map +1 -0
- package/dist/utils/prompts/llmPrompts.js +96 -0
- package/dist/utils/prompts/llmPrompts.js.map +1 -0
- package/dist/utils/prompts/smartDefaults.d.ts +15 -0
- package/dist/utils/prompts/smartDefaults.d.ts.map +1 -0
- package/dist/utils/prompts/smartDefaults.js +105 -0
- package/dist/utils/prompts/smartDefaults.js.map +1 -0
- package/dist/utils/prompts/types.d.ts +38 -0
- package/dist/utils/prompts/types.d.ts.map +1 -0
- package/dist/utils/prompts/types.js +3 -0
- package/dist/utils/prompts/types.js.map +1 -0
- package/dist/utils/theme.d.ts +66 -0
- package/dist/utils/theme.d.ts.map +1 -0
- package/dist/utils/theme.js +93 -0
- package/dist/utils/theme.js.map +1 -0
- package/dist/version.d.ts +8 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +15 -0
- package/dist/version.js.map +1 -0
- package/package.json +18 -11
- package/prompts/update_plan_prompt.md +4 -5
- package/prompts/update_scaffold_prompt.md +14 -35
- package/dist/commands/shared/agents.d.ts +0 -2
- package/dist/commands/shared/agents.d.ts.map +0 -1
- package/dist/commands/shared/agents.js +0 -15
- package/dist/commands/shared/agents.js.map +0 -1
- package/dist/commands/shared/selection.d.ts +0 -12
- package/dist/commands/shared/selection.d.ts.map +0 -1
- package/dist/commands/shared/selection.js +0 -95
- package/dist/commands/shared/selection.js.map +0 -1
- package/dist/generators/agents/contextUtils.d.ts +0 -8
- package/dist/generators/agents/contextUtils.d.ts.map +0 -1
- package/dist/generators/agents/contextUtils.js +0 -15
- package/dist/generators/agents/contextUtils.js.map +0 -1
- package/dist/generators/agents/promptFormatter.d.ts +0 -9
- package/dist/generators/agents/promptFormatter.d.ts.map +0 -1
- package/dist/generators/agents/promptFormatter.js +0 -84
- package/dist/generators/agents/promptFormatter.js.map +0 -1
- package/dist/generators/analyzers/codebaseAnalyzer.d.ts +0 -45
- package/dist/generators/analyzers/codebaseAnalyzer.d.ts.map +0 -1
- package/dist/generators/analyzers/codebaseAnalyzer.js +0 -293
- package/dist/generators/analyzers/codebaseAnalyzer.js.map +0 -1
- package/dist/generators/analyzers/index.d.ts +0 -3
- package/dist/generators/analyzers/index.d.ts.map +0 -1
- package/dist/generators/analyzers/index.js +0 -6
- package/dist/generators/analyzers/index.js.map +0 -1
- package/dist/generators/documentation/documentationTemplates.d.ts +0 -21
- package/dist/generators/documentation/documentationTemplates.d.ts.map +0 -1
- package/dist/generators/documentation/documentationTemplates.js +0 -359
- package/dist/generators/documentation/documentationTemplates.js.map +0 -1
- package/dist/generators/documentation/documentationTypes.d.ts +0 -11
- package/dist/generators/documentation/documentationTypes.d.ts.map +0 -1
- package/dist/generators/documentation/documentationTypes.js +0 -22
- package/dist/generators/documentation/documentationTypes.js.map +0 -1
- package/dist/generators/documentation/documentationUtils.d.ts +0 -7
- package/dist/generators/documentation/documentationUtils.d.ts.map +0 -1
- package/dist/generators/documentation/documentationUtils.js +0 -28
- package/dist/generators/documentation/documentationUtils.js.map +0 -1
- package/dist/generators/documentation/incrementalDocumentationGenerator.d.ts +0 -33
- package/dist/generators/documentation/incrementalDocumentationGenerator.d.ts.map +0 -1
- package/dist/generators/documentation/incrementalDocumentationGenerator.js +0 -400
- package/dist/generators/documentation/incrementalDocumentationGenerator.js.map +0 -1
- package/dist/generators/documentation/templates/frontMatter.d.ts +0 -11
- package/dist/generators/documentation/templates/frontMatter.d.ts.map +0 -1
- package/dist/generators/documentation/templates/frontMatter.js +0 -29
- package/dist/generators/documentation/templates/frontMatter.js.map +0 -1
- package/dist/generators/documentation/templates.d.ts +0 -31
- package/dist/generators/documentation/templates.d.ts.map +0 -1
- package/dist/generators/documentation/templates.js +0 -566
- package/dist/generators/documentation/templates.js.map +0 -1
- package/dist/generators/guidelines/agentIntegration.d.ts +0 -43
- package/dist/generators/guidelines/agentIntegration.d.ts.map +0 -1
- package/dist/generators/guidelines/agentIntegration.js +0 -157
- package/dist/generators/guidelines/agentIntegration.js.map +0 -1
- package/dist/generators/guidelines/guidelineTypes.d.ts +0 -40
- package/dist/generators/guidelines/guidelineTypes.d.ts.map +0 -1
- package/dist/generators/guidelines/guidelineTypes.js +0 -144
- package/dist/generators/guidelines/guidelineTypes.js.map +0 -1
- package/dist/generators/guidelines/guidelinesAnalyzer.d.ts +0 -30
- package/dist/generators/guidelines/guidelinesAnalyzer.d.ts.map +0 -1
- package/dist/generators/guidelines/guidelinesAnalyzer.js +0 -263
- package/dist/generators/guidelines/guidelinesAnalyzer.js.map +0 -1
- package/dist/generators/guidelines/guidelinesGenerator.d.ts +0 -30
- package/dist/generators/guidelines/guidelinesGenerator.d.ts.map +0 -1
- package/dist/generators/guidelines/guidelinesGenerator.js +0 -249
- package/dist/generators/guidelines/guidelinesGenerator.js.map +0 -1
- package/dist/generators/guidelines/guidelinesTemplates.d.ts +0 -23
- package/dist/generators/guidelines/guidelinesTemplates.d.ts.map +0 -1
- package/dist/generators/guidelines/guidelinesTemplates.js +0 -304
- package/dist/generators/guidelines/guidelinesTemplates.js.map +0 -1
- package/dist/generators/guidelines/index.d.ts +0 -6
- package/dist/generators/guidelines/index.d.ts.map +0 -1
- package/dist/generators/guidelines/index.js +0 -16
- package/dist/generators/guidelines/index.js.map +0 -1
- package/dist/generators/moduleGrouper.d.ts +0 -14
- package/dist/generators/moduleGrouper.d.ts.map +0 -1
- package/dist/generators/moduleGrouper.js +0 -82
- package/dist/generators/moduleGrouper.js.map +0 -1
- package/dist/generators/projectAnalyzer.d.ts +0 -14
- package/dist/generators/projectAnalyzer.d.ts.map +0 -1
- package/dist/generators/projectAnalyzer.js +0 -217
- package/dist/generators/projectAnalyzer.js.map +0 -1
- package/dist/services/anthropicClient.d.ts +0 -12
- package/dist/services/anthropicClient.d.ts.map +0 -1
- package/dist/services/anthropicClient.js +0 -98
- package/dist/services/anthropicClient.js.map +0 -1
- package/dist/services/changeAnalyzer.d.ts +0 -44
- package/dist/services/changeAnalyzer.d.ts.map +0 -1
- package/dist/services/changeAnalyzer.js +0 -344
- package/dist/services/changeAnalyzer.js.map +0 -1
- package/dist/services/geminiClient.d.ts +0 -12
- package/dist/services/geminiClient.d.ts.map +0 -1
- package/dist/services/geminiClient.js +0 -96
- package/dist/services/geminiClient.js.map +0 -1
- package/dist/services/grokClient.d.ts +0 -12
- package/dist/services/grokClient.d.ts.map +0 -1
- package/dist/services/grokClient.js +0 -101
- package/dist/services/grokClient.js.map +0 -1
- package/dist/services/openaiClient.d.ts +0 -12
- package/dist/services/openaiClient.d.ts.map +0 -1
- package/dist/services/openaiClient.js +0 -98
- package/dist/services/openaiClient.js.map +0 -1
- package/dist/utils/interactiveMode.d.ts +0 -21
- package/dist/utils/interactiveMode.d.ts.map +0 -1
- package/dist/utils/interactiveMode.js +0 -737
- package/dist/utils/interactiveMode.js.map +0 -1
- package/dist/utils/pricing.d.ts +0 -14
- package/dist/utils/pricing.d.ts.map +0 -1
- package/dist/utils/pricing.js +0 -115
- package/dist/utils/pricing.js.map +0 -1
- package/dist/utils/tokenEstimator.d.ts +0 -28
- package/dist/utils/tokenEstimator.d.ts.map +0 -1
- package/dist/utils/tokenEstimator.js +0 -134
- package/dist/utils/tokenEstimator.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -37,31 +37,30 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
37
37
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
38
|
};
|
|
39
39
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.runInit = runInit;
|
|
40
41
|
exports.runGenerate = runGenerate;
|
|
41
42
|
exports.runAnalyze = runAnalyze;
|
|
42
43
|
exports.runUpdate = runUpdate;
|
|
43
44
|
exports.runPreview = runPreview;
|
|
44
45
|
exports.runGuidelines = runGuidelines;
|
|
45
|
-
exports.
|
|
46
|
+
exports.runLlmFill = runLlmFill;
|
|
46
47
|
const commander_1 = require("commander");
|
|
47
48
|
const path = __importStar(require("path"));
|
|
48
|
-
const fs = __importStar(require("fs-extra"));
|
|
49
|
-
const glob_1 = require("glob");
|
|
50
49
|
const dotenv = __importStar(require("dotenv"));
|
|
51
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
52
50
|
const inquirer_1 = __importDefault(require("inquirer"));
|
|
53
|
-
const
|
|
54
|
-
const documentationGenerator_1 = require("./generators/documentation/documentationGenerator");
|
|
55
|
-
const agentGenerator_1 = require("./generators/agents/agentGenerator");
|
|
51
|
+
const theme_1 = require("./utils/theme");
|
|
56
52
|
const planGenerator_1 = require("./generators/plans/planGenerator");
|
|
57
|
-
const shared_1 = require("./generators/shared");
|
|
58
53
|
const cliUI_1 = require("./utils/cliUI");
|
|
59
|
-
const promptLoader_1 = require("./utils/promptLoader");
|
|
60
54
|
const versionChecker_1 = require("./utils/versionChecker");
|
|
61
55
|
const i18n_1 = require("./utils/i18n");
|
|
62
|
-
const
|
|
63
|
-
const
|
|
64
|
-
const
|
|
56
|
+
const initService_1 = require("./services/init/initService");
|
|
57
|
+
const fillService_1 = require("./services/fill/fillService");
|
|
58
|
+
const planService_1 = require("./services/plan/planService");
|
|
59
|
+
const syncService_1 = require("./services/sync/syncService");
|
|
60
|
+
const serve_1 = require("./services/serve");
|
|
61
|
+
const mcp_1 = require("./services/mcp");
|
|
62
|
+
const prompts_1 = require("./utils/prompts");
|
|
63
|
+
const version_1 = require("./version");
|
|
65
64
|
dotenv.config();
|
|
66
65
|
const initialLocale = (0, i18n_1.detectLocale)(process.argv.slice(2), process.env.AI_CONTEXT_LANG);
|
|
67
66
|
let currentLocale = initialLocale;
|
|
@@ -73,28 +72,40 @@ const localeLabelKeys = {
|
|
|
73
72
|
};
|
|
74
73
|
const program = new commander_1.Command();
|
|
75
74
|
const ui = new cliUI_1.CLIInterface(t);
|
|
76
|
-
const
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
75
|
+
const DEFAULT_MODEL = 'gemini-3-flash-preview';
|
|
76
|
+
const initService = new initService_1.InitService({
|
|
77
|
+
ui,
|
|
78
|
+
t,
|
|
79
|
+
version: version_1.VERSION
|
|
80
|
+
});
|
|
81
|
+
const fillService = new fillService_1.FillService({
|
|
82
|
+
ui,
|
|
83
|
+
t,
|
|
84
|
+
version: version_1.VERSION,
|
|
85
|
+
defaultModel: DEFAULT_MODEL
|
|
86
|
+
});
|
|
87
|
+
const planService = new planService_1.PlanService({
|
|
88
|
+
ui,
|
|
89
|
+
t,
|
|
90
|
+
version: version_1.VERSION,
|
|
91
|
+
defaultModel: DEFAULT_MODEL
|
|
92
|
+
});
|
|
93
|
+
const syncService = new syncService_1.SyncService({
|
|
94
|
+
ui,
|
|
95
|
+
t,
|
|
96
|
+
version: version_1.VERSION
|
|
97
|
+
});
|
|
87
98
|
program
|
|
88
99
|
.name('ai-context')
|
|
89
100
|
.description(t('cli.description'))
|
|
90
|
-
.version(VERSION);
|
|
101
|
+
.version(version_1.VERSION);
|
|
91
102
|
program.option('-l, --lang <locale>', t('global.options.lang'), initialLocale);
|
|
92
103
|
let versionCheckPromise = null;
|
|
93
104
|
function scheduleVersionCheck(force = false) {
|
|
94
105
|
if (!versionCheckPromise || force) {
|
|
95
106
|
versionCheckPromise = (0, versionChecker_1.checkForUpdates)({
|
|
96
|
-
packageName: PACKAGE_NAME,
|
|
97
|
-
currentVersion: VERSION,
|
|
107
|
+
packageName: version_1.PACKAGE_NAME,
|
|
108
|
+
currentVersion: version_1.VERSION,
|
|
98
109
|
ui,
|
|
99
110
|
t,
|
|
100
111
|
force
|
|
@@ -111,34 +122,13 @@ program
|
|
|
111
122
|
.argument('<repo-path>', t('commands.init.arguments.repoPath'))
|
|
112
123
|
.argument('[type]', t('commands.init.arguments.type'), 'both')
|
|
113
124
|
.option('-o, --output <dir>', t('commands.init.options.output'), './.context')
|
|
114
|
-
.option('--docs <keys...>', t('commands.init.options.docs'))
|
|
115
|
-
.option('--agents <keys...>', t('commands.init.options.agents'))
|
|
116
125
|
.option('--exclude <patterns...>', t('commands.init.options.exclude'))
|
|
117
126
|
.option('--include <patterns...>', t('commands.init.options.include'))
|
|
118
127
|
.option('-v, --verbose', t('commands.init.options.verbose'))
|
|
128
|
+
.option('--no-semantic', t('commands.init.options.noSemantic'))
|
|
119
129
|
.action(async (repoPath, type, options) => {
|
|
120
130
|
try {
|
|
121
|
-
await
|
|
122
|
-
}
|
|
123
|
-
catch (error) {
|
|
124
|
-
ui.displayError(t('errors.init.scaffoldFailed'), error);
|
|
125
|
-
process.exit(1);
|
|
126
|
-
}
|
|
127
|
-
});
|
|
128
|
-
program
|
|
129
|
-
.command('scaffold')
|
|
130
|
-
.description(t('commands.scaffold.description'))
|
|
131
|
-
.argument('<repo-path>', t('commands.init.arguments.repoPath'))
|
|
132
|
-
.argument('[type]', t('commands.init.arguments.type'), 'both')
|
|
133
|
-
.option('-o, --output <dir>', t('commands.init.options.output'), './.context')
|
|
134
|
-
.option('--docs <keys...>', t('commands.init.options.docs'))
|
|
135
|
-
.option('--agents <keys...>', t('commands.init.options.agents'))
|
|
136
|
-
.option('--exclude <patterns...>', t('commands.init.options.exclude'))
|
|
137
|
-
.option('--include <patterns...>', t('commands.init.options.include'))
|
|
138
|
-
.option('-v, --verbose', t('commands.init.options.verbose'))
|
|
139
|
-
.action(async (repoPath, type, options) => {
|
|
140
|
-
try {
|
|
141
|
-
await runInit(repoPath, type, options);
|
|
131
|
+
await initService.run(repoPath, type, options);
|
|
142
132
|
}
|
|
143
133
|
catch (error) {
|
|
144
134
|
ui.displayError(t('errors.init.scaffoldFailed'), error);
|
|
@@ -155,17 +145,16 @@ program
|
|
|
155
145
|
.option('-p, --provider <provider>', t('commands.fill.options.provider'))
|
|
156
146
|
.option('--base-url <url>', t('commands.fill.options.baseUrl'))
|
|
157
147
|
.option('--prompt <file>', t('commands.fill.options.prompt'))
|
|
158
|
-
.option('--dry-run', t('commands.fill.options.dryRun'), false)
|
|
159
|
-
.option('--all', t('commands.fill.options.all'), false)
|
|
160
148
|
.option('--limit <number>', t('commands.fill.options.limit'), (value) => parseInt(value, 10))
|
|
161
|
-
.option('--docs <keys...>', t('commands.fill.options.docs'))
|
|
162
|
-
.option('--agents <keys...>', t('commands.fill.options.agents'))
|
|
163
149
|
.option('--exclude <patterns...>', t('commands.fill.options.exclude'))
|
|
164
150
|
.option('--include <patterns...>', t('commands.fill.options.include'))
|
|
165
151
|
.option('-v, --verbose', t('commands.fill.options.verbose'))
|
|
152
|
+
.option('--no-semantic', t('commands.fill.options.noSemantic'))
|
|
153
|
+
.option('--languages <langs>', t('commands.fill.options.languages'))
|
|
154
|
+
.option('--use-lsp', t('commands.fill.options.useLsp'))
|
|
166
155
|
.action(async (repoPath, options) => {
|
|
167
156
|
try {
|
|
168
|
-
await
|
|
157
|
+
await fillService.run(repoPath, options);
|
|
169
158
|
}
|
|
170
159
|
catch (error) {
|
|
171
160
|
ui.displayError(t('errors.fill.failed'), error);
|
|
@@ -179,8 +168,6 @@ program
|
|
|
179
168
|
.option('-o, --output <dir>', t('commands.plan.options.output'), './.context')
|
|
180
169
|
.option('--title <title>', t('commands.plan.options.title'))
|
|
181
170
|
.option('--summary <text>', t('commands.plan.options.summary'))
|
|
182
|
-
.option('--agents <types...>', t('commands.plan.options.agents'))
|
|
183
|
-
.option('--docs <keys...>', t('commands.plan.options.docs'))
|
|
184
171
|
.option('-f, --force', t('commands.plan.options.force'))
|
|
185
172
|
.option('--fill', t('commands.plan.options.fill'))
|
|
186
173
|
.option('-r, --repo <path>', t('commands.plan.options.repo'))
|
|
@@ -193,27 +180,19 @@ program
|
|
|
193
180
|
.option('--include <patterns...>', t('commands.plan.options.include'))
|
|
194
181
|
.option('--exclude <patterns...>', t('commands.plan.options.exclude'))
|
|
195
182
|
.option('-v, --verbose', t('commands.plan.options.verbose'))
|
|
183
|
+
.option('--no-semantic', t('commands.plan.options.noSemantic'))
|
|
184
|
+
.option('--no-lsp', t('commands.plan.options.noLsp'))
|
|
196
185
|
.action(async (planName, rawOptions) => {
|
|
197
|
-
const agentSelection = parseAgentSelection(rawOptions.agents);
|
|
198
|
-
if (agentSelection.invalid.length > 0) {
|
|
199
|
-
ui.displayWarning(t('warnings.agents.unknown', { values: agentSelection.invalid.join(', ') }));
|
|
200
|
-
}
|
|
201
|
-
const docSelection = parseDocSelection(rawOptions.docs);
|
|
202
|
-
if (docSelection.invalid.length > 0) {
|
|
203
|
-
ui.displayWarning(t('warnings.docs.unknown', { values: docSelection.invalid.join(', ') }));
|
|
204
|
-
}
|
|
205
186
|
const outputDir = path.resolve(rawOptions.output || './.context');
|
|
206
187
|
if (rawOptions.fill) {
|
|
207
188
|
try {
|
|
208
|
-
await scaffoldPlanIfNeeded(planName, outputDir, {
|
|
189
|
+
await planService.scaffoldPlanIfNeeded(planName, outputDir, {
|
|
209
190
|
title: rawOptions.title,
|
|
210
191
|
summary: rawOptions.summary,
|
|
211
|
-
agentSelection,
|
|
212
|
-
docSelection,
|
|
213
192
|
force: Boolean(rawOptions.force),
|
|
214
193
|
verbose: Boolean(rawOptions.verbose)
|
|
215
194
|
});
|
|
216
|
-
await
|
|
195
|
+
await planService.fillPlan(planName, { ...rawOptions, output: outputDir });
|
|
217
196
|
}
|
|
218
197
|
catch (error) {
|
|
219
198
|
ui.displayError(t('errors.plan.fillFailed'), error);
|
|
@@ -229,13 +208,13 @@ program
|
|
|
229
208
|
outputDir,
|
|
230
209
|
title: rawOptions.title,
|
|
231
210
|
summary: rawOptions.summary,
|
|
232
|
-
selectedAgentTypes: agentSelection.explicitNone ? null : agentSelection.selected,
|
|
233
|
-
selectedDocKeys: docSelection.explicitNone ? null : docSelection.selected,
|
|
234
211
|
force: Boolean(rawOptions.force),
|
|
235
|
-
verbose: Boolean(rawOptions.verbose)
|
|
212
|
+
verbose: Boolean(rawOptions.verbose),
|
|
213
|
+
semantic: rawOptions.semantic !== false,
|
|
214
|
+
projectPath: rawOptions.repo ? path.resolve(rawOptions.repo) : path.resolve(rawOptions.output || './.context', '..')
|
|
236
215
|
});
|
|
237
216
|
ui.updateSpinner(t('spinner.plan.created'), 'success');
|
|
238
|
-
ui.displaySuccess(t('success.plan.createdAt', { path:
|
|
217
|
+
ui.displaySuccess(t('success.plan.createdAt', { path: theme_1.colors.accent(result.relativePath) }));
|
|
239
218
|
}
|
|
240
219
|
catch (error) {
|
|
241
220
|
ui.updateSpinner(t('spinner.plan.creationFailed'), 'fail');
|
|
@@ -246,91 +225,85 @@ program
|
|
|
246
225
|
ui.stopSpinner();
|
|
247
226
|
}
|
|
248
227
|
});
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
include: rawOptions.include,
|
|
263
|
-
exclude: rawOptions.exclude || [],
|
|
264
|
-
verbose: rawOptions.verbose || false,
|
|
265
|
-
scaffoldDocs: shouldGenerateDocs(resolvedType, docSelection),
|
|
266
|
-
scaffoldAgents: shouldGenerateAgents(resolvedType, agentSelection),
|
|
267
|
-
selectedDocKeys: docSelection.selected,
|
|
268
|
-
selectedAgentTypes: agentSelection.selected
|
|
269
|
-
};
|
|
270
|
-
if (!options.scaffoldDocs && !options.scaffoldAgents) {
|
|
271
|
-
ui.displayWarning(t('warnings.scaffold.noneSelected'));
|
|
272
|
-
return;
|
|
273
|
-
}
|
|
274
|
-
await ensurePaths(options);
|
|
275
|
-
ui.displayWelcome(VERSION);
|
|
276
|
-
ui.displayProjectInfo(options.repoPath, options.outputDir, resolvedType);
|
|
277
|
-
const fileMapper = new fileMapper_1.FileMapper(options.exclude);
|
|
278
|
-
ui.displayStep(1, 3, t('steps.init.analyze'));
|
|
279
|
-
ui.startSpinner(t('spinner.repo.scanning'));
|
|
280
|
-
const repoStructure = await fileMapper.mapRepository(options.repoPath, options.include);
|
|
281
|
-
ui.updateSpinner(t('spinner.repo.scanComplete', {
|
|
282
|
-
fileCount: repoStructure.totalFiles,
|
|
283
|
-
directoryCount: repoStructure.directories.length
|
|
284
|
-
}), 'success');
|
|
285
|
-
let docsGenerated = 0;
|
|
286
|
-
let agentsGenerated = 0;
|
|
287
|
-
const docGenerator = new documentationGenerator_1.DocumentationGenerator();
|
|
288
|
-
const agentGenerator = new agentGenerator_1.AgentGenerator();
|
|
289
|
-
if (options.scaffoldDocs) {
|
|
290
|
-
ui.displayStep(2, 3, t('steps.init.docs'));
|
|
291
|
-
ui.startSpinner(t('spinner.docs.creating'));
|
|
292
|
-
docsGenerated = await docGenerator.generateDocumentation(repoStructure, options.outputDir, { selectedDocs: options.selectedDocKeys }, options.verbose);
|
|
293
|
-
ui.updateSpinner(t('spinner.docs.created', { count: docsGenerated }), 'success');
|
|
228
|
+
program
|
|
229
|
+
.command('sync-agents')
|
|
230
|
+
.description(t('commands.sync.description'))
|
|
231
|
+
.option('-s, --source <dir>', t('commands.sync.options.source'), './.context/agents')
|
|
232
|
+
.option('-t, --target <paths...>', t('commands.sync.options.target'))
|
|
233
|
+
.option('-m, --mode <type>', t('commands.sync.options.mode'), 'symlink')
|
|
234
|
+
.option('-p, --preset <name>', t('commands.sync.options.preset'))
|
|
235
|
+
.option('--force', t('commands.sync.options.force'))
|
|
236
|
+
.option('--dry-run', t('commands.sync.options.dryRun'))
|
|
237
|
+
.option('-v, --verbose', t('commands.sync.options.verbose'))
|
|
238
|
+
.action(async (options) => {
|
|
239
|
+
try {
|
|
240
|
+
await syncService.run(options);
|
|
294
241
|
}
|
|
295
|
-
|
|
296
|
-
ui.
|
|
297
|
-
|
|
298
|
-
agentsGenerated = await agentGenerator.generateAgentPrompts(repoStructure, options.outputDir, options.selectedAgentTypes, options.verbose);
|
|
299
|
-
ui.updateSpinner(t('spinner.agents.created', { count: agentsGenerated }), 'success');
|
|
242
|
+
catch (error) {
|
|
243
|
+
ui.displayError(t('errors.sync.failed'), error);
|
|
244
|
+
process.exit(1);
|
|
300
245
|
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
246
|
+
});
|
|
247
|
+
program
|
|
248
|
+
.command('serve')
|
|
249
|
+
.description('Start passthrough server for external AI agents (stdin/stdout JSON)')
|
|
250
|
+
.option('-r, --repo-path <path>', 'Default repository path for tools')
|
|
251
|
+
.option('-f, --format <format>', 'Output format: json or jsonl', 'jsonl')
|
|
252
|
+
.option('-v, --verbose', 'Enable verbose logging to stderr')
|
|
253
|
+
.action(async (options) => {
|
|
254
|
+
const service = new serve_1.ServeService({
|
|
255
|
+
repoPath: options.repoPath,
|
|
256
|
+
format: options.format,
|
|
257
|
+
verbose: options.verbose
|
|
258
|
+
});
|
|
259
|
+
try {
|
|
260
|
+
await service.run();
|
|
309
261
|
}
|
|
310
|
-
|
|
311
|
-
|
|
262
|
+
catch (error) {
|
|
263
|
+
if (options.verbose) {
|
|
264
|
+
process.stderr.write(`[serve] Error: ${error}\n`);
|
|
265
|
+
}
|
|
266
|
+
process.exit(1);
|
|
312
267
|
}
|
|
313
|
-
|
|
314
|
-
|
|
268
|
+
});
|
|
269
|
+
program
|
|
270
|
+
.command('mcp')
|
|
271
|
+
.description('Start MCP (Model Context Protocol) server for Claude Code integration')
|
|
272
|
+
.option('-r, --repo-path <path>', 'Default repository path for tools')
|
|
273
|
+
.option('-v, --verbose', 'Enable verbose logging to stderr')
|
|
274
|
+
.action(async (options) => {
|
|
275
|
+
try {
|
|
276
|
+
const server = await (0, mcp_1.startMCPServer)({
|
|
277
|
+
repoPath: options.repoPath,
|
|
278
|
+
verbose: options.verbose
|
|
279
|
+
});
|
|
280
|
+
// Handle graceful shutdown
|
|
281
|
+
process.on('SIGINT', async () => {
|
|
282
|
+
await server.stop();
|
|
283
|
+
process.exit(0);
|
|
284
|
+
});
|
|
285
|
+
process.on('SIGTERM', async () => {
|
|
286
|
+
await server.stop();
|
|
287
|
+
process.exit(0);
|
|
288
|
+
});
|
|
315
289
|
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
throw new Error(t('errors.common.repoMissing', { path: options.repoPath }));
|
|
290
|
+
catch (error) {
|
|
291
|
+
if (options.verbose) {
|
|
292
|
+
process.stderr.write(`[mcp] Error: ${error}\n`);
|
|
293
|
+
}
|
|
294
|
+
process.exit(1);
|
|
322
295
|
}
|
|
323
|
-
|
|
296
|
+
});
|
|
297
|
+
async function runInit(repoPath, type, rawOptions) {
|
|
298
|
+
await initService.run(repoPath, type, rawOptions);
|
|
324
299
|
}
|
|
325
300
|
async function runGenerate(repoPath, options) {
|
|
326
301
|
const type = options?.docsOnly ? 'docs' : options?.agentsOnly ? 'agents' : (options?.type || 'both');
|
|
327
|
-
await
|
|
302
|
+
await initService.run(repoPath, type, {
|
|
328
303
|
output: options?.output ?? options?.outputDir ?? './.context',
|
|
329
304
|
include: options?.include,
|
|
330
305
|
exclude: options?.exclude,
|
|
331
306
|
verbose: options?.verbose,
|
|
332
|
-
docs: options?.docs,
|
|
333
|
-
agents: options?.agents,
|
|
334
307
|
docsOnly: options?.docsOnly,
|
|
335
308
|
agentsOnly: options?.agentsOnly
|
|
336
309
|
});
|
|
@@ -347,621 +320,8 @@ async function runPreview(..._args) {
|
|
|
347
320
|
async function runGuidelines(..._args) {
|
|
348
321
|
throw new Error(t('errors.commands.guidelinesRemoved'));
|
|
349
322
|
}
|
|
350
|
-
async function resolveLlmConfig(rawOptions, defaults) {
|
|
351
|
-
const providerEnvMap = llmClientFactory_1.LLMClientFactory.getEnvironmentVariables();
|
|
352
|
-
const defaultModels = llmClientFactory_1.LLMClientFactory.getDefaultModels();
|
|
353
|
-
let provider = rawOptions.provider;
|
|
354
|
-
let model = rawOptions.model;
|
|
355
|
-
let apiKey = rawOptions.apiKey;
|
|
356
|
-
if (!apiKey) {
|
|
357
|
-
if (provider) {
|
|
358
|
-
for (const envVar of providerEnvMap[provider]) {
|
|
359
|
-
const value = process.env[envVar];
|
|
360
|
-
if (value) {
|
|
361
|
-
apiKey = value;
|
|
362
|
-
break;
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
else {
|
|
367
|
-
outer: for (const [prov, envVars] of Object.entries(providerEnvMap)) {
|
|
368
|
-
for (const envVar of envVars) {
|
|
369
|
-
const value = process.env[envVar];
|
|
370
|
-
if (value) {
|
|
371
|
-
apiKey = value;
|
|
372
|
-
provider = prov;
|
|
373
|
-
break outer;
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
if (!provider) {
|
|
380
|
-
if (model) {
|
|
381
|
-
provider = llmClientFactory_1.LLMClientFactory.detectProviderFromModel(model);
|
|
382
|
-
}
|
|
383
|
-
else if (apiKey) {
|
|
384
|
-
provider = llmClientFactory_1.LLMClientFactory.getProviderFromApiKey(apiKey);
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
if (!model) {
|
|
388
|
-
if (provider === 'openrouter' && process.env.OPENROUTER_MODEL) {
|
|
389
|
-
model = process.env.OPENROUTER_MODEL;
|
|
390
|
-
}
|
|
391
|
-
else if (provider && defaultModels[provider]?.length) {
|
|
392
|
-
model = defaultModels[provider][0];
|
|
393
|
-
}
|
|
394
|
-
else {
|
|
395
|
-
model = defaults.fallbackModel;
|
|
396
|
-
provider = llmClientFactory_1.LLMClientFactory.detectProviderFromModel(model);
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
if (!provider) {
|
|
400
|
-
provider = llmClientFactory_1.LLMClientFactory.detectProviderFromModel(model || defaults.fallbackModel);
|
|
401
|
-
}
|
|
402
|
-
if (!apiKey) {
|
|
403
|
-
for (const envVar of providerEnvMap[provider]) {
|
|
404
|
-
const value = process.env[envVar];
|
|
405
|
-
if (value) {
|
|
406
|
-
apiKey = value;
|
|
407
|
-
break;
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
if (!apiKey) {
|
|
412
|
-
const envVars = providerEnvMap[provider];
|
|
413
|
-
throw new Error(t('errors.fill.apiKeyMissing', {
|
|
414
|
-
provider: provider.toUpperCase(),
|
|
415
|
-
envVars: envVars.join(', ')
|
|
416
|
-
}));
|
|
417
|
-
}
|
|
418
|
-
return {
|
|
419
|
-
provider,
|
|
420
|
-
model: model || defaults.fallbackModel,
|
|
421
|
-
apiKey,
|
|
422
|
-
baseUrl: rawOptions.baseUrl
|
|
423
|
-
};
|
|
424
|
-
}
|
|
425
323
|
async function runLlmFill(repoPath, rawOptions) {
|
|
426
|
-
|
|
427
|
-
const outputDir = path.resolve(rawOptions.output || './.context');
|
|
428
|
-
const docsDir = path.join(outputDir, 'docs');
|
|
429
|
-
const agentsDir = path.join(outputDir, 'agents');
|
|
430
|
-
await ensureDirectoryExists(docsDir, t('errors.fill.missingDocsScaffold'));
|
|
431
|
-
await ensureDirectoryExists(agentsDir, t('errors.fill.missingAgentsScaffold'));
|
|
432
|
-
const docSelection = parseDocSelection(rawOptions.docs);
|
|
433
|
-
const agentSelection = parseAgentSelection(rawOptions.agents);
|
|
434
|
-
if (docSelection.invalid.length > 0) {
|
|
435
|
-
ui.displayWarning(t('warnings.docs.unknown', { values: docSelection.invalid.join(', ') }));
|
|
436
|
-
}
|
|
437
|
-
if (agentSelection.invalid.length > 0) {
|
|
438
|
-
ui.displayWarning(t('warnings.agents.unknown', { values: agentSelection.invalid.join(', ') }));
|
|
439
|
-
}
|
|
440
|
-
const { provider, model, apiKey, baseUrl } = await resolveLlmConfig(rawOptions, {
|
|
441
|
-
fallbackModel: DEFAULT_MODEL
|
|
442
|
-
});
|
|
443
|
-
const scaffoldPrompt = await (0, promptLoader_1.resolveScaffoldPrompt)(rawOptions.prompt, missingPath => t('errors.fill.promptMissing', { path: missingPath }));
|
|
444
|
-
const docAllowlist = docSelection.explicitNone
|
|
445
|
-
? new Set()
|
|
446
|
-
: (0, guideRegistry_1.getDocFilesByKeys)(docSelection.selected);
|
|
447
|
-
const agentAllowlist = agentSelection.explicitNone
|
|
448
|
-
? new Set()
|
|
449
|
-
: getAgentFilesByTypes(agentSelection.selected);
|
|
450
|
-
const options = {
|
|
451
|
-
repoPath: resolvedRepo,
|
|
452
|
-
outputDir,
|
|
453
|
-
provider,
|
|
454
|
-
model,
|
|
455
|
-
apiKey,
|
|
456
|
-
baseUrl,
|
|
457
|
-
include: rawOptions.include,
|
|
458
|
-
exclude: rawOptions.exclude,
|
|
459
|
-
verbose: rawOptions.verbose || false,
|
|
460
|
-
dryRun: rawOptions.dryRun || false,
|
|
461
|
-
processAll: rawOptions.all || false,
|
|
462
|
-
limit: rawOptions.limit,
|
|
463
|
-
selectedDocKeys: docSelection.selected,
|
|
464
|
-
selectedAgentTypes: agentSelection.selected,
|
|
465
|
-
selectedDocFiles: docAllowlist,
|
|
466
|
-
selectedAgentFiles: agentAllowlist
|
|
467
|
-
};
|
|
468
|
-
const scaffoldPromptDisplayPath = scaffoldPrompt.path
|
|
469
|
-
? path.relative(process.cwd(), scaffoldPrompt.path) || scaffoldPrompt.path
|
|
470
|
-
: undefined;
|
|
471
|
-
if (scaffoldPrompt.source === 'custom' && scaffoldPromptDisplayPath) {
|
|
472
|
-
ui.displayInfo(t('info.prompt.title'), t('info.prompt.usingCustom', { path: scaffoldPromptDisplayPath }));
|
|
473
|
-
}
|
|
474
|
-
else if (scaffoldPrompt.source === 'package' && scaffoldPromptDisplayPath) {
|
|
475
|
-
ui.displayInfo(t('info.prompt.title'), t('info.prompt.usingPackage', { path: scaffoldPromptDisplayPath }));
|
|
476
|
-
}
|
|
477
|
-
else {
|
|
478
|
-
ui.displayInfo(t('info.prompt.title'), t('info.prompt.usingBundled'));
|
|
479
|
-
}
|
|
480
|
-
ui.displayWelcome(VERSION);
|
|
481
|
-
ui.displayProjectInfo(options.repoPath, options.outputDir, `fill:${options.provider}`);
|
|
482
|
-
const fileMapper = new fileMapper_1.FileMapper(options.exclude);
|
|
483
|
-
ui.displayStep(1, 3, t('steps.fill.analyze'));
|
|
484
|
-
ui.startSpinner(t('spinner.repo.scanning'));
|
|
485
|
-
const repoStructure = await fileMapper.mapRepository(options.repoPath, options.include);
|
|
486
|
-
ui.updateSpinner(t('spinner.repo.scanComplete', {
|
|
487
|
-
fileCount: repoStructure.totalFiles,
|
|
488
|
-
directoryCount: repoStructure.directories.length
|
|
489
|
-
}), 'success');
|
|
490
|
-
const systemPrompt = scaffoldPrompt.content;
|
|
491
|
-
const llmClient = llmClientFactory_1.LLMClientFactory.createClient({
|
|
492
|
-
apiKey: options.apiKey,
|
|
493
|
-
model: options.model,
|
|
494
|
-
provider: options.provider,
|
|
495
|
-
baseUrl: options.baseUrl
|
|
496
|
-
});
|
|
497
|
-
const targets = await collectTargets(docsDir, agentsDir, options.processAll, options.limit, options.selectedDocFiles, options.selectedAgentFiles);
|
|
498
|
-
if (targets.length === 0) {
|
|
499
|
-
ui.displayWarning(t('warnings.fill.noTargets'));
|
|
500
|
-
return;
|
|
501
|
-
}
|
|
502
|
-
const contextSummary = buildContextSummary(repoStructure);
|
|
503
|
-
const results = [];
|
|
504
|
-
ui.displayStep(2, 3, t('steps.fill.processFiles', { count: targets.length, model: options.model }));
|
|
505
|
-
for (const target of targets) {
|
|
506
|
-
const relativePath = path.relative(options.outputDir, target.fullPath);
|
|
507
|
-
ui.startSpinner(t('spinner.fill.processing', { path: relativePath }));
|
|
508
|
-
try {
|
|
509
|
-
const currentContent = await fs.readFile(target.fullPath, 'utf-8');
|
|
510
|
-
const userPrompt = buildUserPrompt(relativePath, currentContent, contextSummary, target.isAgent);
|
|
511
|
-
const updatedContent = await llmClient.generateText(userPrompt, systemPrompt);
|
|
512
|
-
if (!updatedContent || !updatedContent.trim()) {
|
|
513
|
-
ui.updateSpinner(t('spinner.fill.noContent', { path: relativePath }), 'warn');
|
|
514
|
-
results.push({ file: relativePath, status: 'skipped', message: t('messages.fill.emptyResponse') });
|
|
515
|
-
continue;
|
|
516
|
-
}
|
|
517
|
-
if (options.dryRun) {
|
|
518
|
-
ui.updateSpinner(t('spinner.fill.dryRunPreview', { path: relativePath }), 'info');
|
|
519
|
-
console.log(chalk_1.default.gray(`\n${t('messages.fill.previewStart')}`));
|
|
520
|
-
console.log(updatedContent.trim());
|
|
521
|
-
console.log(chalk_1.default.gray(`${t('messages.fill.previewEnd')}\n`));
|
|
522
|
-
}
|
|
523
|
-
else {
|
|
524
|
-
await fs.writeFile(target.fullPath, ensureTrailingNewline(updatedContent));
|
|
525
|
-
ui.updateSpinner(t('spinner.fill.updated', { path: relativePath }), 'success');
|
|
526
|
-
}
|
|
527
|
-
results.push({ file: relativePath, status: options.dryRun ? 'skipped' : 'updated' });
|
|
528
|
-
}
|
|
529
|
-
catch (error) {
|
|
530
|
-
ui.updateSpinner(t('spinner.fill.failed', { path: relativePath }), 'fail');
|
|
531
|
-
results.push({
|
|
532
|
-
file: relativePath,
|
|
533
|
-
status: 'failed',
|
|
534
|
-
message: error instanceof Error ? error.message : String(error)
|
|
535
|
-
});
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
ui.displayStep(3, 3, t('steps.fill.summary'));
|
|
539
|
-
printLlmSummary(llmClient.getUsageStats(), results, options.dryRun);
|
|
540
|
-
ui.displaySuccess(t('success.fill.completed'));
|
|
541
|
-
}
|
|
542
|
-
async function scaffoldPlanIfNeeded(planName, outputDir, options) {
|
|
543
|
-
const resolvedOutput = path.resolve(outputDir);
|
|
544
|
-
const plansDir = path.join(resolvedOutput, 'plans');
|
|
545
|
-
const normalizedInput = planName.replace(/\.md$/i, '');
|
|
546
|
-
const slug = shared_1.GeneratorUtils.slugify(normalizedInput);
|
|
547
|
-
if (!slug) {
|
|
548
|
-
throw new Error(t('errors.plan.invalidName'));
|
|
549
|
-
}
|
|
550
|
-
const planPath = path.join(plansDir, `${slug}.md`);
|
|
551
|
-
const planExists = await fs.pathExists(planPath);
|
|
552
|
-
if (planExists && !options.force) {
|
|
553
|
-
return;
|
|
554
|
-
}
|
|
555
|
-
const generator = new planGenerator_1.PlanGenerator();
|
|
556
|
-
const result = await generator.generatePlan({
|
|
557
|
-
planName,
|
|
558
|
-
outputDir: resolvedOutput,
|
|
559
|
-
title: options.title,
|
|
560
|
-
summary: options.summary,
|
|
561
|
-
selectedAgentTypes: options.agentSelection
|
|
562
|
-
? options.agentSelection.explicitNone
|
|
563
|
-
? null
|
|
564
|
-
: options.agentSelection.selected
|
|
565
|
-
: undefined,
|
|
566
|
-
selectedDocKeys: options.docSelection
|
|
567
|
-
? options.docSelection.explicitNone
|
|
568
|
-
? null
|
|
569
|
-
: options.docSelection.selected
|
|
570
|
-
: undefined,
|
|
571
|
-
force: Boolean(options.force),
|
|
572
|
-
verbose: Boolean(options.verbose)
|
|
573
|
-
});
|
|
574
|
-
const relativePath = result.relativePath;
|
|
575
|
-
const message = planExists && options.force
|
|
576
|
-
? t('messages.plan.regenerated', { path: relativePath })
|
|
577
|
-
: t('messages.plan.created', { path: relativePath });
|
|
578
|
-
ui.displayInfo(t('info.plan.scaffolded.title'), message);
|
|
579
|
-
}
|
|
580
|
-
async function runPlanFill(planName, rawOptions) {
|
|
581
|
-
const outputDir = path.resolve(rawOptions.output || './.context');
|
|
582
|
-
const plansDir = path.join(outputDir, 'plans');
|
|
583
|
-
await ensureDirectoryExists(plansDir, t('errors.plan.missingPlansDir'));
|
|
584
|
-
const normalizedInput = planName.replace(/\.md$/i, '');
|
|
585
|
-
const slug = shared_1.GeneratorUtils.slugify(normalizedInput);
|
|
586
|
-
if (!slug) {
|
|
587
|
-
throw new Error(t('errors.plan.invalidName'));
|
|
588
|
-
}
|
|
589
|
-
const candidateFiles = new Set();
|
|
590
|
-
candidateFiles.add(path.join(plansDir, `${slug}.md`));
|
|
591
|
-
if (planName.toLowerCase().endsWith('.md')) {
|
|
592
|
-
candidateFiles.add(path.join(plansDir, planName));
|
|
593
|
-
}
|
|
594
|
-
let planPath;
|
|
595
|
-
for (const candidate of candidateFiles) {
|
|
596
|
-
if (await fs.pathExists(candidate)) {
|
|
597
|
-
planPath = candidate;
|
|
598
|
-
break;
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
if (!planPath) {
|
|
602
|
-
const expected = Array.from(candidateFiles).map(file => path.relative(process.cwd(), file)).join(' or ');
|
|
603
|
-
throw new Error(t('errors.plan.notFound', { expected }));
|
|
604
|
-
}
|
|
605
|
-
const docsDir = path.join(outputDir, 'docs');
|
|
606
|
-
const agentsDir = path.join(outputDir, 'agents');
|
|
607
|
-
await ensureDirectoryExists(docsDir, t('errors.fill.missingDocsScaffold'));
|
|
608
|
-
await ensureDirectoryExists(agentsDir, t('errors.fill.missingAgentsScaffold'));
|
|
609
|
-
const repoPath = path.resolve(rawOptions.repo || process.cwd());
|
|
610
|
-
if (!(await fs.pathExists(repoPath))) {
|
|
611
|
-
throw new Error(t('errors.common.repoMissing', { path: repoPath }));
|
|
612
|
-
}
|
|
613
|
-
const { provider, model, apiKey, baseUrl } = await resolveLlmConfig(rawOptions, {
|
|
614
|
-
fallbackModel: DEFAULT_MODEL
|
|
615
|
-
});
|
|
616
|
-
const planPrompt = await (0, promptLoader_1.resolvePlanPrompt)(rawOptions.prompt, missingPath => t('errors.fill.promptMissing', { path: missingPath }));
|
|
617
|
-
const planContent = await fs.readFile(planPath, 'utf-8');
|
|
618
|
-
const docsIndexPath = path.join(docsDir, 'README.md');
|
|
619
|
-
const agentsIndexPath = path.join(agentsDir, 'README.md');
|
|
620
|
-
const docsIndex = (await fs.pathExists(docsIndexPath)) ? await fs.readFile(docsIndexPath, 'utf-8') : undefined;
|
|
621
|
-
const agentsIndex = (await fs.pathExists(agentsIndexPath)) ? await fs.readFile(agentsIndexPath, 'utf-8') : undefined;
|
|
622
|
-
const referencedDocs = await loadReferencedMarkdown(docsDir, extractPlanReferences(planContent, 'docs'));
|
|
623
|
-
const referencedAgents = await loadReferencedMarkdown(agentsDir, extractPlanReferences(planContent, 'agents'));
|
|
624
|
-
const planPromptDisplayPath = planPrompt.path
|
|
625
|
-
? path.relative(process.cwd(), planPrompt.path) || planPrompt.path
|
|
626
|
-
: undefined;
|
|
627
|
-
if (planPrompt.source === 'custom' && planPromptDisplayPath) {
|
|
628
|
-
ui.displayInfo(t('info.prompt.title'), t('info.prompt.usingCustom', { path: planPromptDisplayPath }));
|
|
629
|
-
}
|
|
630
|
-
else if (planPrompt.source === 'package' && planPromptDisplayPath) {
|
|
631
|
-
ui.displayInfo(t('info.prompt.title'), t('info.prompt.usingPackage', { path: planPromptDisplayPath }));
|
|
632
|
-
}
|
|
633
|
-
else {
|
|
634
|
-
ui.displayInfo(t('info.prompt.title'), t('info.prompt.usingBundled'));
|
|
635
|
-
}
|
|
636
|
-
ui.displayWelcome(VERSION);
|
|
637
|
-
ui.displayProjectInfo(repoPath, outputDir, `plan-fill:${provider}`);
|
|
638
|
-
const fileMapper = new fileMapper_1.FileMapper(rawOptions.exclude);
|
|
639
|
-
ui.displayStep(1, 3, t('steps.plan.summary'));
|
|
640
|
-
ui.startSpinner(t('spinner.planFill.analyzingRepo'));
|
|
641
|
-
const repoStructure = await fileMapper.mapRepository(repoPath, rawOptions.include);
|
|
642
|
-
const contextSummary = buildContextSummary(repoStructure);
|
|
643
|
-
ui.updateSpinner(t('spinner.planFill.summaryReady'), 'success');
|
|
644
|
-
const systemPrompt = planPrompt.content;
|
|
645
|
-
const llmClient = llmClientFactory_1.LLMClientFactory.createClient({
|
|
646
|
-
apiKey,
|
|
647
|
-
model,
|
|
648
|
-
provider,
|
|
649
|
-
baseUrl
|
|
650
|
-
});
|
|
651
|
-
const planRelativePath = path.relative(outputDir, planPath);
|
|
652
|
-
const results = [];
|
|
653
|
-
ui.displayStep(2, 3, t('steps.plan.update', { path: planRelativePath, model }));
|
|
654
|
-
ui.startSpinner(t('spinner.planFill.updating', { path: planRelativePath }));
|
|
655
|
-
try {
|
|
656
|
-
const userPrompt = buildPlanUserPrompt({
|
|
657
|
-
relativePath: planRelativePath,
|
|
658
|
-
planContent,
|
|
659
|
-
contextSummary,
|
|
660
|
-
docsIndex,
|
|
661
|
-
agentsIndex,
|
|
662
|
-
docs: referencedDocs,
|
|
663
|
-
agents: referencedAgents
|
|
664
|
-
});
|
|
665
|
-
const updatedContent = await llmClient.generateText(userPrompt, systemPrompt);
|
|
666
|
-
if (!updatedContent || !updatedContent.trim()) {
|
|
667
|
-
ui.updateSpinner(t('spinner.planFill.noContent'), 'warn');
|
|
668
|
-
results.push({ file: planRelativePath, status: 'skipped', message: t('messages.fill.emptyResponse') });
|
|
669
|
-
}
|
|
670
|
-
else if (rawOptions.dryRun) {
|
|
671
|
-
ui.updateSpinner(t('spinner.planFill.dryRun'), 'info');
|
|
672
|
-
console.log(chalk_1.default.gray(`\n${t('messages.fill.previewStart')}`));
|
|
673
|
-
console.log(updatedContent.trim());
|
|
674
|
-
console.log(chalk_1.default.gray(`${t('messages.fill.previewEnd')}\n`));
|
|
675
|
-
results.push({ file: planRelativePath, status: 'skipped', message: 'dry-run' });
|
|
676
|
-
}
|
|
677
|
-
else {
|
|
678
|
-
await fs.writeFile(planPath, ensureTrailingNewline(updatedContent));
|
|
679
|
-
ui.updateSpinner(t('spinner.planFill.updated', { path: planRelativePath }), 'success');
|
|
680
|
-
results.push({ file: planRelativePath, status: 'updated' });
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
catch (error) {
|
|
684
|
-
ui.updateSpinner(t('spinner.planFill.failed'), 'fail');
|
|
685
|
-
results.push({
|
|
686
|
-
file: planRelativePath,
|
|
687
|
-
status: 'failed',
|
|
688
|
-
message: error instanceof Error ? error.message : String(error)
|
|
689
|
-
});
|
|
690
|
-
}
|
|
691
|
-
finally {
|
|
692
|
-
ui.stopSpinner();
|
|
693
|
-
}
|
|
694
|
-
ui.displayStep(3, 3, t('steps.plan.summaryResults'));
|
|
695
|
-
printLlmSummary(llmClient.getUsageStats(), results, Boolean(rawOptions.dryRun));
|
|
696
|
-
ui.displaySuccess(t('success.plan.filled'));
|
|
697
|
-
}
|
|
698
|
-
async function ensureDirectoryExists(dir, message) {
|
|
699
|
-
const exists = await fs.pathExists(dir);
|
|
700
|
-
if (!exists) {
|
|
701
|
-
throw new Error(message);
|
|
702
|
-
}
|
|
703
|
-
}
|
|
704
|
-
async function collectTargets(docsDir, agentsDir, processAll, limit, docAllowlist, agentAllowlist) {
|
|
705
|
-
const docFiles = await (0, glob_1.glob)('**/*.md', { cwd: docsDir, absolute: true });
|
|
706
|
-
const agentFiles = await (0, glob_1.glob)('**/*.md', { cwd: agentsDir, absolute: true });
|
|
707
|
-
const candidates = [...docFiles, ...agentFiles];
|
|
708
|
-
const targets = [];
|
|
709
|
-
for (const fullPath of candidates) {
|
|
710
|
-
const content = await fs.readFile(fullPath, 'utf-8');
|
|
711
|
-
const hasMarkers = /<!--\s*ai-task:/.test(content) || /<!--\s*ai-slot:/.test(content) || /TODO/.test(content);
|
|
712
|
-
const isAgent = fullPath.includes(`${path.sep}agents${path.sep}`);
|
|
713
|
-
const fileName = path.basename(fullPath);
|
|
714
|
-
if (isAgent) {
|
|
715
|
-
if (agentAllowlist && !agentAllowlist.has(fileName)) {
|
|
716
|
-
continue;
|
|
717
|
-
}
|
|
718
|
-
}
|
|
719
|
-
else {
|
|
720
|
-
if (docAllowlist && !docAllowlist.has(fileName)) {
|
|
721
|
-
continue;
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
const explicitSelection = isAgent ? !!agentAllowlist : !!docAllowlist;
|
|
725
|
-
const shouldInclude = processAll ||
|
|
726
|
-
hasMarkers ||
|
|
727
|
-
(explicitSelection && (isAgent ? agentAllowlist.has(fileName) : docAllowlist.has(fileName)));
|
|
728
|
-
if (!shouldInclude) {
|
|
729
|
-
continue;
|
|
730
|
-
}
|
|
731
|
-
targets.push({ fullPath, hasMarkers, isAgent });
|
|
732
|
-
if (limit && targets.length >= limit) {
|
|
733
|
-
break;
|
|
734
|
-
}
|
|
735
|
-
}
|
|
736
|
-
return targets;
|
|
737
|
-
}
|
|
738
|
-
function buildContextSummary(repoStructure) {
|
|
739
|
-
const directories = new Set();
|
|
740
|
-
repoStructure.directories.forEach(dir => {
|
|
741
|
-
const [first] = dir.relativePath.split(/[\\/]/).filter(Boolean);
|
|
742
|
-
if (first) {
|
|
743
|
-
directories.add(first);
|
|
744
|
-
}
|
|
745
|
-
});
|
|
746
|
-
const topDirs = Array.from(directories).sort().slice(0, 12);
|
|
747
|
-
const totalSizeMb = (repoStructure.totalSize / (1024 * 1024)).toFixed(2);
|
|
748
|
-
return [
|
|
749
|
-
`Top-level directories: ${topDirs.length ? topDirs.join(', ') : 'n/a'}`,
|
|
750
|
-
`Total files scanned: ${repoStructure.totalFiles}`,
|
|
751
|
-
`Repository size (approx.): ${totalSizeMb} MB`
|
|
752
|
-
].join('\n');
|
|
753
|
-
}
|
|
754
|
-
function buildUserPrompt(relativePath, currentContent, contextSummary, isAgent) {
|
|
755
|
-
const guidance = [
|
|
756
|
-
'- Preserve YAML front matter and existing `ai-task` sections.',
|
|
757
|
-
'- Replace TODOs and resolve `ai-slot` placeholders with concrete information.',
|
|
758
|
-
'- Ensure success criteria in the front matter are satisfied.',
|
|
759
|
-
'- Return only the full updated Markdown for this file.'
|
|
760
|
-
];
|
|
761
|
-
if (isAgent) {
|
|
762
|
-
guidance.push('- Keep agent responsibilities, best practices, and documentation touchpoints aligned with the latest docs.');
|
|
763
|
-
}
|
|
764
|
-
else {
|
|
765
|
-
guidance.push('- Maintain accurate cross-links between docs and referenced resources.');
|
|
766
|
-
}
|
|
767
|
-
return [
|
|
768
|
-
`Target file: ${relativePath}`,
|
|
769
|
-
'Repository summary:',
|
|
770
|
-
contextSummary,
|
|
771
|
-
'',
|
|
772
|
-
'Guidance:',
|
|
773
|
-
...guidance,
|
|
774
|
-
'',
|
|
775
|
-
'Current content:',
|
|
776
|
-
'<file>',
|
|
777
|
-
currentContent,
|
|
778
|
-
'</file>'
|
|
779
|
-
].join('\n');
|
|
780
|
-
}
|
|
781
|
-
function buildPlanUserPrompt(context) {
|
|
782
|
-
const guidance = [
|
|
783
|
-
'- Preserve the YAML front matter and `ai-task` wrapper already in the plan.',
|
|
784
|
-
'- Replace TODOs with concrete steps that align with the provided documentation and agent playbooks.',
|
|
785
|
-
'- Keep the Agent Lineup and Documentation Touchpoints tables accurate and sorted.',
|
|
786
|
-
'- Ensure the work is segmented into phases, each with numbered steps, named owners, deliverables, evidence expectations, and a concluding Git commit checkpoint.',
|
|
787
|
-
'- Return only the full updated Markdown for this plan.'
|
|
788
|
-
];
|
|
789
|
-
const sections = [
|
|
790
|
-
`Target file: ${context.relativePath}`,
|
|
791
|
-
'Repository summary:',
|
|
792
|
-
context.contextSummary,
|
|
793
|
-
'',
|
|
794
|
-
'Guidance:',
|
|
795
|
-
...guidance,
|
|
796
|
-
'',
|
|
797
|
-
'Current plan:',
|
|
798
|
-
'<plan>',
|
|
799
|
-
context.planContent,
|
|
800
|
-
'</plan>'
|
|
801
|
-
];
|
|
802
|
-
if (context.docsIndex) {
|
|
803
|
-
sections.push('', 'Documentation index (docs/README.md):', '<docs-index>', context.docsIndex, '</docs-index>');
|
|
804
|
-
}
|
|
805
|
-
if (context.agentsIndex) {
|
|
806
|
-
sections.push('', 'Agent handbook (agents/README.md):', '<agents-index>', context.agentsIndex, '</agents-index>');
|
|
807
|
-
}
|
|
808
|
-
context.docs.forEach(doc => {
|
|
809
|
-
sections.push('', `Referenced documentation (${doc.path}):`, '<doc>', doc.content, '</doc>');
|
|
810
|
-
});
|
|
811
|
-
context.agents.forEach(agent => {
|
|
812
|
-
sections.push('', `Referenced agent playbook (${agent.path}):`, '<agent>', agent.content, '</agent>');
|
|
813
|
-
});
|
|
814
|
-
return sections.join('\n');
|
|
815
|
-
}
|
|
816
|
-
function extractPlanReferences(content, type) {
|
|
817
|
-
const regex = type === 'docs'
|
|
818
|
-
? /\]\(\.\.\/docs\/([^)#]+)(?:#[^)]*)?\)/g
|
|
819
|
-
: /\]\(\.\.\/agents\/([^)#]+)(?:#[^)]*)?\)/g;
|
|
820
|
-
const references = [];
|
|
821
|
-
let match;
|
|
822
|
-
while ((match = regex.exec(content)) !== null) {
|
|
823
|
-
const rawPath = match[1].trim();
|
|
824
|
-
if (!rawPath)
|
|
825
|
-
continue;
|
|
826
|
-
const normalized = rawPath.replace(/^\.\//, '').replace(/#.*$/, '');
|
|
827
|
-
if (!normalized || normalized.includes('..'))
|
|
828
|
-
continue;
|
|
829
|
-
if (!references.includes(normalized)) {
|
|
830
|
-
references.push(normalized);
|
|
831
|
-
}
|
|
832
|
-
}
|
|
833
|
-
return references;
|
|
834
|
-
}
|
|
835
|
-
async function loadReferencedMarkdown(baseDir, fileNames) {
|
|
836
|
-
const results = [];
|
|
837
|
-
const seen = new Set();
|
|
838
|
-
for (const name of fileNames) {
|
|
839
|
-
const cleanName = name.replace(/#.*$/, '');
|
|
840
|
-
if (!cleanName || seen.has(cleanName)) {
|
|
841
|
-
continue;
|
|
842
|
-
}
|
|
843
|
-
const normalized = path.normalize(cleanName).replace(/^\.\//, '');
|
|
844
|
-
if (normalized.includes('..')) {
|
|
845
|
-
continue;
|
|
846
|
-
}
|
|
847
|
-
const fullPath = path.join(baseDir, normalized);
|
|
848
|
-
if (!(await fs.pathExists(fullPath))) {
|
|
849
|
-
continue;
|
|
850
|
-
}
|
|
851
|
-
const content = await fs.readFile(fullPath, 'utf-8');
|
|
852
|
-
results.push({ path: normalized, content });
|
|
853
|
-
seen.add(cleanName);
|
|
854
|
-
}
|
|
855
|
-
return results;
|
|
856
|
-
}
|
|
857
|
-
function ensureTrailingNewline(content) {
|
|
858
|
-
return content.endsWith('\n') ? content : `${content}\n`;
|
|
859
|
-
}
|
|
860
|
-
function printLlmSummary(usage, results, dryRun) {
|
|
861
|
-
const updated = results.filter(r => r.status === 'updated').length;
|
|
862
|
-
const skipped = results.filter(r => r.status === 'skipped').length;
|
|
863
|
-
const failed = results.filter(r => r.status === 'failed');
|
|
864
|
-
console.log('\n' + chalk_1.default.bold('📄 LLM Fill Summary'));
|
|
865
|
-
console.log(chalk_1.default.gray('─'.repeat(50)));
|
|
866
|
-
console.log(`${chalk_1.default.blue('Updated files:')} ${chalk_1.default.white(updated.toString())}`);
|
|
867
|
-
console.log(`${chalk_1.default.blue('Skipped files:')} ${chalk_1.default.white(skipped.toString())}${dryRun ? chalk_1.default.gray(' (dry run)') : ''}`);
|
|
868
|
-
console.log(`${chalk_1.default.blue('Failures:')} ${failed.length}`);
|
|
869
|
-
if (usage.totalCalls > 0) {
|
|
870
|
-
console.log(chalk_1.default.gray('─'.repeat(50)));
|
|
871
|
-
console.log(`${chalk_1.default.blue('LLM calls:')} ${usage.totalCalls}`);
|
|
872
|
-
console.log(`${chalk_1.default.blue('Prompt tokens:')} ${usage.totalPromptTokens}`);
|
|
873
|
-
console.log(`${chalk_1.default.blue('Completion tokens:')} ${usage.totalCompletionTokens}`);
|
|
874
|
-
console.log(`${chalk_1.default.blue('Estimated cost:')} ${usage.estimatedCost.toFixed(4)}`);
|
|
875
|
-
console.log(`${chalk_1.default.blue('Model:')} ${usage.model}`);
|
|
876
|
-
}
|
|
877
|
-
if (failed.length > 0) {
|
|
878
|
-
console.log(chalk_1.default.gray('─'.repeat(50)));
|
|
879
|
-
failed.forEach(f => {
|
|
880
|
-
console.log(`${chalk_1.default.red('✖')} ${chalk_1.default.white(f.file)} — ${chalk_1.default.gray(f.message || 'Unknown error')}`);
|
|
881
|
-
});
|
|
882
|
-
}
|
|
883
|
-
}
|
|
884
|
-
function parseDocSelection(input) {
|
|
885
|
-
if (input === undefined) {
|
|
886
|
-
return { selected: undefined, invalid: [], provided: false, explicitNone: false };
|
|
887
|
-
}
|
|
888
|
-
if (Array.isArray(input) && input.length === 0) {
|
|
889
|
-
return { selected: [], invalid: [], provided: true, explicitNone: true };
|
|
890
|
-
}
|
|
891
|
-
const values = toStringArray(input);
|
|
892
|
-
const normalized = values.map(value => value.toLowerCase().replace(/\.md$/, ''));
|
|
893
|
-
const valid = Array.from(new Set(normalized.filter(key => guideRegistry_1.DOCUMENT_GUIDE_KEYS.includes(key))));
|
|
894
|
-
const invalid = normalized.filter(key => !guideRegistry_1.DOCUMENT_GUIDE_KEYS.includes(key));
|
|
895
|
-
if (values.length > 0 && valid.length === 0 && invalid.length > 0) {
|
|
896
|
-
return { selected: undefined, invalid, provided: true, explicitNone: false };
|
|
897
|
-
}
|
|
898
|
-
return { selected: valid.length > 0 ? valid : undefined, invalid, provided: true, explicitNone: false };
|
|
899
|
-
}
|
|
900
|
-
function parseAgentSelection(input) {
|
|
901
|
-
if (input === undefined) {
|
|
902
|
-
return { selected: undefined, invalid: [], provided: false, explicitNone: false };
|
|
903
|
-
}
|
|
904
|
-
if (Array.isArray(input) && input.length === 0) {
|
|
905
|
-
return { selected: [], invalid: [], provided: true, explicitNone: true };
|
|
906
|
-
}
|
|
907
|
-
const values = toStringArray(input);
|
|
908
|
-
const normalized = values.map(value => value.toLowerCase().replace(/\.md$/, ''));
|
|
909
|
-
const allowed = new Set(agentTypes_1.AGENT_TYPES);
|
|
910
|
-
const valid = Array.from(new Set(normalized.filter(value => allowed.has(value))));
|
|
911
|
-
const invalid = normalized.filter(value => !allowed.has(value));
|
|
912
|
-
if (values.length > 0 && valid.length === 0 && invalid.length > 0) {
|
|
913
|
-
return { selected: undefined, invalid, provided: true, explicitNone: false };
|
|
914
|
-
}
|
|
915
|
-
return { selected: valid.length > 0 ? valid : undefined, invalid, provided: true, explicitNone: false };
|
|
916
|
-
}
|
|
917
|
-
function shouldGenerateDocs(resolvedType, selection) {
|
|
918
|
-
if (selection.explicitNone) {
|
|
919
|
-
return false;
|
|
920
|
-
}
|
|
921
|
-
if (resolvedType === 'agents') {
|
|
922
|
-
return false;
|
|
923
|
-
}
|
|
924
|
-
if (!selection.provided) {
|
|
925
|
-
return resolvedType === 'docs' || resolvedType === 'both';
|
|
926
|
-
}
|
|
927
|
-
if (selection.selected && selection.selected.length === 0) {
|
|
928
|
-
return false;
|
|
929
|
-
}
|
|
930
|
-
return resolvedType === 'docs' || resolvedType === 'both';
|
|
931
|
-
}
|
|
932
|
-
function shouldGenerateAgents(resolvedType, selection) {
|
|
933
|
-
if (selection.explicitNone) {
|
|
934
|
-
return false;
|
|
935
|
-
}
|
|
936
|
-
if (resolvedType === 'docs') {
|
|
937
|
-
return false;
|
|
938
|
-
}
|
|
939
|
-
if (!selection.provided) {
|
|
940
|
-
return resolvedType === 'agents' || resolvedType === 'both';
|
|
941
|
-
}
|
|
942
|
-
if (selection.selected && selection.selected.length === 0) {
|
|
943
|
-
return false;
|
|
944
|
-
}
|
|
945
|
-
return resolvedType === 'agents' || resolvedType === 'both';
|
|
946
|
-
}
|
|
947
|
-
function toStringArray(input) {
|
|
948
|
-
if (Array.isArray(input)) {
|
|
949
|
-
return input.map(item => item.toString().trim()).filter(Boolean);
|
|
950
|
-
}
|
|
951
|
-
if (input === null || input === undefined) {
|
|
952
|
-
return [];
|
|
953
|
-
}
|
|
954
|
-
return input
|
|
955
|
-
.toString()
|
|
956
|
-
.split(',')
|
|
957
|
-
.map((part) => part.trim())
|
|
958
|
-
.filter(Boolean);
|
|
959
|
-
}
|
|
960
|
-
function formatAgentLabel(value) {
|
|
961
|
-
return value
|
|
962
|
-
.split('-')
|
|
963
|
-
.map(segment => segment.charAt(0).toUpperCase() + segment.slice(1))
|
|
964
|
-
.join(' ');
|
|
324
|
+
await fillService.run(repoPath, rawOptions);
|
|
965
325
|
}
|
|
966
326
|
async function selectLocale(showWelcome) {
|
|
967
327
|
const { locale } = await inquirer_1.default.prompt([
|
|
@@ -980,7 +340,7 @@ async function selectLocale(showWelcome) {
|
|
|
980
340
|
currentLocale = normalizedLocale;
|
|
981
341
|
translateFn = (0, i18n_1.createTranslator)(normalizedLocale);
|
|
982
342
|
if (showWelcome) {
|
|
983
|
-
ui.displayWelcome(VERSION);
|
|
343
|
+
ui.displayWelcome(version_1.VERSION);
|
|
984
344
|
}
|
|
985
345
|
}
|
|
986
346
|
async function runInteractive() {
|
|
@@ -996,6 +356,7 @@ async function runInteractive() {
|
|
|
996
356
|
{ name: t('prompts.main.choice.scaffold'), value: 'scaffold' },
|
|
997
357
|
{ name: t('prompts.main.choice.fill'), value: 'fill' },
|
|
998
358
|
{ name: t('prompts.main.choice.plan'), value: 'plan' },
|
|
359
|
+
{ name: t('prompts.main.choice.syncAgents'), value: 'syncAgents' },
|
|
999
360
|
{ name: t('prompts.main.choice.changeLanguage'), value: 'changeLanguage' },
|
|
1000
361
|
{ name: t('prompts.main.choice.exit'), value: 'exit' }
|
|
1001
362
|
]
|
|
@@ -1015,9 +376,12 @@ async function runInteractive() {
|
|
|
1015
376
|
else if (action === 'fill') {
|
|
1016
377
|
await runInteractiveLlmFill();
|
|
1017
378
|
}
|
|
1018
|
-
else {
|
|
379
|
+
else if (action === 'plan') {
|
|
1019
380
|
await runInteractivePlan();
|
|
1020
381
|
}
|
|
382
|
+
else if (action === 'syncAgents') {
|
|
383
|
+
await runInteractiveSync();
|
|
384
|
+
}
|
|
1021
385
|
ui.displayInfo(t('info.interactive.returning.title'), t('info.interactive.returning.detail'));
|
|
1022
386
|
}
|
|
1023
387
|
ui.displaySuccess(t('success.interactive.goodbye'));
|
|
@@ -1041,58 +405,19 @@ async function runInteractiveScaffold() {
|
|
|
1041
405
|
default: defaultOutput
|
|
1042
406
|
}
|
|
1043
407
|
]);
|
|
1044
|
-
const {
|
|
1045
|
-
{
|
|
1046
|
-
type: 'confirm',
|
|
1047
|
-
name: 'includeDocs',
|
|
1048
|
-
message: t('prompts.scaffold.includeDocs'),
|
|
1049
|
-
default: true
|
|
1050
|
-
}
|
|
1051
|
-
]);
|
|
1052
|
-
let selectedDocs;
|
|
1053
|
-
if (includeDocs) {
|
|
1054
|
-
const { docs } = await inquirer_1.default.prompt([
|
|
1055
|
-
{
|
|
1056
|
-
type: 'checkbox',
|
|
1057
|
-
name: 'docs',
|
|
1058
|
-
message: t('prompts.scaffold.selectDocs'),
|
|
1059
|
-
choices: DOC_CHOICES,
|
|
1060
|
-
default: DOC_CHOICES.map(choice => choice.value)
|
|
1061
|
-
}
|
|
1062
|
-
]);
|
|
1063
|
-
selectedDocs = docs;
|
|
1064
|
-
}
|
|
1065
|
-
else {
|
|
1066
|
-
selectedDocs = [];
|
|
1067
|
-
}
|
|
1068
|
-
const { includeAgents } = await inquirer_1.default.prompt([
|
|
408
|
+
const { scaffoldType } = await inquirer_1.default.prompt([
|
|
1069
409
|
{
|
|
1070
|
-
type: '
|
|
1071
|
-
name: '
|
|
1072
|
-
message: t('prompts.scaffold.
|
|
1073
|
-
|
|
410
|
+
type: 'list',
|
|
411
|
+
name: 'scaffoldType',
|
|
412
|
+
message: t('prompts.scaffold.type'),
|
|
413
|
+
choices: [
|
|
414
|
+
{ name: t('prompts.scaffold.typeBoth'), value: 'both' },
|
|
415
|
+
{ name: t('prompts.scaffold.typeDocs'), value: 'docs' },
|
|
416
|
+
{ name: t('prompts.scaffold.typeAgents'), value: 'agents' }
|
|
417
|
+
],
|
|
418
|
+
default: 'both'
|
|
1074
419
|
}
|
|
1075
420
|
]);
|
|
1076
|
-
let selectedAgents;
|
|
1077
|
-
if (includeAgents) {
|
|
1078
|
-
const { agents } = await inquirer_1.default.prompt([
|
|
1079
|
-
{
|
|
1080
|
-
type: 'checkbox',
|
|
1081
|
-
name: 'agents',
|
|
1082
|
-
message: t('prompts.scaffold.selectAgents'),
|
|
1083
|
-
choices: AGENT_CHOICES,
|
|
1084
|
-
default: AGENT_CHOICES.map(choice => choice.value)
|
|
1085
|
-
}
|
|
1086
|
-
]);
|
|
1087
|
-
selectedAgents = agents;
|
|
1088
|
-
}
|
|
1089
|
-
else {
|
|
1090
|
-
selectedAgents = [];
|
|
1091
|
-
}
|
|
1092
|
-
if ((selectedDocs?.length ?? 0) === 0 && (selectedAgents?.length ?? 0) === 0) {
|
|
1093
|
-
ui.displayWarning(t('warnings.interactive.nothingSelected'));
|
|
1094
|
-
return;
|
|
1095
|
-
}
|
|
1096
421
|
const { verbose } = await inquirer_1.default.prompt([
|
|
1097
422
|
{
|
|
1098
423
|
type: 'confirm',
|
|
@@ -1101,30 +426,67 @@ async function runInteractiveScaffold() {
|
|
|
1101
426
|
default: false
|
|
1102
427
|
}
|
|
1103
428
|
]);
|
|
1104
|
-
const scaffoldType = determineScaffoldType(selectedDocs, selectedAgents);
|
|
1105
429
|
await runInit(resolvedRepo, scaffoldType, {
|
|
1106
430
|
output: outputDir,
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
verbose
|
|
431
|
+
verbose,
|
|
432
|
+
semantic: true
|
|
1110
433
|
});
|
|
1111
434
|
}
|
|
1112
|
-
function determineScaffoldType(docSelection, agentSelection) {
|
|
1113
|
-
const docsSelected = docSelection === undefined ? true : docSelection.length > 0;
|
|
1114
|
-
const agentsSelected = agentSelection === undefined ? true : agentSelection.length > 0;
|
|
1115
|
-
if (docsSelected && agentsSelected)
|
|
1116
|
-
return 'both';
|
|
1117
|
-
if (docsSelected)
|
|
1118
|
-
return 'docs';
|
|
1119
|
-
return 'agents';
|
|
1120
|
-
}
|
|
1121
435
|
async function runInteractiveLlmFill() {
|
|
436
|
+
const defaults = await (0, prompts_1.detectSmartDefaults)();
|
|
437
|
+
const interactiveMode = await (0, prompts_1.promptInteractiveMode)(t);
|
|
438
|
+
if (interactiveMode === 'quick') {
|
|
439
|
+
// Quick mode: minimal prompts with smart defaults
|
|
440
|
+
const { confirmRepo } = await inquirer_1.default.prompt([
|
|
441
|
+
{
|
|
442
|
+
type: 'confirm',
|
|
443
|
+
name: 'confirmRepo',
|
|
444
|
+
message: `${t('prompts.quick.confirmRepo')} (${defaults.repoPath})`,
|
|
445
|
+
default: true
|
|
446
|
+
}
|
|
447
|
+
]);
|
|
448
|
+
const resolvedRepo = confirmRepo ? defaults.repoPath : (await inquirer_1.default.prompt([
|
|
449
|
+
{ type: 'input', name: 'repoPath', message: t('prompts.fill.repoPath'), default: defaults.repoPath }
|
|
450
|
+
])).repoPath;
|
|
451
|
+
// Get LLM config (auto-detected or prompt for API key)
|
|
452
|
+
const llmConfig = await (0, prompts_1.promptLLMConfig)(t, { defaultModel: DEFAULT_MODEL, skipIfConfigured: true });
|
|
453
|
+
// Build summary
|
|
454
|
+
const summary = {
|
|
455
|
+
operation: 'fill',
|
|
456
|
+
repoPath: resolvedRepo,
|
|
457
|
+
outputDir: defaults.outputDir,
|
|
458
|
+
provider: llmConfig.provider,
|
|
459
|
+
model: llmConfig.model,
|
|
460
|
+
apiKeySource: llmConfig.autoDetected ? 'env' : llmConfig.apiKey ? 'provided' : 'none',
|
|
461
|
+
options: {
|
|
462
|
+
Semantic: true,
|
|
463
|
+
Languages: defaults.detectedLanguages.join(', '),
|
|
464
|
+
LSP: false
|
|
465
|
+
}
|
|
466
|
+
};
|
|
467
|
+
(0, prompts_1.displayConfigSummary)(summary, t);
|
|
468
|
+
const proceed = await (0, prompts_1.promptConfirmProceed)(t);
|
|
469
|
+
if (proceed) {
|
|
470
|
+
await fillService.run(resolvedRepo, {
|
|
471
|
+
output: defaults.outputDir,
|
|
472
|
+
model: llmConfig.model,
|
|
473
|
+
provider: llmConfig.provider,
|
|
474
|
+
apiKey: llmConfig.apiKey,
|
|
475
|
+
verbose: false,
|
|
476
|
+
semantic: true,
|
|
477
|
+
languages: defaults.detectedLanguages,
|
|
478
|
+
useLsp: false
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
// Advanced mode: full configuration
|
|
1122
484
|
const { repoPath } = await inquirer_1.default.prompt([
|
|
1123
485
|
{
|
|
1124
486
|
type: 'input',
|
|
1125
487
|
name: 'repoPath',
|
|
1126
488
|
message: t('prompts.fill.repoPath'),
|
|
1127
|
-
default:
|
|
489
|
+
default: defaults.repoPath
|
|
1128
490
|
}
|
|
1129
491
|
]);
|
|
1130
492
|
const resolvedRepo = path.resolve(repoPath.trim() || '.');
|
|
@@ -1144,20 +506,6 @@ async function runInteractiveLlmFill() {
|
|
|
1144
506
|
}
|
|
1145
507
|
]);
|
|
1146
508
|
const promptPath = promptPathInput.trim() ? path.resolve(promptPathInput.trim()) : undefined;
|
|
1147
|
-
const { dryRun, processAll } = await inquirer_1.default.prompt([
|
|
1148
|
-
{
|
|
1149
|
-
type: 'confirm',
|
|
1150
|
-
name: 'dryRun',
|
|
1151
|
-
message: t('prompts.fill.dryRun'),
|
|
1152
|
-
default: true
|
|
1153
|
-
},
|
|
1154
|
-
{
|
|
1155
|
-
type: 'confirm',
|
|
1156
|
-
name: 'processAll',
|
|
1157
|
-
message: t('prompts.fill.processAll'),
|
|
1158
|
-
default: false
|
|
1159
|
-
}
|
|
1160
|
-
]);
|
|
1161
509
|
const { limit } = await inquirer_1.default.prompt([
|
|
1162
510
|
{
|
|
1163
511
|
type: 'input',
|
|
@@ -1168,131 +516,49 @@ async function runInteractiveLlmFill() {
|
|
|
1168
516
|
]);
|
|
1169
517
|
const limitValue = limit ? parseInt(limit, 10) : undefined;
|
|
1170
518
|
const parsedLimit = Number.isNaN(limitValue) ? undefined : limitValue;
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
else {
|
|
1193
|
-
selectedDocs = [];
|
|
1194
|
-
}
|
|
1195
|
-
const { includeAgents } = await inquirer_1.default.prompt([
|
|
1196
|
-
{
|
|
1197
|
-
type: 'confirm',
|
|
1198
|
-
name: 'includeAgents',
|
|
1199
|
-
message: t('prompts.fill.includeAgents'),
|
|
1200
|
-
default: true
|
|
1201
|
-
}
|
|
1202
|
-
]);
|
|
1203
|
-
let selectedAgents;
|
|
1204
|
-
if (includeAgents) {
|
|
1205
|
-
const { agents } = await inquirer_1.default.prompt([
|
|
1206
|
-
{
|
|
1207
|
-
type: 'checkbox',
|
|
1208
|
-
name: 'agents',
|
|
1209
|
-
message: t('prompts.fill.selectAgents'),
|
|
1210
|
-
choices: AGENT_CHOICES,
|
|
1211
|
-
default: AGENT_CHOICES.map(choice => choice.value)
|
|
1212
|
-
}
|
|
1213
|
-
]);
|
|
1214
|
-
selectedAgents = agents;
|
|
1215
|
-
}
|
|
1216
|
-
else {
|
|
1217
|
-
selectedAgents = [];
|
|
1218
|
-
}
|
|
1219
|
-
if ((selectedDocs?.length ?? 0) === 0 && (selectedAgents?.length ?? 0) === 0) {
|
|
1220
|
-
ui.displayWarning(t('warnings.interactive.nothingSelected'));
|
|
1221
|
-
return;
|
|
1222
|
-
}
|
|
1223
|
-
const { specifyModel } = await inquirer_1.default.prompt([
|
|
1224
|
-
{
|
|
1225
|
-
type: 'confirm',
|
|
1226
|
-
name: 'specifyModel',
|
|
1227
|
-
message: t('prompts.fill.overrideModel'),
|
|
1228
|
-
default: false
|
|
1229
|
-
}
|
|
1230
|
-
]);
|
|
1231
|
-
let provider;
|
|
1232
|
-
let model;
|
|
1233
|
-
if (specifyModel) {
|
|
1234
|
-
const providerAnswer = await inquirer_1.default.prompt([
|
|
1235
|
-
{
|
|
1236
|
-
type: 'list',
|
|
1237
|
-
name: 'provider',
|
|
1238
|
-
message: t('prompts.fill.provider'),
|
|
1239
|
-
choices: ['openrouter', 'openai', 'anthropic', 'gemini', 'grok']
|
|
1240
|
-
}
|
|
1241
|
-
]);
|
|
1242
|
-
provider = providerAnswer.provider;
|
|
1243
|
-
const modelAnswer = await inquirer_1.default.prompt([
|
|
1244
|
-
{
|
|
1245
|
-
type: 'input',
|
|
1246
|
-
name: 'model',
|
|
1247
|
-
message: t('prompts.fill.model'),
|
|
1248
|
-
default: DEFAULT_MODEL
|
|
1249
|
-
}
|
|
1250
|
-
]);
|
|
1251
|
-
model = modelAnswer.model.trim();
|
|
1252
|
-
}
|
|
1253
|
-
const { provideApiKey } = await inquirer_1.default.prompt([
|
|
1254
|
-
{
|
|
1255
|
-
type: 'confirm',
|
|
1256
|
-
name: 'provideApiKey',
|
|
1257
|
-
message: t('prompts.fill.provideApiKey'),
|
|
1258
|
-
default: false
|
|
519
|
+
// Use shared LLM prompt helper
|
|
520
|
+
const llmConfig = await (0, prompts_1.promptLLMConfig)(t, { defaultModel: DEFAULT_MODEL, skipIfConfigured: false });
|
|
521
|
+
// Use shared analysis options prompt
|
|
522
|
+
const analysisOptions = await (0, prompts_1.promptAnalysisOptions)(t, {
|
|
523
|
+
languages: defaults.detectedLanguages,
|
|
524
|
+
useLsp: false
|
|
525
|
+
});
|
|
526
|
+
// Show summary before execution
|
|
527
|
+
const summary = {
|
|
528
|
+
operation: 'fill',
|
|
529
|
+
repoPath: resolvedRepo,
|
|
530
|
+
outputDir,
|
|
531
|
+
provider: llmConfig.provider,
|
|
532
|
+
model: llmConfig.model,
|
|
533
|
+
apiKeySource: llmConfig.autoDetected ? 'env' : llmConfig.apiKey ? 'provided' : 'none',
|
|
534
|
+
options: {
|
|
535
|
+
Semantic: analysisOptions.semantic,
|
|
536
|
+
Languages: analysisOptions.languages?.join(', ') || 'none',
|
|
537
|
+
LSP: analysisOptions.useLsp,
|
|
538
|
+
Verbose: analysisOptions.verbose,
|
|
539
|
+
...(parsedLimit ? { Limit: String(parsedLimit) } : {})
|
|
1259
540
|
}
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
541
|
+
};
|
|
542
|
+
(0, prompts_1.displayConfigSummary)(summary, t);
|
|
543
|
+
const proceed = await (0, prompts_1.promptConfirmProceed)(t);
|
|
544
|
+
if (proceed) {
|
|
545
|
+
await fillService.run(resolvedRepo, {
|
|
546
|
+
output: outputDir,
|
|
547
|
+
prompt: promptPath,
|
|
548
|
+
limit: parsedLimit,
|
|
549
|
+
model: llmConfig.model,
|
|
550
|
+
provider: llmConfig.provider,
|
|
551
|
+
apiKey: llmConfig.apiKey,
|
|
552
|
+
verbose: analysisOptions.verbose,
|
|
553
|
+
semantic: analysisOptions.semantic,
|
|
554
|
+
languages: analysisOptions.languages,
|
|
555
|
+
useLsp: analysisOptions.useLsp
|
|
556
|
+
});
|
|
1272
557
|
}
|
|
1273
|
-
const { verbose } = await inquirer_1.default.prompt([
|
|
1274
|
-
{
|
|
1275
|
-
type: 'confirm',
|
|
1276
|
-
name: 'verbose',
|
|
1277
|
-
message: t('prompts.common.verbose'),
|
|
1278
|
-
default: false
|
|
1279
|
-
}
|
|
1280
|
-
]);
|
|
1281
|
-
await runLlmFill(resolvedRepo, {
|
|
1282
|
-
output: outputDir,
|
|
1283
|
-
prompt: promptPath,
|
|
1284
|
-
docs: selectedDocs,
|
|
1285
|
-
agents: selectedAgents,
|
|
1286
|
-
dryRun,
|
|
1287
|
-
all: processAll,
|
|
1288
|
-
limit: parsedLimit,
|
|
1289
|
-
model,
|
|
1290
|
-
provider,
|
|
1291
|
-
apiKey,
|
|
1292
|
-
verbose
|
|
1293
|
-
});
|
|
1294
558
|
}
|
|
1295
559
|
async function runInteractivePlan() {
|
|
560
|
+
const defaults = await (0, prompts_1.detectSmartDefaults)();
|
|
561
|
+
// Always ask for plan name first
|
|
1296
562
|
const { planName } = await inquirer_1.default.prompt([
|
|
1297
563
|
{
|
|
1298
564
|
type: 'input',
|
|
@@ -1301,6 +567,82 @@ async function runInteractivePlan() {
|
|
|
1301
567
|
default: 'new-plan'
|
|
1302
568
|
}
|
|
1303
569
|
]);
|
|
570
|
+
const interactiveMode = await (0, prompts_1.promptInteractiveMode)(t);
|
|
571
|
+
if (interactiveMode === 'quick') {
|
|
572
|
+
// Quick mode: choose scaffold or fill with defaults
|
|
573
|
+
const { action } = await inquirer_1.default.prompt([
|
|
574
|
+
{
|
|
575
|
+
type: 'list',
|
|
576
|
+
name: 'action',
|
|
577
|
+
message: t('prompts.plan.mode'),
|
|
578
|
+
choices: [
|
|
579
|
+
{ name: t('prompts.plan.modeScaffold'), value: 'scaffold' },
|
|
580
|
+
{ name: t('prompts.plan.modeFill'), value: 'fill' }
|
|
581
|
+
],
|
|
582
|
+
default: 'scaffold'
|
|
583
|
+
}
|
|
584
|
+
]);
|
|
585
|
+
if (action === 'scaffold') {
|
|
586
|
+
// Quick scaffold: just create the template
|
|
587
|
+
const generator = new planGenerator_1.PlanGenerator();
|
|
588
|
+
ui.startSpinner(t('spinner.plan.creating'));
|
|
589
|
+
try {
|
|
590
|
+
const result = await generator.generatePlan({
|
|
591
|
+
planName,
|
|
592
|
+
outputDir: defaults.outputDir,
|
|
593
|
+
verbose: false,
|
|
594
|
+
semantic: true,
|
|
595
|
+
projectPath: defaults.repoPath
|
|
596
|
+
});
|
|
597
|
+
ui.updateSpinner(t('spinner.plan.created'), 'success');
|
|
598
|
+
ui.displaySuccess(t('success.plan.createdAt', { path: theme_1.colors.accent(result.relativePath) }));
|
|
599
|
+
}
|
|
600
|
+
catch (error) {
|
|
601
|
+
ui.updateSpinner(t('spinner.plan.creationFailed'), 'fail');
|
|
602
|
+
ui.displayError(t('errors.plan.creationFailed'), error);
|
|
603
|
+
}
|
|
604
|
+
finally {
|
|
605
|
+
ui.stopSpinner();
|
|
606
|
+
}
|
|
607
|
+
return;
|
|
608
|
+
}
|
|
609
|
+
// Quick fill: use auto-detected LLM config
|
|
610
|
+
const llmConfig = await (0, prompts_1.promptLLMConfig)(t, { defaultModel: DEFAULT_MODEL, skipIfConfigured: true });
|
|
611
|
+
const summary = {
|
|
612
|
+
operation: 'plan',
|
|
613
|
+
repoPath: defaults.repoPath,
|
|
614
|
+
outputDir: defaults.outputDir,
|
|
615
|
+
provider: llmConfig.provider,
|
|
616
|
+
model: llmConfig.model,
|
|
617
|
+
apiKeySource: llmConfig.autoDetected ? 'env' : llmConfig.apiKey ? 'provided' : 'none',
|
|
618
|
+
options: {
|
|
619
|
+
'Plan Name': planName,
|
|
620
|
+
LSP: true,
|
|
621
|
+
'Dry Run': false
|
|
622
|
+
}
|
|
623
|
+
};
|
|
624
|
+
(0, prompts_1.displayConfigSummary)(summary, t);
|
|
625
|
+
const proceed = await (0, prompts_1.promptConfirmProceed)(t);
|
|
626
|
+
if (proceed) {
|
|
627
|
+
try {
|
|
628
|
+
await planService.scaffoldPlanIfNeeded(planName, defaults.outputDir, {});
|
|
629
|
+
await planService.fillPlan(planName, {
|
|
630
|
+
output: defaults.outputDir,
|
|
631
|
+
repo: defaults.repoPath,
|
|
632
|
+
dryRun: false,
|
|
633
|
+
provider: llmConfig.provider,
|
|
634
|
+
model: llmConfig.model,
|
|
635
|
+
apiKey: llmConfig.apiKey,
|
|
636
|
+
lsp: true
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
catch (error) {
|
|
640
|
+
ui.displayError(t('errors.plan.fillFailed'), error);
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
return;
|
|
644
|
+
}
|
|
645
|
+
// Advanced mode: full configuration
|
|
1304
646
|
const defaultOutput = path.resolve(process.cwd(), '.context');
|
|
1305
647
|
const { mode } = await inquirer_1.default.prompt([
|
|
1306
648
|
{
|
|
@@ -1331,50 +673,6 @@ async function runInteractivePlan() {
|
|
|
1331
673
|
filter: (value) => value.trim()
|
|
1332
674
|
}
|
|
1333
675
|
]);
|
|
1334
|
-
const { includeAgents } = await inquirer_1.default.prompt([
|
|
1335
|
-
{
|
|
1336
|
-
type: 'confirm',
|
|
1337
|
-
name: 'includeAgents',
|
|
1338
|
-
message: t('prompts.plan.includeAgents'),
|
|
1339
|
-
default: true
|
|
1340
|
-
}
|
|
1341
|
-
]);
|
|
1342
|
-
let selectedAgents = [];
|
|
1343
|
-
if (includeAgents) {
|
|
1344
|
-
const { agents } = await inquirer_1.default.prompt([
|
|
1345
|
-
{
|
|
1346
|
-
type: 'checkbox',
|
|
1347
|
-
name: 'agents',
|
|
1348
|
-
message: t('prompts.plan.selectAgents'),
|
|
1349
|
-
choices: AGENT_CHOICES,
|
|
1350
|
-
default: AGENT_CHOICES.map(choice => choice.value)
|
|
1351
|
-
}
|
|
1352
|
-
]);
|
|
1353
|
-
selectedAgents = agents;
|
|
1354
|
-
}
|
|
1355
|
-
const { includeDocs } = await inquirer_1.default.prompt([
|
|
1356
|
-
{
|
|
1357
|
-
type: 'confirm',
|
|
1358
|
-
name: 'includeDocs',
|
|
1359
|
-
message: t('prompts.plan.includeDocs'),
|
|
1360
|
-
default: true
|
|
1361
|
-
}
|
|
1362
|
-
]);
|
|
1363
|
-
let selectedDocs = [];
|
|
1364
|
-
if (includeDocs) {
|
|
1365
|
-
const { docs } = await inquirer_1.default.prompt([
|
|
1366
|
-
{
|
|
1367
|
-
type: 'checkbox',
|
|
1368
|
-
name: 'docs',
|
|
1369
|
-
message: t('prompts.plan.selectDocs'),
|
|
1370
|
-
choices: DOC_CHOICES,
|
|
1371
|
-
default: DOC_CHOICES.map(choice => choice.value)
|
|
1372
|
-
}
|
|
1373
|
-
]);
|
|
1374
|
-
selectedDocs = docs;
|
|
1375
|
-
}
|
|
1376
|
-
const agentSelection = parseAgentSelection(selectedAgents);
|
|
1377
|
-
const docSelection = parseDocSelection(selectedDocs);
|
|
1378
676
|
const { repoPath } = await inquirer_1.default.prompt([
|
|
1379
677
|
{
|
|
1380
678
|
type: 'input',
|
|
@@ -1383,6 +681,8 @@ async function runInteractivePlan() {
|
|
|
1383
681
|
default: process.cwd()
|
|
1384
682
|
}
|
|
1385
683
|
]);
|
|
684
|
+
// Use shared LLM prompt helper
|
|
685
|
+
const llmConfig = await (0, prompts_1.promptLLMConfig)(t, { defaultModel: DEFAULT_MODEL, skipIfConfigured: false });
|
|
1386
686
|
const { dryRun } = await inquirer_1.default.prompt([
|
|
1387
687
|
{
|
|
1388
688
|
type: 'confirm',
|
|
@@ -1391,24 +691,53 @@ async function runInteractivePlan() {
|
|
|
1391
691
|
default: true
|
|
1392
692
|
}
|
|
1393
693
|
]);
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
}
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
694
|
+
const { useLsp } = await inquirer_1.default.prompt([
|
|
695
|
+
{
|
|
696
|
+
type: 'confirm',
|
|
697
|
+
name: 'useLsp',
|
|
698
|
+
message: t('prompts.plan.useLsp'),
|
|
699
|
+
default: true
|
|
700
|
+
}
|
|
701
|
+
]);
|
|
702
|
+
// Show summary before execution
|
|
703
|
+
const configSummary = {
|
|
704
|
+
operation: 'plan',
|
|
705
|
+
repoPath,
|
|
706
|
+
outputDir,
|
|
707
|
+
provider: llmConfig.provider,
|
|
708
|
+
model: llmConfig.model,
|
|
709
|
+
apiKeySource: llmConfig.autoDetected ? 'env' : llmConfig.apiKey ? 'provided' : 'none',
|
|
710
|
+
options: {
|
|
711
|
+
'Plan Name': planName,
|
|
712
|
+
LSP: useLsp,
|
|
713
|
+
'Dry Run': dryRun
|
|
714
|
+
}
|
|
715
|
+
};
|
|
716
|
+
(0, prompts_1.displayConfigSummary)(configSummary, t);
|
|
717
|
+
const proceed = await (0, prompts_1.promptConfirmProceed)(t);
|
|
718
|
+
if (proceed) {
|
|
719
|
+
try {
|
|
720
|
+
const resolvedOutput = path.resolve(outputDir.trim() || defaultOutput);
|
|
721
|
+
await planService.scaffoldPlanIfNeeded(planName, resolvedOutput, {
|
|
722
|
+
summary: summary || undefined
|
|
723
|
+
});
|
|
724
|
+
await planService.fillPlan(planName, {
|
|
725
|
+
output: resolvedOutput,
|
|
726
|
+
repo: repoPath,
|
|
727
|
+
dryRun,
|
|
728
|
+
provider: llmConfig.provider,
|
|
729
|
+
model: llmConfig.model,
|
|
730
|
+
apiKey: llmConfig.apiKey,
|
|
731
|
+
lsp: useLsp
|
|
732
|
+
});
|
|
733
|
+
}
|
|
734
|
+
catch (error) {
|
|
735
|
+
ui.displayError(t('errors.plan.fillFailed'), error);
|
|
736
|
+
}
|
|
1409
737
|
}
|
|
1410
738
|
return;
|
|
1411
739
|
}
|
|
740
|
+
// Scaffold mode
|
|
1412
741
|
const { summary } = await inquirer_1.default.prompt([
|
|
1413
742
|
{
|
|
1414
743
|
type: 'input',
|
|
@@ -1417,48 +746,6 @@ async function runInteractivePlan() {
|
|
|
1417
746
|
filter: (value) => value.trim()
|
|
1418
747
|
}
|
|
1419
748
|
]);
|
|
1420
|
-
const { includeAgents } = await inquirer_1.default.prompt([
|
|
1421
|
-
{
|
|
1422
|
-
type: 'confirm',
|
|
1423
|
-
name: 'includeAgents',
|
|
1424
|
-
message: t('prompts.plan.includeAgents'),
|
|
1425
|
-
default: true
|
|
1426
|
-
}
|
|
1427
|
-
]);
|
|
1428
|
-
let selectedAgents = null;
|
|
1429
|
-
if (includeAgents) {
|
|
1430
|
-
const { agents } = await inquirer_1.default.prompt([
|
|
1431
|
-
{
|
|
1432
|
-
type: 'checkbox',
|
|
1433
|
-
name: 'agents',
|
|
1434
|
-
message: t('prompts.plan.selectAgents'),
|
|
1435
|
-
choices: AGENT_CHOICES,
|
|
1436
|
-
default: AGENT_CHOICES.map(choice => choice.value)
|
|
1437
|
-
}
|
|
1438
|
-
]);
|
|
1439
|
-
selectedAgents = agents.length > 0 ? agents : null;
|
|
1440
|
-
}
|
|
1441
|
-
const { includeDocs } = await inquirer_1.default.prompt([
|
|
1442
|
-
{
|
|
1443
|
-
type: 'confirm',
|
|
1444
|
-
name: 'includeDocs',
|
|
1445
|
-
message: t('prompts.plan.includeDocs'),
|
|
1446
|
-
default: true
|
|
1447
|
-
}
|
|
1448
|
-
]);
|
|
1449
|
-
let selectedDocs = null;
|
|
1450
|
-
if (includeDocs) {
|
|
1451
|
-
const { docs } = await inquirer_1.default.prompt([
|
|
1452
|
-
{
|
|
1453
|
-
type: 'checkbox',
|
|
1454
|
-
name: 'docs',
|
|
1455
|
-
message: t('prompts.plan.selectDocs'),
|
|
1456
|
-
choices: DOC_CHOICES,
|
|
1457
|
-
default: DOC_CHOICES.map(choice => choice.value)
|
|
1458
|
-
}
|
|
1459
|
-
]);
|
|
1460
|
-
selectedDocs = docs.length > 0 ? docs : null;
|
|
1461
|
-
}
|
|
1462
749
|
const generator = new planGenerator_1.PlanGenerator();
|
|
1463
750
|
ui.startSpinner(t('spinner.plan.creating'));
|
|
1464
751
|
try {
|
|
@@ -1466,12 +753,12 @@ async function runInteractivePlan() {
|
|
|
1466
753
|
planName,
|
|
1467
754
|
outputDir: path.resolve(outputDir.trim() || defaultOutput),
|
|
1468
755
|
summary: summary || undefined,
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
756
|
+
verbose: false,
|
|
757
|
+
semantic: true,
|
|
758
|
+
projectPath: path.resolve(outputDir.trim() || defaultOutput, '..')
|
|
1472
759
|
});
|
|
1473
760
|
ui.updateSpinner(t('spinner.plan.created'), 'success');
|
|
1474
|
-
ui.displaySuccess(t('success.plan.createdAt', { path:
|
|
761
|
+
ui.displaySuccess(t('success.plan.createdAt', { path: theme_1.colors.accent(result.relativePath) }));
|
|
1475
762
|
}
|
|
1476
763
|
catch (error) {
|
|
1477
764
|
ui.updateSpinner(t('spinner.plan.creationFailed'), 'fail');
|
|
@@ -1481,15 +768,81 @@ async function runInteractivePlan() {
|
|
|
1481
768
|
ui.stopSpinner();
|
|
1482
769
|
}
|
|
1483
770
|
}
|
|
1484
|
-
function
|
|
1485
|
-
|
|
1486
|
-
|
|
771
|
+
async function runInteractiveSync() {
|
|
772
|
+
const defaults = await (0, prompts_1.detectSmartDefaults)();
|
|
773
|
+
const defaultSource = path.resolve(defaults.repoPath, '.context/agents');
|
|
774
|
+
// Simplified: single prompt for target selection with common presets
|
|
775
|
+
const { quickTarget } = await inquirer_1.default.prompt([
|
|
776
|
+
{
|
|
777
|
+
type: 'list',
|
|
778
|
+
name: 'quickTarget',
|
|
779
|
+
message: t('prompts.sync.quickTarget'),
|
|
780
|
+
choices: [
|
|
781
|
+
{ name: t('prompts.sync.quickTarget.common'), value: 'common' },
|
|
782
|
+
{ name: t('prompts.sync.quickTarget.claude'), value: 'claude' },
|
|
783
|
+
{ name: t('prompts.sync.quickTarget.all'), value: 'all' },
|
|
784
|
+
{ name: t('prompts.sync.quickTarget.custom'), value: 'custom' }
|
|
785
|
+
],
|
|
786
|
+
default: 'common'
|
|
787
|
+
}
|
|
788
|
+
]);
|
|
789
|
+
let preset;
|
|
790
|
+
let target;
|
|
791
|
+
let sourcePath = defaultSource;
|
|
792
|
+
if (quickTarget === 'custom') {
|
|
793
|
+
// Custom path: ask for source and target
|
|
794
|
+
const answers = await inquirer_1.default.prompt([
|
|
795
|
+
{
|
|
796
|
+
type: 'input',
|
|
797
|
+
name: 'sourcePath',
|
|
798
|
+
message: t('prompts.sync.source'),
|
|
799
|
+
default: defaultSource
|
|
800
|
+
},
|
|
801
|
+
{
|
|
802
|
+
type: 'input',
|
|
803
|
+
name: 'customPath',
|
|
804
|
+
message: t('prompts.sync.customPath')
|
|
805
|
+
}
|
|
806
|
+
]);
|
|
807
|
+
sourcePath = answers.sourcePath;
|
|
808
|
+
target = [answers.customPath];
|
|
809
|
+
}
|
|
810
|
+
else if (quickTarget === 'common') {
|
|
811
|
+
// Common: Claude + GitHub - use explicit target paths instead of preset
|
|
812
|
+
target = [
|
|
813
|
+
path.resolve(defaults.repoPath, '.claude/agents'),
|
|
814
|
+
path.resolve(defaults.repoPath, '.github/agents')
|
|
815
|
+
];
|
|
816
|
+
}
|
|
817
|
+
else {
|
|
818
|
+
preset = quickTarget;
|
|
819
|
+
}
|
|
820
|
+
// Show summary
|
|
821
|
+
const summary = {
|
|
822
|
+
operation: 'sync',
|
|
823
|
+
repoPath: sourcePath,
|
|
824
|
+
options: {
|
|
825
|
+
Target: quickTarget === 'custom' ? (target?.[0] || 'custom') : quickTarget,
|
|
826
|
+
Mode: 'symlink'
|
|
827
|
+
}
|
|
828
|
+
};
|
|
829
|
+
(0, prompts_1.displayConfigSummary)(summary, t);
|
|
830
|
+
const proceed = await (0, prompts_1.promptConfirmProceed)(t);
|
|
831
|
+
if (proceed) {
|
|
832
|
+
try {
|
|
833
|
+
await syncService.run({
|
|
834
|
+
source: sourcePath,
|
|
835
|
+
mode: 'symlink',
|
|
836
|
+
preset: preset,
|
|
837
|
+
target,
|
|
838
|
+
force: false,
|
|
839
|
+
dryRun: false
|
|
840
|
+
});
|
|
841
|
+
}
|
|
842
|
+
catch (error) {
|
|
843
|
+
ui.displayError(t('errors.sync.failed'), error);
|
|
844
|
+
}
|
|
1487
845
|
}
|
|
1488
|
-
const allowed = new Set(agentTypes_1.AGENT_TYPES);
|
|
1489
|
-
const files = types
|
|
1490
|
-
.filter(type => allowed.has(type))
|
|
1491
|
-
.map(type => `${type}.md`);
|
|
1492
|
-
return files.length ? new Set(files) : undefined;
|
|
1493
846
|
}
|
|
1494
847
|
function filterOutLocaleArgs(args) {
|
|
1495
848
|
const filtered = [];
|
|
@@ -1516,10 +869,43 @@ async function main() {
|
|
|
1516
869
|
}
|
|
1517
870
|
await program.parseAsync(process.argv);
|
|
1518
871
|
}
|
|
872
|
+
/**
|
|
873
|
+
* Check if an error is from user interrupt (Ctrl+C)
|
|
874
|
+
*/
|
|
875
|
+
function isUserInterrupt(error) {
|
|
876
|
+
if (error instanceof Error) {
|
|
877
|
+
// Inquirer's ExitPromptError when user presses Ctrl+C
|
|
878
|
+
if (error.name === 'ExitPromptError')
|
|
879
|
+
return true;
|
|
880
|
+
// Check message patterns
|
|
881
|
+
if (error.message.includes('force closed'))
|
|
882
|
+
return true;
|
|
883
|
+
if (error.message.includes('User force closed'))
|
|
884
|
+
return true;
|
|
885
|
+
}
|
|
886
|
+
return false;
|
|
887
|
+
}
|
|
888
|
+
/**
|
|
889
|
+
* Handle graceful exit
|
|
890
|
+
*/
|
|
891
|
+
function handleGracefulExit() {
|
|
892
|
+
console.log('');
|
|
893
|
+
ui.displaySuccess(t('success.interactive.goodbye'));
|
|
894
|
+
process.exit(0);
|
|
895
|
+
}
|
|
896
|
+
// Handle SIGINT (Ctrl+C) at process level
|
|
897
|
+
process.on('SIGINT', () => {
|
|
898
|
+
handleGracefulExit();
|
|
899
|
+
});
|
|
1519
900
|
if (require.main === module) {
|
|
1520
901
|
main().catch(error => {
|
|
1521
|
-
|
|
1522
|
-
|
|
902
|
+
if (isUserInterrupt(error)) {
|
|
903
|
+
handleGracefulExit();
|
|
904
|
+
}
|
|
905
|
+
else {
|
|
906
|
+
ui.displayError(t('errors.cli.executionFailed'), error);
|
|
907
|
+
process.exit(1);
|
|
908
|
+
}
|
|
1523
909
|
});
|
|
1524
910
|
}
|
|
1525
911
|
//# sourceMappingURL=index.js.map
|