@open-agent-toolkit/cli 0.2.53 → 0.2.54

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 (87) hide show
  1. package/assets/agents/recon-worker.md +105 -0
  2. package/assets/bundle-metadata.json +1 -1
  3. package/assets/docs/cli-utilities/tool-packs.md +62 -8
  4. package/assets/docs/contributing/skills.md +26 -0
  5. package/assets/docs/workflows/skills/index.md +3 -0
  6. package/assets/docs/workflows/skills/recon.md +194 -0
  7. package/assets/public-package-versions.json +4 -4
  8. package/assets/skills/oat-dispatch-subagents/SKILL.md +105 -4
  9. package/assets/skills/oat-dispatch-subagents/references/record-schema.md +226 -0
  10. package/assets/skills/oat-project-autonomous/references/gate-inventory.md +2 -2
  11. package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +2 -2
  12. package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +2 -2
  13. package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +2 -2
  14. package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +2 -2
  15. package/assets/skills/recon/SKILL.md +260 -0
  16. package/assets/skills/recon/references/packet-contract.md +307 -0
  17. package/assets/skills/recon/references/profiles.md +58 -0
  18. package/assets/skills/recon/references/worker-contract.md +71 -0
  19. package/assets/skills/recon/scripts/create-review-brief.mjs +452 -0
  20. package/assets/skills/recon/scripts/lib/canonical-json.mjs +55 -0
  21. package/assets/skills/recon/scripts/lib/contracts.mjs +2462 -0
  22. package/assets/skills/recon/scripts/lib/safe-path.mjs +120 -0
  23. package/assets/skills/recon/scripts/lib/validated-run.mjs +86 -0
  24. package/assets/skills/recon/scripts/reconcile-ledger.mjs +360 -0
  25. package/assets/skills/recon/scripts/render-packet.mjs +392 -0
  26. package/assets/skills/recon/scripts/validate-artifact.mjs +96 -0
  27. package/assets/skills/recon/scripts/validate-packet.mjs +2359 -0
  28. package/dist/commands/doctor/index.js +5 -5
  29. package/dist/commands/init/index.d.ts.map +1 -1
  30. package/dist/commands/init/index.js +6 -7
  31. package/dist/commands/status/index.d.ts +2 -2
  32. package/dist/commands/status/index.d.ts.map +1 -1
  33. package/dist/commands/status/index.js +7 -4
  34. package/dist/commands/sync/index.d.ts.map +1 -1
  35. package/dist/commands/sync/index.js +24 -8
  36. package/dist/commands/sync/sync.types.d.ts +2 -2
  37. package/dist/commands/sync/sync.types.d.ts.map +1 -1
  38. package/dist/commands/tools/migrate/index.d.ts.map +1 -1
  39. package/dist/commands/tools/migrate/index.js +25 -1
  40. package/dist/commands/tools/migrate/migrate-pack.d.ts +5 -0
  41. package/dist/commands/tools/migrate/migrate-pack.d.ts.map +1 -1
  42. package/dist/commands/tools/migrate/migrate-pack.js +66 -7
  43. package/dist/commands/tools/remove/index.js +1 -1
  44. package/dist/commands/tools/remove/remove-tools.d.ts +5 -1
  45. package/dist/commands/tools/remove/remove-tools.d.ts.map +1 -1
  46. package/dist/commands/tools/remove/remove-tools.js +81 -1
  47. package/dist/commands/tools/shared/apply-pack-reconcile.d.ts +3 -0
  48. package/dist/commands/tools/shared/apply-pack-reconcile.d.ts.map +1 -1
  49. package/dist/commands/tools/shared/apply-pack-reconcile.js +40 -9
  50. package/dist/commands/tools/shared/format-pack-inventory.d.ts.map +1 -1
  51. package/dist/commands/tools/shared/format-pack-inventory.js +3 -0
  52. package/dist/commands/tools/shared/install-sync-context.d.ts +2 -1
  53. package/dist/commands/tools/shared/install-sync-context.d.ts.map +1 -1
  54. package/dist/commands/tools/shared/install-sync-context.js +14 -3
  55. package/dist/commands/tools/shared/pack-dependencies.d.ts +14 -0
  56. package/dist/commands/tools/shared/pack-dependencies.d.ts.map +1 -0
  57. package/dist/commands/tools/shared/pack-dependencies.js +54 -0
  58. package/dist/commands/tools/shared/pack-inventory.d.ts.map +1 -1
  59. package/dist/commands/tools/shared/pack-inventory.js +9 -9
  60. package/dist/commands/tools/shared/pack-lifecycle.d.ts +9 -1
  61. package/dist/commands/tools/shared/pack-lifecycle.d.ts.map +1 -1
  62. package/dist/commands/tools/shared/pack-lifecycle.js +102 -9
  63. package/dist/commands/tools/shared/pack-manifest.d.ts +2 -2
  64. package/dist/commands/tools/shared/pack-manifest.d.ts.map +1 -1
  65. package/dist/commands/tools/shared/pack-manifest.js +91 -2
  66. package/dist/commands/tools/shared/pack-reconcile.d.ts +15 -1
  67. package/dist/commands/tools/shared/pack-reconcile.d.ts.map +1 -1
  68. package/dist/commands/tools/shared/pack-reconcile.js +75 -13
  69. package/dist/commands/tools/shared/scoped-pack-intent.d.ts +8 -0
  70. package/dist/commands/tools/shared/scoped-pack-intent.d.ts.map +1 -1
  71. package/dist/commands/tools/shared/scoped-pack-intent.js +61 -15
  72. package/dist/commands/tools/shared/types.d.ts +7 -0
  73. package/dist/commands/tools/shared/types.d.ts.map +1 -1
  74. package/dist/commands/tools/update/update-tools.d.ts.map +1 -1
  75. package/dist/commands/tools/update/update-tools.js +7 -1
  76. package/dist/config/oat-config.d.ts +5 -1
  77. package/dist/config/oat-config.d.ts.map +1 -1
  78. package/dist/config/oat-config.js +19 -0
  79. package/dist/engine/index.d.ts +1 -1
  80. package/dist/engine/index.d.ts.map +1 -1
  81. package/dist/engine/scanner.d.ts +9 -1
  82. package/dist/engine/scanner.d.ts.map +1 -1
  83. package/dist/engine/scanner.js +61 -4
  84. package/dist/shared/types.d.ts +1 -0
  85. package/dist/shared/types.d.ts.map +1 -1
  86. package/dist/shared/types.js +3 -0
  87. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"remove-tools.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/remove/remove-tools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"remove-tools.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/remove/remove-tools.ts"],"names":[],"mappings":"AAMA,OAAO,EAEL,KAAK,wBAAwB,EAC7B,KAAK,mBAAmB,EACzB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACzB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,+CAA+C,CAAC;AAG1F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,KAAK,EAEV,QAAQ,EACR,QAAQ,EACT,MAAM,8BAA8B,CAAC;AAMtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,KAAK,CAAA;CAAE,CAAC;AAEpB,MAAM,WAAW,uBAAuB;IACtC,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,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,wBAAwB,EAAE,CACxB,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,aAAa,EACpB,SAAS,EAAE,MAAM,KACd,OAAO,CAAC,OAAO,CAAC,CAAC;IACtB,cAAc,CAAC,EAAE,CACf,QAAQ,EAAE,SAAS,oBAAoB,EAAE,EACzC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAC3B,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;IACpC,mBAAmB,CAAC,EAAE,CACpB,KAAK,EAAE,wBAAwB,KAC5B,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAClC,qBAAqB,CAAC,EAAE,CAAC,KAAK,EAAE;QAC9B,IAAI,EAAE,QAAQ,CAAC;QACf,KAAK,EAAE,aAAa,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,OAAO,CAAC;KAClB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACxB;AAED,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IACxB,KAAK,EAAE,aAAa,CAAC;CACtB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,aAAa,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,aAAa,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,aAAa,CAAA;KAAE,CAAC,CAAC;IAC7D,iBAAiB,EAAE,KAAK,CAAC;QACvB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,aAAa,CAAC;QACrB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;IACH,YAAY,EAAE,kBAAkB,EAAE,CAAC;IACnC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,CAAC,EAAE,oBAAoB,EAAE,CAAC;CACpC;AA6DD,wBAAgB,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,cAI5E;AA8ID,wBAAsB,WAAW,CAC/B,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,aAAa,EAAE,EACvB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,OAAO,EACf,IAAI,EAAE,uBAAuB,GAC5B,OAAO,CAAC,YAAY,CAAC,CA2NvB;AAED,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,SAAS,QAAQ,EAAE,EAC1B,MAAM,EAAE,SAAS,aAAa,EAAE,EAChC,QAAQ,EAAE,SAAS,kBAAkB,EAAE,EACvC,MAAM,EAAE,OAAO,EACf,gBAAgB,EAAE,SAAS,mBAAmB,EAAE,GAC/C,oBAAoB,EAAE,CAgExB;AAED,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,OAAO,CAAC,YAAY,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,EAC/C,MAAM,EAAE,SAAS,aAAa,EAAE,EAChC,KAAK,EAAE,OAAO,GACb,oBAAoB,EAAE,CAmBxB;AAED,wBAAgB,kCAAkC,CAChD,MAAM,EAAE,OAAO,CAAC,YAAY,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,EAC/C,MAAM,EAAE,SAAS,aAAa,EAAE,EAChC,QAAQ,EAAE,SAAS,kBAAkB,EAAE,EACvC,KAAK,EAAE,cAAc,GAAG,iBAAiB,EACzC,UAAU,EAAE,QAAQ,EACpB,WAAW,EAAE,aAAa,EAC1B,KAAK,EAAE,OAAO,GACb,oBAAoB,EAAE,CAqCxB"}
