@open-agent-toolkit/cli 0.1.48 → 0.1.50

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 (40) hide show
  1. package/assets/docs/cli-utilities/configuration.md +41 -0
  2. package/assets/docs/cli-utilities/workflow-gates.md +17 -0
  3. package/assets/docs/provider-sync/providers.md +5 -1
  4. package/assets/docs/workflows/projects/dispatch-ceiling.md +59 -7
  5. package/assets/docs/workflows/projects/implementation-execution.md +34 -0
  6. package/assets/public-package-versions.json +4 -4
  7. package/assets/skills/oat-project-implement/SKILL.md +49 -22
  8. package/assets/skills/oat-project-review-provide/SKILL.md +18 -2
  9. package/assets/skills/oat-project-review-provide-remote/SKILL.md +28 -1
  10. package/dist/commands/config/index.d.ts +3 -0
  11. package/dist/commands/config/index.d.ts.map +1 -1
  12. package/dist/commands/config/index.js +70 -128
  13. package/dist/commands/doctor/index.d.ts +3 -0
  14. package/dist/commands/doctor/index.d.ts.map +1 -1
  15. package/dist/commands/doctor/index.js +57 -110
  16. package/dist/commands/gate/index.d.ts.map +1 -1
  17. package/dist/commands/gate/index.js +71 -0
  18. package/dist/commands/project/dispatch-ceiling/index.d.ts.map +1 -1
  19. package/dist/commands/project/dispatch-ceiling/index.js +144 -112
  20. package/dist/config/dispatch-matrix.d.ts +59 -0
  21. package/dist/config/dispatch-matrix.d.ts.map +1 -0
  22. package/dist/config/dispatch-matrix.js +264 -0
  23. package/dist/config/oat-config.d.ts +2 -28
  24. package/dist/config/oat-config.d.ts.map +1 -1
  25. package/dist/config/oat-config.js +8 -144
  26. package/dist/config/resolve.d.ts.map +1 -1
  27. package/dist/config/resolve.js +2 -1
  28. package/dist/providers/identity/availability.d.ts +12 -0
  29. package/dist/providers/identity/availability.d.ts.map +1 -1
  30. package/dist/providers/identity/availability.js +72 -29
  31. package/dist/providers/identity/dispatch-report.d.ts +124 -0
  32. package/dist/providers/identity/dispatch-report.d.ts.map +1 -0
  33. package/dist/providers/identity/dispatch-report.js +285 -0
  34. package/dist/providers/identity/dispatch-validation.d.ts +28 -0
  35. package/dist/providers/identity/dispatch-validation.d.ts.map +1 -0
  36. package/dist/providers/identity/dispatch-validation.js +149 -0
  37. package/dist/providers/identity/stamp.d.ts +2 -0
  38. package/dist/providers/identity/stamp.d.ts.map +1 -1
  39. package/dist/providers/identity/stamp.js +3 -1
  40. package/package.json +2 -2
@@ -5,12 +5,14 @@ import { resolveProjectsRoot } from '../shared/oat-paths.js';
5
5
  import { confirmAction, } from '../shared/shared.prompts.js';
6
6
  import { readGlobalOptions } from '../shared/shared.utils.js';
7
7
  import { compileDispatchCeilingPreset } from '../../config/dispatch-ceiling-preset.js';
8
+ import { normalizeDispatchMatrix, validateDispatchRouteTarget, walkDispatchMatrix, } from '../../config/dispatch-matrix.js';
8
9
  import { dispatchPolicyModeDescription, dispatchPolicyPolicyDescription, managedDispatchPolicyValueList, } from '../../config/dispatch-policy-options.js';
9
- import { VALID_DISPATCH_POLICY_MODES, VALID_MANAGED_DISPATCH_POLICIES, isCodexMaterializedRouteTarget, isWorkflowDispatchCandidateLadder, isWorkflowDispatchFallbackRoute, readOatConfig, readOatLocalConfig, readUserConfig, validateDispatchRouteTarget, writeOatConfig, writeOatLocalConfig, writeUserConfig, } from '../../config/oat-config.js';
10
+ import { VALID_DISPATCH_POLICY_MODES, VALID_MANAGED_DISPATCH_POLICIES, readOatConfig, readOatLocalConfig, readUserConfig, writeOatConfig, writeOatLocalConfig, writeUserConfig, } from '../../config/oat-config.js';
10
11
  import { resolveEffectiveConfig, } from '../../config/resolve.js';
11
12
  import { resolveAssetsRoot } from '../../fs/assets.js';
12
13
  import { resolveProjectRoot } from '../../fs/paths.js';
