@open-agent-toolkit/cli 0.1.45 → 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 (69) hide show
  1. package/assets/agents/oat-reviewer.md +2 -2
  2. package/assets/docs/cli-utilities/config-and-local-state.md +7 -0
  3. package/assets/docs/cli-utilities/configuration.md +51 -11
  4. package/assets/docs/provider-sync/config.md +5 -1
  5. package/assets/docs/provider-sync/manifest-and-drift.md +6 -1
  6. package/assets/docs/provider-sync/providers.md +6 -3
  7. package/assets/docs/provider-sync/scope-and-surface.md +2 -1
  8. package/assets/docs/reference/oat-directory-structure.md +2 -2
  9. package/assets/docs/workflows/projects/dispatch-ceiling.md +41 -28
  10. package/assets/docs/workflows/projects/implementation-execution.md +20 -13
  11. package/assets/public-package-versions.json +4 -4
  12. package/assets/skills/oat-project-implement/SKILL.md +114 -59
  13. package/assets/skills/oat-project-quick-start/SKILL.md +32 -20
  14. package/dist/commands/config/index.d.ts +2 -2
  15. package/dist/commands/config/index.d.ts.map +1 -1
  16. package/dist/commands/config/index.js +71 -20
  17. package/dist/commands/doctor/index.d.ts +2 -2
  18. package/dist/commands/doctor/index.d.ts.map +1 -1
  19. package/dist/commands/doctor/index.js +83 -27
  20. package/dist/commands/project/dispatch-ceiling/index.d.ts.map +1 -1
  21. package/dist/commands/project/dispatch-ceiling/index.js +137 -10
  22. package/dist/commands/providers/codex/index.d.ts +4 -0
  23. package/dist/commands/providers/codex/index.d.ts.map +1 -0
  24. package/dist/commands/providers/codex/index.js +7 -0
  25. package/dist/commands/providers/codex/materialize.d.ts +5 -0
  26. package/dist/commands/providers/codex/materialize.d.ts.map +1 -0
  27. package/dist/commands/providers/codex/materialize.js +152 -0
  28. package/dist/commands/providers/index.d.ts +2 -2
  29. package/dist/commands/providers/index.d.ts.map +1 -1
  30. package/dist/commands/providers/index.js +4 -2
  31. package/dist/commands/providers/providers.types.d.ts +23 -0
  32. package/dist/commands/providers/providers.types.d.ts.map +1 -1
  33. package/dist/commands/shared/codex-strays.d.ts.map +1 -1
  34. package/dist/commands/shared/codex-strays.js +11 -1
  35. package/dist/commands/status/index.d.ts +4 -1
  36. package/dist/commands/status/index.d.ts.map +1 -1
  37. package/dist/commands/status/index.js +1 -1
  38. package/dist/commands/sync/index.d.ts.map +1 -1
  39. package/dist/commands/sync/index.js +1 -1
  40. package/dist/commands/sync/sync.types.d.ts +4 -1
  41. package/dist/commands/sync/sync.types.d.ts.map +1 -1
  42. package/dist/config/dispatch-ceiling-preset.d.ts +4 -0
  43. package/dist/config/dispatch-ceiling-preset.d.ts.map +1 -1
  44. package/dist/config/dispatch-ceiling-preset.js +3 -0
  45. package/dist/config/dispatch-policy-options.d.ts +20 -0
  46. package/dist/config/dispatch-policy-options.d.ts.map +1 -0
  47. package/dist/config/dispatch-policy-options.js +96 -0
  48. package/dist/config/oat-config.d.ts +6 -0
  49. package/dist/config/oat-config.d.ts.map +1 -1
  50. package/dist/config/oat-config.js +15 -0
  51. package/dist/providers/ceiling/registry.d.ts +7 -5
  52. package/dist/providers/ceiling/registry.d.ts.map +1 -1
  53. package/dist/providers/ceiling/registry.js +16 -5
  54. package/dist/providers/codex/codec/config-merge.d.ts +6 -0
  55. package/dist/providers/codex/codec/config-merge.d.ts.map +1 -1
  56. package/dist/providers/codex/codec/config-merge.js +7 -0
  57. package/dist/providers/codex/codec/materialize.d.ts +16 -0
  58. package/dist/providers/codex/codec/materialize.d.ts.map +1 -0
  59. package/dist/providers/codex/codec/materialize.js +57 -0
  60. package/dist/providers/codex/codec/shared.d.ts +1 -0
  61. package/dist/providers/codex/codec/shared.d.ts.map +1 -1
  62. package/dist/providers/codex/codec/shared.js +9 -1
  63. package/dist/providers/codex/codec/sync-extension.d.ts +7 -1
  64. package/dist/providers/codex/codec/sync-extension.d.ts.map +1 -1
  65. package/dist/providers/codex/codec/sync-extension.js +183 -46
  66. package/dist/providers/identity/availability.d.ts +24 -1
  67. package/dist/providers/identity/availability.d.ts.map +1 -1
  68. package/dist/providers/identity/availability.js +253 -19
  69. package/package.json +2 -2
@@ -4,7 +4,8 @@ import { buildCommandContext, } from '../../../app/command-context.js';
4
4
  import { getFrontmatterBlock } from '../../shared/frontmatter.js';
