@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,18 @@
1
+ import type { JobStepArtifact, JobStepArtifactTarget } from "@agentxm/workspace-operations";
2
+ export declare const SUBAGENT_CONFIG_SURFACE = ".axm (config/lockfile)";
3
+ export declare const subagentConfigTarget: (change: JobStepArtifactTarget["change"]) => JobStepArtifactTarget;
4
+ export declare const renderedSubagentTargets: (renderedFiles: Readonly<Record<string, ReadonlyArray<{
5
+ readonly path: string;
6
+ }>>>, change: JobStepArtifactTarget["change"]) => ReadonlyArray<JobStepArtifactTarget>;
7
+ export declare const subagentLifecycleArtifact: (args: {
8
+ readonly name: string;
9
+ readonly scope: JobStepArtifact["scope"];
10
+ readonly agents?: ReadonlyArray<string>;
11
+ readonly version?: string;
12
+ readonly change: JobStepArtifact["change"];
13
+ readonly renderedFiles?: Readonly<Record<string, ReadonlyArray<{
14
+ readonly path: string;
15
+ }>>>;
16
+ readonly renderedChange?: JobStepArtifactTarget["change"];
17
+ }) => JobStepArtifact;
18
+ //# sourceMappingURL=artifact.d.ts.map
@@ -0,0 +1,43 @@
1
+ export const SUBAGENT_CONFIG_SURFACE = ".axm (config/lockfile)";
2
+ export const subagentConfigTarget = (change) => ({
3
+ path: SUBAGENT_CONFIG_SURFACE,
4
+ change,
5
+ });
6
+ export const renderedSubagentTargets = (renderedFiles, change) => {
7
+ const byPath = new Map();
8
+ for (const [agentId, files] of Object.entries(renderedFiles)) {
9
+ for (const file of files) {
10
+ const existing = byPath.get(file.path);
11
+ if (existing === undefined) {
12
+ byPath.set(file.path, [agentId]);
13
+ continue;
14
+ }
15
+ if (!existing.includes(agentId)) {
16
+ existing.push(agentId);
17
+ }
18
+ }
19
+ }
20
+ return [...byPath.entries()]
21
+ .sort(([left], [right]) => left.localeCompare(right))
22
+ .map(([path, agentIds]) => ({
23
+ path,
24
+ change,
25
+ ...(agentIds.length > 0 ? { agentIds } : {}),
26
+ }));
27
+ };
28
+ export const subagentLifecycleArtifact = (args) => {
29
+ const renderedTargets = args.renderedFiles === undefined
30
+ ? []
31
+ : renderedSubagentTargets(args.renderedFiles, args.renderedChange ?? args.change);
32
+ const targets = [subagentConfigTarget("updated"), ...renderedTargets];
33
+ return {
34
+ path: renderedTargets[0]?.path ?? SUBAGENT_CONFIG_SURFACE,
35
+ scope: args.scope,
36
+ ...(args.agents === undefined || args.agents.length === 0 ? {} : { agents: args.agents }),
37
+ ...(args.version === undefined ? {} : { version: args.version }),
38
+ change: args.change,
39
+ fileCount: targets.length,
40
+ targets,
41
+ };
42
+ };
43
+ //# sourceMappingURL=artifact.js.map
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Disable subagent executor — removes rendered files but preserves canonical source.
3
+ *
4
+ * Materialized artifacts are observed directly. Accepted-resolution rows identify
5
+ * source content but do not prove that canonical or projected files exist.
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 { CodingAgentRepository } from "@agentxm/extension-workspace";
12
+ import { LifecycleFailureAdapter } from "../../failure-adapter.js";
13
+ import type { OperationHandler } from "@agentxm/workspace-operations";
14
+ import type { Operation } from "@agentxm/workspace-operations";
15
+ import { WorkspaceMutations } from "@agentxm/workspace-state";
16
+ /**
17
+ * Disable a subagent (remove rendered files but keep settings/lockfile entry).
18
+ *
19
+ * @experimental This API is unstable and may change without notice.
20
+ */
21
+ export type DisableSubagentOperation = Operation<"disable-subagent", {
22
+ readonly subagentName: string;
23
+ }>;
24
+ /**
25
+ * Disable-subagent operation handler.
26
+ *
27
+ * Determines lifecycle from the workspace read model, removes observable
28
+ * rendered files, and promotes implicit pack members to a direct disabled
29
+ * preference. Canonical source files are preserved for later re-enablement.
30
+ */
31
+ export declare const disableSubagent: OperationHandler<DisableSubagentOperation, FileSystem.FileSystem | Path.Path | WorkspaceMutations | CodingAgentRepository | LifecycleFailureAdapter>;
32
+ //# sourceMappingURL=disable.d.ts.map
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Disable subagent executor — removes rendered files but preserves canonical source.
3
+ *
4
+ * Materialized artifacts are observed directly. Accepted-resolution rows identify
5
+ * source content but do not prove that canonical or projected files exist.
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 { CodingAgentRepository, findManagedSubagentFiles } from "@agentxm/extension-workspace";
14
+ import { ExtensionLifecycleFailed } from "../../errors.js";
15
+ import { LifecycleFailureAdapter, withAdaptedStepFailures } from "../../failure-adapter.js";
16
+ import { WorkspaceMutations } from "@agentxm/workspace-state";
17
+ import { subagentLifecycleArtifact } from "./artifact.js";
18
+ import * as Layer from "effect/Layer";
19
+ import * as Schema from "effect/Schema";
20
+ import { RenderedFilePathSchema } from "@agentxm/workspace-state";
21
+ import { sanitizeName } from "@agentxm/workspace-state";
22
+ import { installedRowsByName } from "@agentxm/workspace-state";
23
+ const decodeRenderedFilePath = Schema.decodeUnknownSync(RenderedFilePathSchema);
24
+ // -----------------------------------------------------------------------------
25
+ // Public API
26
+ // -----------------------------------------------------------------------------
27
+ /**
28
+ * Disable-subagent operation handler.
29
+ *
30
+ * Determines lifecycle from the workspace read model, removes observable
31
+ * rendered files, and promotes implicit pack members to a direct disabled
32
+ * preference. Canonical source files are preserved for later re-enablement.
33
+ */
34
+ export const disableSubagent = (op) => Effect.gen(function* () {
35
+ const ws = yield* WorkspaceMutations;
36
+ const agentRepo = yield* CodingAgentRepository;
37
+ const fs = yield* FileSystem.FileSystem;
38
+ const path = yield* Path.Path;
39
+ const fsPathLayer = Layer.mergeAll(Layer.succeed(FileSystem.FileSystem, fs), Layer.succeed(Path.Path, path));
40
+ // Read lifecycle to determine promotion needs
41
+ const installedSubagents = yield* ws.records
42
+ .rows("subagent")
43
+ .pipe(Effect.map(installedRowsByName));
44
+ const installed = installedSubagents[op.args.subagentName];
45
+ const isImplicit = installed !== undefined && installed.lifecycle === "implicit";
46
+ const graph = yield* ws.getDesiredStateGraph();
47
+ if (!graph.complete) {
48
+ return yield* new ExtensionLifecycleFailed({
49
+ category: "conflict",
50
+ detail: "Cannot disable the subagent while pack-derived desired state is unresolved.",
51
+ });
52
+ }
53
+ const desiredBeforeDisable = graph.nodes.find((node) => node.type === "subagent" && node.name === op.args.subagentName);
54
+ const renderedFiles = {};
55
+ const configuredAgents = yield* agentRepo.getConfiguredAgents();
56
+ yield* ws.runTransaction({
57
+ transition: Effect.gen(function* () {
58
+ if (isImplicit) {
59
+ const source = desiredBeforeDisable?.source ?? Option.getOrElse(installed.source, () => undefined);
60
+ if (source === undefined) {
61
+ return yield* new ExtensionLifecycleFailed({
62
+ category: "internal",
63
+ detail: `Cannot determine source for implicit subagent "${op.args.subagentName}"`,
64
+ suggestions: [{ description: "Provide a source when disabling this subagent" }],
65
+ });
66
+ }
67
+ yield* ws.setSubagentEntry(op.args.subagentName, {
68
+ source,
69
+ enabled: false,
70
+ });
71
+ }
72
+ else {
73
+ yield* ws.updateSubagentEntry(op.args.subagentName, (entry) => ({
74
+ ...entry,
75
+ enabled: false,
76
+ }));
77
+ }
78
+ yield* Effect.forEach(configuredAgents, (agent) => agent.resolveEffectiveSubagentsDir({ workspaceRoot: ws.baseDir, scope: ws.scope }).pipe(Effect.provide(fsPathLayer), Effect.flatMap((resolved) => resolved._tag === "supported"
79
+ ? findManagedSubagentFiles(resolved.dir, sanitizeName(op.args.subagentName)).pipe(Effect.provide(fsPathLayer), Effect.flatMap((managedPaths) => {
80
+ renderedFiles[agent.id] = managedPaths.map((filePath) => ({
81
+ path: path.relative(ws.baseDir, filePath),
82
+ }));
83
+ return agent
84
+ .removeSubagent({
85
+ workspaceRoot: ws.baseDir,
86
+ scope: ws.scope,
87
+ subagentName: op.args.subagentName,
88
+ renderedFilePaths: managedPaths.map((filePath) => decodeRenderedFilePath(path.relative(ws.baseDir, filePath))),
89
+ })
90
+ .pipe(Effect.flatMap((outcome) => outcome._tag === "conflict"
91
+ ? new ExtensionLifecycleFailed({
92
+ category: "conflict",
93
+ detail: `Subagent removal failed for ${agent.id}: ${outcome.reason}`,
94
+ })
95
+ : Effect.void));
96
+ }))
97
+ : Effect.void)), { concurrency: "unbounded" });
98
+ }).pipe(Effect.provideService(FileSystem.FileSystem, fs), Effect.provideService(Path.Path, path)),
99
+ validate: () => Effect.void,
100
+ });
101
+ return {
102
+ result: "success",
103
+ message: `Disabled ${op.args.subagentName}`,
104
+ artifact: subagentLifecycleArtifact({
105
+ name: op.args.subagentName,
106
+ scope: ws.scope,
107
+ ...(configuredAgents.length === 0
108
+ ? {}
109
+ : { agents: configuredAgents.map((agent) => agent.id) }),
110
+ change: "updated",
111
+ renderedFiles,
112
+ renderedChange: "removed",
113
+ }),
114
+ };
115
+ }).pipe(withAdaptedStepFailures);
116
+ //# sourceMappingURL=disable.js.map
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Enable subagent executor — re-renders agent-native files for a previously disabled subagent.
3
+ *
4
+ * Enabling requires canonical content backed by a usable accepted resolution.
5
+ *
6
+ * @experimental This API is unstable and may change without notice.
7
+ */
8
+ import * as FileSystem from "effect/FileSystem";
9
+ import * as Path from "effect/Path";
10
+ import { CodingAgentRepository } from "@agentxm/extension-workspace";
11
+ import { LifecycleFailureAdapter } from "../../failure-adapter.js";
12
+ import type { OperationHandler } from "@agentxm/workspace-operations";
13
+ import type { Operation } from "@agentxm/workspace-operations";
14
+ import { WorkspaceMutations } from "@agentxm/workspace-state";
15
+ /**
16
+ * Enable a previously disabled subagent (re-render files and update state).
17
+ *
18
+ * @experimental This API is unstable and may change without notice.
19
+ */
20
+ export type EnableSubagentOperation = Operation<"enable-subagent", {
21
+ readonly subagentName: string;
22
+ }>;
23
+ /**
24
+ * Enable-subagent operation handler.
25
+ *
26
+ * Resolves accepted canonical content, renders to configured agents, and then
27
+ * updates the desired settings entry.
28
+ */
29
+ export declare const enableSubagent: OperationHandler<EnableSubagentOperation, FileSystem.FileSystem | Path.Path | WorkspaceMutations | CodingAgentRepository | LifecycleFailureAdapter>;
30
+ //# sourceMappingURL=enable.d.ts.map
@@ -0,0 +1,160 @@
1
+ /**
2
+ * Enable subagent executor — re-renders agent-native files for a previously disabled subagent.
3
+ *
4
+ * Enabling requires canonical content backed by a usable accepted resolution.
5
+ *
6
+ * @experimental This API is unstable and may change without notice.
7
+ */
8
+ import * as FileSystem from "effect/FileSystem";
9
+ import * as Path from "effect/Path";
10
+ import * as Effect from "effect/Effect";
11
+ import * as Option from "effect/Option";
12
+ import * as Schema from "effect/Schema";
13
+ import { CodingAgentRepository, subagentContentFilename, subagentContentPath, warnOnOrphanOverrides, managedSubagentFile, } from "@agentxm/extension-workspace";
14
+ import { ExtensionLifecycleFailed } from "../../errors.js";
15
+ import { LifecycleFailureAdapter, withAdaptedStepFailures } from "../../failure-adapter.js";
16
+ import { WorkspaceMutations } from "@agentxm/workspace-state";
17
+ import { RenderedFilesMapSchema } from "@agentxm/workspace-state";
18
+ import { makeWorkspaceRelativePath } from "@agentxm/extension-model/unstable/path-types";
19
+ import { parseSubagentMd } from "@agentxm/registry-protocol/unstable/content/subagent-content";
20
+ import { subagentLifecycleArtifact } from "./artifact.js";
21
+ import { usableAcceptedCanonical } from "@agentxm/workspace-state";
22
+ /**
23
+ * Strip the meta-only `agentOverrides` key from a frontmatter map so it does
24
+ * not leak into rendered files.
25
+ */
26
+ const stripAgentOverrides = (fm) => {
27
+ if (!("agentOverrides" in fm))
28
+ return fm;
29
+ const { agentOverrides: _agentOverrides, ...rest } = fm;
30
+ return rest;
31
+ };
32
+ // -----------------------------------------------------------------------------
33
+ // Public API
34
+ // -----------------------------------------------------------------------------
35
+ /**
36
+ * Enable-subagent operation handler.
37
+ *
38
+ * Resolves accepted canonical content, renders to configured agents, and then
39
+ * updates the desired settings entry.
40
+ */
41
+ export const enableSubagent = (op) => Effect.gen(function* () {
42
+ const fs = yield* FileSystem.FileSystem;
43
+ const path = yield* Path.Path;
44
+ const ws = yield* WorkspaceMutations;
45
+ const agentRepo = yield* CodingAgentRepository;
46
+ const canonical = yield* usableAcceptedCanonical({
47
+ workspace: ws,
48
+ type: "subagent",
49
+ name: op.args.subagentName,
50
+ });
51
+ if (Option.isNone(canonical) || canonical.value.ref.type !== "subagent") {
52
+ return yield* new ExtensionLifecycleFailed({
53
+ category: "not_found",
54
+ detail: `Accepted subagent content for "${op.args.subagentName}" is not usable`,
55
+ suggestions: [
56
+ {
57
+ description: "Try reinstalling the subagent.",
58
+ cmd: "axm subagents install <source>",
59
+ },
60
+ ],
61
+ });
62
+ }
63
+ const baseDir = ws.baseDir;
64
+ const subagentSrcPath = canonical.value.ref.refType === "registry" || canonical.value.ref.refType === "workspace"
65
+ ? path.join(canonical.value.observation.path, "src")
66
+ : canonical.value.observation.path;
67
+ // Read and parse the subagent content file
68
+ const expectedFilename = subagentContentFilename(op.args.subagentName);
69
+ const contentPath = subagentContentPath(path.join, subagentSrcPath, op.args.subagentName);
70
+ const sourcePath = makeWorkspaceRelativePath(path, baseDir, contentPath);
71
+ if (Option.isNone(sourcePath)) {
72
+ return yield* new ExtensionLifecycleFailed({
73
+ category: "internal",
74
+ detail: `Subagent source path escapes workspace root: ${contentPath}`,
75
+ });
76
+ }
77
+ const managedFile = managedSubagentFile(canonical.value.ref, sourcePath.value);
78
+ const rawContent = yield* fs.readFileString(contentPath).pipe(Effect.mapError((error) => new ExtensionLifecycleFailed({
79
+ category: "internal",
80
+ detail: `Failed to read ${expectedFilename} from ${subagentSrcPath}`,
81
+ suggestions: [
82
+ {
83
+ description: `Ensure the subagent content file exists at ${contentPath}.`,
84
+ },
85
+ ],
86
+ cause: error,
87
+ })));
88
+ const parsed = yield* parseSubagentMd(rawContent, op.args.subagentName).pipe();
89
+ const frontmatter = Option.getOrElse(parsed.frontmatter, () => ({}));
90
+ const agentOverrides = Option.getOrUndefined(parsed.agentOverrides);
91
+ const renderFrontmatter = stripAgentOverrides(frontmatter);
92
+ // Render to all configured agents
93
+ const configuredAgents = yield* agentRepo.getConfiguredAgents();
94
+ yield* warnOnOrphanOverrides(`Subagent "${op.args.subagentName}"`, agentOverrides, configuredAgents.map((a) => a.id));
95
+ const renderedFilesMap = {};
96
+ yield* ws.runTransaction({
97
+ transition: Effect.gen(function* () {
98
+ yield* Effect.forEach(configuredAgents, (agent) => agent
99
+ .addSubagent({
100
+ workspaceRoot: baseDir,
101
+ scope: ws.scope,
102
+ managedFile,
103
+ input: {
104
+ agentId: agent.id,
105
+ name: op.args.subagentName,
106
+ body: parsed.body,
107
+ frontmatter: renderFrontmatter,
108
+ agentOverrides: agentOverrides?.[agent.id],
109
+ },
110
+ force: false,
111
+ })
112
+ .pipe(Effect.flatMap((outcome) => {
113
+ if (outcome._tag === "conflict") {
114
+ return new ExtensionLifecycleFailed({
115
+ category: "conflict",
116
+ detail: `Subagent rendering failed for ${agent.id}: ${outcome.reason}`,
117
+ });
118
+ }
119
+ if (outcome._tag !== "success")
120
+ return Effect.void;
121
+ return Effect.forEach(outcome.renderedFilePaths, (renderedPath) => {
122
+ const relativePath = makeWorkspaceRelativePath(path, baseDir, renderedPath);
123
+ if (Option.isNone(relativePath)) {
124
+ return Effect.fail(new ExtensionLifecycleFailed({
125
+ category: "internal",
126
+ detail: `Rendered subagent path escapes workspace root: ${renderedPath}`,
127
+ }));
128
+ }
129
+ return Effect.succeed({ path: relativePath.value });
130
+ }).pipe(Effect.map((entries) => {
131
+ renderedFilesMap[agent.id] = entries;
132
+ }));
133
+ })), { concurrency: "unbounded" });
134
+ yield* ws.updateSubagentEntry(op.args.subagentName, (entry) => ({
135
+ ...entry,
136
+ enabled: true,
137
+ }));
138
+ }).pipe(Effect.provideService(FileSystem.FileSystem, fs), Effect.provideService(Path.Path, path)),
139
+ validate: () => Effect.void,
140
+ });
141
+ const decodeRenderedFiles = Schema.decodeUnknownSync(RenderedFilesMapSchema);
142
+ const renderedFiles = decodeRenderedFiles(renderedFilesMap);
143
+ const version = canonical.value.accepted?.type === "registry"
144
+ ? canonical.value.accepted.resolvedVersion
145
+ : undefined;
146
+ return {
147
+ result: "success",
148
+ message: `Enabled ${op.args.subagentName}`,
149
+ artifact: subagentLifecycleArtifact({
150
+ name: op.args.subagentName,
151
+ scope: ws.scope,
152
+ agents: configuredAgents.map((agent) => agent.id),
153
+ ...(version === undefined ? {} : { version }),
154
+ change: "updated",
155
+ renderedFiles,
156
+ renderedChange: "updated",
157
+ }),
158
+ };
159
+ }).pipe(withAdaptedStepFailures);
160
+ //# sourceMappingURL=enable.js.map
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Shared install command workflow orchestration.
3
+ *
4
+ * Defines the `InstallExtensionCommandWorkflowActions` interface and
5
+ * `runInstallCommandWorkflow` function shared by all install command handlers.
6
+ *
7
+ * @experimental This API is unstable and may change without notice.
8
+ */
9
+ import * as Effect from "effect/Effect";
10
+ import type * as Scope from "effect/Scope";
11
+ import type { Plan } from "@agentxm/workspace-operations";
12
+ import type { OperationResolution } from "@agentxm/workspace-operations";
13
+ import type { PlanExecution } from "@agentxm/workspace-operations";
14
+ import { LifecycleResolutionProgress } from "../../resolution-progress.js";
15
+ /**
16
+ * Type-specific actions for install command workflows.
17
+ *
18
+ * Each extension type provides its own implementation of these actions.
19
+ * The generic type parameters allow full type safety per extension type.
20
+ *
21
+ * @typeParam Args - Raw command arguments from the active CLI parser
22
+ * @typeParam Parsed - Parsed/validated arguments
23
+ * @typeParam Req - Source request type (for resolution)
24
+ * @typeParam Ref - Extension ref type (discovery output)
25
+ * @typeParam Intent - Command-specific install intent
26
+ * @typeParam ParseError - Failures the argument/plan phases surface
27
+ * @typeParam ResolveError - Failures the interactive resolution phases surface
28
+ */
29
+ export interface InstallExtensionCommandWorkflowActions<Args, Parsed, Req, Ref, Intent, ParseError, ResolveError = ParseError> {
30
+ readonly parseArgs: (args: Args) => Effect.Effect<Parsed, ParseError>;
31
+ readonly resolveSourceRequests: (parsed: Parsed) => Effect.Effect<ReadonlyArray<Req>, ResolveError>;
32
+ readonly discoverRefs: (reqs: ReadonlyArray<Req>) => Effect.Effect<ReadonlyArray<Ref>, ParseError, Scope.Scope>;
33
+ readonly finalizeIntent: (parsed: Parsed, refs: ReadonlyArray<Ref>) => Effect.Effect<Intent, ResolveError>;
34
+ readonly buildPlan: (intent: Intent) => Effect.Effect<Plan, ParseError>;
35
+ }
36
+ /**
37
+ * Run the canonical install command workflow.
38
+ *
39
+ * Executes phases in order: parse -> resolveSource -> discover ->
40
+ * finalizeIntent -> buildPlan -> previewOrApplyPlan.
41
+ */
42
+ export declare const buildInstallCommandPlan: <Args, Parsed, Req, Ref, Intent, ParseError, ResolveError, TransformError = never, TransformRequirements = never>(args: Args, actions: InstallExtensionCommandWorkflowActions<Args, Parsed, Req, Ref, Intent, ParseError, ResolveError>, options?: {
43
+ readonly transformIntent?: (intent: Intent) => Intent;
44
+ readonly transformPlan?: (plan: Plan) => Effect.Effect<Plan, TransformError, TransformRequirements>;
45
+ }) => Effect.Effect<Plan<never, never>, ParseError | ResolveError | TransformError, Scope.Scope | TransformRequirements>;
46
+ /**
47
+ * Run the canonical install command workflow.
48
+ *
49
+ * Executes phases in order: parse -> resolveSource -> discover ->
50
+ * finalizeIntent -> buildPlan -> previewOrApplyPlan.
51
+ */
52
+ export declare const runInstallCommandWorkflow: <Args, Parsed, Req, Ref, Intent, ParseError, ResolveError, TransformError = never, TransformRequirements = never>(args: Args, actions: InstallExtensionCommandWorkflowActions<Args, Parsed, Req, Ref, Intent, ParseError, ResolveError>, options: {
53
+ readonly execution: PlanExecution;
54
+ readonly transformIntent?: (intent: Intent) => Intent;
55
+ readonly transformPlan?: (plan: Plan) => Effect.Effect<Plan, TransformError, TransformRequirements>;
56
+ }) => Effect.Effect<OperationResolution<never>, import("@agentxm/workspace-state").WorkspaceSettingsReadFailure | ParseError | ResolveError | TransformError | import("@agentxm/workspace-operations").CandidateFingerprintFailed | import("@agentxm/workspace-operations").ApprovalRecoveryMissing | import("@agentxm/workspace-operations").PlanInteractionFailed | import("@agentxm/workspace-state").WorkspaceTransitionAcquireFailure | import("@agentxm/workspace-state").LockfileValidationError, import("@agentxm/workspace-state").WorkspaceMutations | import("effect/FileSystem").FileSystem | import("effect/Path").Path | LifecycleResolutionProgress | import("@agentxm/workspace-operations").ResolvePlanInteraction | Exclude<TransformRequirements, Scope.Scope>>;
57
+ //# sourceMappingURL=workflow.d.ts.map
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Shared install command workflow orchestration.
3
+ *
4
+ * Defines the `InstallExtensionCommandWorkflowActions` interface and
5
+ * `runInstallCommandWorkflow` function shared by all install command handlers.
6
+ *
7
+ * @experimental This API is unstable and may change without notice.
8
+ */
9
+ import * as Effect from "effect/Effect";
10
+ import { previewOrApplyPlan } from "@agentxm/workspace-operations";
11
+ import { LifecycleResolutionProgress } from "../../resolution-progress.js";
12
+ // -----------------------------------------------------------------------------
13
+ // Install Command Workflow
14
+ // -----------------------------------------------------------------------------
15
+ /**
16
+ * Run the canonical install command workflow.
17
+ *
18
+ * Executes phases in order: parse -> resolveSource -> discover ->
19
+ * finalizeIntent -> buildPlan -> previewOrApplyPlan.
20
+ */
21
+ export const buildInstallCommandPlan = (args, actions, options) => Effect.gen(function* () {
22
+ const parsed = yield* actions.parseArgs(args);
23
+ const sourceRequests = yield* actions.resolveSourceRequests(parsed);
24
+ const refs = yield* actions.discoverRefs(sourceRequests);
25
+ const finalizedIntent = yield* actions.finalizeIntent(parsed, refs);
26
+ const intent = options?.transformIntent?.(finalizedIntent) ?? finalizedIntent;
27
+ const plan = yield* actions.buildPlan(intent);
28
+ return options?.transformPlan === undefined ? plan : yield* options.transformPlan(plan);
29
+ });
30
+ /**
31
+ * Run the canonical install command workflow.
32
+ *
33
+ * Executes phases in order: parse -> resolveSource -> discover ->
34
+ * finalizeIntent -> buildPlan -> previewOrApplyPlan.
35
+ */
36
+ export const runInstallCommandWorkflow = (args, actions, options) => Effect.gen(function* () {
37
+ const progress = yield* LifecycleResolutionProgress;
38
+ const plan = yield* progress.withSourceResolution(buildInstallCommandPlan(args, actions, options));
39
+ return yield* previewOrApplyPlan(plan, { execution: options.execution });
40
+ }).pipe(Effect.scoped, Effect.map((resolution) => resolution));
41
+ //# sourceMappingURL=workflow.js.map
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Shared uninstall command workflow orchestration.
3
+ *
4
+ * Defines the `UninstallExtensionCommandWorkflowActions` interface and
5
+ * `runUninstallCommandWorkflow` function shared by all uninstall command handlers.
6
+ *
7
+ * @experimental This API is unstable and may change without notice.
8
+ */
9
+ import * as Effect from "effect/Effect";
10
+ import type { Plan } from "@agentxm/workspace-operations";
11
+ import type { StepFailure } from "@agentxm/workspace-operations";
12
+ import type { OperationResolution } from "@agentxm/workspace-operations";
13
+ import type { PlanExecution } from "@agentxm/workspace-operations";
14
+ /**
15
+ * Type-specific actions for uninstall command workflows.
16
+ *
17
+ * Each extension type provides its own implementation of these actions.
18
+ * The generic type parameters allow full type safety per extension type.
19
+ *
20
+ * @typeParam Args - Raw command arguments from the active CLI parser
21
+ * @typeParam Parsed - Parsed/validated arguments
22
+ * @typeParam Intent - Command-specific uninstall intent
23
+ * @typeParam E - Failures the phases surface
24
+ */
25
+ export interface UninstallExtensionCommandWorkflowActions<Args, Parsed, Intent, E> {
26
+ readonly parseArgs: (args: Args) => Effect.Effect<Parsed, E>;
27
+ readonly finalizeIntent: (parsed: Parsed) => Effect.Effect<Intent, E>;
28
+ readonly buildUninstallPlan: (intent: Intent, flags: UninstallWorkflowFlags) => Effect.Effect<Plan, E>;
29
+ }
30
+ export interface UninstallWorkflowFlags {
31
+ readonly execution: PlanExecution;
32
+ /** Optional delayed gate; candidate freshness is checked again after it completes. */
33
+ readonly beforeApply?: () => Effect.Effect<void, StepFailure>;
34
+ }
35
+ /**
36
+ * Run the canonical uninstall command workflow.
37
+ *
38
+ * Executes phases in order: parse -> finalizeIntent -> buildUninstallPlan ->
39
+ * previewOrApplyPlan.
40
+ */
41
+ export declare const runUninstallCommandWorkflow: <Args, Parsed, Intent, E>(args: Args, actions: UninstallExtensionCommandWorkflowActions<Args, Parsed, Intent, E>, flags: UninstallWorkflowFlags) => Effect.Effect<OperationResolution<never>, import("@agentxm/workspace-state").WorkspaceSettingsReadFailure | import("@agentxm/workspace-operations").CandidateFingerprintFailed | import("@agentxm/workspace-operations").ApprovalRecoveryMissing | import("@agentxm/workspace-operations").PlanInteractionFailed | import("@agentxm/workspace-state").WorkspaceTransitionAcquireFailure | import("@agentxm/workspace-state").LockfileValidationError | E, import("@agentxm/workspace-state").WorkspaceMutations | import("effect/FileSystem").FileSystem | import("effect/Path").Path | import("@agentxm/workspace-operations").ResolvePlanInteraction>;
42
+ //# sourceMappingURL=workflow.d.ts.map
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Shared uninstall command workflow orchestration.
3
+ *
4
+ * Defines the `UninstallExtensionCommandWorkflowActions` interface and
5
+ * `runUninstallCommandWorkflow` function shared by all uninstall command handlers.
6
+ *
7
+ * @experimental This API is unstable and may change without notice.
8
+ */
9
+ import * as Effect from "effect/Effect";
10
+ import { previewOrApplyPlan } from "@agentxm/workspace-operations";
11
+ // -----------------------------------------------------------------------------
12
+ // Uninstall Command Workflow
13
+ // -----------------------------------------------------------------------------
14
+ /**
15
+ * Run the canonical uninstall command workflow.
16
+ *
17
+ * Executes phases in order: parse -> finalizeIntent -> buildUninstallPlan ->
18
+ * previewOrApplyPlan.
19
+ */
20
+ export const runUninstallCommandWorkflow = (args, actions, flags) => Effect.gen(function* () {
21
+ const parsed = yield* actions.parseArgs(args);
22
+ const intent = yield* actions.finalizeIntent(parsed);
23
+ const plan = yield* actions.buildUninstallPlan(intent, flags);
24
+ return yield* previewOrApplyPlan(plan, {
25
+ execution: flags.execution,
26
+ ...(flags.beforeApply === undefined ? {} : { beforeApply: flags.beforeApply }),
27
+ });
28
+ }).pipe(Effect.map((resolution) => resolution));
29
+ //# sourceMappingURL=workflow.js.map
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@agentxm/extension-lifecycle",
3
+ "version": "0.28.4-bootstrap.0",
4
+ "description": "AXM extension-lifecycle feature: install, update, uninstall, enable, and disable policy across root and type-specific command forms for the axm CLI. Unstable and unsupported — use the axm.sh CLI.",
5
+ "type": "module",
6
+ "license": "FSL-1.1-MIT",
7
+ "homepage": "https://axm.sh",
8
+ "bugs": {
9
+ "url": "https://github.com/agentxm/axm/issues"
10
+ },
11
+ "author": "AgentXM <hello@agentxm.ai> (https://agentxm.ai)",
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "https://github.com/agentxm/axm.git",
15
+ "directory": "packages/extension-lifecycle"
16
+ },
17
+ "sideEffects": false,
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/src/index.d.ts",
21
+ "default": "./dist/src/index.js"
22
+ },
23
+ "./live": {
24
+ "types": "./dist/src/live.d.ts",
25
+ "default": "./dist/src/live.js"
26
+ }
27
+ },
28
+ "files": [
29
+ "dist/src/",
30
+ "!**/*.map"
31
+ ],
32
+ "publishConfig": {
33
+ "access": "public"
34
+ },
35
+ "engines": {
36
+ "node": ">=22.19.0"
37
+ },
38
+ "nx": {
39
+ "includedScripts": []
40
+ },
41
+ "dependencies": {
42
+ "effect": "4.0.0-rc.112",
43
+ "semver": "^7.8.5",
44
+ "@agentxm/registry-client": "^0.28.4-bootstrap.0",
45
+ "@agentxm/extension-sources": "^0.28.4-bootstrap.0",
46
+ "@agentxm/extension-model": "^0.28.4-bootstrap.0",
47
+ "@agentxm/workspace-state": "^0.28.4-bootstrap.0",
48
+ "@agentxm/registry-protocol": "^0.28.4-bootstrap.0",
49
+ "@agentxm/extension-workspace": "^0.28.4-bootstrap.0",
50
+ "@agentxm/workspace-operations": "^0.28.4-bootstrap.0"
51
+ },
52
+ "devDependencies": {
53
+ "@effect/platform-node": "4.0.0-rc.112",
54
+ "@effect/vitest": "4.0.0-rc.112",
55
+ "@types/bun": "^1.3.14",
56
+ "@types/semver": "^7.5.8",
57
+ "@typescript/native": "npm:typescript@^7.0.2",
58
+ "typescript": "npm:@typescript/typescript6@^6.0.2",
59
+ "vitest": "^4.1.10",
60
+ "yaml": "^2.9.0"
61
+ }
62
+ }