@open-agent-toolkit/cli 0.2.50 → 0.2.52

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 (263) hide show
  1. package/assets/bundle-metadata.json +1 -1
  2. package/assets/docs/cli-utilities/bootstrap.md +6 -2
  3. package/assets/docs/cli-utilities/tool-packs.md +87 -33
  4. package/assets/docs/provider-sync/commands.md +30 -2
  5. package/assets/docs/provider-sync/config.md +19 -0
  6. package/assets/docs/provider-sync/manifest-and-drift.md +37 -0
  7. package/assets/docs/provider-sync/providers.md +69 -2
  8. package/assets/docs/provider-sync/scope-and-surface.md +44 -0
  9. package/assets/docs/reference/cli-reference.md +21 -5
  10. package/assets/docs/reference/file-locations.md +8 -2
  11. package/assets/docs/reference/oat-directory-structure.md +25 -9
  12. package/assets/docs/workflows/projects/artifacts.md +9 -4
  13. package/assets/docs/workflows/projects/evidence-layers.md +110 -1
  14. package/assets/docs/workflows/projects/implementation-execution.md +13 -0
  15. package/assets/docs/workflows/projects/lifecycle.md +17 -5
  16. package/assets/docs/workflows/projects/orchestration-model.md +18 -0
  17. package/assets/docs/workflows/projects/picking-up-projects.md +26 -9
  18. package/assets/docs/workflows/projects/pr-flow.md +5 -3
  19. package/assets/docs/workflows/projects/reviewing-oat-prs.md +12 -8
  20. package/assets/public-package-versions.json +4 -4
  21. package/assets/skills/oat-dispatch-subagents/SKILL.md +57 -1
  22. package/assets/skills/oat-dispatch-subagents/references/record-schema.md +77 -1
  23. package/assets/skills/oat-project-autonomous/references/gate-inventory.md +3 -3
  24. package/assets/skills/oat-project-complete/SKILL.md +193 -26
  25. package/assets/skills/oat-project-complete/scripts/execute-synced-archive-entry.mjs +306 -0
  26. package/assets/skills/oat-project-complete/scripts/finalize-synced-archive.mjs +125 -0
  27. package/assets/skills/oat-project-complete/scripts/parse-synced-archive-resume-fields.mjs +106 -0
  28. package/assets/skills/oat-project-complete/scripts/recover-completion-receipts.mjs +110 -0
  29. package/assets/skills/oat-project-complete/scripts/resolve-synced-archive-entry.mjs +164 -0
  30. package/assets/skills/oat-project-dispatch-subagents/SKILL.md +24 -1
  31. package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +3 -3
  32. package/assets/skills/oat-project-implement/references/dispatch-and-dry-run.md +11 -0
  33. package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +3 -3
  34. package/assets/skills/oat-project-plan-writing/SKILL.md +12 -1
  35. package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +3 -3
  36. package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +3 -3
  37. package/assets/skills/oat-project-review-provide/SKILL.md +12 -1
  38. package/assets/skills/oat-project-review-provide-remote/SKILL.md +12 -1
  39. package/dist/agents/canonical/index.d.ts +2 -0
  40. package/dist/agents/canonical/index.d.ts.map +1 -1
  41. package/dist/agents/canonical/index.js +1 -0
  42. package/dist/agents/canonical/resolve.d.ts +45 -0
  43. package/dist/agents/canonical/resolve.d.ts.map +1 -0
  44. package/dist/agents/canonical/resolve.js +175 -0
  45. package/dist/commands/decision/agents-guidance.d.ts +2 -2
  46. package/dist/commands/decision/agents-guidance.d.ts.map +1 -1
  47. package/dist/commands/decision/agents-guidance.js +1 -4
  48. package/dist/commands/decision/index.d.ts.map +1 -1
  49. package/dist/commands/decision/index.js +25 -6
  50. package/dist/commands/docs/init/index.d.ts +7 -1
  51. package/dist/commands/docs/init/index.d.ts.map +1 -1
  52. package/dist/commands/docs/init/index.js +53 -20
  53. package/dist/commands/doctor/index.d.ts +8 -2
  54. package/dist/commands/doctor/index.d.ts.map +1 -1
  55. package/dist/commands/doctor/index.js +157 -46
  56. package/dist/commands/init/index.d.ts +8 -3
  57. package/dist/commands/init/index.d.ts.map +1 -1
  58. package/dist/commands/init/index.js +64 -26
  59. package/dist/commands/init/tools/index.d.ts +12 -12
  60. package/dist/commands/init/tools/index.d.ts.map +1 -1
  61. package/dist/commands/init/tools/index.js +430 -99
  62. package/dist/commands/init/tools/install-state.d.ts +2 -0
  63. package/dist/commands/init/tools/install-state.d.ts.map +1 -1
  64. package/dist/commands/init/tools/install-state.js +11 -0
  65. package/dist/commands/init/tools/project-guidance.d.ts +49 -0
  66. package/dist/commands/init/tools/project-guidance.d.ts.map +1 -0
  67. package/dist/commands/init/tools/project-guidance.js +144 -0
  68. package/dist/commands/init/tools/workflows/index.d.ts +7 -0
  69. package/dist/commands/init/tools/workflows/index.d.ts.map +1 -1
  70. package/dist/commands/init/tools/workflows/index.js +160 -7
  71. package/dist/commands/pjm/index.d.ts.map +1 -1
  72. package/dist/commands/pjm/index.js +28 -3
  73. package/dist/commands/pjm/init.d.ts +5 -0
  74. package/dist/commands/pjm/init.d.ts.map +1 -1
  75. package/dist/commands/pjm/init.js +19 -3
  76. package/dist/commands/project/archive/archive-utils.d.ts +8 -1
  77. package/dist/commands/project/archive/archive-utils.d.ts.map +1 -1
  78. package/dist/commands/project/archive/archive-utils.js +147 -50
  79. package/dist/commands/project/archive/push-runner.d.ts.map +1 -1
  80. package/dist/commands/project/archive/push-runner.js +15 -2
  81. package/dist/commands/project/dispatch/index.d.ts +10 -0
  82. package/dist/commands/project/dispatch/index.d.ts.map +1 -0
  83. package/dist/commands/project/dispatch/index.js +137 -0
  84. package/dist/commands/project/dispatch/record.d.ts +91 -0
  85. package/dist/commands/project/dispatch/record.d.ts.map +1 -0
  86. package/dist/commands/project/dispatch/record.js +402 -0
  87. package/dist/commands/project/index.d.ts.map +1 -1
  88. package/dist/commands/project/index.js +2 -0
  89. package/dist/commands/project/links/compute.d.ts +1 -0
  90. package/dist/commands/project/links/compute.d.ts.map +1 -1
  91. package/dist/commands/project/links/compute.js +5 -4
  92. package/dist/commands/project/links/index.d.ts +9 -0
  93. package/dist/commands/project/links/index.d.ts.map +1 -1
  94. package/dist/commands/project/links/index.js +71 -2
  95. package/dist/commands/project/list.d.ts +10 -2
  96. package/dist/commands/project/list.d.ts.map +1 -1
  97. package/dist/commands/project/list.js +205 -29
  98. package/dist/commands/project/open/index.d.ts +2 -0
  99. package/dist/commands/project/open/index.d.ts.map +1 -1
  100. package/dist/commands/project/open/index.js +16 -1
  101. package/dist/commands/project/prune/index.d.ts +10 -4
  102. package/dist/commands/project/prune/index.d.ts.map +1 -1
  103. package/dist/commands/project/prune/index.js +85 -15
  104. package/dist/commands/project/pull/index.d.ts +4 -0
  105. package/dist/commands/project/pull/index.d.ts.map +1 -1
  106. package/dist/commands/project/pull/index.js +82 -3
  107. package/dist/commands/project/sync/git.d.ts +9 -0
  108. package/dist/commands/project/sync/git.d.ts.map +1 -1
  109. package/dist/commands/project/sync/git.js +18 -0
  110. package/dist/commands/project/sync/ref-sync.d.ts +16 -1
  111. package/dist/commands/project/sync/ref-sync.d.ts.map +1 -1
  112. package/dist/commands/project/sync/ref-sync.js +288 -17
  113. package/dist/commands/project/sync/resolve-target.d.ts +10 -0
  114. package/dist/commands/project/sync/resolve-target.d.ts.map +1 -1
  115. package/dist/commands/project/sync/resolve-target.js +56 -1
  116. package/dist/commands/providers/inspect/inspect.d.ts +8 -1
  117. package/dist/commands/providers/inspect/inspect.d.ts.map +1 -1
  118. package/dist/commands/providers/inspect/inspect.js +146 -26
  119. package/dist/commands/providers/list/list.d.ts +8 -1
  120. package/dist/commands/providers/list/list.d.ts.map +1 -1
  121. package/dist/commands/providers/list/list.js +139 -23
  122. package/dist/commands/providers/providers.types.d.ts +25 -1
  123. package/dist/commands/providers/providers.types.d.ts.map +1 -1
  124. package/dist/commands/providers/set/index.d.ts +9 -1
  125. package/dist/commands/providers/set/index.d.ts.map +1 -1
  126. package/dist/commands/providers/set/index.js +43 -33
  127. package/dist/commands/remove/skill/remove-skill.d.ts.map +1 -1
  128. package/dist/commands/remove/skill/remove-skill.js +11 -0
  129. package/dist/commands/shared/agents-md.d.ts +42 -14
  130. package/dist/commands/shared/agents-md.d.ts.map +1 -1
  131. package/dist/commands/shared/agents-md.js +364 -70
  132. package/dist/commands/shared/project-scope.d.ts +2 -0
  133. package/dist/commands/shared/project-scope.d.ts.map +1 -1
  134. package/dist/commands/shared/project-scope.js +5 -0
  135. package/dist/commands/state/generate.d.ts +2 -0
  136. package/dist/commands/state/generate.d.ts.map +1 -1
  137. package/dist/commands/state/generate.js +93 -28
  138. package/dist/commands/status/index.d.ts +8 -3
  139. package/dist/commands/status/index.d.ts.map +1 -1
  140. package/dist/commands/status/index.js +147 -32
  141. package/dist/commands/sync/apply.d.ts.map +1 -1
  142. package/dist/commands/sync/apply.js +220 -29
  143. package/dist/commands/sync/dry-run.d.ts.map +1 -1
  144. package/dist/commands/sync/dry-run.js +30 -6
  145. package/dist/commands/sync/index.d.ts +17 -2
  146. package/dist/commands/sync/index.d.ts.map +1 -1
  147. package/dist/commands/sync/index.js +106 -41
  148. package/dist/commands/sync/sync.types.d.ts +39 -2
  149. package/dist/commands/sync/sync.types.d.ts.map +1 -1
  150. package/dist/commands/sync/sync.utils.d.ts +5 -1
  151. package/dist/commands/sync/sync.utils.d.ts.map +1 -1
  152. package/dist/commands/sync/sync.utils.js +73 -0
  153. package/dist/commands/tools/info/info-tool.d.ts +2 -0
  154. package/dist/commands/tools/info/info-tool.d.ts.map +1 -1
  155. package/dist/commands/tools/info/info-tool.js +34 -12
  156. package/dist/commands/tools/install/index.d.ts.map +1 -1
  157. package/dist/commands/tools/install/index.js +19 -3
  158. package/dist/commands/tools/list/list-tools.d.ts +2 -0
  159. package/dist/commands/tools/list/list-tools.d.ts.map +1 -1
  160. package/dist/commands/tools/list/list-tools.js +36 -7
  161. package/dist/commands/tools/remove/index.d.ts.map +1 -1
  162. package/dist/commands/tools/remove/index.js +150 -21
  163. package/dist/commands/tools/remove/remove-tools.d.ts +20 -0
  164. package/dist/commands/tools/remove/remove-tools.d.ts.map +1 -1
  165. package/dist/commands/tools/remove/remove-tools.js +122 -1
  166. package/dist/commands/tools/shared/format-pack-inventory.d.ts +19 -0
  167. package/dist/commands/tools/shared/format-pack-inventory.d.ts.map +1 -1
  168. package/dist/commands/tools/shared/format-pack-inventory.js +109 -0
  169. package/dist/commands/tools/shared/pack-evidence.d.ts +66 -0
  170. package/dist/commands/tools/shared/pack-evidence.d.ts.map +1 -0
  171. package/dist/commands/tools/shared/pack-evidence.js +132 -0
  172. package/dist/commands/tools/shared/pack-inventory.d.ts +1 -0
  173. package/dist/commands/tools/shared/pack-inventory.d.ts.map +1 -1
  174. package/dist/commands/tools/shared/pack-lifecycle-outcome.d.ts +44 -0
  175. package/dist/commands/tools/shared/pack-lifecycle-outcome.d.ts.map +1 -0
  176. package/dist/commands/tools/shared/pack-lifecycle-outcome.js +91 -0
  177. package/dist/commands/tools/update/index.d.ts.map +1 -1
  178. package/dist/commands/tools/update/index.js +74 -4
  179. package/dist/commands/tools/update/update-tools.d.ts +5 -0
  180. package/dist/commands/tools/update/update-tools.d.ts.map +1 -1
  181. package/dist/commands/tools/update/update-tools.js +64 -2
  182. package/dist/config/oat-config.d.ts +5 -0
  183. package/dist/config/oat-config.d.ts.map +1 -1
  184. package/dist/config/oat-config.js +17 -5
  185. package/dist/config/user-sync-config.d.ts +1 -0
  186. package/dist/config/user-sync-config.d.ts.map +1 -1
  187. package/dist/config/user-sync-config.js +8 -0
  188. package/dist/drift/detector.d.ts +2 -2
  189. package/dist/drift/detector.d.ts.map +1 -1
  190. package/dist/drift/detector.js +18 -0
  191. package/dist/drift/strays.d.ts.map +1 -1
  192. package/dist/drift/strays.js +5 -0
  193. package/dist/engine/collection-sync.d.ts +14 -0
  194. package/dist/engine/collection-sync.d.ts.map +1 -0
  195. package/dist/engine/collection-sync.js +282 -0
  196. package/dist/engine/compute-plan.d.ts +8 -1
  197. package/dist/engine/compute-plan.d.ts.map +1 -1
  198. package/dist/engine/compute-plan.js +303 -12
  199. package/dist/engine/engine.types.d.ts +61 -0
  200. package/dist/engine/engine.types.d.ts.map +1 -1
  201. package/dist/engine/execute-plan.d.ts +22 -2
  202. package/dist/engine/execute-plan.d.ts.map +1 -1
  203. package/dist/engine/execute-plan.js +459 -27
  204. package/dist/engine/provider-path-safety.d.ts +1 -0
  205. package/dist/engine/provider-path-safety.d.ts.map +1 -1
  206. package/dist/engine/provider-path-safety.js +15 -0
  207. package/dist/engine/scanner.d.ts +2 -2
  208. package/dist/engine/scanner.d.ts.map +1 -1
  209. package/dist/engine/scanner.js +21 -4
  210. package/dist/fs/io.d.ts +67 -0
  211. package/dist/fs/io.d.ts.map +1 -1
  212. package/dist/fs/io.js +536 -3
  213. package/dist/manifest/index.d.ts +2 -2
  214. package/dist/manifest/index.d.ts.map +1 -1
  215. package/dist/manifest/index.js +1 -1
  216. package/dist/manifest/manager.d.ts +2 -2
  217. package/dist/manifest/manager.d.ts.map +1 -1
  218. package/dist/manifest/manager.js +20 -3
  219. package/dist/manifest/manifest.types.d.ts +704 -13
  220. package/dist/manifest/manifest.types.d.ts.map +1 -1
  221. package/dist/manifest/manifest.types.js +131 -15
  222. package/dist/providers/codex/codec/sync-extension.d.ts.map +1 -1
  223. package/dist/providers/codex/codec/sync-extension.js +41 -10
  224. package/dist/providers/cursor/codec/sync-extension.d.ts.map +1 -1
  225. package/dist/providers/cursor/codec/sync-extension.js +41 -10
  226. package/dist/providers/identity/absolute-paths.d.ts +68 -0
  227. package/dist/providers/identity/absolute-paths.d.ts.map +1 -0
  228. package/dist/providers/identity/absolute-paths.js +144 -0
  229. package/dist/providers/identity/claude-runtime-observation.d.ts +105 -0
  230. package/dist/providers/identity/claude-runtime-observation.d.ts.map +1 -0
  231. package/dist/providers/identity/claude-runtime-observation.fixtures.d.ts +40 -0
  232. package/dist/providers/identity/claude-runtime-observation.fixtures.d.ts.map +1 -0
  233. package/dist/providers/identity/claude-runtime-observation.fixtures.js +146 -0
  234. package/dist/providers/identity/claude-runtime-observation.js +229 -0
  235. package/dist/providers/identity/codex-runtime-observation.d.ts +75 -0
  236. package/dist/providers/identity/codex-runtime-observation.d.ts.map +1 -0
  237. package/dist/providers/identity/codex-runtime-observation.fixtures.d.ts +37 -0
  238. package/dist/providers/identity/codex-runtime-observation.fixtures.d.ts.map +1 -0
  239. package/dist/providers/identity/codex-runtime-observation.fixtures.js +539 -0
  240. package/dist/providers/identity/codex-runtime-observation.js +255 -0
  241. package/dist/providers/identity/generic-dispatch-record.d.ts +313 -0
  242. package/dist/providers/identity/generic-dispatch-record.d.ts.map +1 -0
  243. package/dist/providers/identity/generic-dispatch-record.js +539 -0
  244. package/dist/providers/identity/oat-dispatch-record.d.ts +1964 -0
  245. package/dist/providers/identity/oat-dispatch-record.d.ts.map +1 -0
  246. package/dist/providers/identity/oat-dispatch-record.js +691 -0
  247. package/dist/providers/identity/runtime-observation.d.ts +100 -0
  248. package/dist/providers/identity/runtime-observation.d.ts.map +1 -0
  249. package/dist/providers/identity/runtime-observation.js +169 -0
  250. package/dist/providers/shared/index.d.ts +2 -0
  251. package/dist/providers/shared/index.d.ts.map +1 -1
  252. package/dist/providers/shared/index.js +1 -0
  253. package/dist/providers/shared/materialization-extension.d.ts +12 -0
  254. package/dist/providers/shared/materialization-extension.d.ts.map +1 -1
  255. package/dist/providers/shared/registry.d.ts +69 -0
  256. package/dist/providers/shared/registry.d.ts.map +1 -0
  257. package/dist/providers/shared/registry.js +252 -0
  258. package/dist/providers/shared/restart-adviser.d.ts +26 -0
  259. package/dist/providers/shared/restart-adviser.d.ts.map +1 -0
  260. package/dist/providers/shared/restart-adviser.js +96 -0
  261. package/dist/shared/types.d.ts +4 -0
  262. package/dist/shared/types.d.ts.map +1 -1
  263. package/package.json +2 -2
