@agentxm/extension-lifecycle 0.28.4-bootstrap.0

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 (84) hide show
  1. package/LICENSE +110 -0
  2. package/dist/src/configured-entry-resolution.d.ts +110 -0
  3. package/dist/src/configured-entry-resolution.js +723 -0
  4. package/dist/src/errors.d.ts +39 -0
  5. package/dist/src/errors.js +45 -0
  6. package/dist/src/failure-adapter.d.ts +35 -0
  7. package/dist/src/failure-adapter.js +23 -0
  8. package/dist/src/hooks/configured-agent-outcomes-provider.d.ts +18 -0
  9. package/dist/src/hooks/configured-agent-outcomes-provider.js +39 -0
  10. package/dist/src/hooks/manager.d.ts +15 -0
  11. package/dist/src/hooks/manager.js +751 -0
  12. package/dist/src/index.d.ts +38 -0
  13. package/dist/src/index.js +41 -0
  14. package/dist/src/internal/fs-helpers.d.ts +12 -0
  15. package/dist/src/internal/fs-helpers.js +13 -0
  16. package/dist/src/internal/integrity.d.ts +13 -0
  17. package/dist/src/internal/integrity.js +17 -0
  18. package/dist/src/knowledge/manager.d.ts +11 -0
  19. package/dist/src/knowledge/manager.js +655 -0
  20. package/dist/src/live.d.ts +18 -0
  21. package/dist/src/live.js +18 -0
  22. package/dist/src/mcps/manager.d.ts +16 -0
  23. package/dist/src/mcps/manager.js +213 -0
  24. package/dist/src/mcps/operations/artifact.d.ts +24 -0
  25. package/dist/src/mcps/operations/artifact.js +74 -0
  26. package/dist/src/mcps/operations/disable.d.ts +18 -0
  27. package/dist/src/mcps/operations/disable.js +113 -0
  28. package/dist/src/mcps/operations/enable.d.ts +18 -0
  29. package/dist/src/mcps/operations/enable.js +218 -0
  30. package/dist/src/mcps/operations/install.d.ts +59 -0
  31. package/dist/src/mcps/operations/install.js +566 -0
  32. package/dist/src/mcps/operations/sync-outcome.d.ts +10 -0
  33. package/dist/src/mcps/operations/sync-outcome.js +27 -0
  34. package/dist/src/mcps/operations/uninstall.d.ts +41 -0
  35. package/dist/src/mcps/operations/uninstall.js +189 -0
  36. package/dist/src/packs/dependency-resolution.d.ts +65 -0
  37. package/dist/src/packs/dependency-resolution.js +414 -0
  38. package/dist/src/packs/expansion.d.ts +59 -0
  39. package/dist/src/packs/expansion.js +44 -0
  40. package/dist/src/packs/manager.d.ts +16 -0
  41. package/dist/src/packs/manager.js +181 -0
  42. package/dist/src/packs/operations/install.d.ts +67 -0
  43. package/dist/src/packs/operations/install.js +156 -0
  44. package/dist/src/packs/resolved-dependency.d.ts +29 -0
  45. package/dist/src/packs/resolved-dependency.js +28 -0
  46. package/dist/src/registry-materialization.d.ts +52 -0
  47. package/dist/src/registry-materialization.js +67 -0
  48. package/dist/src/resolution-progress.d.ts +18 -0
  49. package/dist/src/resolution-progress.js +11 -0
  50. package/dist/src/resolution-timeout.d.ts +5 -0
  51. package/dist/src/resolution-timeout.js +11 -0
  52. package/dist/src/rules/manager.d.ts +20 -0
  53. package/dist/src/rules/manager.js +475 -0
  54. package/dist/src/skills/manager.d.ts +18 -0
  55. package/dist/src/skills/manager.js +346 -0
  56. package/dist/src/skills/materialization.d.ts +54 -0
  57. package/dist/src/skills/materialization.js +158 -0
  58. package/dist/src/skills/operations/disable.d.ts +31 -0
  59. package/dist/src/skills/operations/disable.js +110 -0
  60. package/dist/src/skills/operations/enable.d.ts +31 -0
  61. package/dist/src/skills/operations/enable.js +113 -0
  62. package/dist/src/skills/operations/install-result.d.ts +33 -0
  63. package/dist/src/skills/operations/install-result.js +10 -0
  64. package/dist/src/skills/operations/install.d.ts +67 -0
  65. package/dist/src/skills/operations/install.js +590 -0
  66. package/dist/src/skills/operations/source-hash.d.ts +2 -0
  67. package/dist/src/skills/operations/source-hash.js +6 -0
  68. package/dist/src/skills/operations/uninstall.d.ts +40 -0
  69. package/dist/src/skills/operations/uninstall.js +157 -0
  70. package/dist/src/skills/utils.d.ts +11 -0
  71. package/dist/src/skills/utils.js +29 -0
  72. package/dist/src/subagents/manager.d.ts +18 -0
  73. package/dist/src/subagents/manager.js +677 -0
  74. package/dist/src/subagents/operations/artifact.d.ts +18 -0
  75. package/dist/src/subagents/operations/artifact.js +43 -0
  76. package/dist/src/subagents/operations/disable.d.ts +32 -0
  77. package/dist/src/subagents/operations/disable.js +116 -0
  78. package/dist/src/subagents/operations/enable.d.ts +30 -0
  79. package/dist/src/subagents/operations/enable.js +160 -0
  80. package/dist/src/workflows/install-command/workflow.d.ts +57 -0
  81. package/dist/src/workflows/install-command/workflow.js +41 -0
  82. package/dist/src/workflows/uninstall-command/workflow.d.ts +42 -0
  83. package/dist/src/workflows/uninstall-command/workflow.js +29 -0
  84. package/package.json +62 -0
