@agentxm/extension-lifecycle 0.28.12 → 0.28.13

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 (207) hide show
  1. package/dist/src/activation/display-paths.d.ts +25 -0
  2. package/dist/src/activation/display-paths.js +25 -0
  3. package/dist/src/activation/errors.d.ts +16 -0
  4. package/dist/src/activation/errors.js +7 -0
  5. package/dist/src/activation/set-activation.d.ts +134 -0
  6. package/dist/src/activation/set-activation.js +772 -0
  7. package/dist/src/demote/demote-to-external-source.d.ts +82 -0
  8. package/dist/src/demote/demote-to-external-source.js +233 -0
  9. package/dist/src/errors.d.ts +0 -8
  10. package/dist/src/errors.js +0 -8
  11. package/dist/src/glob.d.ts +35 -0
  12. package/dist/src/glob.js +75 -0
  13. package/dist/src/hooks/configured-agent-outcomes-provider.d.ts +7 -3
  14. package/dist/src/hooks/configured-agent-outcomes-provider.js +11 -4
  15. package/dist/src/hooks/install/plan.d.ts +45 -0
  16. package/dist/src/hooks/install/plan.js +224 -0
  17. package/dist/src/hooks/uninstall/plan.d.ts +20 -0
  18. package/dist/src/hooks/uninstall/plan.js +77 -0
  19. package/dist/src/index.d.ts +48 -16
  20. package/dist/src/index.js +60 -17
  21. package/dist/src/install/aggregate-projection-step.d.ts +16 -0
  22. package/dist/src/install/aggregate-projection-step.js +49 -0
  23. package/dist/src/install/configured.d.ts +65 -0
  24. package/dist/src/install/configured.js +406 -0
  25. package/dist/src/install/inline-mcp-operation.d.ts +4 -0
  26. package/dist/src/install/inline-mcp-operation.js +25 -0
  27. package/dist/src/install/install-extensions.d.ts +110 -0
  28. package/dist/src/install/install-extensions.js +282 -0
  29. package/dist/src/install/per-type-install.d.ts +12 -0
  30. package/dist/src/install/per-type-install.js +12 -0
  31. package/dist/src/install/registry-install-target.d.ts +35 -0
  32. package/dist/src/install/registry-install-target.js +66 -0
  33. package/dist/src/install/registry-login-suggestion.d.ts +21 -0
  34. package/dist/src/install/registry-login-suggestion.js +34 -0
  35. package/dist/src/install/registry-source-resolution.d.ts +54 -0
  36. package/dist/src/install/registry-source-resolution.js +216 -0
  37. package/dist/src/install/root-intent.d.ts +19 -0
  38. package/dist/src/install/root-intent.js +122 -0
  39. package/dist/src/install/selection-interaction.d.ts +46 -0
  40. package/dist/src/install/selection-interaction.js +22 -0
  41. package/dist/src/install/vocabulary.d.ts +143 -0
  42. package/dist/src/install/vocabulary.js +29 -0
  43. package/dist/src/knowledge/install/plan.d.ts +35 -0
  44. package/dist/src/knowledge/install/plan.js +128 -0
  45. package/dist/src/knowledge/uninstall/plan.d.ts +23 -0
  46. package/dist/src/knowledge/uninstall/plan.js +140 -0
  47. package/dist/src/live.d.ts +4 -11
  48. package/dist/src/live.js +4 -11
  49. package/dist/src/mcps/install/plan.d.ts +65 -0
  50. package/dist/src/mcps/install/plan.js +301 -0
  51. package/dist/src/mcps/operations/disable.d.ts +5 -3
  52. package/dist/src/mcps/operations/disable.js +6 -4
  53. package/dist/src/mcps/operations/enable.d.ts +5 -3
  54. package/dist/src/mcps/operations/enable.js +8 -6
  55. package/dist/src/mcps/operations/sync-outcome.d.ts +1 -1
  56. package/dist/src/mcps/operations/uninstall.d.ts +5 -3
  57. package/dist/src/mcps/operations/uninstall.js +4 -4
  58. package/dist/src/mcps/uninstall/plan.d.ts +24 -0
  59. package/dist/src/mcps/uninstall/plan.js +109 -0
  60. package/dist/src/packs/artifact.d.ts +21 -0
  61. package/dist/src/packs/artifact.js +32 -0
  62. package/dist/src/packs/constraint-gate.d.ts +30 -0
  63. package/dist/src/packs/constraint-gate.js +76 -0
  64. package/dist/src/packs/expansion.d.ts +13 -14
  65. package/dist/src/packs/expansion.js +1 -2
  66. package/dist/src/packs/graph-transition.d.ts +64 -0
  67. package/dist/src/packs/graph-transition.js +219 -0
  68. package/dist/src/packs/install/plan.d.ts +95 -0
  69. package/dist/src/packs/install/plan.js +845 -0
  70. package/dist/src/packs/member-install-step.d.ts +29 -0
  71. package/dist/src/packs/member-install-step.js +156 -0
  72. package/dist/src/packs/operations/install.d.ts +3 -3
  73. package/dist/src/packs/operations/install.js +5 -5
  74. package/dist/src/packs/promote-authored-pack.d.ts +86 -0
  75. package/dist/src/packs/promote-authored-pack.js +239 -0
  76. package/dist/src/packs/resolved-dependency.d.ts +9 -26
  77. package/dist/src/packs/resolved-dependency.js +8 -20
  78. package/dist/src/packs/uninstall/plan.d.ts +66 -0
  79. package/dist/src/packs/uninstall/plan.js +344 -0
  80. package/dist/src/packs/uninstall/readiness.d.ts +50 -0
  81. package/dist/src/packs/uninstall/readiness.js +130 -0
  82. package/dist/src/publisher-binding.d.ts +8 -40
  83. package/dist/src/publisher-binding.js +8 -46
  84. package/dist/src/rules/install/plan.d.ts +35 -0
  85. package/dist/src/rules/install/plan.js +133 -0
  86. package/dist/src/rules/uninstall/plan.d.ts +19 -0
  87. package/dist/src/rules/uninstall/plan.js +54 -0
  88. package/dist/src/skills/install/bundled.d.ts +73 -0
  89. package/dist/src/skills/install/bundled.js +244 -0
  90. package/dist/src/skills/install/plan.d.ts +72 -0
  91. package/dist/src/skills/install/plan.js +429 -0
  92. package/dist/src/skills/install/selection.d.ts +26 -0
  93. package/dist/src/skills/install/selection.js +41 -0
  94. package/dist/src/skills/install/source.d.ts +21 -0
  95. package/dist/src/skills/install/source.js +76 -0
  96. package/dist/src/skills/operations/disable.d.ts +3 -2
  97. package/dist/src/skills/operations/disable.js +7 -11
  98. package/dist/src/skills/operations/enable.d.ts +3 -2
  99. package/dist/src/skills/operations/enable.js +6 -8
  100. package/dist/src/skills/operations/install.d.ts +4 -4
  101. package/dist/src/skills/operations/install.js +13 -12
  102. package/dist/src/skills/uninstall/plan.d.ts +23 -0
  103. package/dist/src/skills/uninstall/plan.js +165 -0
  104. package/dist/src/skills/utils.js +1 -1
  105. package/dist/src/step-failure-conversion.d.ts +44 -0
  106. package/dist/src/step-failure-conversion.js +26 -0
  107. package/dist/src/step-failure.d.ts +29 -0
  108. package/dist/src/step-failure.js +130 -0
  109. package/dist/src/subagents/install/plan.d.ts +49 -0
  110. package/dist/src/subagents/install/plan.js +270 -0
  111. package/dist/src/subagents/install/selection.d.ts +26 -0
  112. package/dist/src/subagents/install/selection.js +37 -0
  113. package/dist/src/subagents/install/source.d.ts +18 -0
  114. package/dist/src/subagents/install/source.js +72 -0
  115. package/dist/src/subagents/operations/disable.d.ts +5 -3
  116. package/dist/src/subagents/operations/disable.js +5 -3
  117. package/dist/src/subagents/operations/enable.d.ts +5 -3
  118. package/dist/src/subagents/operations/enable.js +17 -12
  119. package/dist/src/subagents/uninstall/plan.d.ts +20 -0
  120. package/dist/src/subagents/uninstall/plan.js +142 -0
  121. package/dist/src/test-packages.d.ts +34 -0
  122. package/dist/src/test-packages.js +111 -0
  123. package/dist/src/test-registry.d.ts +78 -0
  124. package/dist/src/test-registry.js +223 -0
  125. package/dist/src/testing.d.ts +108 -0
  126. package/dist/src/testing.js +241 -0
  127. package/dist/src/uninstall/retention-policy.d.ts +21 -0
  128. package/dist/src/uninstall/retention-policy.js +28 -0
  129. package/dist/src/uninstall/root-intent.d.ts +17 -0
  130. package/dist/src/uninstall/root-intent.js +101 -0
  131. package/dist/src/uninstall/uninstall-extensions.d.ts +61 -0
  132. package/dist/src/uninstall/uninstall-extensions.js +127 -0
  133. package/dist/src/uninstall/vocabulary.d.ts +40 -0
  134. package/dist/src/uninstall/vocabulary.js +14 -0
  135. package/dist/src/update/atomicity.d.ts +22 -0
  136. package/dist/src/update/atomicity.js +23 -0
  137. package/dist/src/update/blockers.d.ts +31 -0
  138. package/dist/src/update/blockers.js +78 -0
  139. package/dist/src/update/configured.d.ts +78 -0
  140. package/dist/src/update/configured.js +546 -0
  141. package/dist/src/update/root-request.d.ts +39 -0
  142. package/dist/src/update/root-request.js +117 -0
  143. package/dist/src/update/selective/plan.d.ts +45 -0
  144. package/dist/src/update/selective/plan.js +61 -0
  145. package/dist/src/update/selective/requirements.d.ts +17 -0
  146. package/dist/src/update/selective/requirements.js +14 -0
  147. package/dist/src/update/selective/selection.d.ts +63 -0
  148. package/dist/src/update/selective/selection.js +85 -0
  149. package/dist/src/update/selective/skills.d.ts +55 -0
  150. package/dist/src/update/selective/skills.js +596 -0
  151. package/dist/src/update/selective/subagents.d.ts +52 -0
  152. package/dist/src/update/selective/subagents.js +331 -0
  153. package/dist/src/update/selective/use-case.d.ts +121 -0
  154. package/dist/src/update/selective/use-case.js +28 -0
  155. package/dist/src/update/selective/vocabulary.d.ts +43 -0
  156. package/dist/src/update/selective/vocabulary.js +28 -0
  157. package/dist/src/update/selector.d.ts +72 -0
  158. package/dist/src/update/selector.js +120 -0
  159. package/dist/src/update/targeted-plan.d.ts +30 -0
  160. package/dist/src/update/targeted-plan.js +113 -0
  161. package/dist/src/update/update-extensions.d.ts +164 -0
  162. package/dist/src/update/update-extensions.js +579 -0
  163. package/dist/src/workspace-paths.d.ts +31 -0
  164. package/dist/src/workspace-paths.js +46 -0
  165. package/package.json +22 -12
  166. package/dist/src/configured-entry-resolution.d.ts +0 -111
  167. package/dist/src/configured-entry-resolution.js +0 -731
  168. package/dist/src/failure-adapter.d.ts +0 -35
  169. package/dist/src/failure-adapter.js +0 -23
  170. package/dist/src/hooks/manager.d.ts +0 -15
  171. package/dist/src/hooks/manager.js +0 -769
  172. package/dist/src/internal/fs-helpers.d.ts +0 -12
  173. package/dist/src/internal/fs-helpers.js +0 -13
  174. package/dist/src/internal/integrity.d.ts +0 -13
  175. package/dist/src/internal/integrity.js +0 -17
  176. package/dist/src/knowledge/manager.d.ts +0 -11
  177. package/dist/src/knowledge/manager.js +0 -711
  178. package/dist/src/mcps/manager.d.ts +0 -16
  179. package/dist/src/mcps/manager.js +0 -247
  180. package/dist/src/mcps/operations/artifact.d.ts +0 -24
  181. package/dist/src/mcps/operations/artifact.js +0 -74
  182. package/dist/src/mcps/operations/install.d.ts +0 -78
  183. package/dist/src/mcps/operations/install.js +0 -596
  184. package/dist/src/packs/dependency-resolution.d.ts +0 -65
  185. package/dist/src/packs/dependency-resolution.js +0 -414
  186. package/dist/src/packs/manager.d.ts +0 -16
  187. package/dist/src/packs/manager.js +0 -181
  188. package/dist/src/registry-materialization.d.ts +0 -52
  189. package/dist/src/registry-materialization.js +0 -72
  190. package/dist/src/release-age-posture.d.ts +0 -23
  191. package/dist/src/release-age-posture.js +0 -15
  192. package/dist/src/resolution-timeout.d.ts +0 -5
  193. package/dist/src/resolution-timeout.js +0 -11
  194. package/dist/src/rules/manager.d.ts +0 -20
  195. package/dist/src/rules/manager.js +0 -480
  196. package/dist/src/skills/manager.d.ts +0 -18
  197. package/dist/src/skills/manager.js +0 -346
  198. package/dist/src/skills/materialization.d.ts +0 -54
  199. package/dist/src/skills/materialization.js +0 -158
  200. package/dist/src/skills/operations/source-hash.d.ts +0 -2
  201. package/dist/src/skills/operations/source-hash.js +0 -6
  202. package/dist/src/subagents/manager.d.ts +0 -18
  203. package/dist/src/subagents/manager.js +0 -722
  204. package/dist/src/workflows/install-command/workflow.d.ts +0 -56
  205. package/dist/src/workflows/install-command/workflow.js +0 -46
  206. package/dist/src/workflows/uninstall-command/workflow.d.ts +0 -42
  207. package/dist/src/workflows/uninstall-command/workflow.js +0 -29
