@agentxm/extension-lifecycle 0.28.11 → 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,282 @@
|
|
|
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 { operationPresentation, prepareExecutionCandidate, resolveExecutionCandidate, } from "@agentxm/workspace-operations";
|
|
21
|
+
import { withPublisherTrust } from "../publisher-binding.js";
|
|
22
|
+
import { planHookInstall } from "../hooks/install/plan.js";
|
|
23
|
+
import { discoverHookRefs, finalizeHookInstallIntent, parseHookInstallRequest, } from "../hooks/install/plan.js";
|
|
24
|
+
import { discoverKnowledgeRefs, finalizeKnowledgeInstallIntent, parseKnowledgeInstallRequest, planKnowledgeInstall, } from "../knowledge/install/plan.js";
|
|
25
|
+
import { discoverMcpServerRefs, finalizeMcpServerInstallIntent, parseMcpServerInstallRequest, planMcpServerInstall, resolveMcpServerSourceRequest, } from "../mcps/install/plan.js";
|
|
26
|
+
import { discoverPackRef, finalizePackInstallIntent, packDiscoveryDiagnostics, parsePackInstallRequest, planPackInstall, resolvePackSourceRequest, } from "../packs/install/plan.js";
|
|
27
|
+
import { discoverRuleRefs, finalizeRuleInstallIntent, parseRuleInstallRequest, planRuleInstall, } from "../rules/install/plan.js";
|
|
28
|
+
import { discoverSkillRefs, finalizeSkillInstallIntent, parseSkillInstallRequest, planSkillInstall, buildCompanionPackagesSection, } from "../skills/install/plan.js";
|
|
29
|
+
import { discoverSubagentRefs, finalizeSubagentInstallIntent, parseSubagentInstallRequest, planSubagentInstall, } from "../subagents/install/plan.js";
|
|
30
|
+
import { BundledAxmSkillAsset, planBundledAxmSkillInstall } from "../skills/install/bundled.js";
|
|
31
|
+
import { buildConfiguredInstallPlan } from "./configured.js";
|
|
32
|
+
import { formatRegistryProbe } from "./registry-source-resolution.js";
|
|
33
|
+
import { resolveRootInstallIntent } from "./root-intent.js";
|
|
34
|
+
import { ExtensionSelectionInteraction } from "./selection-interaction.js";
|
|
35
|
+
import { installRefused, } from "./vocabulary.js";
|
|
36
|
+
const EMPTY_DIAGNOSTICS = { resolutionLines: [], companionPackages: [] };
|
|
37
|
+
const emptyPlan = (request) => ({
|
|
38
|
+
_tag: "Plan",
|
|
39
|
+
name: request.planName,
|
|
40
|
+
description: request.planDescription,
|
|
41
|
+
presentation: operationPresentation({ imperative: "install", past: "Installed", gerund: "Installing" }, Option.getOrUndefined(request.type)),
|
|
42
|
+
jobs: [{ concurrency: 1, steps: [] }],
|
|
43
|
+
});
|
|
44
|
+
const planForType = (type, source, request) => {
|
|
45
|
+
switch (type) {
|
|
46
|
+
case "skill":
|
|
47
|
+
return Effect.gen(function* () {
|
|
48
|
+
const parsed = yield* parseSkillInstallRequest({
|
|
49
|
+
source,
|
|
50
|
+
skills: request.names,
|
|
51
|
+
all: request.all,
|
|
52
|
+
force: request.reinstall,
|
|
53
|
+
nonInteractive: request.nonInteractive,
|
|
54
|
+
}).pipe(Effect.mapError((cause) => cause._tag === "ExtensionLifecycleFailed"
|
|
55
|
+
? cause
|
|
56
|
+
: installRefused({
|
|
57
|
+
category: "validation",
|
|
58
|
+
detail: `Skill source "${source}" could not be resolved`,
|
|
59
|
+
cause,
|
|
60
|
+
})));
|
|
61
|
+
const discovered = yield* discoverSkillRefs(parsed);
|
|
62
|
+
const intent = yield* finalizeSkillInstallIntent(parsed, discovered);
|
|
63
|
+
const plan = yield* planSkillInstall(intent);
|
|
64
|
+
const companions = buildCompanionPackagesSection(intent.skillsToInstall.map((entry) => entry.ref));
|
|
65
|
+
return {
|
|
66
|
+
plan,
|
|
67
|
+
diagnostics: {
|
|
68
|
+
resolutionLines: [
|
|
69
|
+
...(parsed.resolutionProbes.length > 0
|
|
70
|
+
? [`Resolution: ${parsed.resolutionProbes.map(formatRegistryProbe).join("; ")}`]
|
|
71
|
+
: []),
|
|
72
|
+
`Found ${discovered.length} skill${discovered.length === 1 ? "" : "s"}`,
|
|
73
|
+
],
|
|
74
|
+
companionPackages: companions === undefined ? [] : companions.items,
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
});
|
|
78
|
+
case "subagent":
|
|
79
|
+
return Effect.gen(function* () {
|
|
80
|
+
const parsed = yield* parseSubagentInstallRequest({
|
|
81
|
+
source,
|
|
82
|
+
subagents: request.names,
|
|
83
|
+
all: request.all,
|
|
84
|
+
nonInteractive: request.nonInteractive,
|
|
85
|
+
}).pipe(Effect.mapError((cause) => cause._tag === "ExtensionLifecycleFailed"
|
|
86
|
+
? cause
|
|
87
|
+
: installRefused({
|
|
88
|
+
category: "validation",
|
|
89
|
+
detail: `Subagent source "${source}" could not be resolved`,
|
|
90
|
+
cause,
|
|
91
|
+
})));
|
|
92
|
+
const discovered = yield* discoverSubagentRefs(parsed);
|
|
93
|
+
const intent = yield* finalizeSubagentInstallIntent(parsed, discovered);
|
|
94
|
+
return {
|
|
95
|
+
plan: yield* planSubagentInstall(intent),
|
|
96
|
+
diagnostics: {
|
|
97
|
+
resolutionLines: [
|
|
98
|
+
...(parsed.resolutionProbes.length > 0
|
|
99
|
+
? [`Resolution: ${parsed.resolutionProbes.map(formatRegistryProbe).join("; ")}`]
|
|
100
|
+
: []),
|
|
101
|
+
`Found ${discovered.length} subagent${discovered.length === 1 ? "" : "s"}`,
|
|
102
|
+
],
|
|
103
|
+
companionPackages: [],
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
});
|
|
107
|
+
case "rule":
|
|
108
|
+
return Effect.gen(function* () {
|
|
109
|
+
const parsed = yield* parseRuleInstallRequest(source);
|
|
110
|
+
const intent = yield* finalizeRuleInstallIntent(parsed, yield* discoverRuleRefs(parsed));
|
|
111
|
+
return { plan: yield* planRuleInstall(intent), diagnostics: EMPTY_DIAGNOSTICS };
|
|
112
|
+
});
|
|
113
|
+
case "hook":
|
|
114
|
+
return Effect.gen(function* () {
|
|
115
|
+
const parsed = yield* parseHookInstallRequest(source);
|
|
116
|
+
const intent = yield* finalizeHookInstallIntent(parsed, yield* discoverHookRefs(parsed));
|
|
117
|
+
return { plan: yield* planHookInstall(intent), diagnostics: EMPTY_DIAGNOSTICS };
|
|
118
|
+
});
|
|
119
|
+
case "knowledge":
|
|
120
|
+
return Effect.gen(function* () {
|
|
121
|
+
const parsed = yield* parseKnowledgeInstallRequest(source);
|
|
122
|
+
const intent = yield* finalizeKnowledgeInstallIntent(parsed, yield* discoverKnowledgeRefs(parsed));
|
|
123
|
+
return { plan: yield* planKnowledgeInstall(intent), diagnostics: EMPTY_DIAGNOSTICS };
|
|
124
|
+
});
|
|
125
|
+
case "mcp-server":
|
|
126
|
+
return Effect.gen(function* () {
|
|
127
|
+
const parsed = yield* parseMcpServerInstallRequest({
|
|
128
|
+
source,
|
|
129
|
+
localName: request.localName,
|
|
130
|
+
env: request.env,
|
|
131
|
+
force: request.reinstall,
|
|
132
|
+
nonInteractive: request.nonInteractive,
|
|
133
|
+
});
|
|
134
|
+
const sourceRequest = yield* resolveMcpServerSourceRequest(parsed);
|
|
135
|
+
const intent = yield* finalizeMcpServerInstallIntent(parsed, yield* discoverMcpServerRefs(sourceRequest));
|
|
136
|
+
return { plan: yield* planMcpServerInstall(intent), diagnostics: EMPTY_DIAGNOSTICS };
|
|
137
|
+
});
|
|
138
|
+
case "pack":
|
|
139
|
+
return Effect.gen(function* () {
|
|
140
|
+
const parsed = yield* parsePackInstallRequest({
|
|
141
|
+
source,
|
|
142
|
+
nonInteractive: request.nonInteractive,
|
|
143
|
+
});
|
|
144
|
+
const sourceRequest = yield* resolvePackSourceRequest(parsed);
|
|
145
|
+
const discovery = yield* discoverPackRef(sourceRequest);
|
|
146
|
+
const intent = finalizePackInstallIntent(parsed, discovery);
|
|
147
|
+
return {
|
|
148
|
+
plan: yield* planPackInstall(intent),
|
|
149
|
+
diagnostics: {
|
|
150
|
+
resolutionLines: packDiscoveryDiagnostics(sourceRequest, discovery),
|
|
151
|
+
companionPackages: [],
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
/** The types a locator can carry, in the order a locator install reports them. */
|
|
158
|
+
const LOCATOR_TYPES = ["skill", "rule", "hook", "knowledge", "subagent"];
|
|
159
|
+
const isNoMatch = (failure) => failure._tag === "ExtensionLifecycleFailed" &&
|
|
160
|
+
(failure.category === "not_found" || failure.category === "usage");
|
|
161
|
+
/**
|
|
162
|
+
* A locator names a place, not a type. Each installable type is offered the
|
|
163
|
+
* source and the ones that find nothing there simply do not contribute; if no
|
|
164
|
+
* type matches, the locator held nothing AXM can install.
|
|
165
|
+
*/
|
|
166
|
+
const planLocatorInstall = (source, request) => Effect.gen(function* () {
|
|
167
|
+
const attempts = yield* Effect.forEach(LOCATOR_TYPES, (type) => planForType(type, source, request).pipe(Effect.map((planned) => Option.some({ type, ...planned })), Effect.catch((failure) => isNoMatch(failure)
|
|
168
|
+
? Effect.succeed(Option.none())
|
|
169
|
+
: Effect.fail(failure))), { concurrency: 1 });
|
|
170
|
+
const matched = attempts.flatMap((attempt) => (Option.isSome(attempt) ? [attempt.value] : []));
|
|
171
|
+
if (matched.length === 0) {
|
|
172
|
+
return yield* installRefused({
|
|
173
|
+
category: "not_found",
|
|
174
|
+
detail: "No locator-discoverable extensions found in source (supported: skills, rules, hooks, knowledge, and subagents)",
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
// Every matched type is one independent closure inside a single
|
|
178
|
+
// candidate: the preview shows all of them, and each settles on its own.
|
|
179
|
+
const steps = matched.flatMap(({ plan }) => plan.jobs.flatMap((job) => job.steps));
|
|
180
|
+
return {
|
|
181
|
+
types: matched.map(({ type }) => type),
|
|
182
|
+
plan: {
|
|
183
|
+
_tag: "Plan",
|
|
184
|
+
name: request.planName,
|
|
185
|
+
description: request.planDescription,
|
|
186
|
+
presentation: operationPresentation({
|
|
187
|
+
imperative: "install",
|
|
188
|
+
past: "Installed",
|
|
189
|
+
gerund: "Installing",
|
|
190
|
+
}),
|
|
191
|
+
jobs: [{ concurrency: 1, steps, executionPolicy: "best-effort" }],
|
|
192
|
+
},
|
|
193
|
+
diagnostics: {
|
|
194
|
+
resolutionLines: matched.flatMap(({ diagnostics }) => diagnostics.resolutionLines),
|
|
195
|
+
companionPackages: [
|
|
196
|
+
...new Set(matched.flatMap(({ diagnostics }) => diagnostics.companionPackages)),
|
|
197
|
+
],
|
|
198
|
+
},
|
|
199
|
+
configuredAgentOperations: [],
|
|
200
|
+
emptyMessage: Option.none(),
|
|
201
|
+
};
|
|
202
|
+
});
|
|
203
|
+
const planRequest = (request) => Effect.gen(function* () {
|
|
204
|
+
if (request.subject.kind === "bundled") {
|
|
205
|
+
return {
|
|
206
|
+
types: ["skill"],
|
|
207
|
+
plan: yield* planBundledAxmSkillInstall,
|
|
208
|
+
diagnostics: EMPTY_DIAGNOSTICS,
|
|
209
|
+
configuredAgentOperations: [],
|
|
210
|
+
emptyMessage: Option.none(),
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
if (request.subject.kind === "configured") {
|
|
214
|
+
const result = yield* buildConfiguredInstallPlan({
|
|
215
|
+
type: request.type,
|
|
216
|
+
planName: request.planName,
|
|
217
|
+
planDescription: request.planDescription,
|
|
218
|
+
nonInteractive: request.nonInteractive,
|
|
219
|
+
});
|
|
220
|
+
if (result._tag === "NoConfiguredExtensions") {
|
|
221
|
+
return {
|
|
222
|
+
types: Option.toArray(request.type),
|
|
223
|
+
plan: emptyPlan(request),
|
|
224
|
+
diagnostics: EMPTY_DIAGNOSTICS,
|
|
225
|
+
configuredAgentOperations: [],
|
|
226
|
+
emptyMessage: Option.some(result.message),
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
return {
|
|
230
|
+
types: Option.toArray(request.type),
|
|
231
|
+
plan: result.plan,
|
|
232
|
+
diagnostics: EMPTY_DIAGNOSTICS,
|
|
233
|
+
configuredAgentOperations: result.configuredAgentOperations,
|
|
234
|
+
emptyMessage: Option.none(),
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
const source = request.subject.source;
|
|
238
|
+
const type = yield* Option.match(request.type, {
|
|
239
|
+
onSome: (value) => Effect.succeed(value),
|
|
240
|
+
onNone: () => resolveRootInstallIntent(source).pipe(Effect.map((intent) => intent.type)),
|
|
241
|
+
});
|
|
242
|
+
if (type === "locator")
|
|
243
|
+
return yield* planLocatorInstall(source, request);
|
|
244
|
+
const { plan, diagnostics } = yield* planForType(type, source, request);
|
|
245
|
+
return {
|
|
246
|
+
types: [type],
|
|
247
|
+
plan: { ...plan, name: plan.name },
|
|
248
|
+
diagnostics,
|
|
249
|
+
configuredAgentOperations: [],
|
|
250
|
+
emptyMessage: Option.none(),
|
|
251
|
+
};
|
|
252
|
+
});
|
|
253
|
+
// -----------------------------------------------------------------------------
|
|
254
|
+
// prepare
|
|
255
|
+
// -----------------------------------------------------------------------------
|
|
256
|
+
/** Settle an install without writing anything. */
|
|
257
|
+
export const prepareInstallExtensions = Effect.fn("InstallExtensions.prepare")(function* (request) {
|
|
258
|
+
const planned = yield* planRequest(request);
|
|
259
|
+
// Every acceptance a plan proposes is classified against the accepted
|
|
260
|
+
// resolution here, so the root, per-type, locator, and configured routes
|
|
261
|
+
// share one publisher-trust rule instead of restating it five times.
|
|
262
|
+
const trusted = yield* withPublisherTrust(planned.plan);
|
|
263
|
+
const execution = yield* prepareExecutionCandidate(trusted, {
|
|
264
|
+
configuredAgentOperations: planned.configuredAgentOperations,
|
|
265
|
+
});
|
|
266
|
+
return {
|
|
267
|
+
types: planned.types,
|
|
268
|
+
empty: Option.isSome(planned.emptyMessage),
|
|
269
|
+
emptyMessage: planned.emptyMessage,
|
|
270
|
+
diagnostics: planned.diagnostics,
|
|
271
|
+
planName: trusted.name,
|
|
272
|
+
execution,
|
|
273
|
+
};
|
|
274
|
+
});
|
|
275
|
+
/** Preview or apply a settled install, resolving to one operation outcome. */
|
|
276
|
+
export const previewOrApplyInstallExtensions = (candidate, execution) => resolveExecutionCandidate(candidate.execution, execution);
|
|
277
|
+
/** The install use case: settle a request, then preview or apply it. */
|
|
278
|
+
export const InstallExtensions = {
|
|
279
|
+
prepare: prepareInstallExtensions,
|
|
280
|
+
previewOrApply: previewOrApplyInstallExtensions,
|
|
281
|
+
};
|
|
282
|
+
//# sourceMappingURL=install-extensions.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-type install command guidance.
|
|
3
|
+
*
|
|
4
|
+
* Every extension type group registers an `install` subcommand, so the segment
|
|
5
|
+
* list and the command spelling both come straight from the type table.
|
|
6
|
+
*/
|
|
7
|
+
import { type ExtensionType } from "@agentxm/extension-model/unstable/extensions";
|
|
8
|
+
/** Plural type segments whose command group exposes an `install` subcommand. */
|
|
9
|
+
export declare const perTypeInstallPluralSegments: ReadonlyArray<string>;
|
|
10
|
+
/** The install command that resolves for `type`, given an FQN or source. */
|
|
11
|
+
export declare const installCommandFor: (type: ExtensionType, source: string) => string;
|
|
12
|
+
//# sourceMappingURL=per-type-install.d.ts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-type install command guidance.
|
|
3
|
+
*
|
|
4
|
+
* Every extension type group registers an `install` subcommand, so the segment
|
|
5
|
+
* list and the command spelling both come straight from the type table.
|
|
6
|
+
*/
|
|
7
|
+
import { extensionTypePluralSegments, extensionTypeToPlural, } from "@agentxm/extension-model/unstable/extensions";
|
|
8
|
+
/** Plural type segments whose command group exposes an `install` subcommand. */
|
|
9
|
+
export const perTypeInstallPluralSegments = extensionTypePluralSegments;
|
|
10
|
+
/** The install command that resolves for `type`, given an FQN or source. */
|
|
11
|
+
export const installCommandFor = (type, source) => `axm ${extensionTypeToPlural[type]} install ${source}`;
|
|
12
|
+
//# sourceMappingURL=per-type-install.js.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as Result from "effect/Result";
|
|
2
|
+
import { type ExtensionName, type ExtensionType, type Handle } from "@agentxm/extension-model/unstable/extensions";
|
|
3
|
+
import { type VersionRange } from "@agentxm/extension-model/unstable/version-constraints";
|
|
4
|
+
export interface BareRegistryInstallTarget {
|
|
5
|
+
readonly kind: "bare-name";
|
|
6
|
+
readonly name: ExtensionName;
|
|
7
|
+
readonly versionRange?: VersionRange | undefined;
|
|
8
|
+
}
|
|
9
|
+
export interface QualifiedRegistryInstallTarget {
|
|
10
|
+
readonly kind: "registry";
|
|
11
|
+
readonly owner: Handle;
|
|
12
|
+
readonly type: ExtensionType;
|
|
13
|
+
readonly name: ExtensionName;
|
|
14
|
+
readonly versionRange?: VersionRange | undefined;
|
|
15
|
+
}
|
|
16
|
+
export type RegistryInstallTarget = BareRegistryInstallTarget | QualifiedRegistryInstallTarget;
|
|
17
|
+
export type RegistryInstallTargetParseError = {
|
|
18
|
+
readonly kind: "missing-name";
|
|
19
|
+
} | {
|
|
20
|
+
readonly kind: "wrong-type";
|
|
21
|
+
readonly actualType?: ExtensionType | undefined;
|
|
22
|
+
} | {
|
|
23
|
+
readonly kind: "invalid-bare-name";
|
|
24
|
+
} | {
|
|
25
|
+
readonly kind: "invalid-version-constraint";
|
|
26
|
+
} | {
|
|
27
|
+
readonly kind: "not-registry";
|
|
28
|
+
};
|
|
29
|
+
export interface ParseRegistryInstallTargetOptions {
|
|
30
|
+
readonly expectedType: ExtensionType;
|
|
31
|
+
readonly allowBareName: boolean;
|
|
32
|
+
readonly allowBareVersionRange?: boolean | undefined;
|
|
33
|
+
}
|
|
34
|
+
export declare const parseRegistryInstallTarget: (input: string, options: ParseRegistryInstallTargetOptions) => Result.Result<RegistryInstallTarget, RegistryInstallTargetParseError>;
|
|
35
|
+
//# sourceMappingURL=registry-install-target.d.ts.map
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import * as Result from "effect/Result";
|
|
2
|
+
import * as Schema from "effect/Schema";
|
|
3
|
+
import { ExtensionNameSchema, parseSourceQualifiedRegistrySourcePatternParts, toExtensionType, } from "@agentxm/extension-model/unstable/extensions";
|
|
4
|
+
import { VersionRangeSchema, } from "@agentxm/extension-model/unstable/version-constraints";
|
|
5
|
+
const decodeExtensionName = Schema.decodeUnknownResult(ExtensionNameSchema);
|
|
6
|
+
const decodeVersionRange = Schema.decodeUnknownResult(VersionRangeSchema);
|
|
7
|
+
const parseBareName = (input, options) => {
|
|
8
|
+
if (input.startsWith("@")) {
|
|
9
|
+
return Result.fail({ kind: "not-registry" });
|
|
10
|
+
}
|
|
11
|
+
const atIndex = input.indexOf("@");
|
|
12
|
+
const rawName = atIndex === -1 ? input : input.slice(0, atIndex);
|
|
13
|
+
const rawConstraint = atIndex === -1 ? undefined : input.slice(atIndex + 1);
|
|
14
|
+
if (rawConstraint !== undefined && !options.allowBareVersionRange) {
|
|
15
|
+
return Result.fail({ kind: "not-registry" });
|
|
16
|
+
}
|
|
17
|
+
const decodedName = decodeExtensionName(rawName);
|
|
18
|
+
if (Result.isFailure(decodedName)) {
|
|
19
|
+
return Result.fail({ kind: "invalid-bare-name" });
|
|
20
|
+
}
|
|
21
|
+
if (rawConstraint === undefined) {
|
|
22
|
+
return Result.succeed({
|
|
23
|
+
kind: "bare-name",
|
|
24
|
+
name: decodedName.success,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
if (rawConstraint.length === 0) {
|
|
28
|
+
return Result.fail({ kind: "invalid-version-constraint" });
|
|
29
|
+
}
|
|
30
|
+
const decodedConstraint = decodeVersionRange(rawConstraint);
|
|
31
|
+
if (Result.isFailure(decodedConstraint)) {
|
|
32
|
+
return Result.fail({ kind: "invalid-version-constraint" });
|
|
33
|
+
}
|
|
34
|
+
return Result.succeed({
|
|
35
|
+
kind: "bare-name",
|
|
36
|
+
name: decodedName.success,
|
|
37
|
+
versionRange: decodedConstraint.success,
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
export const parseRegistryInstallTarget = (input, options) => {
|
|
41
|
+
const parsedRegistry = parseSourceQualifiedRegistrySourcePatternParts(input);
|
|
42
|
+
if (parsedRegistry !== undefined) {
|
|
43
|
+
const parsedSingularType = parsedRegistry.type !== undefined ? toExtensionType(parsedRegistry.type) : undefined;
|
|
44
|
+
if (parsedSingularType === undefined || parsedSingularType !== options.expectedType) {
|
|
45
|
+
return Result.fail({
|
|
46
|
+
kind: "wrong-type",
|
|
47
|
+
actualType: parsedSingularType,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
if (parsedRegistry.name === undefined) {
|
|
51
|
+
return Result.fail({ kind: "missing-name" });
|
|
52
|
+
}
|
|
53
|
+
return Result.succeed({
|
|
54
|
+
kind: "registry",
|
|
55
|
+
owner: parsedRegistry.owner,
|
|
56
|
+
type: parsedSingularType,
|
|
57
|
+
name: parsedRegistry.name,
|
|
58
|
+
versionRange: parsedRegistry.versionRange,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
if (!options.allowBareName) {
|
|
62
|
+
return Result.fail({ kind: "not-registry" });
|
|
63
|
+
}
|
|
64
|
+
return parseBareName(input, options);
|
|
65
|
+
};
|
|
66
|
+
//# sourceMappingURL=registry-install-target.js.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The offline login hint an install refusal carries.
|
|
3
|
+
*
|
|
4
|
+
* When a registry lookup finds nothing, the extension may simply be private
|
|
5
|
+
* to an account this invocation is not signed in to. Whether every consulted
|
|
6
|
+
* origin already has a credential is the `registry-auth` capability's
|
|
7
|
+
* decision; the wording of the hint is this feature's.
|
|
8
|
+
*
|
|
9
|
+
* @experimental This API is unstable and may change without notice.
|
|
10
|
+
*/
|
|
11
|
+
import * as Effect from "effect/Effect";
|
|
12
|
+
import type { SuggestedAction } from "@agentxm/registry-protocol/unstable/suggested-action";
|
|
13
|
+
/**
|
|
14
|
+
* Suggest signing in when any consulted registry origin has no credential.
|
|
15
|
+
*
|
|
16
|
+
* The credential store and the default registry are optional: an invocation
|
|
17
|
+
* composed without them (a workspace with no registry configured) offers no
|
|
18
|
+
* hint rather than failing.
|
|
19
|
+
*/
|
|
20
|
+
export declare const registryLoginSuggestions: (locations: ReadonlyArray<string>) => Effect.Effect<ReadonlyArray<SuggestedAction>>;
|
|
21
|
+
//# sourceMappingURL=registry-login-suggestion.d.ts.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The offline login hint an install refusal carries.
|
|
3
|
+
*
|
|
4
|
+
* When a registry lookup finds nothing, the extension may simply be private
|
|
5
|
+
* to an account this invocation is not signed in to. Whether every consulted
|
|
6
|
+
* origin already has a credential is the `registry-auth` capability's
|
|
7
|
+
* decision; the wording of the hint is this feature's.
|
|
8
|
+
*
|
|
9
|
+
* @experimental This API is unstable and may change without notice.
|
|
10
|
+
*/
|
|
11
|
+
import * as Effect from "effect/Effect";
|
|
12
|
+
import * as Option from "effect/Option";
|
|
13
|
+
import { CredentialStore, hasCredentialsForAll } from "@agentxm/registry-auth";
|
|
14
|
+
import { RegistryUrl } from "@agentxm/registry-client";
|
|
15
|
+
const LOGIN_SUGGESTION = {
|
|
16
|
+
description: "Sign in to check whether the extension is private.",
|
|
17
|
+
cmd: "axm login",
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Suggest signing in when any consulted registry origin has no credential.
|
|
21
|
+
*
|
|
22
|
+
* The credential store and the default registry are optional: an invocation
|
|
23
|
+
* composed without them (a workspace with no registry configured) offers no
|
|
24
|
+
* hint rather than failing.
|
|
25
|
+
*/
|
|
26
|
+
export const registryLoginSuggestions = (locations) => Effect.gen(function* () {
|
|
27
|
+
const store = yield* Effect.serviceOption(CredentialStore);
|
|
28
|
+
const defaultRegistry = yield* Effect.serviceOption(RegistryUrl);
|
|
29
|
+
if (Option.isNone(store) || Option.isNone(defaultRegistry))
|
|
30
|
+
return [];
|
|
31
|
+
const present = yield* hasCredentialsForAll(locations, defaultRegistry.value).pipe(Effect.provideService(CredentialStore, store.value));
|
|
32
|
+
return present ? [] : [LOGIN_SUGGESTION];
|
|
33
|
+
});
|
|
34
|
+
//# sourceMappingURL=registry-login-suggestion.js.map
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which configured registry supplies a skill or subagent named without one.
|
|
3
|
+
*
|
|
4
|
+
* A bare name or an unqualified `@owner/name` says nothing about which
|
|
5
|
+
* registry hosts it, so every configured host is probed in order and the
|
|
6
|
+
* first that answers wins. Each probe is recorded so the application can
|
|
7
|
+
* show, verbatim, which registries were consulted and what each one said.
|
|
8
|
+
*
|
|
9
|
+
* @experimental This API is unstable and may change without notice.
|
|
10
|
+
*/
|
|
11
|
+
import * as Effect from "effect/Effect";
|
|
12
|
+
import * as Option from "effect/Option";
|
|
13
|
+
import type { ExtensionName, ExtensionType, Handle } from "@agentxm/extension-model/unstable/extensions";
|
|
14
|
+
import type { RegistrySource } from "@agentxm/extension-model/unstable/sources/types";
|
|
15
|
+
import { type SourceResolutionFailure } from "@agentxm/extension-sources";
|
|
16
|
+
import type { SuggestedAction } from "@agentxm/registry-protocol/unstable/suggested-action";
|
|
17
|
+
import type { ExtensionLifecycleFailed } from "../errors.js";
|
|
18
|
+
import { type ResolveInstallRequirements } from "./vocabulary.js";
|
|
19
|
+
/** How to declare a registry when none is configured for the requested owner. */
|
|
20
|
+
export declare const ADD_REGISTRY_SOURCE: SuggestedAction;
|
|
21
|
+
/** The two types whose bare names are resolved against configured registries. */
|
|
22
|
+
export type InstallableRegistryType = Extract<ExtensionType, "skill" | "subagent">;
|
|
23
|
+
/** What one configured registry host answered when it was consulted. */
|
|
24
|
+
export interface RegistryLookupProbe {
|
|
25
|
+
readonly location: string;
|
|
26
|
+
readonly outcome: "matched" | "not-found" | "error";
|
|
27
|
+
readonly reason: Option.Option<string>;
|
|
28
|
+
}
|
|
29
|
+
export interface RegistryResolutionOptions {
|
|
30
|
+
readonly onRegistryProbe: (probe: RegistryLookupProbe) => void;
|
|
31
|
+
}
|
|
32
|
+
/** The sentence a source-resolution failure carries, for probe evidence. */
|
|
33
|
+
export declare const sourceFailureDetail: (error: SourceResolutionFailure) => string;
|
|
34
|
+
/** Render one probe as the line the application prints under `--verbose`. */
|
|
35
|
+
export declare const formatRegistryProbe: (probe: RegistryLookupProbe) => string;
|
|
36
|
+
/** Which configured registry to probe, for which extension. */
|
|
37
|
+
export interface ConfiguredRegistryLookup {
|
|
38
|
+
readonly sourceName: string;
|
|
39
|
+
readonly owner: Handle;
|
|
40
|
+
readonly extensionType: InstallableRegistryType;
|
|
41
|
+
readonly extensionName: Option.Option<ExtensionName>;
|
|
42
|
+
readonly options: Option.Option<RegistryResolutionOptions>;
|
|
43
|
+
}
|
|
44
|
+
/** Probe every host configured under `sourceName` for the named extension. */
|
|
45
|
+
export declare const resolveConfiguredRegistrySource: (args: ConfiguredRegistryLookup) => Effect.Effect<RegistrySource, ExtensionLifecycleFailed, ResolveInstallRequirements>;
|
|
46
|
+
/** Which bare name to resolve against the default registry. */
|
|
47
|
+
export interface DefaultRegistryLookup {
|
|
48
|
+
readonly name: string;
|
|
49
|
+
readonly extensionType: InstallableRegistryType;
|
|
50
|
+
readonly options: Option.Option<RegistryResolutionOptions>;
|
|
51
|
+
}
|
|
52
|
+
/** Resolve a bare name against the default `agentxm` registry and configured owner. */
|
|
53
|
+
export declare const resolveDefaultRegistrySourceByName: (args: DefaultRegistryLookup) => Effect.Effect<RegistrySource, ExtensionLifecycleFailed, ResolveInstallRequirements>;
|
|
54
|
+
//# sourceMappingURL=registry-source-resolution.d.ts.map
|