@@ -1,5 +1,7 @@
1
1
  import { join } from 'node:path';
2
2
  import { packScopeFactsFromInventory, projectPackEvidence, } from '../../tools/shared/pack-evidence.js';
3
+ import { hasScopedPackPlacementEvidence, } from '../../tools/shared/pack-inventory.js';
4
+ import {} from '../../tools/shared/pack-lifecycle.js';
3
5
  import { PACK_MANIFEST } from '../../tools/shared/pack-manifest.js';
4
6
  import { resolveSharedOwnerRetentions } from '../../tools/shared/pack-reconcile.js';
5
7
  import { resolveManagedScopeRoots, validateManagedPath, } from '../../../fs/paths.js';
@@ -121,6 +123,7 @@ export async function removeTools(target, scopes, cwd, home, dryRun, deps) {
121
123
  const removed = [];
122
124
  const removedAssets = [];
123
125
  const retainedOwnerData = [];
126
+ const packOutcomes = [];
124
127
  const assetsRoot = await deps.resolveAssetsRoot();
125
128
  if (target.kind === 'name') {
126
129
  for (const scope of scopes) {
@@ -140,7 +143,84 @@ export async function removeTools(target, scopes, cwd, home, dryRun, deps) {
140
143
  notInstalled: removed.length === 0 ? [target.name] : [],
141
144
  };
142
145
  }
143
- const packOutcomes = [];
146
+ if (deps.reconcilePacks) {
147
+ const packs = selectedPacks(target);
148
+ const requests = [];
149
+ const roots = new Map();
150
+ for (const scope of scopes) {
151
+ const scopeRoot = await deps.resolveScopeRoot(scope, cwd, home);
152
+ roots.set(scope, scopeRoot);
153
+ for (const pack of packs) {
154
+ const definition = PACK_MANIFEST.find(({ name }) => name === pack);
155
+ if (!definition.allowedScopes.includes(scope))
156
+ continue;
157
+ requests.push({
158
+ pack,
159
+ scope,
160
+ scopeRoot,
161
+ assetsRoot,
162
+ action: 'remove',
163
+ });
164
+ }
165
+ }
166
+ const lifecycle = await deps.reconcilePacks(requests, { dryRun });
167
+ for (const entry of lifecycle) {
168
+ for (const operation of entry.plan.operations) {
169
+ if (operation.kind !== 'remove-dir' &&
170
+ operation.kind !== 'remove-file') {
171
+ continue;
172
+ }
173
+ removedAssets.push({
174
+ path: operation.path,
175
+ scope: entry.request.scope,
176
+ });
177
+ const asset = entry.before.assets.find(({ definition }) => definition.id === operation.assetId)?.definition;
178
+ if (asset?.kind === 'skill' || asset?.kind === 'agent') {
179
+ removed.push({
180
+ name: asset.destination.split('/').at(-1).replace(/\.md$/, ''),
181
+ type: asset.kind,
182
+ scope: entry.request.scope,
183
+ });
184
+ }
185
+ }
186
+ retainedOwnerData.push(...entry.plan.retainedAssets.map(({ path }) => ({
187
+ path,
188
+ scope: entry.request.scope,
189
+ reason: 'retained shared owner data',
190
+ })), ...entry.plan.retainedDependencyAssetIds.map((assetId) => ({
191
+ path: entry.before.assets.find(({ definition }) => definition.id === assetId)?.path ?? assetId,
192
+ scope: entry.request.scope,
193
+ reason: 'retained dependency lease',
194
+ })));
195
+ }
196
+ for (const request of requests) {
197
+ const entry = lifecycle.find(({ request: candidate }) => !candidate.dependency &&
198
+ candidate.pack === request.pack &&
199
+ candidate.scope === request.scope);
200
+ packOutcomes.push({
201
+ pack: request.pack,
202
+ scope: request.scope,
203
+ removed: entry ? hasScopedPackPlacementEvidence(entry.before) : false,
204
+ });
205
+ }
206
+ if (target.kind === 'all') {
207
+ for (const scope of scopes) {
208
+ const scopeRoot = roots.get(scope);
209
+ const tools = await deps.scanTools({ scope, scopeRoot, assetsRoot });
210
+ for (const tool of tools.filter(({ pack }) => pack === 'custom')) {
211
+ await removeTool(tool, scopeRoot, dryRun, deps);
212
+ removed.push({ name: tool.name, type: tool.type, scope: tool.scope });
213
+ }
214
+ }
215
+ }
216
+ return {
217
+ removed,
218
+ removedAssets,
219
+ retainedOwnerData,
220
+ packOutcomes,
221
+ notInstalled: [],
222
+ };
223
+ }
144
224
  const plans = [];
145
225
  for (const scope of scopes) {
146
226
  const scopeRoot = await deps.resolveScopeRoot(scope, cwd, home);
@@ -17,6 +17,9 @@ export interface ApplyPackReconcileDependencies {
17
17
  writeIntent: (operation: Extract<PackReconcileOperation, {
18
18
  kind: 'write-intent';
19
19
  }>) => Promise<void>;
20
+ writeLease?: (operation: Extract<PackReconcileOperation, {
21
+ kind: 'write-lease';
22
+ }>) => Promise<void>;
20
23
  inventory: () => Promise<ScopedPackInventory>;
21
24
  sync?: (input: {
22
25
  scope: PackReconcilePlan['scope'];
@@ -1 +1 @@
1
- {"version":3,"file":"apply-pack-reconcile.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/shared/apply-pack-reconcile.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,mBAAmB,EAGzB,MAAM,WAAW,CAAC;AAEnB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,KAAK,EACV,sBAAsB,EACtB,iBAAiB,EAClB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,8BAA8B;IAC7C,mBAAmB,CAAC,EAAE,CACpB,SAAS,EAAE,MAAM,KACd,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAC3D,YAAY,CAAC,EAAE,CACb,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,mBAAmB,KAC7B,OAAO,CAAC;QAAE,eAAe,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5D,aAAa,CAAC,EAAE,CACd,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,OAAO,KACX,OAAO,CAAC,OAAO,CAAC,CAAC;IACtB,QAAQ,CAAC,EAAE,CACT,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,OAAO,KACX,OAAO,CAAC,OAAO,CAAC,CAAC;IACtB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,cAAc,EAAE,CACd,SAAS,EAAE,OAAO,CAAC,sBAAsB,EAAE;QAAE,IAAI,EAAE,iBAAiB,CAAA;KAAE,CAAC,KACpE,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,WAAW,EAAE,CACX,SAAS,EAAE,OAAO,CAAC,sBAAsB,EAAE;QAAE,IAAI,EAAE,cAAc,CAAA;KAAE,CAAC,KACjE,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,SAAS,EAAE,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC9C,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE;QACb,KAAK,EAAE,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAClC,MAAM,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QACpC,qBAAqB,EAAE,SAAS,MAAM,EAAE,CAAC;KAC1C,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,SAAS,sBAAsB,EAAE,CAAC;IAC3C,SAAS,EAAE,mBAAmB,CAAC;IAC/B,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,kCAAkC;IACjD,mBAAmB,CAAC,EAAE,8BAA8B,CAAC,qBAAqB,CAAC,CAAC;IAC5E,YAAY,CAAC,EAAE,8BAA8B,CAAC,cAAc,CAAC,CAAC;CAC/D;AAwBD,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,SAAS;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,EAAE,EAClE,YAAY,GAAE,kCAAuC,GACpD,OAAO,CAAC,IAAI,CAAC,CAsBf;AA2BD,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,iBAAiB,EACvB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,8BAA8B,GAC3C,OAAO,CAAC,wBAAwB,CAAC,CAoFnC"}
1
+ {"version":3,"file":"apply-pack-reconcile.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/shared/apply-pack-reconcile.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,mBAAmB,EAGzB,MAAM,WAAW,CAAC;AAEnB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,KAAK,EACV,sBAAsB,EACtB,iBAAiB,EAClB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,8BAA8B;IAC7C,mBAAmB,CAAC,EAAE,CACpB,SAAS,EAAE,MAAM,KACd,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAC3D,YAAY,CAAC,EAAE,CACb,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,mBAAmB,KAC7B,OAAO,CAAC;QAAE,eAAe,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5D,aAAa,CAAC,EAAE,CACd,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,OAAO,KACX,OAAO,CAAC,OAAO,CAAC,CAAC;IACtB,QAAQ,CAAC,EAAE,CACT,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,OAAO,KACX,OAAO,CAAC,OAAO,CAAC,CAAC;IACtB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,cAAc,EAAE,CACd,SAAS,EAAE,OAAO,CAAC,sBAAsB,EAAE;QAAE,IAAI,EAAE,iBAAiB,CAAA;KAAE,CAAC,KACpE,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,WAAW,EAAE,CACX,SAAS,EAAE,OAAO,CAAC,sBAAsB,EAAE;QAAE,IAAI,EAAE,cAAc,CAAA;KAAE,CAAC,KACjE,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,UAAU,CAAC,EAAE,CACX,SAAS,EAAE,OAAO,CAAC,sBAAsB,EAAE;QAAE,IAAI,EAAE,aAAa,CAAA;KAAE,CAAC,KAChE,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,SAAS,EAAE,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC9C,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE;QACb,KAAK,EAAE,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAClC,MAAM,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QACpC,qBAAqB,EAAE,SAAS,MAAM,EAAE,CAAC;KAC1C,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,SAAS,sBAAsB,EAAE,CAAC;IAC3C,SAAS,EAAE,mBAAmB,CAAC;IAC/B,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,kCAAkC;IACjD,mBAAmB,CAAC,EAAE,8BAA8B,CAAC,qBAAqB,CAAC,CAAC;IAC5E,YAAY,CAAC,EAAE,8BAA8B,CAAC,cAAc,CAAC,CAAC;CAC/D;AAyBD,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,SAAS;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,EAAE,EAClE,YAAY,GAAE,kCAAuC,GACpD,OAAO,CAAC,IAAI,CAAC,CAsBf;AAqDD,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,iBAAiB,EACvB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,8BAA8B,GAC3C,OAAO,CAAC,wBAAwB,CAAC,CA6FnC"}
@@ -12,6 +12,7 @@ function operationPath(operation) {
12
12
  case 'remove-file':
13
13
  return operation.path;
14
14
  case 'write-intent':
15
+ case 'write-lease':
15
16
  return null;
16
17
  }
17
18
  }
@@ -46,12 +47,32 @@ export async function preflightPackReconcilePlans(entries, dependencies = {}) {
46
47
  function assertExpectedInventory(plan, inventory) {
47
48
  if (inventory.pack !== plan.pack ||
48
49
  inventory.scope !== plan.scope ||
49
- inventory.completeness !== plan.expectedCompleteness) {
50
+ (plan.expectedCompleteness !== null &&
51
+ inventory.completeness !== plan.expectedCompleteness)) {
50
52
  throw new Error(`Pack ${plan.pack} ${plan.scope} verification expected ${plan.expectedCompleteness} but found ${inventory.completeness}`);
51
53
  }
54
+ if (plan.expectedAssetStatuses) {
55
+ const invalid = inventory.assets.filter(({ definition, status }) => {
56
+ const expected = plan.expectedAssetStatuses?.[definition.id];
57
+ return expected !== undefined && status !== expected;
58
+ });
59
+ if (invalid.length > 0) {
60
+ throw new Error(`Pack ${plan.pack} ${plan.scope} verification expected selected asset states: ${invalid.map(({ definition, status }) => `${definition.id} expected ${plan.expectedAssetStatuses?.[definition.id]} (${status})`).join(', ')}`);
61
+ }
62
+ }
63
+ else if (plan.expectedAssetStatus) {
64
+ const invalid = inventory.assets.filter(({ definition, status }) => plan.selectedAssetIds.includes(definition.id) &&
65
+ status !== plan.expectedAssetStatus);
66
+ if (invalid.length > 0) {
67
+ throw new Error(`Pack ${plan.pack} ${plan.scope} verification expected selected assets ${plan.expectedAssetStatus}: ${invalid.map(({ definition, status }) => `${definition.id} (${status})`).join(', ')}`);
68
+ }
69
+ }
52
70
  if (plan.action === 'remove')
53
71
  return;
54
- const drifted = inventory.assets.filter(({ definition, status }) => definition.ownership[plan.scope] === 'managed' && status !== 'current');
72
+ const drifted = inventory.assets.filter(({ definition, status }) => definition.ownership[plan.scope] === 'managed' &&
73
+ (plan.expectedCompleteness !== null ||
74
+ plan.selectedAssetIds.includes(definition.id)) &&
75
+ status !== 'current');
55
76
  if (drifted.length > 0) {
56
77
  throw new Error(`Pack ${plan.pack} ${plan.scope} verification found drifted managed assets: ${drifted.map(({ definition, status }) => `${definition.id} (${status})`).join(', ')}`);
57
78
  }
@@ -70,10 +91,10 @@ export async function applyPackReconcilePlan(plan, scopeRoot, dependencies) {
70
91
  validatedPaths.set(path, realPath);
71
92
  }
72
93
  const applied = [];
73
- const intents = [];
94
+ const stateOperations = [];
74
95
  for (const operation of plan.operations) {
75
- if (operation.kind === 'write-intent') {
76
- intents.push(operation);
96
+ if (operation.kind === 'write-intent' || operation.kind === 'write-lease') {
97
+ stateOperations.push(operation);
77
98
  continue;
78
99
  }
79
100
  const path = operationPath(operation);
@@ -108,11 +129,21 @@ export async function applyPackReconcilePlan(plan, scopeRoot, dependencies) {
108
129
  }
109
130
  const verifiedInventory = await dependencies.inventory();
110
131
  assertExpectedInventory(plan, verifiedInventory);
111
- for (const intent of intents) {
112
- await dependencies.writeIntent(intent);
113
- applied.push(intent);
132
+ for (const operation of stateOperations) {
133
+ if (operation.kind === 'write-intent') {
134
+ await dependencies.writeIntent(operation);
135
+ }
136
+ else {
137
+ if (!dependencies.writeLease) {
138
+ throw new Error('Pack dependency reconciliation requires writeLease');
139
+ }
140
+ await dependencies.writeLease(operation);
141
+ }
142
+ applied.push(operation);
114
143
  }
115
- const inventory = intents.length > 0 ? await dependencies.inventory() : verifiedInventory;
144
+ const inventory = stateOperations.length > 0
145
+ ? await dependencies.inventory()
146
+ : verifiedInventory;
116
147
  assertExpectedInventory(plan, inventory);
117
148
  const shouldSync = plan.changedCanonicalPaths.length > 0 && dependencies.sync;
118
149
  if (shouldSync) {
@@ -1 +1 @@
1
- {"version":3,"file":"format-pack-inventory.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/shared/format-pack-inventory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EAIL,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EACtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,CAAC,CAAC;IACjB,MAAM,EAAE,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC;IACnC,KAAK,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACnC,WAAW,EAAE,SAAS,sBAAsB,EAAE,CAAC;CAChD;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE;IAC7C,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB,GAAG,gBAAgB,CAiBnB;AA4CD,wBAAgB,6BAA6B,CAC3C,SAAS,EAAE,aAAa,EACxB,KAAK,EAAE,aAAa,GACnB,gBAAgB,CAiClB;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,SAAS,gBAAgB,EAAE,GACjC,mBAAmB,CAQrB;AAUD,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,gBAAgB,EAC1B,MAAM,SAAO,GACZ,MAAM,EAAE,CAuBV;AAED,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,aAAa,EACxB,MAAM,SAAO,GACZ,MAAM,EAAE,CAuBV"}
1
+ {"version":3,"file":"format-pack-inventory.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/shared/format-pack-inventory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EAIL,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EACtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,CAAC,CAAC;IACjB,MAAM,EAAE,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC;IACnC,KAAK,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACnC,WAAW,EAAE,SAAS,sBAAsB,EAAE,CAAC;CAChD;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE;IAC7C,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB,GAAG,gBAAgB,CAoBnB;AA4CD,wBAAgB,6BAA6B,CAC3C,SAAS,EAAE,aAAa,EACxB,KAAK,EAAE,aAAa,GACnB,gBAAgB,CAiClB;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,SAAS,gBAAgB,EAAE,GACjC,mBAAmB,CAQrB;AAUD,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,gBAAgB,EAC1B,MAAM,SAAO,GACZ,MAAM,EAAE,CAuBV;AAED,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,aAAa,EACxB,MAAM,SAAO,GACZ,MAAM,EAAE,CAuBV"}
@@ -9,6 +9,9 @@ export function unavailablePackEvidence(input) {
9
9
  pack: input.pack,
10
10
  scope,
11
11
  enabled: false,
12
+ direct: false,
13
+ requiredBy: [],
14
+ state: 'absent',
12
15
  source: 'none',
13
16
  configPath: `${scope === 'project' ? '<project>' : '~'}/.oat/config.json`,
14
17
  diagnostics: [],
@@ -1,8 +1,9 @@
1
1
  import type { PackName } from '../../tools/shared/types.js';
2
2
  import type { Command } from 'commander';
3
+ import type { PackDefinition } from './types.js';
3
4
  export declare function canonicalSkillPaths(skillNames: readonly string[]): string[];
4
5
  export declare function canonicalAgentPaths(agentNames: readonly string[]): string[];
5
- export declare function canonicalPathsForPack(pack: PackName): string[];
6
+ export declare function canonicalPathsForPack(pack: PackName, resolveDefinition?: (pack: PackName) => PackDefinition): string[];
6
7
  export declare function canonicalPathsForPacks(packs: readonly PackName[]): string[];
7
8
  export declare function setInstalledCanonicalPaths(command: Command, canonicalPaths: readonly string[]): void;
8
9
  export declare function getInstalledCanonicalPaths(command: Command): string[];
@@ -1 +1 @@
1
- {"version":3,"file":"install-sync-context.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/shared/install-sync-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUzC,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAI3E;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAI3E;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,EAAE,CAE9D;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,GAAG,MAAM,EAAE,CAI3E;AAED,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,OAAO,EAChB,cAAc,EAAE,SAAS,MAAM,EAAE,GAChC,IAAI,CAMN;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,EAAE,CAGrE"}
1
+ {"version":3,"file":"install-sync-context.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/shared/install-sync-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGzC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAQ9C,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAI3E;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAI3E;AAED,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,QAAQ,EACd,iBAAiB,GAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,cAAkC,GACxE,MAAM,EAAE,CAgBV;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,GAAG,MAAM,EAAE,CAI3E;AAED,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,OAAO,EAChB,cAAc,EAAE,SAAS,MAAM,EAAE,GAChC,IAAI,CAMN;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,EAAE,CAGrE"}
@@ -1,4 +1,4 @@
1
- import { getCanonicalProviderPaths } from './pack-manifest.js';
1
+ import { getPackDefinition } from './pack-manifest.js';
2
2
  const INSTALL_SYNC_CANONICAL_PATHS = Symbol('oat.installSyncCanonicalPaths');
3
3
  function uniqueCanonicalPaths(paths) {
4
4
  return [...new Set(paths)];
@@ -9,8 +9,19 @@ export function canonicalSkillPaths(skillNames) {
9
9
  export function canonicalAgentPaths(agentNames) {
10
10
  return uniqueCanonicalPaths(agentNames.map((agentName) => `.agents/agents/${agentName}`));
11
11
  }
12
- export function canonicalPathsForPack(pack) {
13
- return getCanonicalProviderPaths(pack);
12
+ export function canonicalPathsForPack(pack, resolveDefinition = getPackDefinition) {
13
+ const definition = resolveDefinition(pack);
14
+ const direct = definition.assets
15
+ .filter(({ kind }) => kind === 'skill' || kind === 'agent')
16
+ .map(({ destination }) => destination);
17
+ const dependencies = (definition.dependencies ?? []).flatMap((dependency) => {
18
+ const owner = resolveDefinition(dependency.pack);
19
+ const selected = new Set(dependency.assets);
20
+ return owner.assets
21
+ .filter(({ id, kind }) => selected.has(id) && (kind === 'skill' || kind === 'agent'))
22
+ .map(({ destination }) => destination);
23
+ });
24
+ return uniqueCanonicalPaths([...direct, ...dependencies]);
14
25
  }
15
26
  export function canonicalPathsForPacks(packs) {
16
27
  return uniqueCanonicalPaths(packs.flatMap((pack) => canonicalPathsForPack(pack)));
@@ -0,0 +1,14 @@
1
+ import type { PackLifecycleRequest } from './pack-lifecycle.js';
2
+ import type { PackDefinition, PackName } from './types.js';
3
+ export interface PackDependencyLease {
4
+ requiredBy: PackName;
5
+ lease: 'acquire' | 'release';
6
+ }
7
+ export interface ExpandedPackLifecycleRequest extends PackLifecycleRequest {
8
+ assetIds?: readonly string[];
9
+ dependency?: PackDependencyLease;
10
+ }
11
+ export type PackDefinitionResolver = (pack: PackName) => PackDefinition;
12
+ export declare function expandPackLifecycleRequests(requests: readonly PackLifecycleRequest[], resolveDefinition?: PackDefinitionResolver): ExpandedPackLifecycleRequest[];
13
+ export declare function dependencyRetainedAssetIds(pack: PackName, requiredBy: readonly PackName[], resolveDefinition?: PackDefinitionResolver): string[];
14
+ //# sourceMappingURL=pack-dependencies.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pack-dependencies.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/shared/pack-dependencies.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE7D,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExD,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,QAAQ,CAAC;IACrB,KAAK,EAAE,SAAS,GAAG,SAAS,CAAC;CAC9B;AAED,MAAM,WAAW,4BAA6B,SAAQ,oBAAoB;IACxE,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,UAAU,CAAC,EAAE,mBAAmB,CAAC;CAClC;AAED,MAAM,MAAM,sBAAsB,GAAG,CAAC,IAAI,EAAE,QAAQ,KAAK,cAAc,CAAC;AAcxE,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,SAAS,oBAAoB,EAAE,EACzC,iBAAiB,GAAE,sBAA0C,GAC5D,4BAA4B,EAAE,CAmChC;AAED,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,QAAQ,EACd,UAAU,EAAE,SAAS,QAAQ,EAAE,EAC/B,iBAAiB,GAAE,sBAA0C,GAC5D,MAAM,EAAE,CAUV"}
@@ -0,0 +1,54 @@
1
+ import { getPackDefinition } from './pack-manifest.js';
2
+ function requestKey(request) {
3
+ return JSON.stringify({
4
+ pack: request.pack,
5
+ scope: request.scope,
6
+ scopeRoot: request.scopeRoot,
7
+ assetsRoot: request.assetsRoot,
8
+ action: request.action,
9
+ assetIds: [...(request.assetIds ?? [])].sort(),
10
+ dependency: request.dependency ?? null,
11
+ });
12
+ }
13
+ export function expandPackLifecycleRequests(requests, resolveDefinition = getPackDefinition) {
14
+ const expanded = [];
15
+ const seen = new Set();
16
+ const append = (request) => {
17
+ const key = requestKey(request);
18
+ if (seen.has(key))
19
+ return;
20
+ seen.add(key);
21
+ expanded.push(request);
22
+ };
23
+ const visit = (request) => {
24
+ const dependencies = resolveDefinition(request.pack).dependencies ?? [];
25
+ const dependencyRequests = dependencies.map((dependency) => ({
26
+ pack: dependency.pack,
27
+ scope: request.scope,
28
+ scopeRoot: request.scopeRoot,
29
+ assetsRoot: request.assetsRoot,
30
+ action: request.action,
31
+ assetIds: [...dependency.assets],
32
+ dependency: {
33
+ requiredBy: request.pack,
34
+ lease: request.action === 'remove' ? 'release' : 'acquire',
35
+ },
36
+ }));
37
+ if (request.action === 'remove')
38
+ append(request);
39
+ for (const dependency of dependencyRequests)
40
+ visit(dependency);
41
+ if (request.action !== 'remove')
42
+ append(request);
43
+ };
44
+ for (const request of requests)
45
+ visit(request);
46
+ return expanded;
47
+ }
48
+ export function dependencyRetainedAssetIds(pack, requiredBy, resolveDefinition = getPackDefinition) {
49
+ return [
50
+ ...new Set(requiredBy.flatMap((consumer) => (resolveDefinition(consumer).dependencies ?? [])
51
+ .filter((dependency) => dependency.pack === pack)
52
+ .flatMap((dependency) => dependency.assets))),
53
+ ].sort();
54
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"pack-inventory.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/shared/pack-inventory.ts"],"names":[],"mappings":"AAaA,OAAO,EACL,KAAK,aAAa,EAEnB,MAAM,eAAe,CAAC;AAIvB,OAAO,EAEL,KAAK,gBAAgB,EAEtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EACV,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,QAAQ,EACT,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,mBAAmB,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,CAAC;IACxB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EACA,uBAAuB,GACvB,iBAAiB,GACjB,0BAA0B,GAC1B,2BAA2B,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,EAAE,gBAAgB,CAAC;IACzB,YAAY,EAAE,gBAAgB,CAAC;IAC/B,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,WAAW,EAAE,cAAc,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,QAAQ,CAAC;IACf,iFAAiF;IACjF,SAAS,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,aAAa,CAAC;IACvD,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAC9B,WAAW,EAAE,cAAc,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,aAAa,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,0BAA0B,CAAC,EAAE,OAAO,CAAC;CACtC;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8BAA8B,CAAC,EAAE,OAAO,CAAC;CAC1C;AAiRD,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,wBAAwB,GAC9B,OAAO,CAAC,mBAAmB,CAAC,CAwC9B;AAED,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,mBAAmB,GAC7B,OAAO,CAUT;AAED;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAC7C,WAAW,EAAE,aAAa,EAAE,GAC3B,aAAa,EAAE,CAgEjB;AAED,wBAAsB,aAAa,CACjC,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC,aAAa,CAAC,CAiDxB"}
1
+ {"version":3,"file":"pack-inventory.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/shared/pack-inventory.ts"],"names":[],"mappings":"AAaA,OAAO,EAEL,KAAK,aAAa,EACnB,MAAM,eAAe,CAAC;AAIvB,OAAO,EAEL,KAAK,gBAAgB,EAEtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EACV,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,QAAQ,EACT,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,mBAAmB,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,CAAC;IACxB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EACA,uBAAuB,GACvB,iBAAiB,GACjB,0BAA0B,GAC1B,2BAA2B,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,EAAE,gBAAgB,CAAC;IACzB,YAAY,EAAE,gBAAgB,CAAC;IAC/B,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,WAAW,EAAE,cAAc,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,QAAQ,CAAC;IACf,iFAAiF;IACjF,SAAS,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,aAAa,CAAC;IACvD,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAC9B,WAAW,EAAE,cAAc,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,aAAa,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,0BAA0B,CAAC,EAAE,OAAO,CAAC;CACtC;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8BAA8B,CAAC,EAAE,OAAO,CAAC;CAC1C;AAmRD,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,wBAAwB,GAC9B,OAAO,CAAC,mBAAmB,CAAC,CAwC9B;AAED,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,mBAAmB,GAC7B,OAAO,CAUT;AAED;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAC7C,WAAW,EAAE,aAAa,EAAE,GAC3B,aAAa,EAAE,CAgEjB;AAED,wBAAsB,aAAa,CACjC,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC,aAAa,CAAC,CAiDxB"}
@@ -4,7 +4,7 @@ import { compareVersions } from '../../init/tools/shared/version.js';
4
4
  import { getAgentVersion, getSkillVersion } from '../../shared/frontmatter.js';
5
5
  import { readOatConfig } from '../../../config/oat-config.js';
6
6
  import { resolveManagedScopeRoots, validateManagedPath, validateRealPathWithinScope, } from '../../../fs/paths.js';
7
- import { USER_SCOPE_MANAGED_AGENT_FILES, } from '../../../shared/types.js';
7
+ import { isBuiltInUserScopeManagedAgentFile, } from '../../../shared/types.js';
8
8
  import { digestDirectory, digestFile } from './content-digest.js';
9
9
  import { getPackDefinition, PACK_NAMES } from './pack-manifest.js';
10
10
  import { readScopedPackIntent, } from './scoped-pack-intent.js';
@@ -174,27 +174,27 @@ function intentDiagnostic(diagnostic) {
174
174
  /**
175
175
  * User-scope canonical agents are installed into `~/.agents/agents/`, while
176
176
  * native provider-role materialization is caller-resolved from the active
177
- * config-aware adapter set. When that capability is active, only the bundled
178
- * managed role file set (`USER_SCOPE_MANAGED_AGENT_FILES`) is supplied to the
179
- * extension. Completeness alone therefore cannot describe native
180
- * materialization, so the remaining gap is named here instead of staying
181
- * silent. Canonical instruction-read availability is a separate contract.
177
+ * config-aware adapter set. When that capability is active, it supplies the
178
+ * bundled managed role file set plus explicitly user-materializable pack
179
+ * agents. Completeness alone therefore cannot describe native materialization,
180
+ * so the remaining gap is named here instead of staying silent. Canonical
181
+ * instruction-read availability is a separate contract.
182
182
  */
183
183
  function userAgentMaterializationDiagnostics(pack, scope, assets, managedRoleMaterialization) {
184
184
  if (scope !== 'user')
185
185
  return [];
186
- const bundledRoleFiles = new Set(USER_SCOPE_MANAGED_AGENT_FILES);
187
186
  const unmaterialized = assets.filter(({ definition, status }) => definition.kind === 'agent' &&
188
187
  definition.ownership.user === 'managed' &&
189
188
  status !== 'missing' &&
190
189
  (!managedRoleMaterialization ||
191
- !bundledRoleFiles.has(definition.destination.split('/').at(-1) ?? '')));
190
+ (definition.userMaterializable !== true &&
191
+ !isBuiltInUserScopeManagedAgentFile(definition.destination.split('/').at(-1) ?? ''))));
192
192
  if (unmaterialized.length === 0)
193
193
  return [];
194
194
  return [
195
195
  {
196
196
  code: 'user-agent-unmaterialized',
197
- message: `Pack ${pack} installs user-scope canonical agents without native provider-role materialization for the active provider set; canonical instruction reads are unaffected. Active Codex or Cursor materialization supplies only the bundled managed role files (${USER_SCOPE_MANAGED_AGENT_FILES.join(', ')}). Install this pack at project scope to materialize the affected agents.`,
197
+ message: `Pack ${pack} installs user-scope canonical agents without native provider-role materialization for the active provider set; canonical instruction reads are unaffected. Active Codex or Cursor materialization supplies only built-in managed roles and manifest-declared user-materializable agents. Install this pack at project scope to materialize the affected agents.`,
198
198
  paths: unmaterialized.map(({ path }) => path),
199
199
  },
200
200
  ];
@@ -1,7 +1,9 @@
1
1
  import type { ConcreteScope } from '../../../shared/types.js';
2
2
  import { applyPackReconcilePlan, type ApplyPackReconcileDependencies, type ApplyPackReconcileResult, preflightPackReconcilePlans } from './apply-pack-reconcile.js';
3
+ import { type ExpandedPackLifecycleRequest, type PackDefinitionResolver } from './pack-dependencies.js';
3
4
  import { inventoryScopedPack, type ScopedPackInventory } from './pack-inventory.js';
4
5
  import { planPackReconcile, type PackReconcileAction, type PackReconcilePlan } from './pack-reconcile.js';
6
+ import { hasScopedPackOwnershipEvidence } from './scoped-pack-intent.js';
5
7
  import type { PackName } from './types.js';
6
8
  export interface PackLifecycleRequest {
7
9
  pack: PackName;
@@ -11,7 +13,7 @@ export interface PackLifecycleRequest {
11
13
  action: PackReconcileAction;
12
14
  }
13
15
  export interface PackLifecycleResult {
14
- request: PackLifecycleRequest;
16
+ request: ExpandedPackLifecycleRequest;
15
17
  before: ScopedPackInventory;
16
18
  plan: PackReconcilePlan;
17
19
  apply: ApplyPackReconcileResult | null;
@@ -21,6 +23,8 @@ export interface PackLifecycleDependencies {
21
23
  plan?: typeof planPackReconcile;
22
24
  preflight?: typeof preflightPackReconcilePlans;
23
25
  apply?: typeof applyPackReconcilePlan;
26
+ getDefinition?: PackDefinitionResolver;
27
+ hasOwnershipEvidence?: typeof hasScopedPackOwnershipEvidence;
24
28
  applyDependencies?: Partial<ApplyPackReconcileDependencies>;
25
29
  }
26
30
  export declare function reconcilePackLifecycles(requests: readonly PackLifecycleRequest[], options?: {
@@ -31,4 +35,8 @@ export declare function reconcilePackLifecycle(request: PackLifecycleRequest, op
31
35
  dryRun?: boolean;
32
36
  dependencies?: PackLifecycleDependencies;
33
37
  }): Promise<PackLifecycleResult>;
38
+ export declare function reconcilePackDependencyLifecycles(request: PackLifecycleRequest, options?: {
39
+ dryRun?: boolean;
40
+ dependencies?: PackLifecycleDependencies;
41
+ }): Promise<PackLifecycleResult[]>;
34
42
  //# sourceMappingURL=pack-lifecycle.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pack-lifecycle.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/shared/pack-lifecycle.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EACL,sBAAsB,EACtB,KAAK,8BAA8B,EACnC,KAAK,wBAAwB,EAC7B,2BAA2B,EAC5B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,mBAAmB,EACnB,KAAK,mBAAmB,EACzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,iBAAiB,EACjB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACvB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,aAAa,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,mBAAmB,CAAC;CAC7B;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,oBAAoB,CAAC;IAC9B,MAAM,EAAE,mBAAmB,CAAC;IAC5B,IAAI,EAAE,iBAAiB,CAAC;IACxB,KAAK,EAAE,wBAAwB,GAAG,IAAI,CAAC;CACxC;AAED,MAAM,WAAW,yBAAyB;IACxC,SAAS,CAAC,EAAE,OAAO,mBAAmB,CAAC;IACvC,IAAI,CAAC,EAAE,OAAO,iBAAiB,CAAC;IAChC,SAAS,CAAC,EAAE,OAAO,2BAA2B,CAAC;IAC/C,KAAK,CAAC,EAAE,OAAO,sBAAsB,CAAC;IACtC,iBAAiB,CAAC,EAAE,OAAO,CAAC,8BAA8B,CAAC,CAAC;CAC7D;AAyBD,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,SAAS,oBAAoB,EAAE,EACzC,OAAO,GAAE;IACP,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,yBAAyB,CAAC;CACrC,GACL,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAgDhC;AAED,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,oBAAoB,EAC7B,OAAO,GAAE;IACP,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,yBAAyB,CAAC;CACrC,GACL,OAAO,CAAC,mBAAmB,CAAC,CAE9B"}
1
+ {"version":3,"file":"pack-lifecycle.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/shared/pack-lifecycle.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EACL,sBAAsB,EACtB,KAAK,8BAA8B,EACnC,KAAK,wBAAwB,EAC7B,2BAA2B,EAC5B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAGL,KAAK,4BAA4B,EACjC,KAAK,sBAAsB,EAC5B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,mBAAmB,EACnB,KAAK,mBAAmB,EACzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,iBAAiB,EAEjB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACvB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,8BAA8B,EAG/B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,aAAa,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,mBAAmB,CAAC;CAC7B;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,4BAA4B,CAAC;IACtC,MAAM,EAAE,mBAAmB,CAAC;IAC5B,IAAI,EAAE,iBAAiB,CAAC;IACxB,KAAK,EAAE,wBAAwB,GAAG,IAAI,CAAC;CACxC;AAED,MAAM,WAAW,yBAAyB;IACxC,SAAS,CAAC,EAAE,OAAO,mBAAmB,CAAC;IACvC,IAAI,CAAC,EAAE,OAAO,iBAAiB,CAAC;IAChC,SAAS,CAAC,EAAE,OAAO,2BAA2B,CAAC;IAC/C,KAAK,CAAC,EAAE,OAAO,sBAAsB,CAAC;IACtC,aAAa,CAAC,EAAE,sBAAsB,CAAC;IACvC,oBAAoB,CAAC,EAAE,OAAO,8BAA8B,CAAC;IAC7D,iBAAiB,CAAC,EAAE,OAAO,CAAC,8BAA8B,CAAC,CAAC;CAC7D;AAkCD,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,SAAS,oBAAoB,EAAE,EACzC,OAAO,GAAE;IACP,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,yBAAyB,CAAC;CACrC,GACL,OAAO,CAAC,mBAAmB,EAAE,CAAC,CA+HhC;AAED,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,oBAAoB,EAC7B,OAAO,GAAE;IACP,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,yBAAyB,CAAC;CACrC,GACL,OAAO,CAAC,mBAAmB,CAAC,CAY9B;AAED,wBAAsB,iCAAiC,CACrD,OAAO,EAAE,oBAAoB,EAC7B,OAAO,GAAE;IACP,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,yBAAyB,CAAC;CACrC,GACL,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAOhC"}
@@ -2,9 +2,18 @@ import { mkdir, writeFile } from 'node:fs/promises';
2
2
  import { dirname } from 'node:path';
3
3
  import { readOatConfig, writeOatConfig } from '../../../config/oat-config.js';
4
4
  import { applyPackReconcilePlan, preflightPackReconcilePlans, } from './apply-pack-reconcile.js';
5
+ import { dependencyRetainedAssetIds, expandPackLifecycleRequests, } from './pack-dependencies.js';
5
6
  import { inventoryScopedPack, } from './pack-inventory.js';
6
- import { planPackReconcile, } from './pack-reconcile.js';
7
- import { writeScopedPackIntent } from './scoped-pack-intent.js';
7
+ import { planPackReconcile, resolveSharedOwnerRetentions, } from './pack-reconcile.js';
8
+ import { hasScopedPackOwnershipEvidence, writeScopedPackIntent, writeScopedPackLease, } from './scoped-pack-intent.js';
9
+ function lifecycleInventoryKey(request) {
10
+ return JSON.stringify({
11
+ pack: request.pack,
12
+ scope: request.scope,
13
+ scopeRoot: request.scopeRoot,
14
+ assetsRoot: request.assetsRoot,
15
+ });
16
+ }
8
17
  async function writeGenerated(scopeRoot, operation) {
9
18
  await mkdir(dirname(operation.destination), { recursive: true });
10
19
  switch (operation.generation) {
@@ -27,17 +36,83 @@ async function writeGenerated(scopeRoot, operation) {
27
36
  }
28
37
  export async function reconcilePackLifecycles(requests, options = {}) {
29
38
  const dependencies = options.dependencies ?? {};
39
+ const getDefinition = dependencies.getDefinition;
30
40
  const inventory = dependencies.inventory ?? inventoryScopedPack;
31
41
  const plan = dependencies.plan ?? planPackReconcile;
32
- const planned = await Promise.all(requests.map(async (request) => {
33
- const before = await inventory(request);
34
- return {
42
+ const expanded = expandPackLifecycleRequests(requests, getDefinition);
43
+ const initialInventories = new Map();
44
+ const finalLeaseConsumers = new Map();
45
+ for (const request of expanded) {
46
+ if (!request.dependency)
47
+ continue;
48
+ const key = lifecycleInventoryKey(request);
49
+ let consumers = finalLeaseConsumers.get(key);
50
+ if (!consumers) {
51
+ const inventoried = await inventory(request);
52
+ initialInventories.set(key, inventoried);
53
+ consumers = [...inventoried.intent.requiredBy];
54
+ }
55
+ const nextConsumers = new Set(consumers);
56
+ if (request.dependency.lease === 'acquire') {
57
+ nextConsumers.add(request.dependency.requiredBy);
58
+ }
59
+ else {
60
+ nextConsumers.delete(request.dependency.requiredBy);
61
+ }
62
+ finalLeaseConsumers.set(key, [...nextConsumers].sort());
63
+ }
64
+ const projectedLeaseConsumers = new Map();
65
+ const planned = [];
66
+ for (const request of expanded) {
67
+ const key = lifecycleInventoryKey(request);
68
+ const inventoried = initialInventories.get(key) ?? (await inventory(request));
69
+ const projectedConsumers = projectedLeaseConsumers.get(key);
70
+ const before = projectedConsumers
71
+ ? {
72
+ ...inventoried,
73
+ intent: {
74
+ ...inventoried.intent,
75
+ requiredBy: projectedConsumers,
76
+ },
77
+ }
78
+ : inventoried;
79
+ const retainedAssets = request.action === 'remove'
80
+ ? await resolveSharedOwnerRetentions({
81
+ packs: [request.pack],
82
+ scope: request.scope,
83
+ scopeRoot: request.scopeRoot,
84
+ hasOwnershipEvidence: async (pack, scope, scopeRoot) => (dependencies.hasOwnershipEvidence ??
85
+ hasScopedPackOwnershipEvidence)({
86
+ pack,
87
+ scope,
88
+ scopeRoot,
89
+ }),
90
+ })
91
+ : [];
92
+ const retainedConsumers = finalLeaseConsumers.get(key) ?? before.intent.requiredBy;
93
+ const reconcilePlan = plan({
94
+ ...request,
95
+ inventory: before,
96
+ retainedAssets,
97
+ retainedDependencyAssetIds: dependencyRetainedAssetIds(request.pack, retainedConsumers, getDefinition),
98
+ });
99
+ planned.push({
35
100
  request,
36
101
  before,
37
- plan: plan({ ...request, inventory: before }),
102
+ plan: reconcilePlan,
38
103
  apply: null,
39
- };
40
- }));
104
+ });
105
+ if (request.dependency) {
106
+ const nextConsumers = new Set(before.intent.requiredBy);
107
+ if (request.dependency.lease === 'acquire') {
108
+ nextConsumers.add(request.dependency.requiredBy);
109
+ }
110
+ else {
111
+ nextConsumers.delete(request.dependency.requiredBy);
112
+ }
113
+ projectedLeaseConsumers.set(key, [...nextConsumers].sort());
114
+ }
115
+ }
41
116
  if (options.dryRun)
42
117
  return planned;
43
118
  await (dependencies.preflight ?? preflightPackReconcilePlans)(planned.map(({ request, plan: value }) => ({
@@ -56,6 +131,13 @@ export async function reconcilePackLifecycles(requests, options = {}) {
56
131
  scopeRoot: request.scopeRoot,
57
132
  enabled: operation.enabled,
58
133
  }),
134
+ writeLease: async (operation) => writeScopedPackLease({
135
+ pack: operation.pack,
136
+ scope: operation.scope,
137
+ scopeRoot: request.scopeRoot,
138
+ requiredBy: operation.requiredBy,
139
+ enabled: operation.enabled,
140
+ }),
59
141
  inventory: async () => inventory(request),
60
142
  });
61
143
  results.push({ ...entry, apply: applied });
@@ -63,5 +145,16 @@ export async function reconcilePackLifecycles(requests, options = {}) {
63
145
  return results;
64
146
  }
65
147
  export async function reconcilePackLifecycle(request, options = {}) {
66
- return (await reconcilePackLifecycles([request], options))[0];
148
+ const results = await reconcilePackLifecycles([request], options);
149
+ return (results.find(({ request: candidate }) => candidate.pack === request.pack &&
150
+ candidate.scope === request.scope &&
151
+ candidate.scopeRoot === request.scopeRoot &&
152
+ candidate.action === request.action &&
153
+ !candidate.dependency) ?? results[0]);
154
+ }
155
+ export async function reconcilePackDependencyLifecycles(request, options = {}) {
156
+ const dependencyRequests = expandPackLifecycleRequests([request], options.dependencies?.getDefinition).filter(({ dependency }) => dependency !== undefined);
157
+ if (dependencyRequests.length === 0)
158
+ return [];
159
+ return reconcilePackLifecycles(dependencyRequests, options);
67
160
  }
@@ -1,5 +1,5 @@
1
- import type { PackAssetDefinition, PackAssetGeneration, PackAssetKind, PackAssetOwnership, PackDefinition, PackName } from './types.js';
2
- export type { PackAssetDefinition, PackAssetGeneration, PackAssetKind, PackAssetOwnership, PackDefinition, };
1
+ import type { PackAssetDefinition, PackAssetGeneration, PackAssetKind, PackAssetOwnership, PackDependencyDefinition, PackDefinition, PackName } from './types.js';
2
+ export type { PackAssetDefinition, PackAssetGeneration, PackAssetKind, PackAssetOwnership, PackDependencyDefinition, PackDefinition, };
3
3
  export declare const PACK_NAMES: readonly ["core", "ideas", "docs", "workflows", "utility", "project-management", "research", "brainstorm"];
4
4
  export declare function isPackName(value: string): value is PackName;
5
5
  export declare const PACK_MANIFEST: readonly PackDefinition[];
@@ -1 +1 @@
1
- {"version":3,"file":"pack-manifest.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/shared/pack-manifest.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACb,kBAAkB,EAClB,cAAc,EACd,QAAQ,EACT,MAAM,SAAS,CAAC;AAEjB,YAAY,EACV,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACb,kBAAkB,EAClB,cAAc,GACf,CAAC;AAEF,eAAO,MAAM,UAAU,4GASiB,CAAC;AAEzC,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,QAAQ,CAE3D;AA8HD,eAAO,MAAM,aAAa,EAAE,SAAS,cAAc,EAwKlD,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,QAAQ,GAAG,cAAc,CAMhE;AAED,wBAAgB,aAAa,CAC3B,IAAI,EAAE,QAAQ,EACd,IAAI,CAAC,EAAE,aAAa,GACnB,SAAS,mBAAmB,EAAE,CAGhC;AAED,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,GAC9C,MAAM,EAAE,CAQV;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,EAAE,CAIlE;AA0DD,wBAAgB,oBAAoB,CAClC,QAAQ,GAAE,SAAS,cAAc,EAAkB,GAClD,IAAI,CA6DN"}
1
+ {"version":3,"file":"pack-manifest.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/shared/pack-manifest.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACb,kBAAkB,EAClB,wBAAwB,EACxB,cAAc,EACd,QAAQ,EACT,MAAM,SAAS,CAAC;AAEjB,YAAY,EACV,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACb,kBAAkB,EAClB,wBAAwB,EACxB,cAAc,GACf,CAAC;AAEF,eAAO,MAAM,UAAU,4GASiB,CAAC;AAEzC,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,QAAQ,CAE3D;AAkID,eAAO,MAAM,aAAa,EAAE,SAAS,cAAc,EAwLlD,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,QAAQ,GAAG,cAAc,CAMhE;AAED,wBAAgB,aAAa,CAC3B,IAAI,EAAE,QAAQ,EACd,IAAI,CAAC,EAAE,aAAa,GACnB,SAAS,mBAAmB,EAAE,CAGhC;AAED,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,GAC9C,MAAM,EAAE,CAQV;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,EAAE,CAIlE;AAoJD,wBAAgB,oBAAoB,CAClC,QAAQ,GAAE,SAAS,cAAc,EAAkB,GAClD,IAAI,CAiEN"}