@open-agent-toolkit/cli 0.1.43 → 0.1.46

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 (94) hide show
  1. package/assets/agents/oat-reviewer.md +2 -2
  2. package/assets/config/dispatch-matrix-recommendation.json +23 -0
  3. package/assets/docs/cli-utilities/config-and-local-state.md +7 -0
  4. package/assets/docs/cli-utilities/configuration.md +104 -25
  5. package/assets/docs/cli-utilities/workflow-gates.md +79 -16
  6. package/assets/docs/contributing/code.md +10 -4
  7. package/assets/docs/contributing/hooks-and-safety.md +23 -0
  8. package/assets/docs/provider-sync/config.md +5 -1
  9. package/assets/docs/provider-sync/manifest-and-drift.md +6 -1
  10. package/assets/docs/provider-sync/providers.md +6 -3
  11. package/assets/docs/provider-sync/scope-and-surface.md +2 -1
  12. package/assets/docs/reference/oat-directory-structure.md +2 -2
  13. package/assets/docs/workflows/projects/dispatch-ceiling.md +110 -27
  14. package/assets/docs/workflows/projects/implementation-execution.md +20 -13
  15. package/assets/public-package-versions.json +4 -4
  16. package/assets/skills/oat-project-implement/SKILL.md +155 -58
  17. package/assets/skills/oat-project-plan/SKILL.md +22 -3
  18. package/assets/skills/oat-project-quick-start/SKILL.md +54 -23
  19. package/assets/templates/state.md +5 -0
  20. package/dist/commands/config/index.d.ts +6 -0
  21. package/dist/commands/config/index.d.ts.map +1 -1
  22. package/dist/commands/config/index.js +429 -20
  23. package/dist/commands/doctor/index.d.ts +6 -1
  24. package/dist/commands/doctor/index.d.ts.map +1 -1
  25. package/dist/commands/doctor/index.js +209 -19
  26. package/dist/commands/gate/index.d.ts +39 -2
  27. package/dist/commands/gate/index.d.ts.map +1 -1
  28. package/dist/commands/gate/index.js +343 -30
  29. package/dist/commands/internal/cursor-current-target.d.ts +37 -0
  30. package/dist/commands/internal/cursor-current-target.d.ts.map +1 -0
  31. package/dist/commands/internal/cursor-current-target.js +228 -0
  32. package/dist/commands/internal/index.d.ts.map +1 -1
  33. package/dist/commands/internal/index.js +2 -0
  34. package/dist/commands/project/dispatch-ceiling/index.d.ts.map +1 -1
  35. package/dist/commands/project/dispatch-ceiling/index.js +487 -17
  36. package/dist/commands/providers/codex/index.d.ts +4 -0
  37. package/dist/commands/providers/codex/index.d.ts.map +1 -0
  38. package/dist/commands/providers/codex/index.js +7 -0
  39. package/dist/commands/providers/codex/materialize.d.ts +5 -0
  40. package/dist/commands/providers/codex/materialize.d.ts.map +1 -0
  41. package/dist/commands/providers/codex/materialize.js +152 -0
  42. package/dist/commands/providers/index.d.ts +2 -2
  43. package/dist/commands/providers/index.d.ts.map +1 -1
  44. package/dist/commands/providers/index.js +4 -2
  45. package/dist/commands/providers/providers.types.d.ts +23 -0
  46. package/dist/commands/providers/providers.types.d.ts.map +1 -1
  47. package/dist/commands/shared/codex-strays.d.ts.map +1 -1
  48. package/dist/commands/shared/codex-strays.js +11 -1
  49. package/dist/commands/status/index.d.ts +4 -1
  50. package/dist/commands/status/index.d.ts.map +1 -1
  51. package/dist/commands/status/index.js +1 -1
  52. package/dist/commands/sync/index.d.ts.map +1 -1
  53. package/dist/commands/sync/index.js +1 -1
  54. package/dist/commands/sync/sync.types.d.ts +4 -1
  55. package/dist/commands/sync/sync.types.d.ts.map +1 -1
  56. package/dist/config/dispatch-ceiling-preset.d.ts +4 -0
  57. package/dist/config/dispatch-ceiling-preset.d.ts.map +1 -1
  58. package/dist/config/dispatch-ceiling-preset.js +3 -0
  59. package/dist/config/dispatch-policy-options.d.ts +20 -0
  60. package/dist/config/dispatch-policy-options.d.ts.map +1 -0
  61. package/dist/config/dispatch-policy-options.js +96 -0
  62. package/dist/config/oat-config.d.ts +21 -5
  63. package/dist/config/oat-config.d.ts.map +1 -1
  64. package/dist/config/oat-config.js +118 -10
  65. package/dist/config/resolve.js +12 -0
  66. package/dist/manifest/manifest.types.d.ts +12 -12
  67. package/dist/providers/ceiling/registry.d.ts +7 -5
  68. package/dist/providers/ceiling/registry.d.ts.map +1 -1
  69. package/dist/providers/ceiling/registry.js +32 -5
  70. package/dist/providers/codex/codec/config-merge.d.ts +6 -0
  71. package/dist/providers/codex/codec/config-merge.d.ts.map +1 -1
  72. package/dist/providers/codex/codec/config-merge.js +7 -0
  73. package/dist/providers/codex/codec/materialize.d.ts +16 -0
  74. package/dist/providers/codex/codec/materialize.d.ts.map +1 -0
  75. package/dist/providers/codex/codec/materialize.js +57 -0
  76. package/dist/providers/codex/codec/shared.d.ts +1 -0
  77. package/dist/providers/codex/codec/shared.d.ts.map +1 -1
  78. package/dist/providers/codex/codec/shared.js +9 -1
  79. package/dist/providers/codex/codec/sync-extension.d.ts +7 -1
  80. package/dist/providers/codex/codec/sync-extension.d.ts.map +1 -1
  81. package/dist/providers/codex/codec/sync-extension.js +183 -46
  82. package/dist/providers/identity/availability.d.ts +45 -0
  83. package/dist/providers/identity/availability.d.ts.map +1 -0
  84. package/dist/providers/identity/availability.js +353 -0
  85. package/dist/providers/identity/family.d.ts +13 -0
  86. package/dist/providers/identity/family.d.ts.map +1 -0
  87. package/dist/providers/identity/family.js +32 -0
  88. package/dist/providers/identity/provenance.d.ts +21 -0
  89. package/dist/providers/identity/provenance.d.ts.map +1 -0
  90. package/dist/providers/identity/provenance.js +65 -0
  91. package/dist/providers/identity/stamp.d.ts +35 -0
  92. package/dist/providers/identity/stamp.d.ts.map +1 -0
  93. package/dist/providers/identity/stamp.js +171 -0
  94. package/package.json +2 -2
