@renseiai/agentfactory 0.8.18 → 0.8.20

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 (117) hide show
  1. package/dist/src/config/repository-config.d.ts +7 -0
  2. package/dist/src/config/repository-config.d.ts.map +1 -1
  3. package/dist/src/config/repository-config.js +15 -1
  4. package/dist/src/config/repository-config.test.js +1 -1
  5. package/dist/src/governor/decision-engine-adapter.d.ts +43 -0
  6. package/dist/src/governor/decision-engine-adapter.d.ts.map +1 -0
  7. package/dist/src/governor/decision-engine-adapter.js +417 -0
  8. package/dist/src/governor/decision-engine-adapter.test.d.ts +2 -0
  9. package/dist/src/governor/decision-engine-adapter.test.d.ts.map +1 -0
  10. package/dist/src/governor/decision-engine-adapter.test.js +362 -0
  11. package/dist/src/governor/decision-engine.js +3 -7
  12. package/dist/src/governor/decision-engine.test.js +5 -5
  13. package/dist/src/governor/index.d.ts +1 -0
  14. package/dist/src/governor/index.d.ts.map +1 -1
  15. package/dist/src/governor/index.js +1 -0
  16. package/dist/src/index.d.ts +1 -0
  17. package/dist/src/index.d.ts.map +1 -1
  18. package/dist/src/index.js +1 -0
  19. package/dist/src/manifest/route-manifest.d.ts.map +1 -1
  20. package/dist/src/manifest/route-manifest.js +4 -0
  21. package/dist/src/merge-queue/adapters/local.d.ts +68 -0
  22. package/dist/src/merge-queue/adapters/local.d.ts.map +1 -0
  23. package/dist/src/merge-queue/adapters/local.js +136 -0
  24. package/dist/src/merge-queue/adapters/local.test.d.ts +2 -0
  25. package/dist/src/merge-queue/adapters/local.test.d.ts.map +1 -0
  26. package/dist/src/merge-queue/adapters/local.test.js +176 -0
  27. package/dist/src/merge-queue/index.d.ts +13 -5
  28. package/dist/src/merge-queue/index.d.ts.map +1 -1
  29. package/dist/src/merge-queue/index.js +13 -6
  30. package/dist/src/merge-queue/merge-queue.integration.test.js +19 -0
  31. package/dist/src/merge-queue/merge-worker.d.ts.map +1 -1
  32. package/dist/src/merge-queue/merge-worker.js +29 -0
  33. package/dist/src/merge-queue/types.d.ts +1 -1
  34. package/dist/src/merge-queue/types.d.ts.map +1 -1
  35. package/dist/src/orchestrator/index.d.ts +4 -0
  36. package/dist/src/orchestrator/index.d.ts.map +1 -1
  37. package/dist/src/orchestrator/index.js +3 -0
  38. package/dist/src/orchestrator/orchestrator.d.ts +58 -0
  39. package/dist/src/orchestrator/orchestrator.d.ts.map +1 -1
  40. package/dist/src/orchestrator/orchestrator.js +552 -97
  41. package/dist/src/orchestrator/parse-work-result.d.ts.map +1 -1
  42. package/dist/src/orchestrator/parse-work-result.js +3 -1
  43. package/dist/src/orchestrator/parse-work-result.test.js +6 -0
  44. package/dist/src/orchestrator/quality-baseline.d.ts +83 -0
  45. package/dist/src/orchestrator/quality-baseline.d.ts.map +1 -0
  46. package/dist/src/orchestrator/quality-baseline.js +313 -0
  47. package/dist/src/orchestrator/quality-baseline.test.d.ts +2 -0
  48. package/dist/src/orchestrator/quality-baseline.test.d.ts.map +1 -0
  49. package/dist/src/orchestrator/quality-baseline.test.js +448 -0
  50. package/dist/src/orchestrator/quality-ratchet.d.ts +70 -0
  51. package/dist/src/orchestrator/quality-ratchet.d.ts.map +1 -0
  52. package/dist/src/orchestrator/quality-ratchet.js +162 -0
  53. package/dist/src/orchestrator/quality-ratchet.test.d.ts +2 -0
  54. package/dist/src/orchestrator/quality-ratchet.test.d.ts.map +1 -0
  55. package/dist/src/orchestrator/quality-ratchet.test.js +335 -0
  56. package/dist/src/orchestrator/types.d.ts +2 -0
  57. package/dist/src/orchestrator/types.d.ts.map +1 -1
  58. package/dist/src/providers/claude-provider.d.ts.map +1 -1
  59. package/dist/src/providers/claude-provider.js +11 -0
  60. package/dist/src/providers/codex-app-server-provider.d.ts +237 -0
  61. package/dist/src/providers/codex-app-server-provider.d.ts.map +1 -0
  62. package/dist/src/providers/codex-app-server-provider.js +1041 -0
  63. package/dist/src/providers/codex-app-server-provider.test.d.ts +2 -0
  64. package/dist/src/providers/codex-app-server-provider.test.d.ts.map +1 -0
  65. package/dist/src/providers/codex-app-server-provider.test.js +589 -0
  66. package/dist/src/providers/codex-approval-bridge.d.ts +49 -0
  67. package/dist/src/providers/codex-approval-bridge.d.ts.map +1 -0
  68. package/dist/src/providers/codex-approval-bridge.js +117 -0
  69. package/dist/src/providers/codex-approval-bridge.test.d.ts +2 -0
  70. package/dist/src/providers/codex-approval-bridge.test.d.ts.map +1 -0
  71. package/dist/src/providers/codex-approval-bridge.test.js +188 -0
  72. package/dist/src/providers/codex-provider.d.ts +24 -4
  73. package/dist/src/providers/codex-provider.d.ts.map +1 -1
  74. package/dist/src/providers/codex-provider.js +58 -6
  75. package/dist/src/providers/index.d.ts +1 -0
  76. package/dist/src/providers/index.d.ts.map +1 -1
  77. package/dist/src/providers/index.js +1 -0
  78. package/dist/src/providers/types.d.ts +25 -0
  79. package/dist/src/providers/types.d.ts.map +1 -1
  80. package/dist/src/routing/observation-recorder.test.js +1 -1
  81. package/dist/src/routing/observation-store.d.ts +15 -1
  82. package/dist/src/routing/observation-store.d.ts.map +1 -1
  83. package/dist/src/routing/observation-store.test.js +17 -11
  84. package/dist/src/routing/types.d.ts +1 -1
  85. package/dist/src/templates/adapters.d.ts +25 -0
  86. package/dist/src/templates/adapters.d.ts.map +1 -1
  87. package/dist/src/templates/adapters.js +70 -0
  88. package/dist/src/templates/adapters.test.js +49 -0
  89. package/dist/src/templates/index.d.ts +3 -1
  90. package/dist/src/templates/index.d.ts.map +1 -1
  91. package/dist/src/templates/index.js +1 -0
  92. package/dist/src/templates/registry.d.ts +31 -0
  93. package/dist/src/templates/registry.d.ts.map +1 -1
  94. package/dist/src/templates/registry.js +91 -0
  95. package/dist/src/templates/schema.d.ts +31 -0
  96. package/dist/src/templates/schema.d.ts.map +1 -0
  97. package/dist/src/templates/schema.js +139 -0
  98. package/dist/src/templates/schema.test.d.ts +2 -0
  99. package/dist/src/templates/schema.test.d.ts.map +1 -0
  100. package/dist/src/templates/schema.test.js +215 -0
  101. package/dist/src/templates/types.d.ts +22 -0
  102. package/dist/src/templates/types.d.ts.map +1 -1
  103. package/dist/src/templates/types.js +12 -0
  104. package/dist/src/tools/index.d.ts +2 -0
  105. package/dist/src/tools/index.d.ts.map +1 -1
  106. package/dist/src/tools/index.js +1 -0
  107. package/dist/src/tools/registry.d.ts +9 -1
  108. package/dist/src/tools/registry.d.ts.map +1 -1
  109. package/dist/src/tools/registry.js +13 -1
  110. package/dist/src/tools/stdio-server-entry.d.ts +25 -0
  111. package/dist/src/tools/stdio-server-entry.d.ts.map +1 -0
  112. package/dist/src/tools/stdio-server-entry.js +205 -0
  113. package/dist/src/tools/stdio-server.d.ts +87 -0
  114. package/dist/src/tools/stdio-server.d.ts.map +1 -0
  115. package/dist/src/tools/stdio-server.js +138 -0
  116. package/dist/src/workflow/workflow-types.d.ts +3 -3
  117. package/package.json +3 -2
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=quality-ratchet.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quality-ratchet.test.d.ts","sourceRoot":"","sources":["../../../src/orchestrator/quality-ratchet.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,335 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { loadQualityRatchet, checkQualityRatchet, updateQualityRatchet, initializeQualityRatchet, formatRatchetResult, } from './quality-ratchet.js';
3
+ vi.mock('node:fs', () => ({
4
+ readFileSync: vi.fn(),
5
+ writeFileSync: vi.fn(),
6
+ existsSync: vi.fn(),
7
+ }));
8
+ import { readFileSync, writeFileSync, existsSync } from 'node:fs';
9
+ const mockReadFileSync = vi.mocked(readFileSync);
10
+ const mockWriteFileSync = vi.mocked(writeFileSync);
11
+ const mockExistsSync = vi.mocked(existsSync);
12
+ beforeEach(() => {
13
+ vi.resetAllMocks();
14
+ });
15
+ function makeRatchet(overrides) {
16
+ return {
17
+ version: 1,
18
+ updatedAt: '2026-01-01T00:00:00Z',
19
+ updatedBy: 'SUP-100',
20
+ thresholds: {
21
+ testCount: { min: 100 },
22
+ testFailures: { max: 0 },
23
+ typecheckErrors: { max: 5 },
24
+ lintErrors: { max: 10 },
25
+ },
26
+ ...overrides,
27
+ };
28
+ }
29
+ function makeBaseline(overrides) {
30
+ return {
31
+ timestamp: '2026-03-30T00:00:00Z',
32
+ commitSha: 'abc123',
33
+ tests: { total: 100, passed: 100, failed: 0, skipped: 0 },
34
+ typecheck: { errorCount: 5, exitCode: 0 },
35
+ lint: { errorCount: 10, warningCount: 20 },
36
+ ...overrides,
37
+ };
38
+ }
39
+ // ---------------------------------------------------------------------------
40
+ // loadQualityRatchet
41
+ // ---------------------------------------------------------------------------
42
+ describe('loadQualityRatchet', () => {
43
+ it('loads and parses a valid ratchet file', () => {
44
+ const ratchet = makeRatchet();
45
+ mockExistsSync.mockReturnValue(true);
46
+ mockReadFileSync.mockReturnValue(JSON.stringify(ratchet));
47
+ const result = loadQualityRatchet('/repo');
48
+ expect(result).toEqual(ratchet);
49
+ });
50
+ it('returns null when file does not exist', () => {
51
+ mockExistsSync.mockReturnValue(false);
52
+ expect(loadQualityRatchet('/repo')).toBeNull();
53
+ });
54
+ it('throws on invalid JSON', () => {
55
+ mockExistsSync.mockReturnValue(true);
56
+ mockReadFileSync.mockReturnValue('not json');
57
+ expect(() => loadQualityRatchet('/repo')).toThrow();
58
+ });
59
+ it('throws on missing version', () => {
60
+ mockExistsSync.mockReturnValue(true);
61
+ mockReadFileSync.mockReturnValue(JSON.stringify({ thresholds: {} }));
62
+ expect(() => loadQualityRatchet('/repo')).toThrow('Invalid quality ratchet');
63
+ });
64
+ it('throws on missing thresholds', () => {
65
+ mockExistsSync.mockReturnValue(true);
66
+ mockReadFileSync.mockReturnValue(JSON.stringify({ version: 1 }));
67
+ expect(() => loadQualityRatchet('/repo')).toThrow('Invalid quality ratchet');
68
+ });
69
+ });
70
+ // ---------------------------------------------------------------------------
71
+ // checkQualityRatchet
72
+ // ---------------------------------------------------------------------------
73
+ describe('checkQualityRatchet', () => {
74
+ it('passes when all metrics are within thresholds', () => {
75
+ const ratchet = makeRatchet();
76
+ const current = makeBaseline();
77
+ const result = checkQualityRatchet(ratchet, current);
78
+ expect(result.passed).toBe(true);
79
+ expect(result.violations).toHaveLength(0);
80
+ });
81
+ it('fails when test count drops below minimum', () => {
82
+ const ratchet = makeRatchet();
83
+ const current = makeBaseline({ tests: { total: 90, passed: 90, failed: 0, skipped: 0 } });
84
+ const result = checkQualityRatchet(ratchet, current);
85
+ expect(result.passed).toBe(false);
86
+ expect(result.violations).toHaveLength(1);
87
+ expect(result.violations[0].metric).toBe('testCount');
88
+ expect(result.violations[0].direction).toBe('below-min');
89
+ });
90
+ it('fails when test failures exceed maximum', () => {
91
+ const ratchet = makeRatchet();
92
+ const current = makeBaseline({ tests: { total: 100, passed: 97, failed: 3, skipped: 0 } });
93
+ const result = checkQualityRatchet(ratchet, current);
94
+ expect(result.passed).toBe(false);
95
+ expect(result.violations[0].metric).toBe('testFailures');
96
+ });
97
+ it('fails when typecheck errors exceed maximum', () => {
98
+ const ratchet = makeRatchet();
99
+ const current = makeBaseline({ typecheck: { errorCount: 8, exitCode: 1 } });
100
+ const result = checkQualityRatchet(ratchet, current);
101
+ expect(result.passed).toBe(false);
102
+ expect(result.violations[0].metric).toBe('typecheckErrors');
103
+ });
104
+ it('fails when lint errors exceed maximum', () => {
105
+ const ratchet = makeRatchet();
106
+ const current = makeBaseline({ lint: { errorCount: 15, warningCount: 20 } });
107
+ const result = checkQualityRatchet(ratchet, current);
108
+ expect(result.passed).toBe(false);
109
+ expect(result.violations[0].metric).toBe('lintErrors');
110
+ });
111
+ it('reports multiple violations', () => {
112
+ const ratchet = makeRatchet();
113
+ const current = makeBaseline({
114
+ tests: { total: 80, passed: 75, failed: 5, skipped: 0 },
115
+ typecheck: { errorCount: 10, exitCode: 1 },
116
+ });
117
+ const result = checkQualityRatchet(ratchet, current);
118
+ expect(result.passed).toBe(false);
119
+ expect(result.violations.length).toBeGreaterThanOrEqual(3);
120
+ });
121
+ it('passes when metrics exactly equal thresholds (boundary)', () => {
122
+ const ratchet = makeRatchet({
123
+ thresholds: {
124
+ testCount: { min: 100 },
125
+ testFailures: { max: 2 },
126
+ typecheckErrors: { max: 5 },
127
+ lintErrors: { max: 10 },
128
+ },
129
+ });
130
+ const current = makeBaseline({
131
+ tests: { total: 100, passed: 98, failed: 2, skipped: 0 },
132
+ typecheck: { errorCount: 5, exitCode: 0 },
133
+ lint: { errorCount: 10, warningCount: 0 },
134
+ });
135
+ const result = checkQualityRatchet(ratchet, current);
136
+ expect(result.passed).toBe(true);
137
+ expect(result.violations).toHaveLength(0);
138
+ });
139
+ it('fails when metric is one over the max threshold (boundary)', () => {
140
+ const ratchet = makeRatchet({
141
+ thresholds: {
142
+ testCount: { min: 100 },
143
+ testFailures: { max: 0 },
144
+ typecheckErrors: { max: 5 },
145
+ lintErrors: { max: 10 },
146
+ },
147
+ });
148
+ const current = makeBaseline({
149
+ tests: { total: 100, passed: 99, failed: 1, skipped: 0 },
150
+ });
151
+ const result = checkQualityRatchet(ratchet, current);
152
+ expect(result.passed).toBe(false);
153
+ expect(result.violations).toHaveLength(1);
154
+ expect(result.violations[0].metric).toBe('testFailures');
155
+ expect(result.violations[0].actual).toBe(1);
156
+ expect(result.violations[0].threshold).toBe(0);
157
+ });
158
+ it('fails when test count is one below the min threshold (boundary)', () => {
159
+ const ratchet = makeRatchet();
160
+ const current = makeBaseline({
161
+ tests: { total: 99, passed: 99, failed: 0, skipped: 0 },
162
+ });
163
+ const result = checkQualityRatchet(ratchet, current);
164
+ expect(result.passed).toBe(false);
165
+ expect(result.violations[0].metric).toBe('testCount');
166
+ expect(result.violations[0].actual).toBe(99);
167
+ });
168
+ it('passes with zero-threshold ratchet when metrics are zero', () => {
169
+ const ratchet = makeRatchet({
170
+ thresholds: {
171
+ testCount: { min: 0 },
172
+ testFailures: { max: 0 },
173
+ typecheckErrors: { max: 0 },
174
+ lintErrors: { max: 0 },
175
+ },
176
+ });
177
+ const current = makeBaseline({
178
+ tests: { total: 0, passed: 0, failed: 0, skipped: 0 },
179
+ typecheck: { errorCount: 0, exitCode: 0 },
180
+ lint: { errorCount: 0, warningCount: 0 },
181
+ });
182
+ const result = checkQualityRatchet(ratchet, current);
183
+ expect(result.passed).toBe(true);
184
+ });
185
+ });
186
+ // ---------------------------------------------------------------------------
187
+ // updateQualityRatchet
188
+ // ---------------------------------------------------------------------------
189
+ describe('updateQualityRatchet', () => {
190
+ it('tightens thresholds when metrics improve', () => {
191
+ const ratchet = makeRatchet();
192
+ mockExistsSync.mockReturnValue(true);
193
+ mockReadFileSync.mockReturnValue(JSON.stringify(ratchet));
194
+ const improved = makeBaseline({
195
+ tests: { total: 110, passed: 110, failed: 0, skipped: 0 },
196
+ typecheck: { errorCount: 2, exitCode: 0 },
197
+ lint: { errorCount: 5, warningCount: 10 },
198
+ });
199
+ const updated = updateQualityRatchet('/repo', improved, 'SUP-200');
200
+ expect(updated).toBe(true);
201
+ expect(mockWriteFileSync).toHaveBeenCalled();
202
+ const written = JSON.parse(mockWriteFileSync.mock.calls[0][1]);
203
+ expect(written.thresholds.testCount.min).toBe(110);
204
+ expect(written.thresholds.typecheckErrors.max).toBe(2);
205
+ expect(written.thresholds.lintErrors.max).toBe(5);
206
+ expect(written.updatedBy).toBe('SUP-200');
207
+ });
208
+ it('does not update when metrics are worse or equal', () => {
209
+ const ratchet = makeRatchet();
210
+ mockExistsSync.mockReturnValue(true);
211
+ mockReadFileSync.mockReturnValue(JSON.stringify(ratchet));
212
+ const same = makeBaseline();
213
+ const updated = updateQualityRatchet('/repo', same, 'SUP-200');
214
+ expect(updated).toBe(false);
215
+ expect(mockWriteFileSync).not.toHaveBeenCalled();
216
+ });
217
+ it('returns false when ratchet file does not exist', () => {
218
+ mockExistsSync.mockReturnValue(false);
219
+ const updated = updateQualityRatchet('/repo', makeBaseline(), 'SUP-200');
220
+ expect(updated).toBe(false);
221
+ });
222
+ it('tightens only the metrics that improved (partial improvement)', () => {
223
+ const ratchet = makeRatchet({
224
+ thresholds: {
225
+ testCount: { min: 100 },
226
+ testFailures: { max: 5 },
227
+ typecheckErrors: { max: 10 },
228
+ lintErrors: { max: 20 },
229
+ },
230
+ });
231
+ mockExistsSync.mockReturnValue(true);
232
+ mockReadFileSync.mockReturnValue(JSON.stringify(ratchet));
233
+ // Only typecheck improved, rest is same or worse
234
+ const partial = makeBaseline({
235
+ tests: { total: 100, passed: 95, failed: 5, skipped: 0 },
236
+ typecheck: { errorCount: 3, exitCode: 0 },
237
+ lint: { errorCount: 20, warningCount: 0 },
238
+ });
239
+ const updated = updateQualityRatchet('/repo', partial, 'SUP-300');
240
+ expect(updated).toBe(true);
241
+ const written = JSON.parse(mockWriteFileSync.mock.calls[0][1]);
242
+ expect(written.thresholds.testCount.min).toBe(100); // unchanged
243
+ expect(written.thresholds.testFailures.max).toBe(5); // unchanged (equal)
244
+ expect(written.thresholds.typecheckErrors.max).toBe(3); // tightened
245
+ expect(written.thresholds.lintErrors.max).toBe(20); // unchanged (equal)
246
+ });
247
+ it('sets updatedAt to a recent timestamp', () => {
248
+ const ratchet = makeRatchet();
249
+ mockExistsSync.mockReturnValue(true);
250
+ mockReadFileSync.mockReturnValue(JSON.stringify(ratchet));
251
+ const improved = makeBaseline({
252
+ tests: { total: 200, passed: 200, failed: 0, skipped: 0 },
253
+ });
254
+ const before = new Date().toISOString();
255
+ updateQualityRatchet('/repo', improved, 'SUP-400');
256
+ const after = new Date().toISOString();
257
+ const written = JSON.parse(mockWriteFileSync.mock.calls[0][1]);
258
+ expect(written.updatedAt >= before).toBe(true);
259
+ expect(written.updatedAt <= after).toBe(true);
260
+ });
261
+ });
262
+ // ---------------------------------------------------------------------------
263
+ // initializeQualityRatchet
264
+ // ---------------------------------------------------------------------------
265
+ describe('initializeQualityRatchet', () => {
266
+ it('creates ratchet file from baseline', () => {
267
+ const baseline = makeBaseline({
268
+ tests: { total: 50, passed: 48, failed: 2, skipped: 0 },
269
+ typecheck: { errorCount: 3, exitCode: 0 },
270
+ lint: { errorCount: 7, warningCount: 15 },
271
+ });
272
+ const ratchet = initializeQualityRatchet('/repo', baseline);
273
+ expect(ratchet.version).toBe(1);
274
+ expect(ratchet.thresholds.testCount.min).toBe(50);
275
+ expect(ratchet.thresholds.testFailures.max).toBe(2);
276
+ expect(ratchet.thresholds.typecheckErrors.max).toBe(3);
277
+ expect(ratchet.thresholds.lintErrors.max).toBe(7);
278
+ expect(mockWriteFileSync).toHaveBeenCalled();
279
+ });
280
+ it('initializes from a zero-metric baseline', () => {
281
+ const baseline = makeBaseline({
282
+ tests: { total: 0, passed: 0, failed: 0, skipped: 0 },
283
+ typecheck: { errorCount: 0, exitCode: 0 },
284
+ lint: { errorCount: 0, warningCount: 0 },
285
+ });
286
+ const ratchet = initializeQualityRatchet('/repo', baseline);
287
+ expect(ratchet.thresholds.testCount.min).toBe(0);
288
+ expect(ratchet.thresholds.testFailures.max).toBe(0);
289
+ expect(ratchet.thresholds.typecheckErrors.max).toBe(0);
290
+ expect(ratchet.thresholds.lintErrors.max).toBe(0);
291
+ });
292
+ it('sets updatedBy to "manual"', () => {
293
+ const ratchet = initializeQualityRatchet('/repo', makeBaseline());
294
+ expect(ratchet.updatedBy).toBe('manual');
295
+ });
296
+ it('writes JSON with trailing newline', () => {
297
+ initializeQualityRatchet('/repo', makeBaseline());
298
+ const written = mockWriteFileSync.mock.calls[0][1];
299
+ expect(written.endsWith('\n')).toBe(true);
300
+ });
301
+ });
302
+ // ---------------------------------------------------------------------------
303
+ // formatRatchetResult
304
+ // ---------------------------------------------------------------------------
305
+ describe('formatRatchetResult', () => {
306
+ it('formats a passing result', () => {
307
+ expect(formatRatchetResult({ passed: true, violations: [] })).toContain('passed');
308
+ });
309
+ it('formats a failing result with violations', () => {
310
+ const result = formatRatchetResult({
311
+ passed: false,
312
+ violations: [
313
+ { metric: 'testCount', threshold: 100, actual: 90, direction: 'below-min' },
314
+ { metric: 'typecheckErrors', threshold: 5, actual: 8, direction: 'above-max' },
315
+ ],
316
+ });
317
+ expect(result).toContain('**FAILED**');
318
+ expect(result).toContain('testCount');
319
+ expect(result).toContain('below minimum');
320
+ expect(result).toContain('typecheckErrors');
321
+ expect(result).toContain('exceeds maximum');
322
+ });
323
+ it('formats a single violation', () => {
324
+ const result = formatRatchetResult({
325
+ passed: false,
326
+ violations: [
327
+ { metric: 'lintErrors', threshold: 10, actual: 15, direction: 'above-max' },
328
+ ],
329
+ });
330
+ expect(result).toContain('**FAILED**');
331
+ expect(result).toContain('lintErrors');
332
+ expect(result).toContain('15');
333
+ expect(result).toContain('10');
334
+ });
335
+ });
@@ -115,6 +115,8 @@ export interface OrchestratorConfig {
115
115
  repository?: string;
116
116
  /** Merge queue adapter for automated merge operations */
117
117
  mergeQueueAdapter?: import('../merge-queue/types.js').MergeQueueAdapter;
118
+ /** Storage backend for the local merge queue adapter (required when provider is 'local') */
119
+ mergeQueueStorage?: import('../merge-queue/adapters/local.js').LocalMergeQueueStorage;
118
120
  }
