@agentxm/extension-lifecycle 0.29.2 → 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.
Files changed (55) hide show
  1. package/dist/src/activation/set-activation.d.ts +22 -40
  2. package/dist/src/activation/set-activation.js +199 -331
  3. package/dist/src/demote/demote-to-external-source.d.ts +1 -1
  4. package/dist/src/demote/demote-to-external-source.js +53 -24
  5. package/dist/src/hooks/configured-agent-outcomes-provider.d.ts +4 -4
  6. package/dist/src/hooks/configured-agent-outcomes-provider.js +23 -17
  7. package/dist/src/hooks/install/plan.js +6 -3
  8. package/dist/src/hooks/uninstall/plan.js +4 -3
  9. package/dist/src/index.d.ts +1 -2
  10. package/dist/src/index.js +1 -2
  11. package/dist/src/install/root-intent.d.ts +2 -2
  12. package/dist/src/install/vocabulary.d.ts +5 -4
  13. package/dist/src/knowledge/install/plan.js +2 -1
  14. package/dist/src/knowledge/uninstall/plan.js +4 -3
  15. package/dist/src/live.d.ts +1 -1
  16. package/dist/src/live.js +1 -1
  17. package/dist/src/mcps/install/plan.js +2 -3
  18. package/dist/src/mcps/operations/disable.js +1 -1
  19. package/dist/src/mcps/operations/enable.js +20 -35
  20. package/dist/src/mcps/operations/uninstall.js +2 -1
  21. package/dist/src/mcps/uninstall/plan.js +13 -4
  22. package/dist/src/packs/graph-transition.d.ts +0 -25
  23. package/dist/src/packs/graph-transition.js +0 -101
  24. package/dist/src/packs/install/plan.d.ts +0 -13
  25. package/dist/src/packs/install/plan.js +12 -9
  26. package/dist/src/packs/member-install-step.js +8 -21
  27. package/dist/src/packs/promote-authored-pack.js +6 -3
  28. package/dist/src/packs/uninstall/plan.js +52 -20
  29. package/dist/src/rules/install/plan.js +6 -3
  30. package/dist/src/rules/uninstall/plan.js +4 -3
  31. package/dist/src/skills/install/bundled.js +4 -4
  32. package/dist/src/skills/install/plan.js +3 -2
  33. package/dist/src/skills/operations/install.d.ts +0 -1
  34. package/dist/src/skills/operations/install.js +9 -18
  35. package/dist/src/skills/uninstall/plan.js +4 -3
  36. package/dist/src/subagents/install/plan.js +3 -2
  37. package/dist/src/subagents/operations/enable.js +1 -3
  38. package/dist/src/subagents/uninstall/plan.js +4 -3
  39. package/dist/src/testing.d.ts +1 -1
  40. package/dist/src/testing.js +2 -1
  41. package/dist/src/uninstall/root-intent.d.ts +1 -1
  42. package/dist/src/uninstall/uninstall-extensions.d.ts +1 -1
  43. package/dist/src/uninstall/uninstall-extensions.js +77 -1
  44. package/dist/src/update/root-request.d.ts +2 -2
  45. package/dist/src/update/selective/skills.d.ts +1 -1
  46. package/dist/src/update/selective/skills.js +0 -1
  47. package/dist/src/update/selective/subagents.d.ts +1 -1
  48. package/dist/src/update/selective/subagents.js +3 -2
  49. package/dist/src/update/selective/use-case.d.ts +2 -2
  50. package/dist/src/update/targeted-plan.js +4 -2
  51. package/dist/src/workspace-paths.d.ts +0 -6
  52. package/dist/src/workspace-paths.js +0 -10
  53. package/package.json +22 -24
  54. package/dist/src/uninstall/retention-policy.d.ts +0 -21
  55. package/dist/src/uninstall/retention-policy.js +0 -28
