@open-agent-toolkit/cli 0.1.48 → 0.1.51

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 (53) hide show
  1. package/assets/agents/oat-phase-implementer.md +16 -5
  2. package/assets/docs/cli-utilities/configuration.md +41 -0
  3. package/assets/docs/cli-utilities/workflow-gates.md +18 -1
  4. package/assets/docs/provider-sync/commands.md +29 -1
  5. package/assets/docs/provider-sync/providers.md +18 -5
  6. package/assets/docs/provider-sync/scope-and-surface.md +13 -0
  7. package/assets/docs/workflows/projects/dispatch-ceiling.md +59 -7
  8. package/assets/docs/workflows/projects/implementation-execution.md +63 -3
  9. package/assets/docs/workflows/projects/reviews.md +18 -1
  10. package/assets/public-package-versions.json +4 -4
  11. package/assets/skills/oat-agent-instructions-analyze/references/docs/provider-reference.md +8 -2
  12. package/assets/skills/oat-agent-instructions-apply/references/docs/provider-reference.md +8 -2
  13. package/assets/skills/oat-project-implement/SKILL.md +141 -59
  14. package/assets/skills/oat-project-review-provide/SKILL.md +44 -10
  15. package/assets/skills/oat-project-review-provide-remote/SKILL.md +28 -1
  16. package/dist/commands/config/index.d.ts +3 -0
  17. package/dist/commands/config/index.d.ts.map +1 -1
  18. package/dist/commands/config/index.js +70 -128
  19. package/dist/commands/doctor/index.d.ts +3 -0
  20. package/dist/commands/doctor/index.d.ts.map +1 -1
  21. package/dist/commands/doctor/index.js +205 -195
  22. package/dist/commands/gate/index.d.ts.map +1 -1
  23. package/dist/commands/gate/index.js +72 -1
  24. package/dist/commands/project/dispatch-ceiling/index.d.ts.map +1 -1
  25. package/dist/commands/project/dispatch-ceiling/index.js +224 -112
  26. package/dist/commands/providers/codex/materialize.d.ts.map +1 -1
  27. package/dist/commands/providers/codex/materialize.js +31 -15
  28. package/dist/config/dispatch-matrix.d.ts +59 -0
  29. package/dist/config/dispatch-matrix.d.ts.map +1 -0
  30. package/dist/config/dispatch-matrix.js +264 -0
  31. package/dist/config/oat-config.d.ts +2 -28
  32. package/dist/config/oat-config.d.ts.map +1 -1
  33. package/dist/config/oat-config.js +8 -144
  34. package/dist/config/resolve.d.ts.map +1 -1
  35. package/dist/config/resolve.js +2 -1
  36. package/dist/providers/codex/codec/config-merge.d.ts +8 -2
  37. package/dist/providers/codex/codec/config-merge.d.ts.map +1 -1
  38. package/dist/providers/codex/codec/config-merge.js +17 -2
  39. package/dist/providers/codex/codec/sync-extension.d.ts.map +1 -1
  40. package/dist/providers/codex/codec/sync-extension.js +14 -4
  41. package/dist/providers/identity/availability.d.ts +12 -0
  42. package/dist/providers/identity/availability.d.ts.map +1 -1
  43. package/dist/providers/identity/availability.js +72 -29
  44. package/dist/providers/identity/dispatch-report.d.ts +124 -0
  45. package/dist/providers/identity/dispatch-report.d.ts.map +1 -0
  46. package/dist/providers/identity/dispatch-report.js +285 -0
  47. package/dist/providers/identity/dispatch-validation.d.ts +28 -0
  48. package/dist/providers/identity/dispatch-validation.d.ts.map +1 -0
  49. package/dist/providers/identity/dispatch-validation.js +149 -0
  50. package/dist/providers/identity/stamp.d.ts +2 -0
  51. package/dist/providers/identity/stamp.d.ts.map +1 -1
  52. package/dist/providers/identity/stamp.js +3 -1
  53. package/package.json +2 -2
@@ -1,13 +1,14 @@
1
1
  import { access, mkdtemp, readdir, readFile, rm, symlink, } from 'node:fs/promises';
2
2
  import { tmpdir } from 'node:os';
3
- import { join } from 'node:path';
3
+ import { dirname, join } from 'node:path';
4
4
  import { buildCommandContext, } from '../../app/command-context.js';
