@open-agent-toolkit/cli 0.2.36 → 0.2.38

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 (183) hide show
  1. package/assets/bundle-metadata.json +1 -1
  2. package/assets/docs/cli-utilities/backlog-lifecycle.md +18 -0
  3. package/assets/docs/cli-utilities/bootstrap.md +6 -3
  4. package/assets/docs/cli-utilities/config-and-local-state.md +26 -12
  5. package/assets/docs/cli-utilities/configuration.md +36 -13
  6. package/assets/docs/cli-utilities/tool-packs.md +423 -51
  7. package/assets/docs/provider-sync/scope-and-surface.md +4 -1
  8. package/assets/docs/reference/cli-reference.md +5 -3
  9. package/assets/docs/reference/file-locations.md +28 -4
  10. package/assets/docs/reference/troubleshooting.md +132 -2
  11. package/assets/docs/workflows/projects/lifecycle.md +21 -2
  12. package/assets/public-package-versions.json +4 -4
  13. package/assets/scripts/generate-oat-state.sh +441 -0
  14. package/assets/scripts/generate-thin-index.sh +200 -0
  15. package/assets/skills/oat-agent-instructions-analyze/SKILL.md +10 -5
  16. package/assets/skills/oat-agent-instructions-apply/SKILL.md +30 -5
  17. package/assets/skills/oat-brainstorm/SKILL.md +34 -8
  18. package/assets/skills/oat-brainstorm/references/destinations.md +6 -1
  19. package/assets/skills/oat-docs-analyze/SKILL.md +9 -4
  20. package/assets/skills/oat-docs-apply/SKILL.md +6 -3
  21. package/assets/skills/oat-pjm-add-backlog-item/SKILL.md +14 -1
  22. package/assets/skills/oat-pjm-decision/SKILL.md +22 -10
  23. package/assets/skills/oat-pjm-review-backlog/SKILL.md +20 -3
  24. package/assets/skills/oat-pjm-update-repo-reference/SKILL.md +20 -10
  25. package/assets/skills/oat-project-autonomous/references/gate-inventory.md +1 -1
  26. package/assets/skills/oat-project-document/SKILL.md +21 -3
  27. package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +1 -1
  28. package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +1 -1
  29. package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +1 -1
  30. package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +1 -1
  31. package/assets/skills/oat-project-summary/SKILL.md +23 -11
  32. package/assets/skills/oat-repo-knowledge-index/SKILL.md +6 -3
  33. package/dist/commands/backlog/index.d.ts +2 -0
  34. package/dist/commands/backlog/index.d.ts.map +1 -1
  35. package/dist/commands/backlog/index.js +67 -23
  36. package/dist/commands/backlog/new.d.ts +3 -0
  37. package/dist/commands/backlog/new.d.ts.map +1 -1
  38. package/dist/commands/backlog/new.js +8 -21
  39. package/dist/commands/decision/agents-guidance.d.ts.map +1 -1
  40. package/dist/commands/decision/agents-guidance.js +2 -1
  41. package/dist/commands/decision/index.d.ts +2 -0
  42. package/dist/commands/decision/index.d.ts.map +1 -1
  43. package/dist/commands/decision/index.js +19 -3
  44. package/dist/commands/decision/new.d.ts +4 -0
  45. package/dist/commands/decision/new.d.ts.map +1 -1
  46. package/dist/commands/decision/new.js +11 -30
  47. package/dist/commands/doctor/index.d.ts +4 -0
  48. package/dist/commands/doctor/index.d.ts.map +1 -1
  49. package/dist/commands/doctor/index.js +254 -9
  50. package/dist/commands/init/tools/brainstorm/index.d.ts.map +1 -1
  51. package/dist/commands/init/tools/brainstorm/index.js +20 -6
  52. package/dist/commands/init/tools/docs/index.d.ts.map +1 -1
  53. package/dist/commands/init/tools/docs/index.js +4 -1
  54. package/dist/commands/init/tools/ideas/index.d.ts.map +1 -1
  55. package/dist/commands/init/tools/ideas/index.js +4 -1
  56. package/dist/commands/init/tools/index.d.ts +11 -2
  57. package/dist/commands/init/tools/index.d.ts.map +1 -1
  58. package/dist/commands/init/tools/index.js +459 -351
  59. package/dist/commands/init/tools/install-state.d.ts +2 -0
  60. package/dist/commands/init/tools/install-state.d.ts.map +1 -1
  61. package/dist/commands/init/tools/install-state.js +11 -0
  62. package/dist/commands/init/tools/project-management/agents-guidance.d.ts.map +1 -1
  63. package/dist/commands/init/tools/project-management/agents-guidance.js +3 -1
  64. package/dist/commands/init/tools/project-management/index.d.ts +1 -0
  65. package/dist/commands/init/tools/project-management/index.d.ts.map +1 -1
  66. package/dist/commands/init/tools/project-management/index.js +24 -55
  67. package/dist/commands/init/tools/project-management/install-project-management.d.ts +4 -0
  68. package/dist/commands/init/tools/project-management/install-project-management.d.ts.map +1 -1
  69. package/dist/commands/init/tools/project-management/install-project-management.js +4 -1
  70. package/dist/commands/init/tools/research/index.d.ts.map +1 -1
  71. package/dist/commands/init/tools/research/index.js +4 -1
  72. package/dist/commands/init/tools/shared/copy-helpers.d.ts.map +1 -1
  73. package/dist/commands/init/tools/shared/copy-helpers.js +10 -0
  74. package/dist/commands/init/tools/shared/skill-manifest.d.ts +15 -15
  75. package/dist/commands/init/tools/shared/skill-manifest.d.ts.map +1 -1
  76. package/dist/commands/init/tools/shared/skill-manifest.js +17 -122
  77. package/dist/commands/init/tools/utility/index.d.ts.map +1 -1
  78. package/dist/commands/init/tools/utility/index.js +4 -1
  79. package/dist/commands/init/tools/workflows/index.d.ts.map +1 -1
  80. package/dist/commands/init/tools/workflows/index.js +4 -1
  81. package/dist/commands/init/tools/workflows/install-workflows.d.ts.map +1 -1
  82. package/dist/commands/init/tools/workflows/install-workflows.js +2 -4
  83. package/dist/commands/pjm/adoption.d.ts +12 -0
  84. package/dist/commands/pjm/adoption.d.ts.map +1 -0
  85. package/dist/commands/pjm/adoption.js +47 -0
  86. package/dist/commands/pjm/doctor.d.ts +3 -2
  87. package/dist/commands/pjm/doctor.d.ts.map +1 -1
  88. package/dist/commands/pjm/doctor.js +28 -13
  89. package/dist/commands/pjm/index.d.ts +2 -0
  90. package/dist/commands/pjm/index.d.ts.map +1 -1
  91. package/dist/commands/pjm/index.js +11 -3
  92. package/dist/commands/pjm/init.d.ts +3 -0
  93. package/dist/commands/pjm/init.d.ts.map +1 -1
  94. package/dist/commands/pjm/init.js +37 -32
  95. package/dist/commands/pjm/migrate.d.ts +1 -0
  96. package/dist/commands/pjm/migrate.d.ts.map +1 -1
  97. package/dist/commands/pjm/migrate.js +1 -0
  98. package/dist/commands/pjm/template-source.d.ts +14 -0
  99. package/dist/commands/pjm/template-source.d.ts.map +1 -0
  100. package/dist/commands/pjm/template-source.js +56 -0
  101. package/dist/commands/remove/skills/remove-skills.d.ts.map +1 -1
  102. package/dist/commands/remove/skills/remove-skills.js +10 -19
  103. package/dist/commands/status/index.d.ts +5 -0
  104. package/dist/commands/status/index.d.ts.map +1 -1
  105. package/dist/commands/status/index.js +203 -2
  106. package/dist/commands/sync/index.d.ts.map +1 -1
  107. package/dist/commands/sync/index.js +40 -7
  108. package/dist/commands/sync/sync.types.d.ts +4 -0
  109. package/dist/commands/sync/sync.types.d.ts.map +1 -1
  110. package/dist/commands/tools/has/has-pack.d.ts +11 -2
  111. package/dist/commands/tools/has/has-pack.d.ts.map +1 -1
  112. package/dist/commands/tools/has/has-pack.js +33 -20
  113. package/dist/commands/tools/index.d.ts.map +1 -1
  114. package/dist/commands/tools/index.js +3 -1
  115. package/dist/commands/tools/info/info-tool.d.ts +3 -0
  116. package/dist/commands/tools/info/info-tool.d.ts.map +1 -1
  117. package/dist/commands/tools/info/info-tool.js +29 -4
  118. package/dist/commands/tools/list/list-tools.d.ts +3 -0
  119. package/dist/commands/tools/list/list-tools.d.ts.map +1 -1
  120. package/dist/commands/tools/list/list-tools.js +31 -4
  121. package/dist/commands/tools/migrate/index.d.ts +26 -0
  122. package/dist/commands/tools/migrate/index.d.ts.map +1 -0
  123. package/dist/commands/tools/migrate/index.js +312 -0
  124. package/dist/commands/tools/migrate/migrate-pack.d.ts +81 -0
  125. package/dist/commands/tools/migrate/migrate-pack.d.ts.map +1 -0
  126. package/dist/commands/tools/migrate/migrate-pack.js +324 -0
  127. package/dist/commands/tools/outdated/outdated-tools.d.ts +11 -0
  128. package/dist/commands/tools/outdated/outdated-tools.d.ts.map +1 -1
  129. package/dist/commands/tools/outdated/outdated-tools.js +33 -5
  130. package/dist/commands/tools/remove/index.d.ts.map +1 -1
  131. package/dist/commands/tools/remove/index.js +73 -20
  132. package/dist/commands/tools/remove/remove-tools.d.ts +28 -0
  133. package/dist/commands/tools/remove/remove-tools.d.ts.map +1 -1
  134. package/dist/commands/tools/remove/remove-tools.js +156 -26
  135. package/dist/commands/tools/shared/apply-pack-reconcile.d.ts +41 -0
  136. package/dist/commands/tools/shared/apply-pack-reconcile.d.ts.map +1 -0
  137. package/dist/commands/tools/shared/apply-pack-reconcile.js +126 -0
  138. package/dist/commands/tools/shared/auto-sync.d.ts +5 -2
  139. package/dist/commands/tools/shared/auto-sync.d.ts.map +1 -1
  140. package/dist/commands/tools/shared/auto-sync.js +1 -0
  141. package/dist/commands/tools/shared/content-digest.d.ts +3 -0
  142. package/dist/commands/tools/shared/content-digest.d.ts.map +1 -0
  143. package/dist/commands/tools/shared/content-digest.js +57 -0
  144. package/dist/commands/tools/shared/format-pack-inventory.d.ts +3 -0
  145. package/dist/commands/tools/shared/format-pack-inventory.d.ts.map +1 -0
  146. package/dist/commands/tools/shared/format-pack-inventory.js +21 -0
  147. package/dist/commands/tools/shared/install-sync-context.d.ts.map +1 -1
  148. package/dist/commands/tools/shared/install-sync-context.js +2 -25
  149. package/dist/commands/tools/shared/pack-inventory.d.ts +46 -0
  150. package/dist/commands/tools/shared/pack-inventory.d.ts.map +1 -0
  151. package/dist/commands/tools/shared/pack-inventory.js +207 -0
  152. package/dist/commands/tools/shared/pack-lifecycle.d.ts +34 -0
  153. package/dist/commands/tools/shared/pack-lifecycle.d.ts.map +1 -0
  154. package/dist/commands/tools/shared/pack-lifecycle.js +67 -0
  155. package/dist/commands/tools/shared/pack-manifest.d.ts +11 -0
  156. package/dist/commands/tools/shared/pack-manifest.d.ts.map +1 -0
  157. package/dist/commands/tools/shared/pack-manifest.js +384 -0
  158. package/dist/commands/tools/shared/pack-paths.d.ts +21 -0
  159. package/dist/commands/tools/shared/pack-paths.d.ts.map +1 -0
  160. package/dist/commands/tools/shared/pack-paths.js +35 -0
  161. package/dist/commands/tools/shared/pack-reconcile.d.ts +64 -0
  162. package/dist/commands/tools/shared/pack-reconcile.d.ts.map +1 -0
  163. package/dist/commands/tools/shared/pack-reconcile.js +158 -0
  164. package/dist/commands/tools/shared/project-tools-config.d.ts.map +1 -1
  165. package/dist/commands/tools/shared/project-tools-config.js +12 -38
  166. package/dist/commands/tools/shared/scan-tools.js +2 -2
  167. package/dist/commands/tools/shared/scoped-pack-intent.d.ts +34 -0
  168. package/dist/commands/tools/shared/scoped-pack-intent.d.ts.map +1 -0
  169. package/dist/commands/tools/shared/scoped-pack-intent.js +116 -0
  170. package/dist/commands/tools/shared/types.d.ts +22 -0
  171. package/dist/commands/tools/shared/types.d.ts.map +1 -1
  172. package/dist/commands/tools/update/index.d.ts.map +1 -1
  173. package/dist/commands/tools/update/index.js +30 -5
  174. package/dist/commands/tools/update/update-tools.d.ts +9 -1
  175. package/dist/commands/tools/update/update-tools.d.ts.map +1 -1
  176. package/dist/commands/tools/update/update-tools.js +176 -64
  177. package/dist/config/oat-config.d.ts +6 -0
  178. package/dist/config/oat-config.d.ts.map +1 -1
  179. package/dist/config/oat-config.js +49 -20
  180. package/dist/fs/paths.d.ts +12 -0
  181. package/dist/fs/paths.d.ts.map +1 -1
  182. package/dist/fs/paths.js +87 -1
  183. package/package.json +2 -2
