@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,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How a lifecycle closure serializes a failure into the plan-step vocabulary.
|
|
3
|
+
*
|
|
4
|
+
* The feature owns this: a lifecycle step that failed must report the same
|
|
5
|
+
* category, sentence, and recovery whether the failure came from lifecycle
|
|
6
|
+
* policy, from the materialization machinery underneath it, from workspace
|
|
7
|
+
* state, or from the transaction around it. Nothing is supplied by the
|
|
8
|
+
* application, so a lifecycle use case carries no failure adapter in its
|
|
9
|
+
* requirements.
|
|
10
|
+
*
|
|
11
|
+
* Categories and detail sentences are the serialized contract of machine
|
|
12
|
+
* output; families that already carry their own category and fact sentence
|
|
13
|
+
* keep both rather than being replaced with a generic sentence.
|
|
14
|
+
*
|
|
15
|
+
* @experimental This API is unstable and may change without notice.
|
|
16
|
+
*/
|
|
17
|
+
import { OPERATION_ERROR_CATEGORIES, StepFailure, restorationIncompleteToStepFailure, workspaceStateReadFailureToStepFailure, workspaceTransactionFailureToStepFailure, } from "@agentxm/workspace-operations";
|
|
18
|
+
import { LifecyclePostconditionViolated, projectionErrorToStepFailure, } from "@agentxm/extension-materialization";
|
|
19
|
+
import { isProjectionError } from "@agentxm/workspace-projection";
|
|
20
|
+
import { WorkspaceRestorationIncomplete, } from "@agentxm/workspace-transactions";
|
|
21
|
+
import { ExtensionLifecycleFailed } from "./errors.js";
|
|
22
|
+
const CATEGORIES = new Set(OPERATION_ERROR_CATEGORIES);
|
|
23
|
+
const isCategory = (value) => typeof value === "string" && CATEGORIES.has(value);
|
|
24
|
+
const property = (failure, key) => key in failure ? Reflect.get(failure, key) : undefined;
|
|
25
|
+
const WORKSPACE_STATE_READ_TAGS = new Set([
|
|
26
|
+
"SettingsDecodeError",
|
|
27
|
+
"SettingsParseError",
|
|
28
|
+
"SettingsIoError",
|
|
29
|
+
"LockfileIoError",
|
|
30
|
+
"LockfileParseError",
|
|
31
|
+
"LockfileDecodeError",
|
|
32
|
+
"LockfileVersionUnsupported",
|
|
33
|
+
"WorkspaceRootEscape",
|
|
34
|
+
]);
|
|
35
|
+
const WORKSPACE_TRANSACTION_TAGS = new Set([
|
|
36
|
+
"WorkspaceSnapshotError",
|
|
37
|
+
"WorkspaceDirectoryError",
|
|
38
|
+
"TransitionLockError",
|
|
39
|
+
"TransitionLockUnavailable",
|
|
40
|
+
"WorkspaceTransitionCompromised",
|
|
41
|
+
]);
|
|
42
|
+
const isWorkspaceStateReadFailure = (failure) => WORKSPACE_STATE_READ_TAGS.has(failure._tag);
|
|
43
|
+
const isWorkspaceTransactionFailure = (failure) => WORKSPACE_TRANSACTION_TAGS.has(failure._tag);
|
|
44
|
+
const postconditionDetail = (failure) => {
|
|
45
|
+
switch (failure.postcondition) {
|
|
46
|
+
case "install-observable":
|
|
47
|
+
return `Installed ${failure.targetType} "${failure.targetName}" did not satisfy its observable contract`;
|
|
48
|
+
case "install-declared":
|
|
49
|
+
return `Installed ${failure.targetType} "${failure.targetName}" has no desired-state declaration`;
|
|
50
|
+
case "new-observable":
|
|
51
|
+
return `New ${failure.targetType} "${failure.targetName}" did not satisfy its observable contract`;
|
|
52
|
+
case "new-declared":
|
|
53
|
+
return `New ${failure.targetType} "${failure.targetName}" has no desired-state declaration`;
|
|
54
|
+
case "materialize-observable":
|
|
55
|
+
return `Reconciled ${failure.targetType} "${failure.targetName}" did not satisfy its observable contract`;
|
|
56
|
+
case "uninstall-remains-declared":
|
|
57
|
+
return `Uninstalled ${failure.targetType} "${failure.targetName}" remains declared`;
|
|
58
|
+
case "uninstall-observed-state":
|
|
59
|
+
return `Uninstalled ${failure.targetType} "${failure.targetName}" has an invalid observed postcondition`;
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* A family this conversion does not name still carries its own decision: the
|
|
64
|
+
* producer recorded a category and a fact sentence, so both survive, and the
|
|
65
|
+
* failure itself stays in `cause` for the diagnostic chain.
|
|
66
|
+
*/
|
|
67
|
+
const carriedFailure = (failure) => {
|
|
68
|
+
const carriedCategory = property(failure, "category");
|
|
69
|
+
const carriedDetail = property(failure, "detail");
|
|
70
|
+
return new StepFailure({
|
|
71
|
+
category: isCategory(carriedCategory) ? carriedCategory : "internal",
|
|
72
|
+
detail: typeof carriedDetail === "string"
|
|
73
|
+
? carriedDetail
|
|
74
|
+
: `The lifecycle step failed with ${failure._tag}`,
|
|
75
|
+
cause: failure,
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Serialize one lifecycle-closure failure into the plan-step vocabulary.
|
|
80
|
+
*
|
|
81
|
+
* Families this feature or the machinery beneath it constructs are rendered
|
|
82
|
+
* exactly; families the kernel already serializes are delegated to it; and
|
|
83
|
+
* anything else carries its producer's own category and sentence through.
|
|
84
|
+
*/
|
|
85
|
+
export const lifecycleStepFailure = (failure) => {
|
|
86
|
+
if (failure instanceof StepFailure)
|
|
87
|
+
return failure;
|
|
88
|
+
if (failure instanceof ExtensionLifecycleFailed) {
|
|
89
|
+
return new StepFailure({
|
|
90
|
+
category: failure.category,
|
|
91
|
+
detail: failure.detail ?? `The lifecycle step was refused (${failure.category})`,
|
|
92
|
+
...(failure.recover === undefined && failure.suggestions === undefined
|
|
93
|
+
? {}
|
|
94
|
+
: {
|
|
95
|
+
suggestions: [
|
|
96
|
+
...(failure.recover === undefined
|
|
97
|
+
? []
|
|
98
|
+
: [
|
|
99
|
+
{
|
|
100
|
+
description: failure.recover,
|
|
101
|
+
...(failure.cmd === undefined ? {} : { cmd: failure.cmd }),
|
|
102
|
+
},
|
|
103
|
+
]),
|
|
104
|
+
...(failure.suggestions ?? []),
|
|
105
|
+
],
|
|
106
|
+
}),
|
|
107
|
+
...(failure.cause === undefined ? {} : { cause: failure.cause }),
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
if (failure instanceof LifecyclePostconditionViolated) {
|
|
111
|
+
return new StepFailure({ category: "internal", detail: postconditionDetail(failure) });
|
|
112
|
+
}
|
|
113
|
+
if (failure instanceof WorkspaceRestorationIncomplete) {
|
|
114
|
+
return restorationIncompleteToStepFailure(failure);
|
|
115
|
+
}
|
|
116
|
+
if (isWorkspaceTransactionFailure(failure)) {
|
|
117
|
+
return workspaceTransactionFailureToStepFailure(failure);
|
|
118
|
+
}
|
|
119
|
+
if (isWorkspaceStateReadFailure(failure)) {
|
|
120
|
+
return workspaceStateReadFailureToStepFailure(failure);
|
|
121
|
+
}
|
|
122
|
+
// Shared projection states domain facts and renders nothing, so the
|
|
123
|
+
// capability that unions it renders it; `carriedFailure` would find no
|
|
124
|
+
// category and report a projection refusal as an internal defect.
|
|
125
|
+
if (isProjectionError(failure)) {
|
|
126
|
+
return projectionErrorToStepFailure(failure);
|
|
127
|
+
}
|
|
128
|
+
return carriedFailure(failure);
|
|
129
|
+
};
|
|
130
|
+
//# sourceMappingURL=step-failure.js.map
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Installing subagents.
|
|
3
|
+
*
|
|
4
|
+
* A subagent is rendered into each configured agent's own subagents
|
|
5
|
+
* directory, so a user-scope workspace can only hold one when every
|
|
6
|
+
* configured agent has a user-scope placement to render into.
|
|
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 { SubagentManager } from "@agentxm/extension-materialization";
|
|
13
|
+
import type { Handle } from "@agentxm/extension-model/unstable/extensions";
|
|
14
|
+
import type { SubagentExtensionRef } from "@agentxm/extension-model/unstable/extensions/refs/subagent";
|
|
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 SourceResolutionFailure } from "@agentxm/extension-sources";
|
|
18
|
+
import { type Plan } from "@agentxm/workspace-operations";
|
|
19
|
+
import type { ExtensionLifecycleFailed } from "../../errors.js";
|
|
20
|
+
import { type RegistryLookupProbe } from "../../install/registry-source-resolution.js";
|
|
21
|
+
import { ExtensionSelectionInteraction, type ExtensionSelectionCancelled } from "../../install/selection-interaction.js";
|
|
22
|
+
import { type InstallStepRequirements, type ResolveInstallRequirements, type SubagentInstallIntent } from "../../install/vocabulary.js";
|
|
23
|
+
/** A subagent source after grammar parsing, before anything is discovered. */
|
|
24
|
+
export interface ParsedSubagentInstallRequest {
|
|
25
|
+
readonly source: Source;
|
|
26
|
+
readonly versionRange: Option.Option<VersionRange>;
|
|
27
|
+
readonly requestedSubagents: ReadonlyArray<string>;
|
|
28
|
+
readonly requestedOwner: Option.Option<Handle>;
|
|
29
|
+
/** Which configured registry hosts were consulted, and what each answered. */
|
|
30
|
+
readonly resolutionProbes: ReadonlyArray<RegistryLookupProbe>;
|
|
31
|
+
readonly all: boolean;
|
|
32
|
+
readonly nonInteractive: boolean;
|
|
33
|
+
}
|
|
34
|
+
/** What a subagent install command supplies before anything is parsed. */
|
|
35
|
+
export interface SubagentInstallArgs {
|
|
36
|
+
readonly source: string;
|
|
37
|
+
readonly subagents: ReadonlyArray<string>;
|
|
38
|
+
readonly all: boolean;
|
|
39
|
+
readonly nonInteractive: boolean;
|
|
40
|
+
}
|
|
41
|
+
/** Read the subagent source grammar and route it to the source that serves it. */
|
|
42
|
+
export declare const parseSubagentInstallRequest: (args: SubagentInstallArgs) => Effect.Effect<ParsedSubagentInstallRequest, ExtensionLifecycleFailed | SourceResolutionFailure, ResolveInstallRequirements>;
|
|
43
|
+
/** Discover the subagents the parsed source offers, or refuse when it has none. */
|
|
44
|
+
export declare const discoverSubagentRefs: (request: ParsedSubagentInstallRequest) => Effect.Effect<ReadonlyArray<SubagentExtensionRef>, ExtensionLifecycleFailed, ResolveInstallRequirements>;
|
|
45
|
+
/** Settle which of the discovered subagents this request installs. */
|
|
46
|
+
export declare const finalizeSubagentInstallIntent: (request: ParsedSubagentInstallRequest, discovered: ReadonlyArray<SubagentExtensionRef>) => Effect.Effect<SubagentInstallIntent, ExtensionLifecycleFailed | ExtensionSelectionCancelled, ExtensionSelectionInteraction>;
|
|
47
|
+
/** The closures a settled subagent intent becomes. */
|
|
48
|
+
export declare const planSubagentInstall: (intent: SubagentInstallIntent) => Effect.Effect<Plan<InstallStepRequirements>, ExtensionLifecycleFailed, InstallStepRequirements | SubagentManager>;
|
|
49
|
+
//# sourceMappingURL=plan.d.ts.map
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Installing subagents.
|
|
3
|
+
*
|
|
4
|
+
* A subagent is rendered into each configured agent's own subagents
|
|
5
|
+
* directory, so a user-scope workspace can only hold one when every
|
|
6
|
+
* configured agent has a user-scope placement to render into.
|
|
7
|
+
*
|
|
8
|
+
* @experimental This API is unstable and may change without notice.
|
|
9
|
+
*/
|
|
10
|
+
import * as Array from "effect/Array";
|
|
11
|
+
import * as Effect from "effect/Effect";
|
|
12
|
+
import * as Option from "effect/Option";
|
|
13
|
+
import { NO_MATERIALIZATION_OBSERVATION, SubagentManager, buildInstallOperation, } from "@agentxm/extension-materialization";
|
|
14
|
+
import { parseInputPattern, } from "@agentxm/extension-model/unstable/sources/parser";
|
|
15
|
+
import { SourceHostProviders, sourceResolutionFailureCategory, } from "@agentxm/extension-sources";
|
|
16
|
+
import { operationPresentation, } from "@agentxm/workspace-operations";
|
|
17
|
+
import { CodingAgentRepository } from "@agentxm/workspace-projection";
|
|
18
|
+
import { WorkspaceMutations } from "@agentxm/workspace-state";
|
|
19
|
+
import { lifecycleStepFailure } from "../../step-failure.js";
|
|
20
|
+
import { sourceFailureDetail, } from "../../install/registry-source-resolution.js";
|
|
21
|
+
import { ExtensionSelectionInteraction, } from "../../install/selection-interaction.js";
|
|
22
|
+
import { installRefused, } from "../../install/vocabulary.js";
|
|
23
|
+
import { determineSubagentsToInstall } from "./selection.js";
|
|
24
|
+
import { resolveSubagentInstallSource } from "./source.js";
|
|
25
|
+
const isRemoteReadNotImplemented = (error) => sourceFailureDetail(error).includes("not implemented");
|
|
26
|
+
const discoverHowToFix = (source, error) => {
|
|
27
|
+
if (source.type === "registry") {
|
|
28
|
+
if (isRemoteReadNotImplemented(error)) {
|
|
29
|
+
return "Remote registry discovery is not yet supported for HTTP(S) sources. Use a file:// registry source, or install from github:owner/repo.";
|
|
30
|
+
}
|
|
31
|
+
return "Verify the configured registry is reachable and contains the requested owner/subagent.";
|
|
32
|
+
}
|
|
33
|
+
if (source.type === "local") {
|
|
34
|
+
return "Verify the source path contains subagent directories with <name>.md files.";
|
|
35
|
+
}
|
|
36
|
+
return "Verify the source is reachable and contains valid subagent directories.";
|
|
37
|
+
};
|
|
38
|
+
const noSubagentsFoundHowToFix = (source) => {
|
|
39
|
+
if (source.type === "registry") {
|
|
40
|
+
return "Verify the owner and subagent name exist in the configured registry.";
|
|
41
|
+
}
|
|
42
|
+
if (source.type === "local") {
|
|
43
|
+
return "Verify the source path contains subagent directories with <name>.md files.";
|
|
44
|
+
}
|
|
45
|
+
return "Verify the source contains subagent directories with <name>.md files.";
|
|
46
|
+
};
|
|
47
|
+
const extractRequestedSubagents = (argSubagents, parsedSource) => argSubagents.length > 0
|
|
48
|
+
? argSubagents
|
|
49
|
+
: parsedSource.pattern.pattern === "name-input"
|
|
50
|
+
? [parsedSource.pattern.name]
|
|
51
|
+
: parsedSource.pattern.pattern === "registry-pattern-input"
|
|
52
|
+
? Option.isSome(parsedSource.pattern.name)
|
|
53
|
+
? [parsedSource.pattern.name.value]
|
|
54
|
+
: []
|
|
55
|
+
: [];
|
|
56
|
+
const extractRequestedOwner = (parsedSource, source) => parsedSource.pattern.pattern === "registry-pattern-input"
|
|
57
|
+
? Option.some(parsedSource.pattern.owner)
|
|
58
|
+
: source.type === "registry"
|
|
59
|
+
? source.owner
|
|
60
|
+
: Option.none();
|
|
61
|
+
const previousResolvedVersion = (entry) => {
|
|
62
|
+
if (typeof entry !== "object" || entry === null)
|
|
63
|
+
return undefined;
|
|
64
|
+
if (!("type" in entry) || entry.type !== "registry")
|
|
65
|
+
return undefined;
|
|
66
|
+
if (!("resolvedVersion" in entry) || typeof entry.resolvedVersion !== "string")
|
|
67
|
+
return undefined;
|
|
68
|
+
return entry.resolvedVersion;
|
|
69
|
+
};
|
|
70
|
+
const previousContentIdentity = (entry) => {
|
|
71
|
+
if (typeof entry !== "object" || entry === null)
|
|
72
|
+
return undefined;
|
|
73
|
+
if (!("contentIdentity" in entry) || typeof entry.contentIdentity !== "string")
|
|
74
|
+
return undefined;
|
|
75
|
+
return entry.contentIdentity;
|
|
76
|
+
};
|
|
77
|
+
const artifactChange = (args) => {
|
|
78
|
+
if (!args.installedBefore)
|
|
79
|
+
return "created";
|
|
80
|
+
const sameVersion = args.previousVersion === args.version;
|
|
81
|
+
const sameSource = args.previousSourceHash === undefined ||
|
|
82
|
+
args.sourceHash === undefined ||
|
|
83
|
+
args.previousSourceHash === args.sourceHash;
|
|
84
|
+
return sameVersion && sameSource ? "unchanged" : "updated";
|
|
85
|
+
};
|
|
86
|
+
/** Read the subagent source grammar and route it to the source that serves it. */
|
|
87
|
+
export const parseSubagentInstallRequest = Effect.fn("InstallExtensions.parseSubagentRequest")(function* (args) {
|
|
88
|
+
const parsedSourceOption = parseInputPattern(args.source.trim());
|
|
89
|
+
if (Option.isNone(parsedSourceOption)) {
|
|
90
|
+
return yield* installRefused({
|
|
91
|
+
category: "validation",
|
|
92
|
+
detail: "Invalid source: Unable to parse source",
|
|
93
|
+
suggestions: [
|
|
94
|
+
{
|
|
95
|
+
description: "Valid formats: local path, github:owner/repo, gitlab:owner/repo, or https://example.com",
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
const parsedSource = parsedSourceOption.value;
|
|
101
|
+
const versionRange = parsedSource.pattern.pattern === "registry-pattern-input"
|
|
102
|
+
? parsedSource.pattern.versionRange
|
|
103
|
+
: Option.none();
|
|
104
|
+
const resolutionProbes = [];
|
|
105
|
+
const source = yield* resolveSubagentInstallSource(parsedSource, {
|
|
106
|
+
onRegistryProbe: (probe) => {
|
|
107
|
+
resolutionProbes.push(probe);
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
return {
|
|
111
|
+
source,
|
|
112
|
+
versionRange,
|
|
113
|
+
requestedSubagents: extractRequestedSubagents(args.subagents, parsedSource),
|
|
114
|
+
requestedOwner: extractRequestedOwner(parsedSource, source),
|
|
115
|
+
resolutionProbes,
|
|
116
|
+
all: args.all,
|
|
117
|
+
nonInteractive: args.nonInteractive,
|
|
118
|
+
};
|
|
119
|
+
});
|
|
120
|
+
/** Discover the subagents the parsed source offers, or refuse when it has none. */
|
|
121
|
+
export const discoverSubagentRefs = Effect.fn("InstallExtensions.discoverSubagents")(function* (request) {
|
|
122
|
+
const sources = yield* SourceHostProviders;
|
|
123
|
+
const discovered = yield* sources
|
|
124
|
+
.find(request.source, {
|
|
125
|
+
names: request.requestedSubagents,
|
|
126
|
+
type: "subagent",
|
|
127
|
+
owner: request.requestedOwner,
|
|
128
|
+
versionRange: request.versionRange,
|
|
129
|
+
})
|
|
130
|
+
.pipe(Effect.map(Array.filter((ref) => ref.type === "subagent")), Effect.mapError((cause) => installRefused({
|
|
131
|
+
category: sourceResolutionFailureCategory(cause) === "not_found" ? "not_found" : "usage",
|
|
132
|
+
detail: "Failed to discover subagents from source",
|
|
133
|
+
suggestions: [{ description: discoverHowToFix(request.source, cause) }],
|
|
134
|
+
cause,
|
|
135
|
+
})));
|
|
136
|
+
if (Array.isReadonlyArrayEmpty(discovered)) {
|
|
137
|
+
return yield* installRefused({
|
|
138
|
+
category: "not_found",
|
|
139
|
+
detail: "No subagents found in source",
|
|
140
|
+
suggestions: [{ description: noSubagentsFoundHowToFix(request.source) }],
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
return discovered;
|
|
144
|
+
});
|
|
145
|
+
/** Settle which of the discovered subagents this request installs. */
|
|
146
|
+
export const finalizeSubagentInstallIntent = Effect.fn("InstallExtensions.finalizeSubagentIntent")(function* (request, discovered) {
|
|
147
|
+
const [first, ...rest] = discovered;
|
|
148
|
+
if (first === undefined) {
|
|
149
|
+
return yield* installRefused({
|
|
150
|
+
category: "not_found",
|
|
151
|
+
detail: "No subagents found in source",
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
const candidates = [first, ...rest];
|
|
155
|
+
const selected = yield* determineSubagentsToInstall(candidates, {
|
|
156
|
+
requestedSubagents: request.requestedSubagents,
|
|
157
|
+
all: request.all,
|
|
158
|
+
nonInteractive: request.nonInteractive,
|
|
159
|
+
});
|
|
160
|
+
if (Array.isReadonlyArrayEmpty(selected)) {
|
|
161
|
+
return { subagentsToInstall: [] };
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
subagentsToInstall: selected.map((ref) => ({
|
|
165
|
+
ref,
|
|
166
|
+
versionRange: ref.refType === "registry" ? request.versionRange : Option.none(),
|
|
167
|
+
})),
|
|
168
|
+
};
|
|
169
|
+
});
|
|
170
|
+
/** The closures a settled subagent intent becomes. */
|
|
171
|
+
export const planSubagentInstall = Effect.fn("InstallExtensions.planSubagents")(function* (intent) {
|
|
172
|
+
const ws = yield* WorkspaceMutations;
|
|
173
|
+
const subagentManager = yield* SubagentManager;
|
|
174
|
+
const agentRepo = yield* CodingAgentRepository;
|
|
175
|
+
// A user-scope workspace can only hold subagents when every configured
|
|
176
|
+
// agent has a user-scope placement to render them into.
|
|
177
|
+
if (ws.scope === "user") {
|
|
178
|
+
const agents = yield* agentRepo.getConfiguredAgents().pipe(Effect.mapError((cause) => installRefused({
|
|
179
|
+
category: "internal",
|
|
180
|
+
detail: "Configured agents could not be read",
|
|
181
|
+
cause,
|
|
182
|
+
})));
|
|
183
|
+
const placements = yield* Effect.forEach(agents, (agent) => agent
|
|
184
|
+
.resolveEffectiveSubagentsDir({ workspaceRoot: ws.baseDir, scope: ws.scope })
|
|
185
|
+
.pipe(Effect.map((outcome) => ({ agentId: agent.id, outcome }))), { concurrency: "unbounded" }).pipe(Effect.mapError((cause) => installRefused({
|
|
186
|
+
category: "internal",
|
|
187
|
+
detail: "Configured subagent placement could not be resolved",
|
|
188
|
+
cause,
|
|
189
|
+
})));
|
|
190
|
+
const refused = placements.flatMap(({ agentId, outcome }) => outcome._tag === "unsupported" ||
|
|
191
|
+
outcome._tag === "misconfigured" ||
|
|
192
|
+
outcome._tag === "disabled"
|
|
193
|
+
? [`${agentId}: ${outcome.reason}`]
|
|
194
|
+
: []);
|
|
195
|
+
if (refused.length > 0) {
|
|
196
|
+
return yield* installRefused({
|
|
197
|
+
category: "validation",
|
|
198
|
+
detail: `Cannot install subagents in user scope for the configured agent placement: ${refused.join("; ")}`,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
const steps = yield* Effect.forEach(intent.subagentsToInstall, (entry) => Effect.gen(function* () {
|
|
203
|
+
const ref = entry.ref;
|
|
204
|
+
const previousLockEntry = yield* ws
|
|
205
|
+
.getLockedSubagent(ref.subagent.name)
|
|
206
|
+
.pipe(Effect.catch(() => Effect.succeed(Option.none())));
|
|
207
|
+
const previousVersion = Option.match(previousLockEntry, {
|
|
208
|
+
onNone: () => undefined,
|
|
209
|
+
onSome: previousResolvedVersion,
|
|
210
|
+
});
|
|
211
|
+
const sourceHashBeforeInstall = Option.match(previousLockEntry, {
|
|
212
|
+
onNone: () => undefined,
|
|
213
|
+
onSome: previousContentIdentity,
|
|
214
|
+
});
|
|
215
|
+
const version = ref.refType === "registry" ? ref.version : undefined;
|
|
216
|
+
return buildInstallOperation(subagentManager, {
|
|
217
|
+
toStepFailure: lifecycleStepFailure,
|
|
218
|
+
ref,
|
|
219
|
+
versionRange: entry.versionRange,
|
|
220
|
+
installedBefore: subagentManager
|
|
221
|
+
.isInstalled({ target: { type: "subagent", name: ref.subagent.name } })
|
|
222
|
+
.pipe(Effect.catch(() => Effect.succeed(false))),
|
|
223
|
+
buildArtifact: ({ installedBefore, materialization, }) => Effect.gen(function* () {
|
|
224
|
+
const lockEntryOption = yield* ws
|
|
225
|
+
.getLockedSubagent(ref.subagent.name)
|
|
226
|
+
.pipe(Effect.catch(() => Effect.succeed(Option.none())));
|
|
227
|
+
const sourceHash = previousContentIdentity(Option.getOrUndefined(lockEntryOption));
|
|
228
|
+
const change = artifactChange({
|
|
229
|
+
installedBefore,
|
|
230
|
+
previousVersion,
|
|
231
|
+
version,
|
|
232
|
+
previousSourceHash: sourceHashBeforeInstall,
|
|
233
|
+
sourceHash,
|
|
234
|
+
});
|
|
235
|
+
const observation = Option.match(materialization, {
|
|
236
|
+
onNone: () => NO_MATERIALIZATION_OBSERVATION,
|
|
237
|
+
onSome: (facts) => facts.observation,
|
|
238
|
+
});
|
|
239
|
+
const targets = observation.targets.map((target) => ({
|
|
240
|
+
path: target.path,
|
|
241
|
+
change,
|
|
242
|
+
...(target.agentIds === undefined ? {} : { agentIds: target.agentIds }),
|
|
243
|
+
}));
|
|
244
|
+
return {
|
|
245
|
+
path: targets[0]?.path ?? ref.subagent.name,
|
|
246
|
+
scope: ws.scope,
|
|
247
|
+
agents: observation.agents,
|
|
248
|
+
...(version !== undefined ? { version } : {}),
|
|
249
|
+
change,
|
|
250
|
+
...(previousVersion !== undefined && previousVersion !== version
|
|
251
|
+
? { previousVersion }
|
|
252
|
+
: {}),
|
|
253
|
+
...(targets.length === 0 ? {} : { fileCount: targets.length, targets }),
|
|
254
|
+
};
|
|
255
|
+
}),
|
|
256
|
+
});
|
|
257
|
+
}).pipe(Effect.mapError((cause) => installRefused({
|
|
258
|
+
category: "internal",
|
|
259
|
+
detail: `Subagent install planning failed for ${entry.ref.subagent.name}`,
|
|
260
|
+
cause,
|
|
261
|
+
}))), { concurrency: 1 });
|
|
262
|
+
return {
|
|
263
|
+
_tag: "Plan",
|
|
264
|
+
name: intent.subagentsToInstall.length === 1 ? "Install subagent" : "Install subagents",
|
|
265
|
+
description: Option.none(),
|
|
266
|
+
presentation: operationPresentation({ imperative: "install", past: "Installed", gerund: "Installing" }, "subagent"),
|
|
267
|
+
jobs: [{ concurrency: 1, steps }],
|
|
268
|
+
};
|
|
269
|
+
});
|
|
270
|
+
//# sourceMappingURL=plan.js.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which of a source's subagents this request installs.
|
|
3
|
+
*
|
|
4
|
+
* The same decision the skill route makes, over subagent names: named
|
|
5
|
+
* patterns must match, `--all` and an unattended invocation take everything,
|
|
6
|
+
* a single subagent needs no decision, and anything else is a person's
|
|
7
|
+
* choice.
|
|
8
|
+
*
|
|
9
|
+
* @experimental This API is unstable and may change without notice.
|
|
10
|
+
*/
|
|
11
|
+
import * as Array from "effect/Array";
|
|
12
|
+
import * as Effect from "effect/Effect";
|
|
13
|
+
import type { SubagentExtensionRef } from "@agentxm/extension-model/unstable/extensions/refs/subagent";
|
|
14
|
+
import type { ExtensionLifecycleFailed } from "../../errors.js";
|
|
15
|
+
import { ExtensionSelectionInteraction, type ExtensionSelectionCancelled } from "../../install/selection-interaction.js";
|
|
16
|
+
export interface SubagentSelectionRequest {
|
|
17
|
+
/** Names or glob patterns the request named explicitly. */
|
|
18
|
+
readonly requestedSubagents: ReadonlyArray<string>;
|
|
19
|
+
/** Take everything the source offers without asking. */
|
|
20
|
+
readonly all: boolean;
|
|
21
|
+
/** No prompt can open in this invocation. */
|
|
22
|
+
readonly nonInteractive: boolean;
|
|
23
|
+
}
|
|
24
|
+
/** Settle which discovered subagents this request installs. */
|
|
25
|
+
export declare const determineSubagentsToInstall: (subagents: Array.NonEmptyReadonlyArray<SubagentExtensionRef>, request: SubagentSelectionRequest) => Effect.Effect<ReadonlyArray<SubagentExtensionRef>, ExtensionLifecycleFailed | ExtensionSelectionCancelled, ExtensionSelectionInteraction>;
|
|
26
|
+
//# sourceMappingURL=selection.d.ts.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which of a source's subagents this request installs.
|
|
3
|
+
*
|
|
4
|
+
* The same decision the skill route makes, over subagent names: named
|
|
5
|
+
* patterns must match, `--all` and an unattended invocation take everything,
|
|
6
|
+
* a single subagent needs no decision, and anything else is a person's
|
|
7
|
+
* choice.
|
|
8
|
+
*
|
|
9
|
+
* @experimental This API is unstable and may change without notice.
|
|
10
|
+
*/
|
|
11
|
+
import * as Array from "effect/Array";
|
|
12
|
+
import * as Effect from "effect/Effect";
|
|
13
|
+
import { expandGlobs } from "../../glob.js";
|
|
14
|
+
import { ExtensionSelectionInteraction, } from "../../install/selection-interaction.js";
|
|
15
|
+
import { installRefused } from "../../install/vocabulary.js";
|
|
16
|
+
/** Settle which discovered subagents this request installs. */
|
|
17
|
+
export const determineSubagentsToInstall = Effect.fn("InstallExtensions.determineSubagentsToInstall")(function* (subagents, request) {
|
|
18
|
+
if (request.requestedSubagents.length > 0) {
|
|
19
|
+
const allNames = Array.map(subagents, (subagent) => subagent.subagent.name);
|
|
20
|
+
const matched = expandGlobs(request.requestedSubagents, allNames);
|
|
21
|
+
if (matched.length === 0) {
|
|
22
|
+
return yield* installRefused({
|
|
23
|
+
category: "internal",
|
|
24
|
+
detail: `No subagents matched: ${request.requestedSubagents.join(", ")}`,
|
|
25
|
+
suggestions: [{ description: "Check the subagent names or patterns and try again." }],
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return Array.filter(subagents, (subagent) => matched.includes(subagent.subagent.name));
|
|
29
|
+
}
|
|
30
|
+
if (request.all || request.nonInteractive)
|
|
31
|
+
return subagents;
|
|
32
|
+
if (subagents.length === 1)
|
|
33
|
+
return subagents;
|
|
34
|
+
const interaction = yield* ExtensionSelectionInteraction;
|
|
35
|
+
return yield* interaction.selectSubagents(subagents);
|
|
36
|
+
});
|
|
37
|
+
//# sourceMappingURL=selection.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which source a subagent install request names.
|
|
3
|
+
*
|
|
4
|
+
* The same routing the skill request uses, minus the SCP address form, which
|
|
5
|
+
* no subagent source has ever been published under.
|
|
6
|
+
*
|
|
7
|
+
* @experimental This API is unstable and may change without notice.
|
|
8
|
+
*/
|
|
9
|
+
import * as Effect from "effect/Effect";
|
|
10
|
+
import type { InputParseResult } from "@agentxm/extension-model/unstable/sources/parser";
|
|
11
|
+
import type { Source } from "@agentxm/extension-model/unstable/sources/types";
|
|
12
|
+
import { type SourceResolutionFailure } from "@agentxm/extension-sources";
|
|
13
|
+
import type { ExtensionLifecycleFailed } from "../../errors.js";
|
|
14
|
+
import { type RegistryResolutionOptions } from "../../install/registry-source-resolution.js";
|
|
15
|
+
import { type ResolveInstallRequirements } from "../../install/vocabulary.js";
|
|
16
|
+
/** Route one parsed subagent locator to the source that serves it. */
|
|
17
|
+
export declare const resolveSubagentInstallSource: (parseResult: InputParseResult, options?: RegistryResolutionOptions) => Effect.Effect<Source, ExtensionLifecycleFailed | SourceResolutionFailure, ResolveInstallRequirements>;
|
|
18
|
+
//# sourceMappingURL=source.d.ts.map
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which source a subagent install request names.
|
|
3
|
+
*
|
|
4
|
+
* The same routing the skill request uses, minus the SCP address form, which
|
|
5
|
+
* no subagent source has ever been published under.
|
|
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 { resolveShorthandInputSource, resolveSlashInputSource, routeUrlInput, } from "@agentxm/extension-sources";
|
|
12
|
+
import { resolveConfiguredRegistrySource, resolveDefaultRegistrySourceByName, } from "../../install/registry-source-resolution.js";
|
|
13
|
+
import { installRefused } from "../../install/vocabulary.js";
|
|
14
|
+
const resolveSubagentRegistrySource = (pattern, options) => Effect.gen(function* () {
|
|
15
|
+
if (Option.isSome(pattern.type) && pattern.type.value !== "subagents") {
|
|
16
|
+
return yield* installRefused({
|
|
17
|
+
category: "usage",
|
|
18
|
+
detail: `Cannot install "${pattern.type.value}" extensions with "subagents install"`,
|
|
19
|
+
recover: `Use the "${pattern.type.value}" command instead, or remove the type qualifier to install as a subagent`,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
return yield* resolveConfiguredRegistrySource({
|
|
23
|
+
sourceName: pattern.sourceName,
|
|
24
|
+
owner: pattern.owner,
|
|
25
|
+
extensionType: "subagent",
|
|
26
|
+
extensionName: pattern.name,
|
|
27
|
+
options,
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
/** Route one parsed subagent locator to the source that serves it. */
|
|
31
|
+
export const resolveSubagentInstallSource = Effect.fn("InstallExtensions.resolveSubagentSource")(function* (parseResult, options) {
|
|
32
|
+
const resolutionOptions = Option.fromUndefinedOr(options);
|
|
33
|
+
const pattern = parseResult.pattern;
|
|
34
|
+
switch (pattern.pattern) {
|
|
35
|
+
case "registry-pattern-input":
|
|
36
|
+
return yield* resolveSubagentRegistrySource(pattern, resolutionOptions);
|
|
37
|
+
case "shorthand-input":
|
|
38
|
+
return yield* resolveShorthandInputSource({
|
|
39
|
+
pattern,
|
|
40
|
+
originalInput: parseResult.originalInput,
|
|
41
|
+
});
|
|
42
|
+
case "slash-pattern":
|
|
43
|
+
return yield* resolveSlashInputSource(pattern, parseResult.originalInput);
|
|
44
|
+
case "name-input":
|
|
45
|
+
return yield* resolveDefaultRegistrySourceByName({
|
|
46
|
+
name: pattern.name,
|
|
47
|
+
extensionType: "subagent",
|
|
48
|
+
options: resolutionOptions,
|
|
49
|
+
});
|
|
50
|
+
case "url-input":
|
|
51
|
+
return yield* routeUrlInput(pattern.url, parseResult.originalInput);
|
|
52
|
+
case "file-path-pattern":
|
|
53
|
+
return { type: "local", path: pattern.path };
|
|
54
|
+
case "workspace-pattern-input":
|
|
55
|
+
return yield* installRefused({
|
|
56
|
+
category: "conflict",
|
|
57
|
+
detail: `Workspace source "${parseResult.originalInput}" is locally authoritative and cannot be installed over`,
|
|
58
|
+
suggestions: [
|
|
59
|
+
{ description: "Sync the workspace package", cmd: "axm sync" },
|
|
60
|
+
{ description: "Enable the workspace subagent", cmd: "axm subagents enable <name>" },
|
|
61
|
+
],
|
|
62
|
+
});
|
|
63
|
+
case "git-scp-address":
|
|
64
|
+
case "glob-input":
|
|
65
|
+
return yield* installRefused({
|
|
66
|
+
category: "usage",
|
|
67
|
+
detail: `Input pattern "${pattern.pattern}" is not supported for subagent installation`,
|
|
68
|
+
recover: "Use a registry reference (e.g., @owner/subagents/name), a URL, or a shorthand (owner/repo) instead",
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
//# sourceMappingURL=source.js.map
|
|
@@ -6,13 +6,15 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @experimental This API is unstable and may change without notice.
|
|
8
8
|
*/
|
|
9
|
+
import { NativeWriteAuthority } from "@agentxm/agent-integration";
|
|
9
10
|
import * as FileSystem from "effect/FileSystem";
|
|
10
11
|
import * as Path from "effect/Path";
|
|
11
|
-
import { CodingAgentRepository } from "@agentxm/
|
|
12
|
-
import {
|
|
12
|
+
import { CodingAgentRepository } from "@agentxm/workspace-projection";
|
|
13
|
+
import { StepFailureConversion } from "../../step-failure-conversion.js";
|
|
13
14
|
import type { OperationHandler } from "@agentxm/workspace-operations";
|
|
14
15
|
import type { Operation } from "@agentxm/workspace-operations";
|
|
15
16
|
import { WorkspaceMutations } from "@agentxm/workspace-state";
|
|
17
|
+
import { WorkspaceTransactionScope } from "@agentxm/workspace-transactions";
|
|
16
18
|
/**
|
|
17
19
|
* Disable a subagent (remove rendered files but keep settings/lockfile entry).
|
|
18
20
|
*
|
|
@@ -28,5 +30,5 @@ export type DisableSubagentOperation = Operation<"disable-subagent", {
|
|
|
28
30
|
* rendered files, and promotes implicit pack members to a direct disabled
|
|
29
31
|
* preference. Canonical source files are preserved for later re-enablement.
|
|
30
32
|
*/
|
|
31
|
-
export declare const disableSubagent: OperationHandler<DisableSubagentOperation, FileSystem.FileSystem | Path.Path | WorkspaceMutations | CodingAgentRepository |
|
|
33
|
+
export declare const disableSubagent: OperationHandler<DisableSubagentOperation, FileSystem.FileSystem | Path.Path | WorkspaceMutations | WorkspaceTransactionScope | CodingAgentRepository | NativeWriteAuthority | StepFailureConversion>;
|
|
32
34
|
//# sourceMappingURL=disable.d.ts.map
|
|
@@ -6,14 +6,16 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @experimental This API is unstable and may change without notice.
|
|
8
8
|
*/
|
|
9
|
+
import { NativeWriteAuthority } from "@agentxm/agent-integration";
|
|
9
10
|
import * as FileSystem from "effect/FileSystem";
|
|
10
11
|
import * as Path from "effect/Path";
|
|
11
12
|
import * as Effect from "effect/Effect";
|
|
12
13
|
import * as Option from "effect/Option";
|
|
13
|
-
import { CodingAgentRepository, findManagedSubagentFiles } from "@agentxm/
|
|
14
|
+
import { CodingAgentRepository, findManagedSubagentFiles } from "@agentxm/workspace-projection";
|
|
14
15
|
import { ExtensionLifecycleFailed } from "../../errors.js";
|
|
15
|
-
import {
|
|
16
|
+
import { StepFailureConversion, withAdaptedStepFailures } from "../../step-failure-conversion.js";
|
|
16
17
|
import { WorkspaceMutations } from "@agentxm/workspace-state";
|
|
18
|
+
import { WorkspaceTransactionScope, runWorkspaceTransaction, } from "@agentxm/workspace-transactions";
|
|
17
19
|
import { subagentLifecycleArtifact } from "./artifact.js";
|
|
18
20
|
import * as Layer from "effect/Layer";
|
|
19
21
|
import * as Schema from "effect/Schema";
|
|
@@ -53,7 +55,7 @@ export const disableSubagent = (op) => Effect.gen(function* () {
|
|
|
53
55
|
const desiredBeforeDisable = graph.nodes.find((node) => node.type === "subagent" && node.name === op.args.subagentName);
|
|
54
56
|
const renderedFiles = {};
|
|
55
57
|
const configuredAgents = yield* agentRepo.getConfiguredAgents();
|
|
56
|
-
yield*
|
|
58
|
+
yield* runWorkspaceTransaction({
|
|
57
59
|
transition: Effect.gen(function* () {
|
|
58
60
|
if (isImplicit) {
|
|
59
61
|
const source = desiredBeforeDisable?.source ?? Option.getOrElse(installed.source, () => undefined);
|