@@ -0,0 +1,157 @@
1
+ /**
2
+ * Uninstall skill executor — orchestrates per-skill removal pipeline.
3
+ *
4
+ * Pipeline: resolve desired/observed state -> remove agent artifacts
5
+ * concurrently -> remove canonical source -> clear settings and accepted resolution.
6
+ *
7
+ * @experimental This API is unstable and may change without notice.
8
+ */
9
+ import * as FileSystem from "effect/FileSystem";
10
+ import * as Path from "effect/Path";
11
+ import * as Effect from "effect/Effect";
12
+ import * as Option from "effect/Option";
13
+ import * as Layer from "effect/Layer";
14
+ import { DefaultCodingAgentRepository } from "@agentxm/extension-workspace";
15
+ import { AGENTS } from "@agentxm/extension-model/unstable/agents/registry";
16
+ import { ExtensionLifecycleFailed } from "../../errors.js";
17
+ import { LifecycleFailureAdapter, withAdaptedStepFailures } from "../../failure-adapter.js";
18
+ import { WorkspaceMutations } from "@agentxm/workspace-state";
19
+ import { removeIfExists } from "@agentxm/workspace-state";
20
+ import { sanitizeName } from "@agentxm/workspace-state";
21
+ import { acceptedCanonicalObservation, acceptedLockedCanonicalPath, removableAcceptedCanonicalPath, } from "@agentxm/workspace-state";
22
+ // Operation types
23
+ // -----------------------------------------------------------------------------
24
+ const isKnownAgentId = (id) => Object.hasOwn(AGENTS, id);
25
+ // -----------------------------------------------------------------------------
26
+ // Public API
27
+ // -----------------------------------------------------------------------------
28
+ /**
29
+ * Uninstall-skill operation handler.
30
+ *
31
+ * Reads workspace paths from the WorkspaceMutations service, then orchestrates:
32
+ * 1. Sanitize skill name for filesystem
33
+ * 2. Resolve configured and observed state
34
+ * 3. Remove agent symlinks concurrently (skip missing)
35
+ * 4. Remove from all known canonical locations (full uninstall only)
36
+ * 5. Remove or update settings and accepted resolution
37
+ */
38
+ export const uninstallSkill = (op) => Effect.gen(function* () {
39
+ const fs = yield* FileSystem.FileSystem;
40
+ const path = yield* Path.Path;
41
+ const ws = yield* WorkspaceMutations;
42
+ const base = ws.baseDir;
43
+ const fsPathLayer = Layer.mergeAll(Layer.succeed(FileSystem.FileSystem, fs), Layer.succeed(Path.Path, path));
44
+ const sanitizedName = sanitizeName(op.args.skillName);
45
+ const desired = yield* ws.getDesiredStateGraph();
46
+ if (!desired.complete) {
47
+ return yield* new ExtensionLifecycleFailed({
48
+ category: "conflict",
49
+ detail: "Cannot uninstall the skill while the desired extension graph is incomplete.",
50
+ recover: "Repair or reinstall the configured packs, then retry.",
51
+ });
52
+ }
53
+ const desiredNode = desired.nodes.find((node) => node.type === "skill" && node.name === op.args.skillName);
54
+ const acceptedCanonical = yield* acceptedCanonicalObservation({
55
+ workspace: ws,
56
+ type: "skill",
57
+ name: op.args.skillName,
58
+ });
59
+ const lockedCanonical = yield* acceptedLockedCanonicalPath({
60
+ workspace: ws,
61
+ type: "skill",
62
+ name: op.args.skillName,
63
+ });
64
+ const removableCanonical = Option.orElse(removableAcceptedCanonicalPath(acceptedCanonical), () => lockedCanonical);
65
+ const installedOnDisk = yield* Option.match(removableCanonical, {
66
+ onNone: () => Effect.succeed(false),
67
+ onSome: (canonicalPath) => fs.exists(canonicalPath).pipe(Effect.catch(() => Effect.succeed(false))),
68
+ });
69
+ if (desiredNode === undefined && !installedOnDisk) {
70
+ return { result: "success", message: "not installed" };
71
+ }
72
+ // Determine which configured agent artifacts to remove. Per-agent state is
73
+ // derived from settings and disk rather than persisted in the lockfile.
74
+ const agentFilter = op.args.agents;
75
+ const isPartialUninstall = agentFilter.length > 0;
76
+ const materializationAgents = yield* DefaultCodingAgentRepository.getMaterializationAgents().pipe(Effect.provideService(WorkspaceMutations, ws));
77
+ const agentsToRemove = isPartialUninstall
78
+ ? agentFilter
79
+ : materializationAgents.map((agent) => agent.id);
80
+ const remainingAgents = materializationAgents
81
+ .map((agent) => agent.id)
82
+ .filter((agent) => !agentsToRemove.includes(agent));
83
+ const agentsById = new Map(materializationAgents.map((agent) => [agent.id, agent]));
84
+ const resolveAgentArtifactPath = (agentId) => {
85
+ const configuredAgent = agentsById.get(agentId);
86
+ const agentEffect = configuredAgent !== undefined
87
+ ? Effect.succeed(Option.some(configuredAgent))
88
+ : isKnownAgentId(agentId)
89
+ ? DefaultCodingAgentRepository.get(agentId).pipe(Effect.map(Option.some))
90
+ : Effect.succeed(Option.none());
91
+ return agentEffect.pipe(Effect.flatMap((agentOption) => {
92
+ if (Option.isNone(agentOption))
93
+ return Effect.succeed(Option.none());
94
+ return agentOption.value
95
+ .resolveEffectiveSkillsDir({ workspaceRoot: base })
96
+ .pipe(Effect.map((outcome) => outcome._tag === "supported"
97
+ ? Option.some(path.normalize(path.join(outcome.dir, sanitizedName)))
98
+ : Option.none()));
99
+ }), Effect.provide(fsPathLayer));
100
+ };
101
+ const retainedArtifactOptions = yield* Effect.forEach(remainingAgents, resolveAgentArtifactPath, { concurrency: "unbounded" });
102
+ const retainedArtifactPaths = new Set(retainedArtifactOptions.flatMap((artifactPath) => Option.isSome(artifactPath) ? [artifactPath.value] : []));
103
+ // Remove agent symlinks/copies concurrently using adapter-derived paths.
104
+ yield* Effect.forEach(agentsToRemove, (agentId) => {
105
+ const configuredAgent = agentsById.get(agentId);
106
+ const agentEffect = configuredAgent !== undefined
107
+ ? Effect.succeed(Option.some(configuredAgent))
108
+ : isKnownAgentId(agentId)
109
+ ? DefaultCodingAgentRepository.get(agentId).pipe(Effect.map(Option.some))
110
+ : Effect.succeed(Option.none());
111
+ return agentEffect.pipe(Effect.flatMap((agentOption) => {
112
+ if (Option.isNone(agentOption)) {
113
+ return Effect.succeed({
114
+ _tag: "unsupported",
115
+ reason: `Unknown coding agent: ${agentId}`,
116
+ });
117
+ }
118
+ return agentOption.value.resolveEffectiveSkillsDir({ workspaceRoot: base });
119
+ }), Effect.provide(fsPathLayer), Effect.flatMap((outcome) => outcome._tag === "supported"
120
+ ? (() => {
121
+ const artifactPath = path.normalize(path.join(outcome.dir, sanitizedName));
122
+ return retainedArtifactPaths.has(artifactPath)
123
+ ? Effect.void
124
+ : fs
125
+ .remove(artifactPath, { recursive: true })
126
+ .pipe(Effect.catch(() => Effect.void));
127
+ })()
128
+ : Effect.void));
129
+ }, { concurrency: "unbounded" });
130
+ // Handle partial vs full uninstall
131
+ if (isPartialUninstall) {
132
+ const agentList = [...agentsToRemove].join(", ");
133
+ return {
134
+ result: "success",
135
+ message: `Uninstalled ${op.args.skillName} from ${agentList}`,
136
+ };
137
+ }
138
+ const packOwned = desiredNode?.origins.some((origin) => origin.type === "pack") ?? false;
139
+ if (packOwned) {
140
+ // Pack still references this skill — remove from settings only, keep lockfile + disk
141
+ yield* ws.removeSkillFromSettings(op.args.skillName).pipe(Effect.catch(() => Effect.void));
142
+ return {
143
+ result: "success",
144
+ message: `Uninstalled ${op.args.skillName}`,
145
+ };
146
+ }
147
+ // Full uninstall removes only the canonical package proven by accepted authority.
148
+ if (Option.isSome(removableCanonical))
149
+ yield* removeIfExists(fs, removableCanonical.value);
150
+ // Remove from both settings and lockfile (swallow errors on full uninstall)
151
+ yield* ws.removeSkill(op.args.skillName).pipe(Effect.catch(() => Effect.void));
152
+ return {
153
+ result: "success",
154
+ message: `Uninstalled ${op.args.skillName}`,
155
+ };
156
+ }).pipe(withAdaptedStepFailures);
157
+ //# sourceMappingURL=uninstall.js.map
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Post-discovery skill utilities.
3
+ *
4
+ * Display name resolution, filtering by name, and name sanitization
5
+ * for discovered skills. Consumed by the install handler and UI layer.
6
+ *
7
+ * @experimental This API is unstable and may change without notice.
8
+ */
9
+ import type { SkillExtensionRef } from "@agentxm/extension-model/unstable/extensions/refs/skill";
10
+ export declare const getSkillDisplayName: (ref: SkillExtensionRef) => string;
11
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Post-discovery skill utilities.
3
+ *
4
+ * Display name resolution, filtering by name, and name sanitization
5
+ * for discovered skills. Consumed by the install handler and UI layer.
6
+ *
7
+ * @experimental This API is unstable and may change without notice.
8
+ */
9
+ import { stripFileProtocol } from "../internal/fs-helpers.js";
10
+ // -----------------------------------------------------------------------------
11
+ // Display Name
12
+ // -----------------------------------------------------------------------------
13
+ /**
14
+ * Returns the display name for a skill.
15
+ *
16
+ * Uses `skill.name` when present, falls back to `basename(location)`.
17
+ */
18
+ /**
19
+ * Extract the last path segment from a location string.
20
+ */
21
+ const basenamePure = (location) => {
22
+ const stripped = stripFileProtocol(location);
23
+ return stripped.split("/").pop() ?? stripped;
24
+ };
25
+ export const getSkillDisplayName = (ref) => ref.skill.name ||
26
+ (ref.refType === "git-hosted" || ref.refType === "local"
27
+ ? basenamePure(ref.location)
28
+ : ref.skill.name);
29
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Subagent extension manager service.
3
+ *
4
+ * Implements ExtensionManager<SubagentExtensionRef> with canonical source
5
+ * materialization, per-agent rendering via CodingAgent.addSubagent(),
6
+ * and source-hash-based skip logic.
7
+ *
8
+ * @experimental This API is unstable and may change without notice.
9
+ */
10
+ import * as FileSystem from "effect/FileSystem";
11
+ import * as HttpClient from "effect/unstable/http/HttpClient";
12
+ import * as Path from "effect/Path";
13
+ import * as Layer from "effect/Layer";
14
+ import { WorkspaceMutations } from "@agentxm/workspace-state";
15
+ import { CodingAgentRepository } from "@agentxm/extension-workspace";
16
+ import { SubagentManager } from "@agentxm/extension-workspace";
17
+ export declare const SubagentManagerLive: Layer.Layer<SubagentManager, never, WorkspaceMutations | FileSystem.FileSystem | HttpClient.HttpClient | Path.Path | CodingAgentRepository>;
18
+ //# sourceMappingURL=manager.d.ts.map