agentic-orchestrator 0.1.26 → 0.1.28

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.
Files changed (172) hide show
  1. package/AGENTS.md +2 -2
  2. package/CLAUDE.md +2 -2
  3. package/README.md +47 -14
  4. package/agentic/orchestrator/agents.yaml +13 -0
  5. package/agentic/orchestrator/policy.yaml +3 -0
  6. package/agentic/orchestrator/schemas/agents.schema.json +76 -0
  7. package/agentic/orchestrator/schemas/policy.schema.json +16 -0
  8. package/agentic/orchestrator/schemas/policy.user.schema.json +16 -0
  9. package/agentic/orchestrator/schemas/state.schema.json +53 -0
  10. package/apps/control-plane/src/application/configuration-service.ts +181 -0
  11. package/apps/control-plane/src/application/kernel-tool-wiring.ts +292 -0
  12. package/apps/control-plane/src/application/services/checkpoint-service.ts +523 -0
  13. package/apps/control-plane/src/application/services/feature-send-message-service.ts +132 -0
  14. package/apps/control-plane/src/application/services/patch-service.ts +29 -5
  15. package/apps/control-plane/src/application/services/repo-operations-service.ts +276 -0
  16. package/apps/control-plane/src/application/services/worktree-watchdog-service.ts +156 -0
  17. package/apps/control-plane/src/cli/cli-argument-parser.ts +12 -0
  18. package/apps/control-plane/src/cli/help-command-handler.ts +17 -0
  19. package/apps/control-plane/src/cli/init-command-handler.ts +31 -0
  20. package/apps/control-plane/src/cli/resume-command-handler.ts +31 -4
  21. package/apps/control-plane/src/cli/rollback-command-handler.ts +217 -0
  22. package/apps/control-plane/src/cli/run-command-handler.ts +8 -0
  23. package/apps/control-plane/src/cli/types.ts +3 -0
  24. package/apps/control-plane/src/core/kernel-types.ts +55 -0
  25. package/apps/control-plane/src/core/kernel.ts +61 -878
  26. package/apps/control-plane/src/core/tool-caller.ts +10 -0
  27. package/apps/control-plane/src/core/utils/field-readers.ts +38 -0
  28. package/apps/control-plane/src/core/utils/index-normalizer.ts +119 -0
  29. package/apps/control-plane/src/core/utils/path-normalizers.ts +22 -0
  30. package/apps/control-plane/src/interfaces/cli/bootstrap.ts +15 -0
  31. package/apps/control-plane/src/providers/api-worker-provider.ts +14 -12
  32. package/apps/control-plane/src/providers/cli-worker-provider.ts +82 -12
  33. package/apps/control-plane/src/providers/providers.ts +45 -24
  34. package/apps/control-plane/src/providers/worker-provider-factory.ts +36 -1
  35. package/apps/control-plane/src/supervisor/run-coordinator.ts +91 -36
  36. package/apps/control-plane/src/supervisor/runtime.ts +107 -1
  37. package/apps/control-plane/src/supervisor/types.ts +9 -0
  38. package/apps/control-plane/src/supervisor/worker-decision-loop.ts +253 -14
  39. package/apps/control-plane/test/checkpoint-service.spec.ts +537 -0
  40. package/apps/control-plane/test/cli-helpers.spec.ts +28 -0
  41. package/apps/control-plane/test/cli.unit.spec.ts +52 -0
  42. package/apps/control-plane/test/configuration-service.spec.ts +466 -0
  43. package/apps/control-plane/test/dashboard-api.integration.spec.ts +537 -0
  44. package/apps/control-plane/test/dashboard-client.spec.ts +233 -0
  45. package/apps/control-plane/test/feature-send-message-service.spec.ts +314 -0
  46. package/apps/control-plane/test/init-wizard.spec.ts +35 -0
  47. package/apps/control-plane/test/path-normalizers.spec.ts +41 -0
  48. package/apps/control-plane/test/repo-operations-service.spec.ts +339 -0
  49. package/apps/control-plane/test/resume-command.spec.ts +33 -0
  50. package/apps/control-plane/test/review-workspace-logic.spec.ts +130 -0
  51. package/apps/control-plane/test/rollback-command.spec.ts +208 -0
  52. package/apps/control-plane/test/run-coordinator.spec.ts +119 -0
  53. package/apps/control-plane/test/worker-decision-loop.spec.ts +209 -0
  54. package/apps/control-plane/test/worker-provider-adapters.spec.ts +102 -0
  55. package/apps/control-plane/test/worker-provider-factory.spec.ts +14 -0
  56. package/apps/control-plane/test/worktree-watchdog-service.spec.ts +147 -0
  57. package/config/agentic/orchestrator/agents.yaml +13 -0
  58. package/dist/apps/control-plane/application/configuration-service.d.ts +19 -0
  59. package/dist/apps/control-plane/application/configuration-service.js +123 -0
  60. package/dist/apps/control-plane/application/configuration-service.js.map +1 -0
  61. package/dist/apps/control-plane/application/kernel-tool-wiring.d.ts +39 -0
  62. package/dist/apps/control-plane/application/kernel-tool-wiring.js +38 -0
  63. package/dist/apps/control-plane/application/kernel-tool-wiring.js.map +1 -0
  64. package/dist/apps/control-plane/application/services/checkpoint-service.d.ts +84 -0
  65. package/dist/apps/control-plane/application/services/checkpoint-service.js +367 -0
  66. package/dist/apps/control-plane/application/services/checkpoint-service.js.map +1 -0
  67. package/dist/apps/control-plane/application/services/feature-send-message-service.d.ts +25 -0
  68. package/dist/apps/control-plane/application/services/feature-send-message-service.js +105 -0
  69. package/dist/apps/control-plane/application/services/feature-send-message-service.js.map +1 -0
  70. package/dist/apps/control-plane/application/services/patch-service.d.ts +6 -0
  71. package/dist/apps/control-plane/application/services/patch-service.js +11 -2
  72. package/dist/apps/control-plane/application/services/patch-service.js.map +1 -1
  73. package/dist/apps/control-plane/application/services/repo-operations-service.d.ts +70 -0
  74. package/dist/apps/control-plane/application/services/repo-operations-service.js +213 -0
  75. package/dist/apps/control-plane/application/services/repo-operations-service.js.map +1 -0
  76. package/dist/apps/control-plane/application/services/worktree-watchdog-service.d.ts +23 -0
  77. package/dist/apps/control-plane/application/services/worktree-watchdog-service.js +119 -0
  78. package/dist/apps/control-plane/application/services/worktree-watchdog-service.js.map +1 -0
  79. package/dist/apps/control-plane/cli/cli-argument-parser.js +12 -0
  80. package/dist/apps/control-plane/cli/cli-argument-parser.js.map +1 -1
  81. package/dist/apps/control-plane/cli/help-command-handler.js +17 -0
  82. package/dist/apps/control-plane/cli/help-command-handler.js.map +1 -1
  83. package/dist/apps/control-plane/cli/init-command-handler.js +23 -0
  84. package/dist/apps/control-plane/cli/init-command-handler.js.map +1 -1
  85. package/dist/apps/control-plane/cli/resume-command-handler.js +25 -5
  86. package/dist/apps/control-plane/cli/resume-command-handler.js.map +1 -1
  87. package/dist/apps/control-plane/cli/rollback-command-handler.d.ts +6 -0
  88. package/dist/apps/control-plane/cli/rollback-command-handler.js +177 -0
  89. package/dist/apps/control-plane/cli/rollback-command-handler.js.map +1 -0
  90. package/dist/apps/control-plane/cli/run-command-handler.js +7 -1
  91. package/dist/apps/control-plane/cli/run-command-handler.js.map +1 -1
  92. package/dist/apps/control-plane/cli/types.d.ts +3 -0
  93. package/dist/apps/control-plane/cli/types.js +1 -0
  94. package/dist/apps/control-plane/cli/types.js.map +1 -1
  95. package/dist/apps/control-plane/core/configuration-service.d.ts +25 -0
  96. package/dist/apps/control-plane/core/configuration-service.js +130 -0
  97. package/dist/apps/control-plane/core/configuration-service.js.map +1 -0
  98. package/dist/apps/control-plane/core/kernel-tool-wiring.d.ts +50 -0
  99. package/dist/apps/control-plane/core/kernel-tool-wiring.js +44 -0
  100. package/dist/apps/control-plane/core/kernel-tool-wiring.js.map +1 -0
  101. package/dist/apps/control-plane/core/kernel-types.d.ts +48 -0
  102. package/dist/apps/control-plane/core/kernel-types.js +2 -0
  103. package/dist/apps/control-plane/core/kernel-types.js.map +1 -0
  104. package/dist/apps/control-plane/core/kernel.d.ts +17 -48
  105. package/dist/apps/control-plane/core/kernel.js +44 -539
  106. package/dist/apps/control-plane/core/kernel.js.map +1 -1
  107. package/dist/apps/control-plane/core/tool-caller.d.ts +10 -0
  108. package/dist/apps/control-plane/core/utils/error-normalizer.d.ts +2 -0
  109. package/dist/apps/control-plane/core/utils/error-normalizer.js +51 -0
  110. package/dist/apps/control-plane/core/utils/error-normalizer.js.map +1 -0
  111. package/dist/apps/control-plane/core/utils/field-readers.d.ts +9 -0
  112. package/dist/apps/control-plane/core/utils/field-readers.js +30 -0
  113. package/dist/apps/control-plane/core/utils/field-readers.js.map +1 -0
  114. package/dist/apps/control-plane/core/utils/index-normalizer.d.ts +7 -0
  115. package/dist/apps/control-plane/core/utils/index-normalizer.js +92 -0
  116. package/dist/apps/control-plane/core/utils/index-normalizer.js.map +1 -0
  117. package/dist/apps/control-plane/core/utils/path-normalizers.d.ts +2 -0
  118. package/dist/apps/control-plane/core/utils/path-normalizers.js +17 -0
  119. package/dist/apps/control-plane/core/utils/path-normalizers.js.map +1 -0
  120. package/dist/apps/control-plane/interfaces/cli/bootstrap.js +13 -1
  121. package/dist/apps/control-plane/interfaces/cli/bootstrap.js.map +1 -1
  122. package/dist/apps/control-plane/providers/api-worker-provider.d.ts +4 -13
  123. package/dist/apps/control-plane/providers/api-worker-provider.js +10 -0
  124. package/dist/apps/control-plane/providers/api-worker-provider.js.map +1 -1
  125. package/dist/apps/control-plane/providers/cli-worker-provider.d.ts +11 -13
  126. package/dist/apps/control-plane/providers/cli-worker-provider.js +64 -0
  127. package/dist/apps/control-plane/providers/cli-worker-provider.js.map +1 -1
  128. package/dist/apps/control-plane/providers/providers.d.ts +31 -24
  129. package/dist/apps/control-plane/providers/providers.js +10 -0
  130. package/dist/apps/control-plane/providers/providers.js.map +1 -1
  131. package/dist/apps/control-plane/providers/worker-provider-factory.d.ts +11 -0
  132. package/dist/apps/control-plane/providers/worker-provider-factory.js +20 -1
  133. package/dist/apps/control-plane/providers/worker-provider-factory.js.map +1 -1
  134. package/dist/apps/control-plane/supervisor/run-coordinator.d.ts +3 -0
  135. package/dist/apps/control-plane/supervisor/run-coordinator.js +81 -33
  136. package/dist/apps/control-plane/supervisor/run-coordinator.js.map +1 -1
  137. package/dist/apps/control-plane/supervisor/runtime.d.ts +8 -1
  138. package/dist/apps/control-plane/supervisor/runtime.js +90 -0
  139. package/dist/apps/control-plane/supervisor/runtime.js.map +1 -1
  140. package/dist/apps/control-plane/supervisor/types.d.ts +11 -0
  141. package/dist/apps/control-plane/supervisor/types.js.map +1 -1
  142. package/dist/apps/control-plane/supervisor/worker-decision-loop.d.ts +21 -1
  143. package/dist/apps/control-plane/supervisor/worker-decision-loop.js +207 -13
  144. package/dist/apps/control-plane/supervisor/worker-decision-loop.js.map +1 -1
  145. package/package.json +1 -1
  146. package/packages/web-dashboard/package.json +2 -0
  147. package/packages/web-dashboard/src/app/analytics/page.tsx +83 -2
  148. package/packages/web-dashboard/src/app/api/actions/route.ts +92 -1
  149. package/packages/web-dashboard/src/app/api/analytics/route.ts +5 -2
  150. package/packages/web-dashboard/src/app/api/features/[id]/checkpoints/[checkpointId]/diff/route.ts +43 -0
  151. package/packages/web-dashboard/src/app/api/features/[id]/checkpoints/compare/route.ts +45 -0
  152. package/packages/web-dashboard/src/app/api/features/[id]/checkpoints/stream/route.ts +170 -0
  153. package/packages/web-dashboard/src/app/api/features/[id]/file-diff/route.ts +144 -0
  154. package/packages/web-dashboard/src/app/api/features/[id]/log-stream/route.ts +167 -0
  155. package/packages/web-dashboard/src/app/api/features/[id]/raw-logs/[filename]/route.ts +65 -0
  156. package/packages/web-dashboard/src/app/api/features/[id]/raw-logs/route.ts +63 -0
  157. package/packages/web-dashboard/src/app/api/features/[id]/timeline/route.ts +60 -0
  158. package/packages/web-dashboard/src/app/feature/[id]/page.tsx +32 -11
  159. package/packages/web-dashboard/src/app/globals.css +2 -0
  160. package/packages/web-dashboard/src/components/detail-panel.tsx +483 -0
  161. package/packages/web-dashboard/src/components/review-workspace.tsx +1162 -0
  162. package/packages/web-dashboard/src/lib/aop-client.ts +725 -0
  163. package/packages/web-dashboard/src/lib/review-contracts.ts +182 -0
  164. package/packages/web-dashboard/src/lib/review-workspace-logic.ts +64 -0
  165. package/packages/web-dashboard/src/lib/types.ts +131 -0
  166. package/packages/web-dashboard/src/styles/dashboard.module.css +333 -0
  167. package/spec-files/completed/agentic_orchestrator_execution_mode_spec.md +1905 -0
  168. package/spec-files/outstanding/agentic_orchestrator_runtime_inspection_spec.md +940 -0
  169. package/spec-files/outstanding/execution_mode_critical_review.md +355 -0
  170. package/spec-files/outstanding/shadow_workspace_implementation_spec.md +1271 -0
  171. package/spec-files/outstanding/shadow_workspace_spec_summary.md +222 -0
  172. package/spec-files/progress.md +269 -1
