@agentxm/extension-materialization 0.29.4 → 0.30.1

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.
@@ -1,631 +0,0 @@
1
- /**
2
- * Shared extension closure recipes — install, materialize, uninstall, and the
3
- * authored-package transition.
4
- *
5
- * A recipe composes one manager's contract into one plan step. Requirements
6
- * stay explicit: the step declares the manager's `R` plus the transaction
7
- * scope its closure runs in, and the command boundary composes them once. The
8
- * facts a materialization observed travel from `materializeInstall` to the
9
- * settings and lockfile writes and to the step's artifact as values.
10
- *
11
- * @experimental This API is unstable and may change without notice.
12
- * @packageDocumentation
13
- */
14
- import * as Effect from "effect/Effect";
15
- import * as Option from "effect/Option";
16
- import { LifecyclePostconditionViolated, ScaffoldedExtensionUnresolved } from "./errors.js";
17
- import { SourceAuthorityBlocked } from "@agentxm/extension-resolution";
18
- import { applyProjectionPlans, projectionPlanExclusionWarnings, } from "@agentxm/workspace-projection";
19
- import { isWorkspaceSourceLocator } from "@agentxm/extension-model/unstable/sources/workspace";
20
- import { evaluateSourceAuthority } from "@agentxm/extension-resolution";
21
- import { formatDeprecationWarning } from "@agentxm/registry-client";
22
- import { runWorkspaceTransaction } from "@agentxm/workspace-transactions";
23
- import { toExtensionTypePlural } from "@agentxm/extension-model/unstable/extensions/common";
24
- // -----------------------------------------------------------------------------
25
- // Target Helpers
26
- // -----------------------------------------------------------------------------
27
- /**
28
- * Derive an ExtensionTarget from an ExtensionRef.
29
- *
30
- * Pack targets include owner; leaf-extension targets are name-only.
31
- */
32
- export const targetFromRef = (ref) => {
33
- switch (ref.type) {
34
- case "skill":
35
- return { type: "skill", name: ref.skill.name };
36
- case "pack":
37
- return { type: "pack", name: ref.pack.name, owner: ref.owner };
38
- case "mcp-server":
39
- return { type: "mcp-server", name: ref.server.name };
40
- case "subagent":
41
- return { type: "subagent", name: ref.subagent.name };
42
- case "rule":
43
- return { type: "rule", name: ref.rule.name };
44
- case "hook":
45
- return { type: "hook", name: ref.hook.name };
46
- case "knowledge":
47
- return { type: "knowledge", name: ref.knowledge.name };
48
- }
49
- };
50
- export const extensionRefLifecycleWarnings = (ref) => ref.refType === "registry"
51
- ? [
52
- ...(ref.deprecation === undefined
53
- ? []
54
- : [
55
- formatDeprecationWarning(`${ref.owner}/${toExtensionTypePlural(ref.type)}/${ref.name}`, ref.deprecation),
56
- ]),
57
- ...(ref.lifecycleWarnings ?? []),
58
- ]
59
- : [];
60
- export const extensionRefRegistryLifecycle = (ref) => ref.refType !== "registry" || ref.deprecation === undefined
61
- ? undefined
62
- : { deprecation: ref.deprecation };
63
- /**
64
- * Produce a display label from an ExtensionTarget.
65
- *
66
- * Pack targets render as `owner/name`; others render as `name`.
67
- */
68
- export const toLabel = (target) => target.type === "pack" ? `${target.owner}/${target.name}` : target.name;
69
- /**
70
- * Produce a stable step identity key from an ExtensionTarget.
71
- *
72
- * This is internal plan identity, not display text.
73
- */
74
- export const toStepKey = (target) => target.type === "pack"
75
- ? `${target.type}:${target.owner}/${target.name}`
76
- : `${target.type}:${target.name}`;
77
- /**
78
- * Format a single PackageUrlParts as a compact display string.
79
- *
80
- * Examples: `pkg:npm/react`, `pkg:npm/@angular/core@18.0.0`
81
- */
82
- export const formatPackageUrlParts = (parts) => {
83
- const ns = parts.namespace !== undefined ? `${parts.namespace}/` : "";
84
- const ver = parts.version !== undefined ? `@${parts.version}` : "";
85
- return `pkg:${parts.type}/${ns}${parts.name}${ver}`;
86
- };
87
- /**
88
- * Build a display label with optional packages suffix.
89
- *
90
- * When packages is non-empty, appends them parenthesized:
91
- * `code-review (pkg:npm/react, pkg:npm/typescript)`
92
- */
93
- export const toLabelWithCompanions = (target, packages) => {
94
- const base = toLabel(target);
95
- if (packages.length === 0)
96
- return base;
97
- const purls = packages.map(formatPackageUrlParts).join(", ");
98
- return `${base} (${purls})`;
99
- };
100
- const NO_PROJECTION_WARNINGS = [];
101
- /**
102
- * Render the manager's shared aggregate units and return the operator-facing
103
- * report for every desired contributor those units could not render. The
104
- * report travels with the step that performed the render.
105
- */
106
- const applyManagerProjectionPlans = (manager) => manager.projectionPlans === undefined
107
- ? Effect.succeed(NO_PROJECTION_WARNINGS)
108
- : manager
109
- .projectionPlans()
110
- .pipe(Effect.flatMap((plans) => applyProjectionPlans(plans).pipe(Effect.as(projectionPlanExclusionWarnings(plans)))));
111
- const isConfigured = (manager, target) => {
112
- if (manager.isConfigured !== undefined)
113
- return manager.isConfigured({ target });
114
- if (manager.getConfiguredSource === undefined)
115
- return Effect.succeed(false);
116
- return manager.getConfiguredSource({ target }).pipe(Effect.map(Option.isSome));
117
- };
118
- /**
119
- * Execute the canonical install sequence.
120
- *
121
- * Root installs materialize and commit desired state plus any accepted external
122
- * resolution before validating the observable postcondition. Pack-derived
123
- * installs omit the root settings declaration while retaining that resolution.
124
- */
125
- const runInstallOperation = (manager, args) => Effect.gen(function* () {
126
- const target = targetFromRef(args.ref);
127
- const configuredSource = manager.getConfiguredSource === undefined
128
- ? Option.none()
129
- : yield* manager.getConfiguredSource({ target });
130
- const authority = evaluateSourceAuthority({
131
- target: { ...target, identity: toStepKey(target) },
132
- relationship: { kind: "root" },
133
- requested: {
134
- identity: `${args.ref.refType}:${toStepKey(target)}`,
135
- workspace: args.ref.refType === "workspace",
136
- },
137
- ...(Option.isNone(configuredSource)
138
- ? {}
139
- : {
140
- configured: {
141
- identity: configuredSource.value,
142
- workspace: isWorkspaceSourceLocator(configuredSource.value),
143
- },
144
- }),
145
- ...(args.allowWorkspaceReplacement === undefined
146
- ? {}
147
- : { allowWorkspaceReplacement: args.allowWorkspaceReplacement }),
148
- });
149
- if (authority.kind === "blocked") {
150
- return yield* new SourceAuthorityBlocked({
151
- detail: authority.fact.detail,
152
- recovery: authority.fact.recovery,
153
- });
154
- }
155
- const installedBefore = args.installedBefore === undefined ? false : yield* args.installedBefore;
156
- const transaction = yield* runWorkspaceTransaction({
157
- transition: Effect.gen(function* () {
158
- const cleanupSupersededCanonical = manager.prepareSourceTransition === undefined
159
- ? Effect.void
160
- : yield* manager.prepareSourceTransition({ ref: args.ref });
161
- const materialization = yield* manager.materializeInstall({
162
- ref: args.ref,
163
- ...(args.force === undefined ? {} : { force: args.force }),
164
- });
165
- if (!args.skipSettings) {
166
- yield* manager.upsertSettingsEntry({
167
- ref: args.ref,
168
- versionRange: args.versionRange,
169
- materialization: Option.some(materialization),
170
- });
171
- }
172
- yield* manager.upsertLockfileEntry({
173
- ref: args.ref,
174
- materialization: Option.some(materialization),
175
- });
176
- yield* cleanupSupersededCanonical;
177
- // Desired state and canonical content are committed; render every
178
- // shared aggregate unit once from the complete contributor set.
179
- const projectionWarnings = args.skipProjections !== true
180
- ? yield* applyManagerProjectionPlans(manager)
181
- : NO_PROJECTION_WARNINGS;
182
- return { installedBefore, materialization, projectionWarnings };
183
- }),
184
- validate: () => Effect.gen(function* () {
185
- if (args.deferObservableValidation !== true) {
186
- const installed = yield* manager.isInstalled({ target });
187
- if (!installed) {
188
- return yield* new LifecyclePostconditionViolated({
189
- postcondition: "install-observable",
190
- targetType: target.type,
191
- targetName: target.name,
192
- });
193
- }
194
- }
195
- if (args.skipSettings !== true &&
196
- (manager.isConfigured !== undefined || manager.getConfiguredSource !== undefined)) {
197
- const configured = yield* isConfigured(manager, target);
198
- if (!configured) {
199
- return yield* new LifecyclePostconditionViolated({
200
- postcondition: "install-declared",
201
- targetType: target.type,
202
- targetName: target.name,
203
- });
204
- }
205
- }
206
- }),
207
- });
208
- const artifact = args.buildArtifact === undefined
209
- ? undefined
210
- : yield* args.buildArtifact({
211
- installedBefore,
212
- materialization: Option.some(transaction.materialization),
213
- });
214
- const artifactWithLifecycle = artifact === undefined ||
215
- args.ref.refType !== "registry" ||
216
- args.ref.deprecation === undefined
217
- ? artifact
218
- : { ...artifact, registryLifecycle: { deprecation: args.ref.deprecation } };
219
- return {
220
- result: "success",
221
- message: args.message ?? "Applied install operation",
222
- ...(artifactWithLifecycle === undefined ? {} : { artifact: artifactWithLifecycle }),
223
- ...(transaction.projectionWarnings.length === 0
224
- ? {}
225
- : { warnings: transaction.projectionWarnings }),
226
- };
227
- }).pipe(Effect.mapError(args.toStepFailure));
228
- /**
229
- * Build a PlannedJobStep for an install operation.
230
- *
231
- * The step keeps the manager's requirements and the transaction scope in its
232
- * `run` effect; the command boundary composes them once.
233
- */
234
- export const buildInstallOperation = (manager, args) => {
235
- const target = targetFromRef(args.ref);
236
- const companionPkgs = args.ref.refType === "registry" ? args.ref.packages : [];
237
- const lifecycleWarnings = extensionRefLifecycleWarnings(args.ref);
238
- const registryLifecycle = extensionRefRegistryLifecycle(args.ref);
239
- // The proposed Registry identity travels with the step as structured data,
240
- // so trust classification compares bindings rather than reading warnings.
241
- const registryBinding = args.ref.refType === "registry"
242
- ? {
243
- extensionType: args.ref.type,
244
- target: target.name,
245
- owner: args.ref.owner,
246
- packageName: args.ref.name,
247
- version: args.ref.version,
248
- publisherBindingId: args.ref.publisherBindingId,
249
- }
250
- : undefined;
251
- const base = {
252
- key: toStepKey(target),
253
- label: toLabelWithCompanions(target, companionPkgs),
254
- run: runInstallOperation(manager, args),
255
- ...(registryLifecycle === undefined ? {} : { registryLifecycle }),
256
- ...(registryBinding === undefined ? {} : { registryBinding }),
257
- };
258
- return lifecycleWarnings.length === 0
259
- ? { ...base, readiness: "ready" }
260
- : {
261
- ...base,
262
- readiness: "warn",
263
- warnMessage: lifecycleWarnings.join("; "),
264
- };
265
- };
266
- /**
267
- * Build a PlannedJobStep for `new` commands.
268
- *
269
- * A read-only preflight runs first. The transaction then snapshots the source
270
- * path, scaffolds it, seeds desired state, resolves the canonical package, and
271
- * materializes projections before validating the authored postcondition.
272
- */
273
- export const buildAuthoredExtensionStep = (manager, args) => {
274
- const target = args.target;
275
- return {
276
- key: toStepKey(target),
277
- label: args.label ?? toLabel(target),
278
- readiness: "ready",
279
- ...(args.plannedArtifact === undefined ? {} : { artifact: args.plannedArtifact }),
280
- run: (args.allowConfiguredSourceTransition === true
281
- ? Effect.void
282
- : manager.listMaterializable()).pipe(Effect.andThen(runWorkspaceTransaction({
283
- targets: Array.from(new Set([args.location, ...(args.transactionTargets ?? [])])).sort(),
284
- transition: Effect.gen(function* () {
285
- if (args.preflight !== undefined)
286
- yield* args.preflight;
287
- yield* args.scaffold;
288
- yield* args.markAuthored;
289
- const materializable = yield* manager.listMaterializable();
290
- const ref = materializable.find((candidate) => toStepKey(targetFromRef(candidate)) === toStepKey(target));
291
- if (ref === undefined) {
292
- return yield* new ScaffoldedExtensionUnresolved({
293
- targetType: target.type,
294
- targetName: target.name,
295
- });
296
- }
297
- const installedBefore = args.installedBefore === undefined ? false : yield* args.installedBefore;
298
- let materialization = Option.none();
299
- if (args.enabled !== false || args.materializeWhenDisabled === true) {
300
- materialization =
301
- args.materializeInstall === undefined
302
- ? Option.some(yield* manager.materializeInstall({ ref }))
303
- : yield* args.materializeInstall(ref);
304
- }
305
- yield* manager.upsertSettingsEntry({
306
- ref,
307
- versionRange: args.versionRange,
308
- materialization,
309
- });
310
- if (args.finalizeAuthored !== undefined) {
311
- yield* args.finalizeAuthored;
312
- }
313
- if (args.enabled === false && args.materializeWhenDisabled === true) {
314
- yield* manager.materializeDeactivate({ target });
315
- }
316
- else if (args.enabled !== false) {
317
- // Desired state is committed; render shared aggregate units once
318
- // from the complete contributor set.
319
- return {
320
- ref,
321
- installedBefore,
322
- materialization,
323
- projectionWarnings: yield* applyManagerProjectionPlans(manager),
324
- };
325
- }
326
- return {
327
- ref,
328
- installedBefore,
329
- materialization,
330
- projectionWarnings: NO_PROJECTION_WARNINGS,
331
- };
332
- }),
333
- validate: () => Effect.gen(function* () {
334
- const installed = yield* manager.isInstalled({ target });
335
- if (args.enabled !== false && !installed) {
336
- return yield* new LifecyclePostconditionViolated({
337
- postcondition: "new-observable",
338
- targetType: target.type,
339
- targetName: target.name,
340
- });
341
- }
342
- if (manager.getConfiguredSource !== undefined) {
343
- const configured = yield* manager.getConfiguredSource({ target });
344
- if (Option.isNone(configured)) {
345
- return yield* new LifecyclePostconditionViolated({
346
- postcondition: "new-declared",
347
- targetType: target.type,
348
- targetName: target.name,
349
- });
350
- }
351
- }
352
- }),
353
- })), Effect.flatMap(({ installedBefore, materialization }) => Effect.gen(function* () {
354
- const artifact = args.buildArtifact === undefined
355
- ? undefined
356
- : yield* args.buildArtifact({ installedBefore, materialization });
357
- return {
358
- result: "success",
359
- message: args.message,
360
- ...(artifact === undefined ? {} : { artifact }),
361
- };
362
- })), Effect.mapError(args.toStepFailure)),
363
- };
364
- };
365
- /**
366
- * Build a PlannedJobStep for existing `new` commands.
367
- *
368
- * New commands remain enabled by default while sharing the authored-package
369
- * transaction used by fork and native import.
370
- */
371
- export const buildNewExtensionStep = (manager, args) => {
372
- if (args.ref.refType !== "workspace") {
373
- return {
374
- key: toStepKey(args.target),
375
- label: args.label ?? toLabel(args.target),
376
- readiness: "error",
377
- errorMessage: "New authored extensions require a workspace source",
378
- };
379
- }
380
- return buildAuthoredExtensionStep(manager, {
381
- ...args,
382
- location: args.ref.location,
383
- enabled: true,
384
- });
385
- };
386
- const runMaterializeOperation = (manager, args) => Effect.gen(function* () {
387
- const target = targetFromRef(args.ref);
388
- const materialization = yield* runWorkspaceTransaction({
389
- transition: Effect.gen(function* () {
390
- const observed = yield* manager.materializeInstall({
391
- ref: args.ref,
392
- ...(args.force === undefined ? {} : { force: args.force }),
393
- });
394
- if (args.validateMaterialized !== undefined) {
395
- yield* args.validateMaterialized({ materialization: observed });
396
- }
397
- yield* manager.upsertLockfileEntry({
398
- ref: args.ref,
399
- materialization: Option.some(observed),
400
- });
401
- return observed;
402
- }),
403
- validate: () => manager.isInstalled({ target }).pipe(Effect.flatMap((installed) => installed
404
- ? Effect.void
405
- : new LifecyclePostconditionViolated({
406
- postcondition: "materialize-observable",
407
- targetType: target.type,
408
- targetName: target.name,
409
- }))),
410
- });
411
- const artifact = args.buildArtifact === undefined ? undefined : yield* args.buildArtifact({ materialization });
412
- return {
413
- result: "success",
414
- message: args.message ?? "Synced agent artifacts",
415
- ...(artifact === undefined ? {} : { artifact }),
416
- };
417
- }).pipe(Effect.mapError(args.toStepFailure));
418
- export const buildMaterializeOperation = (manager, args) => {
419
- const target = targetFromRef(args.ref);
420
- const companionPkgs = args.ref.refType === "registry" ? args.ref.packages : [];
421
- return {
422
- key: toStepKey(target),
423
- label: args.label ?? toLabelWithCompanions(target, companionPkgs),
424
- readiness: "ready",
425
- run: runMaterializeOperation(manager, args),
426
- };
427
- };
428
- const uninstallSettlementMessage = (target, settlement) => {
429
- const label = toLabel(target);
430
- if (settlement.declaration === "absent" && settlement.canonical === "absent") {
431
- return `${label} is already absent`;
432
- }
433
- switch (settlement.canonical) {
434
- case "absent":
435
- return `Unconfigured ${label}; no canonical package was present`;
436
- case "removed":
437
- return `Removed ${label}`;
438
- case "retained-by-pack":
439
- return `Unconfigured ${label}; retained its package because an installed pack still requires it`;
440
- case "preserved-authored":
441
- return `Unconfigured ${label}; preserved its workspace-authored source`;
442
- case "preserved-unowned":
443
- return `Unconfigured ${label}; preserved canonical content without an accepted source owner`;
444
- case "preserved-unreadable":
445
- return `Unconfigured ${label}; preserved its package because its manifest could not be read`;
446
- }
447
- };
448
- /**
449
- * Plain-language account of a registration-only removal: what was retired, why
450
- * its content could not be verified, what was left in place, and what the
451
- * operator can do about the remainder.
452
- */
453
- const unreadablePackageWarning = (target, retirement) => `${toLabel(target)}: its package manifest ${retirement.reason === "missing" ? "is missing" : "cannot be read"} at ${retirement.manifestPath}, so AXM removed its configuration entry and accepted resolution and left its package content in place. Delete that content yourself once you no longer need it.`;
454
- /**
455
- * Execute the uninstall sequence with retention check.
456
- *
457
- * If the target is still required by an installed pack:
458
- * 1. Remove settings entry
459
- *
460
- * If not required:
461
- * 1. Unmaterialize from disk
462
- * 2. Remove lockfile entry
463
- * 3. Remove settings entry
464
- */
465
- const runUninstallOperation = (manager, retentionPolicy, args) => Effect.gen(function* () {
466
- const configuredSource = manager.getConfiguredSource === undefined
467
- ? Option.none()
468
- : yield* manager.getConfiguredSource({ target: args.target });
469
- const configured = yield* isConfigured(manager, args.target);
470
- const transition = Effect.gen(function* () {
471
- const applyProjections = () => args.skipProjections !== true
472
- ? applyManagerProjectionPlans(manager)
473
- : Effect.succeed(NO_PROJECTION_WARNINGS);
474
- if (args.retirement !== undefined) {
475
- // Nothing about the package can be verified, so only the registration
476
- // AXM itself wrote is removable. Canonical content stays untouched.
477
- yield* manager.removeSettingsEntry({
478
- target: args.target,
479
- materialization: Option.none(),
480
- });
481
- yield* manager.removeLockfileEntry({
482
- target: args.target,
483
- materialization: Option.none(),
484
- });
485
- return {
486
- settlement: {
487
- declaration: "removed",
488
- canonical: "preserved-unreadable",
489
- },
490
- unmaterialization: Option.none(),
491
- expectedInstalled: undefined,
492
- projectionWarnings: yield* applyProjections(),
493
- };
494
- }
495
- const isInstalled = yield* manager.isInstalled({ target: args.target });
496
- if (!isInstalled) {
497
- if (configured) {
498
- // Configured extensions may still own native agent projections even
499
- // when they have no canonical managed package on disk.
500
- const withdrawn = yield* manager.materializeUninstall({ target: args.target });
501
- const unmaterialization = Option.some(withdrawn);
502
- yield* manager.removeSettingsEntry({
503
- target: args.target,
504
- materialization: unmaterialization,
505
- });
506
- yield* manager.removeLockfileEntry({
507
- target: args.target,
508
- materialization: unmaterialization,
509
- });
510
- return {
511
- settlement: {
512
- declaration: "removed",
513
- canonical: "absent",
514
- },
515
- unmaterialization,
516
- expectedInstalled: false,
517
- projectionWarnings: yield* applyProjections(),
518
- };
519
- }
520
- return {
521
- settlement: {
522
- declaration: "absent",
523
- canonical: "absent",
524
- },
525
- unmaterialization: Option.none(),
526
- expectedInstalled: false,
527
- projectionWarnings: NO_PROJECTION_WARNINGS,
528
- };
529
- }
530
- const stillRequiredByPack = yield* retentionPolicy.isRequiredByInstalledPack({
531
- target: args.target,
532
- });
533
- if (stillRequiredByPack) {
534
- yield* manager.removeSettingsEntry({ target: args.target, materialization: Option.none() });
535
- return {
536
- settlement: {
537
- declaration: "removed",
538
- canonical: "retained-by-pack",
539
- },
540
- unmaterialization: Option.none(),
541
- expectedInstalled: true,
542
- projectionWarnings: yield* applyProjections(),
543
- };
544
- }
545
- const unmaterialization = Option.some(yield* manager.materializeUninstall({ target: args.target }));
546
- yield* manager.removeSettingsEntry({
547
- target: args.target,
548
- materialization: unmaterialization,
549
- });
550
- yield* manager.removeLockfileEntry({
551
- target: args.target,
552
- materialization: unmaterialization,
553
- });
554
- // The target has left the desired-state graph; re-render every shared
555
- // aggregate unit once so only reachable contributors remain.
556
- const projectionWarnings = yield* applyProjections();
557
- return {
558
- projectionWarnings,
559
- unmaterialization,
560
- settlement: {
561
- declaration: "removed",
562
- canonical: Option.match(configuredSource, {
563
- onNone: () => "preserved-unowned",
564
- onSome: (source) => isWorkspaceSourceLocator(source)
565
- ? "preserved-authored"
566
- : "removed",
567
- }),
568
- },
569
- expectedInstalled: Option.match(configuredSource, {
570
- onNone: () => undefined,
571
- onSome: (source) => (isWorkspaceSourceLocator(source) ? undefined : false),
572
- }),
573
- };
574
- });
575
- const result = yield* runWorkspaceTransaction({
576
- transition,
577
- validate: (outcome) => Effect.gen(function* () {
578
- if (manager.isConfigured !== undefined || manager.getConfiguredSource !== undefined) {
579
- const remainsConfigured = yield* isConfigured(manager, args.target);
580
- if (remainsConfigured) {
581
- return yield* new LifecyclePostconditionViolated({
582
- postcondition: "uninstall-remains-declared",
583
- targetType: args.target.type,
584
- targetName: args.target.name,
585
- });
586
- }
587
- }
588
- const installed = yield* manager.isInstalled({ target: args.target });
589
- if (outcome.expectedInstalled !== undefined && installed !== outcome.expectedInstalled) {
590
- return yield* new LifecyclePostconditionViolated({
591
- postcondition: "uninstall-observed-state",
592
- targetType: args.target.type,
593
- targetName: args.target.name,
594
- });
595
- }
596
- }),
597
- });
598
- const warnings = [
599
- ...(args.retirement === undefined
600
- ? []
601
- : [unreadablePackageWarning(args.target, args.retirement)]),
602
- ...result.projectionWarnings,
603
- ];
604
- const artifact = args.buildArtifact === undefined
605
- ? undefined
606
- : yield* args.buildArtifact({
607
- settlement: result.settlement,
608
- unmaterialization: result.unmaterialization,
609
- });
610
- return {
611
- result: "success",
612
- message: uninstallSettlementMessage(args.target, result.settlement),
613
- ...(result.settlement.declaration === "absent" ? { disposition: "unchanged" } : {}),
614
- ...(artifact === undefined ? {} : { artifact }),
615
- ...(warnings.length === 0 ? {} : { warnings }),
616
- };
617
- }).pipe(Effect.mapError(args.toStepFailure));
618
- /**
619
- * Build a PlannedJobStep for an uninstall operation.
620
- *
621
- * The step keeps the manager's requirements and the transaction scope in its
622
- * `run` effect; the command boundary composes them once.
623
- */
624
- export const buildUninstallOperation = (manager, retentionPolicy, args) => {
625
- return {
626
- label: toLabel(args.target),
627
- readiness: "ready",
628
- run: runUninstallOperation(manager, retentionPolicy, args),
629
- };
630
- };
631
- //# sourceMappingURL=operations.js.map
@@ -1,28 +0,0 @@
1
- /**
2
- * Materializing an authored MCP server package during create, fork, adopt, and
3
- * native import.
4
- *
5
- * The authored closure recipe accepts a type-specific materialization because
6
- * an MCP server's canonical content is realized by the install operation
7
- * rather than by its manager. Both live in this capability, so every authoring
8
- * route reaches the same realization without importing a peer feature.
9
- *
10
- * @experimental This API is unstable and may change without notice.
11
- */
12
- import * as Effect from "effect/Effect";
13
- import * as Option from "effect/Option";
14
- import type { McpServerExtensionRef } from "@agentxm/extension-model/unstable/extensions/refs/mcp-server";
15
- import type { McpServerMaterializationFacts } from "../managers.js";
16
- import type { ExtensionManagerFailure } from "../errors.js";
17
- import { type McpServerInstallRequirements } from "./install-operation.js";
18
- /**
19
- * Realize the authored package's canonical content and native projections
20
- * without touching workspace state: the authored closure commits desired state
21
- * itself. Reports no acquisition facts — an authored package has no accepted
22
- * registry resolution for the entry writers to record.
23
- */
24
- export declare const materializeAuthoredMcpServer: (args: {
25
- readonly ref: McpServerExtensionRef;
26
- readonly nonInteractive: boolean;
27
- }) => Effect.Effect<Option.Option<McpServerMaterializationFacts>, ExtensionManagerFailure, McpServerInstallRequirements>;
28
- //# sourceMappingURL=authored-materialization.d.ts.map