@@ -1,58 +1,20 @@
1
1
  /**
2
- * Publisher binding trust classification.
2
+ * Publisher-change plan shaping.
3
3
  *
4
- * A Registry resolution binds a publisher identity. When an operation
5
- * proposes to replace an already accepted binding for the same configured
6
- * extension with a different one, that transition is a trust decision a
7
- * person makes at a prompt: no flag and no unattended mode can approve it.
8
- * Every route that can replace an accepted binding — root and type update
9
- * forms, reinstall and re-resolution, and pack closures — classifies the
10
- * transition from the structured accepted and proposed identities here, so
11
- * the same rule holds everywhere the transition can occur.
12
- *
13
- * A first acceptance is not a change, and an integrity mismatch while
14
- * reacquiring the same accepted identity remains a hard failure elsewhere.
4
+ * `@agentxm/extension-resolution` classifies whether a proposed Registry
5
+ * acceptance replaces an accepted publisher binding. This module turns that
6
+ * classification into plan vocabulary: the per-step warning, the
7
+ * interactive-only risk condition, and the blocking condition raised when an
8
+ * accepted resolution cannot be read at all.
15
9
  *
16
10
  * @experimental This API is unstable and may change without notice.
17
11
  */
18
12
  import * as Effect from "effect/Effect";