@@ -1,6 +1,8 @@
1
1
  import { buildCommandContext, type CommandContext } from '../../app/command-context.js';
2
+ import { type PromptContext } from '../shared/shared.prompts.js';
2
3
  import { type OatConfig, type OatLocalConfig, type UserConfig } from '../../config/oat-config.js';
3
4
  import { type ResolvedConfig } from '../../config/resolve.js';
5
+ import { type MatrixCellAvailabilityResponse, type ValidateMatrixCellOptions } from '../../providers/identity/availability.js';
4
6
  import { Command } from 'commander';
5
7
  interface ConfigCommandDependencies {
6
8
  buildCommandContext: (options: Parameters<typeof buildCommandContext>[0]) => CommandContext;
@@ -13,6 +15,10 @@ interface ConfigCommandDependencies {
13
15
  writeUserConfig: (userConfigDir: string, config: UserConfig) => Promise<void>;
14
16
  resolveProjectsRoot: (repoRoot: string, env: NodeJS.ProcessEnv) => Promise<string>;
15
17
  resolveEffectiveConfig: (repoRoot: string, userConfigDir: string, env: NodeJS.ProcessEnv) => Promise<ResolvedConfig>;
18
+ resolveAssetsRoot: () => Promise<string>;
19
+ readFile: (path: string) => Promise<string>;
20
+ confirmAction: (message: string, ctx: PromptContext) => Promise<boolean>;
21
+ validateMatrixCell: (provider: string, value: string, options: ValidateMatrixCellOptions) => Promise<MatrixCellAvailabilityResponse>;
16
22
  processEnv: NodeJS.ProcessEnv;
17
23
  }
18
24
  export declare function createConfigCommand(overrides?: Partial<ConfigCommandDependencies>): Command;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/config/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAIhF,OAAO,EACL,KAAK,SAAS,EACd,KAAK,cAAc,EAGnB,KAAK,UAAU,EAUhB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,KAAK,cAAc,EAEpB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgEpC,UAAU,yBAAyB;IACjC,mBAAmB,EAAE,CACnB,OAAO,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,KAC/C,cAAc,CAAC;IACpB,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,mBAAmB,EAAE,CACnB,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,CAAC,UAAU,KACnB,OAAO,CAAC,MAAM,CAAC,CAAC;IACrB,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,MAAM,CAAC,UAAU,CAAC;CAC/B;AAyzCD,wBAAgB,mBAAmB,CACjC,SAAS,GAAE,OAAO,CAAC,yBAAyB,CAAM,GACjD,OAAO,CA0GT"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/config/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mBAAmB,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEhF,OAAO,EAEL,KAAK,aAAa,EACnB,MAAM,iCAAiC,CAAC;AAQzC,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,cAAc,EAGnB,KAAK,UAAU,EAehB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,KAAK,cAAc,EAEpB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAGL,KAAK,8BAA8B,EACnC,KAAK,yBAAyB,EAC/B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkFpC,UAAU,yBAAyB;IACjC,mBAAmB,EAAE,CACnB,OAAO,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,KAC/C,cAAc,CAAC;IACpB,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,mBAAmB,EAAE,CACnB,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,CAAC,UAAU,KACnB,OAAO,CAAC,MAAM,CAAC,CAAC;IACrB,sBAAsB,EAAE,CACtB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,GAAG,EAAE,MAAM,CAAC,UAAU,KACnB,OAAO,CAAC,cAAc,CAAC,CAAC;IAC7B,iBAAiB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACzE,kBAAkB,EAAE,CAClB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,yBAAyB,KAC/B,OAAO,CAAC,8BAA8B,CAAC,CAAC;IAC7C,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC;CAC/B;AA65DD,wBAAgB,mBAAmB,CACjC,SAAS,GAAE,OAAO,CAAC,yBAAyB,CAAM,GACjD,OAAO,CAwKT"}