13
14
  import { normalizeMatrixCellAvailability, validateMatrixCell, } from '../../providers/identity/availability.js';
15
+ import { createDispatchValidationPassContext, validateDispatchMatrixRefs, } from '../../providers/identity/dispatch-validation.js';
14
16
  import { Command } from 'commander';
15
17
  import { createConfigDumpCommand } from './dump.js';
16
18
  const DISPATCH_CEILING_PROVIDER_KEY_PREFIX = 'workflow.dispatchCeiling.providers.';
@@ -563,6 +565,8 @@ const DEFAULT_DEPENDENCIES = {
563
565
  readFile: (path) => readFileDefault(path, 'utf8'),
564
566
  confirmAction,
565
567
  validateMatrixCell,
568
+ createDispatchValidationPassContext,
569
+ validateDispatchMatrixRefs,
566
570
  processEnv: process.env,
567
571
  };
568
572
  function isConfigKey(value) {
@@ -765,130 +769,62 @@ function parseDispatchMatrixRecommendation(raw) {
765
769
  if (!isRecord(parsed.providers)) {
766
770
  throw new Error('Dispatch matrix recommendation asset is missing providers.');
767
771
  }
772
+ const normalized = normalizeDispatchMatrix(parsed.providers, {
773
+ pathPrefix: 'workflow.dispatchCeiling.providers',
774
+ compatibilityMode: 'layered-config',
775
+ });
768
776
  return {
769
777
  version,
770
- providers: parsed.providers,
778
+ providers: normalized.providers,
779
+ issues: normalized.issues,
771
780
  };
772
781
  }
773
- function isRouteTarget(entry) {
774
- return isRecord(entry);
775
- }
776
- function formatRouteTargetValue(entry) {
777
- return [entry.model, entry.effort].filter(Boolean).join('/');
782
+ function collectDispatchMatrixCellRefs(providers) {
783
+ return walkDispatchMatrix(providers, {
784
+ source: 'repo-config',
785
+ pathPrefix: 'workflow.dispatchCeiling.providers',
786
+ });
778
787
  }
779
- function addDispatchMatrixCellRefs(refs, provider, path, cell) {
780
- if (typeof cell === 'string') {
781
- refs.push({ provider, value: cell, path });
782
- return;
783
- }
784
- const addEntry = (entry, entryPath) => {
785
- if (typeof entry === 'string') {
786
- refs.push({ provider, value: entry, path: entryPath });
787
- return;
788
- }
789
- if (!isRouteTarget(entry)) {
790
- return;
791
- }
792
- const targetProvider = entry.harness ?? provider;
793
- if (isCodexMaterializedRouteTarget(provider, entry)) {
794
- if (entry.model && entry.effort) {
795
- refs.push({
796
- provider: targetProvider,
797
- value: formatRouteTargetValue(entry),
798
- path: entryPath,
799
- target: entry,
800
- });
801
- return;
802
- }
803
- }
804
- if (entry.model) {
805
- refs.push({
806
- provider: targetProvider,
807
- value: entry.model,
808
- path: `${entryPath}.model`,
809
- });
810
- }
811
- if (entry.effort) {
812
- refs.push({
813
- provider: targetProvider,
814
- value: entry.effort,
815
- path: `${entryPath}.effort`,
816
- });
817
- }
818
- };
819
- if (isWorkflowDispatchCandidateLadder(cell)) {
820
- for (const [candidateIndex, candidate] of cell.candidates.entries()) {
821
- const candidatePath = `${path}.candidates[${candidateIndex}]`;
822
- if (isWorkflowDispatchFallbackRoute(candidate)) {
823
- for (const [routeIndex, entry] of candidate.route.entries()) {
824
- addEntry(entry, `${candidatePath}.route[${routeIndex}]`);
825
- }
826
- continue;
827
- }
828
- addEntry(candidate, candidatePath);
788
+ function collectDispatchMatrixTargetValidationErrors(refs, issues) {
789
+ const errors = issues.map((issue) => {
790
+ const relativePath = issue.path.startsWith(DISPATCH_CEILING_PROVIDER_KEY_PREFIX)
791
+ ? issue.path.slice(DISPATCH_CEILING_PROVIDER_KEY_PREFIX.length)
792
+ : '';
793
+ const provider = relativePath.split(/[.[]/, 1)[0] ?? '';
794
+ const closedValues = closedDispatchProviderValues(provider);
795
+ if (typeof issue.value === 'string' && closedValues) {
796
+ return `Invalid value for ${issue.path}: expected one of ${closedValues.join(' | ')}, got '${issue.value}'`;
829
797
  }
830
- return;
831
- }
832
- for (const [index, entry] of cell.entries()) {
833
- addEntry(entry, `${path}[${index}]`);
834
- }
835
- }
836
- function collectDispatchMatrixCellRefs(providers) {
837
- const refs = [];
838
- for (const [provider, providerValue] of Object.entries(providers)) {
839
- const providerPath = `workflow.dispatchCeiling.providers.${provider}`;
840
- if (typeof providerValue === 'string') {
841
- refs.push({ provider, value: providerValue, path: providerPath });
798
+ return `${issue.path}: malformed dispatch matrix entry (${issue.kind}).`;
799
+ });
800
+ for (const ref of refs) {
801
+ if (ref.target === null) {
842
802
  continue;
843
803
  }
844
- for (const [tier, cell] of Object.entries(providerValue)) {
845
- if (cell === undefined) {
846
- continue;
847
- }
848
- addDispatchMatrixCellRefs(refs, provider, `${providerPath}.${tier}`, cell);
804
+ const validation = validateDispatchRouteTarget(ref.provider, ref.target);
805
+ if (!validation.valid) {
806
+ errors.push(`${ref.path}: ${validation.reason}`);
849
807
  }
850
808
  }
851
- return refs;
809
+ return errors;
852
810
  }
853
- function collectDispatchMatrixTargetValidationErrors(providers) {
854
- const errors = [];
855
- for (const [provider, providerValue] of Object.entries(providers)) {
856
- if (typeof providerValue === 'string') {
857
- continue;
858
- }
859
- const providerPath = `workflow.dispatchCeiling.providers.${provider}`;
860
- for (const [tier, cell] of Object.entries(providerValue)) {
861
- if (cell === undefined || typeof cell === 'string') {
862
- continue;
863
- }
864
- const validateEntry = (entry, entryPath) => {
865
- if (!isRouteTarget(entry)) {
866
- return;
867
- }
868
- const validation = validateDispatchRouteTarget(provider, entry);
869
- if (!validation.valid) {
870
- errors.push(`${entryPath}: ${validation.reason}`);
871
- }
872
- };
873
- if (isWorkflowDispatchCandidateLadder(cell)) {
874
- for (const [candidateIndex, candidate] of cell.candidates.entries()) {
875
- const candidatePath = `${providerPath}.${tier}.candidates[${candidateIndex}]`;
876
- if (isWorkflowDispatchFallbackRoute(candidate)) {
877
- for (const [routeIndex, entry] of candidate.route.entries()) {
878
- validateEntry(entry, `${candidatePath}.route[${routeIndex}]`);
879
- }
880
- continue;
881
- }
882
- validateEntry(candidate, candidatePath);
883
- }
884
- continue;
885
- }
886
- for (const [index, entry] of cell.entries()) {
887
- validateEntry(entry, `${providerPath}.${tier}[${index}]`);
888
- }
889
- }
811
+ function toAvailabilityRef(ref) {
812
+ if (ref.value !== null) {
813
+ return { provider: ref.provider, value: ref.value, path: ref.path };
890
814
  }
891
- return errors;
815
+ if (ref.target === null) {
816
+ return null;
817
+ }
818
+ const value = ref.target.model ?? ref.target.effort;
819
+ if (!value) {
820
+ return null;
821
+ }
822
+ return {
823
+ provider: ref.target.harness ?? ref.provider,
824
+ value,
825
+ path: ref.path,
826
+ target: ref.target,
827
+ };
892
828
  }
893
829
  function applyWorkflowValue(workflow, key, value) {
894
830
  const subKey = key.slice('workflow.'.length);
@@ -1225,28 +1161,34 @@ async function loadDispatchMatrixRecommendation(dependencies) {
1225
1161
  return parseDispatchMatrixRecommendation(await dependencies.readFile(assetPath));
1226
1162
  }
1227
1163
  async function validateRecommendationCells(repoRoot, recommendation, dependencies, warn) {
1228
- const targetErrors = collectDispatchMatrixTargetValidationErrors(recommendation.providers);
1164
+ const refs = collectDispatchMatrixCellRefs(recommendation.providers);
1165
+ const targetErrors = collectDispatchMatrixTargetValidationErrors(refs, recommendation.issues);
1229
1166
  if (targetErrors.length > 0) {
1230
1167
  throw new Error(targetErrors.join('\n'));
1231
1168
  }
1232
- for (const ref of collectDispatchMatrixCellRefs(recommendation.providers)) {
1169
+ const availabilityRefs = refs.filter((matrixRef) => {
1170
+ const ref = toAvailabilityRef(matrixRef);
1171
+ if (ref === null) {
1172
+ return false;
1173
+ }
1233
1174
  const closedValues = closedDispatchProviderValues(ref.provider);
1234
1175
  if (!ref.target && closedValues && !closedValues.includes(ref.value)) {
1235
1176
  throw new Error(`Invalid value for ${ref.path}: expected one of ${closedValues.join(' | ')}, got '${ref.value}'`);
1236
1177
  }
1237
- let availability;
1238
- try {
1239
- availability = await dependencies.validateMatrixCell(ref.provider, ref.value, {
1240
- cwd: repoRoot,
1241
- env: dependencies.processEnv,
1242
- detailed: true,
1243
- ...(ref.target ? { target: ref.target } : {}),
1244
- });
1245
- }
1246
- catch {
1247
- availability = 'unvalidated';
1248
- }
1249
- const warning = matrixCellAvailabilityWarning(ref.path, ref.value, availability);
1178
+ return true;
1179
+ });
1180
+ const pass = dependencies.createDispatchValidationPassContext({
1181
+ cwd: repoRoot,
1182
+ env: dependencies.processEnv,
1183
+ validateMatrixCell: dependencies.validateMatrixCell,
1184
+ });
1185
+ const results = await dependencies.validateDispatchMatrixRefs(availabilityRefs, pass);
1186
+ for (const result of results) {
1187
+ const ref = toAvailabilityRef(result.ref);
1188
+ const warning = matrixCellAvailabilityWarning(ref.path, ref.value, {
1189
+ availability: result.status,
1190
+ ...(result.diagnostic ? { message: result.diagnostic } : {}),
1191
+ });
1250
1192
  if (warning) {
1251
1193
  warn(warning);
1252
1194
  }
@@ -3,6 +3,7 @@ import { type PjmDoctorOptions } from '../pjm/doctor.js';
3
3
  import { type OatConfig, type OatLocalConfig, type UserConfig } from '../../config/oat-config.js';
4
4
  import { type Manifest } from '../../manifest/index.js';
5
5
  import { type MatrixCellAvailabilityResponse, type ValidateMatrixCellOptions } from '../../providers/identity/availability.js';
6
+ import { createDispatchValidationPassContext, validateDispatchMatrixRefs } from '../../providers/identity/dispatch-validation.js';
6
7
  import type { ConcreteScope } from '../../shared/types.js';
7
8
  import { type DoctorCheck } from '../../ui/output.js';
8
9
  import { Command } from 'commander';
@@ -23,6 +24,8 @@ interface DoctorDependencies {
23
24
  readOatLocalConfig: (repoRoot: string) => Promise<OatLocalConfig>;
24
25
  readUserConfig: (userConfigDir: string) => Promise<UserConfig>;
25
26
  validateMatrixCell: (provider: string, value: string, options: ValidateMatrixCellOptions) => Promise<MatrixCellAvailabilityResponse>;
27
+ createDispatchValidationPassContext: typeof createDispatchValidationPassContext;
28
+ validateDispatchMatrixRefs: typeof validateDispatchMatrixRefs;
26
29
  processEnv: NodeJS.ProcessEnv;
27
30
  runPjmDoctorChecks: (repoRoot: string, options?: PjmDoctorOptions) => Promise<DoctorCheck[]>;
28
31
  checkSkillVersions: (scopeRoot: string, assetsRoot: string, pathExists: (path: string) => Promise<boolean>) => Promise<SkillVersionReport>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/doctor/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/doctor/index.ts"],"names":[],"mappings":"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"}
@@ -7,7 +7,8 @@ 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);
146
- }
147
- function formatRouteTargetValue(entry) {
148
- return [entry.model, entry.effort].filter(Boolean).join('/');
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
+ });
149
156
  }
150
- function addDispatchMatrixCellRefs(refs, layer, provider, path, cell) {
151
- if (typeof cell === 'string') {
152
- refs.push({ layer, provider, value: cell, path });
153
- return;
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';
154
167
  }
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;
168
+ }
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
  }
@@ -547,9 +494,9 @@ async function runChecksForScope(scope, scopeRoot, userConfigDir, dependencies)
547
494
  dependencies.readOatLocalConfig(scopeRoot),
548
495
  ]);
549
496
  checks.push(await createDispatchMatrixDoctorCheck(scopeRoot, [
550
- { layer: 'user', config: userConfig },
551
- { layer: 'shared', config },
552
- { layer: 'local', config: localConfig },
497
+ { source: 'user-config', config: userConfig },
498
+ { source: 'repo-config', config },
499
+ { source: 'local-config', config: localConfig },
553
500
  ], dependencies));
554
501
  const projectManagementEnabled = config.tools?.['project-management'] === true;
555
502
  if (projectManagementEnabled) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/gate/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/gate/index.ts"],"names":[],"mappings":"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"}