@@ -1,15 +1,20 @@
1
1
  import { basename, join, relative } from 'node:path';
2
2
  import { buildCommandContext, } from '../../app/command-context.js';
3
+ import { resolvePjmAdoption, } from '../pjm/adoption.js';
3
4
  import { adoptStrayToCanonical, isAdoptionConflictError, isAdoptionSourceUnavailableError, } from '../shared/adopt-stray.js';
4
5
  import { detectCodexRoleStrays, filterMaterializationManagedStrays, regenerateCodexAfterAdoption, } from '../shared/codex-strays.js';
5
6
  import { applyNativeSkillDisposition, getNativeSkillProviderDetails, isNativeSkillCandidate, } from '../shared/native-skill-disposition.js';
6
7
  import { withScopeOption } from '../shared/scope-option.js';
7
8
  import { confirmAction, selectManyWithAbort, selectWithAbort, } from '../shared/shared.prompts.js';
8
9
  import { readGlobalOptions, resolveConcreteScopes, } from '../shared/shared.utils.js';
10
+ import { hasScopedPackPlacementEvidence, inventoryPack, } from '../tools/shared/pack-inventory.js';
11
+ import { PACK_NAMES } from '../tools/shared/pack-manifest.js';
12
+ import { formatPackPath, formatPackPaths, updatePackRecovery, } from '../tools/shared/pack-paths.js';
9
13
  import { DEFAULT_SYNC_CONFIG, loadSyncConfig, } from '../../config/index.js';
