mcoda 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -2
- package/README.md +9 -300
- package/dist/bin/McodaEntrypoint.d.ts +5 -0
- package/dist/bin/McodaEntrypoint.d.ts.map +1 -0
- package/dist/bin/McodaEntrypoint.js +175 -0
- package/dist/commands/agents/AgentsCommands.d.ts +4 -0
- package/dist/commands/agents/AgentsCommands.d.ts.map +1 -0
- package/dist/commands/agents/AgentsCommands.js +376 -0
- package/dist/commands/agents/GatewayAgentCommand.d.ts +4 -0
- package/dist/commands/agents/GatewayAgentCommand.d.ts.map +1 -0
- package/dist/commands/agents/GatewayAgentCommand.js +583 -0
- package/dist/commands/agents/TestAgentCommand.d.ts +4 -0
- package/dist/commands/agents/TestAgentCommand.d.ts.map +1 -0
- package/dist/commands/agents/TestAgentCommand.js +57 -0
- package/dist/commands/backlog/BacklogCommands.d.ts +17 -0
- package/dist/commands/backlog/BacklogCommands.d.ts.map +1 -0
- package/dist/commands/backlog/BacklogCommands.js +260 -0
- package/dist/commands/backlog/OrderTasksCommand.d.ts +16 -0
- package/dist/commands/backlog/OrderTasksCommand.d.ts.map +1 -0
- package/dist/commands/backlog/OrderTasksCommand.js +211 -0
- package/dist/commands/backlog/TaskShowCommands.d.ts +16 -0
- package/dist/commands/backlog/TaskShowCommands.d.ts.map +1 -0
- package/dist/commands/backlog/TaskShowCommands.js +275 -0
- package/dist/commands/docs/DocsCommands.d.ts +37 -0
- package/dist/commands/docs/DocsCommands.d.ts.map +1 -0
- package/dist/commands/docs/DocsCommands.js +381 -0
- package/dist/commands/estimate/EstimateCommands.d.ts +24 -0
- package/dist/commands/estimate/EstimateCommands.d.ts.map +1 -0
- package/dist/commands/estimate/EstimateCommands.js +259 -0
- package/dist/commands/jobs/JobsCommands.d.ts +24 -0
- package/dist/commands/jobs/JobsCommands.d.ts.map +1 -0
- package/dist/commands/jobs/JobsCommands.js +535 -0
- package/dist/commands/openapi/OpenapiCommands.d.ts +14 -0
- package/dist/commands/openapi/OpenapiCommands.d.ts.map +1 -0
- package/dist/commands/openapi/OpenapiCommands.js +157 -0
- package/dist/commands/planning/CreateTasksCommand.d.ts +17 -0
- package/dist/commands/planning/CreateTasksCommand.d.ts.map +1 -0
- package/dist/commands/planning/CreateTasksCommand.js +134 -0
- package/dist/commands/planning/MigrateTasksCommand.d.ts +15 -0
- package/dist/commands/planning/MigrateTasksCommand.d.ts.map +1 -0
- package/dist/commands/planning/MigrateTasksCommand.js +95 -0
- package/dist/commands/planning/PlanningCommands.d.ts +3 -0
- package/dist/commands/planning/PlanningCommands.d.ts.map +1 -0
- package/dist/commands/planning/PlanningCommands.js +2 -0
- package/dist/commands/planning/QaTasksCommand.d.ts +30 -0
- package/dist/commands/planning/QaTasksCommand.d.ts.map +1 -0
- package/dist/commands/planning/QaTasksCommand.js +293 -0
- package/dist/commands/planning/RefineTasksCommand.d.ts +30 -0
- package/dist/commands/planning/RefineTasksCommand.d.ts.map +1 -0
- package/dist/commands/planning/RefineTasksCommand.js +365 -0
- package/dist/commands/review/CodeReviewCommand.d.ts +21 -0
- package/dist/commands/review/CodeReviewCommand.d.ts.map +1 -0
- package/dist/commands/review/CodeReviewCommand.js +236 -0
- package/dist/commands/routing/RoutingCommands.d.ts +7 -0
- package/dist/commands/routing/RoutingCommands.d.ts.map +1 -0
- package/dist/commands/routing/RoutingCommands.js +484 -0
- package/dist/commands/telemetry/TelemetryCommands.d.ts +26 -0
- package/dist/commands/telemetry/TelemetryCommands.d.ts.map +1 -0
- package/dist/commands/telemetry/TelemetryCommands.js +313 -0
- package/dist/commands/update/UpdateCommands.d.ts +4 -0
- package/dist/commands/update/UpdateCommands.d.ts.map +1 -0
- package/dist/commands/update/UpdateCommands.js +280 -0
- package/dist/commands/work/WorkOnTasksCommand.d.ts +21 -0
- package/dist/commands/work/WorkOnTasksCommand.d.ts.map +1 -0
- package/dist/commands/work/WorkOnTasksCommand.js +238 -0
- package/dist/commands/workspace/SetWorkspaceCommand.d.ts +9 -0
- package/dist/commands/workspace/SetWorkspaceCommand.d.ts.map +1 -0
- package/dist/commands/workspace/SetWorkspaceCommand.js +128 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/package.json +31 -16
- package/.editorconfig +0 -9
- package/.eslintrc.cjs +0 -12
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -29
- package/.github/ISSUE_TEMPLATE/config.yml +0 -5
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -19
- package/.github/workflows/ci.yml +0 -37
- package/.github/workflows/nightly.yml +0 -38
- package/.github/workflows/release-dry-run.yml +0 -40
- package/.github/workflows/release-please.yml +0 -22
- package/.github/workflows/release.yml +0 -139
- package/.prettierrc +0 -5
- package/.release-please-manifest.json +0 -8
- package/CLA.md +0 -42
- package/CONTRIBUTING.md +0 -38
- package/docs/oss_publishing_plan.md +0 -41
- package/docs/pdr/.gitkeep +0 -0
- package/docs/quality_gates.md +0 -32
- package/docs/rfp/.gitkeep +0 -0
- package/docs/sds/sds.md +0 -11963
- package/docs/usage.md +0 -72
- package/openapi/gen-openapi.ts +0 -1
- package/openapi/generated/clients/.gitkeep +0 -0
- package/openapi/generated/types/.gitkeep +0 -0
- package/openapi/generated/types/index.ts +0 -118
- package/openapi/mcoda.yaml +0 -2063
- package/pack-mcoda.sh +0 -88
- package/packages/agents/CHANGELOG.md +0 -7
- package/packages/agents/LICENSE +0 -21
- package/packages/agents/README.md +0 -9
- package/packages/agents/package.json +0 -41
- package/packages/agents/src/AgentService/.gitkeep +0 -0
- package/packages/agents/src/AgentService/AgentService.d.ts +0 -21
- package/packages/agents/src/AgentService/AgentService.d.ts.map +0 -1
- package/packages/agents/src/AgentService/AgentService.js +0 -141
- package/packages/agents/src/AgentService/AgentService.ts +0 -308
- package/packages/agents/src/__tests__/AgentService.test.ts +0 -284
- package/packages/agents/src/adapters/AdapterTypes.d.ts +0 -29
- package/packages/agents/src/adapters/AdapterTypes.d.ts.map +0 -1
- package/packages/agents/src/adapters/AdapterTypes.js +0 -1
- package/packages/agents/src/adapters/AdapterTypes.ts +0 -32
- package/packages/agents/src/adapters/codex/.gitkeep +0 -0
- package/packages/agents/src/adapters/codex/CodexAdapter.d.ts +0 -11
- package/packages/agents/src/adapters/codex/CodexAdapter.d.ts.map +0 -1
- package/packages/agents/src/adapters/codex/CodexAdapter.js +0 -43
- package/packages/agents/src/adapters/codex/CodexAdapter.ts +0 -63
- package/packages/agents/src/adapters/codex/CodexCliRunner.ts +0 -154
- package/packages/agents/src/adapters/gemini/.gitkeep +0 -0
- package/packages/agents/src/adapters/gemini/GeminiAdapter.d.ts +0 -11
- package/packages/agents/src/adapters/gemini/GeminiAdapter.d.ts.map +0 -1
- package/packages/agents/src/adapters/gemini/GeminiAdapter.js +0 -42
- package/packages/agents/src/adapters/gemini/GeminiAdapter.ts +0 -58
- package/packages/agents/src/adapters/gemini/GeminiCliRunner.ts +0 -75
- package/packages/agents/src/adapters/local/.gitkeep +0 -0
- package/packages/agents/src/adapters/local/LocalAdapter.d.ts +0 -11
- package/packages/agents/src/adapters/local/LocalAdapter.d.ts.map +0 -1
- package/packages/agents/src/adapters/local/LocalAdapter.js +0 -38
- package/packages/agents/src/adapters/local/LocalAdapter.ts +0 -43
- package/packages/agents/src/adapters/ollama/OllamaCliAdapter.ts +0 -58
- package/packages/agents/src/adapters/ollama/OllamaCliRunner.ts +0 -70
- package/packages/agents/src/adapters/ollama/OllamaRemoteAdapter.ts +0 -205
- package/packages/agents/src/adapters/openai/.gitkeep +0 -0
- package/packages/agents/src/adapters/openai/OpenAiAdapter.d.ts +0 -11
- package/packages/agents/src/adapters/openai/OpenAiAdapter.d.ts.map +0 -1
- package/packages/agents/src/adapters/openai/OpenAiAdapter.js +0 -51
- package/packages/agents/src/adapters/openai/OpenAiAdapter.ts +0 -56
- package/packages/agents/src/adapters/openai/OpenAiCliAdapter.ts +0 -62
- package/packages/agents/src/adapters/qa/.gitkeep +0 -0
- package/packages/agents/src/adapters/qa/QaAdapter.d.ts +0 -11
- package/packages/agents/src/adapters/qa/QaAdapter.d.ts.map +0 -1
- package/packages/agents/src/adapters/qa/QaAdapter.js +0 -37
- package/packages/agents/src/adapters/qa/QaAdapter.ts +0 -42
- package/packages/agents/src/adapters/zhipu/ZhipuApiAdapter.ts +0 -273
- package/packages/agents/src/index.d.ts +0 -8
- package/packages/agents/src/index.d.ts.map +0 -1
- package/packages/agents/src/index.js +0 -7
- package/packages/agents/src/index.ts +0 -11
- package/packages/agents/tsconfig.json +0 -14
- package/packages/cli/CHANGELOG.md +0 -7
- package/packages/cli/LICENSE +0 -21
- package/packages/cli/README.md +0 -23
- package/packages/cli/package.json +0 -61
- package/packages/cli/src/__tests__/AgentsCommands.test.ts +0 -137
- package/packages/cli/src/__tests__/BacklogCommands.test.ts +0 -40
- package/packages/cli/src/__tests__/CodeReviewCommand.test.ts +0 -594
- package/packages/cli/src/__tests__/CreateTasksCommand.test.ts +0 -40
- package/packages/cli/src/__tests__/DocsCommands.test.ts +0 -41
- package/packages/cli/src/__tests__/EstimateCommands.test.ts +0 -54
- package/packages/cli/src/__tests__/JobsCommands.behavior.test.ts +0 -311
- package/packages/cli/src/__tests__/JobsCommands.test.ts +0 -49
- package/packages/cli/src/__tests__/MigrateTasksCommand.test.ts +0 -36
- package/packages/cli/src/__tests__/OpenapiCommands.test.ts +0 -34
- package/packages/cli/src/__tests__/OrderTasksCommand.test.ts +0 -150
- package/packages/cli/src/__tests__/PlanningCommands.test.ts +0 -9
- package/packages/cli/src/__tests__/QaTasksCommand.test.ts +0 -58
- package/packages/cli/src/__tests__/RefineTasksCommand.test.ts +0 -63
- package/packages/cli/src/__tests__/RoutingCommands.test.ts +0 -302
- package/packages/cli/src/__tests__/SetWorkspaceCommand.test.ts +0 -18
- package/packages/cli/src/__tests__/TaskShowCommands.test.ts +0 -130
- package/packages/cli/src/__tests__/TelemetryCommands.test.ts +0 -35
- package/packages/cli/src/__tests__/TestAgentCommand.test.ts +0 -41
- package/packages/cli/src/__tests__/UpdateCommands.test.ts +0 -292
- package/packages/cli/src/__tests__/WorkOnTasksCommand.test.ts +0 -42
- package/packages/cli/src/bin/.gitkeep +0 -0
- package/packages/cli/src/bin/McodaEntrypoint.ts +0 -180
- package/packages/cli/src/commands/agents/.gitkeep +0 -0
- package/packages/cli/src/commands/agents/AgentsCommands.ts +0 -374
- package/packages/cli/src/commands/agents/GatewayAgentCommand.ts +0 -621
- package/packages/cli/src/commands/agents/TestAgentCommand.ts +0 -63
- package/packages/cli/src/commands/backlog/.gitkeep +0 -0
- package/packages/cli/src/commands/backlog/BacklogCommands.ts +0 -286
- package/packages/cli/src/commands/backlog/OrderTasksCommand.ts +0 -237
- package/packages/cli/src/commands/backlog/TaskShowCommands.ts +0 -289
- package/packages/cli/src/commands/docs/.gitkeep +0 -0
- package/packages/cli/src/commands/docs/DocsCommands.ts +0 -413
- package/packages/cli/src/commands/estimate/EstimateCommands.ts +0 -290
- package/packages/cli/src/commands/jobs/.gitkeep +0 -0
- package/packages/cli/src/commands/jobs/JobsCommands.ts +0 -595
- package/packages/cli/src/commands/openapi/OpenapiCommands.ts +0 -167
- package/packages/cli/src/commands/planning/.gitkeep +0 -0
- package/packages/cli/src/commands/planning/CreateTasksCommand.ts +0 -149
- package/packages/cli/src/commands/planning/MigrateTasksCommand.ts +0 -105
- package/packages/cli/src/commands/planning/PlanningCommands.ts +0 -1
- package/packages/cli/src/commands/planning/QaTasksCommand.ts +0 -320
- package/packages/cli/src/commands/planning/RefineTasksCommand.ts +0 -408
- package/packages/cli/src/commands/review/CodeReviewCommand.ts +0 -262
- package/packages/cli/src/commands/routing/.gitkeep +0 -0
- package/packages/cli/src/commands/routing/RoutingCommands.ts +0 -554
- package/packages/cli/src/commands/telemetry/.gitkeep +0 -0
- package/packages/cli/src/commands/telemetry/TelemetryCommands.ts +0 -348
- package/packages/cli/src/commands/update/.gitkeep +0 -0
- package/packages/cli/src/commands/update/UpdateCommands.ts +0 -301
- package/packages/cli/src/commands/work/WorkOnTasksCommand.ts +0 -264
- package/packages/cli/src/commands/workspace/SetWorkspaceCommand.ts +0 -132
- package/packages/cli/test/packaging_guardrails.test.js +0 -75
- package/packages/cli/tsconfig.json +0 -20
- package/packages/core/CHANGELOG.md +0 -7
- package/packages/core/LICENSE +0 -21
- package/packages/core/README.md +0 -9
- package/packages/core/package.json +0 -45
- package/packages/core/src/__tests__/SmokeClasses.test.ts +0 -32
- package/packages/core/src/api/AgentsApi.ts +0 -219
- package/packages/core/src/api/QaTasksApi.ts +0 -38
- package/packages/core/src/api/TasksApi.ts +0 -35
- package/packages/core/src/api/__tests__/AgentsApi.test.ts +0 -203
- package/packages/core/src/api/__tests__/QaTasksApi.test.ts +0 -51
- package/packages/core/src/api/__tests__/TasksApi.test.ts +0 -56
- package/packages/core/src/config/.gitkeep +0 -0
- package/packages/core/src/config/ConfigService.ts +0 -1
- package/packages/core/src/domain/dependencies/.gitkeep +0 -0
- package/packages/core/src/domain/dependencies/Dependency.ts +0 -1
- package/packages/core/src/domain/epics/.gitkeep +0 -0
- package/packages/core/src/domain/epics/Epic.ts +0 -1
- package/packages/core/src/domain/projects/.gitkeep +0 -0
- package/packages/core/src/domain/projects/Project.ts +0 -1
- package/packages/core/src/domain/tasks/.gitkeep +0 -0
- package/packages/core/src/domain/tasks/Task.ts +0 -1
- package/packages/core/src/domain/userStories/.gitkeep +0 -0
- package/packages/core/src/domain/userStories/UserStory.ts +0 -1
- package/packages/core/src/index.ts +0 -27
- package/packages/core/src/prompts/.gitkeep +0 -0
- package/packages/core/src/prompts/PdrPrompts.ts +0 -23
- package/packages/core/src/prompts/PromptLoader.ts +0 -1
- package/packages/core/src/prompts/SdsPrompts.ts +0 -47
- package/packages/core/src/services/agents/.gitkeep +0 -0
- package/packages/core/src/services/agents/AgentManagementService.ts +0 -1
- package/packages/core/src/services/agents/GatewayAgentService.ts +0 -956
- package/packages/core/src/services/agents/RoutingService.ts +0 -461
- package/packages/core/src/services/agents/__tests__/GatewayAgentService.test.ts +0 -72
- package/packages/core/src/services/agents/__tests__/RoutingService.test.ts +0 -267
- package/packages/core/src/services/agents/generated/RoutingApiClient.ts +0 -89
- package/packages/core/src/services/backlog/.gitkeep +0 -0
- package/packages/core/src/services/backlog/BacklogService.ts +0 -580
- package/packages/core/src/services/backlog/TaskOrderingService.ts +0 -868
- package/packages/core/src/services/backlog/__tests__/BacklogService.test.ts +0 -219
- package/packages/core/src/services/backlog/__tests__/TaskOrderingService.test.ts +0 -268
- package/packages/core/src/services/docs/.gitkeep +0 -0
- package/packages/core/src/services/docs/DocsService.ts +0 -1913
- package/packages/core/src/services/docs/__tests__/DocsService.test.ts +0 -350
- package/packages/core/src/services/estimate/EstimateService.ts +0 -111
- package/packages/core/src/services/estimate/VelocityService.ts +0 -272
- package/packages/core/src/services/estimate/__tests__/VelocityAndEstimate.test.ts +0 -209
- package/packages/core/src/services/estimate/types.ts +0 -41
- package/packages/core/src/services/execution/.gitkeep +0 -0
- package/packages/core/src/services/execution/ExecutionService.ts +0 -1
- package/packages/core/src/services/execution/QaFollowupService.ts +0 -289
- package/packages/core/src/services/execution/QaProfileService.ts +0 -160
- package/packages/core/src/services/execution/QaTasksService.ts +0 -1303
- package/packages/core/src/services/execution/TaskSelectionService.ts +0 -362
- package/packages/core/src/services/execution/TaskStateService.ts +0 -64
- package/packages/core/src/services/execution/WorkOnTasksService.ts +0 -2023
- package/packages/core/src/services/execution/__tests__/QaFollowupService.test.ts +0 -58
- package/packages/core/src/services/execution/__tests__/QaProfileService.test.ts +0 -49
- package/packages/core/src/services/execution/__tests__/QaTasksService.test.ts +0 -157
- package/packages/core/src/services/execution/__tests__/TaskSelectionService.test.ts +0 -179
- package/packages/core/src/services/execution/__tests__/TaskStateService.test.ts +0 -51
- package/packages/core/src/services/execution/__tests__/WorkOnTasksService.test.ts +0 -285
- package/packages/core/src/services/jobs/.gitkeep +0 -0
- package/packages/core/src/services/jobs/JobInsightsService.ts +0 -355
- package/packages/core/src/services/jobs/JobResumeService.ts +0 -119
- package/packages/core/src/services/jobs/JobService.ts +0 -648
- package/packages/core/src/services/jobs/JobsApiClient.ts +0 -113
- package/packages/core/src/services/jobs/__tests__/JobInsightsService.test.ts +0 -17
- package/packages/core/src/services/jobs/__tests__/JobResumeService.test.ts +0 -45
- package/packages/core/src/services/jobs/__tests__/JobService.test.ts +0 -44
- package/packages/core/src/services/openapi/OpenApiService.ts +0 -558
- package/packages/core/src/services/openapi/__tests__/OpenApiService.test.ts +0 -57
- package/packages/core/src/services/planning/.gitkeep +0 -0
- package/packages/core/src/services/planning/CreateTasksService.ts +0 -1280
- package/packages/core/src/services/planning/KeyHelpers.ts +0 -80
- package/packages/core/src/services/planning/PlanningService.ts +0 -1
- package/packages/core/src/services/planning/RefineTasksService.ts +0 -1552
- package/packages/core/src/services/planning/__tests__/CreateTasksService.test.ts +0 -288
- package/packages/core/src/services/planning/__tests__/KeyHelpers.test.ts +0 -16
- package/packages/core/src/services/planning/__tests__/RefineTasksService.test.ts +0 -172
- package/packages/core/src/services/review/CodeReviewService.ts +0 -1386
- package/packages/core/src/services/review/__tests__/CodeReviewService.test.ts +0 -89
- package/packages/core/src/services/system/SystemUpdateService.ts +0 -177
- package/packages/core/src/services/system/__tests__/SystemUpdateService.test.ts +0 -40
- package/packages/core/src/services/tasks/TaskApiResolver.ts +0 -37
- package/packages/core/src/services/tasks/TaskDetailService.ts +0 -494
- package/packages/core/src/services/tasks/__tests__/TaskApiResolver.test.ts +0 -41
- package/packages/core/src/services/tasks/__tests__/TaskDetailService.test.ts +0 -178
- package/packages/core/src/services/telemetry/.gitkeep +0 -0
- package/packages/core/src/services/telemetry/TelemetryService.ts +0 -515
- package/packages/core/src/services/telemetry/__tests__/TelemetryService.test.ts +0 -160
- package/packages/core/src/workspace/.gitkeep +0 -0
- package/packages/core/src/workspace/WorkspaceManager.ts +0 -234
- package/packages/core/tsconfig.json +0 -20
- package/packages/db/CHANGELOG.md +0 -7
- package/packages/db/LICENSE +0 -21
- package/packages/db/README.md +0 -9
- package/packages/db/package.json +0 -42
- package/packages/db/src/__tests__/GlobalRepository.test.ts +0 -109
- package/packages/db/src/__tests__/SchemaAlignment.test.ts +0 -80
- package/packages/db/src/__tests__/WorkspaceRepository.test.ts +0 -19
- package/packages/db/src/index.d.ts +0 -6
- package/packages/db/src/index.d.ts.map +0 -1
- package/packages/db/src/index.js +0 -5
- package/packages/db/src/index.ts +0 -6
- package/packages/db/src/migrations/global/.gitkeep +0 -0
- package/packages/db/src/migrations/global/GlobalMigrations.d.ts +0 -9
- package/packages/db/src/migrations/global/GlobalMigrations.d.ts.map +0 -1
- package/packages/db/src/migrations/global/GlobalMigrations.js +0 -68
- package/packages/db/src/migrations/global/GlobalMigrations.ts +0 -336
- package/packages/db/src/migrations/workspace/.gitkeep +0 -0
- package/packages/db/src/migrations/workspace/WorkspaceMigrations.d.ts +0 -9
- package/packages/db/src/migrations/workspace/WorkspaceMigrations.d.ts.map +0 -1
- package/packages/db/src/migrations/workspace/WorkspaceMigrations.js +0 -251
- package/packages/db/src/migrations/workspace/WorkspaceMigrations.ts +0 -248
- package/packages/db/src/repositories/global/.gitkeep +0 -0
- package/packages/db/src/repositories/global/GlobalRepository.d.ts +0 -30
- package/packages/db/src/repositories/global/GlobalRepository.d.ts.map +0 -1
- package/packages/db/src/repositories/global/GlobalRepository.js +0 -209
- package/packages/db/src/repositories/global/GlobalRepository.ts +0 -492
- package/packages/db/src/repositories/workspace/.gitkeep +0 -0
- package/packages/db/src/repositories/workspace/WorkspaceRepository.d.ts +0 -282
- package/packages/db/src/repositories/workspace/WorkspaceRepository.d.ts.map +0 -1
- package/packages/db/src/repositories/workspace/WorkspaceRepository.js +0 -773
- package/packages/db/src/repositories/workspace/WorkspaceRepository.ts +0 -1511
- package/packages/db/src/sqlite/connection.d.ts +0 -11
- package/packages/db/src/sqlite/connection.d.ts.map +0 -1
- package/packages/db/src/sqlite/connection.js +0 -31
- package/packages/db/src/sqlite/connection.ts +0 -35
- package/packages/db/src/sqlite/pragmas.d.ts +0 -5
- package/packages/db/src/sqlite/pragmas.d.ts.map +0 -1
- package/packages/db/src/sqlite/pragmas.js +0 -6
- package/packages/db/src/sqlite/pragmas.ts +0 -10
- package/packages/db/tsconfig.json +0 -13
- package/packages/generators/package.json +0 -21
- package/packages/generators/src/__tests__/Generators.test.ts +0 -19
- package/packages/generators/src/index.ts +0 -1
- package/packages/generators/src/openapi/generateTypes.ts +0 -1
- package/packages/generators/src/openapi/validateSchema.ts +0 -1
- package/packages/generators/src/scaffolding/docs/.gitkeep +0 -0
- package/packages/generators/src/scaffolding/docs/DocsScaffolder.ts +0 -1
- package/packages/generators/src/scaffolding/global/.gitkeep +0 -0
- package/packages/generators/src/scaffolding/global/GlobalScaffolder.ts +0 -1
- package/packages/generators/src/scaffolding/workspace/.gitkeep +0 -0
- package/packages/generators/src/scaffolding/workspace/WorkspaceScaffolder.ts +0 -1
- package/packages/generators/tsconfig.json +0 -10
- package/packages/integrations/CHANGELOG.md +0 -7
- package/packages/integrations/LICENSE +0 -21
- package/packages/integrations/README.md +0 -9
- package/packages/integrations/package.json +0 -47
- package/packages/integrations/src/docdex/.gitkeep +0 -0
- package/packages/integrations/src/docdex/DocdexClient.d.ts +0 -50
- package/packages/integrations/src/docdex/DocdexClient.d.ts.map +0 -1
- package/packages/integrations/src/docdex/DocdexClient.js +0 -216
- package/packages/integrations/src/docdex/DocdexClient.ts +0 -261
- package/packages/integrations/src/docdex/__tests__/DocdexClient.test.ts +0 -29
- package/packages/integrations/src/index.d.ts +0 -2
- package/packages/integrations/src/index.d.ts.map +0 -1
- package/packages/integrations/src/index.js +0 -4
- package/packages/integrations/src/index.ts +0 -5
- package/packages/integrations/src/issues/.gitkeep +0 -0
- package/packages/integrations/src/issues/IssuesClient.ts +0 -1
- package/packages/integrations/src/issues/__tests__/IssuesClient.test.ts +0 -10
- package/packages/integrations/src/qa/.gitkeep +0 -0
- package/packages/integrations/src/qa/ChromiumQaAdapter.ts +0 -89
- package/packages/integrations/src/qa/CliQaAdapter.ts +0 -95
- package/packages/integrations/src/qa/MaestroQaAdapter.ts +0 -91
- package/packages/integrations/src/qa/QaAdapter.ts +0 -7
- package/packages/integrations/src/qa/QaClient.ts +0 -1
- package/packages/integrations/src/qa/QaTypes.ts +0 -26
- package/packages/integrations/src/qa/__tests__/ChromiumQaAdapter.test.ts +0 -30
- package/packages/integrations/src/qa/__tests__/CliQaAdapter.test.ts +0 -33
- package/packages/integrations/src/qa/__tests__/MaestroQaAdapter.test.ts +0 -30
- package/packages/integrations/src/qa/index.ts +0 -5
- package/packages/integrations/src/system/SystemClient.ts +0 -50
- package/packages/integrations/src/system/__tests__/SystemClient.test.ts +0 -40
- package/packages/integrations/src/telemetry/TelemetryClient.ts +0 -139
- package/packages/integrations/src/telemetry/__tests__/TelemetryClient.test.ts +0 -41
- package/packages/integrations/src/vcs/.gitkeep +0 -0
- package/packages/integrations/src/vcs/VcsClient.ts +0 -211
- package/packages/integrations/src/vcs/__tests__/VcsClient.test.ts +0 -26
- package/packages/integrations/tsconfig.json +0 -14
- package/packages/shared/CHANGELOG.md +0 -7
- package/packages/shared/LICENSE +0 -21
- package/packages/shared/README.md +0 -9
- package/packages/shared/package.json +0 -40
- package/packages/shared/src/__tests__/CommandMetadata.test.ts +0 -15
- package/packages/shared/src/__tests__/ServiceShells.test.ts +0 -16
- package/packages/shared/src/crypto/.gitkeep +0 -0
- package/packages/shared/src/crypto/CryptoHelper.d.ts +0 -15
- package/packages/shared/src/crypto/CryptoHelper.d.ts.map +0 -1
- package/packages/shared/src/crypto/CryptoHelper.js +0 -54
- package/packages/shared/src/crypto/CryptoHelper.ts +0 -57
- package/packages/shared/src/errors/.gitkeep +0 -0
- package/packages/shared/src/errors/ErrorFactory.ts +0 -1
- package/packages/shared/src/index.d.ts +0 -6
- package/packages/shared/src/index.d.ts.map +0 -1
- package/packages/shared/src/index.js +0 -4
- package/packages/shared/src/index.ts +0 -35
- package/packages/shared/src/logging/.gitkeep +0 -0
- package/packages/shared/src/logging/Logger.ts +0 -1
- package/packages/shared/src/metadata/CommandMetadata.ts +0 -165
- package/packages/shared/src/openapi/.gitkeep +0 -0
- package/packages/shared/src/openapi/OpenApiTypes.d.ts +0 -216
- package/packages/shared/src/openapi/OpenApiTypes.d.ts.map +0 -1
- package/packages/shared/src/openapi/OpenApiTypes.js +0 -1
- package/packages/shared/src/openapi/OpenApiTypes.ts +0 -312
- package/packages/shared/src/paths/.gitkeep +0 -0
- package/packages/shared/src/paths/PathHelper.d.ts +0 -12
- package/packages/shared/src/paths/PathHelper.d.ts.map +0 -1
- package/packages/shared/src/paths/PathHelper.js +0 -24
- package/packages/shared/src/paths/PathHelper.ts +0 -29
- package/packages/shared/src/qa/QaProfile.ts +0 -14
- package/packages/shared/src/utils/.gitkeep +0 -0
- package/packages/shared/src/utils/UtilityService.ts +0 -1
- package/packages/shared/tsconfig.json +0 -10
- package/packages/testing/package.json +0 -26
- package/packages/testing/src/__tests__/TestingFakes.test.ts +0 -15
- package/packages/testing/src/cli/e2e/.gitkeep +0 -0
- package/packages/testing/src/cli/e2e/E2eSuite.ts +0 -1
- package/packages/testing/src/fakes/agents/.gitkeep +0 -0
- package/packages/testing/src/fakes/agents/FakeAgents.ts +0 -1
- package/packages/testing/src/fakes/docdex/.gitkeep +0 -0
- package/packages/testing/src/fakes/docdex/FakeDocdexClient.ts +0 -1
- package/packages/testing/src/fakes/qa/.gitkeep +0 -0
- package/packages/testing/src/fakes/qa/FakeQaClient.ts +0 -1
- package/packages/testing/src/fakes/vcs/.gitkeep +0 -0
- package/packages/testing/src/fakes/vcs/FakeVcsClient.ts +0 -1
- package/packages/testing/src/fixtures/db/.gitkeep +0 -0
- package/packages/testing/src/fixtures/db/DbFixtures.ts +0 -1
- package/packages/testing/src/fixtures/workspaces/.gitkeep +0 -0
- package/packages/testing/src/fixtures/workspaces/WorkspaceFixtures.ts +0 -1
- package/packages/testing/src/index.ts +0 -1
- package/packages/testing/tsconfig.json +0 -10
- package/pnpm-workspace.yaml +0 -2
- package/prompts/README.md +0 -5
- package/prompts/code-reviewer.md +0 -23
- package/prompts/code-writer.md +0 -35
- package/prompts/gateway-agent.md +0 -27
- package/prompts/qa-agent.md +0 -21
- package/release-please-config.json +0 -39
- package/scripts/build-all.ts +0 -1
- package/scripts/dev.ts +0 -1
- package/scripts/install-local-cli.sh +0 -28
- package/scripts/pack-npm-tarballs.js +0 -63
- package/scripts/release.ts +0 -1
- package/scripts/run-node-tests.js +0 -37
- package/tests/all.js +0 -127
- package/tests/api/openapi_spec.test.js +0 -21
- package/tests/artifacts.md +0 -31
- package/tests/component/cli_version.test.js +0 -38
- package/tests/integration/workspace_resolver.test.js +0 -44
- package/tests/unit/crypto_helper.test.js +0 -36
- package/tests/unit/path_helper.test.js +0 -20
- package/tsconfig.base.json +0 -32
- /package/{packages/cli/src/index.ts → dist/index.js} +0 -0
|
@@ -1,558 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import { promises as fs } from "node:fs";
|
|
3
|
-
import YAML from "yaml";
|
|
4
|
-
import SwaggerParser from "@apidevtools/swagger-parser";
|
|
5
|
-
import { AgentService } from "@mcoda/agents";
|
|
6
|
-
import { DocdexClient, DocdexDocument } from "@mcoda/integrations";
|
|
7
|
-
import { GlobalRepository } from "@mcoda/db";
|
|
8
|
-
import { Agent } from "@mcoda/shared";
|
|
9
|
-
import { WorkspaceResolution } from "../../workspace/WorkspaceManager.js";
|
|
10
|
-
import { JobService } from "../jobs/JobService.js";
|
|
11
|
-
import { RoutingService } from "../agents/RoutingService.js";
|
|
12
|
-
|
|
13
|
-
export interface GenerateOpenapiOptions {
|
|
14
|
-
workspace: WorkspaceResolution;
|
|
15
|
-
agentName?: string;
|
|
16
|
-
agentStream?: boolean;
|
|
17
|
-
force?: boolean;
|
|
18
|
-
dryRun?: boolean;
|
|
19
|
-
validateOnly?: boolean;
|
|
20
|
-
cliVersion: string;
|
|
21
|
-
onToken?: (token: string) => void;
|
|
22
|
-
projectKey?: string;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export interface GenerateOpenapiResult {
|
|
26
|
-
jobId: string;
|
|
27
|
-
commandRunId: string;
|
|
28
|
-
outputPath?: string;
|
|
29
|
-
spec: string;
|
|
30
|
-
docdexId?: string;
|
|
31
|
-
warnings: string[];
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
interface ContextBlock {
|
|
35
|
-
label: string;
|
|
36
|
-
content: string;
|
|
37
|
-
priority: number;
|
|
38
|
-
tokens: number;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
interface OpenapiContext {
|
|
42
|
-
blocks: ContextBlock[];
|
|
43
|
-
docdexAvailable: boolean;
|
|
44
|
-
warnings: string[];
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const OPENAPI_TAGS = [
|
|
48
|
-
// For project-specific specs, tags come from context; this is only a fallback.
|
|
49
|
-
];
|
|
50
|
-
|
|
51
|
-
const OPENAPI_VERSION = "3.1.0";
|
|
52
|
-
const CONTEXT_TOKEN_BUDGET = 8000;
|
|
53
|
-
|
|
54
|
-
const estimateTokens = (text: string): number => Math.max(1, Math.ceil(text.length / 4));
|
|
55
|
-
|
|
56
|
-
const fileExists = async (candidate: string): Promise<boolean> => {
|
|
57
|
-
try {
|
|
58
|
-
await fs.access(candidate);
|
|
59
|
-
return true;
|
|
60
|
-
} catch {
|
|
61
|
-
return false;
|
|
62
|
-
}
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
const readGitBranch = async (workspaceRoot: string): Promise<string | undefined> => {
|
|
66
|
-
const headPath = path.join(workspaceRoot, ".git", "HEAD");
|
|
67
|
-
try {
|
|
68
|
-
const content = await fs.readFile(headPath, "utf8");
|
|
69
|
-
const match = content.match(/ref: refs\/heads\/(.+)/);
|
|
70
|
-
return match ? match[1].trim() : content.trim();
|
|
71
|
-
} catch {
|
|
72
|
-
return undefined;
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
class OpenapiContextAssembler {
|
|
77
|
-
constructor(private docdex: DocdexClient, private workspace: WorkspaceResolution, private projectKey?: string) {}
|
|
78
|
-
|
|
79
|
-
private summarize(doc: DocdexDocument): string {
|
|
80
|
-
const text = doc.content ?? "";
|
|
81
|
-
if (!text) return doc.title ?? doc.path ?? doc.id ?? "Document";
|
|
82
|
-
return text.split(/\r?\n/).slice(0, 5).join(" ").slice(0, 400);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
private async findLatestLocalDoc(docType: string): Promise<DocdexDocument | undefined> {
|
|
86
|
-
const candidates: { path: string; mtime: number }[] = [];
|
|
87
|
-
const dirNames = [".mcoda/docs", "docs"];
|
|
88
|
-
for (const dir of dirNames) {
|
|
89
|
-
const target = path.join(this.workspace.workspaceRoot, dir, docType.toLowerCase());
|
|
90
|
-
try {
|
|
91
|
-
const entries = await fs.readdir(target);
|
|
92
|
-
for (const entry of entries.filter((e) => e.endsWith(".md"))) {
|
|
93
|
-
const full = path.join(target, entry);
|
|
94
|
-
const stat = await fs.stat(full);
|
|
95
|
-
candidates.push({ path: full, mtime: stat.mtimeMs });
|
|
96
|
-
}
|
|
97
|
-
} catch {
|
|
98
|
-
// ignore
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
const latest = candidates.sort((a, b) => b.mtime - a.mtime)[0];
|
|
102
|
-
if (!latest) return undefined;
|
|
103
|
-
const content = await fs.readFile(latest.path, "utf8");
|
|
104
|
-
const timestamp = new Date(latest.mtime).toISOString();
|
|
105
|
-
return {
|
|
106
|
-
id: `local-${docType.toLowerCase()}-${path.basename(latest.path)}`,
|
|
107
|
-
docType,
|
|
108
|
-
path: latest.path,
|
|
109
|
-
content,
|
|
110
|
-
createdAt: timestamp,
|
|
111
|
-
updatedAt: timestamp,
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
private formatBlock(doc: DocdexDocument, label: string, priority: number, maxSegments = 5): ContextBlock {
|
|
116
|
-
const segments = (doc.segments ?? []).slice(0, maxSegments);
|
|
117
|
-
const heading = `[${doc.docType}] ${label}`;
|
|
118
|
-
const source = doc.path ?? doc.id ?? label;
|
|
119
|
-
const body = segments.length
|
|
120
|
-
? segments
|
|
121
|
-
.map((seg, idx) => {
|
|
122
|
-
const head = seg.heading ?? `Segment ${idx + 1}`;
|
|
123
|
-
const trimmed = seg.content.length > 1000 ? `${seg.content.slice(0, 1000)}...` : seg.content;
|
|
124
|
-
return `### ${head}\n${trimmed}`;
|
|
125
|
-
})
|
|
126
|
-
.join("\n\n")
|
|
127
|
-
: doc.content ?? this.summarize(doc);
|
|
128
|
-
const content = [heading, `Source: ${source}`, body].filter(Boolean).join("\n");
|
|
129
|
-
return {
|
|
130
|
-
label,
|
|
131
|
-
content,
|
|
132
|
-
priority,
|
|
133
|
-
tokens: estimateTokens(content),
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
private enforceBudget(blocks: ContextBlock[], warnings: string[]): ContextBlock[] {
|
|
138
|
-
let total = blocks.reduce((sum, b) => sum + b.tokens, 0);
|
|
139
|
-
if (total <= CONTEXT_TOKEN_BUDGET) return blocks;
|
|
140
|
-
const ordered = [...blocks].sort((a, b) => a.priority - b.priority);
|
|
141
|
-
for (const block of ordered) {
|
|
142
|
-
if (total <= CONTEXT_TOKEN_BUDGET) break;
|
|
143
|
-
const summary = `${block.label}: ${block.content.slice(0, 400)}`;
|
|
144
|
-
total -= block.tokens;
|
|
145
|
-
block.content = summary;
|
|
146
|
-
block.tokens = estimateTokens(summary);
|
|
147
|
-
total += block.tokens;
|
|
148
|
-
warnings.push(`Context for ${block.label} truncated to fit budget.`);
|
|
149
|
-
}
|
|
150
|
-
return blocks;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
async build(): Promise<OpenapiContext> {
|
|
154
|
-
const warnings: string[] = [];
|
|
155
|
-
const blocks: ContextBlock[] = [];
|
|
156
|
-
let docdexAvailable = true;
|
|
157
|
-
let sdsDocs: DocdexDocument[] = [];
|
|
158
|
-
let pdrDocs: DocdexDocument[] = [];
|
|
159
|
-
let rfpDocs: DocdexDocument[] = [];
|
|
160
|
-
let openapiDocs: DocdexDocument[] = [];
|
|
161
|
-
let schemaDocs: DocdexDocument[] = [];
|
|
162
|
-
try {
|
|
163
|
-
[sdsDocs, pdrDocs, rfpDocs, openapiDocs, schemaDocs] = await Promise.all([
|
|
164
|
-
this.docdex.search({ docType: "SDS", profile: "openapi", projectKey: this.projectKey }),
|
|
165
|
-
this.docdex.search({ docType: "PDR", profile: "openapi", projectKey: this.projectKey }),
|
|
166
|
-
this.docdex.search({ docType: "RFP", profile: "openapi", projectKey: this.projectKey }),
|
|
167
|
-
this.docdex.search({ docType: "OPENAPI", profile: "openapi", projectKey: this.projectKey }),
|
|
168
|
-
this.docdex.search({ docType: "Architecture", profile: "openapi", projectKey: this.projectKey }),
|
|
169
|
-
]);
|
|
170
|
-
} catch (error) {
|
|
171
|
-
docdexAvailable = false;
|
|
172
|
-
warnings.push(
|
|
173
|
-
`Docdex unavailable; falling back to local docs for OpenAPI context (${(error as Error).message ?? "unknown"})`,
|
|
174
|
-
);
|
|
175
|
-
}
|
|
176
|
-
// Fallbacks when docdex returns no hits
|
|
177
|
-
if (sdsDocs.length === 0) {
|
|
178
|
-
const local = await this.findLatestLocalDoc("SDS");
|
|
179
|
-
if (local) {
|
|
180
|
-
blocks.push(this.formatBlock(local, "Local SDS (no docdex)", 1, 8));
|
|
181
|
-
warnings.push("No SDS found in docdex; using latest local SDS file.");
|
|
182
|
-
sdsDocs = [local];
|
|
183
|
-
} else {
|
|
184
|
-
warnings.push("No SDS found in docdex or local workspace.");
|
|
185
|
-
}
|
|
186
|
-
} else {
|
|
187
|
-
blocks.push(this.formatBlock(sdsDocs[0], "SDS OpenAPI contract", 1, 8));
|
|
188
|
-
}
|
|
189
|
-
if (pdrDocs.length === 0) {
|
|
190
|
-
const local = await this.findLatestLocalDoc("PDR");
|
|
191
|
-
if (local) {
|
|
192
|
-
blocks.push(this.formatBlock(local, "Local PDR (no docdex)", 2, 6));
|
|
193
|
-
warnings.push("No PDR found in docdex; using latest local PDR file.");
|
|
194
|
-
pdrDocs = [local];
|
|
195
|
-
} else {
|
|
196
|
-
warnings.push("No PDR found in docdex or local workspace.");
|
|
197
|
-
}
|
|
198
|
-
} else {
|
|
199
|
-
blocks.push(this.formatBlock(pdrDocs[0], "PDR context", 2, 6));
|
|
200
|
-
}
|
|
201
|
-
if (rfpDocs.length === 0) {
|
|
202
|
-
const local = await this.findLatestLocalDoc("RFP");
|
|
203
|
-
if (local) {
|
|
204
|
-
blocks.push(this.formatBlock(local, "Local RFP (no docdex)", 2, 6));
|
|
205
|
-
warnings.push("No RFP found in docdex; using latest local RFP file.");
|
|
206
|
-
rfpDocs = [local];
|
|
207
|
-
} else {
|
|
208
|
-
warnings.push("No RFP found in docdex or local workspace.");
|
|
209
|
-
}
|
|
210
|
-
} else {
|
|
211
|
-
blocks.push(this.formatBlock(rfpDocs[0], "RFP alignment", 2, 6));
|
|
212
|
-
}
|
|
213
|
-
if (openapiDocs.length > 0) {
|
|
214
|
-
blocks.push(this.formatBlock(openapiDocs[0], "Existing OpenAPI docdex", 1, 6));
|
|
215
|
-
}
|
|
216
|
-
if (schemaDocs.length > 0) {
|
|
217
|
-
blocks.push(this.formatBlock(schemaDocs[0], "Data model & persistence", 1, 6));
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
if (!blocks.length) {
|
|
221
|
-
const localSds = await this.findLatestLocalDoc("SDS");
|
|
222
|
-
if (localSds) blocks.push(this.formatBlock(localSds, "Local SDS", 1, 6));
|
|
223
|
-
const localPdr = await this.findLatestLocalDoc("PDR");
|
|
224
|
-
if (localPdr) blocks.push(this.formatBlock(localPdr, "Local PDR", 2, 6));
|
|
225
|
-
}
|
|
226
|
-
return {
|
|
227
|
-
blocks: this.enforceBudget(blocks, warnings),
|
|
228
|
-
docdexAvailable,
|
|
229
|
-
warnings,
|
|
230
|
-
};
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
export class OpenApiService {
|
|
235
|
-
private docdex: DocdexClient;
|
|
236
|
-
private jobService: JobService;
|
|
237
|
-
private agentService: AgentService;
|
|
238
|
-
private routingService: RoutingService;
|
|
239
|
-
private workspace: WorkspaceResolution;
|
|
240
|
-
|
|
241
|
-
constructor(
|
|
242
|
-
workspace: WorkspaceResolution,
|
|
243
|
-
deps: { docdex?: DocdexClient; jobService?: JobService; agentService: AgentService; routingService: RoutingService; noTelemetry?: boolean },
|
|
244
|
-
) {
|
|
245
|
-
this.workspace = workspace;
|
|
246
|
-
this.docdex = deps?.docdex ?? new DocdexClient({ workspaceRoot: workspace.workspaceRoot });
|
|
247
|
-
this.jobService = deps?.jobService ?? new JobService(workspace, undefined, { noTelemetry: deps?.noTelemetry });
|
|
248
|
-
this.agentService = deps.agentService;
|
|
249
|
-
this.routingService = deps.routingService;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
static async create(workspace: WorkspaceResolution, options: { noTelemetry?: boolean } = {}): Promise<OpenApiService> {
|
|
253
|
-
const repo = await GlobalRepository.create();
|
|
254
|
-
const agentService = new AgentService(repo);
|
|
255
|
-
const routingService = await RoutingService.create();
|
|
256
|
-
const docdex = new DocdexClient({
|
|
257
|
-
workspaceRoot: workspace.workspaceRoot,
|
|
258
|
-
baseUrl: workspace.config?.docdexUrl ?? process.env.MCODA_DOCDEX_URL,
|
|
259
|
-
});
|
|
260
|
-
const jobService = new JobService(workspace, undefined, { noTelemetry: options.noTelemetry });
|
|
261
|
-
return new OpenApiService(workspace, { agentService, routingService, docdex, jobService, noTelemetry: options.noTelemetry });
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
async close(): Promise<void> {
|
|
265
|
-
if ((this.agentService as any).close) await this.agentService.close();
|
|
266
|
-
if ((this.jobService as any).close) await this.jobService.close();
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
private async resolveAgent(agentName?: string): Promise<Agent> {
|
|
270
|
-
const resolved = await this.routingService.resolveAgentForCommand({
|
|
271
|
-
workspace: this.workspace,
|
|
272
|
-
commandName: "openapi-from-docs",
|
|
273
|
-
overrideAgentSlug: agentName,
|
|
274
|
-
});
|
|
275
|
-
return resolved.agent;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
private async invokeAgent(
|
|
279
|
-
agent: Agent,
|
|
280
|
-
prompt: string,
|
|
281
|
-
stream: boolean,
|
|
282
|
-
jobId: string,
|
|
283
|
-
onToken?: (token: string) => void,
|
|
284
|
-
): Promise<{ output: string; adapter: string; metadata?: Record<string, unknown> }> {
|
|
285
|
-
if (stream) {
|
|
286
|
-
try {
|
|
287
|
-
const generator = await this.agentService.invokeStream(agent.id, { input: prompt, metadata: { jobId } });
|
|
288
|
-
const chunks: string[] = [];
|
|
289
|
-
for await (const chunk of generator) {
|
|
290
|
-
chunks.push(chunk.output);
|
|
291
|
-
await this.jobService.appendLog(jobId, chunk.output);
|
|
292
|
-
if (onToken) onToken(chunk.output);
|
|
293
|
-
}
|
|
294
|
-
return { output: chunks.join(""), adapter: agent.adapter };
|
|
295
|
-
} catch {
|
|
296
|
-
const fallback = await this.agentService.invoke(agent.id, { input: prompt, metadata: { jobId } });
|
|
297
|
-
await this.jobService.appendLog(jobId, fallback.output);
|
|
298
|
-
if (onToken) onToken(fallback.output);
|
|
299
|
-
return { output: fallback.output, adapter: fallback.adapter, metadata: fallback.metadata };
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
const result = await this.agentService.invoke(agent.id, { input: prompt, metadata: { jobId } });
|
|
303
|
-
await this.jobService.appendLog(jobId, result.output);
|
|
304
|
-
if (onToken) onToken(result.output);
|
|
305
|
-
return { output: result.output, adapter: result.adapter, metadata: result.metadata };
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
private sanitizeOutput(raw: string): string {
|
|
309
|
-
const trimmed = raw.trim();
|
|
310
|
-
if (trimmed.startsWith("```")) {
|
|
311
|
-
const withoutFence = trimmed.replace(/^```[a-zA-Z]*\s*/m, "").replace(/```$/, "");
|
|
312
|
-
return withoutFence.trim();
|
|
313
|
-
}
|
|
314
|
-
return trimmed;
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
private validateSpec(doc: any): string[] {
|
|
318
|
-
const errors: string[] = [];
|
|
319
|
-
if (!doc || typeof doc !== "object") {
|
|
320
|
-
errors.push("Spec is not a YAML object.");
|
|
321
|
-
return errors;
|
|
322
|
-
}
|
|
323
|
-
if (!doc.openapi) errors.push("Missing openapi version");
|
|
324
|
-
if (!doc.info?.title) errors.push("Missing info.title");
|
|
325
|
-
if (!doc.info?.version) errors.push("Missing info.version");
|
|
326
|
-
if (!doc.paths) errors.push("paths section is required (can be empty if no HTTP API)");
|
|
327
|
-
return errors;
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
private async runOpenapiValidator(doc: any): Promise<string[]> {
|
|
331
|
-
try {
|
|
332
|
-
await SwaggerParser.validate(doc as any);
|
|
333
|
-
return [];
|
|
334
|
-
} catch (error) {
|
|
335
|
-
const details = (error as any)?.details as { message?: string }[] | undefined;
|
|
336
|
-
if (Array.isArray(details) && details.length) {
|
|
337
|
-
return details.map((d) => d.message ?? String(error));
|
|
338
|
-
}
|
|
339
|
-
return [(error as Error).message];
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
private buildPrompt(context: OpenapiContext, cliVersion: string, retryReasons?: string[]): string {
|
|
344
|
-
const contextBlocks = context.blocks
|
|
345
|
-
.map((block) => `### ${block.label}\n${block.content}`)
|
|
346
|
-
.join("\n\n");
|
|
347
|
-
const retryNote = retryReasons?.length
|
|
348
|
-
? `\nPrevious attempt issues:\n${retryReasons.map((r) => `- ${r}`).join("\n")}\nFix them in this draft.\n`
|
|
349
|
-
: "";
|
|
350
|
-
return [
|
|
351
|
-
"You are generating an OpenAPI 3.1 YAML for THIS workspace/project using only the provided PDR/SDS/RFP context.",
|
|
352
|
-
"Derive resources, schemas, and HTTP endpoints directly from the product requirements (e.g., todos CRUD, filters, search, bulk actions).",
|
|
353
|
-
"If the documents describe a frontend-only/localStorage app, design a minimal REST API that could back those features (e.g., /todos, /todos/{id}, bulk operations, search/filter params) instead of returning an empty spec.",
|
|
354
|
-
"Prefer concise tags derived from domain resources (e.g., Todos). Avoid generic mcoda/system endpoints unless explicitly described in the context.",
|
|
355
|
-
`Use OpenAPI version ${OPENAPI_VERSION}, set info.title to the project name from context (fallback \"mcoda API\"), and info.version ${cliVersion}.`,
|
|
356
|
-
"Return only valid YAML (no Markdown fences, no commentary).",
|
|
357
|
-
retryNote,
|
|
358
|
-
"Scope rules:",
|
|
359
|
-
"- Derive endpoints, schemas, and tags from the provided PDR/SDS/RFP context only.",
|
|
360
|
-
"- Do NOT emit generic mcoda CLI/system endpoints unless explicitly described.",
|
|
361
|
-
"- Prefer concise schemas and operations that map to described APIs; omit unused boilerplate.",
|
|
362
|
-
"Context:",
|
|
363
|
-
contextBlocks || "No context available; if none, produce a minimal empty spec with paths: {}.",
|
|
364
|
-
].join("\n\n");
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
private async ensureOpenapiDir(): Promise<string> {
|
|
368
|
-
const dir = path.join(this.workspace.workspaceRoot, "openapi");
|
|
369
|
-
await fs.mkdir(dir, { recursive: true });
|
|
370
|
-
return dir;
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
private async backupIfNeeded(target: string): Promise<string | undefined> {
|
|
374
|
-
if (!(await fileExists(target))) return undefined;
|
|
375
|
-
const backup = `${target}.bak`;
|
|
376
|
-
await fs.copyFile(target, backup);
|
|
377
|
-
return backup;
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
private async registerOpenapi(outPath: string, content: string): Promise<DocdexDocument> {
|
|
381
|
-
const branch = this.workspace.config?.branch ?? (await readGitBranch(this.workspace.workspaceRoot));
|
|
382
|
-
return this.docdex.registerDocument({
|
|
383
|
-
docType: "OPENAPI",
|
|
384
|
-
path: outPath,
|
|
385
|
-
content,
|
|
386
|
-
metadata: {
|
|
387
|
-
workspace: this.workspace.workspaceId,
|
|
388
|
-
branch,
|
|
389
|
-
status: "canonical",
|
|
390
|
-
projectKey: (this.workspace.config as any)?.projectKey,
|
|
391
|
-
},
|
|
392
|
-
});
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
private async validateExistingSpec(target: string): Promise<{ spec: string; issues: string[] }> {
|
|
396
|
-
const content = await fs.readFile(target, "utf8");
|
|
397
|
-
const parsed = YAML.parse(content);
|
|
398
|
-
const issues = this.validateSpec(parsed);
|
|
399
|
-
const validatorIssues = await this.runOpenapiValidator(parsed);
|
|
400
|
-
issues.push(...validatorIssues);
|
|
401
|
-
return { spec: content, issues };
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
async generateFromDocs(options: GenerateOpenapiOptions): Promise<GenerateOpenapiResult> {
|
|
405
|
-
const commandRun = await this.jobService.startCommandRun("openapi-from-docs", options.projectKey);
|
|
406
|
-
const job = await this.jobService.startJob("openapi_change", commandRun.id, options.projectKey, {
|
|
407
|
-
commandName: commandRun.commandName,
|
|
408
|
-
payload: { workspaceRoot: this.workspace.workspaceRoot, projectKey: options.projectKey },
|
|
409
|
-
});
|
|
410
|
-
const warnings: string[] = [];
|
|
411
|
-
try {
|
|
412
|
-
const projectKey = options.projectKey ?? (this.workspace.config as any)?.projectKey;
|
|
413
|
-
const assembler = new OpenapiContextAssembler(this.docdex, this.workspace, projectKey);
|
|
414
|
-
const context = await assembler.build();
|
|
415
|
-
warnings.push(...context.warnings);
|
|
416
|
-
await this.jobService.writeCheckpoint(job.id, {
|
|
417
|
-
stage: "context_built",
|
|
418
|
-
timestamp: new Date().toISOString(),
|
|
419
|
-
details: { docdexAvailable: context.docdexAvailable },
|
|
420
|
-
});
|
|
421
|
-
await this.jobService.recordTokenUsage({
|
|
422
|
-
timestamp: new Date().toISOString(),
|
|
423
|
-
workspaceId: this.workspace.workspaceId,
|
|
424
|
-
commandName: "openapi-from-docs",
|
|
425
|
-
jobId: job.id,
|
|
426
|
-
action: "docdex_context",
|
|
427
|
-
promptTokens: 0,
|
|
428
|
-
completionTokens: 0,
|
|
429
|
-
metadata: { docdexAvailable: context.docdexAvailable },
|
|
430
|
-
});
|
|
431
|
-
|
|
432
|
-
const openapiDir = await this.ensureOpenapiDir();
|
|
433
|
-
const outputPath = path.join(openapiDir, "mcoda.yaml");
|
|
434
|
-
if (options.validateOnly) {
|
|
435
|
-
if (!(await fileExists(outputPath))) {
|
|
436
|
-
throw new Error(`Cannot validate missing spec: ${outputPath}`);
|
|
437
|
-
}
|
|
438
|
-
const { spec, issues } = await this.validateExistingSpec(outputPath);
|
|
439
|
-
const validationNote = issues.length ? `Validation issues:\n${issues.join("\n")}` : "Validation passed.";
|
|
440
|
-
await this.jobService.appendLog(job.id, `${validationNote}\n`);
|
|
441
|
-
const jobState = issues.length ? "failed" : "completed";
|
|
442
|
-
const commandState = issues.length ? "failed" : "succeeded";
|
|
443
|
-
await this.jobService.updateJobStatus(job.id, jobState, { payload: { validation: validationNote } });
|
|
444
|
-
await this.jobService.finishCommandRun(commandRun.id, commandState, issues.join("; "));
|
|
445
|
-
return {
|
|
446
|
-
jobId: job.id,
|
|
447
|
-
commandRunId: commandRun.id,
|
|
448
|
-
outputPath,
|
|
449
|
-
spec,
|
|
450
|
-
warnings,
|
|
451
|
-
};
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
if (!options.force && (await fileExists(outputPath))) {
|
|
455
|
-
throw new Error(`File exists, use --force to overwrite (${outputPath})`);
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
const agent = await this.resolveAgent(options.agentName);
|
|
459
|
-
const stream = options.agentStream ?? true;
|
|
460
|
-
|
|
461
|
-
let specYaml = "";
|
|
462
|
-
let parsed: any;
|
|
463
|
-
let adapter = agent.adapter;
|
|
464
|
-
let agentMetadata: Record<string, unknown> | undefined;
|
|
465
|
-
let lastErrors: string[] | undefined;
|
|
466
|
-
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
467
|
-
const prompt = this.buildPrompt(context, options.cliVersion, lastErrors);
|
|
468
|
-
const { output, adapter: usedAdapter, metadata } = await this.invokeAgent(
|
|
469
|
-
agent,
|
|
470
|
-
prompt,
|
|
471
|
-
stream,
|
|
472
|
-
job.id,
|
|
473
|
-
options.onToken,
|
|
474
|
-
);
|
|
475
|
-
adapter = usedAdapter;
|
|
476
|
-
agentMetadata = metadata;
|
|
477
|
-
specYaml = this.sanitizeOutput(output);
|
|
478
|
-
try {
|
|
479
|
-
parsed = YAML.parse(specYaml);
|
|
480
|
-
if (!parsed.info) parsed.info = {};
|
|
481
|
-
const projectTitle = options.projectKey ?? (this.workspace.config as any)?.projectKey;
|
|
482
|
-
parsed.info.title = parsed.info.title ?? projectTitle ?? "mcoda API";
|
|
483
|
-
parsed.info.version = options.cliVersion;
|
|
484
|
-
parsed.openapi = parsed.openapi ?? OPENAPI_VERSION;
|
|
485
|
-
const errors = this.validateSpec(parsed);
|
|
486
|
-
const validatorErrors = await this.runOpenapiValidator(parsed);
|
|
487
|
-
errors.push(...validatorErrors);
|
|
488
|
-
await this.jobService.recordTokenUsage({
|
|
489
|
-
timestamp: new Date().toISOString(),
|
|
490
|
-
workspaceId: this.workspace.workspaceId,
|
|
491
|
-
commandName: "openapi-from-docs",
|
|
492
|
-
jobId: job.id,
|
|
493
|
-
agentId: agent.id,
|
|
494
|
-
modelName: agent.defaultModel,
|
|
495
|
-
action: attempt === 0 ? "draft_openapi" : "draft_openapi_retry",
|
|
496
|
-
promptTokens: estimateTokens(prompt),
|
|
497
|
-
completionTokens: estimateTokens(output),
|
|
498
|
-
metadata: { adapter, provider: adapter, attempt },
|
|
499
|
-
});
|
|
500
|
-
if (errors.length === 0) {
|
|
501
|
-
specYaml = YAML.stringify(parsed);
|
|
502
|
-
break;
|
|
503
|
-
}
|
|
504
|
-
if (attempt === 1) {
|
|
505
|
-
throw new Error(`Generated spec failed validation: ${errors.join("; ")}`);
|
|
506
|
-
}
|
|
507
|
-
lastErrors = errors;
|
|
508
|
-
} catch (error) {
|
|
509
|
-
if (attempt === 1) {
|
|
510
|
-
throw new Error((error as Error).message || "Failed to parse generated YAML");
|
|
511
|
-
}
|
|
512
|
-
lastErrors = [(error as Error).message ?? "Invalid YAML"];
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
let backup: string | undefined;
|
|
517
|
-
if (!options.dryRun) {
|
|
518
|
-
backup = await this.backupIfNeeded(outputPath);
|
|
519
|
-
await fs.writeFile(outputPath, specYaml, "utf8");
|
|
520
|
-
} else {
|
|
521
|
-
warnings.push("Dry run enabled; spec not written to disk.");
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
let docdexId: string | undefined;
|
|
525
|
-
if (!options.dryRun && context.docdexAvailable) {
|
|
526
|
-
try {
|
|
527
|
-
const registered = await this.registerOpenapi(outputPath, specYaml);
|
|
528
|
-
docdexId = registered.id;
|
|
529
|
-
} catch (error) {
|
|
530
|
-
warnings.push(`Docdex registration skipped: ${(error as Error).message}`);
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
await this.jobService.updateJobStatus(job.id, "completed", {
|
|
535
|
-
payload: {
|
|
536
|
-
outputPath,
|
|
537
|
-
backupPath: backup,
|
|
538
|
-
docdexId,
|
|
539
|
-
adapter,
|
|
540
|
-
agentMetadata,
|
|
541
|
-
},
|
|
542
|
-
});
|
|
543
|
-
await this.jobService.finishCommandRun(commandRun.id, "succeeded");
|
|
544
|
-
return {
|
|
545
|
-
jobId: job.id,
|
|
546
|
-
commandRunId: commandRun.id,
|
|
547
|
-
outputPath: options.dryRun ? undefined : outputPath,
|
|
548
|
-
spec: specYaml,
|
|
549
|
-
docdexId,
|
|
550
|
-
warnings,
|
|
551
|
-
};
|
|
552
|
-
} catch (error) {
|
|
553
|
-
await this.jobService.updateJobStatus(job.id, "failed", { errorSummary: (error as Error).message });
|
|
554
|
-
await this.jobService.finishCommandRun(commandRun.id, "failed", (error as Error).message);
|
|
555
|
-
throw error;
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import test from "node:test";
|
|
2
|
-
import assert from "node:assert/strict";
|
|
3
|
-
import fs from "node:fs/promises";
|
|
4
|
-
import os from "node:os";
|
|
5
|
-
import path from "node:path";
|
|
6
|
-
import { WorkspaceResolver } from "../../../workspace/WorkspaceManager.js";
|
|
7
|
-
import { JobService } from "../../jobs/JobService.js";
|
|
8
|
-
import { OpenApiService } from "../OpenApiService.js";
|
|
9
|
-
|
|
10
|
-
test("OpenApiService generates spec with stubbed agent", async () => {
|
|
11
|
-
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "mcoda-openapi-"));
|
|
12
|
-
const previous = process.env.MCODA_DISABLE_DB;
|
|
13
|
-
process.env.MCODA_DISABLE_DB = "1";
|
|
14
|
-
const workspace = await WorkspaceResolver.resolveWorkspace({ cwd: dir, explicitWorkspace: dir });
|
|
15
|
-
const jobService = new JobService(workspace.workspaceRoot);
|
|
16
|
-
const spec = [
|
|
17
|
-
"openapi: 3.1.0",
|
|
18
|
-
"info:",
|
|
19
|
-
" title: Demo API",
|
|
20
|
-
" version: 0.1.2",
|
|
21
|
-
"paths: {}",
|
|
22
|
-
"",
|
|
23
|
-
].join("\n");
|
|
24
|
-
|
|
25
|
-
const service = new OpenApiService(workspace, {
|
|
26
|
-
jobService,
|
|
27
|
-
docdex: { search: async () => [] } as any,
|
|
28
|
-
routingService: {
|
|
29
|
-
resolveAgentForCommand: async () => ({
|
|
30
|
-
agent: { id: "agent-1", slug: "agent-1", adapter: "local", defaultModel: "stub" },
|
|
31
|
-
}),
|
|
32
|
-
} as any,
|
|
33
|
-
agentService: {
|
|
34
|
-
invoke: async () => ({ output: spec, adapter: "local" }),
|
|
35
|
-
} as any,
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
try {
|
|
39
|
-
const result = await service.generateFromDocs({
|
|
40
|
-
workspace,
|
|
41
|
-
cliVersion: "0.1.2",
|
|
42
|
-
agentStream: false,
|
|
43
|
-
dryRun: true,
|
|
44
|
-
});
|
|
45
|
-
assert.ok(result.spec.includes("openapi: 3.1.0"));
|
|
46
|
-
assert.equal(result.outputPath, undefined);
|
|
47
|
-
assert.ok(result.warnings.some((w) => w.toLowerCase().includes("dry run")));
|
|
48
|
-
} finally {
|
|
49
|
-
await service.close();
|
|
50
|
-
if (previous === undefined) {
|
|
51
|
-
delete process.env.MCODA_DISABLE_DB;
|
|
52
|
-
} else {
|
|
53
|
-
process.env.MCODA_DISABLE_DB = previous;
|
|
54
|
-
}
|
|
55
|
-
await fs.rm(dir, { recursive: true, force: true });
|
|
56
|
-
}
|
|
57
|
-
});
|
|
File without changes
|