@@ -1,8 +1,14 @@
1
1
  import { execSync } from 'node:child_process';
2
2
  import { readdir, writeFile } from 'node:fs/promises';
3
- import { basename, join } from 'node:path';
3
+ import { basename, dirname, join, resolve } from 'node:path';
4
+ import { classifyLegacySyncedRecord, probeAuthoritativeCompletedRef, } from '../project/list.js';
5
+ import { defaultGitRunner } from '../project/sync/git.js';
6
+ import { listSyncedRecords } from '../project/sync/record.js';
7
+ import { buildSyncTarget } from '../project/sync/ref-sync.js';
8
+ import { probeSyncedTerminalRefs } from '../project/sync/resolve-target.js';
4
9
  import { parseFrontmatterField } from '../shared/frontmatter.js';
5
10
  import { resolveProjectsRoot } from '../shared/oat-paths.js';
11
+ import { resolveScopeRoot } from '../shared/project-scope.js';
6
12
  import { readOatLocalConfig } from '../../config/oat-config.js';
7
13
  import { ensureDir, fileExists } from '../../fs/io.js';
8
14
  const defaultGit = {
@@ -310,22 +316,41 @@ function isTerminalCoordinationProject(kind, phase, phaseStatus) {
310
316
  phase === 'decomposition' &&
311
317
  phaseStatus === 'complete');
312
318
  }