@@ -69,7 +69,7 @@ declare const settleDemotion: (request: DemoteRequest) => Effect.Effect<{
69
69
  fqn: string;
70
70
  authoredPath: string;
71
71
  execution: ExecutionCandidate<InstallStepRequirements, never>;
72
- }, ExtensionLifecycleFailed | import("@agentxm/workspace-state").PathTraversalDetected | import("@agentxm/extension-sources").SourceSyntaxInvalid | import("@agentxm/extension-sources").SourceHostNotConfigured | import("@agentxm/extension-sources").SourceNotResolvable | import("@agentxm/extension-sources").SourceNetworkFailure | import("@agentxm/extension-sources").GitOperationFailed | import("@agentxm/extension-sources").WorkspaceCatalogUnavailable | import("@agentxm/extension-sources").AxmSkillGateUnavailable | import("@agentxm/registry-client").RegistryProblem | import("@agentxm/registry-client").RegistryRequestFailed | import("@agentxm/registry-client").RegistryOperationFailed | import("@agentxm/workspace-state").LockfileIoError | import("@agentxm/workspace-state").LockfileParseError | import("@agentxm/workspace-state").LockfileDecodeError | import("@agentxm/workspace-state").LockfileVersionUnsupported | WorkspaceSettingsReadFailure | import("@agentxm/workspace-state").LockfileValidationError | import("@agentxm/workspace-state").LockEntrySourceMissing | import("@agentxm/workspace-state").LockEntryUrlInvalid | import("@agentxm/workspace-state").LockEntryNameInvalid | import("@agentxm/workspace-state").LockEntryEndpointConflict | import("@agentxm/workspace-state").LockEntrySourceTypeConflict | import("@agentxm/workspace-state").AcceptedResolutionMissing | import("@agentxm/workspace-state").InlineExtensionSourceMissing | import("@agentxm/workspace-state").PackageContentHashFailed | import("@agentxm/workspace-state").WorkspaceSourceInvalid | import("@agentxm/extension-model/unstable/extensions").FqnInvalidError | import("@agentxm/extension-resolution").ExtensionResolutionFailed | import("@agentxm/workspace-operations").CandidateFingerprintFailed, FileSystem.FileSystem | Path.Path | WorkspaceMutations | import("@agentxm/workspace-state").ConfiguredAgentOutcomesProvider | ExtensionManagers | import("effect/unstable/http/HttpClient").HttpClient | import("@agentxm/extension-resolution").ReleaseAgePosture | import("effect/Scope").Scope | import("@agentxm/extension-sources").SourceHostProviders | import("@agentxm/extension-sources").WorkspaceCatalog>;
72
+ }, ExtensionLifecycleFailed | import("@agentxm/workspace-state").PathTraversalDetected | import("@agentxm/extension-sources").SourceSyntaxInvalid | import("@agentxm/extension-sources").SourceHostNotConfigured | import("@agentxm/extension-sources").SourceNotResolvable | import("@agentxm/extension-sources").SourceNetworkFailure | import("@agentxm/extension-sources").GitOperationFailed | import("@agentxm/extension-sources").WorkspaceCatalogUnavailable | import("@agentxm/extension-sources").AxmSkillGateUnavailable | import("@agentxm/registry-client").RegistryProblem | import("@agentxm/registry-client").RegistryRequestFailed | import("@agentxm/registry-client").RegistryOperationFailed | import("@agentxm/workspace-state").LockfileIoError | import("@agentxm/workspace-state").LockfileParseError | import("@agentxm/workspace-state").LockfileDecodeError | import("@agentxm/workspace-state").LockfileVersionUnsupported | WorkspaceSettingsReadFailure | import("@agentxm/workspace-state").LockfileValidationError | import("@agentxm/workspace-state").LockEntrySourceMissing | import("@agentxm/workspace-state").LockEntryUrlInvalid | import("@agentxm/workspace-state").LockEntryNameInvalid | import("@agentxm/workspace-state").LockEntryEndpointConflict | import("@agentxm/workspace-state").LockEntrySourceTypeConflict | import("@agentxm/workspace-state").AcceptedResolutionMissing | import("@agentxm/workspace-state").InlineExtensionSourceMissing | import("@agentxm/workspace-state").PackageContentHashFailed | import("@agentxm/workspace-state").WorkspaceSourceInvalid | import("@agentxm/extension-model/unstable/extensions").FqnInvalidError | import("@agentxm/extension-resolution").ExtensionResolutionFailed | import("@agentxm/workspace-operations").CandidateFingerprintFailed, FileSystem.FileSystem | Path.Path | WorkspaceMutations | import("effect/unstable/http/HttpClient").HttpClient | import("@agentxm/workspace-state").ConfiguredAgentOutcomesProvider | ExtensionManagers | import("@agentxm/extension-resolution").ReleaseAgePosture | import("effect/Scope").Scope | import("@agentxm/extension-sources").SourceHostProviders | import("@agentxm/extension-sources").WorkspaceCatalog>;
73
73
  export declare const prepareDemote: (request: DemoteRequest) => Effect.Effect<DemoteCandidate, DemoteFailure, PrepareDemoteRequirements>;
74
74
  /** Preview or apply a settled demotion, resolving to one operation outcome. */
75
75
  export declare const previewOrApplyDemote: (candidate: DemoteCandidate, execution: PlanExecution) => Effect.Effect<import("@agentxm/workspace-operations").OperationResolution<never>, WorkspaceSettingsReadFailure | import("@agentxm/workspace-operations").ApprovalRecoveryMissing | import("@agentxm/workspace-operations").PlanInteractionFailed | import("@agentxm/workspace-transactions").WorkspaceTransitionAcquireFailure, import("@agentxm/workspace-state").ConfiguredAgentOutcomesProvider | import("@agentxm/workspace-transactions").FootprintRecorder | import("@agentxm/workspace-operations").OperationJournal | import("@agentxm/workspace-operations").ResolvePlanInteraction | InstallStepRequirements>;
@@ -20,7 +20,8 @@ import * as Effect from "effect/Effect";
20
20
  import * as FileSystem from "effect/FileSystem";
21
21
  import * as Option from "effect/Option";
22
22
  import * as Path from "effect/Path";
23
- import { ExtensionManagers, buildInstallOperation } from "@agentxm/extension-materialization";
23
+ import { ExtensionManagers } from "@agentxm/extension-materialization";
24
+ import { buildInstallOperation } from "@agentxm/workspace-reconciliation";
24
25
  import { formatFqn, parseFqn, } from "@agentxm/extension-model/unstable/extensions";
25
26
  import { isWorkspaceSourceLocator } from "@agentxm/extension-model/unstable/sources/workspace";
26
27
  import { makeConfiguredReleaseAgeEvaluation, resolveConfiguredHook, resolveConfiguredKnowledge, resolveConfiguredMcpServer, resolveConfiguredPack, resolveConfiguredRule, resolveConfiguredSkill, resolveConfiguredSubagent, } from "@agentxm/extension-resolution";