5
5
  import { compareVersions } from '../init/tools/shared/version.js';
6
6
  import { createPjmDisabledCheck, runPjmDoctorChecks, } from '../pjm/doctor.js';
7
7
  import { getSkillVersion } from '../shared/frontmatter.js';
8
8
  import { withScopeOption } from '../shared/scope-option.js';
9
9
  import { readGlobalOptions, resolveConcreteScopes, } from '../shared/shared.utils.js';
10
- import { readOatConfig, readOatLocalConfig, readUserConfig, isCodexMaterializedRouteTarget, isWorkflowDispatchCandidateLadder, isWorkflowDispatchFallbackRoute, } from '../../config/oat-config.js';
10
+ import { walkDispatchMatrix, } from '../../config/dispatch-matrix.js';
11
+ import { readOatConfig, readOatLocalConfig, readUserConfig, } from '../../config/oat-config.js';
11
12
  import { resolveAssetsRoot } from '../../fs/assets.js';
12
13
  import { resolveProjectRoot, resolveScopeRoot } from '../../fs/paths.js';
13
14
  import TOML from '@iarna/toml';
@@ -18,7 +19,8 @@ import { isOatManagedCodexRoleFile } from '../../providers/codex/codec/shared.js
18
19
  import { copilotAdapter } from '../../providers/copilot/index.js';
19
20
  import { cursorAdapter } from '../../providers/cursor/index.js';
20
21
  import { geminiAdapter } from '../../providers/gemini/index.js';
21
- import { normalizeMatrixCellAvailability, validateMatrixCell, } from '../../providers/identity/availability.js';
22
+ import { validateMatrixCell, } from '../../providers/identity/availability.js';
23
+ import { createDispatchValidationPassContext, validateDispatchMatrixRefs, } from '../../providers/identity/dispatch-validation.js';
22
24
  import { formatDoctorResults } from '../../ui/output.js';
23
25
  import { Command } from 'commander';
