@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
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Installing what the workspace already declares.
|
|
3
|
+
*
|
|
4
|
+
* `axm install` with no source, and every `<type> install` with no source, ask
|
|
5
|
+
* the same question: bring the workspace to the state its settings describe.
|
|
6
|
+
* Each enabled configured entry resolves to the version its declared source
|
|
7
|
+
* and the release-age policy allow, becomes its own closure, and the shared
|
|
8
|
+
* aggregate projections are rendered once at the end from the complete
|
|
9
|
+
* contributor set. A member reached twice — declared directly and required by
|
|
10
|
+
* a pack — is installed once, from the direct declaration.
|
|
11
|
+
*
|
|
12
|
+
* @experimental This API is unstable and may change without notice.
|
|
13
|
+
*/
|
|
14
|
+
import * as Effect from "effect/Effect";
|
|
15
|
+
import * as Option from "effect/Option";
|
|
16
|
+
import { HookManager, KnowledgeManager, McpServerManager, PackManager, RuleManager, SkillManager, SubagentManager } from "@agentxm/extension-materialization";
|
|
17
|
+
import { type InstallableExtensionType } from "@agentxm/extension-model/unstable/extensions/installable-types";
|
|
18
|
+
import { ReleaseAgePosture, ExtensionResolutionFailed } from "@agentxm/extension-resolution";
|
|
19
|
+
import { type ConfiguredAgentOperation, type Plan } from "@agentxm/workspace-operations";
|
|
20
|
+
import type { ExtensionLifecycleFailed } from "../errors.js";
|
|
21
|
+
import { type PackInstallRequirements } from "../packs/install/plan.js";
|
|
22
|
+
import { type InstallStepRequirements, type ResolveInstallRequirements } from "./vocabulary.js";
|
|
23
|
+
/** Which extension types a configured-entry sweep covers. */
|
|
24
|
+
export type ConfiguredInstallableType = InstallableExtensionType;
|
|
25
|
+
/** What a configured-entry sweep settled: a plan, or nothing to do. */
|
|
26
|
+
export type ConfiguredInstallPlanResult = {
|
|
27
|
+
readonly _tag: "NoConfiguredExtensions";
|
|
28
|
+
readonly message: string;
|
|
29
|
+
} | {
|
|
30
|
+
readonly _tag: "ConfiguredInstallPlan";
|
|
31
|
+
readonly plan: Plan<InstallStepRequirements>;
|
|
32
|
+
readonly configuredAgentOperations: ReadonlyArray<ConfiguredAgentOperation>;
|
|
33
|
+
};
|
|
34
|
+
/** Everything a configured-entry sweep reads before it freezes a candidate. */
|
|
35
|
+
export type ConfiguredInstallRequirements = InstallStepRequirements | PackInstallRequirements | ResolveInstallRequirements | ReleaseAgePosture | HookManager | KnowledgeManager | McpServerManager | PackManager | RuleManager | SkillManager | SubagentManager;
|
|
36
|
+
/**
|
|
37
|
+
* Every failure settling the configured closure can surface: this feature's
|
|
38
|
+
* own refusal, plus the resolution refusal a configured entry's source
|
|
39
|
+
* carries through with its own category and sentence.
|
|
40
|
+
*/
|
|
41
|
+
export type ConfiguredInstallFailure = ExtensionLifecycleFailed | ExtensionResolutionFailed;
|
|
42
|
+
/**
|
|
43
|
+
* Build the configured Pack graph as one recovery candidate.
|
|
44
|
+
*
|
|
45
|
+
* Recovery only runs for Packs whose observed tree already diverged from the
|
|
46
|
+
* accepted resolution, so the installed tree is never reused.
|
|
47
|
+
*/
|
|
48
|
+
/** Which configured packs a recovery rebuilds, and what to call the operation. */
|
|
49
|
+
export interface ConfiguredPackRecoveryRequest {
|
|
50
|
+
readonly planName: string;
|
|
51
|
+
readonly planDescription: Option.Option<string>;
|
|
52
|
+
readonly packNames: ReadonlySet<string>;
|
|
53
|
+
readonly nonInteractive: boolean;
|
|
54
|
+
}
|
|
55
|
+
export declare const buildConfiguredPackInstallPlan: (args: ConfiguredPackRecoveryRequest) => Effect.Effect<ConfiguredInstallPlanResult, ConfiguredInstallFailure, ConfiguredInstallRequirements>;
|
|
56
|
+
/** Plan the install of every enabled configured entry, or of one type's. */
|
|
57
|
+
/** Which configured entries a sweep covers, and what to call the operation. */
|
|
58
|
+
export interface ConfiguredInstallRequest {
|
|
59
|
+
readonly type: Option.Option<ConfiguredInstallableType>;
|
|
60
|
+
readonly planName: string;
|
|
61
|
+
readonly planDescription: Option.Option<string>;
|
|
62
|
+
readonly nonInteractive: boolean;
|
|
63
|
+
}
|
|
64
|
+
export declare const buildConfiguredInstallPlan: (args: ConfiguredInstallRequest) => Effect.Effect<ConfiguredInstallPlanResult, ConfiguredInstallFailure, ConfiguredInstallRequirements>;
|
|
65
|
+
//# sourceMappingURL=configured.d.ts.map
|
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Installing what the workspace already declares.
|
|
3
|
+
*
|
|
4
|
+
* `axm install` with no source, and every `<type> install` with no source, ask
|
|
5
|
+
* the same question: bring the workspace to the state its settings describe.
|
|
6
|
+
* Each enabled configured entry resolves to the version its declared source
|
|
7
|
+
* and the release-age policy allow, becomes its own closure, and the shared
|
|
8
|
+
* aggregate projections are rendered once at the end from the complete
|
|
9
|
+
* contributor set. A member reached twice — declared directly and required by
|
|
10
|
+
* a pack — is installed once, from the direct declaration.
|
|
11
|
+
*
|
|
12
|
+
* @experimental This API is unstable and may change without notice.
|
|
13
|
+
*/
|
|
14
|
+
import * as DateTime from "effect/DateTime";
|
|
15
|
+
import * as Effect from "effect/Effect";
|
|
16
|
+
import * as Option from "effect/Option";
|
|
17
|
+
import { HookManager, KnowledgeManager, McpServerManager, PackManager, RuleManager, SkillManager, SubagentManager, } from "@agentxm/extension-materialization";
|
|
18
|
+
import { decodeExtensionNameSync, extensionTypePluralSentenceLabels, parseRegistrySourceRef, } from "@agentxm/extension-model/unstable/extensions";
|
|
19
|
+
import { installableExtensionTypes, toInstallableExtensionTypePlural, } from "@agentxm/extension-model/unstable/extensions/installable-types";
|
|
20
|
+
import { ReleaseAgePosture, acceptedPackDependencyResolver, ExtensionResolutionFailed, hydrateAcceptedPackRef, makeConfiguredReleaseAgeEvaluation, normalizeReleaseAgeRecords, resolveConfiguredHook, resolveConfiguredKnowledge, resolveConfiguredMcpServer, resolveConfiguredPack, resolveConfiguredRule, resolveConfiguredSkill, resolveConfiguredSubagent, } from "@agentxm/extension-resolution";
|
|
21
|
+
import { operationPresentation, } from "@agentxm/workspace-operations";
|
|
22
|
+
import { WorkspaceMutations, acceptedResolutionRef, enabledConfiguredEntries, } from "@agentxm/workspace-state";
|
|
23
|
+
import { planHookInstall } from "../hooks/install/plan.js";
|
|
24
|
+
import { planKnowledgeInstall } from "../knowledge/install/plan.js";
|
|
25
|
+
import { planMcpServerInstall } from "../mcps/install/plan.js";
|
|
26
|
+
import { planPackInstall } from "../packs/install/plan.js";
|
|
27
|
+
import { configuredPackConstraintBlockPlan, prospectivePackConstraintProblems, } from "../packs/constraint-gate.js";
|
|
28
|
+
import { planRuleInstall } from "../rules/install/plan.js";
|
|
29
|
+
import { planSkillInstall } from "../skills/install/plan.js";
|
|
30
|
+
import { planSubagentInstall } from "../subagents/install/plan.js";
|
|
31
|
+
import { buildAggregateProjectionStep } from "./aggregate-projection-step.js";
|
|
32
|
+
import { inlineMcpNotApplicablePlan } from "./inline-mcp-operation.js";
|
|
33
|
+
import { installRefused, } from "./vocabulary.js";
|
|
34
|
+
/**
|
|
35
|
+
* The configured-agent operations this sweep projects and verifies. A step's
|
|
36
|
+
* label carries the extension name the operation is about; the collector that
|
|
37
|
+
* produced it carries the type.
|
|
38
|
+
*/
|
|
39
|
+
const configuredAgentOperationsFrom = (collections) => {
|
|
40
|
+
const operations = new Map();
|
|
41
|
+
for (const { type, collection } of collections) {
|
|
42
|
+
for (const fragment of collection.fragments) {
|
|
43
|
+
if (fragment.key.startsWith("not-applicable:"))
|
|
44
|
+
continue;
|
|
45
|
+
const name = fragment.step.label.replace(/^(?:Install|Reinstall|Skip|Update)\s+/u, "");
|
|
46
|
+
operations.set(`${type}:${name}`, { extensionType: type, name, plannedState: "enabled" });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return [...operations.values()];
|
|
50
|
+
};
|
|
51
|
+
const noConfiguredMessage = (type) => Option.match(type, {
|
|
52
|
+
onNone: () => "No configured extensions.",
|
|
53
|
+
onSome: (value) => `No configured ${extensionTypePluralSentenceLabels[toInstallableExtensionTypePlural(value)]}.`,
|
|
54
|
+
});
|
|
55
|
+
const flattenPlanSteps = (plan) => plan.jobs.flatMap((job) => job.steps);
|
|
56
|
+
const toCollectedPlans = ({ plans, holdbacks = [], bypasses = [], originForStep = () => "direct", }) => ({
|
|
57
|
+
plans,
|
|
58
|
+
holdbacks: [...holdbacks, ...plans.flatMap((plan) => plan.releaseAge?.holdbacks ?? [])],
|
|
59
|
+
bypasses: [...bypasses, ...plans.flatMap((plan) => plan.releaseAge?.bypasses ?? [])],
|
|
60
|
+
fragments: plans.flatMap((plan) => flattenPlanSteps(plan).map((step, index) => ({
|
|
61
|
+
key: step.key ?? step.label,
|
|
62
|
+
origin: originForStep(index),
|
|
63
|
+
step,
|
|
64
|
+
}))),
|
|
65
|
+
});
|
|
66
|
+
const attachConfiguredReleaseAge = (plan, evaluation, releaseAge) => releaseAge === undefined
|
|
67
|
+
? plan
|
|
68
|
+
: {
|
|
69
|
+
...plan,
|
|
70
|
+
releaseAge: {
|
|
71
|
+
evaluatedAt: DateTime.formatIso(evaluation.evaluatedAt),
|
|
72
|
+
holdbacks: normalizeReleaseAgeRecords([
|
|
73
|
+
...releaseAge.holdbacks,
|
|
74
|
+
...(plan.releaseAge?.holdbacks ?? []),
|
|
75
|
+
]),
|
|
76
|
+
bypasses: normalizeReleaseAgeRecords([
|
|
77
|
+
...releaseAge.bypasses,
|
|
78
|
+
...(plan.releaseAge?.bypasses ?? []),
|
|
79
|
+
]),
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* One member declared directly and also required by a pack is installed from
|
|
84
|
+
* the direct declaration: the person who wrote it down chose that version.
|
|
85
|
+
*/
|
|
86
|
+
const mergeFragments = (collections) => {
|
|
87
|
+
const byKey = new Map();
|
|
88
|
+
for (const fragment of collections.flatMap((collection) => collection.fragments)) {
|
|
89
|
+
const existing = byKey.get(fragment.key);
|
|
90
|
+
if (existing === undefined) {
|
|
91
|
+
byKey.set(fragment.key, fragment);
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (existing.origin === "dependency" && fragment.origin === "direct") {
|
|
95
|
+
byKey.set(fragment.key, fragment);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return [...byKey.values()];
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* A resolution refusal already carries its own category and fact sentence —
|
|
102
|
+
* a held release, an unsatisfiable constraint, a blocked source authority —
|
|
103
|
+
* so it travels unchanged rather than being replaced with a generic conflict
|
|
104
|
+
* the operator cannot act on. Anything else becomes this feature's refusal,
|
|
105
|
+
* naming the configured entry that could not be resolved.
|
|
106
|
+
*/
|
|
107
|
+
const resolutionFailed = (name) => (cause) => cause instanceof ExtensionResolutionFailed
|
|
108
|
+
? cause
|
|
109
|
+
: installRefused({
|
|
110
|
+
category: "conflict",
|
|
111
|
+
detail: `Configured extension "${name}" could not be resolved`,
|
|
112
|
+
cause,
|
|
113
|
+
});
|
|
114
|
+
const resolvePackIntent = Effect.fn("InstallExtensions.resolveConfiguredPackIntent")(function* (args) {
|
|
115
|
+
const ws = yield* WorkspaceMutations;
|
|
116
|
+
const accepted = yield* acceptedResolutionRef({
|
|
117
|
+
workspace: ws,
|
|
118
|
+
type: "pack",
|
|
119
|
+
name: args.name,
|
|
120
|
+
}).pipe(Effect.mapError(resolutionFailed(args.name)));
|
|
121
|
+
const shared = {
|
|
122
|
+
unattended: true,
|
|
123
|
+
nonInteractive: args.nonInteractive,
|
|
124
|
+
releaseAgeEvaluation: args.releaseAgeEvaluation,
|
|
125
|
+
releaseAgeHoldbackBehavior: "preserve-or-block",
|
|
126
|
+
...(args.forceCanonical === true ? { forceCanonical: true } : {}),
|
|
127
|
+
...(args.deferProjections === true ? { deferProjections: true } : {}),
|
|
128
|
+
};
|
|
129
|
+
if (Option.isSome(accepted) && accepted.value.type === "pack") {
|
|
130
|
+
const packToInstall = yield* hydrateAcceptedPackRef(args.name, accepted.value);
|
|
131
|
+
return {
|
|
132
|
+
intent: {
|
|
133
|
+
packToInstall,
|
|
134
|
+
versionRange: Option.fromUndefinedOr(parseRegistrySourceRef(args.source)?.versionRange),
|
|
135
|
+
dependencyResolver: acceptedPackDependencyResolver(),
|
|
136
|
+
...shared,
|
|
137
|
+
},
|
|
138
|
+
releaseAge: undefined,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
const resolved = yield* resolveConfiguredPack(args.name, args.source, args.releaseAgeEvaluation).pipe(Effect.mapError(resolutionFailed(args.name)));
|
|
142
|
+
return {
|
|
143
|
+
intent: {
|
|
144
|
+
packToInstall: resolved.ref,
|
|
145
|
+
versionRange: resolved.versionRange,
|
|
146
|
+
...shared,
|
|
147
|
+
},
|
|
148
|
+
releaseAge: "releaseAge" in resolved ? resolved.releaseAge : undefined,
|
|
149
|
+
};
|
|
150
|
+
});
|
|
151
|
+
const collectPackPlans = Effect.fn("InstallExtensions.collectConfiguredPacks")(function* (args) {
|
|
152
|
+
const ws = yield* WorkspaceMutations;
|
|
153
|
+
const configured = yield* ws.getConfiguredPackEntries().pipe(Effect.mapError((cause) => installRefused({
|
|
154
|
+
category: "internal",
|
|
155
|
+
detail: "Configured packs could not be read",
|
|
156
|
+
cause,
|
|
157
|
+
})));
|
|
158
|
+
const entries = enabledConfiguredEntries(configured).filter(([name]) => args.selectedNames === undefined || args.selectedNames.has(name));
|
|
159
|
+
const resolvedPacks = yield* Effect.forEach(entries, ([name, entry]) => resolvePackIntent({
|
|
160
|
+
name,
|
|
161
|
+
source: entry.source,
|
|
162
|
+
releaseAgeEvaluation: args.releaseAgeEvaluation,
|
|
163
|
+
nonInteractive: args.nonInteractive,
|
|
164
|
+
...(args.forceCanonical === undefined ? {} : { forceCanonical: args.forceCanonical }),
|
|
165
|
+
...(args.deferProjections === undefined ? {} : { deferProjections: args.deferProjections }),
|
|
166
|
+
}), { concurrency: "unbounded" });
|
|
167
|
+
const prospectivePacks = resolvedPacks.map(({ intent }) => intent.packToInstall);
|
|
168
|
+
const constraintProblems = yield* prospectivePackConstraintProblems({
|
|
169
|
+
workspace: ws,
|
|
170
|
+
prospectivePacks,
|
|
171
|
+
...(args.selectedNames === undefined ? {} : { selectedNames: args.selectedNames }),
|
|
172
|
+
}).pipe(Effect.mapError((cause) => installRefused({
|
|
173
|
+
category: "internal",
|
|
174
|
+
detail: "Prospective pack constraints could not be evaluated",
|
|
175
|
+
cause,
|
|
176
|
+
})));
|
|
177
|
+
const releaseAge = resolvedPacks.flatMap(({ releaseAge }) => releaseAge === undefined ? [] : [releaseAge]);
|
|
178
|
+
if (constraintProblems.length > 0) {
|
|
179
|
+
return toCollectedPlans({
|
|
180
|
+
plans: [
|
|
181
|
+
configuredPackConstraintBlockPlan({ operation: "install", problems: constraintProblems }),
|
|
182
|
+
],
|
|
183
|
+
holdbacks: releaseAge.flatMap((record) => record.holdbacks),
|
|
184
|
+
bypasses: releaseAge.flatMap((record) => record.bypasses),
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
const plans = yield* Effect.forEach(resolvedPacks, ({ intent, releaseAge }) => planPackInstall(intent).pipe(Effect.map((plan) => attachConfiguredReleaseAge(plan, args.releaseAgeEvaluation, releaseAge))), { concurrency: "unbounded" });
|
|
188
|
+
// A pack's own step comes first; everything after it is a member the pack
|
|
189
|
+
// brought in, and a direct declaration of that member wins over it.
|
|
190
|
+
return toCollectedPlans({
|
|
191
|
+
plans,
|
|
192
|
+
originForStep: (index) => (index === 0 ? "direct" : "dependency"),
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
const collectSimpleTypePlans = (type, releaseAgeEvaluation, nonInteractive) => Effect.gen(function* () {
|
|
196
|
+
const ws = yield* WorkspaceMutations;
|
|
197
|
+
const readFailed = (cause) => installRefused({
|
|
198
|
+
category: "internal",
|
|
199
|
+
detail: `Configured ${type} entries could not be read`,
|
|
200
|
+
cause,
|
|
201
|
+
});
|
|
202
|
+
const planFor = (name, source) => {
|
|
203
|
+
switch (type) {
|
|
204
|
+
case "skill":
|
|
205
|
+
return resolveConfiguredSkill(name, source, releaseAgeEvaluation).pipe(Effect.mapError(resolutionFailed(name)), Effect.flatMap((resolved) => planSkillInstall({
|
|
206
|
+
skillsToInstall: [{ ref: resolved.ref, versionRange: resolved.versionRange }],
|
|
207
|
+
}).pipe(Effect.map((plan) => attachConfiguredReleaseAge(plan, releaseAgeEvaluation, "releaseAge" in resolved ? resolved.releaseAge : undefined)))));
|
|
208
|
+
case "subagent":
|
|
209
|
+
return resolveConfiguredSubagent(name, source, releaseAgeEvaluation).pipe(Effect.mapError(resolutionFailed(name)), Effect.flatMap((resolved) => planSubagentInstall({
|
|
210
|
+
subagentsToInstall: [{ ref: resolved.ref, versionRange: resolved.versionRange }],
|
|
211
|
+
}).pipe(Effect.map((plan) => attachConfiguredReleaseAge(plan, releaseAgeEvaluation, "releaseAge" in resolved ? resolved.releaseAge : undefined)))));
|
|
212
|
+
case "rule":
|
|
213
|
+
return resolveConfiguredRule(name, source, releaseAgeEvaluation).pipe(Effect.mapError(resolutionFailed(name)), Effect.flatMap((resolved) => planRuleInstall({
|
|
214
|
+
refs: [{ ref: resolved.ref, versionRange: resolved.versionRange }],
|
|
215
|
+
deferProjections: true,
|
|
216
|
+
}).pipe(Effect.map((plan) => attachConfiguredReleaseAge(plan, releaseAgeEvaluation, "releaseAge" in resolved ? resolved.releaseAge : undefined)))));
|
|
217
|
+
case "hook":
|
|
218
|
+
return resolveConfiguredHook(name, source, releaseAgeEvaluation).pipe(Effect.mapError(resolutionFailed(name)), Effect.flatMap((resolved) => planHookInstall({
|
|
219
|
+
refs: [{ ref: resolved.ref, versionRange: resolved.versionRange }],
|
|
220
|
+
deferProjections: true,
|
|
221
|
+
}).pipe(Effect.map((plan) => attachConfiguredReleaseAge(plan, releaseAgeEvaluation, "releaseAge" in resolved ? resolved.releaseAge : undefined)))));
|
|
222
|
+
case "knowledge":
|
|
223
|
+
return resolveConfiguredKnowledge(name, source, releaseAgeEvaluation).pipe(Effect.mapError(resolutionFailed(name)), Effect.flatMap((resolved) => planKnowledgeInstall({
|
|
224
|
+
refs: [{ ref: resolved.ref, versionRange: resolved.versionRange }],
|
|
225
|
+
deferProjections: true,
|
|
226
|
+
}).pipe(Effect.map((plan) => attachConfiguredReleaseAge(plan, releaseAgeEvaluation, "releaseAge" in resolved ? resolved.releaseAge : undefined)))));
|
|
227
|
+
case "mcp-server":
|
|
228
|
+
return resolveConfiguredMcpServer(name, source, releaseAgeEvaluation).pipe(Effect.mapError(resolutionFailed(name)), Effect.flatMap((resolved) => planMcpServerInstall({
|
|
229
|
+
ref: resolved.ref,
|
|
230
|
+
localName: decodeExtensionNameSync(name),
|
|
231
|
+
versionRange: resolved.versionRange,
|
|
232
|
+
force: false,
|
|
233
|
+
nonInteractive,
|
|
234
|
+
}).pipe(Effect.map((plan) => attachConfiguredReleaseAge(plan, releaseAgeEvaluation, "releaseAge" in resolved ? resolved.releaseAge : undefined)))));
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
switch (type) {
|
|
238
|
+
case "skill": {
|
|
239
|
+
const configured = yield* ws.getConfiguredSkillEntries().pipe(Effect.mapError(readFailed));
|
|
240
|
+
// A bundled skill is shipped with the CLI, not acquired from a source.
|
|
241
|
+
const entries = enabledConfiguredEntries(configured).filter(([, entry]) => entry.origin !== "bundled");
|
|
242
|
+
return toCollectedPlans({
|
|
243
|
+
plans: yield* Effect.forEach(entries, ([name, entry]) => planFor(name, entry.source), {
|
|
244
|
+
concurrency: "unbounded",
|
|
245
|
+
}),
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
case "subagent": {
|
|
249
|
+
const configured = yield* ws
|
|
250
|
+
.getConfiguredSubagentEntries()
|
|
251
|
+
.pipe(Effect.mapError(readFailed));
|
|
252
|
+
return toCollectedPlans({
|
|
253
|
+
plans: yield* Effect.forEach(enabledConfiguredEntries(configured), ([name, entry]) => planFor(name, entry.source), { concurrency: "unbounded" }),
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
case "rule": {
|
|
257
|
+
const configured = yield* ws.getConfiguredRuleEntries().pipe(Effect.mapError(readFailed));
|
|
258
|
+
return toCollectedPlans({
|
|
259
|
+
plans: yield* Effect.forEach(enabledConfiguredEntries(configured), ([name, entry]) => planFor(name, entry.source), { concurrency: "unbounded" }),
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
case "hook": {
|
|
263
|
+
const configured = yield* ws.getConfiguredHookEntries().pipe(Effect.mapError(readFailed));
|
|
264
|
+
return toCollectedPlans({
|
|
265
|
+
plans: yield* Effect.forEach(enabledConfiguredEntries(configured), ([name, entry]) => planFor(name, entry.source), { concurrency: "unbounded" }),
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
case "knowledge": {
|
|
269
|
+
const configured = yield* ws
|
|
270
|
+
.getConfiguredKnowledgeEntries()
|
|
271
|
+
.pipe(Effect.mapError(readFailed));
|
|
272
|
+
return toCollectedPlans({
|
|
273
|
+
plans: yield* Effect.forEach(enabledConfiguredEntries(configured), ([name, entry]) => planFor(name, entry.source), { concurrency: "unbounded" }),
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
case "mcp-server": {
|
|
277
|
+
const configured = yield* ws
|
|
278
|
+
.getConfiguredMcpServerEntries()
|
|
279
|
+
.pipe(Effect.mapError(readFailed));
|
|
280
|
+
return toCollectedPlans({
|
|
281
|
+
plans: yield* Effect.forEach(enabledConfiguredEntries(configured), ([name, entry]) =>
|
|
282
|
+
// An inline connection is workspace configuration, not an
|
|
283
|
+
// acquired package: `axm sync` reconciles it, install does not.
|
|
284
|
+
entry.kind === "inline"
|
|
285
|
+
? Effect.succeed(inlineMcpNotApplicablePlan(name, "install"))
|
|
286
|
+
: planFor(name, entry.source), { concurrency: "unbounded" }),
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
export const buildConfiguredPackInstallPlan = Effect.fn("InstallExtensions.buildConfiguredPackInstallPlan")(function* (args) {
|
|
292
|
+
const releaseAgeEvaluation = yield* makeConfiguredReleaseAgeEvaluation().pipe(Effect.mapError((cause) => installRefused({
|
|
293
|
+
category: "internal",
|
|
294
|
+
detail: "Release-age policy could not be evaluated",
|
|
295
|
+
cause,
|
|
296
|
+
})));
|
|
297
|
+
const collection = yield* collectPackPlans({
|
|
298
|
+
releaseAgeEvaluation,
|
|
299
|
+
nonInteractive: args.nonInteractive,
|
|
300
|
+
selectedNames: args.packNames,
|
|
301
|
+
forceCanonical: true,
|
|
302
|
+
});
|
|
303
|
+
const fragments = mergeFragments([collection]);
|
|
304
|
+
if (fragments.length === 0) {
|
|
305
|
+
const nothingConfigured = {
|
|
306
|
+
_tag: "NoConfiguredExtensions",
|
|
307
|
+
message: noConfiguredMessage(Option.some("pack")),
|
|
308
|
+
};
|
|
309
|
+
return nothingConfigured;
|
|
310
|
+
}
|
|
311
|
+
const holdbacks = normalizeReleaseAgeRecords(collection.holdbacks);
|
|
312
|
+
const bypasses = normalizeReleaseAgeRecords(collection.bypasses);
|
|
313
|
+
const settled = {
|
|
314
|
+
_tag: "ConfiguredInstallPlan",
|
|
315
|
+
plan: {
|
|
316
|
+
_tag: "Plan",
|
|
317
|
+
name: args.planName,
|
|
318
|
+
description: args.planDescription,
|
|
319
|
+
presentation: operationPresentation({ imperative: "install", past: "Installed", gerund: "Installing" }, "pack"),
|
|
320
|
+
jobs: [{ concurrency: 1, steps: fragments.map((fragment) => fragment.step) }],
|
|
321
|
+
...(holdbacks.length === 0 && bypasses.length === 0
|
|
322
|
+
? {}
|
|
323
|
+
: {
|
|
324
|
+
releaseAge: {
|
|
325
|
+
evaluatedAt: DateTime.formatIso(releaseAgeEvaluation.evaluatedAt),
|
|
326
|
+
holdbacks,
|
|
327
|
+
bypasses,
|
|
328
|
+
},
|
|
329
|
+
}),
|
|
330
|
+
},
|
|
331
|
+
configuredAgentOperations: [...args.packNames].map((name) => ({
|
|
332
|
+
extensionType: "pack",
|
|
333
|
+
name,
|
|
334
|
+
plannedState: "enabled",
|
|
335
|
+
})),
|
|
336
|
+
};
|
|
337
|
+
return settled;
|
|
338
|
+
});
|
|
339
|
+
export const buildConfiguredInstallPlan = Effect.fn("InstallExtensions.buildConfiguredInstallPlan")(function* (args) {
|
|
340
|
+
const releaseAgeEvaluation = yield* makeConfiguredReleaseAgeEvaluation().pipe(Effect.mapError((cause) => installRefused({
|
|
341
|
+
category: "internal",
|
|
342
|
+
detail: "Release-age policy could not be evaluated",
|
|
343
|
+
cause,
|
|
344
|
+
})));
|
|
345
|
+
const selectedTypes = installableExtensionTypes.filter((type) => Option.match(args.type, { onNone: () => true, onSome: (value) => value === type }));
|
|
346
|
+
const collections = yield* Effect.forEach(selectedTypes, (type) => (type === "pack"
|
|
347
|
+
? collectPackPlans({
|
|
348
|
+
releaseAgeEvaluation,
|
|
349
|
+
nonInteractive: args.nonInteractive,
|
|
350
|
+
deferProjections: true,
|
|
351
|
+
})
|
|
352
|
+
: collectSimpleTypePlans(type, releaseAgeEvaluation, args.nonInteractive)).pipe(Effect.map((collection) => ({ type, collection }))), { concurrency: "unbounded" });
|
|
353
|
+
const fragments = mergeFragments(collections.map(({ collection }) => collection));
|
|
354
|
+
if (fragments.length === 0) {
|
|
355
|
+
const nothingConfigured = {
|
|
356
|
+
_tag: "NoConfiguredExtensions",
|
|
357
|
+
message: noConfiguredMessage(args.type),
|
|
358
|
+
};
|
|
359
|
+
return nothingConfigured;
|
|
360
|
+
}
|
|
361
|
+
// A pack contributes rules, hooks, and knowledge bundles, so its presence
|
|
362
|
+
// implies all three aggregate units may need re-rendering.
|
|
363
|
+
const aggregateTypes = new Set();
|
|
364
|
+
for (const { type, collection } of collections) {
|
|
365
|
+
if (collection.fragments.length === 0)
|
|
366
|
+
continue;
|
|
367
|
+
if (type === "pack") {
|
|
368
|
+
aggregateTypes.add("rule");
|
|
369
|
+
aggregateTypes.add("hook");
|
|
370
|
+
aggregateTypes.add("knowledge");
|
|
371
|
+
}
|
|
372
|
+
else if (type === "rule" || type === "hook" || type === "knowledge") {
|
|
373
|
+
aggregateTypes.add(type);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
const projectionStep = yield* buildAggregateProjectionStep({ types: aggregateTypes });
|
|
377
|
+
const holdbacks = normalizeReleaseAgeRecords(collections.flatMap(({ collection }) => collection.holdbacks));
|
|
378
|
+
const bypasses = normalizeReleaseAgeRecords(collections.flatMap(({ collection }) => collection.bypasses));
|
|
379
|
+
const settled = {
|
|
380
|
+
_tag: "ConfiguredInstallPlan",
|
|
381
|
+
plan: {
|
|
382
|
+
_tag: "Plan",
|
|
383
|
+
name: args.planName,
|
|
384
|
+
description: args.planDescription,
|
|
385
|
+
presentation: operationPresentation({ imperative: "install", past: "Installed", gerund: "Installing" }, Option.getOrUndefined(args.type)),
|
|
386
|
+
jobs: [
|
|
387
|
+
{
|
|
388
|
+
concurrency: 1,
|
|
389
|
+
steps: [...fragments.map((fragment) => fragment.step), ...Option.toArray(projectionStep)],
|
|
390
|
+
},
|
|
391
|
+
],
|
|
392
|
+
...(holdbacks.length === 0 && bypasses.length === 0
|
|
393
|
+
? {}
|
|
394
|
+
: {
|
|
395
|
+
releaseAge: {
|
|
396
|
+
evaluatedAt: DateTime.formatIso(releaseAgeEvaluation.evaluatedAt),
|
|
397
|
+
holdbacks,
|
|
398
|
+
bypasses,
|
|
399
|
+
},
|
|
400
|
+
}),
|
|
401
|
+
},
|
|
402
|
+
configuredAgentOperations: configuredAgentOperationsFrom(collections),
|
|
403
|
+
};
|
|
404
|
+
return settled;
|
|
405
|
+
});
|
|
406
|
+
//# sourceMappingURL=configured.js.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { InstallStepRequirements } from "./vocabulary.js";
|
|
2
|
+
import type { Plan } from "@agentxm/workspace-operations";
|
|
3
|
+
export declare const inlineMcpNotApplicablePlan: (name: string, operation: "install" | "update") => Plan<InstallStepRequirements>;
|
|
4
|
+
//# sourceMappingURL=inline-mcp-operation.d.ts.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Option from "effect/Option";
|
|
3
|
+
export const inlineMcpNotApplicablePlan = (name, operation) => ({
|
|
4
|
+
_tag: "Plan",
|
|
5
|
+
name: `Skip inline MCP server ${operation}`,
|
|
6
|
+
description: Option.some(`${name} is authored directly in workspace configuration`),
|
|
7
|
+
jobs: [
|
|
8
|
+
{
|
|
9
|
+
concurrency: 1,
|
|
10
|
+
steps: [
|
|
11
|
+
{
|
|
12
|
+
key: `not-applicable:mcp-server:${name}`,
|
|
13
|
+
readiness: "ready",
|
|
14
|
+
label: name,
|
|
15
|
+
run: Effect.succeed({
|
|
16
|
+
result: "success",
|
|
17
|
+
disposition: "skipped",
|
|
18
|
+
message: `${name} is inline workspace configuration; run axm sync to reconcile it`,
|
|
19
|
+
}),
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
});
|
|
25
|
+
//# sourceMappingURL=inline-mcp-operation.js.map
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Installing extensions.
|
|
3
|
+
*
|
|
4
|
+
* One use case behind seventeen command spellings. `axm install` with a
|
|
5
|
+
* registry FQN, `axm <type> install <source>`, `axm install <locator>`, and
|
|
6
|
+
* either form with no source at all are the same decision with different
|
|
7
|
+
* amounts already known: which type, which source, which versions, and which
|
|
8
|
+
* of a source's contents the person wants.
|
|
9
|
+
*
|
|
10
|
+
* `prepare` settles all of that and writes nothing. The locator form is the
|
|
11
|
+
* reason it must: a locator can carry skills, rules, hooks, knowledge bundles
|
|
12
|
+
* and subagents at once, and each is an independent closure inside one
|
|
13
|
+
* prepared candidate — so the preview shows the whole set, one type failing
|
|
14
|
+
* leaves the others committed, and the operation reports every outcome.
|
|
15
|
+
*
|
|
16
|
+
* @experimental This API is unstable and may change without notice.
|
|
17
|
+
*/
|
|
18
|
+
import * as Effect from "effect/Effect";
|
|
19
|
+
import * as Option from "effect/Option";
|
|
20
|
+
import type { InstallableExtensionType } from "@agentxm/extension-model/unstable/extensions/installable-types";
|
|
21
|
+
import { type ExecutionCandidate, type OperationResolution, type PlanExecution } from "@agentxm/workspace-operations";
|
|
22
|
+
import type { ExtensionResolutionFailed } from "@agentxm/extension-resolution";
|
|
23
|
+
import type { ExtensionLifecycleFailed } from "../errors.js";
|
|
24
|
+
import { BundledAxmSkillAsset } from "../skills/install/bundled.js";
|
|
25
|
+
import { type ConfiguredInstallRequirements } from "./configured.js";
|
|
26
|
+
import type { ExtensionSelectionCancelled } from "./selection-interaction.js";
|
|
27
|
+
import { ExtensionSelectionInteraction } from "./selection-interaction.js";
|
|
28
|
+
import { type InstallExecutionFailure, type InstallStepRequirements, type PrepareInstallRequirements } from "./vocabulary.js";
|
|
29
|
+
/**
|
|
30
|
+
* What the request installs: the extensions the workspace already declares,
|
|
31
|
+
* one source a person named, or the official skill the executable carries.
|
|
32
|
+
*/
|
|
33
|
+
export type InstallSubject = {
|
|
34
|
+
readonly kind: "configured";
|
|
35
|
+
} | {
|
|
36
|
+
readonly kind: "source";
|
|
37
|
+
readonly source: string;
|
|
38
|
+
} | {
|
|
39
|
+
readonly kind: "bundled";
|
|
40
|
+
};
|
|
41
|
+
/** One install request, whatever command spelling produced it. */
|
|
42
|
+
export interface InstallExtensionsRequest {
|
|
43
|
+
/**
|
|
44
|
+
* The type the command fixed. `none` is the root form: a registry FQN names
|
|
45
|
+
* its own type and a locator is opened to find out.
|
|
46
|
+
*/
|
|
47
|
+
readonly type: Option.Option<InstallableExtensionType>;
|
|
48
|
+
readonly subject: InstallSubject;
|
|
49
|
+
/** Names or glob patterns the request named inside the source. */
|
|
50
|
+
readonly names: ReadonlyArray<string>;
|
|
51
|
+
/** Take everything the source offers without asking. */
|
|
52
|
+
readonly all: boolean;
|
|
53
|
+
/** Re-materialize even when the canonical tree already matches the lockfile. */
|
|
54
|
+
readonly reinstall: boolean;
|
|
55
|
+
/** The local connection name an MCP install writes under. */
|
|
56
|
+
readonly localName: Option.Option<string>;
|
|
57
|
+
/** `KEY=VALUE` inputs an MCP install supplies. */
|
|
58
|
+
readonly env: ReadonlyArray<string>;
|
|
59
|
+
/** No prompt can open in this invocation. */
|
|
60
|
+
readonly nonInteractive: boolean;
|
|
61
|
+
/** Human-readable name for the operation, chosen by the command. */
|
|
62
|
+
readonly planName: string;
|
|
63
|
+
readonly planDescription: Option.Option<string>;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Evidence the settling collected that the application may show but that no
|
|
67
|
+
* decision depends on: which registries were consulted, and which packages
|
|
68
|
+
* the selected extensions declare themselves compatible with.
|
|
69
|
+
*/
|
|
70
|
+
export interface InstallDiagnostics {
|
|
71
|
+
readonly resolutionLines: ReadonlyArray<string>;
|
|
72
|
+
readonly companionPackages: ReadonlyArray<string>;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* A settled install: every decision is made and nothing is written. `types`
|
|
76
|
+
* says which extension types the prepared closures cover, so a root locator
|
|
77
|
+
* install can report the five it detected.
|
|
78
|
+
*/
|
|
79
|
+
export interface InstallExtensionsCandidate {
|
|
80
|
+
readonly types: ReadonlyArray<InstallableExtensionType>;
|
|
81
|
+
/** Nothing matched the request; the application renders its own no-op. */
|
|
82
|
+
readonly empty: boolean;
|
|
83
|
+
/** Present only when nothing matched: what to tell the person. */
|
|
84
|
+
readonly emptyMessage: Option.Option<string>;
|
|
85
|
+
readonly diagnostics: InstallDiagnostics;
|
|
86
|
+
readonly planName: string;
|
|
87
|
+
readonly execution: ExecutionCandidate<InstallStepRequirements | BundledAxmSkillAsset>;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Every failure settling an install can surface before anything is written.
|
|
91
|
+
* A configured entry's resolution refusal travels with its own category and
|
|
92
|
+
* sentence rather than as this feature's generic refusal.
|
|
93
|
+
*/
|
|
94
|
+
export type InstallExtensionsFailure = ExtensionLifecycleFailed | ExtensionResolutionFailed | ExtensionSelectionCancelled | InstallExecutionFailure;
|
|
95
|
+
/** Settle an install without writing anything. */
|
|
96
|
+
export declare const prepareInstallExtensions: (request: InstallExtensionsRequest) => Effect.Effect<InstallExtensionsCandidate, InstallExtensionsFailure, PrepareInstallRequirements | ConfiguredInstallRequirements | ExtensionSelectionInteraction | BundledAxmSkillAsset>;
|
|
97
|
+
/**
|
|
98
|
+
* Everything resolving a settled install writes through: the candidate's own
|
|
99
|
+
* step requirements plus the operation boundary that presents, journals, and
|
|
100
|
+
* applies it.
|
|
101
|
+
*/
|
|
102
|
+
export type ResolveInstallExtensionsRequirements = PrepareInstallRequirements | BundledAxmSkillAsset;
|
|
103
|
+
/** Preview or apply a settled install, resolving to one operation outcome. */
|
|
104
|
+
export declare const previewOrApplyInstallExtensions: (candidate: InstallExtensionsCandidate, execution: PlanExecution) => Effect.Effect<OperationResolution, InstallExtensionsFailure, ResolveInstallExtensionsRequirements>;
|
|
105
|
+
/** The install use case: settle a request, then preview or apply it. */
|
|
106
|
+
export declare const InstallExtensions: {
|
|
107
|
+
readonly prepare: (request: InstallExtensionsRequest) => Effect.Effect<InstallExtensionsCandidate, InstallExtensionsFailure, PrepareInstallRequirements | ConfiguredInstallRequirements | ExtensionSelectionInteraction | BundledAxmSkillAsset>;
|
|
108
|
+
readonly previewOrApply: (candidate: InstallExtensionsCandidate, execution: PlanExecution) => Effect.Effect<OperationResolution, InstallExtensionsFailure, ResolveInstallExtensionsRequirements>;
|
|
109
|
+
};
|
|
110
|
+
//# sourceMappingURL=install-extensions.d.ts.map
|