10
14
  import { resolveUserSyncConfig } from '../../config/user-sync-config.js';
11
15
  import { detectDrift, detectStrays, filterKnownStrays, } from '../../drift/index.js';
12
16
  import { HOOK_DRIFT_WARNING, HOOK_STRAY_INFO, scanBundledManagedAgents, scanCanonical, } from '../../engine/index.js';
17
+ import { resolveAssetsRoot } from '../../fs/assets.js';
13
18
  import { normalizeToPosixPath, resolveProjectRoot, resolveScopeRoot, } from '../../fs/paths.js';
14
19
  import { loadManifest, saveManifest } from '../../manifest/manager.js';
15
20
  import { claudeAdapter } from '../../providers/claude/index.js';
@@ -66,6 +71,9 @@ const DEFAULT_DEPENDENCIES = {
66
71
  adoptStray: adoptStrayDefault,
67
72
  applyNativeSkillDisposition,
68
73
  formatStatusTable,
74
+ resolveAssetsRoot,
75
+ inventoryPack,
76
+ resolvePjmAdoption,
69
77
  };
70
78
  function entryInsideMapping(entryProviderPath, mappingProviderDir) {
71
79
  const normalizedEntryPath = normalizeToPosixPath(entryProviderPath);
@@ -125,6 +133,177 @@ function formatPathForScope(scope, providerPath) {
125
133
  function formatStrayChoiceLabel(scope, providerPath, provider) {
126
134
  return `[${scope}] ${basename(providerPath)} (${provider})`;
127
135
  }
136
+ function packDiagnosticRecovery(pack, diagnostic, scope) {
137
+ if (diagnostic.code === 'duplicate-scope') {
138
+ return `oat tools migrate --pack ${pack} --from project --to user`;
139
+ }
140
+ if (diagnostic.code === 'legacy-false-conflict' && scope) {
141
+ return updatePackRecovery(pack, scope);
142
+ }
143
+ return null;
144
+ }
145
+ function toStatusPackDiagnostic(pack, diagnostic, scope, roots) {
146
+ return {
147
+ code: diagnostic.code,
148
+ message: diagnostic.message,
149
+ paths: diagnostic.paths.map((path) => formatPackPath(path, roots)),
150
+ recovery: packDiagnosticRecovery(pack, diagnostic, scope),
151
+ };
152
+ }
153
+ function toStatusPackScopeState(pack, scoped, roots) {
154
+ const { scope } = scoped;
155
+ const missing = scoped.assets.filter((asset) => asset.definition.ownership[scope] === 'managed' &&
156
+ asset.status === 'missing');
157
+ const stale = scoped.assets.filter(({ status }) => status === 'outdated');
158
+ const newer = scoped.assets.filter(({ status }) => status === 'newer');
159
+ const retainedOverrides = scoped.assets.filter((asset) => asset.definition.ownership[scope] === 'seed-if-missing' &&
160
+ asset.status === 'present');
161
+ const needsRepair = scoped.completeness !== 'complete' || stale.length > 0;
162
+ return {
163
+ scope,
164
+ intent: scoped.intent.source,
165
+ completeness: scoped.completeness,
166
+ stale: stale.length,
167
+ newer: newer.length,
168
+ retainedOverrides: retainedOverrides.length,
169
+ missing: missing.map(({ path }) => formatPackPath(path, roots)),
170
+ diagnostics: scoped.diagnostics.map((diagnostic) => toStatusPackDiagnostic(pack, diagnostic, scope, roots)),
171
+ recovery: needsRepair ? updatePackRecovery(pack, scope) : null,
172
+ };
173
+ }
174
+ /**
175
+ * Only scope-level diagnostics carry a known scope. Pack-level diagnostics
176
+ * (cross-scope duplication, shared-owner observations) are reported once on
177
+ * the pack itself so no diagnostic is silently dropped or double counted.
178
+ */
179
+ function collectPackLevelDiagnostics(inventory, roots) {
180
+ const scopedMessages = new Set(inventory.scopes.flatMap(({ diagnostics }) => diagnostics.map(({ message }) => message)));
181
+ return inventory.diagnostics
182
+ .filter(({ message }) => !scopedMessages.has(message))
183
+ .map((diagnostic) => toStatusPackDiagnostic(inventory.pack, diagnostic, null, roots));
184
+ }
185
+ function toStatusPackState(inventory, roots) {
186
+ const scopes = inventory.scopes.filter(hasScopedPackPlacementEvidence);
187
+ const diagnostics = collectPackLevelDiagnostics(inventory, roots);
188
+ if (scopes.length === 0 && diagnostics.length === 0) {
189
+ return null;
190
+ }
191
+ return {
192
+ pack: inventory.pack,
193
+ placement: inventory.placement,
194
+ scopes: scopes.map((scoped) => toStatusPackScopeState(inventory.pack, scoped, roots)),
195
+ diagnostics,
196
+ };
197
+ }
198
+ /**
199
+ * Repository PJM adoption is only actionable when this repository shows PJM
200
+ * intent. User-scope PJM capability is now the default, so an unadopted
201
+ * repository with no project-scope PJM evidence is normal and stays silent.
202
+ */
203
+ function shouldReportPjmAdoption(adoption, states) {
204
+ if (adoption.state === 'partial-initialization') {
205
+ return true;
206
+ }
207
+ if (adoption.state !== 'none') {
208
+ return false;
209
+ }
210
+ const pjm = states.find(({ pack }) => pack === 'project-management');
211
+ return (pjm?.scopes ?? []).some(({ scope }) => scope === 'project');
212
+ }
213
+ async function collectPackReport(scopeRoots, unavailableScopes, dependencies) {
214
+ const roots = {
215
+ ...(scopeRoots.has('project')
216
+ ? { projectRoot: scopeRoots.get('project') }
217
+ : {}),
218
+ ...(scopeRoots.has('user') ? { userRoot: scopeRoots.get('user') } : {}),
219
+ };
220
+ if (scopeRoots.size === 0) {
221
+ return { states: [], unavailableScopes, pjm: null };
222
+ }
223
+ const assetsRoot = await dependencies.resolveAssetsRoot();
224
+ const inventories = await Promise.all(PACK_NAMES.map((pack) => dependencies.inventoryPack({ pack, assetsRoot, ...roots })));
225
+ const states = inventories
226
+ .map((inventory) => toStatusPackState(inventory, roots))
227
+ .filter((state) => state !== null);
228
+ const projectRoot = scopeRoots.get('project');
229
+ if (!projectRoot) {
230
+ return { states, unavailableScopes, pjm: null };
231
+ }
232
+ const adoption = await dependencies.resolvePjmAdoption({
233
+ projectRoot,
234
+ repoRoot: join(projectRoot, '.oat', 'repo'),
235
+ });
236
+ return {
237
+ states,
238
+ unavailableScopes,
239
+ pjm: {
240
+ state: adoption.state,
241
+ // Every other path in this payload is redacted through `formatPackPath`;
242
+ // the PJM repo root follows the same contract rather than emitting a raw
243
+ // absolute path.
244
+ repoRoot: formatPackPath(adoption.repoRoot, roots),
245
+ recovery: adoption.recovery,
246
+ },
247
+ };
248
+ }
249
+ function describePackScope(state) {
250
+ const details = [state.completeness];
251
+ if (state.missing.length > 0) {
252
+ details.push(`${state.missing.length} missing`);
253
+ }
254
+ if (state.stale > 0)
255
+ details.push(`${state.stale} stale`);
256
+ if (state.newer > 0)
257
+ details.push(`${state.newer} newer`);
258
+ if (state.retainedOverrides > 0) {
259
+ details.push(`${state.retainedOverrides} retained override(s)`);
260
+ }
261
+ return `${state.scope} (${details.join(', ')})`;
262
+ }
263
+ function formatPackReport(report) {
264
+ const lines = [];
265
+ if (report.states.length > 0) {
266
+ lines.push('Pack state:');
267
+ for (const state of report.states) {
268
+ const scopeSummary = state.scopes.length > 0
269
+ ? state.scopes.map(describePackScope).join(', ')
270
+ : 'no installed scope';
271
+ lines.push(` ${state.pack}: ${scopeSummary}`);
272
+ for (const scope of state.scopes) {
273
+ if (scope.missing.length > 0) {
274
+ lines.push(` Missing: ${formatPackPaths(scope.missing, {})}`);
275
+ }
276
+ for (const diagnostic of scope.diagnostics) {
277
+ lines.push(` ${diagnostic.code}: ${diagnostic.message}`);
278
+ if (diagnostic.recovery) {
279
+ lines.push(` Fix: ${diagnostic.recovery}`);
280
+ }
281
+ }
282
+ if (scope.recovery) {
283
+ lines.push(` Fix: ${scope.recovery}`);
284
+ }
285
+ }
286
+ for (const diagnostic of state.diagnostics) {
287
+ lines.push(` ${diagnostic.code}: ${diagnostic.message}`);
288
+ if (diagnostic.recovery) {
289
+ lines.push(` Fix: ${diagnostic.recovery}`);
290
+ }
291
+ }
292
+ }
293
+ }
294
+ for (const scope of report.unavailableScopes) {
295
+ lines.push(`${scope} scope is unavailable here; pack state is reported for the remaining scope(s).`);
296
+ }
297
+ if (report.pjm && shouldReportPjmAdoption(report.pjm, report.states)) {
298
+ lines.push(report.pjm.state === 'partial-initialization'
299
+ ? 'PJM: this repository has a partial PJM scaffold and has not adopted PJM.'
300
+ : 'PJM: this repository has not adopted PJM.');
301
+ if (report.pjm.recovery) {
302
+ lines.push(` Fix: ${report.pjm.recovery}`);
303
+ }
304
+ }
305
+ return lines.length > 0 ? lines.join('\n') : null;
306
+ }
128
307
  async function collectScopeReports(scope, context, dependencies) {
129
308
  const scopeRoot = await dependencies.resolveScopeRoot(scope, context);
130
309
  const manifestPath = join(scopeRoot, '.oat', 'sync', 'manifest.json');
@@ -310,10 +489,26 @@ async function collectScopeReports(scope, context, dependencies) {
310
489
  async function runStatusCommand(context, dependencies, options = {}) {
311
490
  const reports = [];
312
491
  const scopeCollections = [];
313
- for (const scope of resolveConcreteScopes(context.scope)) {
314
- const scopeReportCollection = await collectScopeReports(scope, context, dependencies);
492
+ const scopes = resolveConcreteScopes(context.scope);
493
+ const scopeRoots = new Map();
494
+ const unavailableScopes = [];
495
+ for (const scope of scopes) {
496
+ let scopeReportCollection;
497
+ try {
498
+ scopeReportCollection = await collectScopeReports(scope, context, dependencies);
499
+ }
500
+ catch (error) {
501
+ // `--scope all` outside a Git repository still reports user scope; an
502
+ // explicitly requested scope stays a hard failure.
503
+ if (scope === 'project' && scopes.includes('user')) {
504
+ unavailableScopes.push(scope);
505
+ continue;
506
+ }
507
+ throw error;
508
+ }
315
509
  reports.push(...scopeReportCollection.reports);
316
510
  scopeCollections.push(scopeReportCollection);
511
+ scopeRoots.set(scope, scopeReportCollection.scopeRoot);
317
512
  }
318
513
  const summary = summarizeReports(reports);
319
514
  const hasIssues = summary.total > 0 && summary.inSync !== summary.total;
@@ -331,11 +526,13 @@ async function runStatusCommand(context, dependencies, options = {}) {
331
526
  }
332
527
  return;
333
528
  }
529
+ const packReport = await collectPackReport(scopeRoots, unavailableScopes, dependencies);
334
530
  if (context.json) {
335
531
  const payload = {
336
532
  scope: context.scope,
337
533
  reports,
338
534
  summary,
535
+ packs: packReport,
339
536
  };
340
537
  if (!context.interactive && summary.stray > 0) {
341
538
  payload.remediation = DEFAULT_REMEDIATION;
@@ -344,6 +541,10 @@ async function runStatusCommand(context, dependencies, options = {}) {
344
541
  }
345
542
  else {
346
543
  context.logger.info(dependencies.formatStatusTable(reports));
544
+ const packSummary = formatPackReport(packReport);
545
+ if (packSummary) {
546
+ context.logger.info(packSummary);
547
+ }
347
548
  }
348
549
  if (summary.stray > 0) {
349
550
  if (context.interactive) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/index.ts"],"names":[],"mappings":"AA2CA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAI5C,OAAO,KAAK,EAEV,uBAAuB,EAGxB,MAAM,cAAc,CAAC;AA4XtB,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":"AA2CA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAI5C,OAAO,KAAK,EAGV,uBAAuB,EAGxB,MAAM,cAAc,CAAC;AAoZtB,wBAAgB,iBAAiB,CAC/B,SAAS,GAAE,OAAO,CAAC,uBAAuB,CAAM,GAC/C,OAAO,CAuDT"}
@@ -1,4 +1,4 @@
1
- import { join } from 'node:path';
1
+ import { join, relative } from 'node:path';
2
2
  import { buildCommandContext } from '../../app/command-context.js';
3
3
  import { PROVIDER_CONFIG_REMEDIATION } from '../shared/messages.js';
4
4
  import { withScopeOption } from '../shared/scope-option.js';
@@ -76,6 +76,16 @@ function validateInstallCanonicalPaths(paths) {
76
76
  }
77
77
  return paths;
78
78
  }
79
+ function validateRemoveCanonicalPaths(paths) {
80
+ if (!paths?.length)
81
+ return undefined;
82
+ for (const path of paths) {
83
+ if (!INSTALL_CANONICAL_PATH_PATTERN.test(path)) {
84
+ throw new CliError(`Invalid --remove-canonical path: ${path}`, 1);
85
+ }
86
+ }
87
+ return paths;
88
+ }
79
89
  function hasProviderMismatches(mismatches) {
80
90
  return (mismatches.detectedUnset.length > 0 ||
81
91
  mismatches.detectedDisabled.length > 0);
@@ -172,7 +182,7 @@ function detectVersionSkew(scope, manifest) {
172
182
  }
173
183
  return { scope, producingVersion, invokingVersion };
174
184
  }
175
- async function computePlans(context, dependencies, allowedCanonicalPaths) {
185
+ async function computePlans(context, dependencies, canonicalFilter) {
176
186
  const scopePlans = [];
177
187
  for (const scope of resolveConcreteScopes(context.scope)) {
178
188
  const scopeRoot = await dependencies.resolveScopeRoot(scope, context);
@@ -183,6 +193,13 @@ async function computePlans(context, dependencies, allowedCanonicalPaths) {
183
193
  dependencies.loadSyncConfig(configPath),
184
194
  dependencies.scanCanonical(scopeRoot, scope),
185
195
  ]);
196
+ if (canonicalFilter?.mode === 'remove') {
197
+ const existing = new Set(canonical.map(({ canonicalPath }) => relative(scopeRoot, canonicalPath).replaceAll('\\', '/')));
198
+ const stillPresent = canonicalFilter.paths.filter((path) => existing.has(path));
199
+ if (stillPresent.length > 0) {
200
+ throw new CliError(`Cannot remove canonical provider views while source exists: ${stillPresent.join(', ')}`, 1);
201
+ }
202
+ }
186
203
  const adapters = dependencies.getAdapters();
187
204
  const initialResolution = await dependencies.getConfigAwareAdapters(adapters, scopeRoot, config);
188
205
  const resolved = await maybeResolveProviderMismatches(context, scope, scopeRoot, configPath, config, adapters, {
@@ -196,7 +213,7 @@ async function computePlans(context, dependencies, allowedCanonicalPaths) {
196
213
  scope,
197
214
  config: resolved.config,
198
215
  scopeRoot,
199
- allowedCanonicalPaths,
216
+ allowedCanonicalPaths: canonicalFilter?.paths,
200
217
  });
201
218
  const activeAdapterNames = resolved.activeAdapters.map((adapter) => adapter.name);
202
219
  const enabledExtensions = dependencies
@@ -208,7 +225,7 @@ async function computePlans(context, dependencies, allowedCanonicalPaths) {
208
225
  const materializationExtensionPlans = await Promise.all(enabledExtensions.map((extension) => extension.computePlan({
209
226
  scopeRoot,
210
227
  canonicalEntries: extensionCanonical,
211
- allowedCanonicalPaths,
228
+ allowedCanonicalPaths: canonicalFilter?.paths,
212
229
  options: { userConfigDir: join(context.home, '.oat') },
213
230
  })));
214
231
  const materializationExtensions = materializationExtensionPlans.map((extensionPlan) => ({
@@ -270,8 +287,8 @@ function logVersionSkewWarnings(context, scopePlans) {
270
287
  context.logger.warn(`Sync manifest version skew [${skew.scope}]: manifest produced by oat "${skew.producingVersion}" but invoked by oat "${skew.invokingVersion}".`);
271
288
  }
272
289
  }
273
- async function runSyncCommand(context, dependencies, allowedCanonicalPaths) {
274
- const scopePlans = await computePlans(context, dependencies, allowedCanonicalPaths);
290
+ async function runSyncCommand(context, dependencies, canonicalFilter) {
291
+ const scopePlans = await computePlans(context, dependencies, canonicalFilter);
275
292
  logNonInteractiveMismatchGuidance(context, scopePlans);
276
293
  logVersionSkewWarnings(context, scopePlans);
277
294
  if (context.dryRun) {
@@ -294,10 +311,26 @@ export function createSyncCommand(overrides = {}) {
294
311
  .argParser((value, previous) => [
295
312
  ...(previous ?? []),
296
313
  value,
314
+ ]))
315
+ .addOption(new Option('--remove-canonical <path>', 'Internal removal sync filter')
316
+ .hideHelp()
317
+ .default([])
318
+ .argParser((value, previous) => [
319
+ ...(previous ?? []),
320
+ value,
297
321
  ]))
298
322
  .action(async (_options, command) => {
299
323
  const context = dependencies.buildCommandContext(readGlobalOptions(command));
300
324
  const options = command.opts();
301
- await runSyncCommand(context, dependencies, validateInstallCanonicalPaths(options.installCanonical));
325
+ const installPaths = validateInstallCanonicalPaths(options.installCanonical);
326
+ const removePaths = validateRemoveCanonicalPaths(options.removeCanonical);
327
+ if (installPaths?.length && removePaths?.length) {
328
+ throw new CliError('--install-canonical and --remove-canonical cannot be combined', 1);
329
+ }
330
+ await runSyncCommand(context, dependencies, installPaths?.length
331
+ ? { mode: 'install', paths: installPaths }
332
+ : removePaths?.length
333
+ ? { mode: 'remove', paths: removePaths }
334
+ : undefined);
302
335
  });
303
336
  }
@@ -9,6 +9,10 @@ export interface SyncProviderMismatches {
9
9
  detectedUnset: string[];
10
10
  detectedDisabled: string[];
11
11
  }
12
+ export interface CanonicalSyncFilter {
13
+ mode: 'install' | 'remove';
14
+ paths: string[];
15
+ }
12
16
  /**
13
17
  * Advisory diagnostic emitted when the CLI version that produced a scope's sync
14
18
  * manifest differs from the CLI version invoking sync. Comparison is symmetric
@@ -1 +1 @@
1
- {"version":3,"file":"sync.types.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/sync.types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sync.types.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/sync.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,KAAK,EACV,iBAAiB,EACjB,aAAa,EACd,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC1E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EACV,yBAAyB,EACzB,0BAA0B,EAC1B,wBAAwB,EACxB,wBAAwB,EACxB,mBAAmB,EACnB,eAAe,EAChB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAE1D,MAAM,WAAW,sBAAsB;IACrC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC3B,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,aAAa,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,aAAa,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,QAAQ,CAAC;IACf,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC;IAC7B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,kBAAkB,CAAC,EAAE,sBAAsB,CAAC;IAC5C,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,6BAA6B,EAAE,mBAAmB,EAAE,CAAC;IACrD,yBAAyB,EAAE,+BAA+B,EAAE,CAAC;CAC9D;AAED,MAAM,WAAW,WAAW;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,KAAK,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,OAAO,EAAE,WAAW,CAAC;IACrB,kBAAkB,CAAC,EAAE,sBAAsB,EAAE,CAAC;IAC9C,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC;IAChC,yBAAyB,CAAC,EAAE,+BAA+B,EAAE,CAAC;IAC9D,qEAAqE;IACrE,eAAe,CAAC,EAAE,qBAAqB,EAAE,CAAC;CAC3C;AAED,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,qBAAqB;IACpC,UAAU,EAAE,uBAAuB,EAAE,CAAC;IACtC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,+BAA+B;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,wBAAwB,EAAE,CAAC;IACvC,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,4BAA4B,GAAG,wBAAwB,CACjE,mBAAmB,EACnB;IACE,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,cAAc,EAAE,CAAC;IACnC,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;IACjC,OAAO,EAAE;QACP,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;KACzB,CAAC;CACH,CACF,CAAC;AAEF,MAAM,WAAW,uBAAuB;IACtC,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,gBAAgB,EAAE,CAChB,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE,cAAc,KACpB,OAAO,CAAC,MAAM,CAAC,CAAC;IACrB,YAAY,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1D,cAAc,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IAC5D,cAAc,EAAE,CACd,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,UAAU,KACf,OAAO,CAAC,UAAU,CAAC,CAAC;IACzB,aAAa,EAAE,CACb,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,aAAa,KACjB,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IAC/B,wBAAwB,EAAE,MAAM,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IAC1D,WAAW,EAAE,MAAM,eAAe,EAAE,CAAC;IACrC,sBAAsB,EAAE,CACtB,QAAQ,EAAE,eAAe,EAAE,EAC3B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,UAAU,KACf,OAAO,CAAC,yBAAyB,CAAC,CAAC;IACxC,wBAAwB,EAAE,CAAC,CAAC,SAAS,MAAM,EACzC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAC/B,GAAG,EAAE,aAAa,KACf,OAAO,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IACzB,eAAe,EAAE,CAAC,IAAI,EAAE;QACtB,SAAS,EAAE,cAAc,EAAE,CAAC;QAC5B,QAAQ,EAAE,eAAe,EAAE,CAAC;QAC5B,QAAQ,EAAE,QAAQ,CAAC;QACnB,KAAK,EAAE,aAAa,CAAC;QACrB,MAAM,EAAE,UAAU,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;QAClB,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;KAClC,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IACxB,eAAe,EAAE,CACf,IAAI,EAAE,QAAQ,EACd,QAAQ,EAAE,QAAQ,EAClB,YAAY,EAAE,MAAM,KACjB,OAAO,CAAC,UAAU,CAAC,CAAC;IACzB,4BAA4B,EAAE,MAAM,4BAA4B,EAAE,CAAC;IACnE,iCAAiC,EAAE,CACjC,SAAS,EAAE,4BAA4B,EACvC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,mBAAmB,KACtB,OAAO,CAAC,0BAA0B,CAAC,CAAC;IACzC,cAAc,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,KAAK,MAAM,CAAC;CAC9D"}
@@ -1,18 +1,27 @@
1
1
  import type { CommandContext } from '../../../app/command-context.js';
2
+ import { type InventoryScopedPackInput, type ScopedPackInventory } from '../../tools/shared/pack-inventory.js';
3
+ import { isPackName, PACK_NAMES } from '../../tools/shared/pack-manifest.js';
2
4
  import type { ScanToolsOptions } from '../../tools/shared/scan-tools.js';
3
5
  import type { PackName, ToolInfo } from '../../tools/shared/types.js';
4
6
  import type { ConcreteScope } from '../../../shared/types.js';
5
- export declare const PACK_NAMES: readonly ["core", "ideas", "docs", "workflows", "utility", "project-management", "research", "brainstorm"];
7
+ export { isPackName, PACK_NAMES };
6
8
  export interface PackAvailability {
7
9
  pack: PackName;
8
10
  available: boolean;
9
11
  scopes: ConcreteScope[];
12
+ unavailableScopes: ConcreteScope[];
13
+ completeness: Partial<Record<ConcreteScope, ScopedPackInventory['completeness']>>;
14
+ missing: Array<{
15
+ scope: ConcreteScope;
16
+ asset: string;
17
+ path: string;
18
+ }>;
10
19
  }
11
20
  export interface PackAvailabilityDependencies {
12
21
  scanTools: (options: ScanToolsOptions) => Promise<ToolInfo[]>;
13
22
  resolveScopeRoot: (scope: ConcreteScope, cwd: string, home: string) => Promise<string>;
14
23
  resolveAssetsRoot: () => Promise<string>;
24
+ inventoryScopedPack?: (input: InventoryScopedPackInput) => Promise<ScopedPackInventory>;
15
25
  }
16
- export declare function isPackName(value: string): value is PackName;
17
26
  export declare function resolvePackAvailability(pack: PackName, scopes: ConcreteScope[], context: CommandContext, dependencies: PackAvailabilityDependencies): Promise<PackAvailability>;
18
27
  //# sourceMappingURL=has-pack.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"has-pack.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/has/has-pack.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,eAAO,MAAM,UAAU,4GASiB,CAAC;AAEzC,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,QAAQ,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,aAAa,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,4BAA4B;IAC3C,SAAS,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC9D,gBAAgB,EAAE,CAChB,KAAK,EAAE,aAAa,EACpB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,KACT,OAAO,CAAC,MAAM,CAAC,CAAC;IACrB,iBAAiB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1C;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,QAAQ,CAE3D;AAED,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,aAAa,EAAE,EACvB,OAAO,EAAE,cAAc,EACvB,YAAY,EAAE,4BAA4B,GACzC,OAAO,CAAC,gBAAgB,CAAC,CAyB3B"}
1
+ {"version":3,"file":"has-pack.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/has/has-pack.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAEL,KAAK,wBAAwB,EAC7B,KAAK,mBAAmB,EACzB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAEL,UAAU,EACV,UAAU,EACX,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC;AAElC,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,QAAQ,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,iBAAiB,EAAE,aAAa,EAAE,CAAC;IACnC,YAAY,EAAE,OAAO,CACnB,MAAM,CAAC,aAAa,EAAE,mBAAmB,CAAC,cAAc,CAAC,CAAC,CAC3D,CAAC;IACF,OAAO,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,aAAa,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACvE;AAED,MAAM,WAAW,4BAA4B;IAC3C,SAAS,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC9D,gBAAgB,EAAE,CAChB,KAAK,EAAE,aAAa,EACpB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,KACT,OAAO,CAAC,MAAM,CAAC,CAAC;IACrB,iBAAiB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,mBAAmB,CAAC,EAAE,CACpB,KAAK,EAAE,wBAAwB,KAC5B,OAAO,CAAC,mBAAmB,CAAC,CAAC;CACnC;AAED,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,aAAa,EAAE,EACvB,OAAO,EAAE,cAAc,EACvB,YAAY,EAAE,4BAA4B,GACzC,OAAO,CAAC,gBAAgB,CAAC,CAqD3B"}
@@ -1,27 +1,37 @@
1
- export const PACK_NAMES = [
2
- 'core',
3
- 'ideas',
4
- 'docs',
5
- 'workflows',
6
- 'utility',
7
- 'project-management',
8
- 'research',
9
- 'brainstorm',
10
- ];
11
- export function isPackName(value) {
12
- return PACK_NAMES.includes(value);
13
- }
1
+ import { inventoryScopedPack, } from '../../tools/shared/pack-inventory.js';
2
+ import { getPackDefinition, isPackName, PACK_NAMES, } from '../../tools/shared/pack-manifest.js';
3
+ export { isPackName, PACK_NAMES };
14
4
  export async function resolvePackAvailability(pack, scopes, context, dependencies) {
15
5
  const assetsRoot = await dependencies.resolveAssetsRoot();
16
6
  const matchingScopes = [];
7
+ const completeness = {};
8
+ const missing = [];
9
+ const allowedScopes = new Set(getPackDefinition(pack).allowedScopes);
10
+ const unavailableScopes = scopes.filter((scope) => !allowedScopes.has(scope));
17
11
  for (const scope of scopes) {
18
- const scopeRoot = await dependencies.resolveScopeRoot(scope, context.cwd, context.home);
19
- const tools = await dependencies.scanTools({
20
- scope,
21
- scopeRoot,
22
- assetsRoot,
23
- });
24
- if (tools.some((tool) => tool.pack === pack)) {
12
+ if (!allowedScopes.has(scope))
13
+ continue;
14
+ let scopeRoot;
15
+ try {
16
+ scopeRoot = await dependencies.resolveScopeRoot(scope, context.cwd, context.home);
17
+ }
18
+ catch (error) {
19
+ // `has` is an availability probe, and user scope is now the default
20
+ // install target, so a query that spans both scopes still has a complete
21
+ // answer outside a Git repository. An explicitly requested project scope
22
+ // stays a hard failure.
23
+ if (scope === 'project' && scopes.includes('user')) {
24
+ unavailableScopes.push(scope);
25
+ continue;
26
+ }
27
+ throw error;
28
+ }
29
+ const inventory = await (dependencies.inventoryScopedPack ?? inventoryScopedPack)({ pack, scope, scopeRoot, assetsRoot });
30
+ completeness[scope] = inventory.completeness;
31
+ missing.push(...inventory.assets
32
+ .filter(({ definition, status }) => definition.ownership[scope] === 'managed' && status === 'missing')
33
+ .map(({ definition, path }) => ({ scope, asset: definition.id, path })));
34
+ if (inventory.completeness === 'complete') {
25
35
  matchingScopes.push(scope);
26
36
  }
27
37
  }
@@ -29,5 +39,8 @@ export async function resolvePackAvailability(pack, scopes, context, dependencie
29
39
  pack,
30
40
  available: matchingScopes.length > 0,
31
41
  scopes: matchingScopes,
42
+ unavailableScopes,
43
+ completeness,
44
+ missing,
32
45
  };
33
46
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,wBAAgB,kBAAkB,IAAI,OAAO,CAc5C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,wBAAgB,kBAAkB,IAAI,OAAO,CAe5C"}
@@ -3,16 +3,18 @@ import { createToolsHasCommand } from './has/index.js';
3
3
  import { createToolsInfoCommand } from './info/index.js';
4
4
  import { createToolsInstallCommand } from './install/index.js';
5
5
  import { createToolsListCommand } from './list/index.js';
6
+ import { createToolsMigrateCommand } from './migrate/index.js';
6
7
  import { createToolsOutdatedCommand } from './outdated/index.js';
7
8
  import { createToolsRemoveCommand } from './remove/index.js';
8
9
  import { createToolsUpdateCommand } from './update/index.js';
9
10
  export function createToolsCommand() {
10
- const cmd = new Command('tools').description('Manage OAT tool packs (install, update, remove, list)');
11
+ const cmd = new Command('tools').description('Manage OAT tool packs (install, update, migrate, remove, list)');
11
12
  cmd.addCommand(createToolsListCommand());
12
13
  cmd.addCommand(createToolsOutdatedCommand());
13
14
  cmd.addCommand(createToolsInfoCommand());
14
15
  cmd.addCommand(createToolsHasCommand());
15
16
  cmd.addCommand(createToolsUpdateCommand());
17
+ cmd.addCommand(createToolsMigrateCommand());
16
18
  cmd.addCommand(createToolsRemoveCommand());
17
19
  cmd.addCommand(createToolsInstallCommand());
18
20
  return cmd;
@@ -1,4 +1,5 @@
1
1
  import type { CommandContext } from '../../../app/command-context.js';
2
+ import { type InventoryPackInput, type PackInventory } from '../../tools/shared/pack-inventory.js';
2
3
  import type { ScanToolsOptions } from '../../tools/shared/scan-tools.js';
3
4
  import type { ToolInfo } from '../../tools/shared/types.js';
4
5
  export interface ToolDetail extends ToolInfo {
@@ -12,10 +13,12 @@ export interface InfoToolDependencies {
12
13
  resolveScopeRoot: (scope: 'project' | 'user', cwd: string, home: string) => Promise<string>;
13
14
  resolveAssetsRoot: () => Promise<string>;
14
15
  getToolDetail: (tool: ToolInfo, scopeRoot: string) => Promise<Omit<ToolDetail, keyof ToolInfo>>;
16
+ inventoryPack?: (input: InventoryPackInput) => Promise<PackInventory>;
15
17
  }
16
18
  export interface InfoToolResult {
17
19
  found: boolean;
18
20
  tool: ToolDetail | null;
21
+ pack: PackInventory | null;
19
22
  }
20
23
  export declare function runInfoTool(context: CommandContext, name: string, dependencies: InfoToolDependencies): Promise<InfoToolResult>;
21
24
  //# sourceMappingURL=info-tool.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"info-tool.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/info/info-tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAE7D,MAAM,WAAW,UAAW,SAAQ,QAAQ;IAC1C,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC9D,gBAAgB,EAAE,CAChB,KAAK,EAAE,SAAS,GAAG,MAAM,EACzB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,KACT,OAAO,CAAC,MAAM,CAAC,CAAC;IACrB,iBAAiB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,aAAa,EAAE,CACb,IAAI,EAAE,QAAQ,EACd,SAAS,EAAE,MAAM,KACd,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,QAAQ,CAAC,CAAC,CAAC;CAChD;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;CACzB;AAED,wBAAsB,WAAW,CAC/B,OAAO,EAAE,cAAc,EACvB,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,oBAAoB,GACjC,OAAO,CAAC,cAAc,CAAC,CA6DzB"}
1
+ {"version":3,"file":"info-tool.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/info/info-tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3D,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,aAAa,EACnB,MAAM,uCAAuC,CAAC;AAE/C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAE7D,MAAM,WAAW,UAAW,SAAQ,QAAQ;IAC1C,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC9D,gBAAgB,EAAE,CAChB,KAAK,EAAE,SAAS,GAAG,MAAM,EACzB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,KACT,OAAO,CAAC,MAAM,CAAC,CAAC;IACrB,iBAAiB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,aAAa,EAAE,CACb,IAAI,EAAE,QAAQ,EACd,SAAS,EAAE,MAAM,KACd,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,QAAQ,CAAC,CAAC,CAAC;IAC/C,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;CACvE;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;IACxB,IAAI,EAAE,aAAa,GAAG,IAAI,CAAC;CAC5B;AAED,wBAAsB,WAAW,CAC/B,OAAO,EAAE,cAAc,EACvB,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,oBAAoB,GACjC,OAAO,CAAC,cAAc,CAAC,CAmFzB"}
@@ -1,10 +1,35 @@
1
1
  import { resolveConcreteScopes } from '../../shared/shared.utils.js';
2
+ import { formatPackInventoryDetails } from '../../tools/shared/format-pack-inventory.js';
3
+ import { inventoryPack, } from '../../tools/shared/pack-inventory.js';
4
+ import { PACK_MANIFEST } from '../../tools/shared/pack-manifest.js';
2
5
  export async function runInfoTool(context, name, dependencies) {
3
6
  const { logger } = context;
4
7
  const scopes = resolveConcreteScopes(context.scope);
5
8
  const assetsRoot = await dependencies.resolveAssetsRoot();
9
+ const roots = {};
6
10
  for (const scope of scopes) {
7
- const scopeRoot = await dependencies.resolveScopeRoot(scope, context.cwd, context.home);
11
+ roots[scope] = await dependencies.resolveScopeRoot(scope, context.cwd, context.home);
12
+ }
13
+ const packName = PACK_MANIFEST.find(({ name: candidate }) => candidate === name)?.name;
14
+ if (packName) {
15
+ const pack = await (dependencies.inventoryPack ?? inventoryPack)({
16
+ pack: packName,
17
+ assetsRoot,
18
+ projectRoot: roots.project,
19
+ userRoot: roots.user,
20
+ });
21
+ if (context.json)
22
+ logger.json({ tool: null, pack });
23
+ else {
24
+ logger.info(`${pack.pack}`);
25
+ logger.info(` Placement: ${pack.placement}`);
26
+ for (const line of formatPackInventoryDetails(pack))
27
+ logger.info(line);
28
+ }
29
+ return { found: true, tool: null, pack };
30
+ }
31
+ for (const scope of scopes) {
32
+ const scopeRoot = roots[scope];
8
33
  const tools = await dependencies.scanTools({
9
34
  scope,
10
35
  scopeRoot,
@@ -17,7 +42,7 @@ export async function runInfoTool(context, name, dependencies) {
17
42
  const toolDetail = { ...match, ...detail };
18
43
  if (context.json) {
19
44
  logger.json({ tool: toolDetail });
20
- return { found: true, tool: toolDetail };
45
+ return { found: true, tool: toolDetail, pack: null };
21
46
  }
22
47
  logger.info(`${toolDetail.name}`);
23
48
  logger.info(` Type: ${toolDetail.type}`);
@@ -40,7 +65,7 @@ export async function runInfoTool(context, name, dependencies) {
40
65
  if (toolDetail.status === 'outdated') {
41
66
  logger.warn(` Update available: ${toolDetail.version ?? '?'} -> ${toolDetail.bundledVersion ?? '?'}`);
42
67
  }
43
- return { found: true, tool: toolDetail };
68
+ return { found: true, tool: toolDetail, pack: null };
44
69
  }
45
70
  if (context.json) {
46
71
  logger.json({ tool: null, error: `Tool '${name}' not found` });
@@ -48,5 +73,5 @@ export async function runInfoTool(context, name, dependencies) {
48
73
  else {
49
74
  logger.error(`Tool '${name}' not found.`);
50
75
  }
51
- return { found: false, tool: null };
76
+ return { found: false, tool: null, pack: null };
52
77
  }
@@ -1,13 +1,16 @@
1
1
  import type { CommandContext } from '../../../app/command-context.js';
2
+ import { type InventoryPackInput, type PackInventory } from '../../tools/shared/pack-inventory.js';
2
3
  import type { ScanToolsOptions } from '../../tools/shared/scan-tools.js';
3
4
  import type { ToolInfo } from '../../tools/shared/types.js';
4
5
  export interface ListToolsDependencies {
5
6
  scanTools: (options: ScanToolsOptions) => Promise<ToolInfo[]>;
6
7
  resolveScopeRoot: (scope: 'project' | 'user', cwd: string, home: string) => Promise<string>;
7
8
  resolveAssetsRoot: () => Promise<string>;
9
+ inventoryPack?: (input: InventoryPackInput) => Promise<PackInventory>;
8
10
  }
9
11
  export interface ListToolsResult {
10
12
  tools: ToolInfo[];
13
+ packs: PackInventory[];
11
14
  }
12
15
  export declare function runListTools(context: CommandContext, dependencies: ListToolsDependencies): Promise<ListToolsResult>;
13
16
  //# sourceMappingURL=list-tools.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"list-tools.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/list/list-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAE7D,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC9D,gBAAgB,EAAE,CAChB,KAAK,EAAE,SAAS,GAAG,MAAM,EACzB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,KACT,OAAO,CAAC,MAAM,CAAC,CAAC;IACrB,iBAAiB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,cAAc,EACvB,YAAY,EAAE,qBAAqB,GAClC,OAAO,CAAC,eAAe,CAAC,CAiE1B"}
1
+ {"version":3,"file":"list-tools.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/list/list-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3D,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,aAAa,EACnB,MAAM,uCAAuC,CAAC;AAE/C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAE7D,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC9D,gBAAgB,EAAE,CAChB,KAAK,EAAE,SAAS,GAAG,MAAM,EACzB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,KACT,OAAO,CAAC,MAAM,CAAC,CAAC;IACrB,iBAAiB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;CACvE;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,KAAK,EAAE,aAAa,EAAE,CAAC;CACxB;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,cAAc,EACvB,YAAY,EAAE,qBAAqB,GAClC,OAAO,CAAC,eAAe,CAAC,CAiG1B"}