@agentxm/extension-materialization 0.28.14-preview.1789139351.5cd4595aa
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/LICENSE +110 -0
- package/README.md +16 -0
- package/dist/src/desired-state/errors.d.ts +22 -0
- package/dist/src/desired-state/errors.js +22 -0
- package/dist/src/desired-state/retained-materialization.d.ts +58 -0
- package/dist/src/desired-state/retained-materialization.js +119 -0
- package/dist/src/errors.d.ts +42 -0
- package/dist/src/errors.js +14 -0
- package/dist/src/extensions/canonical-directory.d.ts +106 -0
- package/dist/src/extensions/canonical-directory.js +210 -0
- package/dist/src/extensions/canonical-reuse.d.ts +43 -0
- package/dist/src/extensions/canonical-reuse.js +38 -0
- package/dist/src/extensions/copy-directory.d.ts +50 -0
- package/dist/src/extensions/copy-directory.js +78 -0
- package/dist/src/extensions/errors.d.ts +97 -0
- package/dist/src/extensions/errors.js +42 -0
- package/dist/src/extensions/materializable-from-disk.d.ts +37 -0
- package/dist/src/extensions/materializable-from-disk.js +89 -0
- package/dist/src/extensions/operations.d.ts +252 -0
- package/dist/src/extensions/operations.js +631 -0
- package/dist/src/hooks/errors.d.ts +33 -0
- package/dist/src/hooks/errors.js +18 -0
- package/dist/src/hooks/manager.d.ts +13 -0
- package/dist/src/hooks/manager.js +778 -0
- package/dist/src/index.d.ts +44 -0
- package/dist/src/index.js +56 -0
- package/dist/src/knowledge/errors.d.ts +75 -0
- package/dist/src/knowledge/errors.js +36 -0
- package/dist/src/knowledge/manager.d.ts +9 -0
- package/dist/src/knowledge/manager.js +709 -0
- package/dist/src/live.d.ts +20 -0
- package/dist/src/live.js +20 -0
- package/dist/src/manager-contract.d.ts +136 -0
- package/dist/src/manager-contract.js +19 -0
- package/dist/src/manager-registry-live.d.ts +11 -0
- package/dist/src/manager-registry-live.js +23 -0
- package/dist/src/manager-registry.d.ts +37 -0
- package/dist/src/manager-registry.js +22 -0
- package/dist/src/managers.d.ts +147 -0
- package/dist/src/managers.js +32 -0
- package/dist/src/mcps/artifact.d.ts +24 -0
- package/dist/src/mcps/artifact.js +74 -0
- package/dist/src/mcps/authored-materialization.d.ts +28 -0
- package/dist/src/mcps/authored-materialization.js +34 -0
- package/dist/src/mcps/errors.d.ts +105 -0
- package/dist/src/mcps/errors.js +40 -0
- package/dist/src/mcps/install-operation.d.ts +92 -0
- package/dist/src/mcps/install-operation.js +557 -0
- package/dist/src/mcps/manager.d.ts +15 -0
- package/dist/src/mcps/manager.js +253 -0
- package/dist/src/mcps/native-entry.d.ts +51 -0
- package/dist/src/mcps/native-entry.js +100 -0
- package/dist/src/mcps/secret-store-live.d.ts +14 -0
- package/dist/src/mcps/secret-store-live.js +58 -0
- package/dist/src/mcps/secret-store.d.ts +55 -0
- package/dist/src/mcps/secret-store.js +33 -0
- package/dist/src/packs/errors.d.ts +50 -0
- package/dist/src/packs/errors.js +24 -0
- package/dist/src/packs/manager.d.ts +16 -0
- package/dist/src/packs/manager.js +189 -0
- package/dist/src/projection-participants-live.d.ts +17 -0
- package/dist/src/projection-participants-live.js +66 -0
- package/dist/src/projection-step-failure.d.ts +19 -0
- package/dist/src/projection-step-failure.js +76 -0
- package/dist/src/registry-materialization.d.ts +52 -0
- package/dist/src/registry-materialization.js +67 -0
- package/dist/src/rules/errors.d.ts +31 -0
- package/dist/src/rules/errors.js +17 -0
- package/dist/src/rules/manager.d.ts +18 -0
- package/dist/src/rules/manager.js +492 -0
- package/dist/src/skills/errors.d.ts +42 -0
- package/dist/src/skills/errors.js +21 -0
- package/dist/src/skills/manager.d.ts +17 -0
- package/dist/src/skills/manager.js +339 -0
- package/dist/src/skills/materialization.d.ts +52 -0
- package/dist/src/skills/materialization.js +168 -0
- package/dist/src/skills/skill-artifact.d.ts +38 -0
- package/dist/src/skills/skill-artifact.js +70 -0
- package/dist/src/skills/source-hash.d.ts +2 -0
- package/dist/src/skills/source-hash.js +6 -0
- package/dist/src/subagents/errors.d.ts +43 -0
- package/dist/src/subagents/errors.js +20 -0
- package/dist/src/subagents/lock-entry-builder.d.ts +20 -0
- package/dist/src/subagents/lock-entry-builder.js +63 -0
- package/dist/src/subagents/manager.d.ts +17 -0
- package/dist/src/subagents/manager.js +736 -0
- package/dist/src/testing.d.ts +87 -0
- package/dist/src/testing.js +116 -0
- package/package.json +70 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pack manager service.
|
|
3
|
+
*
|
|
4
|
+
* Implements ExtensionManager<PackRef>. Delegates to existing
|
|
5
|
+
* pack materialization functions and workspace service methods.
|
|
6
|
+
*
|
|
7
|
+
* @experimental This API is unstable and may change without notice.
|
|
8
|
+
*/
|
|
9
|
+
import * as FileSystem from "effect/FileSystem";
|
|
10
|
+
import * as Path from "effect/Path";
|
|
11
|
+
import * as Effect from "effect/Effect";
|
|
12
|
+
import * as Layer from "effect/Layer";
|
|
13
|
+
import * as Option from "effect/Option";
|
|
14
|
+
import { PackArchiveFetchFailed, PackDefinitionInvalid, PackInstallStateMissing, PackStagingFailed, } from "./errors.js";
|
|
15
|
+
import { canReuseInstalledPackage, replaceCanonicalDirectoryWithInspection, } from "../extensions/canonical-directory.js";
|
|
16
|
+
import { configuredPacksToDiskRefs } from "../extensions/materializable-from-disk.js";
|
|
17
|
+
import { SourceHostProviders } from "@agentxm/extension-sources";
|
|
18
|
+
import { NO_MATERIALIZATION_OBSERVATION } from "../manager-contract.js";
|
|
19
|
+
import { PackManager } from "../managers.js";
|
|
20
|
+
import { WorkspaceMutations } from "@agentxm/workspace-state";
|
|
21
|
+
import { copyExtensionDirectory } from "../extensions/copy-directory.js";
|
|
22
|
+
import { computePackPathsForLayout } from "@agentxm/workspace-state";
|
|
23
|
+
import { removeIfExists } from "@agentxm/workspace-state";
|
|
24
|
+
import { acceptedRegistryVersionForRef, validateExactResolvedVersion, } from "@agentxm/workspace-state";
|
|
25
|
+
import { decodeVersionSync } from "@agentxm/extension-model/unstable/version-constraints";
|
|
26
|
+
import { configuredRowsByName } from "@agentxm/workspace-state";
|
|
27
|
+
import { isObservedInstalled } from "@agentxm/workspace-state";
|
|
28
|
+
import { acceptedCanonicalObservation, prepareAcceptedCanonicalTransition, removableAcceptedCanonicalPath, } from "@agentxm/workspace-state";
|
|
29
|
+
import { computePackManifestContentIdentity } from "@agentxm/workspace-state";
|
|
30
|
+
import { computeMaterializedTreeIntegrity, } from "@agentxm/workspace-state";
|
|
31
|
+
// Build pack SetPackArgs from a registry ref
|
|
32
|
+
const buildSetPackArgs = (ref, versionRange, treeIntegrity) => ({
|
|
33
|
+
type: "registry",
|
|
34
|
+
sourceType: "registry",
|
|
35
|
+
packageFormat: "agentxm",
|
|
36
|
+
endpoint: ref.source.location,
|
|
37
|
+
extensionType: "pack",
|
|
38
|
+
workspaceName: ref.pack.name,
|
|
39
|
+
owner: ref.owner,
|
|
40
|
+
name: ref.pack.name,
|
|
41
|
+
resolvedVersion: decodeVersionSync(ref.version),
|
|
42
|
+
integrity: Option.getOrElse(ref.integrity, () => ""),
|
|
43
|
+
sourceName: ref.source.name,
|
|
44
|
+
publisherBindingId: ref.publisherBindingId,
|
|
45
|
+
treeIntegrity,
|
|
46
|
+
manifestContentIdentity: computePackManifestContentIdentity({
|
|
47
|
+
owner: ref.owner,
|
|
48
|
+
type: "pack",
|
|
49
|
+
name: ref.pack.name,
|
|
50
|
+
version: ref.version,
|
|
51
|
+
dependencies: ref.pack.dependencies,
|
|
52
|
+
}),
|
|
53
|
+
versionRange,
|
|
54
|
+
});
|
|
55
|
+
// -----------------------------------------------------------------------------
|
|
56
|
+
// Live Layer
|
|
57
|
+
// -----------------------------------------------------------------------------
|
|
58
|
+
export const PackManagerLive = Layer.effect(PackManager, Effect.gen(function* () {
|
|
59
|
+
const ws = yield* WorkspaceMutations;
|
|
60
|
+
const fs = yield* FileSystem.FileSystem;
|
|
61
|
+
const path = yield* Path.Path;
|
|
62
|
+
const sources = yield* SourceHostProviders;
|
|
63
|
+
const baseDir = ws.baseDir;
|
|
64
|
+
const noContent = {
|
|
65
|
+
observation: NO_MATERIALIZATION_OBSERVATION,
|
|
66
|
+
treeIntegrity: Option.none(),
|
|
67
|
+
};
|
|
68
|
+
const acquired = (treeIntegrity) => ({
|
|
69
|
+
observation: NO_MATERIALIZATION_OBSERVATION,
|
|
70
|
+
treeIntegrity: Option.some(treeIntegrity),
|
|
71
|
+
});
|
|
72
|
+
const materializeInstall = Effect.fn("PackManager.materializeInstall")(function* ({ ref, force, }) {
|
|
73
|
+
if (ref.refType === "registry") {
|
|
74
|
+
yield* validateExactResolvedVersion(`packs.${ref.pack.name}.resolvedVersion`, ref.version);
|
|
75
|
+
}
|
|
76
|
+
const packDir = computePackPathsForLayout(path.join, ws.layout, ref.refType === "workspace" ? "workspace" : ref.source.name, ref.owner, ref.pack.name).canonicalPath;
|
|
77
|
+
const canonicalExists = yield* fs.exists(packDir).pipe(Effect.orElseSucceed(() => false));
|
|
78
|
+
if (ref.refType === "workspace") {
|
|
79
|
+
if (ref.scope !== ws.scope || path.resolve(ref.location) !== path.resolve(packDir)) {
|
|
80
|
+
return yield* new PackDefinitionInvalid({
|
|
81
|
+
detail: `Invalid workspace pack source location: ${ref.location}`,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
if (!canonicalExists) {
|
|
85
|
+
return yield* new PackDefinitionInvalid({
|
|
86
|
+
detail: `Workspace pack package is missing: ${packDir}`,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
return noContent;
|
|
90
|
+
}
|
|
91
|
+
const lockedEntry = yield* ws.getLockedPack(ref.pack.name);
|
|
92
|
+
const lockedVersion = acceptedRegistryVersionForRef(lockedEntry, ref);
|
|
93
|
+
if (yield* canReuseInstalledPackage({
|
|
94
|
+
installedPath: packDir,
|
|
95
|
+
force: force === true,
|
|
96
|
+
refVersion: ref.version,
|
|
97
|
+
hasIntegrity: Option.isSome(ref.integrity),
|
|
98
|
+
...(lockedVersion === undefined ? {} : { lockedVersion }),
|
|
99
|
+
existsFailureDetail: (target) => `Failed to check if canonical pack path exists: ${target}`,
|
|
100
|
+
})) {
|
|
101
|
+
if (Option.isSome(lockedEntry)) {
|
|
102
|
+
const observedTree = yield* computeMaterializedTreeIntegrity(packDir);
|
|
103
|
+
if (observedTree === lockedEntry.value.treeIntegrity) {
|
|
104
|
+
return acquired(lockedEntry.value.treeIntegrity);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return yield* Effect.scoped(Effect.gen(function* () {
|
|
109
|
+
const fetched = yield* sources
|
|
110
|
+
.fetch(ref)
|
|
111
|
+
.pipe(Effect.mapError((e) => new PackArchiveFetchFailed({ message: e.message, cause: e })));
|
|
112
|
+
const materialized = yield* replaceCanonicalDirectoryWithInspection({
|
|
113
|
+
baseDir,
|
|
114
|
+
canonicalPath: packDir,
|
|
115
|
+
populate: (stagingPath) => copyExtensionDirectory(fetched.directory, stagingPath).pipe(Effect.mapError((cause) => new PackStagingFailed({ packDir, cause }))),
|
|
116
|
+
inspect: computeMaterializedTreeIntegrity,
|
|
117
|
+
});
|
|
118
|
+
return acquired(materialized.inspection);
|
|
119
|
+
}));
|
|
120
|
+
});
|
|
121
|
+
const materializeUninstall = Effect.fn("PackManager.materializeUninstall")(function* ({ target, }) {
|
|
122
|
+
const canonical = yield* acceptedCanonicalObservation({
|
|
123
|
+
workspace: ws,
|
|
124
|
+
type: "pack",
|
|
125
|
+
name: target.name,
|
|
126
|
+
});
|
|
127
|
+
const packDir = removableAcceptedCanonicalPath(canonical);
|
|
128
|
+
if (Option.isSome(packDir))
|
|
129
|
+
yield* removeIfExists(fs, packDir.value);
|
|
130
|
+
return noContent;
|
|
131
|
+
});
|
|
132
|
+
const materializeDeactivate = () => Effect.succeed(noContent);
|
|
133
|
+
const buildCurrentPackArgs = (ref, versionRange, materialization) => Effect.gen(function* () {
|
|
134
|
+
if (ref.refType !== "registry")
|
|
135
|
+
return Option.none();
|
|
136
|
+
const treeIntegrity = materialization.pipe(Option.flatMap((facts) => facts.treeIntegrity));
|
|
137
|
+
if (Option.isNone(treeIntegrity)) {
|
|
138
|
+
return yield* new PackInstallStateMissing({ name: ref.pack.name });
|
|
139
|
+
}
|
|
140
|
+
return Option.some(buildSetPackArgs(ref, versionRange, treeIntegrity.value));
|
|
141
|
+
});
|
|
142
|
+
return {
|
|
143
|
+
type: "pack",
|
|
144
|
+
isInstalled: Effect.fn("PackManager.isInstalled")(function* ({ target, }) {
|
|
145
|
+
return yield* isObservedInstalled(ws, "pack", target.name);
|
|
146
|
+
}),
|
|
147
|
+
materializeInstall,
|
|
148
|
+
prepareSourceTransition: ({ ref }) => prepareAcceptedCanonicalTransition({
|
|
149
|
+
workspace: ws,
|
|
150
|
+
type: "pack",
|
|
151
|
+
name: ref.pack.name,
|
|
152
|
+
ref,
|
|
153
|
+
}),
|
|
154
|
+
getConfiguredSource: Effect.fn("PackManager.getConfiguredSource")(function* ({ target }) {
|
|
155
|
+
const configured = yield* ws.getConfiguredPackEntries();
|
|
156
|
+
return Option.fromUndefinedOr(configured[target.name]?.source);
|
|
157
|
+
}),
|
|
158
|
+
listMaterializable: Effect.fn("PackManager.listMaterializable")(function* () {
|
|
159
|
+
const configured = yield* ws.records.rows("pack").pipe(Effect.map(configuredRowsByName));
|
|
160
|
+
return yield* configuredPacksToDiskRefs({ fs, path, baseDir, scope: ws.scope, layout: ws.layout }, configured);
|
|
161
|
+
}),
|
|
162
|
+
materializeUninstall,
|
|
163
|
+
materializeDeactivate,
|
|
164
|
+
upsertSettingsEntry: Effect.fn("PackManager.upsertSettingsEntry")(function* ({ ref, versionRange, materialization, }) {
|
|
165
|
+
const args = yield* buildCurrentPackArgs(ref, versionRange, materialization);
|
|
166
|
+
if (Option.isSome(args)) {
|
|
167
|
+
yield* ws.setPack(args.value);
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
yield* ws.setPackEntry(ref.pack.name, {
|
|
171
|
+
source: "workspace",
|
|
172
|
+
enabled: true,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}),
|
|
176
|
+
removeSettingsEntry: ({ target }) => ws.removePackSettings(target.name).pipe(Effect.withSpan("PackManager.removeSettingsEntry")),
|
|
177
|
+
upsertLockfileEntry: Effect.fn("PackManager.upsertLockfileEntry")(function* ({ ref, materialization, }) {
|
|
178
|
+
const args = yield* buildCurrentPackArgs(ref, Option.none(), materialization);
|
|
179
|
+
if (Option.isSome(args)) {
|
|
180
|
+
yield* ws.setPackLock(args.value);
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
yield* ws.removePackLock(ref.pack.name);
|
|
184
|
+
}
|
|
185
|
+
}),
|
|
186
|
+
removeLockfileEntry: ({ target }) => ws.removePackLock(target.name).pipe(Effect.withSpan("PackManager.removeLockfileEntry")),
|
|
187
|
+
};
|
|
188
|
+
}));
|
|
189
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registration of the extension-type managers as projection participants.
|
|
3
|
+
*
|
|
4
|
+
* `workspace-projection` evaluates the invariant facts without knowing which
|
|
5
|
+
* capability materializes a unit; the owners register here instead. Each
|
|
6
|
+
* manager's failure family is restated in projection's participant vocabulary:
|
|
7
|
+
* projection's own failures pass through typed, and anything else becomes
|
|
8
|
+
* `ProjectionParticipantFailed` naming the unit and the failure the manager
|
|
9
|
+
* decided.
|
|
10
|
+
*
|
|
11
|
+
* @experimental This API is unstable and may change without notice.
|
|
12
|
+
*/
|
|
13
|
+
import * as Layer from "effect/Layer";
|
|
14
|
+
import { HookManager, KnowledgeManager, RuleManager, SubagentManager } from "./managers.js";
|
|
15
|
+
import { ProjectionParticipants } from "@agentxm/workspace-projection";
|
|
16
|
+
export declare const ProjectionParticipantsLive: Layer.Layer<ProjectionParticipants, never, SubagentManager | RuleManager | HookManager | KnowledgeManager>;
|
|
17
|
+
//# sourceMappingURL=projection-participants-live.d.ts.map
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registration of the extension-type managers as projection participants.
|
|
3
|
+
*
|
|
4
|
+
* `workspace-projection` evaluates the invariant facts without knowing which
|
|
5
|
+
* capability materializes a unit; the owners register here instead. Each
|
|
6
|
+
* manager's failure family is restated in projection's participant vocabulary:
|
|
7
|
+
* projection's own failures pass through typed, and anything else becomes
|
|
8
|
+
* `ProjectionParticipantFailed` naming the unit and the failure the manager
|
|
9
|
+
* decided.
|
|
10
|
+
*
|
|
11
|
+
* @experimental This API is unstable and may change without notice.
|
|
12
|
+
*/
|
|
13
|
+
import * as Effect from "effect/Effect";
|
|
14
|
+
import * as Layer from "effect/Layer";
|
|
15
|
+
import * as Option from "effect/Option";
|
|
16
|
+
import { HookManager, KnowledgeManager, RuleManager, SubagentManager } from "./managers.js";
|
|
17
|
+
import { isProjectionError, mapProjectionPlanFailure, ProjectionParticipantFailed, ProjectionParticipants, } from "@agentxm/workspace-projection";
|
|
18
|
+
/**
|
|
19
|
+
* A manager failure stated in projection's vocabulary. Projection's own
|
|
20
|
+
* family keeps its exact identity; every other failure is named by the unit it
|
|
21
|
+
* blocked and the failure the manager decided, without an application error
|
|
22
|
+
* envelope and without rendering.
|
|
23
|
+
*/
|
|
24
|
+
const toParticipantFailure = (unitId) => (failure) => isProjectionError(failure)
|
|
25
|
+
? failure
|
|
26
|
+
: new ProjectionParticipantFailed({
|
|
27
|
+
unitId,
|
|
28
|
+
detail: `The owner of ${unitId} could not project it (${failure._tag}).`,
|
|
29
|
+
});
|
|
30
|
+
const participant = (args) => {
|
|
31
|
+
const onFailure = toParticipantFailure(args.failureUnitId);
|
|
32
|
+
return {
|
|
33
|
+
units: args.units,
|
|
34
|
+
projectionPlans: () => args.manager.projectionPlans().pipe(Effect.map((plans) => plans.map((plan) => mapProjectionPlanFailure(plan, onFailure))), Effect.mapError(onFailure)),
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
export const ProjectionParticipantsLive = Layer.effect(ProjectionParticipants, Effect.gen(function* () {
|
|
38
|
+
const rules = yield* RuleManager;
|
|
39
|
+
const hooks = yield* HookManager;
|
|
40
|
+
const knowledge = yield* KnowledgeManager;
|
|
41
|
+
const subagents = yield* SubagentManager;
|
|
42
|
+
const onSubagentFailure = toParticipantFailure("subagent:native-profile");
|
|
43
|
+
return {
|
|
44
|
+
aggregates: [
|
|
45
|
+
participant({
|
|
46
|
+
units: ["rule:instructions-region"],
|
|
47
|
+
failureUnitId: "rule:instructions-region",
|
|
48
|
+
manager: rules,
|
|
49
|
+
}),
|
|
50
|
+
participant({
|
|
51
|
+
units: ["hook:agent-hook-entries", "hook:fallback-region"],
|
|
52
|
+
failureUnitId: "hook:agent-hook-entries",
|
|
53
|
+
manager: hooks,
|
|
54
|
+
}),
|
|
55
|
+
participant({
|
|
56
|
+
units: ["knowledge:discovery-region"],
|
|
57
|
+
failureUnitId: "knowledge:discovery-region",
|
|
58
|
+
manager: knowledge,
|
|
59
|
+
}),
|
|
60
|
+
],
|
|
61
|
+
subagents: Option.some({
|
|
62
|
+
projectionObservation: (ref) => subagents.projectionObservation(ref).pipe(Effect.mapError(onSubagentFailure)),
|
|
63
|
+
}),
|
|
64
|
+
};
|
|
65
|
+
}));
|
|
66
|
+
//# sourceMappingURL=projection-participants-live.js.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conversions from the shared-projection failure family into the plan-step
|
|
3
|
+
* vocabulary.
|
|
4
|
+
*
|
|
5
|
+
* Projection states domain facts and owns no rendering, and the package that
|
|
6
|
+
* owns `StepFailure` cannot see it, so the capability that unions projection
|
|
7
|
+
* into `ExtensionManagerFailure` renders it. Category, detail, and suggestion
|
|
8
|
+
* strings are the plan pipeline's serialized contract: they stay
|
|
9
|
+
* byte-identical to the CLI boundary's `AppError` renderings of the same
|
|
10
|
+
* failures, exactly as `workspaceStateReadFailureToStepFailure` does for the
|
|
11
|
+
* workspace-state family.
|
|
12
|
+
*
|
|
13
|
+
* @experimental This API is unstable and may change without notice.
|
|
14
|
+
*/
|
|
15
|
+
import { StepFailure } from "@agentxm/workspace-operations";
|
|
16
|
+
import type { ProjectionError } from "@agentxm/workspace-projection";
|
|
17
|
+
/** Translate one shared-projection failure into the plan-step vocabulary. */
|
|
18
|
+
export declare const projectionErrorToStepFailure: (error: ProjectionError) => StepFailure;
|
|
19
|
+
//# sourceMappingURL=projection-step-failure.d.ts.map
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conversions from the shared-projection failure family into the plan-step
|
|
3
|
+
* vocabulary.
|
|
4
|
+
*
|
|
5
|
+
* Projection states domain facts and owns no rendering, and the package that
|
|
6
|
+
* owns `StepFailure` cannot see it, so the capability that unions projection
|
|
7
|
+
* into `ExtensionManagerFailure` renders it. Category, detail, and suggestion
|
|
8
|
+
* strings are the plan pipeline's serialized contract: they stay
|
|
9
|
+
* byte-identical to the CLI boundary's `AppError` renderings of the same
|
|
10
|
+
* failures, exactly as `workspaceStateReadFailureToStepFailure` does for the
|
|
11
|
+
* workspace-state family.
|
|
12
|
+
*
|
|
13
|
+
* @experimental This API is unstable and may change without notice.
|
|
14
|
+
*/
|
|
15
|
+
import { StepFailure } from "@agentxm/workspace-operations";
|
|
16
|
+
/** Translate one shared-projection failure into the plan-step vocabulary. */
|
|
17
|
+
export const projectionErrorToStepFailure = (error) => {
|
|
18
|
+
switch (error._tag) {
|
|
19
|
+
case "DesiredStateIncomplete":
|
|
20
|
+
return new StepFailure({
|
|
21
|
+
category: "conflict",
|
|
22
|
+
detail: `Desired state cannot be enumerated completely; fix pack and declaration problems first: ${error.problems}`,
|
|
23
|
+
cause: error,
|
|
24
|
+
});
|
|
25
|
+
case "AuthoredContributorUnsupported":
|
|
26
|
+
return new StepFailure({
|
|
27
|
+
category: "validation",
|
|
28
|
+
detail: `User workspaces do not support workspace-authored ${error.type} packages`,
|
|
29
|
+
cause: error,
|
|
30
|
+
});
|
|
31
|
+
case "ContributorIdentityInvalid":
|
|
32
|
+
return new StepFailure({
|
|
33
|
+
category: "validation",
|
|
34
|
+
detail: `Invalid workspace ${error.type} identity: ${error.identity}`,
|
|
35
|
+
cause: error,
|
|
36
|
+
});
|
|
37
|
+
case "ContributorUnresolved":
|
|
38
|
+
return new StepFailure({
|
|
39
|
+
category: "conflict",
|
|
40
|
+
detail: `Active ${error.type} has no accepted resolution: ${error.name}`,
|
|
41
|
+
cause: error,
|
|
42
|
+
});
|
|
43
|
+
case "ContributorTreeMismatch":
|
|
44
|
+
return new StepFailure({
|
|
45
|
+
category: "conflict",
|
|
46
|
+
detail: `Materialized package tree does not match the accepted lock entry: ${error.packageRoot}`,
|
|
47
|
+
suggestions: [
|
|
48
|
+
{
|
|
49
|
+
description: "Restore the accepted package with install or update, or fork it into the authored workspace tree before editing.",
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
cause: error,
|
|
53
|
+
});
|
|
54
|
+
case "ProjectionTargetUnsupported":
|
|
55
|
+
return new StepFailure({ category: "validation", detail: error.detail, cause: error });
|
|
56
|
+
case "ManagedRegionViolation":
|
|
57
|
+
return new StepFailure({
|
|
58
|
+
category: "conflict",
|
|
59
|
+
detail: error.reason === undefined
|
|
60
|
+
? `Cannot reconcile managed region: ${error.displayPath}`
|
|
61
|
+
: `${error.reason}: ${error.displayPath}`,
|
|
62
|
+
cause: error,
|
|
63
|
+
});
|
|
64
|
+
case "ProjectionIoFailed":
|
|
65
|
+
return new StepFailure({
|
|
66
|
+
category: "internal",
|
|
67
|
+
detail: error.step === "inspect"
|
|
68
|
+
? `Failed to inspect managed-region target: ${error.path}`
|
|
69
|
+
: error.step === "read"
|
|
70
|
+
? `Failed to read managed-region target: ${error.path}`
|
|
71
|
+
: `Failed to reconcile managed-region target: ${error.path}`,
|
|
72
|
+
cause: error.cause,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
//# sourceMappingURL=projection-step-failure.js.map
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registry-backed canonical package materialization.
|
|
3
|
+
*
|
|
4
|
+
* The canonical-directory staging/swap machinery lives beside this module;
|
|
5
|
+
* this module owns only the registry fetch, verify, and extract path.
|
|
6
|
+
*
|
|
7
|
+
* @experimental This API is unstable and may change without notice.
|
|
8
|
+
*/
|
|
9
|
+
import * as Effect from "effect/Effect";
|
|
10
|
+
import * as FileSystem from "effect/FileSystem";
|
|
11
|
+
import * as Option from "effect/Option";
|
|
12
|
+
import * as Path from "effect/Path";
|
|
13
|
+
import * as HttpClient from "effect/unstable/http/HttpClient";
|
|
14
|
+
import type { Version, VersionRange } from "@agentxm/extension-model/unstable/version-constraints";
|
|
15
|
+
import type { RegistryClientFailure } from "@agentxm/registry-client";
|
|
16
|
+
import type { ExtensionName, ExtensionType } from "@agentxm/extension-model/unstable/extensions/common";
|
|
17
|
+
import type { Handle } from "@agentxm/extension-model/unstable/extensions/handle";
|
|
18
|
+
import { ArchiveIntegrityMismatch } from "./extensions/errors.js";
|
|
19
|
+
import { type CanonicalDirectoryReplacementError, type MaterializedPackage } from "./extensions/canonical-directory.js";
|
|
20
|
+
import { type MaterializedTreeInvalid } from "@agentxm/workspace-state";
|
|
21
|
+
export interface RegistryPackageMaterializationMessages {
|
|
22
|
+
readonly integrityMismatchDetail: string;
|
|
23
|
+
}
|
|
24
|
+
export interface MaterializeRegistryPackageArgs<E = never> {
|
|
25
|
+
readonly baseDir: string;
|
|
26
|
+
/**
|
|
27
|
+
* Canonical installed path for this extension. Bytes always land in a sibling
|
|
28
|
+
* staging directory first and are swapped in after validation.
|
|
29
|
+
*/
|
|
30
|
+
readonly destinationPath: string;
|
|
31
|
+
readonly sourceLocation: URL;
|
|
32
|
+
readonly owner: Handle;
|
|
33
|
+
readonly type: ExtensionType;
|
|
34
|
+
readonly name: ExtensionName;
|
|
35
|
+
readonly version: Version | VersionRange;
|
|
36
|
+
readonly integrity: Option.Option<string>;
|
|
37
|
+
readonly messages: RegistryPackageMaterializationMessages;
|
|
38
|
+
readonly validate?: (stagingPath: string) => Effect.Effect<void, E, FileSystem.FileSystem | Path.Path>;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Fetch, verify, and extract a registry package into `destinationPath`.
|
|
42
|
+
*
|
|
43
|
+
* Always writes. Whether new bytes are needed at all is
|
|
44
|
+
* `canReuseInstalledPackage`'s decision, which the caller makes against the
|
|
45
|
+
* canonical installed path before choosing a destination.
|
|
46
|
+
*
|
|
47
|
+
* Registry client and archive-extraction failures stay typed in the channel;
|
|
48
|
+
* the application boundary converts them once.
|
|
49
|
+
*/
|
|
50
|
+
export declare const materializeRegistryPackageWithTreeIntegrity: <E = never>(args: MaterializeRegistryPackageArgs<E>) => Effect.Effect<MaterializedPackage, E | RegistryClientFailure | ArchiveIntegrityMismatch | CanonicalDirectoryReplacementError | MaterializedTreeInvalid, FileSystem.FileSystem | HttpClient.HttpClient | Path.Path>;
|
|
51
|
+
export declare const materializeRegistryPackage: <E = never>(args: MaterializeRegistryPackageArgs<E>) => Effect.Effect<string, ArchiveIntegrityMismatch | MaterializedTreeInvalid | RegistryClientFailure | CanonicalDirectoryReplacementError | E, FileSystem.FileSystem | Path.Path | HttpClient.HttpClient>;
|
|
52
|
+
//# sourceMappingURL=registry-materialization.d.ts.map
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registry-backed canonical package materialization.
|
|
3
|
+
*
|
|
4
|
+
* The canonical-directory staging/swap machinery lives beside this module;
|
|
5
|
+
* this module owns only the registry fetch, verify, and extract path.
|
|
6
|
+
*
|
|
7
|
+
* @experimental This API is unstable and may change without notice.
|
|
8
|
+
*/
|
|
9
|
+
import * as Effect from "effect/Effect";
|
|
10
|
+
import * as FileSystem from "effect/FileSystem";
|
|
11
|
+
import * as Option from "effect/Option";
|
|
12
|
+
import * as Path from "effect/Path";
|
|
13
|
+
import * as HttpClient from "effect/unstable/http/HttpClient";
|
|
14
|
+
import { computeIntegrity, createRegistryClient, extractZip } from "@agentxm/registry-client";
|
|
15
|
+
import { ArchiveIntegrityMismatch } from "./extensions/errors.js";
|
|
16
|
+
import { recoverCanonicalDirectory, replaceCanonicalDirectoryWithInspection, } from "./extensions/canonical-directory.js";
|
|
17
|
+
import { makeThrottledUnitProgress } from "@agentxm/workspace-operations";
|
|
18
|
+
import { computeMaterializedTreeIntegrity, } from "@agentxm/workspace-state";
|
|
19
|
+
const registryLocationForClient = (location) => location.protocol === "file:" ? location.pathname : location.href;
|
|
20
|
+
/**
|
|
21
|
+
* Fetch, verify, and extract a registry package into `destinationPath`.
|
|
22
|
+
*
|
|
23
|
+
* Always writes. Whether new bytes are needed at all is
|
|
24
|
+
* `canReuseInstalledPackage`'s decision, which the caller makes against the
|
|
25
|
+
* canonical installed path before choosing a destination.
|
|
26
|
+
*
|
|
27
|
+
* Registry client and archive-extraction failures stay typed in the channel;
|
|
28
|
+
* the application boundary converts them once.
|
|
29
|
+
*/
|
|
30
|
+
export const materializeRegistryPackageWithTreeIntegrity = (args) => Effect.gen(function* () {
|
|
31
|
+
yield* recoverCanonicalDirectory({
|
|
32
|
+
baseDir: args.baseDir,
|
|
33
|
+
canonicalPath: args.destinationPath,
|
|
34
|
+
});
|
|
35
|
+
const client = yield* createRegistryClient(registryLocationForClient(args.sourceLocation));
|
|
36
|
+
// Continuous download progress reaches the lifecycle broadcast throttled:
|
|
37
|
+
// tens of events per archive, attributed to the unit that is running.
|
|
38
|
+
const reportProgress = yield* makeThrottledUnitProgress({ unit: "bytes" });
|
|
39
|
+
const { archive } = yield* client.getExtensionPackage({
|
|
40
|
+
owner: args.owner,
|
|
41
|
+
type: args.type,
|
|
42
|
+
name: args.name,
|
|
43
|
+
version: Option.some(args.version),
|
|
44
|
+
onProgress: (progress) => reportProgress(progress.done, progress.total),
|
|
45
|
+
});
|
|
46
|
+
if (Option.isSome(args.integrity)) {
|
|
47
|
+
const actualIntegrity = yield* computeIntegrity(archive);
|
|
48
|
+
if (actualIntegrity !== args.integrity.value) {
|
|
49
|
+
return yield* new ArchiveIntegrityMismatch({
|
|
50
|
+
subject: args.messages.integrityMismatchDetail,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const result = yield* replaceCanonicalDirectoryWithInspection({
|
|
55
|
+
baseDir: args.baseDir,
|
|
56
|
+
canonicalPath: args.destinationPath,
|
|
57
|
+
populate: (stagingPath) => extractZip(archive, stagingPath),
|
|
58
|
+
...(args.validate === undefined ? {} : { validate: args.validate }),
|
|
59
|
+
inspect: computeMaterializedTreeIntegrity,
|
|
60
|
+
});
|
|
61
|
+
return {
|
|
62
|
+
canonicalPath: result.canonicalPath,
|
|
63
|
+
treeIntegrity: result.inspection,
|
|
64
|
+
};
|
|
65
|
+
});
|
|
66
|
+
export const materializeRegistryPackage = (args) => materializeRegistryPackageWithTreeIntegrity(args).pipe(Effect.map(({ canonicalPath }) => canonicalPath));
|
|
67
|
+
//# sourceMappingURL=registry-materialization.js.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed failure family for the rule manager. Fields are domain facts; the
|
|
3
|
+
* application error boundary owns rendering, codes, and suggestions.
|
|
4
|
+
*
|
|
5
|
+
* @experimental This API is unstable and may change without notice.
|
|
6
|
+
*/
|
|
7
|
+
declare const RuleDefinitionInvalid_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
8
|
+
readonly _tag: "RuleDefinitionInvalid";
|
|
9
|
+
} & Readonly<A>;
|
|
10
|
+
/**
|
|
11
|
+
* A rule package's source, manifest, or body did not validate. `detail`
|
|
12
|
+
* carries the site's fact sentence verbatim.
|
|
13
|
+
*/
|
|
14
|
+
export declare class RuleDefinitionInvalid extends RuleDefinitionInvalid_base<{
|
|
15
|
+
readonly detail: string;
|
|
16
|
+
readonly cause?: unknown;
|
|
17
|
+
}> {
|
|
18
|
+
}
|
|
19
|
+
declare const RuleInstallStateMissing_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
20
|
+
readonly _tag: "RuleInstallStateMissing";
|
|
21
|
+
} & Readonly<A>;
|
|
22
|
+
/** A lock entry was requested before install recorded the package state. */
|
|
23
|
+
export declare class RuleInstallStateMissing extends RuleInstallStateMissing_base<{
|
|
24
|
+
readonly name: string;
|
|
25
|
+
readonly kind: "tree-integrity" | "content-identity";
|
|
26
|
+
}> {
|
|
27
|
+
}
|
|
28
|
+
/** Every failure the rule manager constructs. */
|
|
29
|
+
export type RuleManagerError = RuleDefinitionInvalid | RuleInstallStateMissing;
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed failure family for the rule manager. Fields are domain facts; the
|
|
3
|
+
* application error boundary owns rendering, codes, and suggestions.
|
|
4
|
+
*
|
|
5
|
+
* @experimental This API is unstable and may change without notice.
|
|
6
|
+
*/
|
|
7
|
+
import * as Data from "effect/Data";
|
|
8
|
+
/**
|
|
9
|
+
* A rule package's source, manifest, or body did not validate. `detail`
|
|
10
|
+
* carries the site's fact sentence verbatim.
|
|
11
|
+
*/
|
|
12
|
+
export class RuleDefinitionInvalid extends Data.TaggedError("RuleDefinitionInvalid") {
|
|
13
|
+
}
|
|
14
|
+
/** A lock entry was requested before install recorded the package state. */
|
|
15
|
+
export class RuleInstallStateMissing extends Data.TaggedError("RuleInstallStateMissing") {
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rule manager service.
|
|
3
|
+
*
|
|
4
|
+
* @experimental This API is unstable and may change without notice.
|
|
5
|
+
*/
|
|
6
|
+
import * as FileSystem from "effect/FileSystem";
|
|
7
|
+
import * as Layer from "effect/Layer";
|
|
8
|
+
import * as Path from "effect/Path";
|
|
9
|
+
import { RuleManager } from "../managers.js";
|
|
10
|
+
import { SourceHostProviders, WorkspaceCatalog } from "@agentxm/extension-sources";
|
|
11
|
+
import type { MaterializationObservation } from "../manager-contract.js";
|
|
12
|
+
import { WorkspaceMutations } from "@agentxm/workspace-state";
|
|
13
|
+
export declare const ruleMaterializationObservation: (managedTarget: string, instructionItems: ReadonlyArray<{
|
|
14
|
+
readonly agentId: string;
|
|
15
|
+
readonly health: string;
|
|
16
|
+
}>) => MaterializationObservation;
|
|
17
|
+
export declare const RuleManagerLive: Layer.Layer<RuleManager, never, FileSystem.FileSystem | Path.Path | WorkspaceMutations | SourceHostProviders | WorkspaceCatalog>;
|
|
18
|
+
//# sourceMappingURL=manager.d.ts.map
|