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