agentic-orchestrator 0.1.6 → 0.1.8
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/.prettierignore +10 -0
- package/.prettierrc.json +24 -0
- package/CLAUDE.md +3 -2
- package/README.md +71 -48
- package/agentic/orchestrator/defaults/policy.defaults.yaml +1 -1
- package/agentic/orchestrator/prompts/planner.system.md +1 -0
- package/agentic/orchestrator/schemas/agents.schema.json +5 -22
- package/agentic/orchestrator/schemas/gates.schema.json +4 -19
- package/agentic/orchestrator/schemas/index.schema.json +3 -14
- package/agentic/orchestrator/schemas/multi-project.schema.json +2 -8
- package/agentic/orchestrator/schemas/plan.schema.json +6 -26
- package/agentic/orchestrator/schemas/policy.schema.json +19 -81
- package/agentic/orchestrator/schemas/policy.user.schema.json +1 -5
- package/agentic/orchestrator/schemas/qa_test_index.schema.json +5 -29
- package/agentic/orchestrator/schemas/state.schema.json +11 -61
- package/agentic/orchestrator/tools/catalog.json +33 -164
- package/agentic/orchestrator/tools/schemas/input/evidence.latest.input.schema.json +1 -3
- package/agentic/orchestrator/tools/schemas/input/feature.delete.input.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/input/feature.get_context.input.schema.json +1 -3
- package/agentic/orchestrator/tools/schemas/input/feature.init.input.schema.json +1 -4
- package/agentic/orchestrator/tools/schemas/input/feature.log_append.input.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/input/feature.ready_to_merge.input.schema.json +1 -6
- package/agentic/orchestrator/tools/schemas/input/feature.state_get.input.schema.json +1 -3
- package/agentic/orchestrator/tools/schemas/input/feature.state_patch.input.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/input/gates.run.input.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/input/locks.acquire.input.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/input/locks.release.input.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/input/performance.record_outcome.input.schema.json +10 -1
- package/agentic/orchestrator/tools/schemas/input/plan.get.input.schema.json +1 -3
- package/agentic/orchestrator/tools/schemas/input/plan.submit.input.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/input/plan.update.input.schema.json +1 -6
- package/agentic/orchestrator/tools/schemas/input/qa.test_index_get.input.schema.json +1 -3
- package/agentic/orchestrator/tools/schemas/input/qa.test_index_update.input.schema.json +1 -6
- package/agentic/orchestrator/tools/schemas/input/repo.apply_patch.input.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/input/repo.diff.input.schema.json +1 -3
- package/agentic/orchestrator/tools/schemas/input/repo.diff_bundle.input.schema.json +1 -3
- package/agentic/orchestrator/tools/schemas/input/repo.ensure_worktree.input.schema.json +1 -4
- package/agentic/orchestrator/tools/schemas/input/repo.read_file.input.schema.json +1 -4
- package/agentic/orchestrator/tools/schemas/input/repo.search.input.schema.json +1 -4
- package/agentic/orchestrator/tools/schemas/input/repo.status.input.schema.json +1 -3
- package/agentic/orchestrator/tools/schemas/input/report.feature_summary.input.schema.json +1 -3
- package/agentic/orchestrator/tools/schemas/output/collisions.scan.output.schema.json +1 -3
- package/agentic/orchestrator/tools/schemas/output/evidence.latest.output.schema.json +1 -4
- package/agentic/orchestrator/tools/schemas/output/feature.delete.output.schema.json +4 -20
- package/agentic/orchestrator/tools/schemas/output/feature.discover_specs.output.schema.json +2 -7
- package/agentic/orchestrator/tools/schemas/output/feature.get_context.output.schema.json +1 -8
- package/agentic/orchestrator/tools/schemas/output/feature.init.output.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/output/feature.log_append.output.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/output/feature.ready_to_merge.output.schema.json +1 -6
- package/agentic/orchestrator/tools/schemas/output/feature.state_get.output.schema.json +1 -4
- package/agentic/orchestrator/tools/schemas/output/feature.state_patch.output.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/output/gates.list.output.schema.json +2 -7
- package/agentic/orchestrator/tools/schemas/output/gates.run.output.schema.json +1 -8
- package/agentic/orchestrator/tools/schemas/output/locks.acquire.output.schema.json +1 -7
- package/agentic/orchestrator/tools/schemas/output/locks.release.output.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/output/performance.get_analytics.output.schema.json +22 -2
- package/agentic/orchestrator/tools/schemas/output/plan.get.output.schema.json +1 -4
- package/agentic/orchestrator/tools/schemas/output/plan.submit.output.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/output/plan.update.output.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/output/qa.test_index_get.output.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/output/qa.test_index_update.output.schema.json +1 -4
- package/agentic/orchestrator/tools/schemas/output/repo.apply_patch.output.schema.json +1 -6
- package/agentic/orchestrator/tools/schemas/output/repo.diff.output.schema.json +1 -4
- package/agentic/orchestrator/tools/schemas/output/repo.diff_bundle.output.schema.json +1 -7
- package/agentic/orchestrator/tools/schemas/output/repo.ensure_worktree.output.schema.json +1 -6
- package/agentic/orchestrator/tools/schemas/output/repo.read_file.output.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/output/repo.search.output.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/output/repo.status.output.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/output/report.dashboard.output.schema.json +1 -4
- package/apps/control-plane/scripts/validate-architecture-rules.mjs +16 -5
- package/apps/control-plane/scripts/validate-docker-mcp-contract.mjs +30 -8
- package/apps/control-plane/scripts/validate-mcp-contracts.ts +13 -7
- package/apps/control-plane/src/application/adapters/adapter-registry.ts +35 -15
- package/apps/control-plane/src/application/multi-project-loader.ts +27 -10
- package/apps/control-plane/src/application/services/activity-monitor-service.ts +26 -14
- package/apps/control-plane/src/application/services/collision-queue-service.ts +31 -17
- package/apps/control-plane/src/application/services/cost-tracking-service.ts +23 -16
- package/apps/control-plane/src/application/services/dependency-scheduler-service.ts +12 -4
- package/apps/control-plane/src/application/services/feature-deletion-service.ts +94 -58
- package/apps/control-plane/src/application/services/feature-lifecycle-service.ts +19 -13
- package/apps/control-plane/src/application/services/feature-state-service.ts +29 -19
- package/apps/control-plane/src/application/services/gate-interpolation-service.ts +7 -2
- package/apps/control-plane/src/application/services/gate-service.ts +64 -41
- package/apps/control-plane/src/application/services/instance-isolation-service.ts +1 -1
- package/apps/control-plane/src/application/services/issue-tracker-service.ts +49 -38
- package/apps/control-plane/src/application/services/lock-service.ts +75 -49
- package/apps/control-plane/src/application/services/merge-service.ts +91 -50
- package/apps/control-plane/src/application/services/notifier-service.ts +42 -20
- package/apps/control-plane/src/application/services/patch-service.ts +73 -44
- package/apps/control-plane/src/application/services/performance-analytics-service.ts +8 -6
- package/apps/control-plane/src/application/services/plan-service.ts +148 -89
- package/apps/control-plane/src/application/services/policy-loader-service.ts +10 -4
- package/apps/control-plane/src/application/services/pr-monitor-service.ts +33 -14
- package/apps/control-plane/src/application/services/qa-index-service.ts +20 -16
- package/apps/control-plane/src/application/services/reactions-service.ts +30 -15
- package/apps/control-plane/src/application/services/reporting-service.ts +16 -12
- package/apps/control-plane/src/application/services/run-lease-service.ts +138 -81
- package/apps/control-plane/src/application/tools/tool-metadata.ts +5 -5
- package/apps/control-plane/src/application/tools/tool-router.ts +6 -3
- package/apps/control-plane/src/cli/aop.ts +2 -2
- package/apps/control-plane/src/cli/attach-command-handler.ts +9 -9
- package/apps/control-plane/src/cli/cleanup-command-handler.ts +16 -11
- package/apps/control-plane/src/cli/cli-argument-parser.ts +6 -3
- package/apps/control-plane/src/cli/dashboard-command-handler.ts +28 -8
- package/apps/control-plane/src/cli/delete-command-handler.ts +7 -7
- package/apps/control-plane/src/cli/env-file.ts +115 -0
- package/apps/control-plane/src/cli/help-command-handler.ts +61 -32
- package/apps/control-plane/src/cli/init-command-handler.ts +182 -56
- package/apps/control-plane/src/cli/io.ts +7 -3
- package/apps/control-plane/src/cli/resume-command-handler.ts +21 -13
- package/apps/control-plane/src/cli/retry-command-handler.ts +12 -11
- package/apps/control-plane/src/cli/run-command-handler.ts +12 -8
- package/apps/control-plane/src/cli/send-command-handler.ts +6 -6
- package/apps/control-plane/src/cli/spec-ingestion-service.ts +14 -8
- package/apps/control-plane/src/cli/spec-input-resolver.ts +6 -1
- package/apps/control-plane/src/cli/spec-utils.ts +2 -2
- package/apps/control-plane/src/cli/status-command-handler.ts +13 -12
- package/apps/control-plane/src/cli/tooling.ts +3 -3
- package/apps/control-plane/src/cli/types.ts +1 -1
- package/apps/control-plane/src/core/collisions.ts +27 -10
- package/apps/control-plane/src/core/constants.ts +13 -7
- package/apps/control-plane/src/core/error-codes.ts +1 -1
- package/apps/control-plane/src/core/fs.ts +11 -5
- package/apps/control-plane/src/core/gates.ts +53 -27
- package/apps/control-plane/src/core/git.ts +18 -6
- package/apps/control-plane/src/core/kernel.ts +513 -227
- package/apps/control-plane/src/core/patch.ts +7 -3
- package/apps/control-plane/src/core/path-layout.ts +5 -1
- package/apps/control-plane/src/core/path-rules.ts +19 -5
- package/apps/control-plane/src/core/qa-index.ts +26 -12
- package/apps/control-plane/src/core/response.ts +9 -6
- package/apps/control-plane/src/core/schemas.ts +29 -10
- package/apps/control-plane/src/core/tool-caller.ts +1 -1
- package/apps/control-plane/src/core/workspace-hooks.ts +5 -5
- package/apps/control-plane/src/index.ts +3 -9
- package/apps/control-plane/src/interfaces/cli/bootstrap.ts +79 -35
- package/apps/control-plane/src/mcp/kernel-tool-executor.ts +7 -3
- package/apps/control-plane/src/mcp/mcp-server-adapter.ts +12 -10
- package/apps/control-plane/src/mcp/operation-ledger.ts +18 -8
- package/apps/control-plane/src/mcp/protocol-contract.ts +2 -2
- package/apps/control-plane/src/mcp/runtime-factory.ts +15 -6
- package/apps/control-plane/src/mcp/token-auth-verifier.ts +3 -2
- package/apps/control-plane/src/mcp/token-claims-validator.ts +11 -7
- package/apps/control-plane/src/mcp/tool-authorizer.ts +1 -3
- package/apps/control-plane/src/mcp/tool-client.ts +17 -5
- package/apps/control-plane/src/mcp/tool-contract-validator.ts +17 -8
- package/apps/control-plane/src/mcp/tool-registry-loader.ts +7 -3
- package/apps/control-plane/src/mcp/tool-runtime.ts +66 -39
- package/apps/control-plane/src/mcp/tools-markdown-generator.ts +6 -1
- package/apps/control-plane/src/providers/providers.ts +137 -54
- package/apps/control-plane/src/supervisor/build-wave-executor.ts +44 -25
- package/apps/control-plane/src/supervisor/planning-wave-executor.ts +46 -33
- package/apps/control-plane/src/supervisor/prompt-bundle-loader.ts +1 -1
- package/apps/control-plane/src/supervisor/qa-wave-executor.ts +38 -23
- package/apps/control-plane/src/supervisor/run-coordinator.ts +71 -36
- package/apps/control-plane/src/supervisor/runtime.ts +59 -35
- package/apps/control-plane/src/supervisor/session-orchestrator.ts +48 -31
- package/apps/control-plane/src/supervisor/types.ts +22 -7
- package/apps/control-plane/src/supervisor/worker-decision-loop.ts +30 -20
- package/apps/control-plane/test/activity-monitor.spec.ts +54 -30
- package/apps/control-plane/test/adapter-registry.spec.ts +5 -5
- package/apps/control-plane/test/aop.spec.ts +4 -4
- package/apps/control-plane/test/batch-operations.spec.ts +20 -18
- package/apps/control-plane/test/bootstrap-attach.spec.ts +52 -19
- package/apps/control-plane/test/bootstrap-edge-cases.spec.ts +58 -27
- package/apps/control-plane/test/bootstrap.spec.ts +72 -40
- package/apps/control-plane/test/cleanup-command.spec.ts +86 -32
- package/apps/control-plane/test/cli-helpers.spec.ts +119 -66
- package/apps/control-plane/test/cli.spec.ts +1 -1
- package/apps/control-plane/test/cli.unit.spec.ts +226 -167
- package/apps/control-plane/test/collision-queue.spec.ts +49 -40
- package/apps/control-plane/test/collisions.spec.ts +30 -30
- package/apps/control-plane/test/core-utils.spec.ts +29 -15
- package/apps/control-plane/test/cost-tracking.spec.ts +38 -22
- package/apps/control-plane/test/dashboard-api.integration.spec.ts +68 -36
- package/apps/control-plane/test/dashboard-client.spec.ts +18 -12
- package/apps/control-plane/test/dashboard-command.spec.ts +11 -7
- package/apps/control-plane/test/delete-command-handler.spec.ts +49 -41
- package/apps/control-plane/test/dependency-scheduler.spec.ts +47 -20
- package/apps/control-plane/test/epoch-tracking.spec.ts +9 -9
- package/apps/control-plane/test/feature-deletion-service.spec.ts +60 -52
- package/apps/control-plane/test/feature-lifecycle.spec.ts +36 -17
- package/apps/control-plane/test/gates.spec.ts +101 -81
- package/apps/control-plane/test/git-spawn-error.spec.ts +1 -1
- package/apps/control-plane/test/helpers.ts +10 -6
- package/apps/control-plane/test/incremental-gates.spec.ts +59 -20
- package/apps/control-plane/test/init-wizard.spec.ts +328 -68
- package/apps/control-plane/test/instance-isolation.spec.ts +43 -10
- package/apps/control-plane/test/issue-tracker.spec.ts +368 -128
- package/apps/control-plane/test/kernel-collision-replay.spec.ts +50 -29
- package/apps/control-plane/test/kernel.branches.spec.ts +64 -40
- package/apps/control-plane/test/kernel.coverage.spec.ts +85 -49
- package/apps/control-plane/test/kernel.coverage2.spec.ts +109 -65
- package/apps/control-plane/test/kernel.spec.ts +134 -51
- package/apps/control-plane/test/lock-service.spec.ts +92 -68
- package/apps/control-plane/test/mcp-helpers.spec.ts +53 -39
- package/apps/control-plane/test/mcp.spec.ts +231 -115
- package/apps/control-plane/test/merge-service.spec.ts +142 -94
- package/apps/control-plane/test/multi-project.spec.ts +28 -22
- package/apps/control-plane/test/notifier-service.spec.ts +136 -92
- package/apps/control-plane/test/parallel-gates.spec.ts +51 -35
- package/apps/control-plane/test/patch-service.spec.ts +128 -48
- package/apps/control-plane/test/performance-analytics.spec.ts +99 -63
- package/apps/control-plane/test/plan-service.spec.ts +50 -39
- package/apps/control-plane/test/planning-wave-executor.spec.ts +95 -71
- package/apps/control-plane/test/policy-loader-service.spec.ts +41 -19
- package/apps/control-plane/test/pr-monitor.spec.ts +113 -64
- package/apps/control-plane/test/providers.spec.ts +208 -104
- package/apps/control-plane/test/qa-index-service.spec.ts +31 -33
- package/apps/control-plane/test/qa-index.spec.ts +58 -61
- package/apps/control-plane/test/reactions.spec.ts +88 -45
- package/apps/control-plane/test/response.spec.ts +5 -5
- package/apps/control-plane/test/resume-command.spec.ts +121 -80
- package/apps/control-plane/test/run-coordinator.spec.ts +205 -136
- package/apps/control-plane/test/schema-date-time.spec.ts +49 -41
- package/apps/control-plane/test/service-retry-paths.spec.ts +77 -57
- package/apps/control-plane/test/services.spec.ts +147 -129
- package/apps/control-plane/test/session-management.spec.ts +136 -74
- package/apps/control-plane/test/spec-ingestion.spec.ts +23 -21
- package/apps/control-plane/test/spec-input-resolver.spec.ts +11 -10
- package/apps/control-plane/test/supervisor-collaborators.spec.ts +168 -121
- package/apps/control-plane/test/supervisor.calltool.spec.ts +21 -18
- package/apps/control-plane/test/supervisor.spec.ts +67 -43
- package/apps/control-plane/test/supervisor.unit.spec.ts +195 -126
- package/apps/control-plane/test/token-auth-verifier.spec.ts +29 -14
- package/apps/control-plane/test/tool-registry-loader.spec.ts +51 -27
- package/apps/control-plane/test/tool-runtime.spec.ts +63 -46
- package/apps/control-plane/test/worker-decision-loop.spec.ts +143 -122
- package/apps/control-plane/test/workspace-hooks.spec.ts +61 -23
- package/apps/control-plane/tsconfig.build.json +2 -7
- package/apps/control-plane/tsconfig.json +1 -5
- package/apps/control-plane/vitest.config.ts +7 -7
- package/config/agentic/orchestrator/adapters.yaml +3 -0
- package/config/agentic/orchestrator/agents.yaml +14 -0
- package/config/agentic/orchestrator/gates.yaml +28 -0
- package/config/agentic/orchestrator/policy.yaml +22 -0
- package/config/agentic/orchestrator/prompts/builder.system.md +1 -0
- package/config/agentic/orchestrator/prompts/planner.system.md +16 -0
- package/config/agentic/orchestrator/prompts/qa.system.md +1 -0
- package/dist/apps/control-plane/application/adapters/adapter-registry.js +12 -5
- package/dist/apps/control-plane/application/adapters/adapter-registry.js.map +1 -1
- package/dist/apps/control-plane/application/multi-project-loader.js +26 -9
- package/dist/apps/control-plane/application/multi-project-loader.js.map +1 -1
- package/dist/apps/control-plane/application/services/activity-monitor-service.js +7 -7
- package/dist/apps/control-plane/application/services/activity-monitor-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/collision-queue-service.js +7 -7
- package/dist/apps/control-plane/application/services/collision-queue-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/cost-tracking-service.js +6 -8
- package/dist/apps/control-plane/application/services/cost-tracking-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/dependency-scheduler-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/feature-deletion-service.js +37 -29
- package/dist/apps/control-plane/application/services/feature-deletion-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/feature-lifecycle-service.js +10 -10
- package/dist/apps/control-plane/application/services/feature-lifecycle-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/feature-state-service.js +11 -11
- package/dist/apps/control-plane/application/services/feature-state-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/gate-interpolation-service.js +3 -1
- package/dist/apps/control-plane/application/services/gate-interpolation-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/gate-service.js +26 -26
- package/dist/apps/control-plane/application/services/gate-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/instance-isolation-service.js +1 -1
- package/dist/apps/control-plane/application/services/instance-isolation-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/issue-tracker-service.js +25 -15
- package/dist/apps/control-plane/application/services/issue-tracker-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/lock-service.js +32 -32
- package/dist/apps/control-plane/application/services/lock-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/merge-service.js +41 -27
- package/dist/apps/control-plane/application/services/merge-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/notifier-service.js +29 -15
- package/dist/apps/control-plane/application/services/notifier-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/patch-service.js +21 -19
- package/dist/apps/control-plane/application/services/patch-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/performance-analytics-service.js +4 -4
- package/dist/apps/control-plane/application/services/performance-analytics-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/plan-service.js +33 -33
- package/dist/apps/control-plane/application/services/plan-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/policy-loader-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/pr-monitor-service.js +23 -11
- package/dist/apps/control-plane/application/services/pr-monitor-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/qa-index-service.js +11 -11
- package/dist/apps/control-plane/application/services/qa-index-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/reactions-service.js +13 -9
- package/dist/apps/control-plane/application/services/reactions-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/reporting-service.js +11 -9
- package/dist/apps/control-plane/application/services/reporting-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/run-lease-service.js +34 -33
- package/dist/apps/control-plane/application/services/run-lease-service.js.map +1 -1
- package/dist/apps/control-plane/application/tools/tool-metadata.js +2 -2
- package/dist/apps/control-plane/application/tools/tool-router.js.map +1 -1
- package/dist/apps/control-plane/cli/attach-command-handler.js +9 -9
- package/dist/apps/control-plane/cli/cleanup-command-handler.js +11 -9
- package/dist/apps/control-plane/cli/cleanup-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/cli-argument-parser.js +4 -3
- package/dist/apps/control-plane/cli/cli-argument-parser.js.map +1 -1
- package/dist/apps/control-plane/cli/dashboard-command-handler.js +23 -7
- package/dist/apps/control-plane/cli/dashboard-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/delete-command-handler.js +7 -7
- package/dist/apps/control-plane/cli/env-file.d.ts +4 -0
- package/dist/apps/control-plane/cli/env-file.js +89 -0
- package/dist/apps/control-plane/cli/env-file.js.map +1 -0
- package/dist/apps/control-plane/cli/help-command-handler.js +58 -30
- package/dist/apps/control-plane/cli/help-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/init-command-handler.js +97 -37
- package/dist/apps/control-plane/cli/init-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/io.js +2 -2
- package/dist/apps/control-plane/cli/io.js.map +1 -1
- package/dist/apps/control-plane/cli/resume-command-handler.js +9 -9
- package/dist/apps/control-plane/cli/resume-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/retry-command-handler.js +12 -11
- package/dist/apps/control-plane/cli/retry-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/run-command-handler.js +12 -8
- package/dist/apps/control-plane/cli/run-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/send-command-handler.js +6 -6
- package/dist/apps/control-plane/cli/spec-ingestion-service.js +10 -8
- package/dist/apps/control-plane/cli/spec-ingestion-service.js.map +1 -1
- package/dist/apps/control-plane/cli/spec-input-resolver.js.map +1 -1
- package/dist/apps/control-plane/cli/spec-utils.js.map +1 -1
- package/dist/apps/control-plane/cli/status-command-handler.js +8 -8
- package/dist/apps/control-plane/cli/status-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/tooling.js +1 -1
- package/dist/apps/control-plane/core/collisions.js +11 -8
- package/dist/apps/control-plane/core/collisions.js.map +1 -1
- package/dist/apps/control-plane/core/constants.js +13 -7
- package/dist/apps/control-plane/core/constants.js.map +1 -1
- package/dist/apps/control-plane/core/error-codes.js +1 -1
- package/dist/apps/control-plane/core/fs.js.map +1 -1
- package/dist/apps/control-plane/core/gates.d.ts +2 -2
- package/dist/apps/control-plane/core/gates.js +26 -19
- package/dist/apps/control-plane/core/gates.js.map +1 -1
- package/dist/apps/control-plane/core/git.js +3 -3
- package/dist/apps/control-plane/core/git.js.map +1 -1
- package/dist/apps/control-plane/core/kernel.d.ts +1 -0
- package/dist/apps/control-plane/core/kernel.js +134 -81
- package/dist/apps/control-plane/core/kernel.js.map +1 -1
- package/dist/apps/control-plane/core/patch.js +7 -3
- package/dist/apps/control-plane/core/patch.js.map +1 -1
- package/dist/apps/control-plane/core/path-layout.d.ts +1 -0
- package/dist/apps/control-plane/core/path-layout.js +4 -1
- package/dist/apps/control-plane/core/path-layout.js.map +1 -1
- package/dist/apps/control-plane/core/path-rules.js +3 -1
- package/dist/apps/control-plane/core/path-rules.js.map +1 -1
- package/dist/apps/control-plane/core/qa-index.js +5 -5
- package/dist/apps/control-plane/core/qa-index.js.map +1 -1
- package/dist/apps/control-plane/core/response.js +3 -3
- package/dist/apps/control-plane/core/response.js.map +1 -1
- package/dist/apps/control-plane/core/schemas.js +10 -6
- package/dist/apps/control-plane/core/schemas.js.map +1 -1
- package/dist/apps/control-plane/core/workspace-hooks.js +3 -3
- package/dist/apps/control-plane/index.d.ts +1 -1
- package/dist/apps/control-plane/index.js +1 -1
- package/dist/apps/control-plane/index.js.map +1 -1
- package/dist/apps/control-plane/interfaces/cli/bootstrap.js +40 -23
- package/dist/apps/control-plane/interfaces/cli/bootstrap.js.map +1 -1
- package/dist/apps/control-plane/mcp/kernel-tool-executor.js +1 -1
- package/dist/apps/control-plane/mcp/kernel-tool-executor.js.map +1 -1
- package/dist/apps/control-plane/mcp/mcp-server-adapter.js +6 -7
- package/dist/apps/control-plane/mcp/mcp-server-adapter.js.map +1 -1
- package/dist/apps/control-plane/mcp/operation-ledger.js +5 -5
- package/dist/apps/control-plane/mcp/operation-ledger.js.map +1 -1
- package/dist/apps/control-plane/mcp/protocol-contract.js +2 -2
- package/dist/apps/control-plane/mcp/runtime-factory.js +2 -2
- package/dist/apps/control-plane/mcp/runtime-factory.js.map +1 -1
- package/dist/apps/control-plane/mcp/token-auth-verifier.js +1 -1
- package/dist/apps/control-plane/mcp/token-auth-verifier.js.map +1 -1
- package/dist/apps/control-plane/mcp/token-claims-validator.js +5 -5
- package/dist/apps/control-plane/mcp/token-claims-validator.js.map +1 -1
- package/dist/apps/control-plane/mcp/tool-authorizer.js +1 -3
- package/dist/apps/control-plane/mcp/tool-authorizer.js.map +1 -1
- package/dist/apps/control-plane/mcp/tool-client.js +2 -2
- package/dist/apps/control-plane/mcp/tool-client.js.map +1 -1
- package/dist/apps/control-plane/mcp/tool-contract-validator.js +3 -3
- package/dist/apps/control-plane/mcp/tool-contract-validator.js.map +1 -1
- package/dist/apps/control-plane/mcp/tool-registry-loader.js +1 -1
- package/dist/apps/control-plane/mcp/tool-registry-loader.js.map +1 -1
- package/dist/apps/control-plane/mcp/tool-runtime.js +17 -17
- package/dist/apps/control-plane/mcp/tool-runtime.js.map +1 -1
- package/dist/apps/control-plane/mcp/tools-markdown-generator.js +6 -1
- package/dist/apps/control-plane/mcp/tools-markdown-generator.js.map +1 -1
- package/dist/apps/control-plane/providers/providers.d.ts +3 -2
- package/dist/apps/control-plane/providers/providers.js +81 -39
- package/dist/apps/control-plane/providers/providers.js.map +1 -1
- package/dist/apps/control-plane/supervisor/build-wave-executor.js +12 -12
- package/dist/apps/control-plane/supervisor/build-wave-executor.js.map +1 -1
- package/dist/apps/control-plane/supervisor/planning-wave-executor.js +19 -16
- package/dist/apps/control-plane/supervisor/planning-wave-executor.js.map +1 -1
- package/dist/apps/control-plane/supervisor/prompt-bundle-loader.js +1 -1
- package/dist/apps/control-plane/supervisor/qa-wave-executor.js +13 -13
- package/dist/apps/control-plane/supervisor/qa-wave-executor.js.map +1 -1
- package/dist/apps/control-plane/supervisor/run-coordinator.js +37 -20
- package/dist/apps/control-plane/supervisor/run-coordinator.js.map +1 -1
- package/dist/apps/control-plane/supervisor/runtime.js +25 -21
- package/dist/apps/control-plane/supervisor/runtime.js.map +1 -1
- package/dist/apps/control-plane/supervisor/session-orchestrator.js +29 -23
- package/dist/apps/control-plane/supervisor/session-orchestrator.js.map +1 -1
- package/dist/apps/control-plane/supervisor/types.d.ts +3 -3
- package/dist/apps/control-plane/supervisor/types.js.map +1 -1
- package/dist/apps/control-plane/supervisor/worker-decision-loop.js +14 -16
- package/dist/apps/control-plane/supervisor/worker-decision-loop.js.map +1 -1
- package/eslint.config.mjs +20 -20
- package/example-configurations/README.md +1 -1
- package/example-configurations/java/agents.yaml +3 -3
- package/example-configurations/java/policy.yaml +1 -1
- package/example-configurations/node/agents.yaml +3 -3
- package/example-configurations/node/policy.yaml +1 -1
- package/package.json +10 -5
- package/packages/web-dashboard/next.config.js +2 -2
- package/packages/web-dashboard/src/app/api/actions/route.ts +25 -9
- package/packages/web-dashboard/src/app/api/events/route.ts +20 -6
- package/packages/web-dashboard/src/app/api/features/[id]/checkout/route.ts +88 -37
- package/packages/web-dashboard/src/app/api/features/[id]/evidence/[artifact]/route.ts +8 -5
- package/packages/web-dashboard/src/app/api/features/[id]/review/route.ts +27 -9
- package/packages/web-dashboard/src/app/api/features/[id]/route.ts +5 -2
- package/packages/web-dashboard/src/app/api/projects/route.ts +5 -5
- package/packages/web-dashboard/src/app/globals.css +10 -2
- package/packages/web-dashboard/src/app/page.tsx +100 -37
- package/packages/web-dashboard/src/lib/aop-client.ts +68 -37
- package/packages/web-dashboard/src/lib/multi-project-config.ts +28 -7
- package/packages/web-dashboard/src/lib/orchestrator-tools.ts +59 -36
- package/packages/web-dashboard/tsconfig.json +3 -11
- package/scripts/nx-safe.mjs +10 -10
- package/spec-files/completed/agentic_orchestrator_cli_delete_command_spec.md +5 -0
- package/spec-files/completed/agentic_orchestrator_feature_gaps_closure_spec.md +189 -90
- package/spec-files/completed/agentic_orchestrator_init_policy_ux_simplification_spec.md +49 -16
- package/spec-files/completed/agentic_orchestrator_mcp_formalization_spec.md +24 -1
- package/spec-files/completed/agentic_orchestrator_single_global_orchestrator_spec.md +9 -0
- package/spec-files/completed/agentic_orchestrator_spec.md +171 -75
- package/spec-files/completed/agentic_orchestrator_validator_hardening_spec.md +25 -17
- package/spec-files/outstanding/agentic_orchestrator_artifact_database_publishing_spec.md +40 -5
- package/spec-files/outstanding/agentic_orchestrator_enterprise_governance_dashboard_spec.md +23 -12
- package/spec-files/outstanding/agentic_orchestrator_knowledge_canary_spec.md +16 -4
- package/spec-files/outstanding/agentic_orchestrator_observability_integrity_diagnostics_spec.md +42 -2
- package/spec-files/outstanding/agentic_orchestrator_performance_improvements_spec.md +209 -130
- package/spec-files/outstanding/agentic_orchestrator_planning_review_quality_spec.md +56 -3
- package/spec-files/outstanding/agentic_orchestrator_productization_commercial_spec.md +77 -10
- package/spec-files/outstanding/agentic_orchestrator_provider_auth_bootstrap_spec.md +384 -0
- package/spec-files/outstanding/agentic_orchestrator_quality_adoption_execution_spec.md +29 -14
- package/spec-files/progress.md +186 -175
- package/tsconfig.json +2 -8
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
GitHubIssueTracker,
|
|
4
4
|
LinearIssueTracker,
|
|
5
5
|
JiraIssueTracker,
|
|
6
|
-
createIssueTracker
|
|
6
|
+
createIssueTracker,
|
|
7
7
|
} from '../src/application/services/issue-tracker-service.js';
|
|
8
8
|
import type { GhRunner, HttpRunner } from '../src/application/services/issue-tracker-service.js';
|
|
9
9
|
|
|
@@ -12,7 +12,7 @@ function makeGhRunner(stdout: string, exitCode = 0): GhRunner {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
function makeHttpRunner(
|
|
15
|
-
responses: Array<{ status?: number; ok?: boolean; body?: unknown }
|
|
15
|
+
responses: Array<{ status?: number; ok?: boolean; body?: unknown }>,
|
|
16
16
|
): HttpRunner & ReturnType<typeof vi.fn> {
|
|
17
17
|
const queue = [...responses];
|
|
18
18
|
const runner = vi.fn(async () => {
|
|
@@ -26,7 +26,7 @@ function makeHttpRunner(
|
|
|
26
26
|
return {
|
|
27
27
|
status: next.status ?? 200,
|
|
28
28
|
ok: next.ok ?? true,
|
|
29
|
-
body
|
|
29
|
+
body,
|
|
30
30
|
};
|
|
31
31
|
});
|
|
32
32
|
return runner as HttpRunner & ReturnType<typeof vi.fn>;
|
|
@@ -40,7 +40,7 @@ describe('G9: Multi-Tracker Support', () => {
|
|
|
40
40
|
title: 'Add dark mode',
|
|
41
41
|
body: 'Users want dark mode.',
|
|
42
42
|
state: 'OPEN',
|
|
43
|
-
url: 'https://github.com/org/repo/issues/42'
|
|
43
|
+
url: 'https://github.com/org/repo/issues/42',
|
|
44
44
|
});
|
|
45
45
|
const runner = makeGhRunner(payload);
|
|
46
46
|
const tracker = new GitHubIssueTracker({ repo: 'org/repo' }, runner);
|
|
@@ -69,9 +69,11 @@ describe('G9: Multi-Tracker Support', () => {
|
|
|
69
69
|
await tracker.updateIssueStatus('42', 'merged');
|
|
70
70
|
await tracker.addComment('42', 'AOP: status -> merged');
|
|
71
71
|
|
|
72
|
-
expect(runner).toHaveBeenCalledWith(expect.arrayContaining(['issue', 'edit', '42', '--state', 'closed']));
|
|
73
72
|
expect(runner).toHaveBeenCalledWith(
|
|
74
|
-
expect.arrayContaining(['issue', '
|
|
73
|
+
expect.arrayContaining(['issue', 'edit', '42', '--state', 'closed']),
|
|
74
|
+
);
|
|
75
|
+
expect(runner).toHaveBeenCalledWith(
|
|
76
|
+
expect.arrayContaining(['issue', 'comment', '42', '--body', 'AOP: status -> merged']),
|
|
75
77
|
);
|
|
76
78
|
});
|
|
77
79
|
|
|
@@ -95,18 +97,18 @@ describe('G9: Multi-Tracker Support', () => {
|
|
|
95
97
|
title: 'Ship feature flag',
|
|
96
98
|
description: 'Implement rollout toggle',
|
|
97
99
|
url: 'https://linear.app/acme/issue/LIN-123',
|
|
98
|
-
state: { name: 'In Progress' }
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
100
|
+
state: { name: 'In Progress' },
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
},
|
|
103
105
|
]);
|
|
104
106
|
const tracker = new LinearIssueTracker(
|
|
105
107
|
{
|
|
106
108
|
token: 'linear-token',
|
|
107
|
-
base_url: 'https://api.linear.app/graphql'
|
|
109
|
+
base_url: 'https://api.linear.app/graphql',
|
|
108
110
|
},
|
|
109
|
-
httpRunner
|
|
111
|
+
httpRunner,
|
|
110
112
|
);
|
|
111
113
|
|
|
112
114
|
const issue = await tracker.getIssue('LIN-123');
|
|
@@ -116,7 +118,7 @@ describe('G9: Multi-Tracker Support', () => {
|
|
|
116
118
|
title: 'Ship feature flag',
|
|
117
119
|
body: 'Implement rollout toggle',
|
|
118
120
|
status: 'in progress',
|
|
119
|
-
url: 'https://linear.app/acme/issue/LIN-123'
|
|
121
|
+
url: 'https://linear.app/acme/issue/LIN-123',
|
|
120
122
|
});
|
|
121
123
|
expect(httpRunner).toHaveBeenCalledTimes(1);
|
|
122
124
|
expect(httpRunner).toHaveBeenCalledWith(
|
|
@@ -124,9 +126,9 @@ describe('G9: Multi-Tracker Support', () => {
|
|
|
124
126
|
expect.objectContaining({
|
|
125
127
|
method: 'POST',
|
|
126
128
|
headers: expect.objectContaining({
|
|
127
|
-
Authorization: 'Bearer linear-token'
|
|
128
|
-
})
|
|
129
|
-
})
|
|
129
|
+
Authorization: 'Bearer linear-token',
|
|
130
|
+
}),
|
|
131
|
+
}),
|
|
130
132
|
);
|
|
131
133
|
});
|
|
132
134
|
|
|
@@ -141,26 +143,26 @@ describe('G9: Multi-Tracker Support', () => {
|
|
|
141
143
|
title: 'Refactor queue',
|
|
142
144
|
description: '',
|
|
143
145
|
url: 'https://linear.app/acme/issue/LIN-200',
|
|
144
|
-
state: { name: 'Todo' }
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
}
|
|
146
|
+
state: { name: 'Todo' },
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
},
|
|
148
150
|
},
|
|
149
151
|
{
|
|
150
152
|
body: {
|
|
151
153
|
data: {
|
|
152
154
|
issueUpdate: {
|
|
153
|
-
success: true
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
155
|
+
success: true,
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
},
|
|
158
160
|
]);
|
|
159
161
|
const tracker = new LinearIssueTracker(
|
|
160
162
|
{
|
|
161
|
-
state_id_building: 'state_in_progress'
|
|
163
|
+
state_id_building: 'state_in_progress',
|
|
162
164
|
},
|
|
163
|
-
httpRunner
|
|
165
|
+
httpRunner,
|
|
164
166
|
);
|
|
165
167
|
|
|
166
168
|
await tracker.updateIssueStatus('LIN-200', 'building');
|
|
@@ -170,7 +172,7 @@ describe('G9: Multi-Tracker Support', () => {
|
|
|
170
172
|
expect(secondCallBody.query).toContain('issueUpdate');
|
|
171
173
|
expect(secondCallBody.variables).toMatchObject({
|
|
172
174
|
id: 'lin_uuid_2',
|
|
173
|
-
stateId: 'state_in_progress'
|
|
175
|
+
stateId: 'state_in_progress',
|
|
174
176
|
});
|
|
175
177
|
});
|
|
176
178
|
|
|
@@ -185,20 +187,20 @@ describe('G9: Multi-Tracker Support', () => {
|
|
|
185
187
|
title: 'Fix race condition',
|
|
186
188
|
description: '',
|
|
187
189
|
url: 'https://linear.app/acme/issue/LIN-300',
|
|
188
|
-
state: { name: 'Todo' }
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}
|
|
190
|
+
state: { name: 'Todo' },
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
},
|
|
192
194
|
},
|
|
193
195
|
{
|
|
194
196
|
body: {
|
|
195
197
|
data: {
|
|
196
198
|
commentCreate: {
|
|
197
|
-
success: true
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
199
|
+
success: true,
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
},
|
|
203
|
+
},
|
|
202
204
|
]);
|
|
203
205
|
const tracker = new LinearIssueTracker({}, httpRunner);
|
|
204
206
|
|
|
@@ -209,7 +211,7 @@ describe('G9: Multi-Tracker Support', () => {
|
|
|
209
211
|
expect(secondCallBody.query).toContain('commentCreate');
|
|
210
212
|
expect(secondCallBody.variables).toMatchObject({
|
|
211
213
|
issueId: 'lin_uuid_3',
|
|
212
|
-
body: 'AOP: feature status changed to `qa`'
|
|
214
|
+
body: 'AOP: feature status changed to `qa`',
|
|
213
215
|
});
|
|
214
216
|
});
|
|
215
217
|
|
|
@@ -223,7 +225,7 @@ describe('G9: Multi-Tracker Support', () => {
|
|
|
223
225
|
title: '',
|
|
224
226
|
body: '',
|
|
225
227
|
status: 'unknown',
|
|
226
|
-
url: ''
|
|
228
|
+
url: '',
|
|
227
229
|
});
|
|
228
230
|
});
|
|
229
231
|
});
|
|
@@ -237,18 +239,18 @@ describe('G9: Multi-Tracker Support', () => {
|
|
|
237
239
|
fields: {
|
|
238
240
|
summary: 'Fix flaky pipeline',
|
|
239
241
|
description: 'Investigate and stabilize',
|
|
240
|
-
status: { name: 'In Progress' }
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
}
|
|
242
|
+
status: { name: 'In Progress' },
|
|
243
|
+
},
|
|
244
|
+
},
|
|
245
|
+
},
|
|
244
246
|
]);
|
|
245
247
|
const tracker = new JiraIssueTracker(
|
|
246
248
|
{
|
|
247
249
|
base_url: 'https://jira.example.com',
|
|
248
250
|
email: 'dev@example.com',
|
|
249
|
-
token: 'jira-token'
|
|
251
|
+
token: 'jira-token',
|
|
250
252
|
},
|
|
251
|
-
httpRunner
|
|
253
|
+
httpRunner,
|
|
252
254
|
);
|
|
253
255
|
|
|
254
256
|
const issue = await tracker.getIssue('PROJ-42');
|
|
@@ -257,16 +259,16 @@ describe('G9: Multi-Tracker Support', () => {
|
|
|
257
259
|
title: 'Fix flaky pipeline',
|
|
258
260
|
body: 'Investigate and stabilize',
|
|
259
261
|
status: 'in progress',
|
|
260
|
-
url: 'https://jira.example.com/browse/PROJ-42'
|
|
262
|
+
url: 'https://jira.example.com/browse/PROJ-42',
|
|
261
263
|
});
|
|
262
264
|
expect(httpRunner).toHaveBeenCalledWith(
|
|
263
265
|
'https://jira.example.com/rest/api/2/issue/PROJ-42?fields=summary,description,status',
|
|
264
266
|
expect.objectContaining({
|
|
265
267
|
method: 'GET',
|
|
266
268
|
headers: expect.objectContaining({
|
|
267
|
-
Authorization: expect.stringContaining('Basic ')
|
|
268
|
-
})
|
|
269
|
-
})
|
|
269
|
+
Authorization: expect.stringContaining('Basic '),
|
|
270
|
+
}),
|
|
271
|
+
}),
|
|
270
272
|
);
|
|
271
273
|
});
|
|
272
274
|
|
|
@@ -277,20 +279,20 @@ describe('G9: Multi-Tracker Support', () => {
|
|
|
277
279
|
transitions: [
|
|
278
280
|
{ id: '11', name: 'To Do' },
|
|
279
281
|
{ id: '22', name: 'In Progress' },
|
|
280
|
-
{ id: '33', name: 'Done' }
|
|
281
|
-
]
|
|
282
|
-
}
|
|
282
|
+
{ id: '33', name: 'Done' },
|
|
283
|
+
],
|
|
284
|
+
},
|
|
283
285
|
},
|
|
284
286
|
{
|
|
285
|
-
body: {}
|
|
286
|
-
}
|
|
287
|
+
body: {},
|
|
288
|
+
},
|
|
287
289
|
]);
|
|
288
290
|
const tracker = new JiraIssueTracker(
|
|
289
291
|
{
|
|
290
292
|
base_url: 'https://jira.example.com',
|
|
291
|
-
transition_building: 'In Progress'
|
|
293
|
+
transition_building: 'In Progress',
|
|
292
294
|
},
|
|
293
|
-
httpRunner
|
|
295
|
+
httpRunner,
|
|
294
296
|
);
|
|
295
297
|
|
|
296
298
|
await tracker.updateIssueStatus('PROJ-7', 'building');
|
|
@@ -301,8 +303,8 @@ describe('G9: Multi-Tracker Support', () => {
|
|
|
301
303
|
'https://jira.example.com/rest/api/2/issue/PROJ-7/transitions',
|
|
302
304
|
expect.objectContaining({
|
|
303
305
|
method: 'POST',
|
|
304
|
-
body: JSON.stringify({ transition: { id: '22' } })
|
|
305
|
-
})
|
|
306
|
+
body: JSON.stringify({ transition: { id: '22' } }),
|
|
307
|
+
}),
|
|
306
308
|
);
|
|
307
309
|
});
|
|
308
310
|
|
|
@@ -316,8 +318,8 @@ describe('G9: Multi-Tracker Support', () => {
|
|
|
316
318
|
'https://jira.example.com/rest/api/2/issue/PROJ-8/comment',
|
|
317
319
|
expect.objectContaining({
|
|
318
320
|
method: 'POST',
|
|
319
|
-
body: JSON.stringify({ body: 'AOP: feature status changed to `merged`' })
|
|
320
|
-
})
|
|
321
|
+
body: JSON.stringify({ body: 'AOP: feature status changed to `merged`' }),
|
|
322
|
+
}),
|
|
321
323
|
);
|
|
322
324
|
});
|
|
323
325
|
});
|
|
@@ -345,7 +347,8 @@ describe('G9: Multi-Tracker Support', () => {
|
|
|
345
347
|
describe('issue-tracker-service branch coverage', () => {
|
|
346
348
|
describe('createGhRunner', () => {
|
|
347
349
|
it('GIVEN_function_provided_WHEN_createGhRunner_called_THEN_returns_that_function', async () => {
|
|
348
|
-
const { createGhRunner } =
|
|
350
|
+
const { createGhRunner } =
|
|
351
|
+
await import('../src/application/services/issue-tracker-service.js');
|
|
349
352
|
const custom = vi.fn(async () => ({ stdout: 'ok', exitCode: 0 }));
|
|
350
353
|
const runner = createGhRunner(custom as GhRunner);
|
|
351
354
|
expect(runner).toBe(custom);
|
|
@@ -375,8 +378,16 @@ describe('issue-tracker-service branch coverage', () => {
|
|
|
375
378
|
const runner: HttpRunner = async (_url, init) => {
|
|
376
379
|
const body = JSON.parse(init.body as string) as Record<string, unknown>;
|
|
377
380
|
const vars = body['variables'] as Record<string, unknown> | undefined;
|
|
378
|
-
calls.push([
|
|
379
|
-
|
|
381
|
+
calls.push([
|
|
382
|
+
body['query'] as string,
|
|
383
|
+
vars?.['issueId'] as string,
|
|
384
|
+
vars?.['stateId'] as string,
|
|
385
|
+
]);
|
|
386
|
+
return {
|
|
387
|
+
status: 200,
|
|
388
|
+
ok: true,
|
|
389
|
+
body: JSON.stringify({ data: { issueUpdate: { success: true } } }),
|
|
390
|
+
};
|
|
380
391
|
};
|
|
381
392
|
const tracker = new LinearIssueTracker({ token: 'tok', state_blocked: 'state_b' }, runner);
|
|
382
393
|
await tracker.updateIssueStatus('LIN-1', 'blocked');
|
|
@@ -384,7 +395,9 @@ describe('issue-tracker-service branch coverage', () => {
|
|
|
384
395
|
});
|
|
385
396
|
|
|
386
397
|
it('GIVEN_http_failure_WHEN_getIssue_called_THEN_returns_fallback_unknown', async () => {
|
|
387
|
-
const runner: HttpRunner = async () => {
|
|
398
|
+
const runner: HttpRunner = async () => {
|
|
399
|
+
throw new Error('network error');
|
|
400
|
+
};
|
|
388
401
|
const tracker = new LinearIssueTracker({ token: 'tok' }, runner as never);
|
|
389
402
|
const issue = await tracker.getIssue('LIN-999');
|
|
390
403
|
expect(issue.id).toBe('LIN-999');
|
|
@@ -404,14 +417,19 @@ describe('issue-tracker-service branch coverage', () => {
|
|
|
404
417
|
callCount += 1;
|
|
405
418
|
if (url.includes('transitions') && (!init.method || init.method === 'GET')) {
|
|
406
419
|
return {
|
|
407
|
-
status: 200,
|
|
408
|
-
|
|
409
|
-
|
|
420
|
+
status: 200,
|
|
421
|
+
ok: true,
|
|
422
|
+
body: JSON.stringify({
|
|
423
|
+
transitions: [{ id: 't1', name: 'To Do' }],
|
|
424
|
+
}),
|
|
410
425
|
};
|
|
411
426
|
}
|
|
412
427
|
return runner(url, init);
|
|
413
428
|
};
|
|
414
|
-
const tracker = new JiraIssueTracker(
|
|
429
|
+
const tracker = new JiraIssueTracker(
|
|
430
|
+
{ base_url: 'https://jira.example.com', token: 'tok', email: 'me@example.com' },
|
|
431
|
+
mockRunner,
|
|
432
|
+
);
|
|
415
433
|
await tracker.updateIssueStatus('PROJ-1', 'planning');
|
|
416
434
|
expect(callCount).toBeGreaterThan(0);
|
|
417
435
|
});
|
|
@@ -422,7 +440,10 @@ describe('JiraIssueTracker additional branch coverage', () => {
|
|
|
422
440
|
it('GIVEN_requestJson_returns_null_WHEN_getIssue_called_THEN_returns_fallback', async () => {
|
|
423
441
|
// Return non-ok response → requestJson returns null
|
|
424
442
|
const runner: HttpRunner = async () => ({ status: 404, ok: false, body: '' });
|
|
425
|
-
const tracker = new JiraIssueTracker(
|
|
443
|
+
const tracker = new JiraIssueTracker(
|
|
444
|
+
{ base_url: 'https://jira.example.com', token: 'tok' },
|
|
445
|
+
runner,
|
|
446
|
+
);
|
|
426
447
|
const issue = await tracker.getIssue('PROJ-999');
|
|
427
448
|
expect(issue.id).toBe('PROJ-999');
|
|
428
449
|
expect(issue.status).toBe('unknown');
|
|
@@ -434,10 +455,15 @@ describe('JiraIssueTracker additional branch coverage', () => {
|
|
|
434
455
|
calls.push(`${String(init.method ?? 'GET')} ${url}`);
|
|
435
456
|
// Only GET for transitions, no matching transition name
|
|
436
457
|
return {
|
|
437
|
-
status: 200,
|
|
458
|
+
status: 200,
|
|
459
|
+
ok: true,
|
|
460
|
+
body: JSON.stringify({ transitions: [{ id: 'x', name: 'To Do' }] }),
|
|
438
461
|
};
|
|
439
462
|
};
|
|
440
|
-
const tracker = new JiraIssueTracker(
|
|
463
|
+
const tracker = new JiraIssueTracker(
|
|
464
|
+
{ base_url: 'https://jira.example.com', token: 'tok' },
|
|
465
|
+
runner,
|
|
466
|
+
);
|
|
441
467
|
// 'building' maps to 'in progress' but transitions only have 'To Do'
|
|
442
468
|
await tracker.updateIssueStatus('PROJ-1', 'building');
|
|
443
469
|
// Only GET should have been called (no POST)
|
|
@@ -455,9 +481,19 @@ describe('JiraIssueTracker additional branch coverage', () => {
|
|
|
455
481
|
let capturedAuth: string | undefined;
|
|
456
482
|
const runner: HttpRunner = async (_, init) => {
|
|
457
483
|
capturedAuth = (init.headers as Record<string, string>)?.['Authorization'];
|
|
458
|
-
return {
|
|
484
|
+
return {
|
|
485
|
+
status: 200,
|
|
486
|
+
ok: true,
|
|
487
|
+
body: JSON.stringify({
|
|
488
|
+
key: 'PROJ-1',
|
|
489
|
+
fields: { summary: 'Test', status: { name: 'Open' } },
|
|
490
|
+
}),
|
|
491
|
+
};
|
|
459
492
|
};
|
|
460
|
-
const tracker = new JiraIssueTracker(
|
|
493
|
+
const tracker = new JiraIssueTracker(
|
|
494
|
+
{ base_url: 'https://jira.example.com', token: 'mytoken' },
|
|
495
|
+
runner,
|
|
496
|
+
);
|
|
461
497
|
await tracker.getIssue('PROJ-1');
|
|
462
498
|
expect(capturedAuth).toBe('Bearer mytoken');
|
|
463
499
|
});
|
|
@@ -471,10 +507,17 @@ describe('issue-tracker-service additional branch coverage', () => {
|
|
|
471
507
|
ok: true,
|
|
472
508
|
body: JSON.stringify({
|
|
473
509
|
key: 'PROJ-1',
|
|
474
|
-
fields: {
|
|
475
|
-
|
|
510
|
+
fields: {
|
|
511
|
+
summary: 'Test',
|
|
512
|
+
description: { type: 'doc', content: [] },
|
|
513
|
+
status: { name: 'Open' },
|
|
514
|
+
},
|
|
515
|
+
}),
|
|
476
516
|
});
|
|
477
|
-
const tracker = new JiraIssueTracker(
|
|
517
|
+
const tracker = new JiraIssueTracker(
|
|
518
|
+
{ base_url: 'https://jira.example.com', token: 'tok' },
|
|
519
|
+
runner,
|
|
520
|
+
);
|
|
478
521
|
// getIssue passes the description through toJiraDescription when calling addComment
|
|
479
522
|
const issue = await tracker.getIssue('PROJ-1');
|
|
480
523
|
// description field (object) should be stringified
|
|
@@ -489,7 +532,7 @@ describe('issue-tracker-service additional branch coverage', () => {
|
|
|
489
532
|
return {
|
|
490
533
|
status: 200,
|
|
491
534
|
ok: true,
|
|
492
|
-
body: JSON.stringify({ transitions: [{ id: '99', name: 'Custom Done' }] })
|
|
535
|
+
body: JSON.stringify({ transitions: [{ id: '99', name: 'Custom Done' }] }),
|
|
493
536
|
};
|
|
494
537
|
}
|
|
495
538
|
return { status: 204, ok: true, body: '' };
|
|
@@ -497,7 +540,7 @@ describe('issue-tracker-service additional branch coverage', () => {
|
|
|
497
540
|
// config has explicit transition for 'merged' → 'custom done'
|
|
498
541
|
const tracker = new JiraIssueTracker(
|
|
499
542
|
{ base_url: 'https://jira.example.com', token: 'tok', transition_merged: 'custom done' },
|
|
500
|
-
runner
|
|
543
|
+
runner,
|
|
501
544
|
);
|
|
502
545
|
await tracker.updateIssueStatus('PROJ-2', 'merged');
|
|
503
546
|
// POST should have been called since 'custom done' matches 'Custom Done' (case-insensitive)
|
|
@@ -511,15 +554,34 @@ describe('issue-tracker-service additional branch coverage', () => {
|
|
|
511
554
|
// First call: resolveIssueNode → return a valid issue
|
|
512
555
|
if (bodies.length === 1) {
|
|
513
556
|
return {
|
|
514
|
-
status: 200,
|
|
515
|
-
|
|
557
|
+
status: 200,
|
|
558
|
+
ok: true,
|
|
559
|
+
body: JSON.stringify({
|
|
560
|
+
data: {
|
|
561
|
+
issueByIdentifier: {
|
|
562
|
+
id: 'lin-uuid-1',
|
|
563
|
+
identifier: 'LIN-1',
|
|
564
|
+
title: 'T',
|
|
565
|
+
description: '',
|
|
566
|
+
url: '',
|
|
567
|
+
state: { name: 'Backlog' },
|
|
568
|
+
},
|
|
569
|
+
},
|
|
570
|
+
}),
|
|
516
571
|
};
|
|
517
572
|
}
|
|
518
573
|
// Second call: mutation
|
|
519
|
-
return {
|
|
574
|
+
return {
|
|
575
|
+
status: 200,
|
|
576
|
+
ok: true,
|
|
577
|
+
body: JSON.stringify({ data: { issueUpdate: { success: true } } }),
|
|
578
|
+
};
|
|
520
579
|
};
|
|
521
580
|
// Provide state_id_backlog so resolveStateId returns non-null → mutation is called
|
|
522
|
-
const tracker = new LinearIssueTracker(
|
|
581
|
+
const tracker = new LinearIssueTracker(
|
|
582
|
+
{ token: 'tok', state_id_backlog: 'state-backlog-id' },
|
|
583
|
+
runner,
|
|
584
|
+
);
|
|
523
585
|
await tracker.updateIssueStatus('LIN-1', 'planning');
|
|
524
586
|
// mapDefaultLinearStatus('planning') → 'backlog' → state_id_backlog → mutation called
|
|
525
587
|
expect(bodies.length).toBe(2);
|
|
@@ -532,14 +594,33 @@ describe('issue-tracker-service additional branch coverage', () => {
|
|
|
532
594
|
bodies.push((init.body as string) ?? '');
|
|
533
595
|
if (bodies.length === 1) {
|
|
534
596
|
return {
|
|
535
|
-
status: 200,
|
|
536
|
-
|
|
597
|
+
status: 200,
|
|
598
|
+
ok: true,
|
|
599
|
+
body: JSON.stringify({
|
|
600
|
+
data: {
|
|
601
|
+
issueByIdentifier: {
|
|
602
|
+
id: 'lin-uuid-2',
|
|
603
|
+
identifier: 'LIN-2',
|
|
604
|
+
title: 'T',
|
|
605
|
+
description: '',
|
|
606
|
+
url: '',
|
|
607
|
+
state: { name: 'In Review' },
|
|
608
|
+
},
|
|
609
|
+
},
|
|
610
|
+
}),
|
|
537
611
|
};
|
|
538
612
|
}
|
|
539
|
-
return {
|
|
613
|
+
return {
|
|
614
|
+
status: 200,
|
|
615
|
+
ok: true,
|
|
616
|
+
body: JSON.stringify({ data: { issueUpdate: { success: true } } }),
|
|
617
|
+
};
|
|
540
618
|
};
|
|
541
619
|
// Provide state_id_in_review so resolveStateId returns non-null → mutation is called
|
|
542
|
-
const tracker = new LinearIssueTracker(
|
|
620
|
+
const tracker = new LinearIssueTracker(
|
|
621
|
+
{ token: 'tok', state_id_in_review: 'state-inreview-id' },
|
|
622
|
+
runner,
|
|
623
|
+
);
|
|
543
624
|
await tracker.updateIssueStatus('LIN-2', 'qa');
|
|
544
625
|
// mapDefaultLinearStatus('qa') → 'in_review' → state_id_in_review → mutation called
|
|
545
626
|
expect(bodies.length).toBe(2);
|
|
@@ -554,12 +635,15 @@ describe('issue-tracker-service additional branch coverage', () => {
|
|
|
554
635
|
return {
|
|
555
636
|
status: 200,
|
|
556
637
|
ok: true,
|
|
557
|
-
body: JSON.stringify({ transitions: [{ id: '5', name: 'In Progress' }] })
|
|
638
|
+
body: JSON.stringify({ transitions: [{ id: '5', name: 'In Progress' }] }),
|
|
558
639
|
};
|
|
559
640
|
}
|
|
560
641
|
return { status: 204, ok: true, body: '' };
|
|
561
642
|
};
|
|
562
|
-
const tracker = new JiraIssueTracker(
|
|
643
|
+
const tracker = new JiraIssueTracker(
|
|
644
|
+
{ base_url: 'https://jira.example.com', token: 'tok' },
|
|
645
|
+
runner,
|
|
646
|
+
);
|
|
563
647
|
await tracker.updateIssueStatus('PROJ-3', 'building');
|
|
564
648
|
// mapDefaultJiraTransition('building') → 'in progress' → matches 'In Progress'
|
|
565
649
|
expect(calls.some((c) => c.startsWith('POST'))).toBe(true);
|
|
@@ -573,12 +657,15 @@ describe('issue-tracker-service additional branch coverage', () => {
|
|
|
573
657
|
return {
|
|
574
658
|
status: 200,
|
|
575
659
|
ok: true,
|
|
576
|
-
body: JSON.stringify({ transitions: [{ id: '1', name: 'To Do' }] })
|
|
660
|
+
body: JSON.stringify({ transitions: [{ id: '1', name: 'To Do' }] }),
|
|
577
661
|
};
|
|
578
662
|
}
|
|
579
663
|
return { status: 204, ok: true, body: '' };
|
|
580
664
|
};
|
|
581
|
-
const tracker = new JiraIssueTracker(
|
|
665
|
+
const tracker = new JiraIssueTracker(
|
|
666
|
+
{ base_url: 'https://jira.example.com', token: 'tok' },
|
|
667
|
+
runner,
|
|
668
|
+
);
|
|
582
669
|
await tracker.updateIssueStatus('PROJ-4', 'planning');
|
|
583
670
|
// mapDefaultJiraTransition('planning') → 'to do' → matches 'To Do'
|
|
584
671
|
expect(calls.some((c) => c.startsWith('POST'))).toBe(true);
|
|
@@ -592,12 +679,15 @@ describe('issue-tracker-service additional branch coverage', () => {
|
|
|
592
679
|
return {
|
|
593
680
|
status: 200,
|
|
594
681
|
ok: true,
|
|
595
|
-
body: JSON.stringify({ transitions: [{ id: '7', name: 'Blocked' }] })
|
|
682
|
+
body: JSON.stringify({ transitions: [{ id: '7', name: 'Blocked' }] }),
|
|
596
683
|
};
|
|
597
684
|
}
|
|
598
685
|
return { status: 204, ok: true, body: '' };
|
|
599
686
|
};
|
|
600
|
-
const tracker = new JiraIssueTracker(
|
|
687
|
+
const tracker = new JiraIssueTracker(
|
|
688
|
+
{ base_url: 'https://jira.example.com', token: 'tok' },
|
|
689
|
+
runner,
|
|
690
|
+
);
|
|
601
691
|
await tracker.updateIssueStatus('PROJ-5', 'blocked');
|
|
602
692
|
expect(calls.some((c) => c.startsWith('POST'))).toBe(true);
|
|
603
693
|
});
|
|
@@ -605,7 +695,8 @@ describe('issue-tracker-service additional branch coverage', () => {
|
|
|
605
695
|
|
|
606
696
|
describe('Issue tracker additional branch coverage', () => {
|
|
607
697
|
it('GIVEN_createHttpRunner_called_without_fn_WHEN_fetch_throws_THEN_returns_zero_status', async () => {
|
|
608
|
-
const { createHttpRunner } =
|
|
698
|
+
const { createHttpRunner } =
|
|
699
|
+
await import('../src/application/services/issue-tracker-service.js');
|
|
609
700
|
const fetchSpy = vi.spyOn(globalThis, 'fetch').mockRejectedValue(new Error('network error'));
|
|
610
701
|
const runner = createHttpRunner();
|
|
611
702
|
const result = await runner('https://example.com', { method: 'GET' });
|
|
@@ -619,7 +710,7 @@ describe('Issue tracker additional branch coverage', () => {
|
|
|
619
710
|
const runner: HttpRunner = async () => ({
|
|
620
711
|
status: 200,
|
|
621
712
|
ok: true,
|
|
622
|
-
body: JSON.stringify({ data: {}, errors: [{ message: 'GraphQL error' }] })
|
|
713
|
+
body: JSON.stringify({ data: {}, errors: [{ message: 'GraphQL error' }] }),
|
|
623
714
|
});
|
|
624
715
|
const tracker = new LinearIssueTracker({ token: 'tok' }, runner);
|
|
625
716
|
const issue = await tracker.getIssue('LIN-99');
|
|
@@ -632,7 +723,7 @@ describe('Issue tracker additional branch coverage', () => {
|
|
|
632
723
|
const runner: HttpRunner = async () => ({
|
|
633
724
|
status: 200,
|
|
634
725
|
ok: true,
|
|
635
|
-
body: JSON.stringify({ data: null })
|
|
726
|
+
body: JSON.stringify({ data: null }),
|
|
636
727
|
});
|
|
637
728
|
const tracker = new LinearIssueTracker({ token: 'tok' }, runner);
|
|
638
729
|
const issue = await tracker.getIssue('LIN-100');
|
|
@@ -645,14 +736,33 @@ describe('Issue tracker additional branch coverage', () => {
|
|
|
645
736
|
bodies.push((init.body as string) ?? '');
|
|
646
737
|
if (bodies.length === 1) {
|
|
647
738
|
return {
|
|
648
|
-
status: 200,
|
|
649
|
-
|
|
739
|
+
status: 200,
|
|
740
|
+
ok: true,
|
|
741
|
+
body: JSON.stringify({
|
|
742
|
+
data: {
|
|
743
|
+
issueByIdentifier: {
|
|
744
|
+
id: 'lin-uuid-3',
|
|
745
|
+
identifier: 'LIN-3',
|
|
746
|
+
title: 'T',
|
|
747
|
+
description: '',
|
|
748
|
+
url: '',
|
|
749
|
+
state: null,
|
|
750
|
+
},
|
|
751
|
+
},
|
|
752
|
+
}),
|
|
650
753
|
};
|
|
651
754
|
}
|
|
652
|
-
return {
|
|
755
|
+
return {
|
|
756
|
+
status: 200,
|
|
757
|
+
ok: true,
|
|
758
|
+
body: JSON.stringify({ data: { issueUpdate: { success: true } } }),
|
|
759
|
+
};
|
|
653
760
|
};
|
|
654
761
|
// Provide state_id_in_progress to cover the 'in_progress' default mapping for unknown status
|
|
655
|
-
const tracker = new LinearIssueTracker(
|
|
762
|
+
const tracker = new LinearIssueTracker(
|
|
763
|
+
{ token: 'tok', state_id_in_progress: 'state-inprogress-id' },
|
|
764
|
+
runner,
|
|
765
|
+
);
|
|
656
766
|
await tracker.updateIssueStatus('LIN-3', 'some_random_unknown_status');
|
|
657
767
|
// mapDefaultLinearStatus returns 'in_progress' → state_id_in_progress → mutation called
|
|
658
768
|
expect(bodies.length).toBe(2);
|
|
@@ -664,8 +774,20 @@ describe('Issue tracker additional branch coverage', () => {
|
|
|
664
774
|
callCount += 1;
|
|
665
775
|
if (callCount === 1) {
|
|
666
776
|
return {
|
|
667
|
-
status: 200,
|
|
668
|
-
|
|
777
|
+
status: 200,
|
|
778
|
+
ok: true,
|
|
779
|
+
body: JSON.stringify({
|
|
780
|
+
data: {
|
|
781
|
+
issueByIdentifier: {
|
|
782
|
+
id: 'lin-uuid-4',
|
|
783
|
+
identifier: 'LIN-4',
|
|
784
|
+
title: 'T',
|
|
785
|
+
description: '',
|
|
786
|
+
url: '',
|
|
787
|
+
state: null,
|
|
788
|
+
},
|
|
789
|
+
},
|
|
790
|
+
}),
|
|
669
791
|
};
|
|
670
792
|
}
|
|
671
793
|
return { status: 200, ok: true, body: JSON.stringify({ data: {} }) };
|
|
@@ -681,9 +803,19 @@ describe('Issue tracker additional branch coverage', () => {
|
|
|
681
803
|
const calls: { auth?: string }[] = [];
|
|
682
804
|
const runner: HttpRunner = async (_, init) => {
|
|
683
805
|
calls.push({ auth: (init.headers as Record<string, string>)['Authorization'] });
|
|
684
|
-
return {
|
|
806
|
+
return {
|
|
807
|
+
status: 200,
|
|
808
|
+
ok: true,
|
|
809
|
+
body: JSON.stringify({
|
|
810
|
+
key: 'PROJ-1',
|
|
811
|
+
fields: { summary: 'Test', description: 'Body', status: { name: 'Open' } },
|
|
812
|
+
}),
|
|
813
|
+
};
|
|
685
814
|
};
|
|
686
|
-
const tracker = new JiraIssueTracker(
|
|
815
|
+
const tracker = new JiraIssueTracker(
|
|
816
|
+
{ base_url: 'https://jira.example.com', token: 'my-token' },
|
|
817
|
+
runner,
|
|
818
|
+
);
|
|
687
819
|
const issue = await tracker.getIssue('PROJ-1');
|
|
688
820
|
expect(issue.title).toBe('Test');
|
|
689
821
|
expect(calls[0].auth).toMatch(/^Bearer /);
|
|
@@ -701,9 +833,16 @@ describe('Issue tracker additional branch coverage', () => {
|
|
|
701
833
|
const calls: string[] = [];
|
|
702
834
|
const runner: HttpRunner = async (_url, init) => {
|
|
703
835
|
calls.push(init.method ?? 'GET');
|
|
704
|
-
return {
|
|
836
|
+
return {
|
|
837
|
+
status: 200,
|
|
838
|
+
ok: true,
|
|
839
|
+
body: JSON.stringify({ transitions: [{ id: '1', name: 'Open' }] }),
|
|
840
|
+
};
|
|
705
841
|
};
|
|
706
|
-
const tracker = new JiraIssueTracker(
|
|
842
|
+
const tracker = new JiraIssueTracker(
|
|
843
|
+
{ base_url: 'https://jira.example.com', token: 'tok' },
|
|
844
|
+
runner,
|
|
845
|
+
);
|
|
707
846
|
await tracker.updateIssueStatus('PROJ-1', 'merged'); // mapDefaultJiraTransition → 'done', no matching transition
|
|
708
847
|
expect(calls.filter((m) => m === 'POST')).toHaveLength(0);
|
|
709
848
|
});
|
|
@@ -712,7 +851,14 @@ describe('Issue tracker additional branch coverage', () => {
|
|
|
712
851
|
const calls: { hasAuth: boolean }[] = [];
|
|
713
852
|
const runner: HttpRunner = async (_, init) => {
|
|
714
853
|
calls.push({ hasAuth: 'Authorization' in (init.headers as Record<string, string>) });
|
|
715
|
-
return {
|
|
854
|
+
return {
|
|
855
|
+
status: 200,
|
|
856
|
+
ok: true,
|
|
857
|
+
body: JSON.stringify({
|
|
858
|
+
key: 'PROJ-1',
|
|
859
|
+
fields: { summary: '', description: null, status: { name: 'Open' } },
|
|
860
|
+
}),
|
|
861
|
+
};
|
|
716
862
|
};
|
|
717
863
|
const tracker = new JiraIssueTracker({ base_url: 'https://jira.example.com' }, runner);
|
|
718
864
|
await tracker.getIssue('PROJ-1');
|
|
@@ -728,17 +874,21 @@ describe('Issue tracker additional branch coverage', () => {
|
|
|
728
874
|
|
|
729
875
|
it('GIVEN_jira_description_is_object_WHEN_getIssue_called_THEN_returns_json_string', async () => {
|
|
730
876
|
const runner: HttpRunner = async () => ({
|
|
731
|
-
status: 200,
|
|
877
|
+
status: 200,
|
|
878
|
+
ok: true,
|
|
732
879
|
body: JSON.stringify({
|
|
733
880
|
key: 'PROJ-2',
|
|
734
881
|
fields: {
|
|
735
882
|
summary: 'Test',
|
|
736
883
|
description: { type: 'doc', content: [] },
|
|
737
|
-
status: { name: 'In Progress' }
|
|
738
|
-
}
|
|
739
|
-
})
|
|
884
|
+
status: { name: 'In Progress' },
|
|
885
|
+
},
|
|
886
|
+
}),
|
|
740
887
|
});
|
|
741
|
-
const tracker = new JiraIssueTracker(
|
|
888
|
+
const tracker = new JiraIssueTracker(
|
|
889
|
+
{ base_url: 'https://jira.example.com', token: 'tok' },
|
|
890
|
+
runner,
|
|
891
|
+
);
|
|
742
892
|
const issue = await tracker.getIssue('PROJ-2');
|
|
743
893
|
expect(issue.body).toContain('doc');
|
|
744
894
|
});
|
|
@@ -750,7 +900,7 @@ describe('LinearIssueTracker addComment and updateIssueStatus guard branches', (
|
|
|
750
900
|
const runner: HttpRunner = async () => ({
|
|
751
901
|
status: 200,
|
|
752
902
|
ok: true,
|
|
753
|
-
body: JSON.stringify({ data: { issueByIdentifier: null } })
|
|
903
|
+
body: JSON.stringify({ data: { issueByIdentifier: null } }),
|
|
754
904
|
});
|
|
755
905
|
// Should not throw and should not call graphql mutation
|
|
756
906
|
let callCount = 0;
|
|
@@ -769,7 +919,9 @@ describe('LinearIssueTracker addComment and updateIssueStatus guard branches', (
|
|
|
769
919
|
const runner: HttpRunner = async () => ({
|
|
770
920
|
status: 200,
|
|
771
921
|
ok: true,
|
|
772
|
-
body: JSON.stringify({
|
|
922
|
+
body: JSON.stringify({
|
|
923
|
+
data: { issueByIdentifier: { identifier: 'LIN-1', title: 'T', description: '', url: '' } },
|
|
924
|
+
}),
|
|
773
925
|
});
|
|
774
926
|
const tracker = new LinearIssueTracker({}, runner);
|
|
775
927
|
await expect(tracker.addComment('LIN-1', 'comment')).resolves.toBeUndefined();
|
|
@@ -779,7 +931,7 @@ describe('LinearIssueTracker addComment and updateIssueStatus guard branches', (
|
|
|
779
931
|
const runner: HttpRunner = async () => ({
|
|
780
932
|
status: 200,
|
|
781
933
|
ok: true,
|
|
782
|
-
body: JSON.stringify({ data: { issueByIdentifier: null } })
|
|
934
|
+
body: JSON.stringify({ data: { issueByIdentifier: null } }),
|
|
783
935
|
});
|
|
784
936
|
const tracker = new LinearIssueTracker({ token: 'tok', state_id_building: 'state-id' }, runner);
|
|
785
937
|
await expect(tracker.updateIssueStatus('LIN-999', 'building')).resolves.toBeUndefined();
|
|
@@ -792,7 +944,7 @@ describe('LinearIssueTracker graphQl invalid body branch', () => {
|
|
|
792
944
|
const runner: HttpRunner = async () => ({
|
|
793
945
|
status: 200,
|
|
794
946
|
ok: true,
|
|
795
|
-
body: 'not valid json {{ response'
|
|
947
|
+
body: 'not valid json {{ response',
|
|
796
948
|
});
|
|
797
949
|
const tracker = new LinearIssueTracker({}, runner);
|
|
798
950
|
const issue = await tracker.getIssue('LIN-invalid-json');
|
|
@@ -805,7 +957,7 @@ describe('LinearIssueTracker graphQl invalid body branch', () => {
|
|
|
805
957
|
const runner: HttpRunner = async () => ({
|
|
806
958
|
status: 200,
|
|
807
959
|
ok: true,
|
|
808
|
-
body: ''
|
|
960
|
+
body: '',
|
|
809
961
|
});
|
|
810
962
|
const tracker = new LinearIssueTracker({}, runner);
|
|
811
963
|
const issue = await tracker.getIssue('LIN-empty-body');
|
|
@@ -821,12 +973,34 @@ describe('LinearIssueTracker mapDefaultLinearStatus building branch', () => {
|
|
|
821
973
|
const runner: HttpRunner = async () => {
|
|
822
974
|
callCount++;
|
|
823
975
|
if (callCount === 1) {
|
|
824
|
-
return {
|
|
976
|
+
return {
|
|
977
|
+
status: 200,
|
|
978
|
+
ok: true,
|
|
979
|
+
body: JSON.stringify({
|
|
980
|
+
data: {
|
|
981
|
+
issueByIdentifier: {
|
|
982
|
+
id: 'lin-uuid-build',
|
|
983
|
+
identifier: 'LIN-B',
|
|
984
|
+
title: 'T',
|
|
985
|
+
description: '',
|
|
986
|
+
url: '',
|
|
987
|
+
state: null,
|
|
988
|
+
},
|
|
989
|
+
},
|
|
990
|
+
}),
|
|
991
|
+
};
|
|
825
992
|
}
|
|
826
|
-
return {
|
|
993
|
+
return {
|
|
994
|
+
status: 200,
|
|
995
|
+
ok: true,
|
|
996
|
+
body: JSON.stringify({ data: { issueUpdate: { success: true } } }),
|
|
997
|
+
};
|
|
827
998
|
};
|
|
828
999
|
// No state_id_building but has state_id_in_progress → mapDefaultLinearStatus('building') → 'in_progress'
|
|
829
|
-
const tracker = new LinearIssueTracker(
|
|
1000
|
+
const tracker = new LinearIssueTracker(
|
|
1001
|
+
{ token: 'tok', state_id_in_progress: 'state-ip-id' },
|
|
1002
|
+
runner,
|
|
1003
|
+
);
|
|
830
1004
|
await tracker.updateIssueStatus('LIN-B', 'building');
|
|
831
1005
|
// Mutation should be called (callCount > 2 if resolveIssueNode needs 2 calls)
|
|
832
1006
|
expect(callCount).toBeGreaterThan(1);
|
|
@@ -840,11 +1014,33 @@ describe('LinearIssueTracker mapDefaultLinearStatus OR branches and lowerCaseSta
|
|
|
840
1014
|
const runner: HttpRunner = async () => {
|
|
841
1015
|
callCount++;
|
|
842
1016
|
if (callCount === 1) {
|
|
843
|
-
return {
|
|
1017
|
+
return {
|
|
1018
|
+
status: 200,
|
|
1019
|
+
ok: true,
|
|
1020
|
+
body: JSON.stringify({
|
|
1021
|
+
data: {
|
|
1022
|
+
issueByIdentifier: {
|
|
1023
|
+
id: 'lin-closed',
|
|
1024
|
+
identifier: 'LIN-C',
|
|
1025
|
+
title: 'T',
|
|
1026
|
+
description: '',
|
|
1027
|
+
url: '',
|
|
1028
|
+
state: null,
|
|
1029
|
+
},
|
|
1030
|
+
},
|
|
1031
|
+
}),
|
|
1032
|
+
};
|
|
844
1033
|
}
|
|
845
|
-
return {
|
|
1034
|
+
return {
|
|
1035
|
+
status: 200,
|
|
1036
|
+
ok: true,
|
|
1037
|
+
body: JSON.stringify({ data: { issueUpdate: { success: true } } }),
|
|
1038
|
+
};
|
|
846
1039
|
};
|
|
847
|
-
const tracker = new LinearIssueTracker(
|
|
1040
|
+
const tracker = new LinearIssueTracker(
|
|
1041
|
+
{ token: 'tok', state_id_done: 'state-done-id' },
|
|
1042
|
+
runner,
|
|
1043
|
+
);
|
|
848
1044
|
await tracker.updateIssueStatus('LIN-C', 'closed');
|
|
849
1045
|
expect(callCount).toBeGreaterThan(1);
|
|
850
1046
|
});
|
|
@@ -855,11 +1051,33 @@ describe('LinearIssueTracker mapDefaultLinearStatus OR branches and lowerCaseSta
|
|
|
855
1051
|
const runner: HttpRunner = async () => {
|
|
856
1052
|
callCount++;
|
|
857
1053
|
if (callCount === 1) {
|
|
858
|
-
return {
|
|
1054
|
+
return {
|
|
1055
|
+
status: 200,
|
|
1056
|
+
ok: true,
|
|
1057
|
+
body: JSON.stringify({
|
|
1058
|
+
data: {
|
|
1059
|
+
issueByIdentifier: {
|
|
1060
|
+
id: 'lin-failed',
|
|
1061
|
+
identifier: 'LIN-F',
|
|
1062
|
+
title: 'T',
|
|
1063
|
+
description: '',
|
|
1064
|
+
url: '',
|
|
1065
|
+
state: null,
|
|
1066
|
+
},
|
|
1067
|
+
},
|
|
1068
|
+
}),
|
|
1069
|
+
};
|
|
859
1070
|
}
|
|
860
|
-
return {
|
|
1071
|
+
return {
|
|
1072
|
+
status: 200,
|
|
1073
|
+
ok: true,
|
|
1074
|
+
body: JSON.stringify({ data: { issueUpdate: { success: true } } }),
|
|
1075
|
+
};
|
|
861
1076
|
};
|
|
862
|
-
const tracker = new LinearIssueTracker(
|
|
1077
|
+
const tracker = new LinearIssueTracker(
|
|
1078
|
+
{ token: 'tok', state_id_blocked: 'state-blocked-id' },
|
|
1079
|
+
runner,
|
|
1080
|
+
);
|
|
863
1081
|
await tracker.updateIssueStatus('LIN-F', 'failed');
|
|
864
1082
|
expect(callCount).toBeGreaterThan(1);
|
|
865
1083
|
});
|
|
@@ -869,7 +1087,18 @@ describe('LinearIssueTracker mapDefaultLinearStatus OR branches and lowerCaseSta
|
|
|
869
1087
|
const runner: HttpRunner = async () => ({
|
|
870
1088
|
status: 200,
|
|
871
1089
|
ok: true,
|
|
872
|
-
body: JSON.stringify({
|
|
1090
|
+
body: JSON.stringify({
|
|
1091
|
+
data: {
|
|
1092
|
+
issueByIdentifier: {
|
|
1093
|
+
id: 'lin-nostate',
|
|
1094
|
+
identifier: 'LIN-NS',
|
|
1095
|
+
title: 'No State',
|
|
1096
|
+
description: 'desc',
|
|
1097
|
+
url: 'https://x',
|
|
1098
|
+
state: null,
|
|
1099
|
+
},
|
|
1100
|
+
},
|
|
1101
|
+
}),
|
|
873
1102
|
});
|
|
874
1103
|
const tracker = new LinearIssueTracker({}, runner);
|
|
875
1104
|
const issue = await tracker.getIssue('LIN-NS');
|
|
@@ -881,7 +1110,18 @@ describe('LinearIssueTracker mapDefaultLinearStatus OR branches and lowerCaseSta
|
|
|
881
1110
|
const runner: HttpRunner = async () => ({
|
|
882
1111
|
status: 200,
|
|
883
1112
|
ok: true,
|
|
884
|
-
body: JSON.stringify({
|
|
1113
|
+
body: JSON.stringify({
|
|
1114
|
+
data: {
|
|
1115
|
+
issueByIdentifier: {
|
|
1116
|
+
id: 'lin-raw-id',
|
|
1117
|
+
identifier: '',
|
|
1118
|
+
title: 'T',
|
|
1119
|
+
description: 'desc',
|
|
1120
|
+
url: 'https://x',
|
|
1121
|
+
state: { name: 'In Progress' },
|
|
1122
|
+
},
|
|
1123
|
+
},
|
|
1124
|
+
}),
|
|
885
1125
|
});
|
|
886
1126
|
const tracker = new LinearIssueTracker({}, runner);
|
|
887
1127
|
const issue = await tracker.getIssue('LIN-NOID');
|