@@ -1,13 +1,25 @@
1
+ import { readFile as readFileDefault } from 'node:fs/promises';
1
2
  import { join } from 'node:path';
2
3
  import { buildCommandContext } from '../../app/command-context.js';
3
4
  import { resolveProjectsRoot } from '../shared/oat-paths.js';
5
+ import { confirmAction, } from '../shared/shared.prompts.js';
4
6
  import { readGlobalOptions } from '../shared/shared.utils.js';
5
7
  import { compileDispatchCeilingPreset } from '../../config/dispatch-ceiling-preset.js';
6
- import { readOatConfig, readOatLocalConfig, readUserConfig, writeOatConfig, writeOatLocalConfig, writeUserConfig, } from '../../config/oat-config.js';
8
+ import { dispatchPolicyModeDescription, dispatchPolicyPolicyDescription, managedDispatchPolicyValueList, } from '../../config/dispatch-policy-options.js';
9
+ import { VALID_DISPATCH_POLICY_MODES, VALID_MANAGED_DISPATCH_POLICIES, isCodexMaterializedRouteTarget, readOatConfig, readOatLocalConfig, readUserConfig, validateDispatchRouteTarget, writeOatConfig, writeOatLocalConfig, writeUserConfig, } from '../../config/oat-config.js';
7
10
  import { resolveEffectiveConfig, } from '../../config/resolve.js';
11
+ import { resolveAssetsRoot } from '../../fs/assets.js';
8
12
  import { resolveProjectRoot } from '../../fs/paths.js';
13
+ import { normalizeMatrixCellAvailability, validateMatrixCell, } from '../../providers/identity/availability.js';
9
14
  import { Command } from 'commander';
10
15
  import { createConfigDumpCommand } from './dump.js';