@@ -88,7 +89,7 @@ const restoreDisabledState = (ws, type, name) => {
88
89
  // -----------------------------------------------------------------------------
89
90
  /**
90
91
  * Resolve the replacement package from its new source and compose the install
91
- * that replaces the authored content. `allowWorkspaceReplacement` is the one
92
+ * that replaces the authored content. `sourceReplacements` is the one
92
93
  * place source authority is deliberately overridden, and it is named here so
93
94
  * no other route can reach it by accident.
94
95
  */
@@ -98,43 +99,71 @@ const replacementStep = Effect.fn("Demote.replacementStep")(function* (type, nam
98
99
  // The one place source authority is deliberately overridden.
99
100
  const common = {
100
101
  toStepFailure: lifecycleStepFailure,
101
- allowWorkspaceReplacement: true,
102
+ sourceReplacements: [{ type, name }],
102
103
  };
103
104
  switch (type) {
104
105
  case "skill":
105
- return buildInstallOperation(managers.skill, {
106
- ...common,
107
- ...(yield* resolveConfiguredSkill(name, source, evaluation)),
106
+ return yield* Effect.gen(function* () {
107
+ const resolved = yield* resolveConfiguredSkill(name, source, evaluation);
108
+ return buildInstallOperation(managers.skill, {
109
+ ...common,
110
+ ...resolved,
111
+ declaration: { name, versionRange: resolved.versionRange },
112
+ });
108
113
  });
109
114
  case "mcp-server":
110
- return buildInstallOperation(managers["mcp-server"], {
111
- ...common,
112
- ...(yield* resolveConfiguredMcpServer(name, source, evaluation)),
115
+ return yield* Effect.gen(function* () {
116
+ const resolved = yield* resolveConfiguredMcpServer(name, source, evaluation);
117
+ return buildInstallOperation(managers["mcp-server"], {
118
+ ...common,
119
+ ...resolved,
120
+ declaration: { name, versionRange: resolved.versionRange },
121
+ });
113
122
  });
114
123
  case "subagent":
115
- return buildInstallOperation(managers.subagent, {
116
- ...common,
117
- ...(yield* resolveConfiguredSubagent(name, source, evaluation)),
124
+ return yield* Effect.gen(function* () {
125
+ const resolved = yield* resolveConfiguredSubagent(name, source, evaluation);
126
+ return buildInstallOperation(managers.subagent, {
127
+ ...common,
128
+ ...resolved,
129
+ declaration: { name, versionRange: resolved.versionRange },
130
+ });
118
131
  });
119
132
  case "rule":
120
- return buildInstallOperation(managers.rule, {
121
- ...common,
122
- ...(yield* resolveConfiguredRule(name, source, evaluation)),
133
+ return yield* Effect.gen(function* () {
134
+ const resolved = yield* resolveConfiguredRule(name, source, evaluation);
135
+ return buildInstallOperation(managers.rule, {
136
+ ...common,
137
+ ...resolved,
138
+ declaration: { name, versionRange: resolved.versionRange },
139
+ });
123
140
  });
124
141
  case "hook":
125
- return buildInstallOperation(managers.hook, {
126
- ...common,
127
- ...(yield* resolveConfiguredHook(name, source, evaluation)),
142
+ return yield* Effect.gen(function* () {
143
+ const resolved = yield* resolveConfiguredHook(name, source, evaluation);
144
+ return buildInstallOperation(managers.hook, {
145
+ ...common,
146
+ ...resolved,
147
+ declaration: { name, versionRange: resolved.versionRange },
148
+ });
128
149
  });
129
150
  case "knowledge":
130
- return buildInstallOperation(managers.knowledge, {
131
- ...common,
132
- ...(yield* resolveConfiguredKnowledge(name, source, evaluation)),
151
+ return yield* Effect.gen(function* () {
152
+ const resolved = yield* resolveConfiguredKnowledge(name, source, evaluation);
153
+ return buildInstallOperation(managers.knowledge, {
154
+ ...common,
155
+ ...resolved,
156
+ declaration: { name, versionRange: resolved.versionRange },
157
+ });
133
158
  });
134
159
  case "pack":
135
- return buildInstallOperation(managers.pack, {
136
- ...common,
137
- ...(yield* resolveConfiguredPack(name, source, evaluation)),
160
+ return yield* Effect.gen(function* () {
161
+ const resolved = yield* resolveConfiguredPack(name, source, evaluation);
162
+ return buildInstallOperation(managers.pack, {
163
+ ...common,
164
+ ...resolved,
165
+ declaration: { name, versionRange: resolved.versionRange },
166
+ });
138
167
  });
139
168
  }
140
169
  });
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Hook-backed implementation of the workspace-state
2
+ * Extension-manager-backed implementation of the workspace-state
3
3
  * `ConfiguredAgentOutcomesProvider` port.
4
4
  *
5
- * The plan pipeline consumes the port; the hook manager owns the effective
5
+ * The plan pipeline consumes the port; extension managers own the effective
6
6
  * per-agent outcome facts. Only the composition root sees both, so the
7
7
  * application wires this layer over the manager, supplying its own failure
8
8
  * serialization so plan resolutions embed byte-identical step failures on
@@ -17,6 +17,6 @@ import * as HttpClient from "effect/unstable/http/HttpClient";
17
17
  import { NativeWriteAuthority } from "@agentxm/agent-integration";
18
18
  import { ConfiguredAgentOutcomesProvider } from "@agentxm/workspace-state";
19
19
  import { StepFailureConversion } from "../step-failure-conversion.js";
20
- import { HookManager } from "@agentxm/extension-materialization";
21
- export declare const HookConfiguredAgentOutcomesProviderLive: Layer.Layer<ConfiguredAgentOutcomesProvider, never, StepFailureConversion | FileSystem.FileSystem | Path.Path | NativeWriteAuthority | HttpClient.HttpClient | HookManager>;
20
+ import { HookManager, McpServerManager } from "@agentxm/extension-materialization";
21
+ export declare const ConfiguredAgentOutcomesProviderLive: Layer.Layer<ConfiguredAgentOutcomesProvider, never, StepFailureConversion | FileSystem.FileSystem | Path.Path | NativeWriteAuthority | HttpClient.HttpClient | HookManager | McpServerManager>;
22
22
  //# sourceMappingURL=configured-agent-outcomes-provider.d.ts.map
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Hook-backed implementation of the workspace-state
2
+ * Extension-manager-backed implementation of the workspace-state
3
3
  * `ConfiguredAgentOutcomesProvider` port.
4
4
  *
5
- * The plan pipeline consumes the port; the hook manager owns the effective
5
+ * The plan pipeline consumes the port; extension managers own the effective
6
6
  * per-agent outcome facts. Only the composition root sees both, so the
7
7
  * application wires this layer over the manager, supplying its own failure
8
8
  * serialization so plan resolutions embed byte-identical step failures on
@@ -18,28 +18,34 @@ import * as HttpClient from "effect/unstable/http/HttpClient";
18
18
  import { NativeWriteAuthority } from "@agentxm/agent-integration";
19
19
  import { ConfiguredAgentOutcomesProvider, ConfiguredAgentOutcomesUnavailable, } from "@agentxm/workspace-state";
20
20
  import { StepFailureConversion } from "../step-failure-conversion.js";
21
- import { HookManager } from "@agentxm/extension-materialization";
22
- export const HookConfiguredAgentOutcomesProviderLive = Layer.effect(ConfiguredAgentOutcomesProvider, Effect.gen(function* () {
21
+ import { HookManager, McpServerManager } from "@agentxm/extension-materialization";
22
+ export const ConfiguredAgentOutcomesProviderLive = Layer.effect(ConfiguredAgentOutcomesProvider, Effect.gen(function* () {
23
23
  const adapter = yield* StepFailureConversion;
24
24
  const hookManager = yield* HookManager;
25
+ const mcpServerManager = yield* McpServerManager;
25
26
  // The provider's members answer with no requirements of their own, so this
26
27
  // layer is the boundary that composes what the manager needs.
27
28
  const managerLayer = Layer.mergeAll(Layer.succeed(FileSystem.FileSystem, yield* FileSystem.FileSystem), Layer.succeed(Path.Path, yield* Path.Path), Layer.succeed(HttpClient.HttpClient, yield* HttpClient.HttpClient), Layer.succeed(NativeWriteAuthority, yield* NativeWriteAuthority));
28
- const configuredAgentOutcomes = hookManager.configuredAgentOutcomes;
29
- if (configuredAgentOutcomes === undefined) {
30
- return { byExtensionType: {} };
31
- }
29
+ const mapFailure = (failure) => {
30
+ const step = adapter.toStepFailure(failure);
31
+ return new ConfiguredAgentOutcomesUnavailable({
32
+ category: step.category,
33
+ detail: step.detail,
34
+ ...(step.suggestions === undefined ? {} : { suggestions: step.suggestions }),
35
+ ...(step.cause === undefined ? {} : { cause: step.cause }),
36
+ });
37
+ };
38
+ const configuredHookOutcomes = hookManager.configuredAgentOutcomes;
32
39
  return {
33
40
  byExtensionType: {
34
- hook: (state) => configuredAgentOutcomes(state).pipe(Effect.provide(managerLayer), Effect.mapError((failure) => {
35
- const step = adapter.toStepFailure(failure);
36
- return new ConfiguredAgentOutcomesUnavailable({
37
- category: step.category,
38
- detail: step.detail,
39
- ...(step.suggestions === undefined ? {} : { suggestions: step.suggestions }),
40
- ...(step.cause === undefined ? {} : { cause: step.cause }),
41
- });
42
- })),
41
+ ...(configuredHookOutcomes === undefined
42
+ ? {}
43
+ : {
44
+ hook: (state) => configuredHookOutcomes(state).pipe(Effect.provide(managerLayer), Effect.mapError(mapFailure)),
45
+ }),
46
+ "mcp-server": (state) => mcpServerManager
47
+ .configuredAgentOutcomes(state)
48
+ .pipe(Effect.provide(managerLayer), Effect.mapError(mapFailure)),
43
49
  },
44
50
  };
45
51
  }));
@@ -9,7 +9,8 @@
9
9
  */
10
10
  import * as Effect from "effect/Effect";
11
11
  import * as Option from "effect/Option";
12
- import { HookManager, buildInstallOperation } from "@agentxm/extension-materialization";
12
+ import { HookManager } from "@agentxm/extension-materialization";
13
+ import { buildInstallOperation } from "@agentxm/workspace-reconciliation";
13
14
  import { parseSourceQualifiedRegistrySourcePatternParts, } from "@agentxm/extension-model/unstable/extensions";
14
15
  import { HOOK_EXTENSION_DIR } from "@agentxm/extension-model/unstable/hooks/manifest-schema";
15
16
  import { SourceHostProviders, resolveSource } from "@agentxm/extension-sources";
@@ -137,8 +138,10 @@ export const planHookInstall = Effect.fn("InstallExtensions.planHooks")(function
137
138
  const operation = buildInstallOperation(hookManager, {
138
139
  toStepFailure: lifecycleStepFailure,
139
140
  ref,
140
- versionRange,
141
- skipProjections: deferProjections,
141
+ declaration: { name: ref.hook.name, versionRange },
142
+ ...(deferProjections
143
+ ? { enclosingClosure: { projections: [ref.type], postconditions: [] } }
144
+ : {}),
142
145
  installedBefore: Effect.succeed(installedBefore),
143
146
  message: `Installed ${ref.hook.name}`,
144
147
  buildArtifact: ({ installedBefore }) => Effect.gen(function* () {
@@ -9,11 +9,12 @@
9
9
  */
10
10
  import * as Effect from "effect/Effect";
11
11
  import * as Option from "effect/Option";
12
- import { HookManager, buildUninstallOperation } from "@agentxm/extension-materialization";
12
+ import { HookManager } from "@agentxm/extension-materialization";
13
+ import { buildUninstallOperation } from "@agentxm/workspace-reconciliation";
13
14
  import { WorkspaceMutations, acquiredExtensionDisplayPathFromLockEntry, } from "@agentxm/workspace-state";
14
15
  import { lifecycleStepFailure } from "../../step-failure.js";
15
16
  import { installRefused } from "../../install/vocabulary.js";
16
- import { makeWorkspaceRetentionPolicy } from "../../uninstall/retention-policy.js";
17
+ import { makeWorkspaceRetentionPolicy } from "@agentxm/workspace-reconciliation";
17
18
  import { workspaceCanonicalRoot, workspaceLockfilePath, workspaceSettingsPath, } from "../../workspace-paths.js";
18
19
  const hookUninstallArtifactTargets = (entry, retained, targetName, scope) => {
19
20
  if (Option.isNone(entry))
@@ -47,7 +48,7 @@ export const parseHookUninstallRequest = Effect.fn("UninstallExtensions.parseHoo
47
48
  export const planHookUninstall = Effect.fn("UninstallExtensions.planHooks")(function* (intent) {
48
49
  const ws = yield* WorkspaceMutations;
49
50
  const hookManager = yield* HookManager;
50
- const retentionPolicy = makeWorkspaceRetentionPolicy(ws);
51
+ const retentionPolicy = makeWorkspaceRetentionPolicy(ws, lifecycleStepFailure);
51
52
  const steps = yield* Effect.forEach(intent.targets, (target) => Effect.gen(function* () {
52
53
  const lockEntry = yield* ws
53
54
  .getLockedHookEntry(target.name)
@@ -30,12 +30,11 @@ export { planRuleInstall } from "./rules/install/plan.js";
30
30
  export { planSkillInstall } from "./skills/install/plan.js";
31
31
  export { planSubagentInstall } from "./subagents/install/plan.js";
32
32
  export { BUNDLED_AXM_SKILL_AUTHORED_BLOCKER, BundledAxmSkillAsset, bundledAxmSkillCanonicalPath, inspectBundledAxmSkillReadiness, installBundledAxmSkill, type BundledAxmSkillAssetService, type BundledAxmSkillReadiness, type BundledAxmSkillSourceFile, } from "./skills/install/bundled.js";
33
- export { buildAtomicPackGraphStep, validatePackGraphPostcondition, type AtomicPackGraphChild, } from "./packs/graph-transition.js";
33
+ export { validatePackGraphPostcondition } from "./packs/graph-transition.js";
34
34
  export { buildPackMemberInstallStep, type PackMemberRef } from "./packs/member-install-step.js";
35
35
  export { configuredPackConstraintBlockPlan, prospectivePackConstraintProblems, relevantPackConstraintProblems, } from "./packs/constraint-gate.js";
36
36
  export { UninstallExtensions, prepareUninstallExtensions, previewOrApplyUninstallExtensions, type PrepareUninstallRequirements, type UninstallExtensionsCandidate, type UninstallExtensionsFailure, type UninstallExtensionsRequest, } from "./uninstall/uninstall-extensions.js";
37
37
  export { resolveRootUninstallIntent, rootUninstallableTypeSegments, type RootUninstallIntent, type RootUninstallableType, } from "./uninstall/root-intent.js";
38
- export { exclusiveMemberRetentionPolicy, makeWorkspaceRetentionPolicy, } from "./uninstall/retention-policy.js";
39
38
  export { PACK_UNINSTALL_GRAPH_BLOCKER_ID, packUninstallRecoveryIdentifiers, planPackUninstallGraphReadiness, type PackRetirement, type PackUninstallGraphReadiness, } from "./packs/uninstall/readiness.js";
40
39
  export { type PackUninstallIntent, type PackUninstallRequirements, type ResolvedPackUninstallTarget, } from "./packs/uninstall/plan.js";
41
40
  export { getSkillDisplayName } from "./skills/utils.js";
package/dist/src/index.js CHANGED
@@ -35,13 +35,12 @@ export { planSubagentInstall } from "./subagents/install/plan.js";
35
35
  // The bundled official AXM skill, and the asset port the application fills.
36
36
  export { BUNDLED_AXM_SKILL_AUTHORED_BLOCKER, BundledAxmSkillAsset, bundledAxmSkillCanonicalPath, inspectBundledAxmSkillReadiness, installBundledAxmSkill, } from "./skills/install/bundled.js";
37
37
  // Pack graph transitions: the atomic step and its desired-state predicate.
38
- export { buildAtomicPackGraphStep, validatePackGraphPostcondition, } from "./packs/graph-transition.js";
38
+ export { validatePackGraphPostcondition } from "./packs/graph-transition.js";
39
39
  export { buildPackMemberInstallStep } from "./packs/member-install-step.js";
40
40
  export { configuredPackConstraintBlockPlan, prospectivePackConstraintProblems, relevantPackConstraintProblems, } from "./packs/constraint-gate.js";
41
41
  // Uninstall: withdrawing extensions, as one use case behind every spelling.
42
42
  export { UninstallExtensions, prepareUninstallExtensions, previewOrApplyUninstallExtensions, } from "./uninstall/uninstall-extensions.js";
43
43
  export { resolveRootUninstallIntent, rootUninstallableTypeSegments, } from "./uninstall/root-intent.js";
44
- export { exclusiveMemberRetentionPolicy, makeWorkspaceRetentionPolicy, } from "./uninstall/retention-policy.js";
45
44
  export { PACK_UNINSTALL_GRAPH_BLOCKER_ID, packUninstallRecoveryIdentifiers, planPackUninstallGraphReadiness, } from "./packs/uninstall/readiness.js";
46
45
  export {} from "./packs/uninstall/plan.js";
47
46
  // Skill lifecycle operations
@@ -2,8 +2,8 @@ import * as Effect from "effect/Effect";
2
2
  import * as Schema from "effect/Schema";
3
3
  import type { ExtensionLifecycleFailed } from "../errors.js";
4
4
  import { type InstallableExtensionType } from "@agentxm/extension-model/unstable/extensions/installable-types";
5
- export declare const rootInstallableTypeSegments: readonly ("knowledge" | "rules" | "hooks" | "mcps" | "skills" | "subagents" | "packs")[];
6
- export declare const RootInstallableTypeSegmentSchema: Schema.Literals<readonly ("knowledge" | "rules" | "hooks" | "mcps" | "skills" | "subagents" | "packs")[]>;
5
+ export declare const rootInstallableTypeSegments: readonly ("knowledge" | "rules" | "hooks" | "skills" | "subagents" | "packs" | "mcps")[];
6
+ export declare const RootInstallableTypeSegmentSchema: Schema.Literals<readonly ("knowledge" | "rules" | "hooks" | "skills" | "subagents" | "packs" | "mcps")[]>;
7
7
  export type RootInstallableTypeSegment = typeof RootInstallableTypeSegmentSchema.Type;
8
8
  export type RootInstallableType = InstallableExtensionType;
9
9
  export interface RootInstallIntent {
@@ -15,7 +15,8 @@ import type * as Path from "effect/Path";
15
15
  import type * as Scope from "effect/Scope";
16
16
  import type * as HttpClient from "effect/unstable/http/HttpClient";
17
17
  import type { NativeWriteAuthority } from "@agentxm/agent-integration";
18
- import type { ManagerRequirements, McpSecretStore, RecipeRequirements } from "@agentxm/extension-materialization";
18
+ import type { ManagerRequirements, McpSecretStore } from "@agentxm/extension-materialization";
19
+ import type { RecipeRequirements } from "@agentxm/workspace-reconciliation";
19
20
  import type { ExtensionName } from "@agentxm/extension-model/unstable/extensions";
20
21
  import type { HookExtensionRef } from "@agentxm/extension-model/unstable/extensions/refs/hook";
21
22
  import type { KnowledgeExtensionRef } from "@agentxm/extension-model/unstable/extensions/refs/knowledge";
@@ -29,8 +30,8 @@ import type { VersionRange } from "@agentxm/extension-model/unstable/version-con
29
30
  import type { ExtensionResolutionFailed, PackDependencyRefResolver } from "@agentxm/extension-resolution";
30
31
  import type { SourceHostProviders, WorkspaceCatalog } from "@agentxm/extension-sources";
31
32
  import type { ApprovalRecoveryMissing, CandidateFingerprintFailed, OperationJournal, PlanInteractionFailed, ResolvePlanInteraction } from "@agentxm/workspace-operations";
32
- import type { CodingAgentRepository } from "@agentxm/workspace-projection";
33
- import type { AcceptedCanonicalRefError, ConfiguredAgentOutcomesProvider, LockfileValidationError, WorkspaceMutations, WorkspaceSettingsReadFailure, WorkspaceStateReadFailure } from "@agentxm/workspace-state";
33
+ import type { CodingAgentRepository, WorkspaceInvariantFacts } from "@agentxm/workspace-projection";
34
+ import type { AcceptedCanonicalRefError, ConfiguredAgentOutcomesProvider, LockfileValidationError, LockfileReader, WorkspaceMutations, WorkspaceSettingsReadFailure, WorkspaceStateReadFailure } from "@agentxm/workspace-state";
34
35
  import type { FootprintRecorder, WorkspaceTransactionScope, WorkspaceTransitionAcquireFailure } from "@agentxm/workspace-transactions";
35
36
  import { ExtensionLifecycleFailed } from "../errors.js";
36
37
  /**
@@ -41,7 +42,7 @@ import { ExtensionLifecycleFailed } from "../errors.js";
41
42
  * composed once at the application's runtime boundary; nothing is captured
42
43
  * into a step's closure on the way, and no failure adapter is among them.
43
44
  */
44
- export type InstallStepRequirements = ManagerRequirements | RecipeRequirements | McpSecretStore | CodingAgentRepository | WorkspaceMutations | NativeWriteAuthority;
45
+ export type InstallStepRequirements = ManagerRequirements | RecipeRequirements | McpSecretStore | CodingAgentRepository | LockfileReader | WorkspaceInvariantFacts | WorkspaceMutations | NativeWriteAuthority;
45
46
  /**
46
47
  * What routing a source locator, probing configured registries, and reading
47
48
  * what a source contains all need.
@@ -9,7 +9,8 @@
9
9
  */
10
10
  import * as Effect from "effect/Effect";
11
11
  import * as Option from "effect/Option";
12
- import { KnowledgeManager, extensionRefLifecycleWarnings, extensionRefRegistryLifecycle, targetFromRef, toLabelWithCompanions, toStepKey, } from "@agentxm/extension-materialization";
12
+ import { KnowledgeManager } from "@agentxm/extension-materialization";
13
+ import { extensionRefLifecycleWarnings, extensionRefRegistryLifecycle, targetFromRef, toLabelWithCompanions, toStepKey, } from "@agentxm/workspace-reconciliation";
13
14
  import { parseSourceQualifiedRegistrySourcePatternParts, } from "@agentxm/extension-model/unstable/extensions";
14
15
  import { SourceHostProviders, resolveSource } from "@agentxm/extension-sources";
15
16
  import { operationPresentation, } from "@agentxm/workspace-operations";
@@ -12,14 +12,15 @@ import * as Effect from "effect/Effect";
12
12
  import * as FileSystem from "effect/FileSystem";
13
13
  import * as Option from "effect/Option";
14
14
  import * as Path from "effect/Path";
15
- import { KnowledgeManager, KnowledgeUnavailable, buildUninstallOperation, } from "@agentxm/extension-materialization";
15
+ import { KnowledgeManager, KnowledgeUnavailable } from "@agentxm/extension-materialization";
16
+ import { buildUninstallOperation } from "@agentxm/workspace-reconciliation";
16
17
  import { makeWorkspaceRelativePath } from "@agentxm/extension-model/unstable/path-types";
17
18
  import { resolveInstructionsConfig } from "@agentxm/workspace-projection";
18
19
  import { WorkspaceMutations, acceptedCanonicalObservation, computeExtensionPathsForLayout, extensionPathSourceFromLockEntry, } from "@agentxm/workspace-state";
19
20
  import { ExtensionLifecycleFailed } from "../../errors.js";
20
21
  import { lifecycleStepFailure } from "../../step-failure.js";
21
22
  import { installRefused } from "../../install/vocabulary.js";
22
- import { makeWorkspaceRetentionPolicy } from "../../uninstall/retention-policy.js";
23
+ import { makeWorkspaceRetentionPolicy } from "@agentxm/workspace-reconciliation";
23
24
  const lockCanonicalRoot = (path, layout, locked) => computeExtensionPathsForLayout(path.join, layout, extensionPathSourceFromLockEntry(locked), "knowledge", locked.workspaceName).canonicalPath;
24
25
  /** Settle whether this Knowledge bundle has anything to remove. */
25
26
  export const parseKnowledgeUninstallRequest = Effect.fn("UninstallExtensions.parseKnowledgeRequest")(function* (selector) {
@@ -107,7 +108,7 @@ const inspectOwnership = Effect.fn("UninstallExtensions.inspectKnowledgeOwnershi
107
108
  export const planKnowledgeUninstall = Effect.fn("UninstallExtensions.planKnowledge")(function* (intent) {
108
109
  const ws = yield* WorkspaceMutations;
109
110
  const manager = yield* KnowledgeManager;
110
- const retentionPolicy = makeWorkspaceRetentionPolicy(ws);
111
+ const retentionPolicy = makeWorkspaceRetentionPolicy(ws, lifecycleStepFailure);
111
112
  /** The accepted ownership fact, not on-disk presence, decides removability. */
112
113
  const isAcceptedTargetPresent = (target) => Effect.gen(function* () {
113
114
  const graph = yield* ws.getDesiredStateGraph();
@@ -7,5 +7,5 @@
7
7
  * @experimental All exports from this module are unstable and may change without notice.
8
8
  * @packageDocumentation
9
9
  */
10
- export { HookConfiguredAgentOutcomesProviderLive } from "./hooks/configured-agent-outcomes-provider.js";
10
+ export { ConfiguredAgentOutcomesProviderLive } from "./hooks/configured-agent-outcomes-provider.js";
11
11
  //# sourceMappingURL=live.d.ts.map
package/dist/src/live.js CHANGED
@@ -7,5 +7,5 @@
7
7
  * @experimental All exports from this module are unstable and may change without notice.
8
8
  * @packageDocumentation
9
9
  */
10
- export { HookConfiguredAgentOutcomesProviderLive } from "./hooks/configured-agent-outcomes-provider.js";
10
+ export { ConfiguredAgentOutcomesProviderLive } from "./hooks/configured-agent-outcomes-provider.js";
11
11
  //# sourceMappingURL=live.js.map
@@ -12,7 +12,7 @@ import * as Effect from "effect/Effect";
12
12
  import * as Option from "effect/Option";
13
13
  import * as Result from "effect/Result";
14
14
  import * as Schema from "effect/Schema";
15
- import { installMcpServer } from "@agentxm/extension-materialization";
15
+ import { installMcpServer } from "@agentxm/workspace-reconciliation";
16
16
  import { CONFIGURABLE_AGENTS_BY_ID, } from "@agentxm/extension-model/unstable/agent-capabilities";
17
17
  import { ExtensionNameSchema, } from "@agentxm/extension-model/unstable/extensions";
18
18
  import { intersectVersionConstraints } from "@agentxm/extension-model/unstable/version-constraints";
@@ -287,8 +287,7 @@ export const planMcpServerInstall = Effect.fn("InstallExtensions.planMcpServer")
287
287
  localName: intent.localName,
288
288
  nonInteractive: intent.nonInteractive,
289
289
  force: intent.force,
290
- versionRange: intent.versionRange,
291
- skipSettings: Option.none(),
290
+ declaration: { name: intent.localName, versionRange: intent.versionRange },
292
291
  env: Option.some(intent.env ?? {}),
293
292
  },
294
293
  }).pipe(Effect.mapError(lifecycleStepFailure)),
@@ -35,7 +35,7 @@ export const disableMcpServer = (op) => Effect.gen(function* () {
35
35
  workspaceRoot: ws.baseDir,
36
36
  scope: ws.scope,
37
37
  serverName: op.args.serverName,
38
- disableOnly: true,
38
+ disableOnly: false,
39
39
  }), { concurrency: "unbounded" });
40
40
  yield* requireSuccessfulMcpSync(op.args.serverName, agents.map((agent, index) => ({
41
41
  agentId: agent.id,
@@ -7,8 +7,8 @@ import * as FileSystem from "effect/FileSystem";
7
7
  import * as Path from "effect/Path";
8
8
  import * as Effect from "effect/Effect";
9
9
  import * as Option from "effect/Option";
10
- import { CodingAgentRepository, applyProjectionPlansWithResults, planSingletonProjection, } from "@agentxm/workspace-projection";
11
- import { NativeWriteAuthority, syncInlineMcpServerToAgents } from "@agentxm/agent-integration";
10
+ import { CodingAgentRepository } from "@agentxm/workspace-projection";
11
+ import { NativeWriteAuthority, syncInlineMcpServerToAgents, syncManifestMcpServerToAgents, } from "@agentxm/agent-integration";
12
12
  import { normalizeHandle, parseExtensionFqnParts, } from "@agentxm/extension-model/unstable/extensions";
13
13
  import { appendWarningsToMessage } from "@agentxm/workspace-operations";
14
14
  import { WorkspaceMutations } from "@agentxm/workspace-state";
@@ -117,37 +117,22 @@ export const enableMcpServer = (op) => Effect.gen(function* () {
117
117
  const owner = trustedIdentity?.type === "mcp-server" ? trustedIdentity.owner : normalizeHandle("@local");
118
118
  const resolvedVersion = accepted?.type === "registry" ? accepted.resolvedVersion : "0.0.0";
119
119
  const agents = yield* agentRepo.getConfiguredAgents();
120
+ const agentIds = agents.map(({ id }) => id);
120
121
  const outcomes = yield* runWorkspaceTransaction({
121
122
  transition: Effect.gen(function* () {
122
- const synced = yield* applyProjectionPlansWithResults(agents.map((agent) => planSingletonProjection({
123
- unitId: "mcp-server:native-config-entry",
124
- targetFile: "mcp:configured-agents",
125
- contributor: op.args,
126
- adapter: {
127
- observe: () => Effect.succeed({
128
- unitId: "mcp-server:native-config-entry",
129
- path: `${agent.id}:${op.args.serverName}`,
130
- present: false,
131
- current: false,
132
- expectedContributors: [op.args.serverName],
133
- observedContributors: [],
134
- }),
135
- apply: () => Effect.gen(function* () {
136
- return yield* agent.addMcpServer({
137
- workspaceRoot: ws.baseDir,
138
- scope: ws.scope,
139
- serverName: op.args.serverName,
140
- canonicalPath,
141
- owner,
142
- resolvedVersion,
143
- enabled: true,
144
- configValues: entry.env,
145
- });
146
- }),
147
- },
148
- })));
149
- yield* requireSuccessfulMcpSync(op.args.serverName, agents.map((agent, index) => ({
150
- agentId: agent.id,
123
+ const synced = yield* syncManifestMcpServerToAgents({
124
+ agentIds,
125
+ workspaceRoot: ws.baseDir,
126
+ scope: ws.scope,
127
+ serverName: op.args.serverName,
128
+ canonicalPath,
129
+ owner,
130
+ resolvedVersion,
131
+ enabled: true,
132
+ configValues: entry.env,
133
+ });
134
+ yield* requireSuccessfulMcpSync(op.args.serverName, agentIds.map((agentId, index) => ({
135
+ agentId,
151
136
  outcome: synced[index] ?? {
152
137
  _tag: "failed",
153
138
  reason: "Agent sync returned no outcome",
@@ -161,17 +146,17 @@ export const enableMcpServer = (op) => Effect.gen(function* () {
161
146
  }).pipe(Effect.provideService(FileSystem.FileSystem, fs), Effect.provideService(Path.Path, path)),
162
147
  validate: () => Effect.void,
163
148
  });
164
- const warnings = mcpSyncWarnings(op.args.serverName, agents.map((agent, index) => ({
165
- agentId: agent.id,
149
+ const warnings = mcpSyncWarnings(op.args.serverName, agentIds.map((agentId, index) => ({
150
+ agentId,
166
151
  outcome: outcomes[index] ?? {
167
152
  _tag: "failed",
168
153
  reason: "Agent sync returned no outcome",
169
154
  },
170
155
  })));
171
- const agentOutcomes = agents.flatMap((agent, index) => {
156
+ const agentOutcomes = agentIds.flatMap((agentId, index) => {
172
157
  const outcome = outcomes[index];
173
158
  return outcome !== undefined && "targets" in outcome
174
- ? [{ agentId: agent.id, targets: outcome.targets }]
159
+ ? [{ agentId, targets: outcome.targets }]
175
160
  : [];
176
161
  });
177
162
  return {
@@ -18,7 +18,8 @@ import { appendWarningsToMessage } from "@agentxm/workspace-operations";
18
18
  import { WorkspaceMutations } from "@agentxm/workspace-state";
19
19
  import { removeIfExists } from "@agentxm/workspace-state";
20
20
  import { acceptedCanonicalObservation, acceptedLockedCanonicalPath, removableAcceptedCanonicalPath, } from "@agentxm/workspace-state";
21
- import { agentConfigTarget, collectSecretInputNames, deleteMcpSecrets, mcpServerArtifact, mcpSettingsTarget, readMcpServerManifest, McpSecretStore, } from "@agentxm/extension-materialization";
21
+ import { agentConfigTarget, mcpServerArtifact, mcpSettingsTarget, McpSecretStore, } from "@agentxm/extension-materialization";
22
+ import { collectSecretInputNames, deleteMcpSecrets, readMcpServerManifest, } from "@agentxm/workspace-reconciliation";
22
23
  import { StepFailureConversion, withAdaptedStepFailures } from "../../step-failure-conversion.js";
23
24
  import { ExtensionLifecycleFailed } from "../../errors.js";
24
25
  const REQUIRED_AGENT_IDS = new Set([
@@ -13,11 +13,13 @@ import * as Effect from "effect/Effect";
13
13
  import * as FileSystem from "effect/FileSystem";
14
14
  import * as Option from "effect/Option";
15
15
  import * as Path from "effect/Path";
16
- import { McpServerManager, buildUninstallOperation, collectSecretInputNames, deleteMcpSecrets, mcpServerArtifact, mcpSourceTarget, readMcpServerManifest, } from "@agentxm/extension-materialization";
16
+ import { McpServerManager, mcpServerArtifact, mcpSourceTarget, } from "@agentxm/extension-materialization";
17
+ import { collectSecretInputNames, deleteMcpSecrets, readMcpServerManifest, } from "@agentxm/workspace-reconciliation";
18
+ import { buildUninstallOperation } from "@agentxm/workspace-reconciliation";
17
19
  import { appendWarningsToMessage, } from "@agentxm/workspace-operations";
18
20
  import { WorkspaceMutations, acceptedLockedCanonicalPath, } from "@agentxm/workspace-state";
19
21
  import { lifecycleStepFailure } from "../../step-failure.js";
20
- import { makeWorkspaceRetentionPolicy } from "../../uninstall/retention-policy.js";
22
+ import { makeWorkspaceRetentionPolicy } from "@agentxm/workspace-reconciliation";
21
23
  import { workspaceLockfilePath, workspaceSettingsPath } from "../../workspace-paths.js";
22
24
  /** One local connection name is removed at a time. */
23
25
  export const parseMcpServerUninstallRequest = (selector) => ({
@@ -28,7 +30,7 @@ export const planMcpServerUninstall = Effect.fn("UninstallExtensions.planMcpServ
28
30
  const ws = yield* WorkspaceMutations;
29
31
  const mcpServerManager = yield* McpServerManager;
30
32
  const path = yield* Path.Path;
31
- const retentionPolicy = makeWorkspaceRetentionPolicy(ws);
33
+ const retentionPolicy = makeWorkspaceRetentionPolicy(ws, lifecycleStepFailure);
32
34
  const steps = intent.targets.map((target) => {
33
35
  const step = buildUninstallOperation(mcpServerManager, retentionPolicy, {
34
36
  toStepFailure: lifecycleStepFailure,
@@ -63,7 +65,14 @@ export const planMcpServerUninstall = Effect.fn("UninstallExtensions.planMcpServ
63
65
  onNone: () => new Set(),
64
66
  onSome: collectSecretInputNames,
65
67
  });
66
- const secretDeletionWarnings = unchanged || desiredNode === undefined || desiredNode.authority === "inline"
68
+ const remaining = yield* ws
69
+ .getDesiredStateGraph()
70
+ .pipe(Effect.mapError(lifecycleStepFailure));
71
+ const remainsDesired = remaining.nodes.some((node) => node.type === "mcp-server" && node.name === target.name);
72
+ const secretDeletionWarnings = unchanged ||
73
+ remainsDesired ||
74
+ desiredNode === undefined ||
75
+ desiredNode.authority === "inline"
67
76
  ? []
68
77
  : (yield* deleteMcpSecrets({
69
78
  scopeRoot: path.resolve(ws.baseDir),
@@ -11,32 +11,7 @@
11
11
  */
12
12
  import * as Effect from "effect/Effect";
13
13
  import { WorkspaceMutations, type DesiredExtensionNode } from "@agentxm/workspace-state";
14
- import { type JobStepArtifact, type PlannedJobStep } from "@agentxm/workspace-operations";
15
14
  import type { ExtensionLifecycleFailed } from "../errors.js";
16
- import { type LifecycleStepFailure } from "../step-failure.js";
17
- import { type InstallStepRequirements } from "../install/vocabulary.js";
18
- export interface AtomicPackGraphChild {
19
- readonly step: PlannedJobStep<InstallStepRequirements>;
20
- readonly coverage: "eligible" | "ineligible";
21
- }
22
- /**
23
- * What a pack transition checks before it writes and after it commits. The
24
- * checks are the planner's, so their failure family and their requirements
25
- * travel with them rather than being fixed here.
26
- */
27
- export interface AtomicPackGraphStepArgs<E extends LifecycleStepFailure, R> {
28
- readonly label: string;
29
- readonly message: string;
30
- readonly artifact: JobStepArtifact;
31
- readonly children: ReadonlyArray<AtomicPackGraphChild>;
32
- readonly reportUnchangedWhenChildrenUnchanged?: boolean;
33
- /** A stale-candidate check that runs under the transition, before any write. */
34
- readonly preTransition?: Effect.Effect<void, E, R>;
35
- /** The desired-graph predicate the committed transition must satisfy. */
36
- readonly validate: Effect.Effect<void, E, R>;
37
- }
38
- /** Wrap a pack transition's children in one workspace transaction. */
39
- export declare const buildAtomicPackGraphStep: <E extends LifecycleStepFailure, R>(args: AtomicPackGraphStepArgs<E, R>) => Effect.Effect<PlannedJobStep<InstallStepRequirements | R>>;
40
15
  interface RequiredPack {
41
16
  readonly name: string;
42
17
  readonly identity: string;