@@ -0,0 +1,147 @@
1
+ import fs from 'node:fs/promises';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+ import { describe, expect, it, vi } from 'vitest';
5
+ import { runGit } from '../src/core/git.js';
6
+ import { WorktreeWatchdogService } from '../src/application/services/worktree-watchdog-service.js';
7
+
8
+ async function initGitRepo(prefix: string): Promise<string> {
9
+ const repoRoot = await fs.mkdtemp(path.join(os.tmpdir(), prefix));
10
+ await runGit(repoRoot, ['init']);
11
+ await runGit(repoRoot, ['config', 'user.email', 'test@example.com']);
12
+ await runGit(repoRoot, ['config', 'user.name', 'AOP Test']);
13
+ await fs.writeFile(path.join(repoRoot, 'tracked.txt'), 'initial\n', 'utf8');
14
+ await runGit(repoRoot, ['add', '.']);
15
+ await runGit(repoRoot, ['commit', '-m', 'init']);
16
+ return repoRoot;
17
+ }
18
+
19
+ async function waitForCondition(check: () => Promise<boolean>, timeoutMs = 2_000): Promise<void> {
20
+ const startedAt = Date.now();
21
+ while (Date.now() - startedAt <= timeoutMs) {
22
+ if (await check()) {
23
+ return;
24
+ }
25
+ await new Promise((resolve) => setTimeout(resolve, 25));
26
+ }
27
+ throw new Error('timeout waiting for condition');
28
+ }
29
+
30
+ describe('WorktreeWatchdogService', () => {
31
+ it('returns empty defaults for unknown features and handles missing watchers', async () => {
32
+ const service = new WorktreeWatchdogService();
33
+ await expect(service.stopWatching('missing-feature')).resolves.toBeUndefined();
34
+ service.resetChangeCount('missing-feature');
35
+ expect(service.getChangeCount('missing-feature')).toBe(0);
36
+ await expect(service.getChangedFiles('missing-feature')).resolves.toEqual([]);
37
+ });
38
+
39
+ it('detects changed files and emits threshold events', async () => {
40
+ const repoRoot = await initGitRepo('aop-watchdog-');
41
+ const service = new WorktreeWatchdogService();
42
+ const thresholdSpy = vi.fn();
43
+
44
+ try {
45
+ service.on('changeThreshold', thresholdSpy);
46
+ await service.startWatching({
47
+ featureId: 'feature_watchdog',
48
+ repoRoot,
49
+ worktreePath: repoRoot,
50
+ pollIntervalMs: 25,
51
+ maxUncommittedChanges: 1,
52
+ });
53
+
54
+ await fs.writeFile(path.join(repoRoot, 'tracked.txt'), 'updated\n', 'utf8');
55
+
56
+ await waitForCondition(async () => service.getChangeCount('feature_watchdog') > 0);
57
+ const changed = await service.getChangedFiles('feature_watchdog');
58
+
59
+ expect(changed).toContain('tracked.txt');
60
+ expect(thresholdSpy).toHaveBeenCalledWith('feature_watchdog');
61
+ } finally {
62
+ await service.stopWatching('feature_watchdog');
63
+ await fs.rm(repoRoot, { recursive: true, force: true });
64
+ }
65
+ });
66
+
67
+ it('resets tracked changes and stops cleanly', async () => {
68
+ const repoRoot = await initGitRepo('aop-watchdog-reset-');
69
+ const service = new WorktreeWatchdogService();
70
+
71
+ try {
72
+ await service.startWatching({
73
+ featureId: 'feature_reset',
74
+ repoRoot,
75
+ worktreePath: repoRoot,
76
+ pollIntervalMs: 25,
77
+ maxUncommittedChanges: 2,
78
+ });
79
+ await fs.writeFile(path.join(repoRoot, 'tracked.txt'), 'changed\n', 'utf8');
80
+ await waitForCondition(async () => service.getChangeCount('feature_reset') > 0);
81
+
82
+ service.resetChangeCount('feature_reset');
83
+ expect(service.getChangeCount('feature_reset')).toBe(0);
84
+
85
+ await service.stopWatching('feature_reset');
86
+ const changed = await service.getChangedFiles('feature_reset');
87
+ expect(changed).toEqual([]);
88
+ } finally {
89
+ await service.stopWatching('feature_reset');
90
+ await fs.rm(repoRoot, { recursive: true, force: true });
91
+ }
92
+ });
93
+
94
+ it('tracks rename paths and resets threshold after worktree is clean again', async () => {
95
+ const repoRoot = await initGitRepo('aop-watchdog-rename-');
96
+ const service = new WorktreeWatchdogService();
97
+ const thresholdSpy = vi.fn();
98
+
99
+ try {
100
+ service.on('changeThreshold', thresholdSpy);
101
+ await service.startWatching({
102
+ featureId: 'feature_rename',
103
+ repoRoot,
104
+ worktreePath: repoRoot,
105
+ pollIntervalMs: 25,
106
+ maxUncommittedChanges: 1,
107
+ });
108
+
109
+ await runGit(repoRoot, ['mv', 'tracked.txt', 'renamed.txt'], { cwd: repoRoot });
110
+ await waitForCondition(async () =>
111
+ (await service.getChangedFiles('feature_rename')).includes('renamed.txt'),
112
+ );
113
+ expect(thresholdSpy).toHaveBeenCalledTimes(1);
114
+
115
+ await runGit(repoRoot, ['reset', '--hard', 'HEAD'], { cwd: repoRoot });
116
+ await waitForCondition(async () => service.getChangeCount('feature_rename') === 0);
117
+
118
+ await fs.writeFile(path.join(repoRoot, 'tracked.txt'), 'again\\n', 'utf8');
119
+ await waitForCondition(async () => thresholdSpy.mock.calls.length >= 2);
120
+ expect(thresholdSpy.mock.calls.length).toBeGreaterThanOrEqual(2);
121
+ } finally {
122
+ await service.stopWatching('feature_rename');
123
+ await fs.rm(repoRoot, { recursive: true, force: true });
124
+ }
125
+ });
126
+
127
+ it('handles non-zero git status polls without throwing', async () => {
128
+ const repoRoot = await initGitRepo('aop-watchdog-nonzero-');
129
+ const service = new WorktreeWatchdogService();
130
+
131
+ try {
132
+ await service.startWatching({
133
+ featureId: 'feature_bad_status',
134
+ repoRoot,
135
+ worktreePath: path.join(repoRoot, '.missing-worktree'),
136
+ pollIntervalMs: -10,
137
+ maxUncommittedChanges: -5,
138
+ });
139
+
140
+ expect(service.getChangeCount('feature_bad_status')).toBe(0);
141
+ expect(await service.getChangedFiles('feature_bad_status')).toEqual([]);
142
+ } finally {
143
+ await service.stopWatching('feature_bad_status');
144
+ await fs.rm(repoRoot, { recursive: true, force: true });
145
+ }
146
+ });
147
+ });
@@ -10,6 +10,19 @@ missing_prompt_behavior: ignore
10
10
  runtime:
11
11
  default_provider: claude
12
12
  default_model: local-default
13
+ execution_mode: interactive
14
+ interactive:
15
+ watchdog_poll_interval_ms: 2000
16
+ checkpoint_interval_ms: 30000
17
+ max_uncommitted_changes: 50
18
+ validation_on_checkpoint: true
19
+ revert_on_violation: false
20
+ violation_severity: warning
21
+ shadow_workspace:
22
+ enabled: false
23
+ promotion_strategy: atomic
24
+ cleanup_on_failure: true
25
+ max_shadow_size_mb: 2048
13
26
  worker_provider_mode: live
14
27
  worker_response_timeout_ms: 1800000
15
28
  worker_spawn_timeout_ms: 15000
@@ -0,0 +1,19 @@
1
+ import type { SchemaRegistry } from '../core/schemas.js';
2
+ import type { AopPathLayout } from '../core/path-layout.js';
3
+ import type { AnyRecord, KernelConfigOverrides, AgentsConfigSnapshot, PolicyConfigSnapshot } from '../core/kernel-types.js';
4
+ export interface LoadedConfiguration {
5
+ gatesConfig: AnyRecord;
6
+ policy: PolicyConfigSnapshot;
7
+ agentsConfig: AgentsConfigSnapshot;
8
+ adaptersConfig: Record<string, unknown>;
9
+ toolRegistry: AnyRecord | null;
10
+ }
11
+ export declare class ConfigurationService {
12
+ private readonly repoRoot;
13
+ private readonly pathLayout;
14
+ private readonly schemaRegistry;
15
+ private readonly configOverrides;
16
+ constructor(repoRoot: string, pathLayout: AopPathLayout, schemaRegistry: SchemaRegistry, configOverrides: KernelConfigOverrides);
17
+ private resolveDefaultConfigPath;
18
+ loadAll(): Promise<LoadedConfiguration>;
19
+ }
@@ -0,0 +1,123 @@
1
+ import path from 'node:path';
2
+ import { pathExists } from '../core/fs.js';
3
+ import { loadAndValidateYaml } from '../core/schemas.js';
4
+ import { ensureAopRuntimeLayout } from '../core/path-layout.js';
5
+ import { loadComposedPolicy } from './services/policy-loader-service.js';
6
+ import { ACTIVITY_DETECTOR_SLOT, NOTIFICATION_CHANNEL_SLOT, SCM_PROVIDER_SLOT, globalAdapterRegistry, } from './adapters/adapter-registry.js';
7
+ import { ToolRegistryLoader } from '../mcp/tool-registry-loader.js';
8
+ import { ERROR_CODES } from '../core/error-codes.js';
9
+ import { readStringField, readObjectField, readPositiveIntegerField, } from '../core/utils/field-readers.js';
10
+ function validateAgentRuntimeTimeoutRelationships(agentsConfig) {
11
+ const runtime = readObjectField(agentsConfig, 'runtime');
12
+ if (Object.keys(runtime).length === 0) {
13
+ return;
14
+ }
15
+ const responseTimeoutMs = readPositiveIntegerField(runtime, 'worker_response_timeout_ms');
16
+ const spawnTimeoutMs = readPositiveIntegerField(runtime, 'worker_spawn_timeout_ms');
17
+ const idleTimeoutMs = readPositiveIntegerField(runtime, 'worker_idle_timeout_ms');
18
+ if (responseTimeoutMs != null && spawnTimeoutMs != null && spawnTimeoutMs >= responseTimeoutMs) {
19
+ throw new Error('invalid_agents_yaml:runtime.worker_spawn_timeout_ms must be less than runtime.worker_response_timeout_ms');
20
+ }
21
+ if (responseTimeoutMs != null && idleTimeoutMs != null && idleTimeoutMs > responseTimeoutMs) {
22
+ throw new Error('invalid_agents_yaml:runtime.worker_idle_timeout_ms must be less than or equal to runtime.worker_response_timeout_ms');
23
+ }
24
+ }
25
+ export class ConfigurationService {
26
+ repoRoot;
27
+ pathLayout;
28
+ schemaRegistry;
29
+ configOverrides;
30
+ constructor(repoRoot, pathLayout, schemaRegistry, configOverrides) {
31
+ this.repoRoot = repoRoot;
32
+ this.pathLayout = pathLayout;
33
+ this.schemaRegistry = schemaRegistry;
34
+ this.configOverrides = configOverrides;
35
+ }
36
+ async resolveDefaultConfigPath(fileName) {
37
+ const primary = path.join(this.pathLayout.orchestratorRoot, fileName);
38
+ if (await pathExists(primary)) {
39
+ return primary;
40
+ }
41
+ const legacy = path.join(this.pathLayout.legacyOrchestratorRoot, fileName);
42
+ if (await pathExists(legacy)) {
43
+ return legacy;
44
+ }
45
+ return primary;
46
+ }
47
+ async loadAll() {
48
+ await ensureAopRuntimeLayout(this.pathLayout);
49
+ const gatesPath = this.configOverrides.gatesPath ?? (await this.resolveDefaultConfigPath('gates.yaml'));
50
+ const policyPath = this.configOverrides.policyPath ?? (await this.resolveDefaultConfigPath('policy.yaml'));
51
+ const agentsPath = this.configOverrides.agentsPath ?? (await this.resolveDefaultConfigPath('agents.yaml'));
52
+ const adaptersPath = this.configOverrides.adaptersPath ?? (await this.resolveDefaultConfigPath('adapters.yaml'));
53
+ const gates = await loadAndValidateYaml(this.schemaRegistry, 'gates.schema.json', gatesPath);
54
+ if (!gates.validation.valid) {
55
+ throw new Error(`invalid_gates_yaml:${JSON.stringify(gates.validation.errors)}`);
56
+ }
57
+ const { mergedPolicy } = await loadComposedPolicy(this.repoRoot, policyPath, this.schemaRegistry);
58
+ const parsedPolicy = mergedPolicy;
59
+ const implementation = readObjectField(parsedPolicy, 'implementation');
60
+ const testing = readObjectField(parsedPolicy, 'testing');
61
+ if (readStringField(implementation, 'workspace') !== 'nx') {
62
+ throw new Error(ERROR_CODES.INVALID_WORKSPACE_IMPLEMENTATION);
63
+ }
64
+ if (readStringField(testing, 'framework') !== 'vitest') {
65
+ throw new Error(ERROR_CODES.INVALID_WORKSPACE_IMPLEMENTATION);
66
+ }
67
+ const agentsExists = await pathExists(agentsPath);
68
+ let agents = { parsed: { version: 1, roles: {} }, validation: { valid: true, errors: [] } };
69
+ if (agentsExists) {
70
+ agents = await loadAndValidateYaml(this.schemaRegistry, 'agents.schema.json', agentsPath);
71
+ if (!agents.validation.valid) {
72
+ throw new Error(`invalid_agents_yaml:${JSON.stringify(agents.validation.errors)}`);
73
+ }
74
+ validateAgentRuntimeTimeoutRelationships(agents.parsed);
75
+ }
76
+ const adaptersExists = await pathExists(adaptersPath);
77
+ let adapters = { parsed: {}, validation: { valid: true, errors: [] } };
78
+ if (adaptersExists) {
79
+ adapters = await loadAndValidateYaml(this.schemaRegistry, 'adapters.schema.json', adaptersPath);
80
+ if (!adapters.validation.valid) {
81
+ throw new Error(`invalid_adapters_yaml:${JSON.stringify(adapters.validation.errors)}`);
82
+ }
83
+ const parsedAdapters = readObjectField(adapters, 'parsed');
84
+ const notificationChannel = readStringField(parsedAdapters, NOTIFICATION_CHANNEL_SLOT.name);
85
+ if (notificationChannel) {
86
+ try {
87
+ globalAdapterRegistry.resolve(NOTIFICATION_CHANNEL_SLOT, notificationChannel, {});
88
+ }
89
+ catch {
90
+ throw new Error(`adapter_not_found:${NOTIFICATION_CHANNEL_SLOT.name}:${notificationChannel}`);
91
+ }
92
+ }
93
+ const activityDetector = readStringField(parsedAdapters, ACTIVITY_DETECTOR_SLOT.name);
94
+ if (activityDetector) {
95
+ try {
96
+ globalAdapterRegistry.resolve(ACTIVITY_DETECTOR_SLOT, activityDetector, {});
97
+ }
98
+ catch {
99
+ throw new Error(`adapter_not_found:${ACTIVITY_DETECTOR_SLOT.name}:${activityDetector}`);
100
+ }
101
+ }
102
+ const scmProvider = readStringField(parsedAdapters, SCM_PROVIDER_SLOT.name);
103
+ if (scmProvider) {
104
+ try {
105
+ globalAdapterRegistry.resolve(SCM_PROVIDER_SLOT, scmProvider, {});
106
+ }
107
+ catch {
108
+ throw new Error(`adapter_not_found:${SCM_PROVIDER_SLOT.name}:${scmProvider}`);
109
+ }
110
+ }
111
+ }
112
+ const registryLoader = new ToolRegistryLoader(this.repoRoot);
113
+ const toolRegistry = await registryLoader.load();
114
+ return {
115
+ gatesConfig: gates.parsed,
116
+ policy: parsedPolicy,
117
+ agentsConfig: agents.parsed,
118
+ adaptersConfig: readObjectField(adapters, 'parsed'),
119
+ toolRegistry,
120
+ };
121
+ }
122
+ }
123
+ //# sourceMappingURL=configuration-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configuration-service.js","sourceRoot":"","sources":["../../../../apps/control-plane/src/application/configuration-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import type { ToolHandlerRegistry, ToolHandlerContext } from './tools/tool-router.js';
2
+ type AnyRecord = Record<string, any>;
3
+ export interface KernelToolFacade {
4
+ featureDiscoverSpecs(): Promise<unknown>;
5
+ featureInit(featureId: string | null): Promise<unknown>;
6
+ featureGetContext(featureId: string | null): Promise<unknown>;
7
+ featureStateGet(featureId: string | null): Promise<unknown>;
8
+ featureStatePatch(featureId: string | null, expectedVersion: number | null, patch: unknown): Promise<unknown>;
9
+ featureLogAppend(featureId: string | null, note: string | null, context: ToolHandlerContext): Promise<unknown>;
10
+ planSubmit(featureId: string | null, plan: unknown, expectedVersion: number | null): Promise<unknown>;
11
+ planGet(featureId: string | null): Promise<unknown>;
12
+ planUpdate(featureId: string | null, expectedPlanVersion: number | null, plan: unknown): Promise<unknown>;
13
+ repoEnsureWorktree(featureId: string | null): Promise<unknown>;
14
+ repoApplyPatch(featureId: string | null, unifiedDiff: string | null): Promise<unknown>;
15
+ repoStatus(featureId: string | null): Promise<unknown>;
16
+ repoDiff(featureId: string | null, options: string[]): Promise<unknown>;
17
+ repoReadFile(featureId: string | null, filePath: string | null): Promise<unknown>;
18
+ repoSearch(featureId: string | null, query: string | null): Promise<unknown>;
19
+ repoDiffBundle(featureId: string | null): Promise<unknown>;
20
+ featureReadyToMerge(featureId: string | null, commitMessage: string | null, mergeStrategy: string | null, userApprovalToken: string | null): Promise<unknown>;
21
+ featureDelete(featureId: string | null, dryRun: boolean | null, confirm: boolean | null, removeWorktree: boolean | null, removeBranch: string | null): Promise<unknown>;
22
+ gatesList(profileName: string | null): Promise<unknown>;
23
+ gatesRun(featureId: string | null, profileName: string | null, mode: string | null): Promise<unknown>;
24
+ evidenceLatest(featureId: string | null): Promise<unknown>;
25
+ qaTestIndexGet(featureId: string | null): Promise<unknown>;
26
+ qaTestIndexUpdate(featureId: string | null, expectedVersion: number | null, updates: unknown, evidenceRefs: unknown[]): Promise<unknown>;
27
+ locksAcquire(resource: string | null, featureId: string | null, waitTimeoutSeconds: number | null): Promise<unknown>;
28
+ locksRelease(resource: string | null, featureId: string | null): Promise<unknown>;
29
+ collisionsScan(): Promise<unknown>;
30
+ reportDashboard(): Promise<unknown>;
31
+ reportFeatureSummary(featureId: string | null): Promise<unknown>;
32
+ featureSendMessage(featureId: string | null, message: string | null): Promise<unknown>;
33
+ costRecord(featureId: string | null, tokensDelta: number, costUsdDelta: number): Promise<unknown>;
34
+ costGet(featureId: string | null): Promise<unknown>;
35
+ performanceRecordOutcome(args: AnyRecord): Promise<unknown>;
36
+ performanceGetAnalytics(provider: string | null, model: string | null): Promise<unknown>;
37
+ }
38
+ export declare function registerKernelTools(toolHandlers: ToolHandlerRegistry, kernel: KernelToolFacade): void;
39
+ export {};
@@ -0,0 +1,38 @@
1
+ import { TOOLS } from '../core/constants.js';
2
+ import { readStringField, readNumberField, readBooleanField, asArray, } from '../core/utils/field-readers.js';
3
+ export function registerKernelTools(toolHandlers, kernel) {
4
+ toolHandlers.register(TOOLS.FEATURE_DISCOVER_SPECS, async () => await kernel.featureDiscoverSpecs());
5
+ toolHandlers.register(TOOLS.FEATURE_INIT, async (args) => await kernel.featureInit(readStringField(args, 'feature_id')));
6
+ toolHandlers.register(TOOLS.FEATURE_GET_CONTEXT, async (args) => await kernel.featureGetContext(readStringField(args, 'feature_id')));
7
+ toolHandlers.register(TOOLS.FEATURE_STATE_GET, async (args) => await kernel.featureStateGet(readStringField(args, 'feature_id')));
8
+ toolHandlers.register(TOOLS.FEATURE_STATE_PATCH, async (args) => await kernel.featureStatePatch(readStringField(args, 'feature_id'), readNumberField(args, 'expected_version'), args.patch));
9
+ toolHandlers.register(TOOLS.FEATURE_LOG_APPEND, async (args, context) => await kernel.featureLogAppend(readStringField(args, 'feature_id'), readStringField(args, 'note'), context));
10
+ toolHandlers.register(TOOLS.PLAN_SUBMIT, async (args) => await kernel.planSubmit(readStringField(args, 'feature_id'), args.plan_json, readNumberField(args, 'expected_version')));
11
+ toolHandlers.register(TOOLS.PLAN_GET, async (args) => await kernel.planGet(readStringField(args, 'feature_id')));
12
+ toolHandlers.register(TOOLS.PLAN_UPDATE, async (args) => await kernel.planUpdate(readStringField(args, 'feature_id'), readNumberField(args, 'expected_plan_version'), args.plan_json));
13
+ toolHandlers.register(TOOLS.REPO_ENSURE_WORKTREE, async (args) => await kernel.repoEnsureWorktree(readStringField(args, 'feature_id')));
14
+ toolHandlers.register(TOOLS.REPO_APPLY_PATCH, async (args) => await kernel.repoApplyPatch(readStringField(args, 'feature_id'), readStringField(args, 'unified_diff')));
15
+ toolHandlers.register(TOOLS.REPO_STATUS, async (args) => await kernel.repoStatus(readStringField(args, 'feature_id')));
16
+ toolHandlers.register(TOOLS.REPO_DIFF, async (args) => await kernel.repoDiff(readStringField(args, 'feature_id'), asArray(args.options)));
17
+ toolHandlers.register(TOOLS.REPO_READ_FILE, async (args) => await kernel.repoReadFile(readStringField(args, 'feature_id'), readStringField(args, 'path')));
18
+ toolHandlers.register(TOOLS.REPO_SEARCH, async (args) => await kernel.repoSearch(readStringField(args, 'feature_id'), readStringField(args, 'query')));
19
+ toolHandlers.register(TOOLS.REPO_DIFF_BUNDLE, async (args) => await kernel.repoDiffBundle(readStringField(args, 'feature_id')));
20
+ toolHandlers.register(TOOLS.FEATURE_READY_TO_MERGE, async (args) => await kernel.featureReadyToMerge(readStringField(args, 'feature_id'), readStringField(args, 'commit_message'), readStringField(args, 'merge_strategy'), readStringField(args, 'user_approval_token')));
21
+ toolHandlers.register(TOOLS.FEATURE_DELETE, async (args) => await kernel.featureDelete(readStringField(args, 'feature_id'), readBooleanField(args, 'dry_run'), readBooleanField(args, 'confirm'), readBooleanField(args, 'remove_worktree'), readStringField(args, 'remove_branch')));
22
+ toolHandlers.register(TOOLS.GATES_LIST, async (args) => await kernel.gatesList(readStringField(args, 'profile')));
23
+ toolHandlers.register(TOOLS.GATES_RUN, async (args) => await kernel.gatesRun(readStringField(args, 'feature_id'), readStringField(args, 'profile'), readStringField(args, 'mode')));
24
+ toolHandlers.register(TOOLS.EVIDENCE_LATEST, async (args) => await kernel.evidenceLatest(readStringField(args, 'feature_id')));
25
+ toolHandlers.register(TOOLS.QA_TEST_INDEX_GET, async (args) => await kernel.qaTestIndexGet(readStringField(args, 'feature_id')));
26
+ toolHandlers.register(TOOLS.QA_TEST_INDEX_UPDATE, async (args) => await kernel.qaTestIndexUpdate(readStringField(args, 'feature_id'), readNumberField(args, 'expected_version'), args.updates, asArray(args.evidence_refs)));
27
+ toolHandlers.register(TOOLS.LOCKS_ACQUIRE, async (args) => await kernel.locksAcquire(readStringField(args, 'resource'), readStringField(args, 'feature_id'), readNumberField(args, 'wait_timeout_seconds')));
28
+ toolHandlers.register(TOOLS.LOCKS_RELEASE, async (args) => await kernel.locksRelease(readStringField(args, 'resource'), readStringField(args, 'feature_id')));
29
+ toolHandlers.register(TOOLS.COLLISIONS_SCAN, async () => await kernel.collisionsScan());
30
+ toolHandlers.register(TOOLS.REPORT_DASHBOARD, async () => await kernel.reportDashboard());
31
+ toolHandlers.register(TOOLS.REPORT_FEATURE_SUMMARY, async (args) => await kernel.reportFeatureSummary(readStringField(args, 'feature_id')));
32
+ toolHandlers.register(TOOLS.FEATURE_SEND_MESSAGE, async (args) => await kernel.featureSendMessage(readStringField(args, 'feature_id'), readStringField(args, 'message')));
33
+ toolHandlers.register(TOOLS.COST_RECORD, async (args) => await kernel.costRecord(readStringField(args, 'feature_id'), typeof args.tokens_used_delta === 'number' ? args.tokens_used_delta : 0, typeof args.estimated_cost_usd_delta === 'number' ? args.estimated_cost_usd_delta : 0));
34
+ toolHandlers.register(TOOLS.COST_GET, async (args) => await kernel.costGet(readStringField(args, 'feature_id')));
35
+ toolHandlers.register(TOOLS.PERFORMANCE_RECORD_OUTCOME, async (args) => await kernel.performanceRecordOutcome(args));
36
+ toolHandlers.register(TOOLS.PERFORMANCE_GET_ANALYTICS, async (args) => await kernel.performanceGetAnalytics(readStringField(args, 'provider'), readStringField(args, 'model')));
37
+ }
38
+ //# sourceMappingURL=kernel-tool-wiring.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kernel-tool-wiring.js","sourceRoot":"","sources":["../../../../apps/control-plane/src/application/kernel-tool-wiring.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ import { parseUnifiedDiff } from '../../core/patch.js';
2
+ import type { PatchValidationResult } from './patch-service.js';
3
+ import type { WorktreeWatchdogService } from './worktree-watchdog-service.js';
4
+ export type ViolationSeverity = 'info' | 'warning' | 'error' | 'critical';
5
+ export type CheckpointValidationStatus = 'valid' | 'invalid' | 'skipped';
6
+ export interface InteractiveExecutionConfig {
7
+ checkpointIntervalMs: number;
8
+ watchdogPollIntervalMs: number;
9
+ maxUncommittedChanges: number;
10
+ validationOnCheckpoint: boolean;
11
+ revertOnViolation: boolean;
12
+ violationSeverity: ViolationSeverity;
13
+ }
14
+ export interface CreateCheckpointInput {
15
+ featureId: string;
16
+ sessionId?: string | null;
17
+ trigger: 'interval' | 'change_threshold' | 'final';
18
+ }
19
+ export interface CheckpointRecord {
20
+ checkpoint_id: string;
21
+ timestamp: string;
22
+ files_changed: string[];
23
+ validation_status: CheckpointValidationStatus;
24
+ violations: string[];
25
+ severity?: ViolationSeverity;
26
+ diff_snapshot: string;
27
+ }
28
+ interface UpdateStateFn {
29
+ (featureId: string, expectedVersion: number | null, updater: (frontMatter: Record<string, unknown>, body: string) => Promise<{
30
+ frontMatter?: Record<string, unknown>;
31
+ body?: string;
32
+ }>): Promise<Record<string, unknown>>;
33
+ }
34
+ interface CheckpointServiceDependencies {
35
+ repoRoot: string;
36
+ featurePathResolver: (featureId: string) => string;
37
+ worktreePathResolver: (featureId: string) => string;
38
+ validateDiff: (featureId: string, parsedDiff: ReturnType<typeof parseUnifiedDiff>) => Promise<PatchValidationResult>;
39
+ watchdog: WorktreeWatchdogService;
40
+ provider: CheckpointProviderPort;
41
+ readState: (featureId: string) => Promise<{
42
+ frontMatter: Record<string, unknown>;
43
+ }>;
44
+ updateState: UpdateStateFn;
45
+ config: InteractiveExecutionConfig;
46
+ }
47
+ /**
48
+ * Minimal provider contract used by checkpoint validation for agent notifications.
49
+ *
50
+ * This keeps application services decoupled from provider-layer runtime interfaces.
51
+ */
52
+ export interface CheckpointProviderPort {
53
+ sendMessage?: (sessionId: string, message: string) => Promise<void>;
54
+ }
55
+ /**
56
+ * Captures and validates interactive-mode checkpoints against plan/policy/locks.
57
+ */
58
+ export declare class CheckpointService {
59
+ private readonly repoRoot;
60
+ private readonly featurePathResolver;
61
+ private readonly worktreePathResolver;
62
+ private readonly validateDiff;
63
+ private readonly watchdog;
64
+ private readonly provider;
65
+ private readonly readState;
66
+ private readonly updateState;
67
+ private readonly config;
68
+ private readonly inFlightByFeature;
69
+ constructor(dependencies: CheckpointServiceDependencies);
70
+ createCheckpoint(input: CreateCheckpointInput): Promise<{
71
+ checkpoint: CheckpointRecord;
72
+ valid: boolean;
73
+ blockMerge: boolean;
74
+ }>;
75
+ getCheckpoints(featureId: string): Promise<CheckpointRecord[]>;
76
+ private notifyAgent;
77
+ private recordCheckpoint;
78
+ private readCheckpoints;
79
+ private interactiveMetricsPath;
80
+ private normalizeMetricsSnapshot;
81
+ private recordInteractiveMetrics;
82
+ private withFeatureLock;
83
+ }
84
+ export {};