24
26
  async function pathExistsDefault(path) {
@@ -134,6 +136,8 @@ function createDependencies() {
134
136
  readOatLocalConfig,
135
137
  readUserConfig,
136
138
  validateMatrixCell,
139
+ createDispatchValidationPassContext,
140
+ validateDispatchMatrixRefs,
137
141
  processEnv: process.env,
138
142
  runPjmDoctorChecks,
139
143
  // Default binding remains self-contained, but still honors the caller-
@@ -141,97 +145,46 @@ function createDependencies() {
141
145
  checkSkillVersions: (scopeRoot, assetsRoot, pathExists = pathExistsDefault) => checkSkillVersionsDefault(scopeRoot, assetsRoot, pathExists),
142
146
  };
143
147
  }
144
- function isRouteTarget(entry) {
145
- return typeof entry === 'object' && entry !== null && !Array.isArray(entry);
148
+ function collectDispatchMatrixCellRefs(layers) {
149
+ return layers.flatMap(({ source, config }) => {
150
+ const providers = config.workflow?.dispatchCeiling?.providers ?? {};
151
+ return walkDispatchMatrix(providers, {
152
+ source,
153
+ pathPrefix: 'workflow.dispatchCeiling.providers',
154
+ });
155
+ });
146
156
  }
147
- function formatRouteTargetValue(entry) {
148
- return [entry.model, entry.effort].filter(Boolean).join('/');
157
+ function dispatchMatrixSourceLabel(source) {
158
+ switch (source) {
159
+ case 'user-config':
160
+ return 'user';
161
+ case 'repo-config':
162
+ return 'shared';
163
+ case 'local-config':
164
+ return 'local';
165
+ case 'project-state':
166
+ return 'project-state';
167
+ }
149
168
  }
150
- function addDispatchMatrixCellRefs(refs, layer, provider, path, cell) {
151
- if (typeof cell === 'string') {
152
- refs.push({ layer, provider, value: cell, path });
153
- return;
154
- }
155
- const addEntry = (entry, entryPath) => {
156
- if (typeof entry === 'string') {
157
- refs.push({ layer, provider, value: entry, path: entryPath });
158
- return;
159
- }
160
- if (!isRouteTarget(entry)) {
161
- return;
162
- }
163
- const targetProvider = entry.harness ?? provider;
164
- if (isCodexMaterializedRouteTarget(provider, entry)) {
165
- if (entry.model && entry.effort) {
166
- refs.push({
167
- layer,
168
- provider: targetProvider,
169
- value: formatRouteTargetValue(entry),
170
- path: entryPath,
171
- target: entry,
172
- });
173
- return;
174
- }
175
- }
176
- if (entry.model) {
177
- refs.push({
178
- layer,
179
- provider: targetProvider,
180
- value: entry.model,
181
- path: `${entryPath}.model`,
182
- });
183
- }
184
- if (entry.effort) {
185
- refs.push({
186
- layer,
187
- provider: targetProvider,
188
- value: entry.effort,
189
- path: `${entryPath}.effort`,
190
- });
191
- }
192
- };
193
- if (isWorkflowDispatchCandidateLadder(cell)) {
194
- for (const [candidateIndex, candidate] of cell.candidates.entries()) {
195
- const candidatePath = `${path}.candidates[${candidateIndex}]`;
196
- if (isWorkflowDispatchFallbackRoute(candidate)) {
197
- for (const [routeIndex, entry] of candidate.route.entries()) {
198
- addEntry(entry, `${candidatePath}.route[${routeIndex}]`);
199
- }
200
- continue;
201
- }
202
- addEntry(candidate, candidatePath);
203
- }
204
- return;
169
+ function dispatchMatrixRefValue(ref) {
170
+ return ref.value ?? ref.target?.model ?? ref.target?.effort ?? 'unknown';
171
+ }
172
+ function dispatchMatrixAvailabilityRef(ref) {
173
+ if (ref.value !== null) {
174
+ return { provider: ref.provider, value: ref.value, target: null };
205
175
  }
206
- for (const [index, entry] of cell.entries()) {
207
- addEntry(entry, `${path}[${index}]`);
176
+ if (ref.target === null) {
177
+ return null;
208
178
  }
209
- }
210
- function collectDispatchMatrixCellRefs(layers) {
211
- const refs = [];
212
- for (const { layer, config } of layers) {
213
- const providers = config.workflow?.dispatchCeiling?.providers ?? {};
214
- for (const [provider, providerValue] of Object.entries(providers)) {
215
- const providerPath = `workflow.dispatchCeiling.providers.${provider}`;
216
- if (typeof providerValue === 'string') {
217
- refs.push({
218
- layer,
219
- provider,
220
- value: providerValue,
221
- path: providerPath,
222
- });
223
- continue;
224
- }
225
- const tierMap = providerValue;
226
- for (const [tier, cell] of Object.entries(tierMap)) {
227
- if (cell === undefined) {
228
- continue;
229
- }
230
- addDispatchMatrixCellRefs(refs, layer, provider, `${providerPath}.${tier}`, cell);
231
- }
232
- }
179
+ const value = ref.target.model ?? ref.target.effort;
180
+ if (!value) {
181
+ return null;
233
182
  }
234
- return refs;
183
+ return {
184
+ provider: ref.target.harness ?? ref.provider,
185
+ value,
186
+ target: ref.target,
187
+ };
235
188
  }
236
189
  function formatDispatchMatrixIssueList(issues) {
237
190
  return issues
@@ -239,12 +192,12 @@ function formatDispatchMatrixIssueList(issues) {
239
192
  const suffix = 'message' in issue && typeof issue.message === 'string'
240
193
  ? `; ${issue.message}`
241
194
  : '';
242
- return `${issue.path}=${issue.value} (${issue.layer} config)${suffix}`;
195
+ return `${issue.path}=${dispatchMatrixRefValue(issue)} (${dispatchMatrixSourceLabel(issue.source)} config)${suffix}`;
243
196
  })
244
197
  .join(', ');
245
198
  }
246
199
  async function createDispatchMatrixDoctorCheck(scopeRoot, layers, dependencies) {
247
- const refs = collectDispatchMatrixCellRefs(layers);
200
+ const refs = collectDispatchMatrixCellRefs(layers).filter((ref) => dispatchMatrixAvailabilityRef(ref) !== null);
248
201
  if (refs.length === 0) {
249
202
  return {
250
203
  name: 'project:dispatch_matrix',
@@ -253,25 +206,19 @@ async function createDispatchMatrixDoctorCheck(scopeRoot, layers, dependencies)
253
206
  message: 'No configured dispatch matrix cells found in user, shared, or local config layers.',
254
207
  };
255
208
  }
209
+ const pass = dependencies.createDispatchValidationPassContext({
210
+ cwd: scopeRoot,
211
+ env: dependencies.processEnv,
212
+ validateMatrixCell: dependencies.validateMatrixCell,
213
+ });
214
+ const results = await dependencies.validateDispatchMatrixRefs(refs, pass);
256
215
  const issues = [];
257
- for (const ref of refs) {
258
- let result;
259
- try {
260
- result = normalizeMatrixCellAvailability(await dependencies.validateMatrixCell(ref.provider, ref.value, {
261
- cwd: scopeRoot,
262
- env: dependencies.processEnv,
263
- detailed: true,
264
- ...(ref.target ? { target: ref.target } : {}),
265
- }));
266
- }
267
- catch {
268
- result = { availability: 'unvalidated' };
269
- }
270
- if (result.availability !== 'valid') {
216
+ for (const result of results) {
217
+ if (result.status !== 'valid') {
271
218
  issues.push({
272
- ...ref,
273
- availability: result.availability,
274
- ...(result.message ? { message: result.message } : {}),
219
+ ...result.ref,
220
+ availability: result.status,
221
+ ...(result.diagnostic ? { message: result.diagnostic } : {}),
275
222
  });
276
223
  }
277
224
  }
@@ -332,6 +279,152 @@ async function isManagedCodexRoleConfig(scopeRoot, roleName, configFile, depende
332
279
  return false;
333
280
  }
334
281
  }
282
+ function getCodexAgents(config) {
283
+ const agents = config.agents;
284
+ return agents && typeof agents === 'object' && !Array.isArray(agents)
285
+ ? agents
286
+ : {};
287
+ }
288
+ function getCodexMaxDepthEntry(config) {
289
+ const agents = getCodexAgents(config);
290
+ return {
291
+ present: Object.prototype.hasOwnProperty.call(agents, 'max_depth'),
292
+ value: agents.max_depth,
293
+ };
294
+ }
295
+ /**
296
+ * Applies Codex config precedence without letting an invalid project value fall
297
+ * through to the lower-precedence user value.
298
+ */
299
+ async function resolveDoctorCodexMaxDepth(scope, parsedConfig, userHome, dependencies) {
300
+ const scopedEntry = getCodexMaxDepthEntry(parsedConfig);
301
+ if (scope !== 'project' || scopedEntry.present) {
302
+ return scopedEntry;
303
+ }
304
+ const userConfigPath = join(userHome, '.codex', 'config.toml');
305
+ if (!(await dependencies.pathExists(userConfigPath))) {
306
+ return scopedEntry;
307
+ }
308
+ try {
309
+ return getCodexMaxDepthEntry(TOML.parse(await dependencies.readFile(userConfigPath)));
310
+ }
311
+ catch {
312
+ return { present: true, value: null };
313
+ }
314
+ }
315
+ function createCodexMaxDepthCheck(scope, entry) {
316
+ const topology = 'root (0) → phase coordinator (1) → task worker (2)';
317
+ const numericDepth = typeof entry.value === 'number' && Number.isFinite(entry.value)
318
+ ? entry.value
319
+ : null;
320
+ const sufficient = numericDepth !== null && numericDepth >= 2;
321
+ let state;
322
+ if (!entry.present) {
323
+ state = 'agents.max_depth is missing';
324
+ }
325
+ else if (numericDepth === null) {
326
+ state = 'agents.max_depth is not a valid number';
327
+ }
328
+ else {
329
+ state = `agents.max_depth is ${numericDepth}`;
330
+ }
331
+ return {
332
+ name: `${scope}:codex_max_depth`,
333
+ description: 'Codex managed-role nested dispatch depth',
334
+ status: sufficient ? 'pass' : 'warn',
335
+ message: sufficient
336
+ ? `${state}; sufficient for ${topology}.`
337
+ : `${state}; OAT managed implementation requires ${topology}.`,
338
+ fix: sufficient
339
+ ? undefined
340
+ : `Run \`oat sync --scope ${scope}\`, or materialize a single role with \`oat providers codex materialize <agent-name> --model <model> --effort <effort> --scope ${scope}\`.`,
341
+ };
342
+ }
343
+ async function runCodexChecksForScope(scope, scopeRoot, userHome, dependencies) {
344
+ const checks = [];
345
+ const codexConfigPath = join(scopeRoot, '.codex', 'config.toml');
346
+ if (!(await dependencies.pathExists(codexConfigPath))) {
347
+ return checks;
348
+ }
349
+ let parsedConfig;
350
+ try {
351
+ parsedConfig = TOML.parse(await dependencies.readFile(codexConfigPath));
352
+ checks.push({
353
+ name: `${scope}:codex_config_toml`,
354
+ description: 'Codex config TOML parseability',
355
+ status: 'pass',
356
+ message: '.codex/config.toml parsed successfully.',
357
+ });
358
+ }
359
+ catch (error) {
360
+ checks.push({
361
+ name: `${scope}:codex_config_toml`,
362
+ description: 'Codex config TOML parseability',
363
+ status: 'fail',
364
+ message: error instanceof Error
365
+ ? `Failed to parse .codex/config.toml: ${error.message}`
366
+ : 'Failed to parse .codex/config.toml.',
367
+ fix: 'Repair .codex/config.toml syntax and rerun doctor.',
368
+ });
369
+ return checks;
370
+ }
371
+ const features = parsedConfig.features &&
372
+ typeof parsedConfig.features === 'object' &&
373
+ !Array.isArray(parsedConfig.features)
374
+ ? parsedConfig.features
375
+ : null;
376
+ const agents = getCodexAgents(parsedConfig);
377
+ const managedRoles = [];
378
+ const roleConfigFiles = new Map();
379
+ for (const [roleName, roleConfig] of Object.entries(agents)) {
380
+ const configFile = getCodexAgentConfigFile(roleConfig);
381
+ if (!configFile) {
382
+ continue;
383
+ }
384
+ roleConfigFiles.set(roleName, configFile);
385
+ if (await isManagedCodexRoleConfig(scopeRoot, roleName, configFile, dependencies)) {
386
+ managedRoles.push(roleName);
387
+ }
388
+ }
389
+ if (managedRoles.length === 0) {
390
+ return checks;
391
+ }
392
+ const multiAgentEnabled = features?.multi_agent === true || features?.multi_agent === 'true';
393
+ checks.push({
394
+ name: `${scope}:codex_multi_agent`,
395
+ description: 'Codex multi-agent feature flag',
396
+ status: multiAgentEnabled ? 'pass' : 'warn',
397
+ message: multiAgentEnabled
398
+ ? 'features.multi_agent is enabled for codex managed roles.'
399
+ : 'Codex managed roles detected but features.multi_agent is not true.',
400
+ fix: multiAgentEnabled
401
+ ? undefined
402
+ : 'Set [features] multi_agent = true in .codex/config.toml.',
403
+ });
404
+ checks.push(createCodexMaxDepthCheck(scope, await resolveDoctorCodexMaxDepth(scope, parsedConfig, userHome, dependencies)));
405
+ const missingRoleFiles = [];
406
+ for (const roleName of managedRoles) {
407
+ const configFile = roleConfigFiles.get(roleName);
408
+ if (!configFile)
409
+ continue;
410
+ const absoluteRolePath = join(scopeRoot, '.codex', configFile);
411
+ if (!(await dependencies.pathExists(absoluteRolePath))) {
412
+ missingRoleFiles.push(configFile);
413
+ }
414
+ }
415
+ checks.push({
416
+ name: `${scope}:codex_role_file_refs`,
417
+ description: 'Codex role config_file references',
418
+ status: missingRoleFiles.length === 0 ? 'pass' : 'warn',
419
+ message: missingRoleFiles.length === 0
420
+ ? 'All codex role config_file references exist.'
421
+ : `Missing codex role files: ${missingRoleFiles.join(', ')}`,
422
+ fix: missingRoleFiles.length === 0
423
+ ? undefined
424
+ : `Regenerate codex roles with \`oat sync --scope ${scope}\`, or materialize a single role with \`oat providers codex materialize <agent-name> --model <model> --effort <effort> --scope ${scope}\`.`,
425
+ });
426
+ return checks;
427
+ }
335
428
  async function runChecksForScope(scope, scopeRoot, userConfigDir, dependencies) {
336
429
  const checks = [];
337
430
  const skillsPath = join(scopeRoot, '.agents', 'skills');
@@ -407,6 +500,7 @@ async function runChecksForScope(scope, scopeRoot, userConfigDir, dependencies)
407
500
  ? undefined
408
501
  : 'Install or enable a provider directory (e.g. .claude, .cursor, .codex).',
409
502
  });
503
+ checks.push(...(await runCodexChecksForScope(scope, scopeRoot, dirname(userConfigDir), dependencies)));
410
504
  if (scope === 'project') {
411
505
  try {
412
506
  const assetsRoot = await dependencies.resolveAssetsRoot();
@@ -456,90 +550,6 @@ async function runChecksForScope(scope, scopeRoot, userConfigDir, dependencies)
456
550
  fix: 'Run `pnpm build` and rerun `oat doctor`.',
457
551
  });
458
552
  }
459
- const codexConfigPath = join(scopeRoot, '.codex', 'config.toml');
460
- const codexConfigExists = await dependencies.pathExists(codexConfigPath);
461
- if (codexConfigExists) {
462
- let parsedConfig = null;
463
- try {
464
- parsedConfig = TOML.parse(await dependencies.readFile(codexConfigPath));
465
- checks.push({
466
- name: `${scope}:codex_config_toml`,
467
- description: 'Codex config TOML parseability',
468
- status: 'pass',
469
- message: '.codex/config.toml parsed successfully.',
470
- });
471
- }
472
- catch (error) {
473
- checks.push({
474
- name: `${scope}:codex_config_toml`,
475
- description: 'Codex config TOML parseability',
476
- status: 'fail',
477
- message: error instanceof Error
478
- ? `Failed to parse .codex/config.toml: ${error.message}`
479
- : 'Failed to parse .codex/config.toml.',
480
- fix: 'Repair .codex/config.toml syntax and rerun doctor.',
481
- });
482
- }
483
- if (parsedConfig) {
484
- const features = parsedConfig.features &&
485
- typeof parsedConfig.features === 'object' &&
486
- !Array.isArray(parsedConfig.features)
487
- ? parsedConfig.features
488
- : null;
489
- const agents = parsedConfig.agents &&
490
- typeof parsedConfig.agents === 'object' &&
491
- !Array.isArray(parsedConfig.agents)
492
- ? parsedConfig.agents
493
- : null;
494
- const managedRoles = [];
495
- const roleConfigFiles = new Map();
496
- for (const [roleName, roleConfig] of Object.entries(agents ?? {})) {
497
- const configFile = getCodexAgentConfigFile(roleConfig);
498
- if (!configFile) {
499
- continue;
500
- }
501
- roleConfigFiles.set(roleName, configFile);
502
- if (await isManagedCodexRoleConfig(scopeRoot, roleName, configFile, dependencies)) {
503
- managedRoles.push(roleName);
504
- }
505
- }
506
- if (managedRoles.length > 0) {
507
- const multiAgentEnabled = features?.multi_agent === true || features?.multi_agent === 'true';
508
- checks.push({
509
- name: `${scope}:codex_multi_agent`,
510
- description: 'Codex multi-agent feature flag',
511
- status: multiAgentEnabled ? 'pass' : 'warn',
512
- message: multiAgentEnabled
513
- ? 'features.multi_agent is enabled for codex managed roles.'
514
- : 'Codex managed roles detected but features.multi_agent is not true.',
515
- fix: multiAgentEnabled
516
- ? undefined
517
- : 'Set [features] multi_agent = true in .codex/config.toml.',
518
- });
519
- const missingRoleFiles = [];
520
- for (const roleName of managedRoles) {
521
- const configFile = roleConfigFiles.get(roleName);
522
- if (!configFile)
523
- continue;
524
- const absoluteRolePath = join(scopeRoot, '.codex', configFile);
525
- if (!(await dependencies.pathExists(absoluteRolePath))) {
526
- missingRoleFiles.push(configFile);
527
- }
528
- }
529
- checks.push({
530
- name: `${scope}:codex_role_file_refs`,
531
- description: 'Codex role config_file references',
532
- status: missingRoleFiles.length === 0 ? 'pass' : 'warn',
533
- message: missingRoleFiles.length === 0
534
- ? 'All codex role config_file references exist.'
535
- : `Missing codex role files: ${missingRoleFiles.join(', ')}`,
536
- fix: missingRoleFiles.length === 0
537
- ? undefined
538
- : 'Regenerate codex roles with `oat sync --scope project`, or materialize a single role with `oat providers codex materialize ...`.',
539
- });
540
- }
541
- }
542
- }
543
553
  const repoReferenceRoot = join(scopeRoot, '.oat', 'repo');
544
554
  const [userConfig, config, localConfig] = await Promise.all([
545
555
  dependencies.readUserConfig(userConfigDir),
@@ -547,9 +557,9 @@ async function runChecksForScope(scope, scopeRoot, userConfigDir, dependencies)
547
557
  dependencies.readOatLocalConfig(scopeRoot),
548
558
  ]);
549
559
  checks.push(await createDispatchMatrixDoctorCheck(scopeRoot, [
550
- { layer: 'user', config: userConfig },
551
- { layer: 'shared', config },
552
- { layer: 'local', config: localConfig },
560
+ { source: 'user-config', config: userConfig },
561
+ { source: 'repo-config', config },
562
+ { source: 'local-config', config: localConfig },
553
563
  ], dependencies));
554
564
  const projectManagementEnabled = config.tools?.['project-management'] === true;
555
565
  if (projectManagementEnabled) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/gate/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAQ9B,OAAO,EAQL,KAAK,UAAU,EAIf,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,UAAU,EAEhB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,iBAAiB,CAAC;AAOzB,OAAO,EAEL,KAAK,WAAW,EACjB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EAExB,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EACL,sBAAsB,EAIvB,MAAM,kBAAkB,CAAC;AAE1B,UAAU,uBAAuB;IAC/B,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;IACxD,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvE,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;IAClE,mBAAmB,EAAE,CACnB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,cAAc,KACnB,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,cAAc,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IAC/D,eAAe,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,sBAAsB,EAAE,CACtB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,GAAG,EAAE,MAAM,CAAC,UAAU,KACnB,OAAO,CAAC,cAAc,CAAC,CAAC;IAC7B,UAAU,EAAE,CACV,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE,iBAAiB,KACvB,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC/B,sBAAsB,EAAE,OAAO,sBAAsB,CAAC;IACtD,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC;CAC/B;AA6CD,UAAU,iBAAiB;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,OAAO,EAAE,gBAAgB,GAAG,cAAc,GAAG,SAAS,CAAC;IACvD,KAAK,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,gBAAgB;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,KAAK,kBAAkB,GAAG,aAAa,GAAG,cAAc,GAAG,MAAM,CAAC;AAClE,KAAK,qBAAqB,GACtB,kBAAkB,GAClB,4BAA4B,GAC5B,2CAA2C,GAC3C,kBAAkB,CAAC;AAUvB,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,WAAW,CAAC;IACpB,SAAS,CAAC,EAAE,qBAAqB,CAAC;IAClC,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACnC;AAED,UAAU,oBAAoB;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,kBAAkB,CAAC;IAC/B,UAAU,EAAE,kBAAkB,CAAC;IAC/B,MAAM,EAAE,WAAW,CAAC;IACpB,aAAa,EAAE,WAAW,EAAE,CAAC;IAC7B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,kBAAkB,EAAE,OAAO,CAAC;IAC5B,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,mBAAmB,GAAG,SAAS,CAAC;CAC5D;AAED,UAAU,qBAAqB;IAC7B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,QAAQ,EAAE,qBAAqB,CAAC;IAChC,QAAQ,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,kBAAkB,CAAC;QAC/B,UAAU,EAAE,kBAAkB,CAAC;QAC/B,MAAM,EAAE,WAAW,CAAC;QACpB,MAAM,EAAE,oBAAoB,CAAC,QAAQ,CAAC,CAAC;QACvC,aAAa,EAAE,WAAW,EAAE,CAAC;QAC7B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;QAC9B,sBAAsB,CAAC,EAAE,MAAM,CAAC;KACjC,CAAC;IACF,QAAQ,EAAE;QACR,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,WAAW,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA4+BD,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,EAC9C,cAAc,EAAE,MAAM,EACtB,KAAK,EAAE,kBAAkB,EACzB,gBAAgB,CAAC,EAAE,oBAAoB,GACtC,kBAAkB,GAAG,IAAI,CAS3B;AA2+CD,wBAAgB,iBAAiB,CAC/B,SAAS,GAAE,OAAO,CAAC,uBAAuB,CAAM,GAC/C,OAAO,CAwMT"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/gate/index.ts"],"names":[],"mappings":"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"}