16
+ const DISPATCH_CEILING_PROVIDER_KEY_PREFIX = 'workflow.dispatchCeiling.providers.';
17
+ const DISPATCH_MATRIX_TIERS = [
18
+ 'economy',
19
+ 'balanced',
20
+ 'high',
21
+ 'frontier',
22
+ ];
11
23
  const KEY_ORDER = [
12
24
  'activeIdea',
13
25
  'activeProject',
@@ -467,7 +479,7 @@ const CONFIG_CATALOG = [
467
479
  defaultValue: 'unset',
468
480
  mutability: 'read/write',
469
481
  owningCommand: 'oat config set workflow.dispatchPolicy.mode <value>',
470
- description: 'Dispatch policy mode. "managed" means OAT selects model/effort from workflow.dispatchPolicy.policy; "inherit" means OAT leaves dispatch controls to the host/provider defaults. Set workflow.dispatchPolicy.policy to choose a managed policy. Resolution: local > shared > user > default.',
482
+ description: dispatchPolicyModeDescription(),
471
483
  },
472
484
  {
473
485
  key: 'workflow.dispatchPolicy.policy',
@@ -478,7 +490,7 @@ const CONFIG_CATALOG = [
478
490
  defaultValue: 'unset',
479
491
  mutability: 'read/write',
480
492
  owningCommand: 'oat config set workflow.dispatchPolicy.policy <value>',
481
- description: 'Managed dispatch policy. economy, balanced, high, and frontier are capped managed policies; uncapped keeps OAT-managed preferred selection without provider caps. Setting this key writes workflow.dispatchPolicy.mode=managed. Resolution: local > shared > user > default.',
493
+ description: dispatchPolicyPolicyDescription(),
482
494
  },
483
495
  {
484
496
  key: 'workflow.dispatchCeiling.providers.codex',
@@ -547,10 +559,49 @@ const DEFAULT_DEPENDENCIES = {
547
559
  writeUserConfig,
548
560
  resolveProjectsRoot,
549
561
  resolveEffectiveConfig,
562
+ resolveAssetsRoot,
563
+ readFile: (path) => readFileDefault(path, 'utf8'),
564
+ confirmAction,
565
+ validateMatrixCell,
550
566
  processEnv: process.env,
551
567
  };
552
568
  function isConfigKey(value) {
553
- return KEY_ORDER.includes(value);
569
+ return (KEY_ORDER.includes(value) ||
570
+ isDispatchCeilingProviderKey(value));
571
+ }
572
+ function isDispatchCeilingProviderKey(value) {
573
+ return (value.startsWith(DISPATCH_CEILING_PROVIDER_KEY_PREFIX) &&
574
+ value.slice(DISPATCH_CEILING_PROVIDER_KEY_PREFIX.length).trim().length > 0);
575
+ }
576
+ function isDispatchMatrixTier(value) {
577
+ return DISPATCH_MATRIX_TIERS.includes(value);
578
+ }
579
+ function parseDispatchCeilingProviderConfigKey(key) {
580
+ const suffix = key.slice(DISPATCH_CEILING_PROVIDER_KEY_PREFIX.length).trim();
581
+ const parts = suffix.split('.').map((part) => part.trim());
582
+ const invalidMessage = `Invalid config key ${key}: expected workflow.dispatchCeiling.providers.<provider> or workflow.dispatchCeiling.providers.<provider>.<tier> with tier one of ${DISPATCH_MATRIX_TIERS.join(' | ')}.`;
583
+ if (parts.some((part) => part.length === 0)) {
584
+ throw new Error(invalidMessage);
585
+ }
586
+ if (parts.length === 1) {
587
+ const provider = parts[0];
588
+ if (!provider) {
589
+ throw new Error(invalidMessage);
590
+ }
591
+ return { provider };
592
+ }
593
+ const tier = parts[parts.length - 1];
594
+ if (!tier || !isDispatchMatrixTier(tier)) {
595
+ throw new Error(invalidMessage);
596
+ }
597
+ const provider = parts.slice(0, -1).join('.').trim();
598
+ if (!provider) {
599
+ throw new Error(invalidMessage);
600
+ }
601
+ return { provider, tier };
602
+ }
603
+ function providerNameFromConfigKey(key) {
604
+ return parseDispatchCeilingProviderConfigKey(key).provider;
554
605
  }
555
606
  function normalizeSharedRoot(value) {
556
607
  const trimmed = value.trim();
@@ -564,14 +615,8 @@ const WORKFLOW_ENUM_VALUES = {
564
615
  'workflow.postImplementSequence': ['wait', 'summary', 'pr', 'docs-pr'],
565
616
  'workflow.reviewExecutionModel': ['subagent', 'inline', 'fresh-session'],
566
617
  'workflow.designMode': ['collaborative', 'selective', 'draft'],
567
- 'workflow.dispatchPolicy.mode': ['managed', 'inherit'],
568
- 'workflow.dispatchPolicy.policy': [
569
- 'economy',
570
- 'balanced',
571
- 'high',
572
- 'frontier',
573
- 'uncapped',
574
- ],
618
+ 'workflow.dispatchPolicy.mode': [...VALID_DISPATCH_POLICY_MODES],
619
+ 'workflow.dispatchPolicy.policy': [...VALID_MANAGED_DISPATCH_POLICIES],
575
620
  'workflow.dispatchCeiling.preset': ['balanced', 'maximum', 'cost-conscious'],
576
621
  'workflow.dispatchCeiling.providers.codex': [
577
622
  'low',
@@ -586,6 +631,15 @@ const WORKFLOW_ENUM_VALUES = {
586
631
  'fable',
587
632
  ],
588
633
  };
634
+ function closedDispatchProviderValues(provider) {
635
+ if (provider === 'codex') {
636
+ return WORKFLOW_ENUM_VALUES['workflow.dispatchCeiling.providers.codex'];
637
+ }
638
+ if (provider === 'claude') {
639
+ return WORKFLOW_ENUM_VALUES['workflow.dispatchCeiling.providers.claude'];
640
+ }
641
+ return undefined;
642
+ }
589
643
  const WORKFLOW_BOOLEAN_KEYS = new Set([
590
644
  'workflow.archiveOnComplete',
591
645
  'workflow.createPrOnComplete',
@@ -666,8 +720,144 @@ function parseWorkflowValue(key, rawValue) {
666
720
  }
667
721
  return normalized;
668
722
  }
723
+ if (isDispatchCeilingProviderKey(key)) {
724
+ const { provider } = parseDispatchCeilingProviderConfigKey(key);
725
+ const normalized = rawValue.trim();
726
+ if (normalized.length === 0) {
727
+ throw new Error(`Invalid value for ${key}: provider values cannot be empty`);
728
+ }
729
+ const closedValues = closedDispatchProviderValues(provider);
730
+ if (closedValues && !closedValues.includes(normalized)) {
731
+ throw new Error(`Invalid value for ${key}: expected one of ${closedValues.join(' | ')}, got '${rawValue}'`);
732
+ }
733
+ return normalized;
734
+ }
669
735
  throw new Error(`Unknown workflow key: ${key}`);
670
736
  }
737
+ function dispatchProviderAvailabilityWarning(key, value, availability) {
738
+ return matrixCellAvailabilityWarning(key, value, availability);
739
+ }
740
+ const DISPATCH_MATRIX_RECOMMENDATION_ASSET = join('config', 'dispatch-matrix-recommendation.json');
741
+ function isRecord(value) {
742
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
743
+ }
744
+ function matrixCellAvailabilityWarning(path, value, availability) {
745
+ const result = normalizeMatrixCellAvailability(availability);
746
+ if (result.availability === 'valid') {
747
+ return null;
748
+ }
749
+ const details = result.message ? ` ${result.message}` : '';
750
+ if (result.availability === 'unknown-value') {
751
+ return `${path} value '${value}' was not recognized by the provider availability oracle; saving anyway.${details}`;
752
+ }
753
+ return `${path} value '${value}' could not be validated because the provider availability oracle is unavailable; saving anyway.${details}`;
754
+ }
755
+ function parseDispatchMatrixRecommendation(raw) {
756
+ const parsed = JSON.parse(raw);
757
+ if (!isRecord(parsed)) {
758
+ throw new Error('Dispatch matrix recommendation asset must be an object.');
759
+ }
760
+ const version = typeof parsed.version === 'string' ? parsed.version.trim() : '';
761
+ if (!version) {
762
+ throw new Error('Dispatch matrix recommendation asset is missing a version.');
763
+ }
764
+ if (!isRecord(parsed.providers)) {
765
+ throw new Error('Dispatch matrix recommendation asset is missing providers.');
766
+ }
767
+ return {
768
+ version,
769
+ providers: parsed.providers,
770
+ };
771
+ }
772
+ function isRouteTarget(entry) {
773
+ return isRecord(entry);
774
+ }
775
+ function formatRouteTargetValue(entry) {
776
+ return [entry.model, entry.effort].filter(Boolean).join('/');
777
+ }
778
+ function addDispatchMatrixCellRefs(refs, provider, path, cell) {
779
+ if (typeof cell === 'string') {
780
+ refs.push({ provider, value: cell, path });
781
+ return;
782
+ }
783
+ for (const [index, entry] of cell.entries()) {
784
+ const entryPath = `${path}[${index}]`;
785
+ if (typeof entry === 'string') {
786
+ refs.push({ provider, value: entry, path: entryPath });
787
+ continue;
788
+ }
789
+ if (!isRouteTarget(entry)) {
790
+ continue;
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
+ continue;
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
+ }
820
+ function collectDispatchMatrixCellRefs(providers) {
821
+ const refs = [];
822
+ for (const [provider, providerValue] of Object.entries(providers)) {
823
+ const providerPath = `workflow.dispatchCeiling.providers.${provider}`;
824
+ if (typeof providerValue === 'string') {
825
+ refs.push({ provider, value: providerValue, path: providerPath });
826
+ continue;
827
+ }
828
+ for (const [tier, cell] of Object.entries(providerValue)) {
829
+ if (cell === undefined) {
830
+ continue;
831
+ }
832
+ addDispatchMatrixCellRefs(refs, provider, `${providerPath}.${tier}`, cell);
833
+ }
834
+ }
835
+ return refs;
836
+ }
837
+ function collectDispatchMatrixTargetValidationErrors(providers) {
838
+ const errors = [];
839
+ for (const [provider, providerValue] of Object.entries(providers)) {
840
+ if (typeof providerValue === 'string') {
841
+ continue;
842
+ }
843
+ const providerPath = `workflow.dispatchCeiling.providers.${provider}`;
844
+ for (const [tier, cell] of Object.entries(providerValue)) {
845
+ if (!Array.isArray(cell)) {
846
+ continue;
847
+ }
848
+ for (const [index, entry] of cell.entries()) {
849
+ if (!isRouteTarget(entry)) {
850
+ continue;
851
+ }
852
+ const validation = validateDispatchRouteTarget(provider, entry);
853
+ if (!validation.valid) {
854
+ errors.push(`${providerPath}.${tier}[${index}]: ${validation.reason}`);
855
+ }
856
+ }
857
+ }
858
+ }
859
+ return errors;
860
+ }
671
861
  function applyWorkflowValue(workflow, key, value) {
672
862
  const subKey = key.slice('workflow.'.length);
673
863
  if (subKey === 'dispatchPolicy.mode') {
@@ -680,7 +870,7 @@ function applyWorkflowValue(workflow, key, value) {
680
870
  }
681
871
  const policy = workflow.dispatchPolicy?.policy;
682
872
  if (!policy) {
683
- throw new Error('Cannot set workflow.dispatchPolicy.mode to managed without an existing workflow.dispatchPolicy.policy. Set workflow.dispatchPolicy.policy <economy|balanced|high|frontier|uncapped> instead.');
873
+ throw new Error(`Cannot set workflow.dispatchPolicy.mode to managed without an existing workflow.dispatchPolicy.policy. Set workflow.dispatchPolicy.policy <${managedDispatchPolicyValueList('|')}> instead.`);
684
874
  }
685
875
  return {
686
876
  ...workflow,
@@ -714,15 +904,37 @@ function applyWorkflowValue(workflow, key, value) {
714
904
  },
715
905
  };
716
906
  }
717
- if (subKey.startsWith('dispatchCeiling.providers.')) {
718
- const providerKey = subKey.slice('dispatchCeiling.providers.'.length);
907
+ if (isDispatchCeilingProviderKey(key)) {
908
+ const { provider, tier } = parseDispatchCeilingProviderConfigKey(key);
909
+ const providers = workflow.dispatchCeiling?.providers ?? {};
910
+ if (tier) {
911
+ const existingProviderValue = providers[provider];
912
+ const existingTierMap = existingProviderValue &&
913
+ typeof existingProviderValue === 'object' &&
914
+ !Array.isArray(existingProviderValue)
915
+ ? existingProviderValue
916
+ : {};
917
+ return {
918
+ ...workflow,
919
+ dispatchCeiling: {
920
+ ...workflow.dispatchCeiling,
921
+ providers: {
922
+ ...providers,
923
+ [provider]: {
924
+ ...existingTierMap,
925
+ [tier]: value,
926
+ },
927
+ },
928
+ },
929
+ };
930
+ }
719
931
  return {
720
932
  ...workflow,
721
933
  dispatchCeiling: {
722
934
  ...workflow.dispatchCeiling,
723
935
  providers: {
724
- ...workflow.dispatchCeiling?.providers,
725
- [providerKey]: value,
936
+ ...providers,
937
+ [provider]: value,
726
938
  },
727
939
  },
728
940
  };
@@ -769,12 +981,32 @@ async function getConfigValue(repoRoot, userConfigDir, key, dependencies) {
769
981
  source: entry.source,
770
982
  };
771
983
  }
772
- async function setConfigValue(repoRoot, userConfigDir, key, rawValue, surface, dependencies) {
984
+ async function listConfigKeys(repoRoot, userConfigDir, dependencies) {
985
+ const resolved = await dependencies.resolveEffectiveConfig(repoRoot, userConfigDir, dependencies.processEnv);
986
+ const staticKeys = new Set(KEY_ORDER);
987
+ const dynamicProviderKeys = Object.keys(resolved.resolved)
988
+ .filter(isDispatchCeilingProviderKey)
989
+ .filter((key) => !staticKeys.has(key))
990
+ .sort();
991
+ return [...KEY_ORDER, ...dynamicProviderKeys];
992
+ }
993
+ async function setConfigValue(repoRoot, userConfigDir, key, rawValue, surface, dependencies, warn) {
773
994
  validateSurfaceForKey(key, surface);
774
995
  const effectiveSurface = surface === 'auto' ? defaultSurfaceForKey(key) : surface;
775
996
  if (isWorkflowKey(key)) {
776
997
  const parsedValue = parseWorkflowValue(key, rawValue);
777
998
  const displayValue = typeof parsedValue === 'boolean' ? String(parsedValue) : parsedValue;
999
+ if (typeof parsedValue === 'string' && isDispatchCeilingProviderKey(key)) {
1000
+ const availability = await dependencies.validateMatrixCell(providerNameFromConfigKey(key), parsedValue, {
1001
+ cwd: repoRoot,
1002
+ env: dependencies.processEnv,
1003
+ detailed: true,
1004
+ });
1005
+ const warning = dispatchProviderAvailabilityWarning(key, parsedValue, availability);
1006
+ if (warning) {
1007
+ warn(warning);
1008
+ }
1009
+ }
778
1010
  if (effectiveSurface === 'user') {
779
1011
  const userConfig = await dependencies.readUserConfig(userConfigDir);
780
1012
  await dependencies.writeUserConfig(userConfigDir, {
@@ -952,6 +1184,115 @@ async function setConfigValue(repoRoot, userConfigDir, key, rawValue, surface, d
952
1184
  source: 'shared',
953
1185
  };
954
1186
  }
1187
+ function hasExistingDispatchMatrix(config) {
1188
+ const providers = config.workflow?.dispatchCeiling?.providers;
1189
+ return providers !== undefined && Object.keys(providers).length > 0;
1190
+ }
1191
+ async function loadDispatchMatrixRecommendation(dependencies) {
1192
+ const assetsRoot = await dependencies.resolveAssetsRoot();
1193
+ const assetPath = join(assetsRoot, DISPATCH_MATRIX_RECOMMENDATION_ASSET);
1194
+ return parseDispatchMatrixRecommendation(await dependencies.readFile(assetPath));
1195
+ }
1196
+ async function validateRecommendationCells(repoRoot, recommendation, dependencies, warn) {
1197
+ const targetErrors = collectDispatchMatrixTargetValidationErrors(recommendation.providers);
1198
+ if (targetErrors.length > 0) {
1199
+ throw new Error(targetErrors.join('\n'));
1200
+ }
1201
+ for (const ref of collectDispatchMatrixCellRefs(recommendation.providers)) {
1202
+ const closedValues = closedDispatchProviderValues(ref.provider);
1203
+ if (!ref.target && closedValues && !closedValues.includes(ref.value)) {
1204
+ throw new Error(`Invalid value for ${ref.path}: expected one of ${closedValues.join(' | ')}, got '${ref.value}'`);
1205
+ }
1206
+ let availability;
1207
+ try {
1208
+ availability = await dependencies.validateMatrixCell(ref.provider, ref.value, {
1209
+ cwd: repoRoot,
1210
+ env: dependencies.processEnv,
1211
+ detailed: true,
1212
+ ...(ref.target ? { target: ref.target } : {}),
1213
+ });
1214
+ }
1215
+ catch {
1216
+ availability = 'unvalidated';
1217
+ }
1218
+ const warning = matrixCellAvailabilityWarning(ref.path, ref.value, availability);
1219
+ if (warning) {
1220
+ warn(warning);
1221
+ }
1222
+ }
1223
+ }
1224
+ function applyDispatchMatrixRecommendation(workflow, recommendation) {
1225
+ return {
1226
+ ...(workflow ?? {}),
1227
+ dispatchCeiling: {
1228
+ ...workflow?.dispatchCeiling,
1229
+ recommendationVersion: recommendation.version,
1230
+ providers: recommendation.providers,
1231
+ },
1232
+ };
1233
+ }
1234
+ async function confirmDispatchMatrixOverwrite(context, dependencies, source, yes) {
1235
+ if (yes) {
1236
+ return;
1237
+ }
1238
+ if (!context.interactive) {
1239
+ throw new Error('Dispatch matrix already exists; rerun interactively or pass --yes to replace it.');
1240
+ }
1241
+ const shouldReplace = await dependencies.confirmAction(`Replace existing dispatch matrix in ${source} config?`, { interactive: context.interactive });
1242
+ if (!shouldReplace) {
1243
+ throw new Error('Dispatch matrix adoption cancelled; existing matrix unchanged.');
1244
+ }
1245
+ }
1246
+ async function adoptDispatchMatrixRecommendation(repoRoot, userConfigDir, options, context, dependencies) {
1247
+ const source = options.surface === 'auto' ? 'local' : options.surface;
1248
+ const recommendation = await loadDispatchMatrixRecommendation(dependencies);
1249
+ if (source === 'user') {
1250
+ const userConfig = await dependencies.readUserConfig(userConfigDir);
1251
+ if (hasExistingDispatchMatrix(userConfig)) {
1252
+ await confirmDispatchMatrixOverwrite(context, dependencies, source, options.yes);
1253
+ }
1254
+ await validateRecommendationCells(repoRoot, recommendation, dependencies, context.logger.warn);
1255
+ await dependencies.writeUserConfig(userConfigDir, {
1256
+ ...userConfig,
1257
+ workflow: applyDispatchMatrixRecommendation(userConfig.workflow, recommendation),
1258
+ });
1259
+ return {
1260
+ key: 'workflow.dispatchCeiling.providers',
1261
+ value: recommendation.version,
1262
+ source,
1263
+ };
1264
+ }
1265
+ if (source === 'local') {
1266
+ const localConfig = await dependencies.readOatLocalConfig(repoRoot);
1267
+ if (hasExistingDispatchMatrix(localConfig)) {
1268
+ await confirmDispatchMatrixOverwrite(context, dependencies, source, options.yes);
1269
+ }
1270
+ await validateRecommendationCells(repoRoot, recommendation, dependencies, context.logger.warn);
1271
+ await dependencies.writeOatLocalConfig(repoRoot, {
1272
+ ...localConfig,
1273
+ workflow: applyDispatchMatrixRecommendation(localConfig.workflow, recommendation),
1274
+ });
1275
+ return {
1276
+ key: 'workflow.dispatchCeiling.providers',
1277
+ value: recommendation.version,
1278
+ source,
1279
+ };
1280
+ }
1281
+ const sharedConfig = await dependencies.readOatConfig(repoRoot);
1282
+ if (hasExistingDispatchMatrix(sharedConfig)) {
1283
+ await confirmDispatchMatrixOverwrite(context, dependencies, source, options.yes);
1284
+ }
1285
+ await validateRecommendationCells(repoRoot, recommendation, dependencies, context.logger.warn);
1286
+ await dependencies.writeOatConfig(repoRoot, {
1287
+ ...sharedConfig,
1288
+ workflow: applyDispatchMatrixRecommendation(sharedConfig.workflow, recommendation),
1289
+ });
1290
+ return {
1291
+ key: 'workflow.dispatchCeiling.providers',
1292
+ value: recommendation.version,
1293
+ source,
1294
+ };
1295
+ }
955
1296
  function formatList(values) {
956
1297
  const keyWidth = Math.max('Key'.length, ...values.map((item) => item.key.length));
957
1298
  const sourceWidth = Math.max('Source'.length, ...values.map((item) => item.source.length));
@@ -1044,7 +1385,7 @@ async function runSet(keyArg, rawValue, surface, context, dependencies) {
1044
1385
  }
1045
1386
  const repoRoot = await dependencies.resolveProjectRoot(context.cwd);
1046
1387
  const userConfigDir = join(context.home, '.oat');
1047
- const result = await setConfigValue(repoRoot, userConfigDir, keyArg, rawValue, surface, dependencies);
1388
+ const result = await setConfigValue(repoRoot, userConfigDir, keyArg, rawValue, surface, dependencies, context.logger.warn);
1048
1389
  if (context.json) {
1049
1390
  context.logger.json({
1050
1391
  status: 'ok',
@@ -1067,12 +1408,42 @@ async function runSet(keyArg, rawValue, surface, context, dependencies) {
1067
1408
  process.exitCode = 1;
1068
1409
  }
1069
1410
  }
1411
+ async function runAdopt(templateArg, options, context, dependencies) {
1412
+ try {
1413
+ if (templateArg !== 'dispatch-matrix') {
1414
+ throw new Error(`Unknown config adoption template: ${templateArg}`);
1415
+ }
1416
+ const repoRoot = await dependencies.resolveProjectRoot(context.cwd);
1417
+ const userConfigDir = join(context.home, '.oat');
1418
+ const result = await adoptDispatchMatrixRecommendation(repoRoot, userConfigDir, options, context, dependencies);
1419
+ if (context.json) {
1420
+ context.logger.json({
1421
+ status: 'ok',
1422
+ ...result,
1423
+ });
1424
+ }
1425
+ else {
1426
+ context.logger.info(`Adopted dispatch matrix recommendation ${result.value} to ${result.source} config.`);
1427
+ }
1428
+ process.exitCode = 0;
1429
+ }
1430
+ catch (error) {
1431
+ const message = error instanceof Error ? error.message : String(error);
1432
+ if (context.json) {
1433
+ context.logger.json({ status: 'error', message });
1434
+ }
1435
+ else {
1436
+ context.logger.error(message);
1437
+ }
1438
+ process.exitCode = 1;
1439
+ }
1440
+ }
1070
1441
  async function runList(context, dependencies) {
1071
1442
  try {
1072
1443
  const repoRoot = await dependencies.resolveProjectRoot(context.cwd);
1073
1444
  const userConfigDir = join(context.home, '.oat');
1074
1445
  const values = [];
1075
- for (const key of KEY_ORDER) {
1446
+ for (const key of await listConfigKeys(repoRoot, userConfigDir, dependencies)) {
1076
1447
  values.push(await getConfigValue(repoRoot, userConfigDir, key, dependencies));
1077
1448
  }
1078
1449
  if (context.json) {
@@ -1182,6 +1553,44 @@ export function createConfigCommand(overrides = {}) {
1182
1553
  }
1183
1554
  process.exitCode = 1;
1184
1555
  }
1556
+ }))
1557
+ .addCommand(new Command('adopt')
1558
+ .description('Adopt a bundled OAT config recommendation')
1559
+ .argument('<template>', 'Recommendation template to adopt')
1560
+ .option('--shared', 'Write to the shared repo config (.oat/config.json)')
1561
+ .option('--local', 'Write to the repo-local config (.oat/config.local.json)')
1562
+ .option('--user', 'Write to the user-level config (~/.oat/config.json)')
1563
+ .option('--yes', 'Replace an existing adopted matrix without prompting')
1564
+ .action(async (template, options, command) => {
1565
+ const context = dependencies.buildCommandContext(readGlobalOptions(command));
1566
+ try {
1567
+ const flagsPresent = [
1568
+ options.shared,
1569
+ options.local,
1570
+ options.user,
1571
+ ].filter(Boolean).length;
1572
+ if (flagsPresent > 1) {
1573
+ throw new Error('--shared, --local, and --user flags are mutually exclusive; pass at most one.');
1574
+ }
1575
+ let surface = 'auto';
1576
+ if (options.shared)
1577
+ surface = 'shared';
1578
+ else if (options.local)
1579
+ surface = 'local';
1580
+ else if (options.user)
1581
+ surface = 'user';
1582
+ await runAdopt(template, { surface, yes: options.yes === true }, context, dependencies);
1583
+ }
1584
+ catch (error) {
1585
+ const message = error instanceof Error ? error.message : String(error);
1586
+ if (context.json) {
1587
+ context.logger.json({ status: 'error', message });
1588
+ }
1589
+ else {
1590
+ context.logger.error(message);
1591
+ }
1592
+ process.exitCode = 1;
1593
+ }
1185
1594
  }))
1186
1595
  .addCommand(new Command('list')
1187
1596
  .description('List resolved OAT config values with sources')
@@ -1,7 +1,8 @@
1
1
  import { type CommandContext, type GlobalOptions } from '../../app/command-context.js';
2
2
  import { type PjmDoctorOptions } from '../pjm/doctor.js';
3
- import { type OatConfig } from '../../config/oat-config.js';
3
+ import { type OatConfig, type OatLocalConfig, type UserConfig } from '../../config/oat-config.js';
4
4
  import { type Manifest } from '../../manifest/index.js';
5
+ import { type MatrixCellAvailabilityResponse, type ValidateMatrixCellOptions } from '../../providers/identity/availability.js';
5
6
  import type { ConcreteScope } from '../../shared/types.js';
6
7
  import { type DoctorCheck } from '../../ui/output.js';
7
8
  import { Command } from 'commander';
@@ -19,6 +20,10 @@ interface DoctorDependencies {
19
20
  readFile: (path: string) => Promise<string>;
20
21
  resolveAssetsRoot: () => Promise<string>;
21
22
  readOatConfig: (repoRoot: string) => Promise<OatConfig>;
23
+ readOatLocalConfig: (repoRoot: string) => Promise<OatLocalConfig>;
24
+ readUserConfig: (userConfigDir: string) => Promise<UserConfig>;
25
+ validateMatrixCell: (provider: string, value: string, options: ValidateMatrixCellOptions) => Promise<MatrixCellAvailabilityResponse>;
26
+ processEnv: NodeJS.ProcessEnv;
22
27
  runPjmDoctorChecks: (repoRoot: string, options?: PjmDoctorOptions) => Promise<DoctorCheck[]>;
23
28
  checkSkillVersions: (scopeRoot: string, assetsRoot: string, pathExists: (path: string) => Promise<boolean>) => Promise<SkillVersionReport>;
24
29
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/doctor/index.ts"],"names":[],"mappings":"AAWA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,sBAAsB,CAAC;AAO9B,OAAO,EAAiB,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAInE,OAAO,EAAgB,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAM9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,KAAK,WAAW,EAAuB,MAAM,YAAY,CAAC;AACnE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,UAAU,kBAAkB;IAC1B,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,gBAAgB,EAAE,CAChB,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE,cAAc,KACpB,OAAO,CAAC,MAAM,CAAC,CAAC;IACrB,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,YAAY,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1D,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7D,cAAc,EAAE,CACd,SAAS,EAAE,MAAM,KACd,OAAO,CACV,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CACnE,CAAC;IACF,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C,iBAAiB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;IACxD,kBAAkB,EAAE,CAClB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,gBAAgB,KACvB,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAC5B,kBAAkB,EAAE,CAClB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,KAC3C,OAAO,CAAC,kBAAkB,CAAC,CAAC;CAClC;AAED,UAAU,oBAAoB;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,UAAU,kBAAkB;IAC1B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,0BAA0B,EAAE,MAAM,CAAC;IACnC,cAAc,EAAE,oBAAoB,EAAE,CAAC;CACxC;AAsbD,wBAAgB,mBAAmB,CACjC,SAAS,GAAE,OAAO,CAAC,kBAAkB,CAAM,GAC1C,OAAO,CAcT"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/doctor/index.ts"],"names":[],"mappings":"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"}