@agentxm/extension-lifecycle 0.29.4 → 0.30.2
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/dist/src/activation/set-activation.d.ts +22 -40
- package/dist/src/activation/set-activation.js +191 -336
- package/dist/src/demote/demote-to-external-source.d.ts +1 -1
- package/dist/src/demote/demote-to-external-source.js +53 -24
- package/dist/src/hooks/install/plan.js +6 -3
- package/dist/src/hooks/uninstall/plan.js +4 -3
- package/dist/src/index.d.ts +1 -5
- package/dist/src/index.js +1 -4
- package/dist/src/install/install-extensions.d.ts +5 -5
- package/dist/src/install/install-extensions.js +2 -1
- package/dist/src/install/root-intent.d.ts +2 -2
- package/dist/src/install/vocabulary.d.ts +5 -4
- package/dist/src/knowledge/install/plan.js +2 -1
- package/dist/src/knowledge/uninstall/plan.js +4 -3
- package/dist/src/mcps/install/plan.d.ts +1 -1
- package/dist/src/mcps/install/plan.js +59 -3
- package/dist/src/mcps/operations/uninstall.js +2 -1
- package/dist/src/mcps/uninstall/plan.js +13 -4
- package/dist/src/packs/graph-transition.d.ts +0 -25
- package/dist/src/packs/graph-transition.js +0 -101
- package/dist/src/packs/install/plan.d.ts +0 -13
- package/dist/src/packs/install/plan.js +12 -9
- package/dist/src/packs/member-install-step.js +8 -21
- package/dist/src/packs/promote-authored-pack.js +6 -3
- package/dist/src/packs/uninstall/plan.js +53 -21
- package/dist/src/rules/install/plan.js +6 -3
- package/dist/src/rules/uninstall/plan.js +4 -3
- package/dist/src/skills/application/index.d.ts +42 -0
- package/dist/src/skills/application/index.js +37 -0
- package/dist/src/skills/domain/selection.d.ts +22 -0
- package/dist/src/skills/domain/selection.js +18 -0
- package/dist/src/skills/install/artifact.d.ts +4 -0
- package/dist/src/skills/install/artifact.js +29 -0
- package/dist/src/skills/install/bundled.js +4 -4
- package/dist/src/skills/install/plan.d.ts +15 -4
- package/dist/src/skills/install/plan.js +114 -97
- package/dist/src/skills/uninstall/plan.js +13 -5
- package/dist/src/step-failure.js +12 -0
- package/dist/src/subagents/application/index.d.ts +42 -0
- package/dist/src/subagents/application/index.js +37 -0
- package/dist/src/subagents/domain/selection.d.ts +22 -0
- package/dist/src/subagents/domain/selection.js +18 -0
- package/dist/src/subagents/install/plan.d.ts +2 -2
- package/dist/src/subagents/install/plan.js +4 -4
- package/dist/src/subagents/operations/enable.js +1 -3
- package/dist/src/subagents/uninstall/plan.js +5 -4
- package/dist/src/testing.d.ts +3 -2
- package/dist/src/testing.js +9 -6
- package/dist/src/uninstall/root-intent.d.ts +2 -1
- package/dist/src/uninstall/root-intent.js +1 -0
- package/dist/src/uninstall/undesired-target.d.ts +26 -0
- package/dist/src/uninstall/undesired-target.js +56 -0
- package/dist/src/uninstall/uninstall-extensions.d.ts +1 -1
- package/dist/src/uninstall/uninstall-extensions.js +103 -3
- package/dist/src/update/root-request.d.ts +2 -2
- package/dist/src/update/selective/plan.d.ts +2 -3
- package/dist/src/update/selective/plan.js +2 -2
- package/dist/src/update/selective/requirements.d.ts +2 -6
- package/dist/src/update/selective/requirements.js +1 -3
- package/dist/src/update/selective/selection.js +1 -1
- package/dist/src/update/selective/skills.d.ts +2 -4
- package/dist/src/update/selective/skills.js +22 -27
- package/dist/src/update/selective/subagents.d.ts +2 -3
- package/dist/src/update/selective/subagents.js +11 -9
- package/dist/src/update/selective/use-case.d.ts +7 -7
- package/dist/src/update/selective/vocabulary.d.ts +1 -1
- package/dist/src/update/selector.js +1 -1
- package/dist/src/update/targeted-plan.js +4 -2
- package/dist/src/workspace-paths.d.ts +0 -6
- package/dist/src/workspace-paths.js +0 -10
- package/package.json +30 -24
- package/dist/src/glob.d.ts +0 -35
- package/dist/src/glob.js +0 -75
- package/dist/src/install/selection-interaction.d.ts +0 -46
- package/dist/src/install/selection-interaction.js +0 -22
- package/dist/src/skills/install/selection.d.ts +0 -26
- package/dist/src/skills/install/selection.js +0 -41
- package/dist/src/skills/operations/install-result.d.ts +0 -33
- package/dist/src/skills/operations/install-result.js +0 -10
- package/dist/src/skills/operations/install.d.ts +0 -67
- package/dist/src/skills/operations/install.js +0 -591
- package/dist/src/subagents/install/selection.d.ts +0 -26
- package/dist/src/subagents/install/selection.js +0 -37
- package/dist/src/uninstall/retention-policy.d.ts +0 -21
- package/dist/src/uninstall/retention-policy.js +0 -28
|
@@ -11,109 +11,8 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import * as Effect from "effect/Effect";
|
|
13
13
|
import { WorkspaceMutations, desiredStateProblemsText, } from "@agentxm/workspace-state";
|
|
14
|
-
import { runWorkspaceTransaction } from "@agentxm/workspace-transactions";
|
|
15
|
-
import { StepFailure, } from "@agentxm/workspace-operations";
|
|
16
|
-
import { lifecycleStepFailure } from "../step-failure.js";
|
|
17
14
|
import { installRefused } from "../install/vocabulary.js";
|
|
18
15
|
const normalizedIdentity = (identity) => identity.startsWith("workspace:") ? identity.slice("workspace:".length) : identity;
|
|
19
|
-
const failedStep = (label, result) => result.result === "error"
|
|
20
|
-
? Effect.fail(result.error ??
|
|
21
|
-
lifecycleStepFailure(installRefused({
|
|
22
|
-
category: "internal",
|
|
23
|
-
detail: `${label} failed: ${result.message}`,
|
|
24
|
-
})))
|
|
25
|
-
: Effect.succeed(result);
|
|
26
|
-
const aggregatePackCoverage = (results, scope) => Effect.gen(function* () {
|
|
27
|
-
const applicableArtifacts = results.flatMap(({ result, coverage }) => coverage === "eligible" &&
|
|
28
|
-
result.result === "success" &&
|
|
29
|
-
result.artifact?.agents !== undefined
|
|
30
|
-
? [result.artifact]
|
|
31
|
-
: []);
|
|
32
|
-
const agents = [];
|
|
33
|
-
for (const artifact of applicableArtifacts) {
|
|
34
|
-
if (artifact.scope !== scope) {
|
|
35
|
-
return yield* installRefused({
|
|
36
|
-
category: "internal",
|
|
37
|
-
detail: `Pack coverage spans ${scope} and ${artifact.scope} scopes`,
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
const artifactAgents = new Set(artifact.agents);
|
|
41
|
-
for (const target of artifact.targets ?? []) {
|
|
42
|
-
for (const agent of target.agentIds ?? []) {
|
|
43
|
-
if (!artifactAgents.has(agent)) {
|
|
44
|
-
return yield* installRefused({
|
|
45
|
-
category: "internal",
|
|
46
|
-
detail: `Pack child target agent ${agent} is absent from its artifact agents`,
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
for (const agent of artifact.agents ?? []) {
|
|
52
|
-
if (agent !== "universal" && !agents.includes(agent))
|
|
53
|
-
agents.push(agent);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
return { applicable: applicableArtifacts.length > 0, agents };
|
|
57
|
-
});
|
|
58
|
-
/** Wrap a pack transition's children in one workspace transaction. */
|
|
59
|
-
export const buildAtomicPackGraphStep = (args) => Effect.sync(() => {
|
|
60
|
-
const readinessErrors = args.children.flatMap(({ step }) => step.readiness === "error" ? [step.errorMessage] : []);
|
|
61
|
-
if (readinessErrors.length > 0) {
|
|
62
|
-
const blockingConditionIds = args.children.flatMap(({ step }) => step.readiness === "error" ? (step.blockingConditionIds ?? []) : []);
|
|
63
|
-
return {
|
|
64
|
-
readiness: "error",
|
|
65
|
-
label: args.label,
|
|
66
|
-
errorMessage: readinessErrors.join("; "),
|
|
67
|
-
artifact: args.artifact,
|
|
68
|
-
...(blockingConditionIds.length === 0 ? {} : { blockingConditionIds }),
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
const readinessWarnings = args.children.flatMap(({ step }) => step.readiness === "warn" ? [step.warnMessage] : []);
|
|
72
|
-
const runnableChildren = args.children.filter((child) => child.step.readiness !== "error");
|
|
73
|
-
let validatedCoverage = { applicable: false, agents: [] };
|
|
74
|
-
const run = runWorkspaceTransaction({
|
|
75
|
-
transition: Effect.gen(function* () {
|
|
76
|
-
if (args.preTransition !== undefined) {
|
|
77
|
-
yield* args.preTransition.pipe(Effect.mapError(lifecycleStepFailure));
|
|
78
|
-
}
|
|
79
|
-
return yield* Effect.forEach(runnableChildren, ({ step, coverage }) => step.run.pipe(Effect.flatMap((result) => failedStep(step.label, result)), Effect.map((result) => ({ result, coverage }))), { concurrency: 1 });
|
|
80
|
-
}),
|
|
81
|
-
validate: (results) => Effect.gen(function* () {
|
|
82
|
-
yield* args.validate;
|
|
83
|
-
validatedCoverage = yield* aggregatePackCoverage(results, args.artifact.scope);
|
|
84
|
-
}).pipe(Effect.mapError(lifecycleStepFailure)),
|
|
85
|
-
}).pipe(Effect.mapError(lifecycleStepFailure), Effect.map((results) => {
|
|
86
|
-
const warnings = results.flatMap(({ result }) => result.result === "success" ? (result.warnings ?? []) : []);
|
|
87
|
-
const allChildrenUnchanged = args.reportUnchangedWhenChildrenUnchanged === true &&
|
|
88
|
-
results.length > 0 &&
|
|
89
|
-
results.every(({ result }) => result.result === "success" && result.artifact?.change === "unchanged");
|
|
90
|
-
const artifact = allChildrenUnchanged
|
|
91
|
-
? { ...args.artifact, change: "unchanged" }
|
|
92
|
-
: args.artifact;
|
|
93
|
-
return {
|
|
94
|
-
result: "success",
|
|
95
|
-
message: args.message,
|
|
96
|
-
artifact: !validatedCoverage.applicable
|
|
97
|
-
? artifact
|
|
98
|
-
: { ...artifact, agents: validatedCoverage.agents },
|
|
99
|
-
...(warnings.length === 0 ? {} : { warnings }),
|
|
100
|
-
};
|
|
101
|
-
}));
|
|
102
|
-
return readinessWarnings.length === 0
|
|
103
|
-
? {
|
|
104
|
-
readiness: "ready",
|
|
105
|
-
label: args.label,
|
|
106
|
-
artifact: args.artifact,
|
|
107
|
-
run,
|
|
108
|
-
}
|
|
109
|
-
: {
|
|
110
|
-
readiness: "warn",
|
|
111
|
-
label: args.label,
|
|
112
|
-
warnMessage: readinessWarnings.join("; "),
|
|
113
|
-
artifact: args.artifact,
|
|
114
|
-
run,
|
|
115
|
-
};
|
|
116
|
-
});
|
|
117
16
|
/** The desired-graph predicate a completed pack transition must satisfy. */
|
|
118
17
|
export const validatePackGraphPostcondition = (args) => Effect.gen(function* () {
|
|
119
18
|
const ws = yield* WorkspaceMutations;
|
|
@@ -1,16 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Installing a pack.
|
|
3
|
-
*
|
|
4
|
-
* A pack install is a graph transition, not a package copy: the pack's own
|
|
5
|
-
* package, every member its manifest resolves to, and every member the
|
|
6
|
-
* previous graph owned and this one drops all change together. Workspace
|
|
7
|
-
* source authority decides whether a locally-authored package may stand in
|
|
8
|
-
* for a declared member, the minimum-release-age policy decides whether a
|
|
9
|
-
* held-back release preserves the current graph or blocks, and the transition
|
|
10
|
-
* is refused if the authority it was planned against changed underneath it.
|
|
11
|
-
*
|
|
12
|
-
* @experimental This API is unstable and may change without notice.
|
|
13
|
-
*/
|
|
14
1
|
import * as Effect from "effect/Effect";
|
|
15
2
|
import * as Option from "effect/Option";
|
|
16
3
|
import * as Path from "effect/Path";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { buildReconciliationClosure } from "@agentxm/workspace-reconciliation";
|
|
1
2
|
/**
|
|
2
3
|
* Installing a pack.
|
|
3
4
|
*
|
|
@@ -16,7 +17,8 @@ import * as Effect from "effect/Effect";
|
|
|
16
17
|
import * as Option from "effect/Option";
|
|
17
18
|
import * as Path from "effect/Path";
|
|
18
19
|
import * as Result from "effect/Result";
|
|
19
|
-
import { HookManager, KnowledgeManager, McpServerManager, PackManager, RuleManager, SkillManager, SubagentManager,
|
|
20
|
+
import { HookManager, KnowledgeManager, McpServerManager, PackManager, RuleManager, SkillManager, SubagentManager, } from "@agentxm/extension-materialization";
|
|
21
|
+
import { buildInstallOperation, buildUninstallOperation, targetFromRef, toLabel, } from "@agentxm/workspace-reconciliation";
|
|
20
22
|
import { parseExtensionFqnParts, toExtensionTypePlural, } from "@agentxm/extension-model/unstable/extensions";
|
|
21
23
|
import { isWorkspaceSourceLocator } from "@agentxm/extension-model/unstable/sources/workspace";
|
|
22
24
|
import { versionSatisfiesRange, } from "@agentxm/extension-model/unstable/version-constraints";
|
|
@@ -31,10 +33,10 @@ import { registryLoginSuggestions } from "../../install/registry-login-suggestio
|
|
|
31
33
|
import { formatRegistryProbe, sourceFailureDetail, } from "../../install/registry-source-resolution.js";
|
|
32
34
|
import { installRefused, } from "../../install/vocabulary.js";
|
|
33
35
|
import { expandPackInstallRefs, expandPackInstallRefsWithReleaseAge } from "../expansion.js";
|
|
34
|
-
import {
|
|
36
|
+
import { validatePackGraphPostcondition } from "../graph-transition.js";
|
|
35
37
|
import { buildPackMemberInstallStep } from "../member-install-step.js";
|
|
36
38
|
import { registrySourceArtifact, registrySourcePath } from "../artifact.js";
|
|
37
|
-
import { makeWorkspaceRetentionPolicy } from "
|
|
39
|
+
import { makeWorkspaceRetentionPolicy } from "@agentxm/workspace-reconciliation";
|
|
38
40
|
const isRemoteReadNotImplemented = (error) => {
|
|
39
41
|
const detail = sourceFailureDetail(error);
|
|
40
42
|
return detail.includes("not implemented") || detail.includes("not yet supported");
|
|
@@ -661,12 +663,12 @@ export const planPackInstall = Effect.fn("InstallExtensions.planPack")(function*
|
|
|
661
663
|
// cleanup by suppressing dropped-member removal until the pre-install graph
|
|
662
664
|
// is complete.
|
|
663
665
|
const existingPack = graph.complete ? currentPackNode : undefined;
|
|
664
|
-
const retentionPolicy = makeWorkspaceRetentionPolicy(ws);
|
|
666
|
+
const retentionPolicy = makeWorkspaceRetentionPolicy(ws, lifecycleStepFailure);
|
|
665
667
|
const installSteps = yield* Effect.forEach(refs, (ref) => ref.type === "pack"
|
|
666
668
|
? Effect.succeed(buildInstallOperation(packManager, {
|
|
667
669
|
toStepFailure: lifecycleStepFailure,
|
|
668
670
|
ref,
|
|
669
|
-
versionRange: intent.versionRange,
|
|
671
|
+
declaration: { name: ref.pack.name, versionRange: intent.versionRange },
|
|
670
672
|
...(intent.forceCanonical === true ? { force: true } : {}),
|
|
671
673
|
installedBefore: graph.complete
|
|
672
674
|
? packManager.isInstalled({
|
|
@@ -724,19 +726,19 @@ export const planPackInstall = Effect.fn("InstallExtensions.planPack")(function*
|
|
|
724
726
|
return buildUninstallOperation(ruleManager, retentionPolicy, {
|
|
725
727
|
toStepFailure: lifecycleStepFailure,
|
|
726
728
|
target,
|
|
727
|
-
|
|
729
|
+
enclosingClosure: { projections: [target.type] },
|
|
728
730
|
});
|
|
729
731
|
case "hook":
|
|
730
732
|
return buildUninstallOperation(hookManager, retentionPolicy, {
|
|
731
733
|
toStepFailure: lifecycleStepFailure,
|
|
732
734
|
target,
|
|
733
|
-
|
|
735
|
+
enclosingClosure: { projections: [target.type] },
|
|
734
736
|
});
|
|
735
737
|
case "knowledge":
|
|
736
738
|
return buildUninstallOperation(knowledgeManager, retentionPolicy, {
|
|
737
739
|
toStepFailure: lifecycleStepFailure,
|
|
738
740
|
target,
|
|
739
|
-
|
|
741
|
+
enclosingClosure: { projections: [target.type] },
|
|
740
742
|
});
|
|
741
743
|
}
|
|
742
744
|
});
|
|
@@ -777,7 +779,8 @@ export const planPackInstall = Effect.fn("InstallExtensions.planPack")(function*
|
|
|
777
779
|
...droppedTargets.map(({ target }) => target.type),
|
|
778
780
|
]),
|
|
779
781
|
});
|
|
780
|
-
const graphStep = yield*
|
|
782
|
+
const graphStep = yield* buildReconciliationClosure({
|
|
783
|
+
toStepFailure: lifecycleStepFailure,
|
|
781
784
|
label: packIdentity,
|
|
782
785
|
message: `Installed ${packIdentity} and ${refs.length - 1} pack member${refs.length === 2 ? "" : "s"}`,
|
|
783
786
|
artifact: {
|
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import * as Effect from "effect/Effect";
|
|
12
12
|
import * as Option from "effect/Option";
|
|
13
|
-
import { HookManager, KnowledgeManager, NO_MATERIALIZATION_OBSERVATION, RuleManager, SkillManager, SubagentManager,
|
|
13
|
+
import { HookManager, KnowledgeManager, NO_MATERIALIZATION_OBSERVATION, RuleManager, SkillManager, SubagentManager, } from "@agentxm/extension-materialization";
|
|
14
|
+
import { installMcpServer } from "@agentxm/workspace-reconciliation";
|
|
15
|
+
import { buildInstallOperation, extensionRefLifecycleWarnings, extensionRefRegistryLifecycle, toLabelWithCompanions, } from "@agentxm/workspace-reconciliation";
|
|
14
16
|
import { WorkspaceMutations } from "@agentxm/workspace-state";
|
|
15
17
|
import { lifecycleStepFailure } from "../step-failure.js";
|
|
16
18
|
import { registrySourceArtifact } from "./artifact.js";
|
|
@@ -28,9 +30,7 @@ export const buildPackMemberInstallStep = Effect.fn("InstallExtensions.buildPack
|
|
|
28
30
|
return buildInstallOperation(skillManager, {
|
|
29
31
|
toStepFailure: lifecycleStepFailure,
|
|
30
32
|
ref,
|
|
31
|
-
|
|
32
|
-
skipSettings: true,
|
|
33
|
-
deferObservableValidation: true,
|
|
33
|
+
enclosingClosure: { projections: [], postconditions: [ref.type] },
|
|
34
34
|
installedBefore: args.graphComplete
|
|
35
35
|
? skillManager.isInstalled({ target: { type: "skill", name: ref.skill.name } })
|
|
36
36
|
: Effect.succeed(false),
|
|
@@ -55,8 +55,6 @@ export const buildPackMemberInstallStep = Effect.fn("InstallExtensions.buildPack
|
|
|
55
55
|
ref,
|
|
56
56
|
nonInteractive: args.nonInteractive,
|
|
57
57
|
force: false,
|
|
58
|
-
versionRange: Option.none(),
|
|
59
|
-
skipSettings: Option.some(true),
|
|
60
58
|
strictAgentSync: Option.some(true),
|
|
61
59
|
env: Option.none(),
|
|
62
60
|
},
|
|
@@ -82,9 +80,7 @@ export const buildPackMemberInstallStep = Effect.fn("InstallExtensions.buildPack
|
|
|
82
80
|
return buildInstallOperation(subagentManager, {
|
|
83
81
|
toStepFailure: lifecycleStepFailure,
|
|
84
82
|
ref,
|
|
85
|
-
|
|
86
|
-
skipSettings: true,
|
|
87
|
-
deferObservableValidation: true,
|
|
83
|
+
enclosingClosure: { projections: [], postconditions: [ref.type] },
|
|
88
84
|
installedBefore: args.graphComplete
|
|
89
85
|
? subagentManager.isInstalled({ target: { type: "subagent", name: ref.subagent.name } })
|
|
90
86
|
: Effect.succeed(false),
|
|
@@ -104,10 +100,7 @@ export const buildPackMemberInstallStep = Effect.fn("InstallExtensions.buildPack
|
|
|
104
100
|
return buildInstallOperation(ruleManager, {
|
|
105
101
|
toStepFailure: lifecycleStepFailure,
|
|
106
102
|
ref,
|
|
107
|
-
|
|
108
|
-
skipSettings: true,
|
|
109
|
-
skipProjections: true,
|
|
110
|
-
deferObservableValidation: true,
|
|
103
|
+
enclosingClosure: { projections: [ref.type], postconditions: [ref.type] },
|
|
111
104
|
installedBefore: args.graphComplete
|
|
112
105
|
? ruleManager.isInstalled({ target: { type: "rule", name: ref.rule.name } })
|
|
113
106
|
: Effect.succeed(false),
|
|
@@ -124,10 +117,7 @@ export const buildPackMemberInstallStep = Effect.fn("InstallExtensions.buildPack
|
|
|
124
117
|
return buildInstallOperation(hookManager, {
|
|
125
118
|
toStepFailure: lifecycleStepFailure,
|
|
126
119
|
ref,
|
|
127
|
-
|
|
128
|
-
skipSettings: true,
|
|
129
|
-
skipProjections: true,
|
|
130
|
-
deferObservableValidation: true,
|
|
120
|
+
enclosingClosure: { projections: [ref.type], postconditions: [ref.type] },
|
|
131
121
|
installedBefore: args.graphComplete
|
|
132
122
|
? hookManager.isInstalled({ target: { type: "hook", name: ref.hook.name } })
|
|
133
123
|
: Effect.succeed(false),
|
|
@@ -143,10 +133,7 @@ export const buildPackMemberInstallStep = Effect.fn("InstallExtensions.buildPack
|
|
|
143
133
|
return buildInstallOperation(knowledgeManager, {
|
|
144
134
|
toStepFailure: lifecycleStepFailure,
|
|
145
135
|
ref,
|
|
146
|
-
|
|
147
|
-
skipSettings: true,
|
|
148
|
-
skipProjections: true,
|
|
149
|
-
deferObservableValidation: true,
|
|
136
|
+
enclosingClosure: { projections: [ref.type], postconditions: [ref.type] },
|
|
150
137
|
installedBefore: args.graphComplete
|
|
151
138
|
? knowledgeManager.isInstalled({ target: { type: "knowledge", name: ref.knowledge.name } })
|
|
152
139
|
: Effect.succeed(false),
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { buildReconciliationClosure } from "@agentxm/workspace-reconciliation";
|
|
1
2
|
/**
|
|
2
3
|
* Unpacking a Pack: promoting its members to direct declarations.
|
|
3
4
|
*
|
|
@@ -22,12 +23,13 @@
|
|
|
22
23
|
import * as Effect from "effect/Effect";
|
|
23
24
|
import * as Option from "effect/Option";
|
|
24
25
|
import * as Path from "effect/Path";
|
|
25
|
-
import { PackManager
|
|
26
|
+
import { PackManager } from "@agentxm/extension-materialization";
|
|
27
|
+
import { buildUninstallOperation, } from "@agentxm/workspace-reconciliation";
|
|
26
28
|
import { operationPresentation, prepareExecutionCandidate, resolveExecutionCandidate, } from "@agentxm/workspace-operations";
|
|
27
29
|
import { WorkspaceMutations, usableAcceptedCanonical, } from "@agentxm/workspace-state";
|
|
28
30
|
import { ExtensionLifecycleFailed } from "../errors.js";
|
|
29
31
|
import { lifecycleStepFailure } from "../step-failure.js";
|
|
30
|
-
import {
|
|
32
|
+
import { validatePackGraphPostcondition } from "./graph-transition.js";
|
|
31
33
|
// -----------------------------------------------------------------------------
|
|
32
34
|
// Promotion
|
|
33
35
|
// -----------------------------------------------------------------------------
|
|
@@ -186,7 +188,8 @@ const settleUnpack = Effect.fn("PromoteAuthoredPack.prepare")(function* (request
|
|
|
186
188
|
})),
|
|
187
189
|
{ path: packDisplayPath(path, ws, packNode), change: "removed" },
|
|
188
190
|
];
|
|
189
|
-
const graphStep = yield*
|
|
191
|
+
const graphStep = yield* buildReconciliationClosure({
|
|
192
|
+
toStepFailure: lifecycleStepFailure,
|
|
190
193
|
label: packNode.identity,
|
|
191
194
|
message: `Unpacked ${packNode.identity} into ${promotions.length} direct declaration${promotions.length === 1 ? "" : "s"}`,
|
|
192
195
|
artifact: {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { buildReconciliationClosure } from "@agentxm/workspace-reconciliation";
|
|
1
2
|
/**
|
|
2
3
|
* Uninstalling packs.
|
|
3
4
|
*
|
|
@@ -13,17 +14,17 @@ import * as Effect from "effect/Effect";
|
|
|
13
14
|
import * as FileSystem from "effect/FileSystem";
|
|
14
15
|
import * as Option from "effect/Option";
|
|
15
16
|
import * as Path from "effect/Path";
|
|
16
|
-
import { HookManager, KnowledgeManager, McpServerManager, PackManager, RuleManager, SkillManager, SubagentManager,
|
|
17
|
+
import { HookManager, KnowledgeManager, McpServerManager, PackManager, RuleManager, SkillManager, SubagentManager, } from "@agentxm/extension-materialization";
|
|
18
|
+
import { buildUninstallOperation, prepareUninstallArtifact, collectCleanupStep, proposeDesiredState, } from "@agentxm/workspace-reconciliation";
|
|
17
19
|
import { parseExtensionFqnParts, } from "@agentxm/extension-model/unstable/extensions";
|
|
18
20
|
import { operationPresentation, } from "@agentxm/workspace-operations";
|
|
19
21
|
import { WorkspaceMutations, decodeDesiredExtensionIdentity, } from "@agentxm/workspace-state";
|
|
20
|
-
import { expandGlob } from "
|
|
22
|
+
import { expandGlob } from "@agentxm/extension-model/unstable/extensions/name-patterns";
|
|
21
23
|
import { lifecycleStepFailure } from "../../step-failure.js";
|
|
22
24
|
import { buildAggregateProjectionStep } from "../../install/aggregate-projection-step.js";
|
|
23
25
|
import { installRefused } from "../../install/vocabulary.js";
|
|
24
|
-
import { exclusiveMemberRetentionPolicy, makeWorkspaceRetentionPolicy, } from "
|
|
25
|
-
import {
|
|
26
|
-
import { buildAtomicPackGraphStep, validatePackGraphPostcondition } from "../graph-transition.js";
|
|
26
|
+
import { exclusiveMemberRetentionPolicy, makeWorkspaceRetentionPolicy, } from "@agentxm/workspace-reconciliation";
|
|
27
|
+
import { validatePackGraphPostcondition } from "../graph-transition.js";
|
|
27
28
|
import { PACK_UNINSTALL_GRAPH_BLOCKER_ID, planPackUninstallGraphReadiness, } from "./readiness.js";
|
|
28
29
|
const normalizedPackIdentity = (identity) => identity.startsWith("workspace:") ? identity.slice("workspace:".length) : identity;
|
|
29
30
|
const identityValidationError = (identity) => installRefused({
|
|
@@ -211,7 +212,7 @@ export const planPackUninstall = Effect.fn("UninstallExtensions.planPacks")(func
|
|
|
211
212
|
const retirement = retirementByIdentity.get(normalizedPackIdentity(pack.desiredIdentity));
|
|
212
213
|
return retirement === undefined ? [] : [[pack.name, retirement]];
|
|
213
214
|
}));
|
|
214
|
-
const retentionPolicy = makeWorkspaceRetentionPolicy(ws);
|
|
215
|
+
const retentionPolicy = makeWorkspaceRetentionPolicy(ws, lifecycleStepFailure);
|
|
215
216
|
const allTargets = new Map();
|
|
216
217
|
for (const pack of intent.packsToUninstall) {
|
|
217
218
|
allTargets.set(`pack:${pack.name}`, pack);
|
|
@@ -234,10 +235,19 @@ export const planPackUninstall = Effect.fn("UninstallExtensions.planPacks")(func
|
|
|
234
235
|
const packTargets = [...allTargets.values()].filter((target) => target.type === "pack");
|
|
235
236
|
const depTargets = [...allTargets.values()].filter((target) => target.type !== "pack");
|
|
236
237
|
const orderedTargets = [...depTargets, ...packTargets];
|
|
237
|
-
const
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
238
|
+
const proposal = yield* proposeDesiredState(intent.packsToUninstall.map((pack) => ({ kind: "remove", type: "pack", name: pack.name }))).pipe(Effect.mapError((cause) => installRefused({
|
|
239
|
+
category: "conflict",
|
|
240
|
+
detail: "Pack retirement intent could not be evaluated",
|
|
241
|
+
cause,
|
|
242
|
+
})));
|
|
243
|
+
const artifacts = yield* Effect.forEach(orderedTargets, (target) => prepareUninstallArtifact(target, proposal)).pipe(Effect.mapError((cause) => installRefused({
|
|
244
|
+
category: "conflict",
|
|
245
|
+
detail: "Pack retirement effects could not be established",
|
|
246
|
+
cause,
|
|
247
|
+
})));
|
|
248
|
+
const artifactTargets = artifacts
|
|
249
|
+
.flatMap((artifact) => artifact.targets ?? [])
|
|
250
|
+
.filter((target, index, all) => all.findIndex((candidate) => candidate.path === target.path && candidate.change === target.change) === index);
|
|
241
251
|
const steps = orderedTargets.map((target) => {
|
|
242
252
|
switch (target.type) {
|
|
243
253
|
case "pack": {
|
|
@@ -276,44 +286,66 @@ export const planPackUninstall = Effect.fn("UninstallExtensions.planPacks")(func
|
|
|
276
286
|
return buildUninstallOperation(ruleManager, exclusiveMemberRetentionPolicy, {
|
|
277
287
|
toStepFailure: lifecycleStepFailure,
|
|
278
288
|
target,
|
|
279
|
-
|
|
289
|
+
enclosingClosure: { projections: [target.type] },
|
|
280
290
|
});
|
|
281
291
|
case "hook":
|
|
282
292
|
return buildUninstallOperation(hookManager, exclusiveMemberRetentionPolicy, {
|
|
283
293
|
toStepFailure: lifecycleStepFailure,
|
|
284
294
|
target,
|
|
285
|
-
|
|
295
|
+
enclosingClosure: { projections: [target.type] },
|
|
286
296
|
});
|
|
287
297
|
case "knowledge":
|
|
288
298
|
return buildUninstallOperation(knowledgeManager, exclusiveMemberRetentionPolicy, {
|
|
289
299
|
toStepFailure: lifecycleStepFailure,
|
|
290
300
|
target,
|
|
291
|
-
|
|
301
|
+
enclosingClosure: { projections: [target.type] },
|
|
292
302
|
});
|
|
293
303
|
}
|
|
294
304
|
});
|
|
305
|
+
const activeNames = (type) => new Set(proposal.after.nodes
|
|
306
|
+
.filter((node) => node.type === type && node.enabled)
|
|
307
|
+
.map((node) => node.name));
|
|
308
|
+
const cleanup = plannedRetirements.length > 0
|
|
309
|
+
? Option.none()
|
|
310
|
+
: yield* collectCleanupStep({
|
|
311
|
+
expectedSkillNames: activeNames("skill"),
|
|
312
|
+
expectedSubagentNames: activeNames("subagent"),
|
|
313
|
+
expectedMcpServerNames: activeNames("mcp-server"),
|
|
314
|
+
expectedHookNames: activeNames("hook"),
|
|
315
|
+
subjects: orderedTargets,
|
|
316
|
+
adapter: {
|
|
317
|
+
toStepFailure: (cause) => lifecycleStepFailure(installRefused({
|
|
318
|
+
category: "conflict",
|
|
319
|
+
detail: ("detail" in cause ? cause.detail : undefined) ?? cause._tag,
|
|
320
|
+
cause,
|
|
321
|
+
})),
|
|
322
|
+
},
|
|
323
|
+
}).pipe(Effect.mapError((cause) => installRefused({
|
|
324
|
+
category: "conflict",
|
|
325
|
+
detail: "Cannot establish owned Pack uninstall outputs",
|
|
326
|
+
cause,
|
|
327
|
+
})));
|
|
295
328
|
const projectionStep = yield* buildAggregateProjectionStep({
|
|
296
329
|
types: new Set(orderedTargets.map((target) => target.type)),
|
|
297
330
|
});
|
|
298
331
|
const registrationOnly = plannedRetirements.length === 0
|
|
299
332
|
? ""
|
|
300
333
|
: ` (${plannedRetirements.length} pack${plannedRetirements.length === 1 ? "" : "s"} unregistered without removing package content)`;
|
|
301
|
-
const graphStep = yield*
|
|
334
|
+
const graphStep = yield* buildReconciliationClosure({
|
|
335
|
+
toStepFailure: lifecycleStepFailure,
|
|
302
336
|
label: `${intent.packsToUninstall.length} pack${intent.packsToUninstall.length === 1 ? "" : "s"}`,
|
|
303
337
|
message: `Uninstalled ${intent.packsToUninstall.length} pack${intent.packsToUninstall.length === 1 ? "" : "s"} and ${depTargets.length} exclusive member${depTargets.length === 1 ? "" : "s"}${registrationOnly}`,
|
|
304
338
|
artifact: {
|
|
305
|
-
path:
|
|
339
|
+
path: artifacts[0]?.path ?? path.relative(ws.baseDir, ws.layout.settingsPath),
|
|
306
340
|
scope: ws.scope,
|
|
307
341
|
change: "removed",
|
|
308
342
|
fileCount: orderedTargets.length,
|
|
309
|
-
targets:
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
// never reported as removed.
|
|
313
|
-
change: target.type === "pack" && retirementByPackName.has(target.name) ? "unchanged" : "removed",
|
|
314
|
-
})),
|
|
343
|
+
targets: artifactTargets,
|
|
344
|
+
references: artifacts.flatMap((artifact) => artifact.references ?? []),
|
|
345
|
+
managedRegions: artifacts.flatMap((artifact) => artifact.managedRegions ?? []),
|
|
315
346
|
},
|
|
316
347
|
children: [
|
|
348
|
+
...Option.toArray(cleanup).map((step) => ({ step, coverage: "ineligible" })),
|
|
317
349
|
...steps.map((step) => ({ step, coverage: "ineligible" })),
|
|
318
350
|
...Option.toArray(projectionStep).map((step) => ({
|
|
319
351
|
step,
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import * as Effect from "effect/Effect";
|
|
11
11
|
import * as Option from "effect/Option";
|
|
12
|
-
import { RuleManager
|
|
12
|
+
import { RuleManager } from "@agentxm/extension-materialization";
|
|
13
|
+
import { buildInstallOperation } from "@agentxm/workspace-reconciliation";
|
|
13
14
|
import { parseSourceQualifiedRegistrySourcePatternParts, } from "@agentxm/extension-model/unstable/extensions";
|
|
14
15
|
import { SourceHostProviders, resolveSource } from "@agentxm/extension-sources";
|
|
15
16
|
import { operationPresentation, } from "@agentxm/workspace-operations";
|
|
@@ -86,8 +87,10 @@ export const planRuleInstall = Effect.fn("InstallExtensions.planRules")(function
|
|
|
86
87
|
const memberSteps = intent.refs.map(({ ref, versionRange }) => buildInstallOperation(ruleManager, {
|
|
87
88
|
toStepFailure: lifecycleStepFailure,
|
|
88
89
|
ref,
|
|
89
|
-
versionRange,
|
|
90
|
-
|
|
90
|
+
declaration: { name: ref.rule.name, versionRange },
|
|
91
|
+
...(deferProjections
|
|
92
|
+
? { enclosingClosure: { projections: [ref.type], postconditions: [] } }
|
|
93
|
+
: {}),
|
|
91
94
|
installedBefore: ruleManager.isInstalled({
|
|
92
95
|
target: { type: "rule", name: ref.rule.name },
|
|
93
96
|
}),
|
|
@@ -8,11 +8,12 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import * as Effect from "effect/Effect";
|
|
10
10
|
import * as Option from "effect/Option";
|
|
11
|
-
import { RuleManager
|
|
11
|
+
import { RuleManager } from "@agentxm/extension-materialization";
|
|
12
|
+
import { buildUninstallOperation } from "@agentxm/workspace-reconciliation";
|
|
12
13
|
import { WorkspaceMutations } from "@agentxm/workspace-state";
|
|
13
14
|
import { lifecycleStepFailure } from "../../step-failure.js";
|
|
14
15
|
import { installRefused } from "../../install/vocabulary.js";
|
|
15
|
-
import { makeWorkspaceRetentionPolicy } from "
|
|
16
|
+
import { makeWorkspaceRetentionPolicy } from "@agentxm/workspace-reconciliation";
|
|
16
17
|
/** Settle whether this rule has anything to remove. */
|
|
17
18
|
export const parseRuleUninstallRequest = Effect.fn("UninstallExtensions.parseRuleRequest")(function* (selector) {
|
|
18
19
|
const ruleManager = yield* RuleManager;
|
|
@@ -35,7 +36,7 @@ export const parseRuleUninstallRequest = Effect.fn("UninstallExtensions.parseRul
|
|
|
35
36
|
export const planRuleUninstall = Effect.fn("UninstallExtensions.planRules")(function* (intent) {
|
|
36
37
|
const ws = yield* WorkspaceMutations;
|
|
37
38
|
const ruleManager = yield* RuleManager;
|
|
38
|
-
const retentionPolicy = makeWorkspaceRetentionPolicy(ws);
|
|
39
|
+
const retentionPolicy = makeWorkspaceRetentionPolicy(ws, lifecycleStepFailure);
|
|
39
40
|
return {
|
|
40
41
|
_tag: "Plan",
|
|
41
42
|
name: "Uninstall rule",
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skills selection application contract and workflow.
|
|
3
|
+
* @experimental This API is unstable and may change without notice.
|
|
4
|
+
*/
|
|
5
|
+
import * as Array from "effect/Array";
|
|
6
|
+
import * as Context from "effect/Context";
|
|
7
|
+
import * as Effect from "effect/Effect";
|
|
8
|
+
import type { SkillExtensionRef } from "@agentxm/extension-model/unstable/extensions/refs/skill";
|
|
9
|
+
import { type SkillSelectionRequest } from "../domain/selection.js";
|
|
10
|
+
declare const SkillSelectionNotFound_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
11
|
+
readonly _tag: "SkillSelectionNotFound";
|
|
12
|
+
} & Readonly<A>;
|
|
13
|
+
export declare class SkillSelectionNotFound extends SkillSelectionNotFound_base<{
|
|
14
|
+
readonly requested: ReadonlyArray<string>;
|
|
15
|
+
readonly available: ReadonlyArray<string>;
|
|
16
|
+
}> {
|
|
17
|
+
}
|
|
18
|
+
declare const SkillSelectionCancelled_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
19
|
+
readonly _tag: "SkillSelectionCancelled";
|
|
20
|
+
} & Readonly<A>;
|
|
21
|
+
export declare class SkillSelectionCancelled extends SkillSelectionCancelled_base<{
|
|
22
|
+
readonly message: string;
|
|
23
|
+
}> {
|
|
24
|
+
}
|
|
25
|
+
declare const SkillSelectionUnavailable_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
26
|
+
readonly _tag: "SkillSelectionUnavailable";
|
|
27
|
+
} & Readonly<A>;
|
|
28
|
+
/** The interface could not obtain a choice; this is distinct from cancellation. */
|
|
29
|
+
export declare class SkillSelectionUnavailable extends SkillSelectionUnavailable_base<{
|
|
30
|
+
readonly cause?: unknown;
|
|
31
|
+
}> {
|
|
32
|
+
}
|
|
33
|
+
declare const SkillSelectionInteraction_base: Context.ServiceClass<SkillSelectionInteraction, "@agentxm/extension-lifecycle/skills/SkillSelectionInteraction", {
|
|
34
|
+
readonly select: (candidates: Array.NonEmptyReadonlyArray<SkillExtensionRef>) => Effect.Effect<ReadonlyArray<SkillExtensionRef>, SkillSelectionCancelled | SkillSelectionUnavailable>;
|
|
35
|
+
}>;
|
|
36
|
+
export declare class SkillSelectionInteraction extends SkillSelectionInteraction_base {
|
|
37
|
+
}
|
|
38
|
+
export type SkillSelectionFailure = SkillSelectionNotFound | SkillSelectionCancelled | SkillSelectionUnavailable;
|
|
39
|
+
/** Resolve the skill-owned decision through this capability's interaction port. */
|
|
40
|
+
export declare const determineSkillsToInstall: (candidates: readonly [SkillExtensionRef, ...SkillExtensionRef[]], request: SkillSelectionRequest) => Effect.Effect<readonly SkillExtensionRef[], SkillSelectionFailure, SkillSelectionInteraction>;
|
|
41
|
+
export {};
|
|
42
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skills selection application contract and workflow.
|
|
3
|
+
* @experimental This API is unstable and may change without notice.
|
|
4
|
+
*/
|
|
5
|
+
import * as Array from "effect/Array";
|
|
6
|
+
import * as Context from "effect/Context";
|
|
7
|
+
import * as Data from "effect/Data";
|
|
8
|
+
import * as Effect from "effect/Effect";
|
|
9
|
+
import { decideSkillSelection } from "../domain/selection.js";
|
|
10
|
+
export class SkillSelectionNotFound extends Data.TaggedError("SkillSelectionNotFound") {
|
|
11
|
+
}
|
|
12
|
+
export class SkillSelectionCancelled extends Data.TaggedError("SkillSelectionCancelled") {
|
|
13
|
+
}
|
|
14
|
+
/** The interface could not obtain a choice; this is distinct from cancellation. */
|
|
15
|
+
export class SkillSelectionUnavailable extends Data.TaggedError("SkillSelectionUnavailable") {
|
|
16
|
+
}
|
|
17
|
+
export class SkillSelectionInteraction extends Context.Service()("@agentxm/extension-lifecycle/skills/SkillSelectionInteraction") {
|
|
18
|
+
}
|
|
19
|
+
/** Resolve the skill-owned decision through this capability's interaction port. */
|
|
20
|
+
export const determineSkillsToInstall = Effect.fn("Skills.determineSelection")(function* (candidates, request) {
|
|
21
|
+
const names = Array.map(candidates, (ref) => ref.skill.name);
|
|
22
|
+
const decision = decideSkillSelection(names, request);
|
|
23
|
+
switch (decision.kind) {
|
|
24
|
+
case "selected":
|
|
25
|
+
return candidates.filter((ref) => decision.names.includes(ref.skill.name));
|
|
26
|
+
case "unmatched":
|
|
27
|
+
return yield* new SkillSelectionNotFound({
|
|
28
|
+
requested: request.requestedSkills,
|
|
29
|
+
available: names,
|
|
30
|
+
});
|
|
31
|
+
case "choice-required": {
|
|
32
|
+
const interaction = yield* SkillSelectionInteraction;
|
|
33
|
+
return yield* interaction.select(candidates);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type * as Array from "effect/Array";
|
|
2
|
+
export interface SkillSelectionRequest {
|
|
3
|
+
readonly requestedSkills: ReadonlyArray<string>;
|
|
4
|
+
readonly all: boolean;
|
|
5
|
+
readonly nonInteractive: boolean;
|
|
6
|
+
}
|
|
7
|
+
export type SkillSelectionDecision = {
|
|
8
|
+
readonly kind: "selected";
|
|
9
|
+
readonly names: ReadonlyArray<string>;
|
|
10
|
+
} | {
|
|
11
|
+
readonly kind: "choice-required";
|
|
12
|
+
} | {
|
|
13
|
+
readonly kind: "unmatched";
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Select this request's skills, preserving source order.
|
|
17
|
+
* Named patterns take precedence over all/unattended selection. The existing
|
|
18
|
+
* union-of-matches behavior is retained; unresolved selector requirements remain
|
|
19
|
+
* explicit in the installation specification.
|
|
20
|
+
*/
|
|
21
|
+
export declare const decideSkillSelection: (names: Array.NonEmptyReadonlyArray<string>, request: SkillSelectionRequest) => SkillSelectionDecision;
|
|
22
|
+
//# sourceMappingURL=selection.d.ts.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { expandGlobs } from "@agentxm/extension-model/unstable/extensions/name-patterns";
|
|
2
|
+
/**
|
|
3
|
+
* Select this request's skills, preserving source order.
|
|
4
|
+
* Named patterns take precedence over all/unattended selection. The existing
|
|
5
|
+
* union-of-matches behavior is retained; unresolved selector requirements remain
|
|
6
|
+
* explicit in the installation specification.
|
|
7
|
+
*/
|
|
8
|
+
export const decideSkillSelection = (names, request) => {
|
|
9
|
+
if (request.requestedSkills.length > 0) {
|
|
10
|
+
const matched = expandGlobs(request.requestedSkills, names);
|
|
11
|
+
return matched.length === 0 ? { kind: "unmatched" } : { kind: "selected", names: matched };
|
|
12
|
+
}
|
|
13
|
+
if (request.all || request.nonInteractive || names.length === 1) {
|
|
14
|
+
return { kind: "selected", names };
|
|
15
|
+
}
|
|
16
|
+
return { kind: "choice-required" };
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=selection.js.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { SkillExtensionRef } from "@agentxm/extension-model/unstable/extensions/refs/skill";
|
|
2
|
+
import type { JobStepArtifactSource } from "@agentxm/workspace-operations";
|
|
3
|
+
export declare const gitHostedSkillArtifactSource: (ref: SkillExtensionRef) => JobStepArtifactSource | undefined;
|
|
4
|
+
//# sourceMappingURL=artifact.d.ts.map
|