@open-agent-toolkit/cli 0.1.73 → 0.1.76

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 (139) hide show
  1. package/assets/config/dispatch-matrix-recommendation.json +13 -17
  2. package/assets/docs/cli-utilities/configuration.md +53 -72
  3. package/assets/docs/cli-utilities/workflow-gates.md +38 -2
  4. package/assets/docs/provider-sync/commands.md +26 -0
  5. package/assets/docs/provider-sync/config.md +17 -6
  6. package/assets/docs/provider-sync/index.md +17 -5
  7. package/assets/docs/provider-sync/manifest-and-drift.md +39 -1
  8. package/assets/docs/provider-sync/providers.md +23 -19
  9. package/assets/docs/provider-sync/scope-and-surface.md +5 -1
  10. package/assets/docs/reference/file-locations.md +9 -3
  11. package/assets/docs/reference/oat-directory-structure.md +11 -3
  12. package/assets/docs/reference/troubleshooting.md +11 -0
  13. package/assets/docs/workflows/projects/artifacts.md +1 -1
  14. package/assets/docs/workflows/projects/dispatch-ceiling.md +29 -33
  15. package/assets/docs/workflows/projects/implementation-execution.md +7 -4
  16. package/assets/docs/workflows/projects/lifecycle.md +4 -3
  17. package/assets/public-package-versions.json +4 -4
  18. package/assets/skills/create-agnostic-skill/SKILL.md +1 -1
  19. package/assets/skills/create-agnostic-skill/references/docs/skills-guide.md +24 -15
  20. package/assets/skills/oat-agent-instructions-analyze/references/docs/provider-reference.md +9 -3
  21. package/assets/skills/oat-agent-instructions-apply/references/docs/provider-reference.md +9 -3
  22. package/assets/skills/oat-dispatch-subagents/SKILL.md +1 -1
  23. package/assets/skills/oat-dispatch-subagents/references/provider-cursor.md +27 -15
  24. package/assets/skills/oat-project-autonomous/SKILL.md +1 -1
  25. package/assets/skills/oat-project-autonomous/references/gate-inventory.md +1 -1
  26. package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +1 -1
  27. package/assets/skills/oat-project-implement/references/completion-and-closeout.md +17 -15
  28. package/assets/skills/oat-project-implement/references/dispatch-and-dry-run.md +15 -9
  29. package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +1 -1
  30. package/assets/skills/oat-project-implement/references/phase-execution.md +11 -5
  31. package/assets/skills/oat-project-import-plan/SKILL.md +30 -8
  32. package/assets/skills/oat-project-plan/SKILL.md +30 -8
  33. package/assets/skills/oat-project-plan-writing/SKILL.md +12 -9
  34. package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +1 -1
  35. package/assets/skills/oat-project-quick-start/SKILL.md +30 -8
  36. package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +1 -1
  37. package/assets/skills/oat-project-review-provide/SKILL.md +19 -11
  38. package/assets/skills/oat-project-review-provide-remote/SKILL.md +27 -4
  39. package/dist/commands/config/index.d.ts.map +1 -1
  40. package/dist/commands/config/index.js +55 -0
  41. package/dist/commands/doctor/index.d.ts +2 -1
  42. package/dist/commands/doctor/index.d.ts.map +1 -1
  43. package/dist/commands/doctor/index.js +37 -1
  44. package/dist/commands/gate/index.d.ts +1 -1
  45. package/dist/commands/gate/index.d.ts.map +1 -1
  46. package/dist/commands/gate/index.js +35 -3
  47. package/dist/commands/init/index.d.ts +7 -3
  48. package/dist/commands/init/index.d.ts.map +1 -1
  49. package/dist/commands/init/index.js +129 -38
  50. package/dist/commands/project/dispatch-ceiling/index.d.ts.map +1 -1
  51. package/dist/commands/project/dispatch-ceiling/index.js +17 -9
  52. package/dist/commands/remove/skill/remove-skill.d.ts +2 -0
  53. package/dist/commands/remove/skill/remove-skill.d.ts.map +1 -1
  54. package/dist/commands/remove/skill/remove-skill.js +20 -2
  55. package/dist/commands/shared/adopt-stray.d.ts.map +1 -1
  56. package/dist/commands/shared/adopt-stray.js +3 -0
  57. package/dist/commands/shared/codex-strays.d.ts +9 -0
  58. package/dist/commands/shared/codex-strays.d.ts.map +1 -1
  59. package/dist/commands/shared/codex-strays.js +4 -0
  60. package/dist/commands/shared/cursor-skill-disposition.d.ts +17 -0
  61. package/dist/commands/shared/cursor-skill-disposition.d.ts.map +1 -0
  62. package/dist/commands/shared/cursor-skill-disposition.js +41 -0
  63. package/dist/commands/status/index.d.ts +17 -5
  64. package/dist/commands/status/index.d.ts.map +1 -1
  65. package/dist/commands/status/index.js +151 -47
  66. package/dist/commands/sync/apply.d.ts.map +1 -1
  67. package/dist/commands/sync/apply.js +50 -24
  68. package/dist/commands/sync/dry-run.d.ts.map +1 -1
  69. package/dist/commands/sync/dry-run.js +31 -18
  70. package/dist/commands/sync/index.d.ts.map +1 -1
  71. package/dist/commands/sync/index.js +34 -25
  72. package/dist/commands/sync/sync.types.d.ts +26 -11
  73. package/dist/commands/sync/sync.types.d.ts.map +1 -1
  74. package/dist/commands/sync/sync.utils.d.ts.map +1 -1
  75. package/dist/commands/sync/sync.utils.js +3 -2
  76. package/dist/config/oat-config.d.ts +0 -1
  77. package/dist/config/oat-config.d.ts.map +1 -1
  78. package/dist/config/oat-config.js +26 -23
  79. package/dist/config/sync-config.d.ts +6 -2
  80. package/dist/config/sync-config.d.ts.map +1 -1
  81. package/dist/config/sync-config.js +18 -6
  82. package/dist/config/user-sync-config.d.ts +11 -0
  83. package/dist/config/user-sync-config.d.ts.map +1 -0
  84. package/dist/config/user-sync-config.js +61 -0
  85. package/dist/drift/strays.d.ts +1 -1
  86. package/dist/drift/strays.d.ts.map +1 -1
  87. package/dist/drift/strays.js +2 -1
  88. package/dist/engine/compute-plan.d.ts.map +1 -1
  89. package/dist/engine/compute-plan.js +154 -4
  90. package/dist/engine/engine.types.d.ts +2 -2
  91. package/dist/engine/engine.types.d.ts.map +1 -1
  92. package/dist/engine/engine.types.js +1 -0
  93. package/dist/engine/execute-plan.d.ts.map +1 -1
  94. package/dist/engine/execute-plan.js +4 -0
  95. package/dist/engine/index.d.ts +1 -1
  96. package/dist/engine/index.d.ts.map +1 -1
  97. package/dist/engine/index.js +1 -1
  98. package/dist/engine/scanner.d.ts +3 -1
  99. package/dist/engine/scanner.d.ts.map +1 -1
  100. package/dist/engine/scanner.js +4 -2
  101. package/dist/manifest/manifest.types.d.ts +12 -12
  102. package/dist/providers/ceiling/registry.d.ts +2 -0
  103. package/dist/providers/ceiling/registry.d.ts.map +1 -1
  104. package/dist/providers/ceiling/registry.js +20 -4
  105. package/dist/providers/codex/codec/sync-extension.d.ts +11 -10
  106. package/dist/providers/codex/codec/sync-extension.d.ts.map +1 -1
  107. package/dist/providers/codex/codec/sync-extension.js +42 -14
  108. package/dist/providers/cursor/codec/catalog.d.ts +18 -0
  109. package/dist/providers/cursor/codec/catalog.d.ts.map +1 -0
  110. package/dist/providers/cursor/codec/catalog.js +39 -0
  111. package/dist/providers/cursor/codec/materialize.d.ts +24 -0
  112. package/dist/providers/cursor/codec/materialize.d.ts.map +1 -0
  113. package/dist/providers/cursor/codec/materialize.js +166 -0
  114. package/dist/providers/cursor/codec/shared.d.ts +14 -0
  115. package/dist/providers/cursor/codec/shared.d.ts.map +1 -0
  116. package/dist/providers/cursor/codec/shared.js +76 -0
  117. package/dist/providers/cursor/codec/sync-extension.d.ts +37 -0
  118. package/dist/providers/cursor/codec/sync-extension.d.ts.map +1 -0
  119. package/dist/providers/cursor/codec/sync-extension.js +393 -0
  120. package/dist/providers/cursor/index.d.ts +3 -0
  121. package/dist/providers/cursor/index.d.ts.map +1 -1
  122. package/dist/providers/cursor/index.js +3 -0
  123. package/dist/providers/cursor/paths.d.ts.map +1 -1
  124. package/dist/providers/cursor/paths.js +6 -4
  125. package/dist/providers/identity/availability.d.ts +7 -0
  126. package/dist/providers/identity/availability.d.ts.map +1 -1
  127. package/dist/providers/identity/availability.js +23 -0
  128. package/dist/providers/shared/adapter.types.d.ts +6 -0
  129. package/dist/providers/shared/adapter.types.d.ts.map +1 -1
  130. package/dist/providers/shared/adapter.utils.d.ts +2 -1
  131. package/dist/providers/shared/adapter.utils.d.ts.map +1 -1
  132. package/dist/providers/shared/adapter.utils.js +29 -6
  133. package/dist/providers/shared/index.d.ts +2 -0
  134. package/dist/providers/shared/index.d.ts.map +1 -1
  135. package/dist/providers/shared/index.js +1 -0
  136. package/dist/providers/shared/materialization-extension.d.ts +44 -0
  137. package/dist/providers/shared/materialization-extension.d.ts.map +1 -0
  138. package/dist/providers/shared/materialization-extension.js +26 -0
  139. package/package.json +2 -2
