@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.
- package/LICENSE +110 -0
- package/dist/src/configured-entry-resolution.d.ts +110 -0
- package/dist/src/configured-entry-resolution.js +723 -0
- package/dist/src/errors.d.ts +39 -0
- package/dist/src/errors.js +45 -0
- package/dist/src/failure-adapter.d.ts +35 -0
- package/dist/src/failure-adapter.js +23 -0
- package/dist/src/hooks/configured-agent-outcomes-provider.d.ts +18 -0
- package/dist/src/hooks/configured-agent-outcomes-provider.js +39 -0
- package/dist/src/hooks/manager.d.ts +15 -0
- package/dist/src/hooks/manager.js +751 -0
- package/dist/src/index.d.ts +38 -0
- package/dist/src/index.js +41 -0
- package/dist/src/internal/fs-helpers.d.ts +12 -0
- package/dist/src/internal/fs-helpers.js +13 -0
- package/dist/src/internal/integrity.d.ts +13 -0
- package/dist/src/internal/integrity.js +17 -0
- package/dist/src/knowledge/manager.d.ts +11 -0
- package/dist/src/knowledge/manager.js +655 -0
- package/dist/src/live.d.ts +18 -0
- package/dist/src/live.js +18 -0
- package/dist/src/mcps/manager.d.ts +16 -0
- package/dist/src/mcps/manager.js +213 -0
- package/dist/src/mcps/operations/artifact.d.ts +24 -0
- package/dist/src/mcps/operations/artifact.js +74 -0
- package/dist/src/mcps/operations/disable.d.ts +18 -0
- package/dist/src/mcps/operations/disable.js +113 -0
- package/dist/src/mcps/operations/enable.d.ts +18 -0
- package/dist/src/mcps/operations/enable.js +218 -0
- package/dist/src/mcps/operations/install.d.ts +59 -0
- package/dist/src/mcps/operations/install.js +566 -0
- package/dist/src/mcps/operations/sync-outcome.d.ts +10 -0
- package/dist/src/mcps/operations/sync-outcome.js +27 -0
- package/dist/src/mcps/operations/uninstall.d.ts +41 -0
- package/dist/src/mcps/operations/uninstall.js +189 -0
- package/dist/src/packs/dependency-resolution.d.ts +65 -0
- package/dist/src/packs/dependency-resolution.js +414 -0
- package/dist/src/packs/expansion.d.ts +59 -0
- package/dist/src/packs/expansion.js +44 -0
- package/dist/src/packs/manager.d.ts +16 -0
- package/dist/src/packs/manager.js +181 -0
- package/dist/src/packs/operations/install.d.ts +67 -0
- package/dist/src/packs/operations/install.js +156 -0
- package/dist/src/packs/resolved-dependency.d.ts +29 -0
- package/dist/src/packs/resolved-dependency.js +28 -0
- package/dist/src/registry-materialization.d.ts +52 -0
- package/dist/src/registry-materialization.js +67 -0
- package/dist/src/resolution-progress.d.ts +18 -0
- package/dist/src/resolution-progress.js +11 -0
- package/dist/src/resolution-timeout.d.ts +5 -0
- package/dist/src/resolution-timeout.js +11 -0
- package/dist/src/rules/manager.d.ts +20 -0
- package/dist/src/rules/manager.js +475 -0
- package/dist/src/skills/manager.d.ts +18 -0
- package/dist/src/skills/manager.js +346 -0
- package/dist/src/skills/materialization.d.ts +54 -0
- package/dist/src/skills/materialization.js +158 -0
- package/dist/src/skills/operations/disable.d.ts +31 -0
- package/dist/src/skills/operations/disable.js +110 -0
- package/dist/src/skills/operations/enable.d.ts +31 -0
- package/dist/src/skills/operations/enable.js +113 -0
- package/dist/src/skills/operations/install-result.d.ts +33 -0
- package/dist/src/skills/operations/install-result.js +10 -0
- package/dist/src/skills/operations/install.d.ts +67 -0
- package/dist/src/skills/operations/install.js +590 -0
- package/dist/src/skills/operations/source-hash.d.ts +2 -0
- package/dist/src/skills/operations/source-hash.js +6 -0
- package/dist/src/skills/operations/uninstall.d.ts +40 -0
- package/dist/src/skills/operations/uninstall.js +157 -0
- package/dist/src/skills/utils.d.ts +11 -0
- package/dist/src/skills/utils.js +29 -0
- package/dist/src/subagents/manager.d.ts +18 -0
- package/dist/src/subagents/manager.js +677 -0
- package/dist/src/subagents/operations/artifact.d.ts +18 -0
- package/dist/src/subagents/operations/artifact.js +43 -0
- package/dist/src/subagents/operations/disable.d.ts +32 -0
- package/dist/src/subagents/operations/disable.js +116 -0
- package/dist/src/subagents/operations/enable.d.ts +30 -0
- package/dist/src/subagents/operations/enable.js +160 -0
- package/dist/src/workflows/install-command/workflow.d.ts +57 -0
- package/dist/src/workflows/install-command/workflow.js +41 -0
- package/dist/src/workflows/uninstall-command/workflow.d.ts +42 -0
- package/dist/src/workflows/uninstall-command/workflow.js +29 -0
- 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
|
+
}
|