5
5
  import { readGlobalOptions } from '../../shared/shared.utils.js';
6
6
  import { compileDispatchPolicyPreset, } from '../../../config/dispatch-ceiling-preset.js';
7
- import { resolveActiveProject, VALID_CLAUDE_DISPATCH_CEILINGS, VALID_CODEX_DISPATCH_CEILINGS, VALID_DISPATCH_MATRIX_TIERS, VALID_MANAGED_DISPATCH_POLICIES, } from '../../../config/oat-config.js';
7
+ import { getDispatchPolicyChoices, managedDispatchPolicyValueList, renderDispatchPolicyChoicesMarkdown, } from '../../../config/dispatch-policy-options.js';
8
+ import { resolveActiveProject, VALID_CLAUDE_DISPATCH_CEILINGS, VALID_CODEX_DISPATCH_CEILINGS, VALID_DISPATCH_MATRIX_TIERS, VALID_MANAGED_DISPATCH_POLICIES, validateDispatchRouteTarget, } from '../../../config/oat-config.js';
8
9
  import { resolveEffectiveConfig, } from '../../../config/resolve.js';
9
10
  import { resolveProjectRoot } from '../../../fs/paths.js';
10
11
  import TOML from '@iarna/toml';
@@ -106,7 +107,7 @@ function isValidManagedPolicy(value) {
106
107
  VALID_MANAGED_DISPATCH_POLICIES.includes(value));
107
108
  }
108
109
  function validManagedPolicyList() {
109
- return VALID_MANAGED_DISPATCH_POLICIES.join(', ');
110
+ return managedDispatchPolicyValueList(', ');
110
111
  }