313
- async function listAvailableProjects(repoRoot, projectsRoot) {
314
- const fullRoot = join(repoRoot, projectsRoot);
315
- try {
316
- const entries = await readdir(fullRoot, { withFileTypes: true });
317
- const dirs = entries.filter((e) => e.isDirectory());
318
- if (dirs.length === 0) {
319
- return {
320
- active: '*(No projects found)*',
321
- decompositions: '*(No decompositions found)*',
322
- };
319
+ async function listAvailableProjects(repoRoot, projectsRoot, gitRunner) {
320
+ const lines = [];
321
+ const decompositions = [];
322
+ const materializedSynced = new Set();
323
+ for (const scope of ['shared', 'synced', 'local']) {
324
+ const scopeRoot = resolveScopeRoot(repoRoot, projectsRoot, scope);
325
+ let entries;
326
+ try {
327
+ entries = await readdir(scopeRoot, { withFileTypes: true });
323
328
  }
324
- const lines = [];
325
- const decompositions = [];
326
- for (const dir of dirs) {
327
- const stateFile = join(fullRoot, dir.name, 'state.md');
329
+ catch {
330
+ continue;
331
+ }
332
+ for (const dir of entries.filter((entry) => entry.isDirectory())) {
333
+ const stateFile = join(scopeRoot, dir.name, 'state.md');
328
334
  if (await fileExists(stateFile)) {
335
+ if (scope === 'synced') {
336
+ materializedSynced.add(dir.name);
337
+ const target = buildSyncTarget(repoRoot, projectsRoot, dir.name);
338
+ const terminal = await probeAuthoritativeCompletedRef(target, gitRunner);
339
+ if (terminal) {
340
+ const row = classifyLegacySyncedRecord({
341
+ schemaVersion: 1,
342
+ slug: dir.name,
343
+ scope: 'synced',
344
+ ref: target.ref,
345
+ remote: 'origin',
346
+ status: 'active',
347
+ createdAt: new Date(0).toISOString(),
348
+ completedAt: null,
349
+ }, target.projectPath, terminal);
350
+ lines.push(`- **${dir.name}** - ${row.recommendation.reason}`);
351
+ continue;
352
+ }
353
+ }
329
354
  const phase = (await parseFrontmatterField(stateFile, 'oat_phase')) || 'unknown';
330
355
  const phaseStatus = (await parseFrontmatterField(stateFile, 'oat_phase_status')) ||
331
356
  'in_progress';
@@ -340,19 +365,29 @@ async function listAvailableProjects(repoRoot, projectsRoot) {
340
365
  }
341
366
  }
342
367
  }
343
- return {
344
- active: lines.length > 0 ? lines.join('\n') : '*(No projects found)*',
345
- decompositions: decompositions.length > 0
346
- ? decompositions.join('\n')
347
- : '*(No decompositions found)*',
348
- };
349
368
  }
350
- catch {
351
- return {
352
- active: '*(No projects directory found)*',
353
- decompositions: '*(No decompositions found)*',
354
- };
369
+ const syncedRoot = resolveScopeRoot(repoRoot, projectsRoot, 'synced');
370
+ const records = await listSyncedRecords(syncedRoot);
371
+ for (const record of records) {
372
+ if (materializedSynced.has(record.slug))
373
+ continue;
374
+ const target = buildSyncTarget(repoRoot, projectsRoot, record.slug);
375
+ const authoritative = await probeAuthoritativeCompletedRef(target, gitRunner);
376
+ const probe = authoritative ??
377
+ (record.archiveSourceRefSha
378
+ ? await probeSyncedTerminalRefs(target, record.archiveSourceRefSha, gitRunner)
379
+ : undefined);
380
+ const row = classifyLegacySyncedRecord(record, target.projectPath, probe);
381
+ lines.push(row.kind === 'recorded-absent'
382
+ ? `- **${record.slug}** - checkout absent; oat project pull ${record.slug}`
383
+ : `- **${record.slug}** - ${row.recommendation.reason}`);
355
384
  }
385
+ return {
386
+ active: lines.length > 0 ? lines.join('\n') : '*(No projects found)*',
387
+ decompositions: decompositions.length > 0
388
+ ? decompositions.join('\n')
389
+ : '*(No decompositions found)*',
390
+ };
356
391
  }
357
392
  function buildDashboardMarkdown(project, state, knowledge, staleness, nextStep, projectsList, generatedDate) {
358
393
  const timestamp = `${generatedDate}`;
@@ -453,18 +488,48 @@ export async function generateStateDashboard(options) {
453
488
  const env = options.env ?? process.env;
454
489
  const today = options.today ?? new Date().toISOString().slice(0, 10);
455
490
  const git = options.git ?? defaultGit;
491
+ const gitRunner = options.gitRunner ?? defaultGitRunner;
456
492
  const dashboardPath = join(repoRoot, '.oat', 'state.md');
457
493
  const projectsRoot = await resolveProjectsRoot(repoRoot, env);
458
494
  const hasProjects = await hasAnyProjects(join(repoRoot, projectsRoot));
459
495
  const project = await readActiveProject(repoRoot);
496
+ let terminalNextStep = null;
497
+ if (project.status === 'active' && project.path) {
498
+ const activePath = resolve(repoRoot, project.path);
499
+ const syncedRoot = resolveScopeRoot(repoRoot, projectsRoot, 'synced');
500
+ if (dirname(activePath) === syncedRoot) {
501
+ const target = buildSyncTarget(repoRoot, projectsRoot, project.name);
502
+ const terminal = await probeAuthoritativeCompletedRef(target, gitRunner);
503
+ if (terminal) {
504
+ const row = classifyLegacySyncedRecord({
505
+ schemaVersion: 1,
506
+ slug: project.name,
507
+ scope: 'synced',
508
+ ref: target.ref,
509
+ remote: 'origin',
510
+ status: 'active',
511
+ createdAt: new Date(0).toISOString(),
512
+ completedAt: null,
513
+ }, activePath, terminal);
514
+ project.status =
515
+ row.kind === 'terminal-invalid'
516
+ ? 'terminal ref mismatch'
517
+ : 'terminal cleanup pending';
518
+ terminalNextStep = {
519
+ step: 'oat-project-complete',
520
+ reason: row.recommendation.reason,
521
+ };
522
+ }
523
+ }
524
+ }
460
525
  let state = null;
461
526
  if (project.status === 'active') {
462
527
  state = await readProjectState(repoRoot, project.path);
463
528
  }
464
529
  const knowledge = await readKnowledgeStatus(repoRoot);
465
530
  const staleness = calculateStaleness(knowledge, git, repoRoot, today);
466
- const nextStep = computeNextStep(project, hasProjects, state);
467
- const projectsList = await listAvailableProjects(repoRoot, projectsRoot);
531
+ const nextStep = terminalNextStep ?? computeNextStep(project, hasProjects, state);
532
+ const projectsList = await listAvailableProjects(repoRoot, projectsRoot, gitRunner);
468
533
  const markdown = buildDashboardMarkdown(project, state, knowledge, staleness, nextStep, projectsList, today);
469
534
  await ensureDir(join(repoRoot, '.oat'));
470
535
  await writeFile(dashboardPath, markdown, 'utf8');
@@ -10,9 +10,9 @@ import { type CanonicalEntry } from '../../engine/index.js';
10
10
  import type { Manifest } from '../../manifest/index.js';
11
11
  import { type CodexExtensionPlan } from '../../providers/codex/codec/sync-extension.js';
12
12
  import { type CursorExtensionPlan } from '../../providers/cursor/codec/sync-extension.js';
13
- import { type PathMapping, type ProviderAdapter } from '../../providers/shared/index.js';
13
+ import { type PathMapping, type ProviderAdapter, type ProviderScopeContext } from '../../providers/shared/index.js';
14
14
  import type { AdoptionSource } from '../../providers/shared/adapter.types.js';
15
- import { type ConcreteScope, type Scope } from '../../shared/types.js';
15
+ import { type CanonicalScanTarget, type ConcreteScope, type Scope } from '../../shared/types.js';
16
16
  import { Command } from 'commander';
17
17
  interface StatusDependencies {
18
18
  buildCommandContext: (options: GlobalOptions) => CommandContext;
@@ -21,12 +21,17 @@ interface StatusDependencies {
21
21
  loadSyncConfig: (configPath: string) => Promise<SyncConfig>;
22
22
  resolveUserSyncConfig: (userConfigDir: string) => Promise<SyncConfig>;
23
23
  saveManifest: (manifestPath: string, manifest: Manifest) => Promise<void>;
24
- scanCanonical: (scopeRoot: string, scope: ConcreteScope) => Promise<CanonicalEntry[]>;
24
+ scanCanonical: (scopeRoot: string, scope: ConcreteScope, targets?: readonly CanonicalScanTarget[]) => Promise<CanonicalEntry[]>;
25
25
  scanBundledManagedAgents: () => Promise<CanonicalEntry[]>;
26
26
  getAdapters: () => ProviderAdapter[];
27
27
  getConfigAwareAdapters: (adapters: ProviderAdapter[], scopeRoot: string, config: SyncConfig) => Promise<{
28
28
  activeAdapters: ProviderAdapter[];
29
29
  }>;
30
+ resolveProviderScopeContext?: (input: {
31
+ scope: ConcreteScope;
32
+ scopeRoot: string;
33
+ config: SyncConfig;
34
+ }) => Promise<ProviderScopeContext>;
30
35
  getSyncMappings: (adapter: ProviderAdapter, scope: Scope) => PathMapping[];
31
36
  getAdoptionSources: (adapter: ProviderAdapter, scope: Scope) => AdoptionSource[];
32
37
  detectDrift: (entry: Manifest['entries'][number], scopeRoot: string, copyTransform?: CopyTransform) => Promise<DriftReport>;
@@ -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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"}
@@ -7,6 +7,7 @@ import { applyNativeSkillDisposition, getNativeSkillProviderDetails, isNativeSki
7
7
  import { withScopeOption } from '../shared/scope-option.js';
8
8
  import { confirmAction, selectManyWithAbort, selectWithAbort, } from '../shared/shared.prompts.js';
9
9
  import { readGlobalOptions, resolveConcreteScopes, } from '../shared/shared.utils.js';
10
+ import { packEvidenceBlock, projectRenderablePackEvidence, unavailablePackEvidence, } from '../tools/shared/format-pack-inventory.js';
10
11
  import { attributeSharedOwnerDiagnostics, hasScopedPackPlacementEvidence, inventoryPack, } from '../tools/shared/pack-inventory.js';
11
12
  import { PACK_NAMES } from '../tools/shared/pack-manifest.js';
12
13
  import { formatPackPath, formatPackPaths, updatePackRecovery, } from '../tools/shared/pack-paths.js';
@@ -17,16 +18,13 @@ import { HOOK_DRIFT_WARNING, HOOK_STRAY_INFO, scanBundledManagedAgents, scanCano
17
18
  import { resolveAssetsRoot } from '../../fs/assets.js';
18
19
  import { normalizeToPosixPath, resolveProjectRoot, resolveScopeRoot, } from '../../fs/paths.js';
19
20
  import { loadManifest, saveManifest } from '../../manifest/manager.js';
20
- import { claudeAdapter } from '../../providers/claude/index.js';
21
- import { codexAdapter } from '../../providers/codex/index.js';
22
21
  import { applyCodexProjectExtensionPlan, computeCodexProjectExtensionPlan, } from '../../providers/codex/codec/sync-extension.js';
23
- import { copilotAdapter } from '../../providers/copilot/index.js';
24
- import { cursorAdapter } from '../../providers/cursor/index.js';
25
22
  import { applyCursorProjectExtensionPlan, computeCursorProjectExtensionPlan, } from '../../providers/cursor/codec/sync-extension.js';
26
- import { geminiAdapter } from '../../providers/gemini/index.js';
27
- import { getConfigAwareAdapters, getSyncMappings, } from '../../providers/shared/index.js';
23
+ import { getConfigAwareAdapters, getProviderRegistrations, getSyncMappings, resolveProviderScopeContext, } from '../../providers/shared/index.js';
28
24
  import { getAdoptionSources } from '../../providers/shared/adapter.utils.js';
29
- import { SCOPE_CONTENT_TYPES, } from '../../shared/types.js';
25
+ import { userAgentMaterializationCoverage, } from '../../providers/shared/registry.js';
26
+ import { adviseProviderRefresh, } from '../../providers/shared/restart-adviser.js';
27
+ import {} from '../../shared/types.js';
30
28
  import { formatStatusTable } from '../../ui/output.js';
31
29
  import { Command } from 'commander';
32
30
  const DEFAULT_REMEDIATION = 'Run "oat init" to adopt stray entries.';
@@ -61,8 +59,49 @@ function unavailablePackReport(error, roots, unavailableScopes) {
61
59
  states: [],
62
60
  unavailableScopes,
63
61
  pjm: null,
62
+ evidence: packEvidenceBlock(PACK_NAMES.map((pack) => unavailablePackEvidence({
63
+ pack,
64
+ scopes: Object.keys(roots).map((key) => key === 'projectRoot' ? 'project' : 'user'),
65
+ reason: detail,
66
+ roots,
67
+ }))),
64
68
  };
65
69
  }
70
+ function collectProviderRefreshAdvice(collections) {
71
+ return collections.flatMap((collection) => {
72
+ const providerContext = collection.providerContext;
73
+ if (!providerContext)
74
+ return [];
75
+ const active = new Set(providerContext.activeProviders);
76
+ return providerContext.registrations.flatMap((registration) => {
77
+ if (!active.has(registration.adapter.name))
78
+ return [];
79
+ return registration.capabilities
80
+ .filter(({ scope, support }) => scope === collection.scope && support === 'supported')
81
+ .map((capability) => ({
82
+ scope: collection.scope,
83
+ provider: registration.adapter.name,
84
+ contentKind: capability.contentKind,
85
+ visibility: adviseProviderRefresh({
86
+ policy: capability.catalogRefresh,
87
+ materialization: 'unknown',
88
+ observation: {
89
+ state: 'not-reported',
90
+ reference: 'oat status inspects managed files but does not query the active provider catalog',
91
+ },
92
+ }),
93
+ }));
94
+ });
95
+ });
96
+ }
97
+ function formatProviderRefreshAdvice(advice) {
98
+ if (advice.length === 0)
99
+ return null;
100
+ return [
101
+ 'Provider catalog visibility:',
102
+ ...advice.map(({ scope, provider, contentKind, visibility }) => ` [${scope}] ${provider}/${contentKind}: ${visibility.state} (${visibility.policy.state})`),
103
+ ].join('\n');
104
+ }
66
105
  const DEFAULT_DEPENDENCIES = {
67
106
  buildCommandContext,
68
107
  async resolveScopeRoot(scope, context) {
@@ -80,15 +119,10 @@ const DEFAULT_DEPENDENCIES = {
80
119
  scanCanonical,
81
120
  scanBundledManagedAgents,
82
121
  getAdapters() {
83
- return [
84
- claudeAdapter,
85
- cursorAdapter,
86
- codexAdapter,
87
- copilotAdapter,
88
- geminiAdapter,
89
- ];
122
+ return getProviderRegistrations().map(({ adapter }) => adapter);
90
123
  },
91
124
  getConfigAwareAdapters,
125
+ resolveProviderScopeContext,
92
126
  getSyncMappings,
93
127
  getAdoptionSources,
94
128
  detectDrift,
@@ -120,9 +154,6 @@ function canonicalInsideMapping(canonicalPath, mappingCanonicalDir) {
120
154
  return (normalizedCanonicalPath === normalizedCanonicalDir ||
121
155
  normalizedCanonicalPath.startsWith(`${normalizedCanonicalDir}/`));
122
156
  }
123
- function contentTypeAllowed(contentType, scope) {
124
- return SCOPE_CONTENT_TYPES[scope].includes(contentType);
125
- }
126
157
  function summarizeReports(reports) {
127
158
  const summary = {
128
159
  total: reports.length,
@@ -243,7 +274,7 @@ function shouldReportPjmAdoption(adoption, states) {
243
274
  const pjm = states.find(({ pack }) => pack === 'project-management');
244
275
  return (pjm?.scopes ?? []).some(({ scope }) => scope === 'project');
245
276
  }
246
- async function collectPackReport(scopeRoots, unavailableScopes, userManagedRoleMaterialization, dependencies) {
277
+ async function collectPackReport(scopeRoots, unavailableScopes, userAgentCoverage, dependencies) {
247
278
  const roots = {
248
279
  ...(scopeRoots.has('project')
249
280
  ? { projectRoot: scopeRoots.get('project') }
@@ -256,6 +287,7 @@ async function collectPackReport(scopeRoots, unavailableScopes, userManagedRoleM
256
287
  states: [],
257
288
  unavailableScopes,
258
289
  pjm: null,
290
+ evidence: packEvidenceBlock([]),
259
291
  };
260
292
  }
261
293
  let inventories;
@@ -266,9 +298,23 @@ async function collectPackReport(scopeRoots, unavailableScopes, userManagedRoleM
266
298
  assetsRoot,
267
299
  ...roots,
268
300
  ...(scopeRoots.has('user')
269
- ? { userManagedRoleMaterialization }
301
+ ? {
302
+ userManagedRoleMaterialization: userAgentCoverage !== 'none',
303
+ }
270
304
  : {}),
271
305
  }))));
306
+ if (userAgentCoverage === 'all') {
307
+ inventories = inventories.map((inventory) => ({
308
+ ...inventory,
309
+ scopes: inventory.scopes.map((scoped) => scoped.scope === 'user'
310
+ ? {
311
+ ...scoped,
312
+ diagnostics: scoped.diagnostics.filter(({ code }) => code !== 'user-agent-unmaterialized'),
313
+ }
314
+ : scoped),
315
+ diagnostics: inventory.diagnostics.filter(({ code }) => code !== 'user-agent-unmaterialized'),
316
+ }));
317
+ }
272
318
  }
273
319
  catch (error) {
274
320
  return unavailablePackReport(error, roots, unavailableScopes);
@@ -276,6 +322,7 @@ async function collectPackReport(scopeRoots, unavailableScopes, userManagedRoleM
276
322
  const states = inventories
277
323
  .map((inventory) => toStatusPackState(inventory, roots))
278
324
  .filter((state) => state !== null);
325
+ const evidence = packEvidenceBlock(inventories.map((canonical) => projectRenderablePackEvidence(canonical, roots)));
279
326
  const projectRoot = scopeRoots.get('project');
280
327
  if (!projectRoot) {
281
328
  return {
@@ -283,6 +330,7 @@ async function collectPackReport(scopeRoots, unavailableScopes, userManagedRoleM
283
330
  states,
284
331
  unavailableScopes,
285
332
  pjm: null,
333
+ evidence,
286
334
  };
287
335
  }
288
336
  const adoption = await dependencies.resolvePjmAdoption({
@@ -301,6 +349,7 @@ async function collectPackReport(scopeRoots, unavailableScopes, userManagedRoleM
301
349
  repoRoot: formatPackPath(adoption.repoRoot, roots),
302
350
  recovery: adoption.recovery,
303
351
  },
352
+ evidence,
304
353
  };
305
354
  }
306
355
  function describePackScope(state) {
@@ -375,29 +424,82 @@ async function collectScopeReports(scope, context, dependencies) {
375
424
  const manifestPath = join(scopeRoot, '.oat', 'sync', 'manifest.json');
376
425
  const syncConfigPath = join(scopeRoot, '.oat', 'sync', 'config.json');
377
426
  const userConfigDir = join(context.home, '.oat');
378
- const [manifest, canonicalEntries, syncConfig, userSyncConfig] = await Promise.all([
427
+ const [manifest, syncConfig, userSyncConfig] = await Promise.all([
379
428
  dependencies.loadManifest(manifestPath),
380
- dependencies.scanCanonical(scopeRoot, scope),
381
429
  dependencies.loadSyncConfig(syncConfigPath),
382
430
  dependencies.resolveUserSyncConfig(userConfigDir),
383
431
  ]);
384
- const adapters = dependencies.getAdapters();
385
- const { activeAdapters } = await dependencies.getConfigAwareAdapters(adapters, scopeRoot, scope === 'user' ? userSyncConfig : syncConfig);
432
+ const effectiveConfig = scope === 'user' ? userSyncConfig : syncConfig;
433
+ const providerContext = dependencies.resolveProviderScopeContext
434
+ ? await dependencies.resolveProviderScopeContext({
435
+ scope,
436
+ scopeRoot,
437
+ config: effectiveConfig,
438
+ })
439
+ : null;
440
+ const adapters = providerContext
441
+ ? providerContext.registrations.map(({ adapter }) => adapter)
442
+ : dependencies.getAdapters();
443
+ const activeAdapters = providerContext
444
+ ? adapters.filter(({ name }) => providerContext.activeProviders.includes(name))
445
+ : await dependencies
446
+ .getConfigAwareAdapters(adapters, scopeRoot, effectiveConfig)
447
+ .then((resolution) => resolution.activeAdapters);
448
+ const activeAdapterNames = activeAdapters.map(({ name }) => name);
449
+ const knownRegistrations = getProviderRegistrations().filter(({ adapter }) => activeAdapterNames.includes(adapter.name));
450
+ const coverageRegistrations = providerContext?.registrations ?? knownRegistrations;
451
+ const mappingScanTargets = activeAdapters
452
+ .flatMap((adapter) => dependencies.getSyncMappings(adapter, scope))
453
+ .map(({ contentType, canonicalDir }) => ({ contentType, canonicalDir }));
454
+ const capabilityScanTargets = coverageRegistrations
455
+ .filter(({ adapter }) => activeAdapterNames.includes(adapter.name))
456
+ .flatMap(({ capabilities }) => capabilities
457
+ .filter((capability) => capability.scope === scope &&
458
+ capability.support === 'supported' &&
459
+ capability.contentKind !== 'directory')
460
+ .map((capability) => ({
461
+ contentType: capability.contentKind,
462
+ canonicalDir: `.agents/${capability.contentKind}s`,
463
+ })));
464
+ const scanTargets = [...mappingScanTargets, ...capabilityScanTargets].filter((target, index, targets) => targets.findIndex((candidate) => candidate.contentType === target.contentType &&
465
+ candidate.canonicalDir === target.canonicalDir) === index);
466
+ const canonicalEntries = await dependencies.scanCanonical(scopeRoot, scope, scanTargets);
467
+ let agentCoverage = userAgentMaterializationCoverage({
468
+ registrations: coverageRegistrations,
469
+ activeProviders: activeAdapterNames,
470
+ });
471
+ if (scope === 'user' && agentCoverage !== 'all') {
472
+ const activeAgentMappings = activeAdapters.flatMap((adapter) => dependencies
473
+ .getSyncMappings(adapter, scope)
474
+ .filter(({ contentType }) => contentType === 'agent'));
475
+ if (activeAgentMappings.some(({ nativeRead }) => !nativeRead)) {
476
+ agentCoverage = 'all';
477
+ }
478
+ else if (activeAgentMappings.length > 0 && agentCoverage === 'none') {
479
+ agentCoverage = 'bundled';
480
+ }
481
+ }
386
482
  const reports = [];
387
483
  const strayCandidates = [];
388
484
  const trackedCanonicalByProvider = new Set(manifest.entries.map((entry) => `${entry.provider}|${normalizeToPosixPath(entry.canonicalPath)}`));
389
485
  const activeProviderNames = new Set(activeAdapters.map((adapter) => adapter.name));
486
+ const activeExtensionProviders = new Set(providerContext
487
+ ? providerContext.registrations
488
+ .filter(({ adapter }) => activeProviderNames.has(adapter.name))
489
+ .flatMap(({ extensions }) => extensions.map(({ provider }) => provider))
490
+ : [...activeProviderNames]);
390
491
  const extensionCanonicalEntries = scope === 'user' &&
391
- (activeProviderNames.has('codex') || activeProviderNames.has('cursor'))
492
+ (activeExtensionProviders.has('codex') ||
493
+ activeExtensionProviders.has('cursor'))
392
494
  ? [
393
495
  ...canonicalEntries,
394
496
  ...(await dependencies.scanBundledManagedAgents()),
395
497
  ]
396
498
  : canonicalEntries;
397
- const codexExtensionPlan = activeProviderNames.has('codex')
499
+ const codexExtensionPlan = activeExtensionProviders.has('codex')
398
500
  ? await dependencies.computeCodexProjectExtensionPlan(scopeRoot, extensionCanonicalEntries, undefined, { userConfigDir })
399
501
  : undefined;
400
- const cursorExtensionPlan = activeProviderNames.has('cursor')
502
+ const cursorExtensionPlan = activeExtensionProviders.has('cursor')
401
503
  ? await dependencies.computeCursorProjectExtensionPlan(scopeRoot, extensionCanonicalEntries, undefined, { userConfigDir })
402
504
  : undefined;
403
505
  const materializationPlans = [
@@ -429,9 +531,6 @@ async function collectScopeReports(scope, context, dependencies) {
429
531
  if (!mappingContentTypes.has(entry.contentType)) {
430
532
  continue;
431
533
  }
432
- if (!contentTypeAllowed(entry.contentType, scope)) {
433
- continue;
434
- }
435
534
  const matchedMapping = mappings.find((mapping) => mapping.contentType === entry.contentType &&
436
535
  entryInsideMapping(entry.providerPath, mapping.providerDir));
437
536
  if (!matchedMapping) {
@@ -549,7 +648,9 @@ async function collectScopeReports(scope, context, dependencies) {
549
648
  manifest,
550
649
  reports: filtered.reports,
551
650
  strayCandidates: filtered.candidates,
552
- activeAdapterNames: activeAdapters.map((adapter) => adapter.name),
651
+ activeAdapterNames,
652
+ userAgentMaterializationCoverage: scope === 'user' ? agentCoverage : 'none',
653
+ providerContext,
553
654
  };
554
655
  }
555
656
  async function runStatusCommand(context, dependencies, options = {}) {
@@ -577,6 +678,7 @@ async function runStatusCommand(context, dependencies, options = {}) {
577
678
  scopeRoots.set(scope, scopeReportCollection.scopeRoot);
578
679
  }
579
680
  const summary = summarizeReports(reports);
681
+ const providerRefreshAdvice = collectProviderRefreshAdvice(scopeCollections);
580
682
  const hasIssues = summary.total > 0 && summary.inSync !== summary.total;
581
683
  if (options.hook) {
582
684
  if (summary.drifted > 0 || summary.missing > 0) {
@@ -592,14 +694,19 @@ async function runStatusCommand(context, dependencies, options = {}) {
592
694
  }
593
695
  return;
594
696
  }
595
- const packReport = await collectPackReport(scopeRoots, unavailableScopes, scopeCollections.some(({ scope, activeAdapterNames }) => scope === 'user' &&
596
- activeAdapterNames.some((name) => name === 'codex' || name === 'cursor')), dependencies);
697
+ const packReport = await collectPackReport(scopeRoots, unavailableScopes, scopeCollections.some((collection) => collection.userAgentMaterializationCoverage === 'all')
698
+ ? 'all'
699
+ : scopeCollections.some((collection) => collection.userAgentMaterializationCoverage === 'bundled')
700
+ ? 'bundled'
701
+ : 'none', dependencies);
597
702
  if (context.json) {
598
703
  const payload = {
599
704
  scope: context.scope,
600
705
  reports,
601
706
  summary,
602
707
  packs: packReport,
708
+ packEvidence: packReport.evidence,
709
+ providerRefreshAdvice,
603
710
  };
604
711
  if (!context.interactive && summary.stray > 0) {
605
712
  payload.remediation = DEFAULT_REMEDIATION;
@@ -612,6 +719,9 @@ async function runStatusCommand(context, dependencies, options = {}) {
612
719
  if (packSummary) {
613
720
  context.logger.info(packSummary);
614
721
  }
722
+ const providerSummary = formatProviderRefreshAdvice(providerRefreshAdvice);
723
+ if (providerSummary)
724
+ context.logger.info(providerSummary);
615
725
  }
616
726
  if (summary.stray > 0) {
617
727
  if (context.interactive) {
@@ -758,6 +868,11 @@ export function createStatusCommand(overrides = {}) {
758
868
  ...DEFAULT_DEPENDENCIES,
759
869
  ...overrides,
760
870
  };
871
+ if (overrides.resolveProviderScopeContext === undefined &&
872
+ (overrides.getAdapters !== undefined ||
873
+ overrides.getConfigAwareAdapters !== undefined)) {
874
+ dependencies.resolveProviderScopeContext = undefined;
875
+ }
761
876
  return withScopeOption(new Command('status'))
762
877
  .description('Report provider sync and drift status')
763
878
  .option('--hook', 'Emit a minimal pre-commit message: warn on managed drift, info on strays')
@@ -1 +1 @@
1
- {"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/apply.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,KAAK,EACV,aAAa,EACb,uBAAuB,EAExB,MAAM,cAAc,CAAC;AAyEtB,wBAAsB,YAAY,CAChC,OAAO,EAAE,cAAc,EACvB,UAAU,EAAE,aAAa,EAAE,EAC3B,YAAY,EAAE,uBAAuB,GACpC,OAAO,CAAC,IAAI,CAAC,CAgHf"}
1
+ {"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/apply.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAiB3D,OAAO,KAAK,EACV,aAAa,EACb,uBAAuB,EAExB,MAAM,cAAc,CAAC;AA2TtB,wBAAsB,YAAY,CAChC,OAAO,EAAE,cAAc,EACvB,UAAU,EAAE,aAAa,EAAE,EAC3B,YAAY,EAAE,uBAAuB,GACpC,OAAO,CAAC,IAAI,CAAC,CA4Kf"}