119
121
  export interface OrchestratorIssue {
120
122
  id: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/orchestrator/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/orchestrator/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"claude-provider.d.ts","sourceRoot":"","sources":["../../../src/providers/claude-provider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,OAAO,KAAK,EACV,aAAa,EACb,gBAAgB,EAChB,WAAW,EAEZ,MAAM,YAAY,CAAA;AAiFnB,qBAAa,cAAe,YAAW,aAAa;IAClD,QAAQ,CAAC,IAAI,EAAG,QAAQ,CAAS;IACjC,QAAQ,CAAC,YAAY;;;MAGX;IAEV,KAAK,CAAC,MAAM,EAAE,gBAAgB,GAAG,WAAW;IAI5C,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAG,WAAW;IAIhE,OAAO,CAAC,YAAY;CA8KrB;AAsND;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,cAAc,CAErD"}
1
+ {"version":3,"file":"claude-provider.d.ts","sourceRoot":"","sources":["../../../src/providers/claude-provider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,OAAO,KAAK,EACV,aAAa,EACb,gBAAgB,EAChB,WAAW,EAEZ,MAAM,YAAY,CAAA;AA6FnB,qBAAa,cAAe,YAAW,aAAa;IAClD,QAAQ,CAAC,IAAI,EAAG,QAAQ,CAAS;IACjC,QAAQ,CAAC,YAAY;;;MAGX;IAEV,KAAK,CAAC,MAAM,EAAE,gBAAgB,GAAG,WAAW;IAI5C,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAG,WAAW;IAIhE,OAAO,CAAC,YAAY;CA8KrB;AAsND;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,cAAc,CAErD"}
@@ -26,6 +26,17 @@ const autonomousCanUseTool = async (toolName, input) => {
26
26
  if (['Write', 'Edit', 'NotebookEdit'].includes(toolName)) {
27
27
  return { behavior: 'allow', updatedInput: input };
28
28
  }
29
+ // Agent tool: always force foreground execution.
30
+ // Coordinators that spawn sub-agents with run_in_background=true exit
31
+ // before sub-agents finish, orphaning work. Strip the flag so the Agent
32
+ // tool blocks until the sub-agent completes.
33
+ if (toolName === 'Agent') {
34
+ if (input.run_in_background) {
35
+ const { run_in_background: _, ...rest } = input;
36
+ return { behavior: 'allow', updatedInput: rest };
37
+ }
38
+ return { behavior: 'allow', updatedInput: input };
39
+ }
29
40
  // Task management and planning
30
41
  if (['Task', 'TaskCreate', 'TaskUpdate', 'TaskGet', 'TaskList',
31
42
  'EnterPlanMode', 'ExitPlanMode', 'Skill'].includes(toolName)) {
@@ -0,0 +1,237 @@
1
+ /**
2
+ * Codex App Server Provider
3
+ *
4
+ * Manages a long-lived `codex app-server` process communicating via JSON-RPC 2.0
5
+ * over stdio. Supports multiple concurrent threads on a single process.
6
+ *
7
+ * Architecture:
8
+ * orchestrator → codex app-server (long-lived, one process)
9
+ * ├── thread_1 (agent session A)
10
+ * ├── thread_2 (agent session B)
11
+ * └── thread_3 (agent session C)
12
+ *
13
+ * Falls back to `codex exec` CLI mode when app-server is unavailable.
14
+ *
15
+ * JSON-RPC 2.0 protocol (over stdio JSONL):
16
+ * 1. initialize + initialized handshake
17
+ * 2. thread/start or thread/resume
18
+ * 3. turn/start with prompt
19
+ * 4. Stream item/*, turn/*, thread/* notifications
20
+ * 5. thread/unsubscribe on completion
21
+ *
22
+ * @see https://developers.openai.com/codex/app-server
23
+ */
24
+ import type { AgentProvider, AgentSpawnConfig, AgentHandle, AgentEvent } from './types.js';
25
+ interface JsonRpcNotification {
26
+ method: string;
27
+ params?: Record<string, unknown>;
28
+ }
29
+ /** Status of a registered MCP server as reported by mcpServerStatus/list */
30
+ export interface McpServerStatusResult {
31
+ name: string;
32
+ status: 'connected' | 'connecting' | 'disconnected' | 'error';
33
+ toolCount?: number;
34
+ error?: string;
35
+ }
36
+ interface AppServerItem {
37
+ id: string;
38
+ type: string;
39
+ text?: string;
40
+ summary?: string;
41
+ content?: string;
42
+ command?: string;
43
+ cwd?: string;
44
+ status?: string;
45
+ exitCode?: number;
46
+ durationMs?: number;
47
+ changes?: Array<{
48
+ path: string;
49
+ kind: string;
50
+ }>;
51
+ server?: string;
52
+ tool?: string;
53
+ arguments?: unknown;
54
+ result?: {
55
+ content?: unknown[];
56
+ };
57
+ error?: {
58
+ message?: string;
59
+ };
60
+ items?: Array<{
61
+ text: string;
62
+ completed: boolean;
63
+ }>;
64
+ phase?: string;
65
+ }
66
+ interface AppServerTurn {
67
+ id: string;
68
+ status?: string;
69
+ usage?: {
70
+ input_tokens?: number;
71
+ output_tokens?: number;
72
+ cached_input_tokens?: number;
73
+ };
74
+ error?: {
75
+ message?: string;
76
+ codexErrorInfo?: string;
77
+ httpStatusCode?: number;
78
+ };
79
+ }
80
+ interface AppServerThread {
81
+ id: string;
82
+ status?: string;
83
+ }
84
+ /**
85
+ * Manages a single long-lived `codex app-server` process.
86
+ *
87
+ * Handles:
88
+ * - Process spawning and stdio communication
89
+ * - JSON-RPC 2.0 initialization handshake
90
+ * - Request/response correlation
91
+ * - Notification routing to thread subscribers
92
+ * - Health monitoring and graceful shutdown
93
+ */
94
+ export declare class AppServerProcessManager {
95
+ private process;
96
+ private readline;
97
+ private nextId;
98
+ private pendingRequests;
99
+ private initialized;
100
+ private shutdownPromise;
101
+ /** Notification listeners keyed by threadId */
102
+ private threadListeners;
103
+ /** Global notification listeners (for notifications without a threadId) */
104
+ private globalListeners;
105
+ private readonly codexBin;
106
+ private readonly cwd;
107
+ private readonly env;
108
+ constructor(options: {
109
+ codexBin?: string;
110
+ cwd: string;
111
+ env?: Record<string, string>;
112
+ });
113
+ /**
114
+ * Start the app-server process and complete the initialization handshake.
115
+ * Idempotent — returns immediately if already initialized.
116
+ */
117
+ start(): Promise<void>;
118
+ /**
119
+ * JSON-RPC 2.0 initialization handshake:
120
+ * 1. Send `initialize` request
121
+ * 2. Receive response
122
+ * 3. Send `initialized` notification
123
+ */
124
+ private initialize;
125
+ /**
126
+ * Send a JSON-RPC request and wait for the response.
127
+ */
128
+ request(method: string, params?: Record<string, unknown>, timeoutMs?: number): Promise<unknown>;
129
+ /**
130
+ * Send a JSON-RPC message (request or notification) to the app-server.
131
+ */
132
+ private send;
133
+ /**
134
+ * Handle an incoming JSON-RPC response.
135
+ */
136
+ private handleResponse;
137
+ /**
138
+ * Handle an incoming JSON-RPC notification.
139
+ * Routes to the appropriate thread listener based on threadId in params.
140
+ */
141
+ private handleNotification;
142
+ /**
143
+ * Subscribe to notifications for a specific thread.
144
+ */
145
+ subscribeThread(threadId: string, listener: (notification: JsonRpcNotification) => void): void;
146
+ /**
147
+ * Unsubscribe from notifications for a specific thread.
148
+ */
149
+ unsubscribeThread(threadId: string): void;
150
+ /**
151
+ * Check if the app-server process is alive and initialized.
152
+ */
153
+ isHealthy(): boolean;
154
+ /** Whether MCP servers have been configured on this process */
155
+ private mcpConfigured;
156
+ /**
157
+ * Register MCP servers with the app-server via config/batchWrite.
158
+ * Called once after initialization to tell Codex about the stdio
159
+ * MCP tool servers (af-linear, af-code-intelligence, etc.).
160
+ *
161
+ * Uses the Codex app-server `config/batchWrite` JSON-RPC method
162
+ * to register multiple MCP server configurations in a single call.
163
+ */
164
+ configureMcpServers(servers: Array<{
165
+ name: string;
166
+ command: string;
167
+ args: string[];
168
+ env?: Record<string, string>;
169
+ }>): Promise<void>;
170
+ /**
171
+ * Query MCP server health via mcpServerStatus/list.
172
+ * Returns the status of all registered MCP servers.
173
+ */
174
+ getMcpServerStatus(): Promise<McpServerStatusResult[]>;
175
+ /**
176
+ * Get the PID of the app-server process.
177
+ */
178
+ get pid(): number | undefined;
179
+ /**
180
+ * Graceful shutdown: unsubscribe all threads, kill process.
181
+ */
182
+ shutdown(): Promise<void>;
183
+ private performShutdown;
184
+ private rejectAllPending;
185
+ }
186
+ export interface AppServerEventMapperState {
187
+ sessionId: string | null;
188
+ totalInputTokens: number;
189
+ totalOutputTokens: number;
190
+ turnCount: number;
191
+ }
192
+ /**
193
+ * Map an App Server notification to normalized AgentEvents.
194
+ * Exported for unit testing.
195
+ */
196
+ export declare function mapAppServerNotification(notification: JsonRpcNotification, state: AppServerEventMapperState): AgentEvent[];
197
+ /**
198
+ * Map item/started and item/completed notifications to AgentEvents.
199
+ * Exported for unit testing.
200
+ */
201
+ export declare function mapAppServerItemEvent(method: string, params: Record<string, unknown>): AgentEvent[];
202
+ /**
203
+ * Normalize Codex MCP tool names to the `mcp__{server}__{tool}` format
204
+ * used by the orchestrator and Claude provider for consistent tool tracking.
205
+ *
206
+ * Codex reports MCP tools as `server` + `tool` (e.g., server='af-linear',
207
+ * tool='af_linear_get_issue'). We normalize to 'mcp__af-linear__af_linear_get_issue'.
208
+ */
209
+ export declare function normalizeMcpToolName(server?: string, tool?: string): string;
210
+ /**
211
+ * Codex App Server Provider
212
+ *
213
+ * Uses a long-lived `codex app-server` process with JSON-RPC 2.0 over stdio.
214
+ * Falls back to `codex exec` CLI mode when CODEX_USE_APP_SERVER is not set
215
+ * or when the app-server binary is unavailable.
216
+ */
217
+ export declare class CodexAppServerProvider implements AgentProvider {
218
+ readonly name: "codex";
219
+ readonly capabilities: {
220
+ readonly supportsMessageInjection: true;
221
+ readonly supportsSessionResume: true;
222
+ };
223
+ /** Shared process manager — one app-server process serves all threads */
224
+ private processManager;
225
+ spawn(config: AgentSpawnConfig): AgentHandle;
226
+ resume(sessionId: string, config: AgentSpawnConfig): AgentHandle;
227
+ /**
228
+ * Shut down the shared app-server process.
229
+ * Called when the orchestrator is done with this provider.
230
+ */
231
+ shutdown(): Promise<void>;
232
+ private getOrCreateProcessManager;
233
+ }
234
+ export declare function createCodexAppServerProvider(): CodexAppServerProvider;
235
+ /** Exported for testing */
236
+ export type { JsonRpcNotification, AppServerItem, AppServerTurn, AppServerThread };
237
+ //# sourceMappingURL=codex-app-server-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-app-server-provider.d.ts","sourceRoot":"","sources":["../../../src/providers/codex-app-server-provider.ts"],"names":[],"mappings":"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"}