111
112
  function validProviderValueList(provider) {
112
113
  return providerValueOrder(provider)?.join(', ') ?? 'none';
@@ -230,6 +231,22 @@ function policyTier(policy) {
230
231
  ? policy
231
232
  : null;
232
233
  }
234
+ function uncappedPreferredTier(provider, role, preferredValue) {
235
+ if (provider !== 'codex' || role === 'reviewer' || preferredValue === null) {
236
+ return null;
237
+ }
238
+ if (VALID_DISPATCH_MATRIX_TIERS.includes(preferredValue)) {
239
+ return preferredValue;
240
+ }
241
+ let matchedTier = null;
242
+ for (const tier of VALID_DISPATCH_MATRIX_TIERS) {
243
+ const compiledValue = compiledPolicyValueForProvider(provider, compileDispatchPolicyPreset(tier));
244
+ if (compiledValue === preferredValue) {
245
+ matchedTier = tier;
246
+ }
247
+ }
248
+ return matchedTier;
249
+ }
233
250
  function dispatchValueFromRouteTarget(target) {
234
251
  const adapter = getCeilingAdapter(target.harness);
235
252
  if (adapter.mechanism === 'pinned-variant') {
@@ -276,12 +293,25 @@ function resolveRouteMatrixCell(provider, route, escalationLevel, cellSource) {
276
293
  const target = typeof entry === 'string'
277
294
  ? routeTargetFromBareValue(provider, entry, routeIndex, route.length)
278
295
  : routeTargetFromObject(provider, entry, routeIndex, route.length);
279
- const value = typeof entry === 'string' ? entry : dispatchValueFromRouteTarget(target);
296
+ const targetValidation = typeof entry === 'string'
297
+ ? { valid: true }
298
+ : validateDispatchRouteTarget(provider, entry);
299
+ const value = targetValidation.valid
300
+ ? typeof entry === 'string'
301
+ ? entry
302
+ : dispatchValueFromRouteTarget(target)
303
+ : null;
304
+ const warnings = targetValidation.valid
305
+ ? []
306
+ : [
307
+ `Ignoring incomplete Codex dispatch target at route index ${routeIndex}: ${targetValidation.reason}`,
308
+ ];
280
309
  return {
281
310
  value,
282
311
  cellSource,
283
312
  target,
284
313
  selectionBranch: routeIndex > 0 ? 'escalation-target' : 'matrix-pinned',
314
+ warnings,
285
315
  };
286
316
  }
287
317
  function resolveProviderCellFromValue(provider, providerValue, tier, cellSource, escalationLevel) {
@@ -294,6 +324,7 @@ function resolveProviderCellFromValue(provider, providerValue, tier, cellSource,
294
324
  cellSource,
295
325
  target: null,
296
326
  selectionBranch: 'prompt-persisted',
327
+ warnings: [],
297
328
  };
298
329
  }
299
330
  if (tier === null) {
@@ -309,6 +340,7 @@ function resolveProviderCellFromValue(provider, providerValue, tier, cellSource,
309
340
  cellSource,
310
341
  target: null,
311
342
  selectionBranch: 'matrix-pinned',
343
+ warnings: [],
312
344
  };
313
345
  }
314
346
  return resolveRouteMatrixCell(provider, cell, escalationLevel, cellSource);
@@ -678,16 +710,24 @@ function selectDispatchValue(provider, role, policy, preferredValue) {
678
710
  };
679
711
  }
680
712
  if (policy.policy === 'uncapped') {
681
- const selectedValue = role === 'reviewer' ? null : preferredValue;
713
+ const targetValue = policy.target
714
+ ? dispatchValueFromRouteTarget(policy.target)
715
+ : null;
716
+ const selectedValue = role === 'reviewer' ? null : (targetValue ?? preferredValue);
717
+ const target = role === 'reviewer' || !targetValue ? null : policy.target;
682
718
  return {
683
719
  ...baseSelection,
684
720
  preferredValue: role === 'reviewer' ? null : preferredValue,
685
721
  selectedValue,
686
722
  capped: false,
687
723
  selectionMode: role === 'reviewer' ? 'no-review-target' : 'uncapped',
688
- selectionBranch: selectedValue ? 'prompt-persisted' : 'unresolved',
689
- family: selectionFamily(provider, selectedValue, null),
690
- target: null,
724
+ selectionBranch: target
725
+ ? policy.selectionBranch
726
+ : selectedValue
727
+ ? 'prompt-persisted'
728
+ : 'unresolved',
729
+ family: selectionFamily(provider, selectedValue, target),
730
+ target,
691
731
  };
692
732
  }
693
733
  if (policy.value === null) {
@@ -740,6 +780,40 @@ function selectDispatchValue(provider, role, policy, preferredValue) {
740
780
  target: selectedValue === policy.value ? policy.target : null,
741
781
  };
742
782
  }
783
+ function hasCodexVariantDispatchArgs(dispatchArgs) {
784
+ return (dispatchArgs !== null &&
785
+ 'variant' in dispatchArgs &&
786
+ typeof dispatchArgs.variant === 'string' &&
787
+ dispatchArgs.variant.length > 0);
788
+ }
789
+ function hasModelDispatchArgs(dispatchArgs) {
790
+ return (dispatchArgs !== null &&
791
+ 'model' in dispatchArgs &&
792
+ typeof dispatchArgs.model === 'string' &&
793
+ dispatchArgs.model.length > 0);
794
+ }
795
+ function modelAxis(selection, dispatchArgs) {
796
+ if (selection.target?.model && dispatchArgs) {
797
+ return `selected:${selection.target.model}`;
798
+ }
799
+ if (hasModelDispatchArgs(dispatchArgs)) {
800
+ return `selected:${dispatchArgs.model}`;
801
+ }
802
+ if (selection.selectionMode === 'inherit-default') {
803
+ return 'inherited';
804
+ }
805
+ return 'unresolved';
806
+ }
807
+ function codexEffortAxis(selection, dispatchArgs) {
808
+ if (hasCodexVariantDispatchArgs(dispatchArgs) && selection.target?.effort) {
809
+ return `selected:${selection.target.effort}`;
810
+ }
811
+ if (selection.selectionMode === 'inherit-default' ||
812
+ selection.selectionMode === 'no-review-target') {
813
+ return 'provider-default';
814
+ }
815
+ return 'unresolved';
816
+ }
743
817
  /**
744
818
  * Join a resolved ceiling value with the active provider's adapter to compute
745
819
  * the enforcement mode, mechanism, dispatch args, and verify-on-upgrade flag.
@@ -753,6 +827,8 @@ function buildProviderResolution(provider, policy, role, orchestratorTier, prefe
753
827
  mode: adapter.supportsCeiling ? 'advisory' : 'unsupported',
754
828
  mechanism: adapter.mechanism,
755
829
  dispatchArgs: null,
830
+ modelAxis: 'unresolved',
831
+ effortAxis: provider === 'codex' ? 'provider-default' : 'not-applicable',
756
832
  verifyOnDispatch: false,
757
833
  cellSource: null,
758
834
  target: null,
@@ -777,6 +853,7 @@ function buildProviderResolution(provider, policy, role, orchestratorTier, prefe
777
853
  const dispatchArgs = dispatchValue && !isCrossHarness
778
854
  ? adapter.compileToDispatchArgs(dispatchValue, role, {
779
855
  orchestratorTier,
856
+ target: selection.target,
780
857
  })
781
858
  : null;
782
859
  let mode;
@@ -794,9 +871,14 @@ function buildProviderResolution(provider, policy, role, orchestratorTier, prefe
794
871
  mode,
795
872
  mechanism: adapter.mechanism,
796
873
  dispatchArgs,
874
+ modelAxis: modelAxis(selection, dispatchArgs),
875
+ effortAxis: provider === 'codex'
876
+ ? codexEffortAxis(selection, dispatchArgs)
877
+ : 'not-applicable',
797
878
  verifyOnDispatch: dispatchValue && !isCrossHarness
798
879
  ? adapter.verifyOnDispatch(dispatchValue, {
799
880
  orchestratorTier,
881
+ target: selection.target,
800
882
  })
801
883
  : false,
802
884
  cellSource: policy.cellSource,
@@ -853,7 +935,7 @@ async function resolveDispatchCeiling(context, dependencies, options) {
853
935
  : 'not-applicable';
854
936
  const preferredValue = normalizePreferredValue(provider, options.preferred);
855
937
  const escalationLevel = normalizeEscalationLevel(options.escalationLevel);
856
- const resolvedValue = await resolveCeilingValue(provider, resolvedConfig, projectPath, dependencies, escalationLevel);
938
+ const resolvedValue = await resolveCeilingValue(provider, resolvedConfig, projectPath, dependencies, escalationLevel, role, preferredValue);
857
939
  for (const warning of resolvedValue?.warnings ?? []) {
858
940
  context.logger.warn(warning);
859
941
  }
@@ -903,14 +985,30 @@ async function resolveDispatchCeiling(context, dependencies, options) {
903
985
  * Never reads the preset label for dispatch — the preset is surfaced as
904
986
  * provenance only.
905
987
  */
906
- async function resolveCeilingValue(provider, resolvedConfig, projectPath, dependencies, escalationLevel) {
988
+ async function resolveCeilingValue(provider, resolvedConfig, projectPath, dependencies, escalationLevel, role, preferredValue) {
907
989
  const configCeiling = readResolvedConfigCeiling(provider, resolvedConfig);
908
990
  const projectCeiling = await resolveProjectStateCeiling(provider, projectPath, dependencies);
909
991
  const baseCeiling = configCeiling ?? projectCeiling;
910
992
  if (!baseCeiling) {
911
993
  return null;
912
994
  }
913
- if (baseCeiling.mode === 'inherit' || baseCeiling.policy === 'uncapped') {
995
+ if (baseCeiling.mode === 'inherit') {
996
+ return baseCeiling;
997
+ }
998
+ if (baseCeiling.policy === 'uncapped') {
999
+ const preferredTier = uncappedPreferredTier(provider, role, preferredValue);
1000
+ if (preferredTier) {
1001
+ const matrixCell = resolveProviderMatrixCell(provider, preferredTier, resolvedConfig, projectCeiling?.matrix ?? null, escalationLevel);
1002
+ if (matrixCell) {
1003
+ return {
1004
+ ...baseCeiling,
1005
+ cellSource: matrixCell.cellSource,
1006
+ target: matrixCell.target,
1007
+ selectionBranch: matrixCell.selectionBranch,
1008
+ warnings: [...baseCeiling.warnings, ...matrixCell.warnings],
1009
+ };
1010
+ }
1011
+ }
914
1012
  return baseCeiling;
915
1013
  }
916
1014
  const tier = policyTier(baseCeiling.policy);
@@ -922,6 +1020,7 @@ async function resolveCeilingValue(provider, resolvedConfig, projectPath, depend
922
1020
  cellSource: matrixCell.cellSource,
923
1021
  target: matrixCell.target,
924
1022
  selectionBranch: matrixCell.selectionBranch,
1023
+ warnings: [...baseCeiling.warnings, ...matrixCell.warnings],
925
1024
  };
926
1025
  }
927
1026
  if (baseCeiling.policy !== 'legacy-ceiling' &&
@@ -1023,12 +1122,40 @@ async function runDispatchCeilingResolve(context, dependencies, options) {
1023
1122
  process.exitCode = 1;
1024
1123
  }
1025
1124
  }
1125
+ async function runDispatchCeilingChoices(context, options) {
1126
+ const choices = getDispatchPolicyChoices();
1127
+ const format = (options.format ?? 'markdown').trim().toLowerCase();
1128
+ if (context.json || options.json) {
1129
+ context.logger.json({ status: 'ok', choices });
1130
+ process.exitCode = 0;
1131
+ return;
1132
+ }
1133
+ if (format !== 'markdown') {
1134
+ context.logger.error(`Invalid choices format "${options.format}". Valid formats: markdown.`);
1135
+ process.exitCode = 1;
1136
+ return;
1137
+ }
1138
+ context.logger.info(renderDispatchPolicyChoicesMarkdown(choices));
1139
+ process.exitCode = 0;
1140
+ }
1026
1141
  export function createProjectDispatchCeilingCommand(overrides = {}) {
1027
1142
  const dependencies = {
1028
1143
  ...DEFAULT_DEPENDENCIES,
1029
1144
  ...overrides,
1030
1145
  };
1031
1146
  const command = new Command('dispatch-ceiling').description('Resolve OAT project dispatch ceiling metadata');
1147
+ command.addCommand(new Command('choices')
1148
+ .description('Print canonical dispatch policy choices')
1149
+ .option('--format <format>', 'Output format: markdown', 'markdown')
1150
+ .option('--json', 'Output machine-readable JSON')
1151
+ .action(async (options, cmd) => {
1152
+ const globalOptions = readGlobalOptions(cmd);
1153
+ const context = dependencies.buildCommandContext({
1154
+ ...globalOptions,
1155
+ json: globalOptions.json === true || options.json === true,
1156
+ });
1157
+ await runDispatchCeilingChoices(context, options);
1158
+ }));
1032
1159
  command.addCommand(new Command('resolve')
1033
1160
  .description('Resolve dispatch policy for a provider')
1034
1161
  .requiredOption('--provider <provider>', 'Provider name: codex, claude, or cursor are enforced; unregistered providers resolve as unsupported advisory')
@@ -0,0 +1,4 @@
1
+ import type { ProvidersCodexDependencies } from '../../providers/providers.types.js';
2
+ import { Command } from 'commander';
3
+ export declare function createProvidersCodexCommand(overrides?: ProvidersCodexDependencies): Command;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/providers/codex/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,qCAAqC,CAAC;AACtF,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,wBAAgB,2BAA2B,CACzC,SAAS,GAAE,0BAA+B,GACzC,OAAO,CAIT"}
@@ -0,0 +1,7 @@
1
+ import { Command } from 'commander';
2
+ import { createCodexMaterializeCommand } from './materialize.js';
3
+ export function createProvidersCodexCommand(overrides = {}) {
4
+ return new Command('codex')
5
+ .description('Codex provider utilities')
6
+ .addCommand(createCodexMaterializeCommand(overrides.materialize));
7
+ }
@@ -0,0 +1,5 @@
1
+ import type { CodexMaterializeResult, ProvidersCodexMaterializeDependencies } from '../../providers/providers.types.js';
2
+ import { Command } from 'commander';
3
+ export declare function formatCodexMaterializeResult(result: CodexMaterializeResult): string;
4
+ export declare function createCodexMaterializeCommand(overrides?: Partial<ProvidersCodexMaterializeDependencies>): Command;
5
+ //# sourceMappingURL=materialize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"materialize.d.ts","sourceRoot":"","sources":["../../../../src/commands/providers/codex/materialize.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,sBAAsB,EACtB,qCAAqC,EACtC,MAAM,qCAAqC,CAAC;AAS7C,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAsD5C,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,sBAAsB,GAC7B,MAAM,CAaR;AAwGD,wBAAgB,6BAA6B,CAC3C,SAAS,GAAE,OAAO,CAAC,qCAAqC,CAAM,GAC7D,OAAO,CAoCT"}
@@ -0,0 +1,152 @@
1
+ import { readFile, writeFile } from 'node:fs/promises';
2
+ import { dirname, isAbsolute, join, resolve } from 'node:path';
3
+ import { parseCanonicalAgentFile } from '../../../agents/canonical/index.js';
4
+ import { buildCommandContext } from '../../../app/command-context.js';
5
+ import { readGlobalOptions } from '../../shared/shared.utils.js';
6
+ import { CliError } from '../../../errors/index.js';
7
+ import { ensureDir, fileExists } from '../../../fs/io.js';
8
+ import { resolveProjectRoot, resolveScopeRoot } from '../../../fs/paths.js';
9
+ import { mergeCodexConfigForRole } from '../../../providers/codex/codec/config-merge.js';
10
+ import { materializeCodexRole } from '../../../providers/codex/codec/materialize.js';
11
+ import { Command, Option } from 'commander';
12
+ function createDependencies() {
13
+ return {
14
+ buildCommandContext,
15
+ async resolveScopeRoot(scope, context) {
16
+ if (scope === 'project') {
17
+ return resolveProjectRoot(context.cwd);
18
+ }
19
+ return resolveScopeRoot(scope, context.cwd, context.home);
20
+ },
21
+ parseCanonicalAgentFile,
22
+ materializeCodexRole,
23
+ };
24
+ }
25
+ function requireOption(value, optionName) {
26
+ const normalized = value?.trim() ?? '';
27
+ if (!normalized) {
28
+ throw new CliError(`Missing required ${optionName}. Pass ${optionName} <value>.`);
29
+ }
30
+ return normalized;
31
+ }
32
+ function resolveAgentPath(agentName, options, scopeRoot) {
33
+ if (options.agentPath) {
34
+ return isAbsolute(options.agentPath)
35
+ ? options.agentPath
36
+ : resolve(scopeRoot, options.agentPath);
37
+ }
38
+ const fileName = agentName.endsWith('.md') ? agentName : `${agentName}.md`;
39
+ return join(scopeRoot, '.agents', 'agents', fileName);
40
+ }
41
+ export function formatCodexMaterializeResult(result) {
42
+ return [
43
+ result.dryRun
44
+ ? 'Codex materialization preview'
45
+ : 'Codex materialization complete',
46
+ `Scope: ${result.scope}`,
47
+ `Agent: ${result.agentPath}`,
48
+ `Role: ${result.roleName}`,
49
+ `Role file: ${result.rolePath}`,
50
+ `Config file: ${result.configPath}`,
51
+ 'TOML preview:',
52
+ result.tomlPreview.trimEnd(),
53
+ ].join('\n');
54
+ }
55
+ async function buildCodexMaterializePlan(agentName, options, context, dependencies) {
56
+ const model = requireOption(options.model, '--model');
57
+ const effort = requireOption(options.effort, '--effort');
58
+ const scope = options.scope;
59
+ const scopeRoot = await dependencies.resolveScopeRoot(scope, context);
60
+ const agentPath = resolveAgentPath(agentName, options, scopeRoot);
61
+ const agent = await dependencies.parseCanonicalAgentFile(agentPath);
62
+ const role = dependencies.materializeCodexRole({
63
+ agent,
64
+ model,
65
+ effort,
66
+ roleName: options.roleName,
67
+ });
68
+ const rolePath = join(scopeRoot, '.codex', role.configFile);
69
+ const configPath = join(scopeRoot, '.codex', 'config.toml');
70
+ return {
71
+ role,
72
+ result: {
73
+ status: context.dryRun ? 'preview' : 'written',
74
+ dryRun: context.dryRun,
75
+ scope,
76
+ agentPath,
77
+ roleName: role.roleName,
78
+ rolePath,
79
+ configPath,
80
+ configFile: role.configFile,
81
+ tomlPreview: role.content,
82
+ },
83
+ };
84
+ }
85
+ async function readOptionalFile(filePath) {
86
+ if (!(await fileExists(filePath))) {
87
+ return null;
88
+ }
89
+ return readFile(filePath, 'utf8');
90
+ }
91
+ async function applyCodexMaterializePlan({ result, role, }) {
92
+ await ensureDir(dirname(result.rolePath));
93
+ await writeFile(result.rolePath, role.content, 'utf8');
94
+ const existingConfig = await readOptionalFile(result.configPath);
95
+ const mergedConfig = mergeCodexConfigForRole({
96
+ existingContent: existingConfig,
97
+ role: {
98
+ roleName: role.roleName,
99
+ description: role.description,
100
+ configFile: role.configFile,
101
+ },
102
+ });
103
+ await ensureDir(dirname(result.configPath));
104
+ await writeFile(result.configPath, mergedConfig.mergedContent, 'utf8');
105
+ }
106
+ async function runCodexMaterializeCommand(agentName, options, context, dependencies) {
107
+ try {
108
+ const plan = await buildCodexMaterializePlan(agentName, options, context, dependencies);
109
+ if (!context.dryRun) {
110
+ await applyCodexMaterializePlan(plan);
111
+ }
112
+ const { result } = plan;
113
+ if (context.json) {
114
+ context.logger.json(result);
115
+ }
116
+ else {
117
+ context.logger.info(formatCodexMaterializeResult(result));
118
+ }
119
+ process.exitCode = 0;
120
+ }
121
+ catch (error) {
122
+ const message = error instanceof Error ? error.message : String(error);
123
+ if (context.json) {
124
+ context.logger.json({ status: 'error', message });
125
+ }
126
+ else {
127
+ context.logger.error(message);
128
+ }
129
+ process.exitCode = error instanceof CliError ? error.exitCode : 1;
130
+ }
131
+ }
132
+ export function createCodexMaterializeCommand(overrides = {}) {
133
+ const dependencies = {
134
+ ...createDependencies(),
135
+ ...overrides,
136
+ };
137
+ return new Command('materialize')
138
+ .description('Materialize a canonical agent as a Codex role')
139
+ .argument('<agent-name>', 'Canonical agent name')
140
+ .addOption(new Option('--scope <scope>', 'Materialization scope')
141
+ .choices(['project', 'user'])
142
+ .default('project'))
143
+ .option('--model <model>', 'Codex model ID')
144
+ .option('--effort <effort>', 'Codex reasoning effort')
145
+ .option('--role-name <role>', 'Override generated Codex role name')
146
+ .option('--agent-path <path>', 'Path to canonical agent markdown')
147
+ .option('--dry-run', 'Preview files without writing')
148
+ .action(async (agentName, options, command) => {
149
+ const context = dependencies.buildCommandContext(readGlobalOptions(command));
150
+ await runCodexMaterializeCommand(agentName, options, context, dependencies);
151
+ });
152
+ }
@@ -1,4 +1,4 @@
1
1
  import { Command } from 'commander';
2
- import type { ProvidersInspectDependencies, ProvidersListDependencies, ProvidersSetDependencies } from './providers.types.js';
3
- export declare function createProvidersCommand(listOverrides?: Partial<ProvidersListDependencies>, inspectOverrides?: Partial<ProvidersInspectDependencies>, setOverrides?: Partial<ProvidersSetDependencies>): Command;
2
+ import type { ProvidersCodexDependencies, ProvidersInspectDependencies, ProvidersListDependencies, ProvidersSetDependencies } from './providers.types.js';
3
+ export declare function createProvidersCommand(listOverrides?: Partial<ProvidersListDependencies>, inspectOverrides?: Partial<ProvidersInspectDependencies>, setOverrides?: Partial<ProvidersSetDependencies>, codexOverrides?: ProvidersCodexDependencies): Command;
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/providers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,OAAO,KAAK,EACV,4BAA4B,EAC5B,yBAAyB,EACzB,wBAAwB,EACzB,MAAM,mBAAmB,CAAC;AAG3B,wBAAgB,sBAAsB,CACpC,aAAa,GAAE,OAAO,CAAC,yBAAyB,CAAM,EACtD,gBAAgB,GAAE,OAAO,CAAC,4BAA4B,CAAM,EAC5D,YAAY,GAAE,OAAO,CAAC,wBAAwB,CAAM,GACnD,OAAO,CAMT"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/providers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,OAAO,KAAK,EACV,0BAA0B,EAC1B,4BAA4B,EAC5B,yBAAyB,EACzB,wBAAwB,EACzB,MAAM,mBAAmB,CAAC;AAG3B,wBAAgB,sBAAsB,CACpC,aAAa,GAAE,OAAO,CAAC,yBAAyB,CAAM,EACtD,gBAAgB,GAAE,OAAO,CAAC,4BAA4B,CAAM,EAC5D,YAAY,GAAE,OAAO,CAAC,wBAAwB,CAAM,EACpD,cAAc,GAAE,0BAA+B,GAC9C,OAAO,CAOT"}
@@ -1,11 +1,13 @@
1
1
  import { Command } from 'commander';
2
+ import { createProvidersCodexCommand } from './codex/index.js';
2
3
  import { createProvidersInspectCommand } from './inspect/inspect.js';
3
4
  import { createProvidersListCommand } from './list/list.js';
4
5
  import { createProvidersSetCommand } from './set/index.js';
5
- export function createProvidersCommand(listOverrides = {}, inspectOverrides = {}, setOverrides = {}) {
6
+ export function createProvidersCommand(listOverrides = {}, inspectOverrides = {}, setOverrides = {}, codexOverrides = {}) {
6
7
  return new Command('providers')
7
8
  .description('Inspect provider capabilities and paths')
8
9
  .addCommand(createProvidersListCommand(listOverrides))
9
10
  .addCommand(createProvidersInspectCommand(inspectOverrides))
10
- .addCommand(createProvidersSetCommand(setOverrides));
11
+ .addCommand(createProvidersSetCommand(setOverrides))
12
+ .addCommand(createProvidersCodexCommand(codexOverrides));
11
13
  }
@@ -1,7 +1,10 @@
1
+ import type { parseCanonicalAgentFile } from '../../agents/canonical/index.js';
1
2
  import type { CommandContext, GlobalOptions } from '../../app/command-context.js';
2
3
  import type { SyncConfig } from '../../config/index.js';
3
4
  import type { CopyTransform, DriftReport } from '../../drift/index.js';
4
5
  import type { Manifest } from '../../manifest/index.js';
6
+ import type { CodexRoleExport } from '../../providers/codex/codec/export-to-codex.js';
7
+ import type { CodexMaterializeRoleOptions } from '../../providers/codex/codec/materialize.js';
5
8
  import type { PathMapping, ProviderAdapter } from '../../providers/shared/index.js';
6
9
  import type { ConcreteScope, ContentType, Scope, SyncStrategy } from '../../shared/types.js';
7
10
  export interface ProviderListSummary {
@@ -60,4 +63,24 @@ export interface ProvidersSetDependencies {
60
63
  loadSyncConfig: (configPath: string) => Promise<SyncConfig>;
61
64
  saveSyncConfig: (configPath: string, config: SyncConfig) => Promise<SyncConfig>;
62
65
  }
66
+ export interface CodexMaterializeResult {
67
+ status: 'preview' | 'written';
68
+ dryRun: boolean;
69
+ scope: ConcreteScope;
70
+ agentPath: string;
71
+ roleName: string;
72
+ rolePath: string;
73
+ configPath: string;
74
+ configFile: string;
75
+ tomlPreview: string;
76
+ }
77
+ export interface ProvidersCodexMaterializeDependencies {
78
+ buildCommandContext: (options: GlobalOptions) => CommandContext;
79
+ resolveScopeRoot: (scope: ConcreteScope, context: CommandContext) => Promise<string>;
80
+ parseCanonicalAgentFile: typeof parseCanonicalAgentFile;
81
+ materializeCodexRole: (options: CodexMaterializeRoleOptions) => CodexRoleExport;
82
+ }
83
+ export interface ProvidersCodexDependencies {
84
+ materialize?: Partial<ProvidersCodexMaterializeDependencies>;
85
+ }
63
86
  //# sourceMappingURL=providers.types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"providers.types.d.ts","sourceRoot":"","sources":["../../../src/commands/providers/providers.types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"providers.types.d.ts","sourceRoot":"","sources":["../../../src/commands/providers/providers.types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"codex-strays.d.ts","sourceRoot":"","sources":["../../../src/commands/shared/codex-strays.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAEhF,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,6BAA6B;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IAC/C,oBAAoB,EAAE,CACpB,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,cAAc,EAAE,KAC/B,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACjC,kBAAkB,EAAE,CAClB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,kBAAkB,KACrB,OAAO,CAAC,OAAO,CAAC,CAAC;CACvB;AAuID,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,cAAc,EAAE,EAClC,gBAAgB,GAAE,GAAG,CAAC,MAAM,CAAa,GACxC,OAAO,CAAC,cAAc,EAAE,CAAC,CAuB3B;AAED,wBAAsB,4BAA4B,CAAC,EACjD,SAAS,EACT,aAAa,EACb,oBAAoB,EACpB,kBAAkB,GACnB,EAAE,6BAA6B,GAAG,OAAO,CAAC,IAAI,CAAC,CAI/C"}
1
+ {"version":3,"file":"codex-strays.d.ts","sourceRoot":"","sources":["../../../src/commands/shared/codex-strays.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAEhF,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,6BAA6B;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IAC/C,oBAAoB,EAAE,CACpB,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,cAAc,EAAE,KAC/B,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACjC,kBAAkB,EAAE,CAClB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,kBAAkB,KACrB,OAAO,CAAC,OAAO,CAAC,CAAC;CACvB;AAgJD,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,cAAc,EAAE,EAClC,gBAAgB,GAAE,GAAG,CAAC,MAAM,CAAa,GACxC,OAAO,CAAC,cAAc,EAAE,CAAC,CAuB3B;AAED,wBAAsB,4BAA4B,CAAC,EACjD,SAAS,EACT,aAAa,EACb,oBAAoB,EACpB,kBAAkB,GACnB,EAAE,6BAA6B,GAAG,OAAO,CAAC,IAAI,CAAC,CAI/C"}
@@ -1,6 +1,7 @@
1
1
  import { readdir, readFile, stat } from 'node:fs/promises';
2
2
  import { join } from 'node:path';
3
3
  import TOML from '@iarna/toml';
4
+ import { isOatManagedCodexRoleFile } from '../../providers/codex/codec/shared.js';
4
5
  function canonicalRoleNames(canonicalEntries) {
5
6
  return new Set(canonicalEntries
6
7
  .filter((entry) => entry.type === 'agent' && entry.isFile)
@@ -60,6 +61,10 @@ async function detectFromConfig(scopeRoot, existingCanonicalRoles, managedRoleNa
60
61
  if (!(await fileExists(absoluteRolePath))) {
61
62
  continue;
62
63
  }
64
+ const roleContent = await readFile(absoluteRolePath, 'utf8');
65
+ if (isOatManagedCodexRoleFile(roleContent, roleName)) {
66
+ continue;
67
+ }
63
68
  strays.push({
64
69
  roleName,
65
70
  providerPath,
@@ -92,9 +97,14 @@ async function detectFromAgentsDirectory(scopeRoot, existingCanonicalRoles, mana
92
97
  managedRoleNames.has(roleName)) {
93
98
  continue;
94
99
  }
100
+ const providerPath = `.codex/agents/${entry.name}`;
101
+ const roleContent = await readFile(join(scopeRoot, providerPath), 'utf8');
102
+ if (isOatManagedCodexRoleFile(roleContent, roleName)) {
103
+ continue;
104
+ }
95
105
  strays.push({
96
106
  roleName,
97
- providerPath: `.codex/agents/${entry.name}`,
107
+ providerPath,
98
108
  });
99
109
  }
100
110
  return strays;
@@ -24,7 +24,10 @@ interface StatusDependencies {
24
24
  detectDrift: (entry: Manifest['entries'][number], scopeRoot: string, copyTransform?: CopyTransform) => Promise<DriftReport>;
25
25
  detectStrays: (provider: string, providerDir: string, manifest: Manifest, canonicalEntries: CanonicalEntry[], mapping?: Pick<PathMapping, 'contentType' | 'providerExtension'>) => Promise<DriftReport[]>;
26
26
  detectCodexRoleStrays: (scopeRoot: string, canonicalEntries: CanonicalEntry[], managedRoleNames?: Set<string>) => Promise<CodexRoleStray[]>;
27
- computeCodexProjectExtensionPlan: (scopeRoot: string, canonicalEntries: CanonicalEntry[]) => Promise<CodexExtensionPlan>;
27
+ computeCodexProjectExtensionPlan: (scopeRoot: string, canonicalEntries: CanonicalEntry[], allowedCanonicalPaths?: string[], options?: {
28
+ userConfigDir?: string;
29
+ env?: NodeJS.ProcessEnv;
30
+ }) => Promise<CodexExtensionPlan>;
28
31
  applyCodexProjectExtensionPlan: (scopeRoot: string, plan: CodexExtensionPlan) => Promise<unknown>;
29
32
  selectManyWithAbort: <T extends string>(message: string, choices: MultiSelectChoice<T>[], ctx: PromptContext) => Promise<T[] | null>;
30
33
  confirmAction: (message: string, ctx: PromptContext) => Promise<boolean>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/status/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/status/index.ts"],"names":[],"mappings":"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"}
@@ -194,7 +194,7 @@ async function collectScopeReports(scope, context, dependencies) {
194
194
  }
195
195
  if (scope === 'project' &&
196
196
  activeAdapters.some((adapter) => adapter.name === 'codex')) {
197
- const codexExtensionPlan = await dependencies.computeCodexProjectExtensionPlan(scopeRoot, canonicalEntries);
197
+ const codexExtensionPlan = await dependencies.computeCodexProjectExtensionPlan(scopeRoot, canonicalEntries, undefined, { userConfigDir: join(context.home, '.oat') });
198
198
  for (const operation of codexExtensionPlan.operations) {
199
199
  if (operation.action === 'skip') {
200
200
  continue;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/index.ts"],"names":[],"mappings":"AAuCA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAI5C,OAAO,KAAK,EAEV,uBAAuB,EAExB,MAAM,cAAc,CAAC;AAoTtB,wBAAgB,iBAAiB,CAC/B,SAAS,GAAE,OAAO,CAAC,uBAAuB,CAAM,GAC/C,OAAO,CA6BT"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/index.ts"],"names":[],"mappings":"AAuCA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAI5C,OAAO,KAAK,EAEV,uBAAuB,EAExB,MAAM,cAAc,CAAC;AAqTtB,wBAAgB,iBAAiB,CAC/B,SAAS,GAAE,OAAO,CAAC,uBAAuB,CAAM,GAC/C,OAAO,CA6BT"}
@@ -169,7 +169,7 @@ async function computePlans(context, dependencies, allowedCanonicalPaths) {
169
169
  let codexExtension;
170
170
  const activeAdapterNames = resolved.activeAdapters.map((adapter) => adapter.name);
171
171
  if (scope === 'project' && activeAdapterNames.includes('codex')) {
172
- codexExtensionPlan = await dependencies.computeCodexProjectExtensionPlan(scopeRoot, canonical, allowedCanonicalPaths);
172
+ codexExtensionPlan = await dependencies.computeCodexProjectExtensionPlan(scopeRoot, canonical, allowedCanonicalPaths, { userConfigDir: join(context.home, '.oat') });
173
173
  codexExtension = {
174
174
  operations: dependencies.toCodexExtensionOperations(codexExtensionPlan),
175
175
  managedRoles: codexExtensionPlan.managedRoles,