@@ -1,8 +1,10 @@
1
- import { access, lstat, readFile, readlink } from 'node:fs/promises';
2
- import { basename, dirname, join, normalize, resolve } from 'node:path';
1
+ import { createHash } from 'node:crypto';
2
+ import { access, lstat, readdir, readFile, readlink, stat, } from 'node:fs/promises';
3
+ import { basename, dirname, join, normalize, relative, resolve, } from 'node:path';
3
4
  import { computeContentHash, computeStringHash } from '../manifest/hash.js';
4
5
  import { findEntry } from '../manifest/manager.js';
5
6
  import { getSyncMappings } from '../providers/shared/adapter.utils.js';
7
+ import { OAT_DIRECTORY_SENTINEL, OAT_MARKER_PREFIX } from './markers.js';
6
8
  function buildUpLevels(depth) {
7
9
  return Array.from({ length: depth }, () => '..');
8
10
  }
@@ -88,6 +90,145 @@ function createRemovalEntry(manifestEntry, scopeRoot) {
88
90
  reason: 'canonical entry no longer exists',
89
91
  };
90
92
  }
93
+ function createRetirementEntry(manifestEntry, scopeRoot, operation, reason) {
94
+ return {
95
+ ...createRemovalEntry(manifestEntry, scopeRoot),
96
+ operation,
97
+ reason,
98
+ };
99
+ }
100
+ function manifestEntryInsideMapping(entry, mapping) {
101
+ if (entry.contentType !== mapping.contentType) {
102
+ return false;
103
+ }
104
+ const canonicalPath = normalize(entry.canonicalPath).replaceAll('\\', '/');
105
+ const canonicalDir = normalize(mapping.canonicalDir).replaceAll('\\', '/');
106
+ return (canonicalPath === canonicalDir ||
107
+ canonicalPath.startsWith(`${canonicalDir}/`));
108
+ }
109
+ async function computeManagedDirectoryCopyHash(providerPath, canonicalPath, contentType) {
110
+ const expectedMarker = `${OAT_MARKER_PREFIX} Source: ${canonicalPath} -->`;
111
+ const sentinelPath = join(providerPath, OAT_DIRECTORY_SENTINEL);
112
+ try {
113
+ const sentinel = await readFile(sentinelPath, 'utf8');
114
+ if (sentinel !== `${expectedMarker}\n`) {
115
+ return null;
116
+ }
117
+ }
118
+ catch {
119
+ return null;
120
+ }
121
+ const files = [];
122
+ async function collectFiles(current) {
123
+ const entries = await readdir(current, { withFileTypes: true });
124
+ for (const entry of entries) {
125
+ const fullPath = join(current, entry.name);
126
+ if (fullPath === sentinelPath) {
127
+ continue;
128
+ }
129
+ if (entry.isDirectory()) {
130
+ if (!(await collectFiles(fullPath))) {
131
+ return false;
132
+ }
133
+ continue;
134
+ }
135
+ if (!entry.isFile()) {
136
+ return false;
137
+ }
138
+ files.push(fullPath);
139
+ }
140
+ return true;
141
+ }
142
+ try {
143
+ if (!(await collectFiles(providerPath))) {
144
+ return null;
145
+ }
146
+ files.sort((left, right) => relative(providerPath, left).localeCompare(relative(providerPath, right)));
147
+ const markerFileName = contentType === 'skill'
148
+ ? 'SKILL.md'
149
+ : contentType === 'agent'
150
+ ? 'AGENT.md'
151
+ : null;
152
+ const markerPath = markerFileName
153
+ ? join(providerPath, markerFileName)
154
+ : null;
155
+ const hash = createHash('sha256');
156
+ for (const file of files) {
157
+ const relativePath = relative(providerPath, file);
158
+ let content = await readFile(file);
159
+ if (file === markerPath) {
160
+ const markerPrefix = Buffer.from(`${expectedMarker}\n`);
161
+ if (content.length < markerPrefix.length ||
162
+ !content.subarray(0, markerPrefix.length).equals(markerPrefix)) {
163
+ return null;
164
+ }
165
+ content = content.subarray(markerPrefix.length);
166
+ }
167
+ hash.update(relativePath);
168
+ hash.update('\0');
169
+ hash.update(content);
170
+ hash.update('\0');
171
+ }
172
+ return hash.digest('hex');
173
+ }
174
+ catch {
175
+ return null;
176
+ }
177
+ }
178
+ async function classifyObsoleteMappingRetirement(manifestEntry, scopeRoot) {
179
+ const providerPath = resolve(scopeRoot, manifestEntry.providerPath);
180
+ const canonicalPath = resolve(scopeRoot, manifestEntry.canonicalPath);
181
+ let providerStat;
182
+ try {
183
+ providerStat = await lstat(providerPath);
184
+ }
185
+ catch (error) {
186
+ if (typeof error === 'object' &&
187
+ error !== null &&
188
+ 'code' in error &&
189
+ error.code === 'ENOENT') {
190
+ return createRetirementEntry(manifestEntry, scopeRoot, 'detach', 'obsolete mapping provider path is missing; detach manifest ownership');
191
+ }
192
+ return createRetirementEntry(manifestEntry, scopeRoot, 'detach', 'obsolete mapping provider path is unverified; preserve and detach manifest ownership');
193
+ }
194
+ if (manifestEntry.strategy === 'symlink') {
195
+ if (providerStat.isSymbolicLink()) {
196
+ try {
197
+ const linkTarget = await readlink(providerPath);
198
+ const resolvedTarget = resolve(dirname(providerPath), linkTarget);
199
+ await stat(resolvedTarget);
200
+ if (resolvedTarget === canonicalPath) {
201
+ return createRetirementEntry(manifestEntry, scopeRoot, 'remove', 'obsolete mapping has verified clean managed symlink');
202
+ }
203
+ }
204
+ catch {
205
+ // Broken or unreadable links are preserved and detached below.
206
+ }
207
+ }
208
+ return createRetirementEntry(manifestEntry, scopeRoot, 'detach', 'obsolete mapping provider path is changed or unverified; preserve and detach manifest ownership');
209
+ }
210
+ const expectedTypeMatches = manifestEntry.isFile
211
+ ? providerStat.isFile()
212
+ : providerStat.isDirectory();
213
+ if (expectedTypeMatches && manifestEntry.contentHash) {
214
+ try {
215
+ const currentHash = await computeContentHash(providerPath, manifestEntry.isFile);
216
+ if (currentHash === manifestEntry.contentHash) {
217
+ return createRetirementEntry(manifestEntry, scopeRoot, 'remove', 'obsolete mapping has verified clean managed copy');
218
+ }
219
+ }
220
+ catch {
221
+ // Hash failures are unverified and therefore non-destructive.
222
+ }
223
+ if (!manifestEntry.isFile) {
224
+ const managedHash = await computeManagedDirectoryCopyHash(providerPath, canonicalPath, manifestEntry.contentType);
225
+ if (managedHash === manifestEntry.contentHash) {
226
+ return createRetirementEntry(manifestEntry, scopeRoot, 'remove', 'obsolete mapping has verified clean managed copy');
227
+ }
228
+ }
229
+ }
230
+ return createRetirementEntry(manifestEntry, scopeRoot, 'detach', 'obsolete mapping provider path is changed or unverified; preserve and detach manifest ownership');
231
+ }
91
232
  async function classifyOperation(canonicalEntry, providerPath, strategy, renderedContent) {
92
233
  if (strategy === 'symlink') {
93
234
  let stat;
@@ -180,16 +321,22 @@ export async function computeSyncPlan({ canonical, adapters, manifest, scope, co
180
321
  const scopeRoot = resolveScopeRoot(canonical, explicitScopeRoot);
181
322
  const seenCanonicalKeys = new Set();
182
323
  const activeProviderNames = new Set();
324
+ const activeMappingsByProvider = new Map();
183
325
  const canonicalFilter = allowedCanonicalPaths
184
326
  ? new Set(allowedCanonicalPaths.map((canonicalPath) => normalize(canonicalPath)))
185
327
  : null;
186
328
  for (const adapter of adapters) {
329
+ if (resolveStrategy(adapter, config)) {
330
+ activeProviderNames.add(adapter.name);
331
+ }
187
332
  for (const mapping of getSyncMappings(adapter, scope)) {
188
333
  const mappingStrategy = resolveStrategy(adapter, config, Boolean(mapping.transformCanonical));
189
334
  if (!mappingStrategy) {
190
335
  continue;
191
336
  }
192
- activeProviderNames.add(adapter.name);
337
+ const activeMappings = activeMappingsByProvider.get(adapter.name) ?? [];
338
+ activeMappings.push(mapping);
339
+ activeMappingsByProvider.set(adapter.name, activeMappings);
193
340
  for (const canonicalEntry of canonical) {
194
341
  if (!entryContentTypeMatches(canonicalEntry, mapping.contentType)) {
195
342
  continue;
@@ -244,7 +391,10 @@ export async function computeSyncPlan({ canonical, adapters, manifest, scope, co
244
391
  !canonicalFilter.has(normalize(manifestEntry.canonicalPath))) {
245
392
  continue;
246
393
  }
247
- removals.push(createRemovalEntry(manifestEntry, scopeRoot));
394
+ const mappingStillExists = (activeMappingsByProvider.get(manifestEntry.provider) ?? []).some((mapping) => manifestEntryInsideMapping(manifestEntry, mapping));
395
+ removals.push(mappingStillExists
396
+ ? createRemovalEntry(manifestEntry, scopeRoot)
397
+ : await classifyObsoleteMappingRetirement(manifestEntry, scopeRoot));
248
398
  }
249
399
  return { scope, entries, removals };
250
400
  }
@@ -1,7 +1,7 @@
1
1
  import type { Scope } from '../shared/types.js';
2
2
  import type { CanonicalEntry } from './scanner.js';
3
3
  export type EngineScope = Exclude<Scope, 'all'>;
4
- export declare const SYNC_OPERATION_TYPES: readonly ["create_symlink", "create_copy", "update_symlink", "update_copy", "remove", "skip"];
4
+ export declare const SYNC_OPERATION_TYPES: readonly ["create_symlink", "create_copy", "update_symlink", "update_copy", "remove", "detach", "skip"];
5
5
  export type SyncOperationType = (typeof SYNC_OPERATION_TYPES)[number];
6
6
  export interface SyncPlanEntry {
7
7
  canonical: CanonicalEntry;
@@ -13,7 +13,7 @@ export interface SyncPlanEntry {
13
13
  renderedContent?: string;
14
14
  }
15
15
  export type RemovalSyncPlanEntry = SyncPlanEntry & {
16
- operation: 'remove';
16
+ operation: 'remove' | 'detach';
17
17
  };
18
18
  export interface SyncPlan {
19
19
  scope: EngineScope;
@@ -1 +1 @@
1
- {"version":3,"file":"engine.types.d.ts","sourceRoot":"","sources":["../../src/engine/engine.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEhD,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAEhD,eAAO,MAAM,oBAAoB,+FAOvB,CAAC;AAEX,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,cAAc,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,iBAAiB,CAAC;IAC7B,QAAQ,EAAE,SAAS,GAAG,MAAM,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,oBAAoB,GAAG,aAAa,GAAG;IAAE,SAAS,EAAE,QAAQ,CAAA;CAAE,CAAC;AAE3E,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,QAAQ,EAAE,oBAAoB,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB"}
1
+ {"version":3,"file":"engine.types.d.ts","sourceRoot":"","sources":["../../src/engine/engine.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEhD,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAEhD,eAAO,MAAM,oBAAoB,yGAQvB,CAAC;AAEX,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,cAAc,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,iBAAiB,CAAC;IAC7B,QAAQ,EAAE,SAAS,GAAG,MAAM,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,oBAAoB,GAAG,aAAa,GAAG;IACjD,SAAS,EAAE,QAAQ,GAAG,QAAQ,CAAC;CAChC,CAAC;AAEF,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,QAAQ,EAAE,oBAAoB,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB"}
@@ -4,5 +4,6 @@ export const SYNC_OPERATION_TYPES = [
4
4
  'update_symlink',
5
5
  'update_copy',
6
6
  'remove',
7
+ 'detach',
7
8
  'skip',
8
9
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"execute-plan.d.ts","sourceRoot":"","sources":["../../src/engine/execute-plan.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,QAAQ,EAAiB,MAAM,0BAA0B,CAAC;AAExE,OAAO,KAAK,EAAE,QAAQ,EAAiB,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAG1E,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAW5D;AAuJD,wBAAsB,eAAe,CACnC,IAAI,EAAE,QAAQ,EACd,QAAQ,EAAE,QAAQ,EAClB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,UAAU,CAAC,CA0BrB"}
1
+ {"version":3,"file":"execute-plan.d.ts","sourceRoot":"","sources":["../../src/engine/execute-plan.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,QAAQ,EAAiB,MAAM,0BAA0B,CAAC;AAExE,OAAO,KAAK,EAAE,QAAQ,EAAiB,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAG1E,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAW5D;AA2JD,wBAAsB,eAAe,CACnC,IAAI,EAAE,QAAQ,EACd,QAAQ,EAAE,QAAQ,EAClB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,UAAU,CAAC,CA0BrB"}
@@ -98,6 +98,10 @@ async function applyEntry(planEntry, manifest) {
98
98
  const { canonicalPath } = resolveManifestPaths(planEntry);
99
99
  return removeEntry(manifest, canonicalPath, planEntry.provider);
100
100
  }
101
+ case 'detach': {
102
+ const { canonicalPath } = resolveManifestPaths(planEntry);
103
+ return removeEntry(manifest, canonicalPath, planEntry.provider);
104
+ }
101
105
  case 'skip': {
102
106
  return manifest;
103
107
  }
@@ -5,5 +5,5 @@ export { configureLocalHooksPath, getHookInstallInfo, HOOK_DRIFT_WARNING, HOOK_M
5
5
  export type { HookInstallInfo, HookStatus } from './hook.js';
6
6
  export { hasMarker, insertMarker, OAT_DIRECTORY_SENTINEL, OAT_MARKER_PREFIX, writeDirectorySentinel, } from './markers.js';
7
7
  export type { CanonicalEntry } from './scanner.js';
8
- export { scanBundledManagedCodexAgents, scanCanonical } from './scanner.js';
8
+ export { scanBundledManagedAgents, scanBundledManagedCodexAgents, scanCanonical, } from './scanner.js';
9
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/engine/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,oBAAoB,EACzB,oBAAoB,EACpB,KAAK,iBAAiB,EACtB,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,UAAU,GAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,eAAe,EACf,kBAAkB,EAClB,YAAY,EACZ,aAAa,GACd,MAAM,QAAQ,CAAC;AAChB,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,EACL,SAAS,EACT,YAAY,EACZ,sBAAsB,EACtB,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,6BAA6B,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/engine/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,oBAAoB,EACzB,oBAAoB,EACpB,KAAK,iBAAiB,EACtB,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,UAAU,GAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,eAAe,EACf,kBAAkB,EAClB,YAAY,EACZ,aAAa,GACd,MAAM,QAAQ,CAAC;AAChB,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,EACL,SAAS,EACT,YAAY,EACZ,sBAAsB,EACtB,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EACL,wBAAwB,EACxB,6BAA6B,EAC7B,aAAa,GACd,MAAM,WAAW,CAAC"}
@@ -3,4 +3,4 @@ export { SYNC_OPERATION_TYPES, } from './engine.types.js';
3
3
  export { executeSyncPlan } from './execute-plan.js';
4
4
  export { configureLocalHooksPath, getHookInstallInfo, HOOK_DRIFT_WARNING, HOOK_MARKER_END, HOOK_MARKER_START, HOOK_STRAY_INFO, installHook, isHookInstalled, REPO_GITHOOKS_PATH, runHookCheck, uninstallHook, } from './hook.js';
5
5
  export { hasMarker, insertMarker, OAT_DIRECTORY_SENTINEL, OAT_MARKER_PREFIX, writeDirectorySentinel, } from './markers.js';
6
- export { scanBundledManagedCodexAgents, scanCanonical } from './scanner.js';
6
+ export { scanBundledManagedAgents, scanBundledManagedCodexAgents, scanCanonical, } from './scanner.js';
@@ -6,7 +6,9 @@ export interface CanonicalEntry {
6
6
  canonicalPath: string;
7
7
  isFile: boolean;
8
8
  }
9
- export declare function scanBundledManagedCodexAgents(): Promise<CanonicalEntry[]>;
9
+ export declare function scanBundledManagedAgents(): Promise<CanonicalEntry[]>;
10
+ /** @deprecated Use scanBundledManagedAgents for provider-neutral materialization. */
11
+ export declare const scanBundledManagedCodexAgents: typeof scanBundledManagedAgents;
10
12
  export declare function scanCanonical(basePath: string, scope: ConcreteScope): Promise<CanonicalEntry[]>;
11
13
  export {};
12
14
  //# sourceMappingURL=scanner.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../src/engine/scanner.ts"],"names":[],"mappings":"AAKA,OAAO,EAGL,KAAK,KAAK,EACX,MAAM,eAAe,CAAC;AAEvB,KAAK,aAAa,GAAG,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAE3C,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,OAAO,CAAC;CACjB;AA0DD,wBAAsB,6BAA6B,IAAI,OAAO,CAC5D,cAAc,EAAE,CACjB,CAsBA;AAED,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,aAAa,GACnB,OAAO,CAAC,cAAc,EAAE,CAAC,CA2B3B"}
1
+ {"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../src/engine/scanner.ts"],"names":[],"mappings":"AAKA,OAAO,EAGL,KAAK,KAAK,EACX,MAAM,eAAe,CAAC;AAEvB,KAAK,aAAa,GAAG,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAE3C,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,OAAO,CAAC;CACjB;AA0DD,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAsB1E;AAED,qFAAqF;AACrF,eAAO,MAAM,6BAA6B,iCAA2B,CAAC;AAEtE,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,aAAa,GACnB,OAAO,CAAC,cAAc,EAAE,CAAC,CA2B3B"}
@@ -43,13 +43,13 @@ async function readEntries(dirPath) {
43
43
  throw error;
44
44
  }
45
45
  }
46
- export async function scanBundledManagedCodexAgents() {
46
+ export async function scanBundledManagedAgents() {
47
47
  const agentsDir = join(await resolveAssetsRoot(), 'agents');
48
48
  const entries = await readEntries(agentsDir);
49
49
  const available = new Set(entries.filter((entry) => entry.isFile).map((entry) => entry.name));
50
50
  const missing = USER_SCOPE_MANAGED_AGENT_FILES.filter((name) => !available.has(name));
51
51
  if (missing.length > 0) {
52
- throw new CliError(`Bundled managed Codex role definitions are unavailable: ${missing.join(', ')}. Reinstall or rebuild OAT before running user sync.`);
52
+ throw new CliError(`Bundled managed role definitions are unavailable: ${missing.join(', ')}. Reinstall or rebuild OAT before running user sync.`);
53
53
  }
54
54
  return USER_SCOPE_MANAGED_AGENT_FILES.map((name) => ({
55
55
  name,
@@ -58,6 +58,8 @@ export async function scanBundledManagedCodexAgents() {
58
58
  isFile: true,
59
59
  }));
60
60
  }
61
+ /** @deprecated Use scanBundledManagedAgents for provider-neutral materialization. */
62
+ export const scanBundledManagedCodexAgents = scanBundledManagedAgents;
61
63
  export async function scanCanonical(basePath, scope) {
62
64
  const scopeRoot = resolve(basePath);
63
65
  const entries = [];
@@ -10,37 +10,37 @@ export declare const ManifestEntrySchema: z.ZodEffects<z.ZodObject<{
10
10
  lastSynced: z.ZodString;
11
11
  }, "strip", z.ZodTypeAny, {
12
12
  provider: string;
13
+ strategy: "symlink" | "copy";
13
14
  canonicalPath: string;
14
15
  providerPath: string;
15
16
  contentType: "skill" | "agent" | "rule";
16
- strategy: "symlink" | "copy";
17
17
  contentHash: string | null;
18
18
  isFile: boolean;
19
19
  lastSynced: string;
20
20
  }, {
21
21
  provider: string;
22
+ strategy: "symlink" | "copy";
22
23
  canonicalPath: string;
23
24
  providerPath: string;
24
25
  contentType: "skill" | "agent" | "rule";
25
- strategy: "symlink" | "copy";
26
26
  contentHash: string | null;
27
27
  lastSynced: string;
28
28
  isFile?: boolean | undefined;
29
29
  }>, {
30
30
  provider: string;
31
+ strategy: "symlink" | "copy";
31
32
  canonicalPath: string;
32
33
  providerPath: string;
33
34
  contentType: "skill" | "agent" | "rule";
34
- strategy: "symlink" | "copy";
35
35
  contentHash: string | null;
36
36
  isFile: boolean;
37
37
  lastSynced: string;
38
38
  }, {
39
39
  provider: string;
40
+ strategy: "symlink" | "copy";
40
41
  canonicalPath: string;
41
42
  providerPath: string;
42
43
  contentType: "skill" | "agent" | "rule";
43
- strategy: "symlink" | "copy";
44
44
  contentHash: string | null;
45
45
  lastSynced: string;
46
46
  isFile?: boolean | undefined;
@@ -59,37 +59,37 @@ export declare const ManifestSchema: z.ZodEffects<z.ZodObject<{
59
59
  lastSynced: z.ZodString;
60
60
  }, "strip", z.ZodTypeAny, {
61
61
  provider: string;
62
+ strategy: "symlink" | "copy";
62
63
  canonicalPath: string;
63
64
  providerPath: string;
64
65
  contentType: "skill" | "agent" | "rule";
65
- strategy: "symlink" | "copy";
66
66
  contentHash: string | null;
67
67
  isFile: boolean;
68
68
  lastSynced: string;
69
69
  }, {
70
70
  provider: string;
71
+ strategy: "symlink" | "copy";
71
72
  canonicalPath: string;
72
73
  providerPath: string;
73
74
  contentType: "skill" | "agent" | "rule";
74
- strategy: "symlink" | "copy";
75
75
  contentHash: string | null;
76
76
  lastSynced: string;
77
77
  isFile?: boolean | undefined;
78
78
  }>, {
79
79
  provider: string;
80
+ strategy: "symlink" | "copy";
80
81
  canonicalPath: string;
81
82
  providerPath: string;
82
83
  contentType: "skill" | "agent" | "rule";
83
- strategy: "symlink" | "copy";
84
84
  contentHash: string | null;
85
85
  isFile: boolean;
86
86
  lastSynced: string;
87
87
  }, {
88
88
  provider: string;
89
+ strategy: "symlink" | "copy";
89
90
  canonicalPath: string;
90
91
  providerPath: string;
91
92
  contentType: "skill" | "agent" | "rule";
92
- strategy: "symlink" | "copy";
93
93
  contentHash: string | null;
94
94
  lastSynced: string;
95
95
  isFile?: boolean | undefined;
@@ -98,10 +98,10 @@ export declare const ManifestSchema: z.ZodEffects<z.ZodObject<{
98
98
  }, "strip", z.ZodTypeAny, {
99
99
  entries: {
100
100
  provider: string;
101
+ strategy: "symlink" | "copy";
101
102
  canonicalPath: string;
102
103
  providerPath: string;
103
104
  contentType: "skill" | "agent" | "rule";
104
- strategy: "symlink" | "copy";
105
105
  contentHash: string | null;
106
106
  isFile: boolean;
107
107
  lastSynced: string;
@@ -112,10 +112,10 @@ export declare const ManifestSchema: z.ZodEffects<z.ZodObject<{
112
112
  }, {
113
113
  entries: {
114
114
  provider: string;
115
+ strategy: "symlink" | "copy";
115
116
  canonicalPath: string;
116
117
  providerPath: string;
117
118
  contentType: "skill" | "agent" | "rule";
118
- strategy: "symlink" | "copy";
119
119
  contentHash: string | null;
120
120
  lastSynced: string;
121
121
  isFile?: boolean | undefined;
@@ -126,10 +126,10 @@ export declare const ManifestSchema: z.ZodEffects<z.ZodObject<{
126
126
  }>, {
127
127
  entries: {
128
128
  provider: string;
129
+ strategy: "symlink" | "copy";
129
130
  canonicalPath: string;
130
131
  providerPath: string;
131
132
  contentType: "skill" | "agent" | "rule";
132
- strategy: "symlink" | "copy";
133
133
  contentHash: string | null;
134
134
  isFile: boolean;
135
135
  lastSynced: string;
@@ -140,10 +140,10 @@ export declare const ManifestSchema: z.ZodEffects<z.ZodObject<{
140
140
  }, {
141
141
  entries: {
142
142
  provider: string;
143
+ strategy: "symlink" | "copy";
143
144
  canonicalPath: string;
144
145
  providerPath: string;
145
146
  contentType: "skill" | "agent" | "rule";
146
- strategy: "symlink" | "copy";
147
147
  contentHash: string | null;
148
148
  lastSynced: string;
149
149
  isFile?: boolean | undefined;
@@ -13,6 +13,7 @@
13
13
  * (no variant files). Every other provider is advisory by default.
14
14
  */
15
15
  export type EnforcementMechanism = 'pinned-variant' | 'model-arg' | 'none';
16
+ export type ProviderSelectionAxis = 'model' | 'model-effort' | 'tier' | 'none';
16
17
  export type CeilingRole = 'implementer' | 'reviewer';
17
18
  export interface CeilingCompileContext {
18
19
  /** The orchestrator's own tier, used to detect above-orchestrator upgrades. */
@@ -33,6 +34,7 @@ export interface ProviderCeilingAdapter {
33
34
  supportsCeiling: boolean;
34
35
  validValues: string[];
35
36
  mechanism: EnforcementMechanism;
37
+ selectionAxis: ProviderSelectionAxis;
36
38
  /**
37
39
  * Compile a ceiling value into dispatch args for the given role, or `null`
38
40
  * when the value is invalid or the provider is advisory/unsupported.
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/providers/ceiling/registry.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;GAaG;AAEH,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,GAAG,WAAW,GAAG,MAAM,CAAC;AAE3E,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,UAAU,CAAC;AAErD,MAAM,WAAW,qBAAqB;IACpC,+EAA+E;IAC/E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,IAAI,CAAC;CACV;AAED,MAAM,MAAM,mBAAmB,GAC3B;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GACnB;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACjB,IAAI,CAAC;AAKT,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,OAAO,CAAC;IACzB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,EAAE,oBAAoB,CAAC;IAChC;;;OAGG;IACH,qBAAqB,CACnB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,qBAAqB,GACzB,mBAAmB,CAAC;IACvB;;;;OAIG;IACH,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC;CACtE;AAMD,wEAAwE;AACxE,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAK9C,CAAC;AA4GF;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,sBAAsB,CAE1E"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/providers/ceiling/registry.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;GAaG;AAEH,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,GAAG,WAAW,GAAG,MAAM,CAAC;AAC3E,MAAM,MAAM,qBAAqB,GAAG,OAAO,GAAG,cAAc,GAAG,MAAM,GAAG,MAAM,CAAC;AAE/E,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,UAAU,CAAC;AAErD,MAAM,WAAW,qBAAqB;IACpC,+EAA+E;IAC/E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,IAAI,CAAC;CACV;AAED,MAAM,MAAM,mBAAmB,GAC3B;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GACnB;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACjB,IAAI,CAAC;AAKT,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,OAAO,CAAC;IACzB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,EAAE,oBAAoB,CAAC;IAChC,aAAa,EAAE,qBAAqB,CAAC;IACrC;;;OAGG;IACH,qBAAqB,CACnB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,qBAAqB,GACzB,mBAAmB,CAAC;IACvB;;;;OAIG;IACH,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC;CACtE;AAMD,wEAAwE;AACxE,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAK9C,CAAC;AA6HF;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,sBAAsB,CAE1E"}
@@ -1,5 +1,7 @@
1
1
  import { VALID_CLAUDE_DISPATCH_CEILINGS, VALID_CODEX_DISPATCH_CEILINGS, } from '../../config/oat-config.js';
2
2
  import { buildCodexMaterializedTargetRoleName } from '../codex/codec/shared.js';
3
+ import { findCursorModelPinMapping } from '../cursor/codec/catalog.js';
4
+ import { buildCursorMaterializedRoleName } from '../cursor/codec/shared.js';
3
5
  const DIRECT_DISPATCH_ROLE_PATTERN = /^oat-(?:phase-implementer|reviewer)(?:-|$)/;
4
6
  export function isDirectDispatchRoleName(value) {
5
7
  return DIRECT_DISPATCH_ROLE_PATTERN.test(value.trim());
@@ -19,6 +21,7 @@ const codexAdapter = {
19
21
  supportsCeiling: true,
20
22
  validValues: [...VALID_CODEX_DISPATCH_CEILINGS],
21
23
  mechanism: 'pinned-variant',
24
+ selectionAxis: 'model-effort',
22
25
  compileToDispatchArgs(value, role, ctx) {
23
26
  if (!VALID_CODEX_DISPATCH_CEILINGS.includes(value)) {
24
27
  return null;
@@ -60,6 +63,7 @@ const claudeAdapter = {
60
63
  supportsCeiling: true,
61
64
  validValues: [...VALID_CLAUDE_DISPATCH_CEILINGS],
62
65
  mechanism: 'model-arg',
66
+ selectionAxis: 'tier',
63
67
  compileToDispatchArgs(value) {
64
68
  if (isDirectDispatchRoleName(value) ||
65
69
  !VALID_CLAUDE_DISPATCH_CEILINGS.includes(value)) {
@@ -76,10 +80,21 @@ const cursorAdapter = {
76
80
  provider: 'cursor',
77
81
  supportsCeiling: true,
78
82
  validValues: [],
79
- mechanism: 'model-arg',
80
- compileToDispatchArgs(value) {
81
- const model = value.trim();
82
- return model && !isDirectDispatchRoleName(model) ? { model } : null;
83
+ mechanism: 'pinned-variant',
84
+ selectionAxis: 'model',
85
+ compileToDispatchArgs(value, role, ctx) {
86
+ const model = ctx.target?.model ?? value.trim();
87
+ if (!model ||
88
+ isDirectDispatchRoleName(model) ||
89
+ !findCursorModelPinMapping(model)) {
90
+ return null;
91
+ }
92
+ return {
93
+ variant: buildCursorMaterializedRoleName({
94
+ agentName: role === 'reviewer' ? CODEX_REVIEWER_ROLE : CODEX_IMPLEMENTER_ROLE,
95
+ ladderModelId: model,
96
+ }),
97
+ };
83
98
  },
84
99
  // Cursor model slugs do not share a total order, so upgrade verification is
85
100
  // not meaningful here; availability is checked by the identity oracle layer.
@@ -93,6 +108,7 @@ function advisoryAdapter(provider) {
93
108
  supportsCeiling: false,
94
109
  validValues: [],
95
110
  mechanism: 'none',
111
+ selectionAxis: 'none',
96
112
  compileToDispatchArgs() {
97
113
  return null;
98
114
  },
@@ -1,5 +1,6 @@
1
1
  import type { CanonicalEntry } from '../../../engine/index.js';
2
- export type CodexExtensionAction = 'create' | 'update' | 'remove' | 'skip';
2
+ import { type MaterializationAction, type MaterializationApplyResult, type MaterializationContext, type MaterializationExtension, type MaterializationPlan, type MaterializationWriteOperation } from '../../shared/index.js';
3
+ export type CodexExtensionAction = MaterializationAction;
3
4
  export type CodexExtensionTarget = 'role' | 'config';
4
5
  export interface CodexExtensionOperation {
5
6
  action: CodexExtensionAction;
@@ -8,20 +9,20 @@ export interface CodexExtensionOperation {
8
9
  reason: string;
9
10
  roleName?: string;
10
11
  }
11
- export interface CodexExtensionWriteOperation extends CodexExtensionOperation {
12
- content?: string;
12
+ export interface CodexExtensionWriteOperation extends MaterializationWriteOperation<'codex', CodexExtensionTarget> {
13
+ roleName?: string;
13
14
  }
14
- export interface CodexExtensionPlan {
15
+ export interface CodexExtensionPlan extends MaterializationPlan<'codex', CodexExtensionTarget, CodexExtensionPlanMetadata> {
15
16
  operations: CodexExtensionWriteOperation[];
16
17
  managedRoles: string[];
17
18
  aggregateConfigHash: string;
18
19
  }
19
- export interface CodexExtensionApplyResult {
20
- applied: number;
21
- failed: number;
22
- skipped: number;
20
+ export interface CodexExtensionPlanMetadata {
21
+ managedRoles: string[];
22
+ aggregateConfigHash: string;
23
23
  }
24
- interface CodexMaterializationTargetOptions {
24
+ export type CodexExtensionApplyResult = MaterializationApplyResult;
25
+ export interface CodexMaterializationTargetOptions {
25
26
  userConfigDir?: string;
26
27
  projectPath?: string | null;
27
28
  env?: NodeJS.ProcessEnv;
@@ -34,5 +35,5 @@ export declare function summarizeCodexExtension(plan: CodexExtensionPlan): {
34
35
  skipped: number;
35
36
  };
36
37
  export declare function toCodexExtensionOperations(plan: CodexExtensionPlan): CodexExtensionOperation[];
37
- export {};
38
+ export declare const codexMaterializationExtension: MaterializationExtension<CodexExtensionPlan, MaterializationContext<CodexMaterializationTargetOptions>>;
38
39
  //# sourceMappingURL=sync-extension.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sync-extension.d.ts","sourceRoot":"","sources":["../../../../src/providers/codex/codec/sync-extension.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAyBpD,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AAC3E,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,QAAQ,CAAC;AAErD,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,oBAAoB,CAAC;IAC7B,MAAM,EAAE,oBAAoB,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,4BAA6B,SAAQ,uBAAuB;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,4BAA4B,EAAE,CAAC;IAC3C,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAgBD,UAAU,iCAAiC;IACzC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAqiBD,wBAAsB,gCAAgC,CACpD,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,cAAc,EAAE,EAClC,qBAAqB,CAAC,EAAE,MAAM,EAAE,EAChC,OAAO,GAAE,iCAAsC,GAC9C,OAAO,CAAC,kBAAkB,CAAC,CAqJ7B;AAED,wBAAsB,8BAA8B,CAClD,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,yBAAyB,CAAC,CA6BpC;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAE1E;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,kBAAkB,GAAG;IACjE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;CACjB,CAaA;AAED,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,kBAAkB,GACvB,uBAAuB,EAAE,CAQ3B"}
1
+ {"version":3,"file":"sync-extension.d.ts","sourceRoot":"","sources":["../../../../src/providers/codex/codec/sync-extension.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAKpD,OAAO,EAGL,KAAK,qBAAqB,EAC1B,KAAK,0BAA0B,EAC/B,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,EAC7B,KAAK,mBAAmB,EACxB,KAAK,6BAA6B,EACnC,MAAM,mBAAmB,CAAC;AAqB3B,MAAM,MAAM,oBAAoB,GAAG,qBAAqB,CAAC;AACzD,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,QAAQ,CAAC;AAErD,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,oBAAoB,CAAC;IAC7B,MAAM,EAAE,oBAAoB,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,4BAA6B,SAAQ,6BAA6B,CACjF,OAAO,EACP,oBAAoB,CACrB;IACC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAmB,SAAQ,mBAAmB,CAC7D,OAAO,EACP,oBAAoB,EACpB,0BAA0B,CAC3B;IACC,UAAU,EAAE,4BAA4B,EAAE,CAAC;IAC3C,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,0BAA0B;IACzC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,MAAM,yBAAyB,GAAG,0BAA0B,CAAC;AAgBnE,MAAM,WAAW,iCAAiC;IAChD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAqiBD,wBAAsB,gCAAgC,CACpD,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,cAAc,EAAE,EAClC,qBAAqB,CAAC,EAAE,MAAM,EAAE,EAChC,OAAO,GAAE,iCAAsC,GAC9C,OAAO,CAAC,kBAAkB,CAAC,CAkL7B;AAED,wBAAsB,8BAA8B,CAClD,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,yBAAyB,CAAC,CA6BpC;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAE1E;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,kBAAkB,GAAG;IACjE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;CACjB,CAEA;AAED,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,kBAAkB,GACvB,uBAAuB,EAAE,CAQ3B;AAED,eAAO,MAAM,6BAA6B,EAAE,wBAAwB,CAClE,kBAAkB,EAClB,sBAAsB,CAAC,iCAAiC,CAAC,CAY1D,CAAC"}