19
13
  import * as Option from "effect/Option";
20
- import { toExtensionTypePlural } from "@agentxm/extension-model/unstable/extensions/common";
14
+ import { classifyPublisherBindingTransition, describePublisherBindingTransition, publisherTransitionWarning, } from "@agentxm/extension-resolution";
21
15
  import { acceptedResolutionRef, WorkspaceMutations } from "@agentxm/workspace-state";
22
- import { targetFromRef } from "@agentxm/extension-workspace";
23
16
  export const PUBLISHER_CHANGE_CONDITION_ID = "publisher-ownership-change";
24
17
  const ACCEPTED_RESOLUTION_UNREADABLE_ID = "accepted-resolution-unreadable";
25
- /** The structured proposal an extension ref makes, when it is a Registry ref. */
26
- export const registryBindingProposal = (ref) => ref.refType === "registry"
27
- ? {
28
- extensionType: ref.type,
29
- target: targetFromRef(ref).name,
30
- owner: ref.owner,
31
- packageName: ref.name,
32
- version: ref.version,
33
- publisherBindingId: ref.publisherBindingId,
34
- }
35
- : undefined;
36
- /**
37
- * Classify one proposed acceptance against the accepted resolution for the
38
- * same configured target. Only a Registry binding replacing a different
39
- * Registry binding is a publisher change.
40
- */
41
- export const classifyPublisherBindingTransition = (args) => Option.flatMap(args.accepted, (accepted) => accepted.refType === "registry" &&
42
- accepted.type === args.proposed.extensionType &&
43
- accepted.publisherBindingId !== args.proposed.publisherBindingId
44
- ? Option.some({
45
- extensionType: args.proposed.extensionType,
46
- target: args.proposed.target,
47
- owner: args.proposed.owner,
48
- packageName: args.proposed.packageName,
49
- accepted: accepted.publisherBindingId,
50
- proposed: args.proposed.publisherBindingId,
51
- })
52
- : Option.none());
53
- const describeTransition = (transition) => `${transition.owner}/${toExtensionTypePlural(transition.extensionType)}/${transition.packageName}`;
54
- /** The warning a step carries when its acceptance changes publisher. */
55
- export const publisherTransitionWarning = (transition) => `Publisher identity changed (${transition.accepted} → ${transition.proposed}); confirm only if you trust the current publisher`;
56
18
  /**
57
19
  * The interactive-only condition a plan carries when any of its steps
58
20
  * replaces an accepted publisher binding.
@@ -64,7 +26,7 @@ export const publisherChangeRiskCondition = (transitions) => transitions.length
64
26
  consent: "interactive-only",
65
27
  id: PUBLISHER_CHANGE_CONDITION_ID,
66
28
  detail: `Publisher identity changed for ${transitions
67
- .map(describeTransition)
29
+ .map(describePublisherBindingTransition)
68
30
  .join(", ")}; confirm only if you trust the current publisher.`,
69
31
  };
70
32
  /** Append the publisher-change condition for the given transitions, if any. */
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Installing rules.
3
+ *
4
+ * The source grammar a rule request accepts, the discovery that turns it into
5
+ * refs, and the closure each ref becomes — including who renders the shared
6
+ * instructions region when more than one rule lands in the same operation.
7
+ *
8
+ * @experimental This API is unstable and may change without notice.
9
+ */
10
+ import * as Effect from "effect/Effect";
11
+ import * as Option from "effect/Option";
12
+ import { RuleManager } from "@agentxm/extension-materialization";
13
+ import { type Handle } from "@agentxm/extension-model/unstable/extensions";
14
+ import type { RuleExtensionRef } from "@agentxm/extension-model/unstable/extensions/refs/rule";
15
+ import type { Source } from "@agentxm/extension-model/unstable/sources/types";
16
+ import type { VersionRange } from "@agentxm/extension-model/unstable/version-constraints";
17
+ import { type Plan } from "@agentxm/workspace-operations";
18
+ import type { ExtensionLifecycleFailed } from "../../errors.js";
19
+ import { type InstallStepRequirements, type ResolveInstallRequirements, type RuleInstallIntent } from "../../install/vocabulary.js";
20
+ /** A rule source after grammar parsing, before anything is discovered. */
21
+ export interface ParsedRuleInstallRequest {
22
+ readonly source: Source;
23
+ readonly names: ReadonlyArray<string>;
24
+ readonly owner: Option.Option<Handle>;
25
+ readonly versionRange: Option.Option<VersionRange>;
26
+ }
27
+ /** Read the rule source grammar: which owner, which names, which range. */
28
+ export declare const parseRuleInstallRequest: (source: string) => Effect.Effect<ParsedRuleInstallRequest, ExtensionLifecycleFailed, ResolveInstallRequirements>;
29
+ /** Discover the rules the parsed source offers. */
30
+ export declare const discoverRuleRefs: (request: ParsedRuleInstallRequest) => Effect.Effect<ReadonlyArray<RuleExtensionRef>, ExtensionLifecycleFailed, ResolveInstallRequirements>;
31
+ /** Settle which rules this request installs, or refuse when none matched. */
32
+ export declare const finalizeRuleInstallIntent: (request: ParsedRuleInstallRequest, refs: ReadonlyArray<RuleExtensionRef>) => Effect.Effect<RuleInstallIntent, ExtensionLifecycleFailed>;
33
+ /** The closures a settled rule intent becomes. */
34
+ export declare const planRuleInstall: (intent: RuleInstallIntent) => Effect.Effect<Plan<InstallStepRequirements>, ExtensionLifecycleFailed, InstallStepRequirements | RuleManager>;
35
+ //# sourceMappingURL=plan.d.ts.map
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Installing rules.
3
+ *
4
+ * The source grammar a rule request accepts, the discovery that turns it into
5
+ * refs, and the closure each ref becomes — including who renders the shared
6
+ * instructions region when more than one rule lands in the same operation.
7
+ *
8
+ * @experimental This API is unstable and may change without notice.
9
+ */
10
+ import * as Effect from "effect/Effect";
11
+ import * as Option from "effect/Option";
12
+ import { RuleManager, buildInstallOperation } from "@agentxm/extension-materialization";
13
+ import { parseSourceQualifiedRegistrySourcePatternParts, } from "@agentxm/extension-model/unstable/extensions";
14
+ import { SourceHostProviders, resolveSource } from "@agentxm/extension-sources";
15
+ import { operationPresentation, } from "@agentxm/workspace-operations";
16
+ import { applyPlannedProjections } from "@agentxm/workspace-projection";
17
+ import { WorkspaceMutations } from "@agentxm/workspace-state";
18
+ import { lifecycleStepFailure } from "../../step-failure.js";
19
+ import { registryLoginSuggestions } from "../../install/registry-login-suggestion.js";
20
+ import { installRefused, } from "../../install/vocabulary.js";
21
+ /** Read the rule source grammar: which owner, which names, which range. */
22
+ export const parseRuleInstallRequest = Effect.fn("InstallExtensions.parseRuleRequest")(function* (source) {
23
+ const input = source.trim();
24
+ const parsed = parseSourceQualifiedRegistrySourcePatternParts(input);
25
+ const resolved = yield* resolveSource(input).pipe(Effect.mapError((error) => installRefused({
26
+ category: "validation",
27
+ detail: `Invalid rule source: ${error.message}`,
28
+ cause: error,
29
+ })));
30
+ return {
31
+ source: resolved,
32
+ names: parsed?.type === "rules" && parsed.name !== undefined ? [parsed.name] : [],
33
+ owner: parsed?.type === "rules"
34
+ ? Option.some(parsed.owner)
35
+ : resolved.type === "registry"
36
+ ? resolved.owner
37
+ : Option.none(),
38
+ versionRange: resolved.type === "registry" && parsed?.type === "rules"
39
+ ? Option.fromUndefinedOr(parsed.versionRange)
40
+ : Option.none(),
41
+ };
42
+ });
43
+ /** Discover the rules the parsed source offers. */
44
+ export const discoverRuleRefs = Effect.fn("InstallExtensions.discoverRules")(function* (request) {
45
+ const sources = yield* SourceHostProviders;
46
+ return yield* sources
47
+ .find(request.source, {
48
+ names: request.names,
49
+ type: "rule",
50
+ owner: request.owner,
51
+ versionRange: request.versionRange,
52
+ })
53
+ .pipe(Effect.mapError((cause) => installRefused({
54
+ category: "network",
55
+ detail: "Rules could not be discovered from the source",
56
+ cause,
57
+ })), Effect.map((refs) => refs.filter((ref) => ref.type === "rule")));
58
+ });
59
+ /** Settle which rules this request installs, or refuse when none matched. */
60
+ export const finalizeRuleInstallIntent = Effect.fn("InstallExtensions.finalizeRuleIntent")(function* (request, refs) {
61
+ if (refs.length === 0) {
62
+ const suggestions = request.source.type === "registry"
63
+ ? yield* registryLoginSuggestions([request.source.location.href])
64
+ : [];
65
+ return yield* installRefused({
66
+ category: "not_found",
67
+ detail: "No rules found in source",
68
+ suggestions,
69
+ });
70
+ }
71
+ return {
72
+ refs: refs.map((ref) => ({
73
+ ref,
74
+ versionRange: ref.refType === "registry" ? request.versionRange : Option.none(),
75
+ })),
76
+ };
77
+ });
78
+ /** The closures a settled rule intent becomes. */
79
+ export const planRuleInstall = Effect.fn("InstallExtensions.planRules")(function* (intent) {
80
+ const ws = yield* WorkspaceMutations;
81
+ const ruleManager = yield* RuleManager;
82
+ // One rule renders the shared instructions region itself; several rules in
83
+ // one operation defer it so the region is rendered once, from the complete
84
+ // contributor set.
85
+ const deferProjections = intent.deferProjections === true || intent.refs.length > 1;
86
+ const memberSteps = intent.refs.map(({ ref, versionRange }) => buildInstallOperation(ruleManager, {
87
+ toStepFailure: lifecycleStepFailure,
88
+ ref,
89
+ versionRange,
90
+ skipProjections: deferProjections,
91
+ installedBefore: ruleManager.isInstalled({
92
+ target: { type: "rule", name: ref.rule.name },
93
+ }),
94
+ buildArtifact: ({ installedBefore }) => Effect.gen(function* () {
95
+ const materialization = yield* ruleManager.aggregateProjectionObservation;
96
+ const change = installedBefore ? "updated" : "created";
97
+ const targets = materialization.targets.map((target) => ({
98
+ path: target.path,
99
+ change,
100
+ ...(target.agentIds === undefined ? {} : { agentIds: target.agentIds }),
101
+ }));
102
+ return {
103
+ path: targets[0]?.path ?? ref.rule.name,
104
+ scope: ws.scope,
105
+ agents: materialization.agents,
106
+ ...(ref.refType === "registry" ? { version: ref.version } : {}),
107
+ change,
108
+ ...(targets.length === 0 ? {} : { fileCount: targets.length, targets }),
109
+ };
110
+ }),
111
+ }));
112
+ const projectionSteps = deferProjections && intent.deferProjections !== true
113
+ ? [
114
+ {
115
+ key: "projection:rule:instructions-region",
116
+ label: "rule projections",
117
+ readiness: "ready",
118
+ run: applyPlannedProjections(ruleManager).pipe(Effect.mapError(lifecycleStepFailure), Effect.as({
119
+ result: "success",
120
+ message: "Rendered installed Rules from the complete contributor set",
121
+ })),
122
+ },
123
+ ]
124
+ : [];
125
+ return {
126
+ _tag: "Plan",
127
+ name: "Install rules",
128
+ description: Option.some("Install rule"),
129
+ presentation: operationPresentation({ imperative: "install", past: "Installed", gerund: "Installing" }, "rule"),
130
+ jobs: [{ concurrency: 1, steps: [...memberSteps, ...projectionSteps] }],
131
+ };
132
+ });
133
+ //# sourceMappingURL=plan.js.map
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Uninstalling a rule.
3
+ *
4
+ * A rule that is neither declared nor installed has nothing to remove, so the
5
+ * request settles to an empty target list rather than a refusal.
6
+ *
7
+ * @experimental This API is unstable and may change without notice.
8
+ */
9
+ import * as Effect from "effect/Effect";
10
+ import { RuleManager } from "@agentxm/extension-materialization";
11
+ import type { Plan } from "@agentxm/workspace-operations";
12
+ import type { ExtensionLifecycleFailed } from "../../errors.js";
13
+ import { type InstallStepRequirements } from "../../install/vocabulary.js";
14
+ import type { RuleUninstallIntent } from "../../uninstall/vocabulary.js";
15
+ /** Settle whether this rule has anything to remove. */
16
+ export declare const parseRuleUninstallRequest: (selector: string) => Effect.Effect<RuleUninstallIntent, ExtensionLifecycleFailed, InstallStepRequirements | RuleManager>;
17
+ /** The closures a settled rule removal becomes. */
18
+ export declare const planRuleUninstall: (intent: RuleUninstallIntent) => Effect.Effect<Plan<InstallStepRequirements>, ExtensionLifecycleFailed, InstallStepRequirements | RuleManager>;
19
+ //# sourceMappingURL=plan.d.ts.map
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Uninstalling a rule.
3
+ *
4
+ * A rule that is neither declared nor installed has nothing to remove, so the
5
+ * request settles to an empty target list rather than a refusal.
6
+ *
7
+ * @experimental This API is unstable and may change without notice.
8
+ */
9
+ import * as Effect from "effect/Effect";
10
+ import * as Option from "effect/Option";
11
+ import { RuleManager, buildUninstallOperation } from "@agentxm/extension-materialization";
12
+ import { WorkspaceMutations } from "@agentxm/workspace-state";
13
+ import { lifecycleStepFailure } from "../../step-failure.js";
14
+ import { installRefused } from "../../install/vocabulary.js";
15
+ import { makeWorkspaceRetentionPolicy } from "../../uninstall/retention-policy.js";
16
+ /** Settle whether this rule has anything to remove. */
17
+ export const parseRuleUninstallRequest = Effect.fn("UninstallExtensions.parseRuleRequest")(function* (selector) {
18
+ const ruleManager = yield* RuleManager;
19
+ const target = { type: "rule", name: selector.trim() };
20
+ return yield* Effect.gen(function* () {
21
+ const configured = ruleManager.getConfiguredSource === undefined
22
+ ? Option.none()
23
+ : yield* ruleManager.getConfiguredSource({ target });
24
+ const installed = yield* ruleManager.isInstalled({ target });
25
+ return Option.isNone(configured) && !installed
26
+ ? { targets: [] }
27
+ : { targets: [target] };
28
+ }).pipe(Effect.mapError((cause) => installRefused({
29
+ category: "internal",
30
+ detail: `Rule "${target.name}" declaration could not be read`,
31
+ cause,
32
+ })));
33
+ });
34
+ /** The closures a settled rule removal becomes. */
35
+ export const planRuleUninstall = Effect.fn("UninstallExtensions.planRules")(function* (intent) {
36
+ const ws = yield* WorkspaceMutations;
37
+ const ruleManager = yield* RuleManager;
38
+ const retentionPolicy = makeWorkspaceRetentionPolicy(ws);
39
+ return {
40
+ _tag: "Plan",
41
+ name: "Uninstall rule",
42
+ description: Option.some("Uninstall rule"),
43
+ jobs: [
44
+ {
45
+ concurrency: 1,
46
+ steps: intent.targets.map((target) => buildUninstallOperation(ruleManager, retentionPolicy, {
47
+ target,
48
+ toStepFailure: lifecycleStepFailure,
49
+ })),
50
+ },
51
+ ],
52
+ };
53
+ });
54
+ //# sourceMappingURL=plan.js.map
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Installing the official AXM skill that ships inside the CLI.
3
+ *
4
+ * The skill's content travels with the executable rather than a registry, so
5
+ * the application supplies it through an asset port and the lifecycle decides
6
+ * everything else: that an authored copy is never overwritten, that the
7
+ * canonical directory is replaced atomically, that the entry is declared as
8
+ * bundled with no accepted external resolution behind it, and that what ends
9
+ * up installed is compatible with the CLI that installed it.
10
+ *
11
+ * @experimental This API is unstable and may change without notice.
12
+ */
13
+ import * as ServiceMap from "effect/Context";
14
+ import * as Effect from "effect/Effect";
15
+ import * as Path from "effect/Path";
16
+ import { type Plan } from "@agentxm/workspace-operations";
17
+ import { WorkspaceMutations } from "@agentxm/workspace-state";
18
+ import { ExtensionLifecycleFailed } from "../../errors.js";
19
+ import { type InstallStepRequirements } from "../../install/vocabulary.js";
20
+ /** One file of the bundled skill's source tree. */
21
+ export interface BundledAxmSkillSourceFile {
22
+ /** Path relative to the skill's `src` directory. */
23
+ readonly path: string;
24
+ readonly base64: string;
25
+ }
26
+ /**
27
+ * The official skill as the running executable carries it, plus the version
28
+ * of that executable. The generator that produces this belongs to the
29
+ * application; the lifecycle only reads it.
30
+ */
31
+ export interface BundledAxmSkillAssetService {
32
+ readonly manifestJson: string;
33
+ readonly version: string;
34
+ readonly cliVersion: string;
35
+ readonly cliVersionRange: string;
36
+ readonly sourceFiles: ReadonlyArray<BundledAxmSkillSourceFile>;
37
+ /** The CLI version this invocation is running. */
38
+ readonly runningCliVersion: string;
39
+ }
40
+ declare const BundledAxmSkillAsset_base: ServiceMap.ServiceClass<BundledAxmSkillAsset, "@agentxm/extension-lifecycle/skills/BundledAxmSkillAsset", BundledAxmSkillAssetService>;
41
+ export declare class BundledAxmSkillAsset extends BundledAxmSkillAsset_base {
42
+ }
43
+ export declare const BUNDLED_AXM_SKILL_AUTHORED_BLOCKER = "The official AXM skill is workspace-authored; bundled recovery will not overwrite its in-flight source.";
44
+ export type BundledAxmSkillReadiness = {
45
+ readonly readiness: "ready";
46
+ readonly canonicalPath: string;
47
+ } | {
48
+ readonly readiness: "error";
49
+ readonly canonicalPath: string;
50
+ readonly errorMessage: string;
51
+ };
52
+ /** Where the bundled skill's canonical package sits. */
53
+ export declare const bundledAxmSkillCanonicalPath: (ws: ServiceMap.Service.Shape<typeof WorkspaceMutations>, path: Path.Path) => string;
54
+ /** Whether bundled recovery may write, or must preserve an authored copy. */
55
+ export declare const inspectBundledAxmSkillReadiness: Effect.Effect<{
56
+ readiness: "error";
57
+ canonicalPath: string;
58
+ errorMessage: string;
59
+ } | {
60
+ readiness: "ready";
61
+ canonicalPath: string;
62
+ errorMessage?: never;
63
+ }, import("@agentxm/workspace-state").WorkspaceSettingsReadFailure, Path.Path | WorkspaceMutations>;
64
+ /** Install the embedded official AXM skill as one rollback-safe transition. */
65
+ export declare const installBundledAxmSkill: Effect.Effect<void, ExtensionLifecycleFailed, InstallStepRequirements | BundledAxmSkillAsset>;
66
+ /**
67
+ * The single closure a bundled install becomes: one step that replaces the
68
+ * canonical package and declares it, refused up front when an authored copy
69
+ * of the official skill is in flight.
70
+ */
71
+ export declare const planBundledAxmSkillInstall: Effect.Effect<Plan<InstallStepRequirements | BundledAxmSkillAsset>, ExtensionLifecycleFailed, InstallStepRequirements>;
72
+ export {};
73
+ //# sourceMappingURL=bundled.d.ts.map
@@ -0,0 +1,244 @@
1
+ /**
2
+ * Installing the official AXM skill that ships inside the CLI.
3
+ *
4
+ * The skill's content travels with the executable rather than a registry, so
5
+ * the application supplies it through an asset port and the lifecycle decides
6
+ * everything else: that an authored copy is never overwritten, that the
7
+ * canonical directory is replaced atomically, that the entry is declared as
8
+ * bundled with no accepted external resolution behind it, and that what ends
9
+ * up installed is compatible with the CLI that installed it.
10
+ *
11
+ * @experimental This API is unstable and may change without notice.
12
+ */
13
+ import * as ServiceMap from "effect/Context";
14
+ import * as Effect from "effect/Effect";
15
+ import * as FileSystem from "effect/FileSystem";
16
+ import * as Option from "effect/Option";
17
+ import * as Path from "effect/Path";
18
+ import { ensureSkillAgentArtifact, replaceCanonicalDirectory, } from "@agentxm/extension-materialization";
19
+ import { AXM_SKILL_CLI_VERSION_METADATA_KEY, AXM_SKILL_CLI_VERSION_RANGE_METADATA_KEY, AXM_SKILL_FQN, evaluateAxmSkillCompatibility, } from "@agentxm/extension-resolution";
20
+ import { operationPresentation, } from "@agentxm/workspace-operations";
21
+ import { CodingAgentRepository } from "@agentxm/workspace-projection";
22
+ import { WorkspaceMutations, sanitizeName } from "@agentxm/workspace-state";
23
+ import { runWorkspaceTransaction } from "@agentxm/workspace-transactions";
24
+ import { ExtensionLifecycleFailed } from "../../errors.js";
25
+ import { lifecycleStepFailure } from "../../step-failure.js";
26
+ import { installRefused } from "../../install/vocabulary.js";
27
+ export class BundledAxmSkillAsset extends ServiceMap.Service()("@agentxm/extension-lifecycle/skills/BundledAxmSkillAsset") {
28
+ }
29
+ const BUNDLED_AXM_SKILL_NAME = sanitizeName("axm");
30
+ export const BUNDLED_AXM_SKILL_AUTHORED_BLOCKER = "The official AXM skill is workspace-authored; bundled recovery will not overwrite its in-flight source.";
31
+ /** Where the bundled skill's canonical package sits. */
32
+ export const bundledAxmSkillCanonicalPath = (ws, path) => path.join(ws.layout.acquiredRoot, "agentxm", "@agentxm", "skills", "axm");
33
+ /** Whether bundled recovery may write, or must preserve an authored copy. */
34
+ export const inspectBundledAxmSkillReadiness = Effect.gen(function* () {
35
+ const ws = yield* WorkspaceMutations;
36
+ const path = yield* Path.Path;
37
+ const configured = yield* ws.getConfiguredSkillEntries();
38
+ const existing = configured[BUNDLED_AXM_SKILL_NAME];
39
+ const canonicalPath = bundledAxmSkillCanonicalPath(ws, path);
40
+ return existing?.source === "workspace" && existing.origin !== "bundled"
41
+ ? {
42
+ readiness: "error",
43
+ canonicalPath,
44
+ errorMessage: BUNDLED_AXM_SKILL_AUTHORED_BLOCKER,
45
+ }
46
+ : { readiness: "ready", canonicalPath };
47
+ });
48
+ const writeFailed = (filePath) => (cause) => installRefused({
49
+ category: "internal",
50
+ detail: `Failed to write bundled AXM skill file: ${filePath}`,
51
+ cause,
52
+ });
53
+ const materializeBundledAxmSkill = Effect.gen(function* () {
54
+ const ws = yield* WorkspaceMutations;
55
+ const fs = yield* FileSystem.FileSystem;
56
+ const path = yield* Path.Path;
57
+ const agentRepo = yield* CodingAgentRepository;
58
+ const asset = yield* BundledAxmSkillAsset;
59
+ const canonicalPath = bundledAxmSkillCanonicalPath(ws, path);
60
+ const skillSrcPath = path.join(canonicalPath, "src");
61
+ yield* replaceCanonicalDirectory({
62
+ baseDir: ws.baseDir,
63
+ canonicalPath,
64
+ populate: (stagingPath) => {
65
+ const stagingSrcPath = path.join(stagingPath, "src");
66
+ const skillJsonPath = path.join(stagingPath, "skill.json");
67
+ return Effect.gen(function* () {
68
+ yield* fs
69
+ .makeDirectory(stagingSrcPath, { recursive: true })
70
+ .pipe(Effect.mapError(writeFailed(stagingSrcPath)));
71
+ yield* fs
72
+ .writeFileString(skillJsonPath, asset.manifestJson)
73
+ .pipe(Effect.mapError(writeFailed(skillJsonPath)));
74
+ yield* Effect.forEach(asset.sourceFiles, (sourceFile) => {
75
+ const destination = path.join(stagingSrcPath, sourceFile.path);
76
+ return fs
77
+ .makeDirectory(path.dirname(destination), { recursive: true })
78
+ .pipe(Effect.andThen(fs.writeFile(destination, Buffer.from(sourceFile.base64, "base64"))), Effect.mapError(writeFailed(destination)));
79
+ }, { concurrency: "unbounded", discard: true });
80
+ });
81
+ },
82
+ });
83
+ const configuredAgents = yield* agentRepo.getConfiguredAgents();
84
+ const resolvedAgents = yield* Effect.forEach(configuredAgents, (agent) => agent
85
+ .resolveEffectiveSkillsDir({ workspaceRoot: ws.baseDir })
86
+ .pipe(Effect.map((outcome) => ({ agentId: agent.id, outcome }))), { concurrency: "unbounded" });
87
+ const misconfigured = resolvedAgents.filter(({ outcome }) => outcome._tag === "misconfigured");
88
+ if (misconfigured.length > 0) {
89
+ return yield* installRefused({
90
+ category: "validation",
91
+ detail: "One or more configured agents have invalid skills directory settings",
92
+ });
93
+ }
94
+ const distinctTargets = [
95
+ ...new Set(resolvedAgents.flatMap(({ outcome }) => outcome._tag === "supported" ? [path.normalize(outcome.dir)] : [])),
96
+ ];
97
+ yield* Effect.forEach(distinctTargets, (targetDir) => ensureSkillAgentArtifact({
98
+ canonicalSkillSrcPath: skillSrcPath,
99
+ targetDir,
100
+ sanitizedName: BUNDLED_AXM_SKILL_NAME,
101
+ baseDir: ws.baseDir,
102
+ }), { concurrency: "unbounded" });
103
+ yield* ws.setSkillEntry(BUNDLED_AXM_SKILL_NAME, {
104
+ source: "workspace",
105
+ enabled: true,
106
+ origin: "bundled",
107
+ });
108
+ yield* ws.removeSkillLock(BUNDLED_AXM_SKILL_NAME);
109
+ });
110
+ /** Install the embedded official AXM skill as one rollback-safe transition. */
111
+ export const installBundledAxmSkill = Effect.gen(function* () {
112
+ const ws = yield* WorkspaceMutations;
113
+ const path = yield* Path.Path;
114
+ const agentRepo = yield* CodingAgentRepository;
115
+ const asset = yield* BundledAxmSkillAsset;
116
+ const readiness = yield* inspectBundledAxmSkillReadiness.pipe(Effect.mapError((cause) => installRefused({
117
+ category: "internal",
118
+ detail: "Bundled AXM skill readiness could not be inspected",
119
+ cause,
120
+ })));
121
+ if (readiness.readiness === "error") {
122
+ return yield* installRefused({
123
+ category: "conflict",
124
+ detail: BUNDLED_AXM_SKILL_AUTHORED_BLOCKER,
125
+ recover: "Preserve the authored skill and inspect executable compatibility guidance",
126
+ cmd: "axm help upgrade",
127
+ });
128
+ }
129
+ const configuredAgents = yield* agentRepo.getConfiguredAgents().pipe(Effect.mapError((cause) => installRefused({
130
+ category: "internal",
131
+ detail: "Configured agents could not be read",
132
+ cause,
133
+ })));
134
+ const targetDirectories = yield* Effect.forEach(configuredAgents, (agent) => agent
135
+ .resolveEffectiveSkillsDir({ workspaceRoot: ws.baseDir })
136
+ .pipe(Effect.map((outcome) => outcome._tag === "supported"
137
+ ? [path.join(path.normalize(outcome.dir), BUNDLED_AXM_SKILL_NAME)]
138
+ : [])), { concurrency: "unbounded" }).pipe(Effect.map((paths) => paths.flat()), Effect.mapError((cause) => installRefused({
139
+ category: "internal",
140
+ detail: "Configured skill placement could not be resolved",
141
+ cause,
142
+ })));
143
+ yield* runWorkspaceTransaction({
144
+ targets: [readiness.canonicalPath, ...targetDirectories],
145
+ transition: materializeBundledAxmSkill,
146
+ validate: () => Effect.gen(function* () {
147
+ const configured = yield* ws.getConfiguredSkillEntries();
148
+ const installedEntry = configured[BUNDLED_AXM_SKILL_NAME];
149
+ if (installedEntry?.source !== "workspace" || installedEntry.origin !== "bundled") {
150
+ return yield* installRefused({
151
+ category: "internal",
152
+ detail: "Bundled AXM skill did not retain its bundled source authority",
153
+ });
154
+ }
155
+ const locked = yield* ws.getLockedSkill(BUNDLED_AXM_SKILL_NAME);
156
+ if (Option.isSome(locked)) {
157
+ return yield* installRefused({
158
+ category: "internal",
159
+ detail: "Bundled AXM skill retained a superseded accepted external resolution",
160
+ });
161
+ }
162
+ // The installed skill must be usable by the executable that installed
163
+ // it, so the same compatibility policy runs inside the transaction.
164
+ const compatibility = evaluateAxmSkillCompatibility({
165
+ cliVersion: asset.runningCliVersion,
166
+ skill: {
167
+ manifestVersion: asset.version,
168
+ source: `bundled:@agentxm/skills/axm@${asset.version}`,
169
+ metadata: {
170
+ [AXM_SKILL_CLI_VERSION_METADATA_KEY]: asset.cliVersion,
171
+ [AXM_SKILL_CLI_VERSION_RANGE_METADATA_KEY]: asset.cliVersionRange,
172
+ },
173
+ },
174
+ });
175
+ if (compatibility.status === "incompatible") {
176
+ return yield* installRefused({
177
+ category: "internal",
178
+ detail: compatibility.detail ??
179
+ "Bundled AXM skill remained incompatible after workspace installation",
180
+ ...(compatibility.recovery.nextAction === null
181
+ ? {}
182
+ : { cmd: compatibility.recovery.nextAction }),
183
+ });
184
+ }
185
+ }),
186
+ }).pipe(Effect.mapError((cause) => cause instanceof ExtensionLifecycleFailed
187
+ ? cause
188
+ : installRefused({
189
+ category: "internal",
190
+ detail: "Bundled AXM skill installation did not complete",
191
+ cause,
192
+ })), Effect.asVoid);
193
+ });
194
+ /**
195
+ * The single closure a bundled install becomes: one step that replaces the
196
+ * canonical package and declares it, refused up front when an authored copy
197
+ * of the official skill is in flight.
198
+ */
199
+ export const planBundledAxmSkillInstall = Effect.gen(function* () {
200
+ const ws = yield* WorkspaceMutations;
201
+ const readiness = yield* inspectBundledAxmSkillReadiness.pipe(Effect.mapError((cause) => installRefused({
202
+ category: "internal",
203
+ detail: "Bundled AXM skill readiness could not be inspected",
204
+ cause,
205
+ })));
206
+ const artifact = {
207
+ path: readiness.canonicalPath,
208
+ scope: ws.scope,
209
+ change: "updated",
210
+ };
211
+ const step = readiness.readiness === "error"
212
+ ? {
213
+ key: "bundled-axm-skill-authored",
214
+ readiness: "error",
215
+ errorMessage: readiness.errorMessage,
216
+ label: AXM_SKILL_FQN,
217
+ artifact,
218
+ }
219
+ : {
220
+ key: "bundled-axm-skill",
221
+ readiness: "ready",
222
+ label: AXM_SKILL_FQN,
223
+ artifact,
224
+ run: installBundledAxmSkill.pipe(Effect.mapError(lifecycleStepFailure), Effect.as({
225
+ result: "success",
226
+ message: "Installed the bundled AXM skill",
227
+ artifact,
228
+ })),
229
+ };
230
+ return {
231
+ _tag: "Plan",
232
+ name: "Install bundled AXM skill",
233
+ description: Option.some("Install the embedded compatible official AXM skill"),
234
+ presentation: operationPresentation({ imperative: "install", past: "Installed", gerund: "Installing" }, "skill"),
235
+ failureSuggestions: [
236
+ {
237
+ description: "Preserve the authored skill and inspect executable compatibility guidance",
238
+ cmd: "axm help upgrade",
239
+ },
240
+ ],
241
+ jobs: [{ concurrency: 1, steps: [step] }],
242
+ };
243
+ });
244
+ //# sourceMappingURL=bundled.js.map