@open-agent-toolkit/cli 0.2.35 → 0.2.37

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,9 +1,13 @@
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 runListTools(context, dependencies) {
3
6
  const { logger } = context;
4
7
  const scopes = resolveConcreteScopes(context.scope);
5
8
  const assetsRoot = await dependencies.resolveAssetsRoot();
6
9
  const allTools = [];
10
+ const roots = {};
7
11
  for (const scope of scopes) {
8
12
  const scopeRoot = await dependencies.resolveScopeRoot(scope, context.cwd, context.home);
9
13
  const tools = await dependencies.scanTools({
@@ -12,14 +16,28 @@ export async function runListTools(context, dependencies) {
12
16
  assetsRoot,
13
17
  });
14
18
  allTools.push(...tools);
19
+ roots[scope] = scopeRoot;
15
20
  }
21
+ const inspectPack = dependencies.inventoryPack ?? inventoryPack;
22
+ const packs = await Promise.all(PACK_MANIFEST.map(({ name }) => inspectPack({
23
+ pack: name,
24
+ assetsRoot,
25
+ projectRoot: roots.project,
26
+ userRoot: roots.user,
27
+ })));
16
28
  if (context.json) {
17
- logger.json({ tools: allTools });
18
- return { tools: allTools };
29
+ logger.json({ tools: allTools, packs });
30
+ return { tools: allTools, packs };
19
31
  }
20
32
  if (allTools.length === 0) {
21
33
  logger.info('No tools installed.');
22
- return { tools: allTools };
34
+ logger.info('Pack inventory:');
35
+ for (const pack of packs) {
36
+ logger.info(`${pack.pack}: ${pack.placement}`);
37
+ for (const line of formatPackInventoryDetails(pack))
38
+ logger.info(line);
39
+ }
40
+ return { tools: allTools, packs };
23
41
  }
24
42
  logger.info('Installed tools:\n');
25
43
  const header = formatRow('NAME', 'TYPE', 'VERSION', 'PACK', 'SCOPE', 'STATUS');
@@ -29,7 +47,16 @@ export async function runListTools(context, dependencies) {
29
47
  for (const tool of allTools) {
30
48
  logger.info(formatRow(tool.name, tool.type, tool.version ?? '-', tool.pack, tool.scope, tool.status));
31
49
  }
32
- return { tools: allTools };
50
+ logger.info('\nPack inventory:');
51
+ for (const pack of packs) {
52
+ const states = pack.scopes
53
+ .map(({ scope, completeness, intent }) => `${scope}=${completeness} (${intent.source})`)
54
+ .join(', ');
55
+ logger.info(`${pack.pack.padEnd(20)} ${pack.placement.padEnd(11)} ${states || 'not inspected'}`);
56
+ for (const line of formatPackInventoryDetails(pack))
57
+ logger.info(line);
58
+ }
59
+ return { tools: allTools, packs };
33
60
  }
34
61
  function formatRow(name, type, version, pack, scope, status) {
35
62
  return [
@@ -0,0 +1,26 @@
1
+ import { type CommandContext, type GlobalOptions } from '../../../app/command-context.js';
2
+ import { confirmAction } from '../../shared/shared.prompts.js';
3
+ import { inventoryScopedPack } from '../../tools/shared/pack-inventory.js';
4
+ import { resolveSharedOwnerRetentions, type ResolveSharedOwnerRetentionsInput } from '../../tools/shared/pack-reconcile.js';
5
+ import type { ConcreteScope } from '../../../shared/types.js';
6
+ import { Command } from 'commander';
7
+ import { type CompleteMigrationSourceRemovalInput, type PackMigrationOutcome, type PackMigrationPreview, type PlanPackMigrationInput } from './migrate-pack.js';
8
+ interface MigrationCommandRuntime {
9
+ context: CommandContext;
10
+ assetsRoot: string;
11
+ }
12
+ export interface MigrationCommandDependencies {
13
+ buildCommandContext: (options: GlobalOptions) => CommandContext;
14
+ resolveProjectRoot: (cwd: string) => Promise<string>;
15
+ resolveScopeRoot: (scope: ConcreteScope, cwd: string, home: string) => string;
16
+ resolveAssetsRoot: () => Promise<string>;
17
+ inventory: typeof inventoryScopedPack;
18
+ resolveSharedRetentions: (input: ResolveSharedOwnerRetentionsInput) => ReturnType<typeof resolveSharedOwnerRetentions>;
19
+ plan: (input: PlanPackMigrationInput) => PackMigrationPreview;
20
+ executeDestination: (preview: PackMigrationPreview, destinationRoot: string, runtime: MigrationCommandRuntime) => Promise<PackMigrationOutcome>;
21
+ completeSourceRemoval: (destination: PackMigrationOutcome, input: CompleteMigrationSourceRemovalInput, runtime: MigrationCommandRuntime) => Promise<PackMigrationOutcome>;
22
+ confirmAction: typeof confirmAction;
23
+ }
24
+ export declare function createToolsMigrateCommand(dependencies?: MigrationCommandDependencies): Command;
25
+ export {};
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/migrate/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAEhE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAE5E,OAAO,EACL,4BAA4B,EAE5B,KAAK,iCAAiC,EACvC,MAAM,uCAAuC,CAAC;AAS/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAE5C,OAAO,EAIL,KAAK,mCAAmC,EACxC,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC5B,MAAM,gBAAgB,CAAC;AAExB,UAAU,uBAAuB;IAC/B,OAAO,EAAE,cAAc,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,4BAA4B;IAC3C,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,gBAAgB,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC9E,iBAAiB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,SAAS,EAAE,OAAO,mBAAmB,CAAC;IACtC,uBAAuB,EAAE,CACvB,KAAK,EAAE,iCAAiC,KACrC,UAAU,CAAC,OAAO,4BAA4B,CAAC,CAAC;IACrD,IAAI,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,oBAAoB,CAAC;IAC9D,kBAAkB,EAAE,CAClB,OAAO,EAAE,oBAAoB,EAC7B,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE,uBAAuB,KAC7B,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACnC,qBAAqB,EAAE,CACrB,WAAW,EAAE,oBAAoB,EACjC,KAAK,EAAE,mCAAmC,EAC1C,OAAO,EAAE,uBAAuB,KAC7B,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACnC,aAAa,EAAE,OAAO,aAAa,CAAC;CACrC;AAuOD,wBAAgB,yBAAyB,CACvC,YAAY,GAAE,4BAAkD,GAC/D,OAAO,CA0IT"}
@@ -0,0 +1,312 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { mkdir, writeFile } from 'node:fs/promises';
3
+ import { dirname } from 'node:path';
4
+ import { buildCommandContext, } from '../../../app/command-context.js';
5
+ import { confirmAction } from '../../shared/shared.prompts.js';
6
+ import { readGlobalOptions } from '../../shared/shared.utils.js';
7
+ import { inventoryScopedPack } from '../../tools/shared/pack-inventory.js';
8
+ import { isPackName, PACK_NAMES } from '../../tools/shared/pack-manifest.js';
9
+ import { resolveSharedOwnerRetentions, } from '../../tools/shared/pack-reconcile.js';
10
+ import { hasScopedPackOwnershipEvidence, writeScopedPackIntent, } from '../../tools/shared/scoped-pack-intent.js';
11
+ import { readOatConfig, writeOatConfig } from '../../../config/oat-config.js';
12
+ import { CliError } from '../../../errors/index.js';
13
+ import { resolveAssetsRoot } from '../../../fs/assets.js';
14
+ import { resolveProjectRoot, resolveScopeRoot } from '../../../fs/paths.js';
15
+ import { Command, Option } from 'commander';
16
+ import { completeMigrationSourceRemoval, executeMigrationDestination, planPackMigration, } from './migrate-pack.js';
17
+ async function runSync(input) {
18
+ const args = [
19
+ ...process.execArgv,
20
+ process.argv[1],
21
+ '--cwd',
22
+ input.context.cwd,
23
+ 'sync',
24
+ '--scope',
25
+ input.scope,
26
+ ];
27
+ for (const path of input.installedCanonicalPaths ?? []) {
28
+ args.push('--install-canonical', path);
29
+ }
30
+ for (const path of input.removedCanonicalPaths ?? []) {
31
+ args.push('--remove-canonical', path);
32
+ }
33
+ await new Promise((resolve, reject) => {
34
+ execFile(process.execPath, args, { cwd: input.context.cwd }, (error) => {
35
+ if (error)
36
+ reject(error);
37
+ else
38
+ resolve();
39
+ });
40
+ });
41
+ }
42
+ async function writeGenerated(scopeRoot, operation) {
43
+ await mkdir(dirname(operation.destination), { recursive: true });
44
+ switch (operation.generation) {
45
+ case 'projects-root-default':
46
+ await writeFile(operation.destination, '.oat/projects/shared\n', 'utf8');
47
+ return;
48
+ case 'projects-config-default': {
49
+ const config = await readOatConfig(scopeRoot);
50
+ if (config.projects?.root?.trim())
51
+ return;
52
+ await writeOatConfig(scopeRoot, {
53
+ ...config,
54
+ projects: { root: '.oat/projects/shared' },
55
+ });
56
+ return;
57
+ }
58
+ case 'empty-file':
59
+ await writeFile(operation.destination, '', 'utf8');
60
+ }
61
+ }
62
+ async function defaultExecuteDestination(preview, destinationRoot, runtime) {
63
+ return executeMigrationDestination(preview, destinationRoot, {
64
+ applyDependencies: {
65
+ writeGenerated: async (operation) => writeGenerated(destinationRoot, operation),
66
+ writeIntent: async (operation) => writeScopedPackIntent({
67
+ pack: operation.pack,
68
+ scope: operation.scope,
69
+ scopeRoot: destinationRoot,
70
+ enabled: operation.enabled,
71
+ }),
72
+ inventory: async () => inventoryScopedPack({
73
+ pack: preview.pack,
74
+ scope: preview.to,
75
+ scopeRoot: destinationRoot,
76
+ assetsRoot: runtime.assetsRoot,
77
+ }),
78
+ },
79
+ sync: async ({ scope, canonicalPaths }) => runSync({
80
+ context: runtime.context,
81
+ scope,
82
+ installedCanonicalPaths: canonicalPaths,
83
+ }),
84
+ });
85
+ }
86
+ async function defaultCompleteSourceRemoval(destination, input, runtime) {
87
+ const preview = destination.preview;
88
+ return completeMigrationSourceRemoval(destination, input, {
89
+ inventory: async () => inventoryScopedPack({
90
+ pack: preview.pack,
91
+ scope: preview.from,
92
+ scopeRoot: input.sourceRoot,
93
+ assetsRoot: runtime.assetsRoot,
94
+ }),
95
+ applyDependencies: {
96
+ writeGenerated: async (operation) => writeGenerated(input.sourceRoot, operation),
97
+ writeIntent: async (operation) => writeScopedPackIntent({
98
+ pack: operation.pack,
99
+ scope: operation.scope,
100
+ scopeRoot: input.sourceRoot,
101
+ enabled: operation.enabled,
102
+ }),
103
+ },
104
+ resolveSourceRetentions: async () => resolveSharedOwnerRetentions({
105
+ packs: [preview.pack],
106
+ scope: preview.from,
107
+ scopeRoot: input.sourceRoot,
108
+ hasOwnershipEvidence: async (pack, scope, scopeRoot) => hasScopedPackOwnershipEvidence({ pack, scope, scopeRoot }),
109
+ }),
110
+ sync: async ({ scope, canonicalPaths }) => runSync({
111
+ context: runtime.context,
112
+ scope,
113
+ removedCanonicalPaths: canonicalPaths,
114
+ }),
115
+ });
116
+ }
117
+ const defaultDependencies = {
118
+ buildCommandContext,
119
+ resolveProjectRoot,
120
+ resolveScopeRoot,
121
+ resolveAssetsRoot,
122
+ inventory: inventoryScopedPack,
123
+ resolveSharedRetentions: resolveSharedOwnerRetentions,
124
+ plan: planPackMigration,
125
+ executeDestination: defaultExecuteDestination,
126
+ completeSourceRemoval: defaultCompleteSourceRemoval,
127
+ confirmAction,
128
+ };
129
+ async function resolveMigrationScopeRoot(scope, context, dependencies) {
130
+ return scope === 'project'
131
+ ? dependencies.resolveProjectRoot(context.cwd)
132
+ : dependencies.resolveScopeRoot(scope, context.cwd, context.home);
133
+ }
134
+ function renderPreview(preview, context) {
135
+ context.logger.info(`Migration preview: ${preview.pack} (${preview.from} -> ${preview.to})`);
136
+ const groups = [
137
+ ['Additions', preview.additions],
138
+ ['Duplicates', preview.duplicates],
139
+ ['Conflicts', preview.conflicts],
140
+ ['Source removals', preview.removals],
141
+ ['Retained owner data', preview.retained],
142
+ ];
143
+ for (const [label, entries] of groups) {
144
+ context.logger.info(`${label}: ${entries.length}`);
145
+ for (const entry of entries) {
146
+ context.logger.info(` - ${entry.assetId} [${entry.kind}] ${entry.scope} ${entry.status}: ${entry.path}${entry.reason ? ` (${entry.reason})` : ''}`);
147
+ }
148
+ }
149
+ for (const diagnostic of preview.diagnostics) {
150
+ context.logger.info(`Diagnostic ${diagnostic.code}: ${diagnostic.message} (${diagnostic.paths.join(', ')})`);
151
+ }
152
+ }
153
+ function emitOutcome(outcome, dryRun, context) {
154
+ if (context.json) {
155
+ context.logger.json({
156
+ operation: 'migrate',
157
+ dryRun,
158
+ ...outcome,
159
+ });
160
+ return;
161
+ }
162
+ if (outcome.status === 'migrated') {
163
+ context.logger.success(`Migrated ${outcome.preview.pack} from ${outcome.preview.from} to ${outcome.preview.to}.`);
164
+ }
165
+ else if (outcome.status === 'retained-both') {
166
+ context.logger.warn(`Destination is verified; ${outcome.preview.pack} remains installed at both scopes.`);
167
+ }
168
+ else if (outcome.status === 'blocked') {
169
+ context.logger.error('Migration is blocked by destination conflicts.');
170
+ }
171
+ else if (outcome.status === 'source-removal-failed' ||
172
+ outcome.status === 'source-sync-failed') {
173
+ context.logger.error(`Destination is verified, but ${outcome.preview.from} source removal did not complete.`);
174
+ }
175
+ else if (outcome.status === 'destination-sync-failed') {
176
+ context.logger.error(`Destination canonical files are verified, but provider sync did not complete; source was retained.`);
177
+ }
178
+ for (const recovery of outcome.recovery ?? []) {
179
+ context.logger.info(recovery);
180
+ }
181
+ }
182
+ function emitError(error, context, exitCode) {
183
+ const message = error instanceof Error ? error.message : String(error);
184
+ if (context.json) {
185
+ context.logger.json({ status: 'error', operation: 'migrate', message });
186
+ }
187
+ else {
188
+ context.logger.error(message);
189
+ }
190
+ process.exitCode = error instanceof CliError ? error.exitCode : exitCode;
191
+ }
192
+ export function createToolsMigrateCommand(dependencies = defaultDependencies) {
193
+ return new Command('migrate')
194
+ .description('Move an installed tool pack between scopes safely')
195
+ .addOption(new Option('--pack <pack>', 'Pack to migrate')
196
+ .choices([...PACK_NAMES])
197
+ .makeOptionMandatory())
198
+ .addOption(new Option('--from <scope>', 'Source scope')
199
+ .choices(['project', 'user'])
200
+ .makeOptionMandatory())
201
+ .addOption(new Option('--to <scope>', 'Destination scope')
202
+ .choices(['project', 'user'])
203
+ .makeOptionMandatory())
204
+ .option('--dry-run', 'Preview migration without applying')
205
+ .action(async (options, command) => {
206
+ const context = dependencies.buildCommandContext(readGlobalOptions(command));
207
+ const packValue = String(options.pack);
208
+ if (!isPackName(packValue)) {
209
+ emitError(new Error(`Unknown tool pack: ${packValue}`), context, 1);
210
+ return;
211
+ }
212
+ const pack = packValue;
213
+ const from = options.from;
214
+ const to = options.to;
215
+ let sourceRoot;
216
+ let destinationRoot;
217
+ let assetsRoot;
218
+ let preview;
219
+ try {
220
+ [sourceRoot, destinationRoot, assetsRoot] = await Promise.all([
221
+ resolveMigrationScopeRoot(from, context, dependencies),
222
+ resolveMigrationScopeRoot(to, context, dependencies),
223
+ dependencies.resolveAssetsRoot(),
224
+ ]);
225
+ const [sourceInventory, destinationInventory, sourceRetentions] = await Promise.all([
226
+ dependencies.inventory({
227
+ pack,
228
+ scope: from,
229
+ scopeRoot: sourceRoot,
230
+ assetsRoot,
231
+ }),
232
+ dependencies.inventory({
233
+ pack,
234
+ scope: to,
235
+ scopeRoot: destinationRoot,
236
+ assetsRoot,
237
+ }),
238
+ dependencies.resolveSharedRetentions({
239
+ packs: [pack],
240
+ scope: from,
241
+ scopeRoot: sourceRoot,
242
+ hasOwnershipEvidence: async (owner, scope, root) => hasScopedPackOwnershipEvidence({
243
+ pack: owner,
244
+ scope,
245
+ scopeRoot: root,
246
+ }),
247
+ }),
248
+ ]);
249
+ preview = dependencies.plan({
250
+ pack,
251
+ from,
252
+ to,
253
+ sourceRoot,
254
+ destinationRoot,
255
+ assetsRoot,
256
+ sourceInventory,
257
+ destinationInventory,
258
+ sourceRetentions,
259
+ });
260
+ }
261
+ catch (error) {
262
+ emitError(error, context, 1);
263
+ return;
264
+ }
265
+ if (options.dryRun) {
266
+ const outcome = {
267
+ preview,
268
+ status: preview.status === 'blocked' ? 'blocked' : 'previewed',
269
+ };
270
+ if (context.json)
271
+ emitOutcome(outcome, true, context);
272
+ else
273
+ renderPreview(preview, context);
274
+ process.exitCode = preview.status === 'blocked' ? 1 : 0;
275
+ return;
276
+ }
277
+ if (!context.json)
278
+ renderPreview(preview, context);
279
+ if (preview.status === 'blocked') {
280
+ const outcome = { preview, status: 'blocked' };
281
+ emitOutcome(outcome, false, context);
282
+ process.exitCode = 1;
283
+ return;
284
+ }
285
+ try {
286
+ const runtime = { context, assetsRoot };
287
+ const destination = await dependencies.executeDestination(preview, destinationRoot, runtime);
288
+ if (destination.status === 'destination-sync-failed') {
289
+ emitOutcome(destination, false, context);
290
+ process.exitCode = 2;
291
+ return;
292
+ }
293
+ const confirmation = context.interactive
294
+ ? (await dependencies.confirmAction(`Destination verified. Remove ${pack} from ${from} scope?`, context))
295
+ ? 'confirmed'
296
+ : 'declined'
297
+ : 'non-interactive';
298
+ const outcome = await dependencies.completeSourceRemoval(destination, { confirmation, sourceRoot, assetsRoot }, runtime);
299
+ emitOutcome(outcome, false, context);
300
+ process.exitCode =
301
+ outcome.status === 'source-removal-failed' ||
302
+ outcome.status === 'source-sync-failed'
303
+ ? 2
304
+ : confirmation === 'non-interactive'
305
+ ? 1
306
+ : 0;
307
+ }
308
+ catch (error) {
309
+ emitError(error, context, 2);
310
+ }
311
+ });
312
+ }
@@ -0,0 +1,81 @@
1
+ import { applyPackReconcilePlan, type ApplyPackReconcileDependencies } from '../../tools/shared/apply-pack-reconcile.js';
2
+ import { type ScopedPackInventory } from '../../tools/shared/pack-inventory.js';
3
+ import { planPackReconcile, type PackSharedOwnerRetention, type PackReconcilePlan } from '../../tools/shared/pack-reconcile.js';
4
+ import type { PackAssetKind, PackAssetStatus, PackName } from '../../tools/shared/types.js';
5
+ import type { ConcreteScope } from '../../../shared/types.js';
6
+ export interface MigrationAssetPreview {
7
+ assetId: string;
8
+ kind: PackAssetKind;
9
+ scope: ConcreteScope;
10
+ path: string;
11
+ status: PackAssetStatus;
12
+ reason?: string;
13
+ }
14
+ export interface PackMigrationPreview {
15
+ pack: PackName;
16
+ from: ConcreteScope;
17
+ to: ConcreteScope;
18
+ projectRoot: string;
19
+ sourceIntent: ScopedPackInventory['intent']['source'];
20
+ status: 'ready' | 'blocked';
21
+ additions: readonly MigrationAssetPreview[];
22
+ duplicates: readonly MigrationAssetPreview[];
23
+ conflicts: readonly MigrationAssetPreview[];
24
+ removals: readonly MigrationAssetPreview[];
25
+ retained: readonly MigrationAssetPreview[];
26
+ diagnostics: ScopedPackInventory['intent']['diagnostics'];
27
+ destinationPlan: PackReconcilePlan;
28
+ }
29
+ export interface MigrationPendingSync {
30
+ scope: ConcreteScope;
31
+ action: 'install' | 'remove';
32
+ projectRoot: string;
33
+ canonicalPaths: readonly string[];
34
+ command: string;
35
+ }
36
+ export interface PackMigrationOutcome {
37
+ preview: PackMigrationPreview;
38
+ status: 'previewed' | 'blocked' | 'destination-verified' | 'destination-sync-failed' | 'retained-both' | 'migrated' | 'source-removal-failed' | 'source-sync-failed';
39
+ destinationInventory?: ScopedPackInventory;
40
+ sourceInventory?: ScopedPackInventory;
41
+ recovery?: readonly string[];
42
+ pendingSync?: MigrationPendingSync;
43
+ }
44
+ export interface PlanPackMigrationInput {
45
+ pack: PackName;
46
+ from: ConcreteScope;
47
+ to: ConcreteScope;
48
+ sourceRoot: string;
49
+ destinationRoot: string;
50
+ assetsRoot: string;
51
+ sourceInventory: ScopedPackInventory;
52
+ destinationInventory: ScopedPackInventory;
53
+ sourceRetentions?: readonly PackSharedOwnerRetention[];
54
+ }
55
+ export interface MigrationSyncInput {
56
+ scope: ConcreteScope;
57
+ action: 'install' | 'remove';
58
+ canonicalPaths: readonly string[];
59
+ }
60
+ export interface ExecuteMigrationDestinationDependencies {
61
+ apply?: typeof applyPackReconcilePlan;
62
+ applyDependencies: ApplyPackReconcileDependencies;
63
+ sync?: (input: MigrationSyncInput) => Promise<void>;
64
+ }
65
+ export interface CompleteMigrationSourceRemovalInput {
66
+ confirmation: 'confirmed' | 'declined' | 'non-interactive';
67
+ sourceRoot: string;
68
+ assetsRoot: string;
69
+ }
70
+ export interface CompleteMigrationSourceRemovalDependencies {
71
+ inventory: () => Promise<ScopedPackInventory>;
72
+ plan?: typeof planPackReconcile;
73
+ apply?: typeof applyPackReconcilePlan;
74
+ applyDependencies: Omit<ApplyPackReconcileDependencies, 'inventory'>;
75
+ resolveSourceRetentions?: () => Promise<PackSharedOwnerRetention[]>;
76
+ sync?: (input: MigrationSyncInput) => Promise<void>;
77
+ }
78
+ export declare function planPackMigration(input: PlanPackMigrationInput): PackMigrationPreview;
79
+ export declare function executeMigrationDestination(preview: PackMigrationPreview, destinationRoot: string, dependencies: ExecuteMigrationDestinationDependencies): Promise<PackMigrationOutcome>;
80
+ export declare function completeMigrationSourceRemoval(destination: PackMigrationOutcome, input: CompleteMigrationSourceRemovalInput, dependencies: CompleteMigrationSourceRemovalDependencies): Promise<PackMigrationOutcome>;
81
+ //# sourceMappingURL=migrate-pack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate-pack.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/migrate/migrate-pack.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,KAAK,8BAA8B,EACpC,MAAM,6CAA6C,CAAC;AACrD,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,uCAAuC,CAAC;AAE/C,OAAO,EACL,iBAAiB,EACjB,KAAK,wBAAwB,EAC7B,KAAK,iBAAiB,EACvB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EACf,QAAQ,EACT,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,aAAa,CAAC;IACpB,KAAK,EAAE,aAAa,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,aAAa,CAAC;IACpB,EAAE,EAAE,aAAa,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,mBAAmB,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC;IACtD,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,SAAS,EAAE,SAAS,qBAAqB,EAAE,CAAC;IAC5C,UAAU,EAAE,SAAS,qBAAqB,EAAE,CAAC;IAC7C,SAAS,EAAE,SAAS,qBAAqB,EAAE,CAAC;IAC5C,QAAQ,EAAE,SAAS,qBAAqB,EAAE,CAAC;IAC3C,QAAQ,EAAE,SAAS,qBAAqB,EAAE,CAAC;IAC3C,WAAW,EAAE,mBAAmB,CAAC,QAAQ,CAAC,CAAC,aAAa,CAAC,CAAC;IAC1D,eAAe,EAAE,iBAAiB,CAAC;CACpC;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,oBAAoB,CAAC;IAC9B,MAAM,EACF,WAAW,GACX,SAAS,GACT,sBAAsB,GACtB,yBAAyB,GACzB,eAAe,GACf,UAAU,GACV,uBAAuB,GACvB,oBAAoB,CAAC;IACzB,oBAAoB,CAAC,EAAE,mBAAmB,CAAC;IAC3C,eAAe,CAAC,EAAE,mBAAmB,CAAC;IACtC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,WAAW,CAAC,EAAE,oBAAoB,CAAC;CACpC;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,aAAa,CAAC;IACpB,EAAE,EAAE,aAAa,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,mBAAmB,CAAC;IACrC,oBAAoB,EAAE,mBAAmB,CAAC;IAC1C,gBAAgB,CAAC,EAAE,SAAS,wBAAwB,EAAE,CAAC;CACxD;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,uCAAuC;IACtD,KAAK,CAAC,EAAE,OAAO,sBAAsB,CAAC;IACtC,iBAAiB,EAAE,8BAA8B,CAAC;IAClD,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrD;AAED,MAAM,WAAW,mCAAmC;IAClD,YAAY,EAAE,WAAW,GAAG,UAAU,GAAG,iBAAiB,CAAC;IAC3D,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,0CAA0C;IACzD,SAAS,EAAE,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC9C,IAAI,CAAC,EAAE,OAAO,iBAAiB,CAAC;IAChC,KAAK,CAAC,EAAE,OAAO,sBAAsB,CAAC;IACtC,iBAAiB,EAAE,IAAI,CAAC,8BAA8B,EAAE,WAAW,CAAC,CAAC;IACrE,uBAAuB,CAAC,EAAE,MAAM,OAAO,CAAC,wBAAwB,EAAE,CAAC,CAAC;IACpE,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrD;AA8BD,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,sBAAsB,GAC5B,oBAAoB,CAqJtB;AAED,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,oBAAoB,EAC7B,eAAe,EAAE,MAAM,EACvB,YAAY,EAAE,uCAAuC,GACpD,OAAO,CAAC,oBAAoB,CAAC,CA0E/B;AAsDD,wBAAsB,8BAA8B,CAClD,WAAW,EAAE,oBAAoB,EACjC,KAAK,EAAE,mCAAmC,EAC1C,YAAY,EAAE,0CAA0C,GACvD,OAAO,CAAC,oBAAoB,CAAC,CAoJ/B"}