@agentxm/extension-materialization 0.29.1 → 0.29.4

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.
@@ -13,7 +13,7 @@
13
13
  */
14
14
  export { NO_MATERIALIZATION_OBSERVATION, type ExtensionManager, type ManagerRequirements, type MaterializationFacts, type MaterializationObservation, } from "./manager-contract.js";
15
15
  export { ExtensionManagers, type ExtensionManagersService } from "./manager-registry.js";
16
- export { HookManager, KnowledgeManager, McpServerManager, PackManager, RuleManager, SkillManager, SubagentManager, type AcquiredContentFacts, type HookManagerService, type HookMaterializationFacts, type KnowledgeManagerService, type KnowledgeMaterializationFacts, type KnowledgeSyncResult, type McpServerMaterializationFacts, type PackMaterializationFacts, type RuleManagerService, type RuleMaterializationFacts, type SkillMaterializationFacts, type SubagentManagerService, type SubagentMaterializationFacts, } from "./managers.js";
16
+ export { HookManager, KnowledgeManager, McpServerManager, PackManager, RuleManager, SkillManager, SubagentManager, type AcquiredContentFacts, type HookManagerService, type HookMaterializationFacts, type KnowledgeManagerService, type KnowledgeMaterializationFacts, type KnowledgeSyncResult, type McpServerMaterializationFacts, type McpServerManagerService, type PackMaterializationFacts, type RuleManagerService, type RuleMaterializationFacts, type SkillMaterializationFacts, type SubagentManagerService, type SubagentMaterializationFacts, } from "./managers.js";
17
17
  export type { ExtensionManagerFailure, ExtensionMaterializationError } from "./errors.js";
18
18
  export { ArchiveIntegrityMismatch, CanonicalPackageProbeFailed, CreateDestinationExists, LifecyclePostconditionViolated, PackageCopyFailed, PackageMaterializationFailed, ScaffoldedExtensionUnresolved, StagedPackageInvalid, type MaterializationError, } from "./extensions/errors.js";
19
19
  export { HookDefinitionInvalid, HookInstallStateMissing, type HookManagerError, } from "./hooks/errors.js";
@@ -11,11 +11,10 @@
11
11
  * @experimental This API is unstable and may change without notice.
12
12
  */
13
13
  import * as ServiceMap from "effect/Context";
14
- import type { McpServerExtensionRef } from "@agentxm/extension-model/unstable/extensions/refs/mcp-server";
15
14
  import type { PackRef } from "@agentxm/extension-model/unstable/extensions/refs/pack";
16
15
  import type { SkillExtensionRef } from "@agentxm/extension-model/unstable/extensions/refs/skill";
17
16
  import type { ExtensionManager, ManagerRequirements } from "./manager-contract.js";
18
- import type { HookManagerService, KnowledgeManagerService, McpServerMaterializationFacts, PackMaterializationFacts, RuleManagerService, SkillMaterializationFacts, SubagentManagerService } from "./managers.js";
17
+ import type { HookManagerService, KnowledgeManagerService, McpServerManagerService, PackMaterializationFacts, RuleManagerService, SkillMaterializationFacts, SubagentManagerService } from "./managers.js";
19
18
  /** The manager each extension type is materialized through. */
20
19
  export interface ExtensionManagersService {
21
20
  readonly skill: ExtensionManager<SkillExtensionRef, SkillMaterializationFacts, ManagerRequirements>;
@@ -23,7 +22,7 @@ export interface ExtensionManagersService {
23
22
  readonly rule: RuleManagerService;
24
23
  readonly hook: HookManagerService;
25
24
  readonly knowledge: KnowledgeManagerService;
26
- readonly "mcp-server": ExtensionManager<McpServerExtensionRef, McpServerMaterializationFacts, ManagerRequirements>;
25
+ readonly "mcp-server": McpServerManagerService;
27
26
  readonly pack: ExtensionManager<PackRef, PackMaterializationFacts, ManagerRequirements>;
28
27
  }
29
28
  declare const ExtensionManagers_base: ServiceMap.ServiceClass<ExtensionManagers, "@agentxm/extension-materialization/ExtensionManagers", ExtensionManagersService>;
@@ -17,7 +17,7 @@ import * as ServiceMap from "effect/Context";
17
17
  import type { ExtensionManager, ManagerRequirements, MaterializationFacts, MaterializationObservation } from "./manager-contract.js";
18
18
  import type { ExtensionManagerFailure } from "./errors.js";
19
19
  import type { ProjectionPlan } from "@agentxm/workspace-projection";
20
- import type { ConfiguredAgentOutcome } from "@agentxm/workspace-state";
20
+ import type { ConfiguredAgentOutcome, McpServerEntry } from "@agentxm/workspace-state";
21
21
  import type { WorkspaceTransactionScope } from "@agentxm/workspace-transactions";
22
22
  import type { SourceHash } from "@agentxm/extension-model/unstable/sources/source-hash";
23
23
  import type { TreeIntegrity } from "@agentxm/workspace-state";
@@ -83,7 +83,15 @@ export type PackMaterializationFacts = AcquiredContentFacts;
83
83
  declare const SkillManager_base: ServiceMap.ServiceClass<SkillManager, "@agentxm/extension-materialization/managers/SkillManager", ExtensionManager<SkillExtensionRef, SkillMaterializationFacts, ManagerRequirements>>;
84
84
  export declare class SkillManager extends SkillManager_base {
85
85
  }
86
- declare const McpServerManager_base: ServiceMap.ServiceClass<McpServerManager, "@agentxm/extension-materialization/managers/McpServerManager", ExtensionManager<McpServerExtensionRef, McpServerMaterializationFacts, ManagerRequirements>>;
86
+ export interface McpServerManagerService extends ExtensionManager<McpServerExtensionRef, McpServerMaterializationFacts, ManagerRequirements> {
87
+ readonly configuredAgentOutcomes: (state: "projected" | "current") => Effect.Effect<ReadonlyArray<ConfiguredAgentOutcome>, ExtensionManagerFailure, ManagerRequirements>;
88
+ readonly configuredAgentOutcomesForEntry: (args: {
89
+ readonly name: string;
90
+ readonly entry: McpServerEntry;
91
+ readonly state: "projected" | "current";
92
+ }) => Effect.Effect<ReadonlyArray<ConfiguredAgentOutcome>, ExtensionManagerFailure, ManagerRequirements>;
93
+ }
94
+ declare const McpServerManager_base: ServiceMap.ServiceClass<McpServerManager, "@agentxm/extension-materialization/managers/McpServerManager", McpServerManagerService>;
87
95
  export declare class McpServerManager extends McpServerManager_base {
88
96
  }
89
97
  export interface SubagentManagerService extends ExtensionManager<SubagentExtensionRef, SubagentMaterializationFacts, ManagerRequirements> {
@@ -18,8 +18,8 @@ import * as Array from "effect/Array";
18
18
  import * as Effect from "effect/Effect";
19
19
  import * as Option from "effect/Option";
20
20
  import * as Schema from "effect/Schema";
21
- import { NativeWriteAuthority } from "@agentxm/agent-integration";
22
- import { CodingAgentRepository, applyProjectionPlansWithResults, planSingletonProjection, } from "@agentxm/workspace-projection";
21
+ import { NativeWriteAuthority, syncManifestMcpServerToAgents } from "@agentxm/agent-integration";
22
+ import { CodingAgentRepository } from "@agentxm/workspace-projection";
23
23
  import { mcpRegistryResolutionKey } from "@agentxm/workspace-state";
24
24
  import { isPathSafe } from "@agentxm/extension-model/unstable/path-types";
25
25
  import { acceptedRegistryVersionForRef, validateExactResolvedVersion, } from "@agentxm/workspace-state";
@@ -262,6 +262,7 @@ const syncConfiguredAgentsOnInstall = (args) => Effect.gen(function* () {
262
262
  warnings.push(`Skipping unknown configured agents: ${unknownConfiguredAgentIds.join(", ")}`);
263
263
  }
264
264
  const configuredAgents = yield* agentRepo.getConfiguredAgents();
265
+ const configuredAgentIds = configuredAgents.map(({ id }) => id);
265
266
  let outcomes;
266
267
  if (args.nothingRunnable) {
267
268
  outcomes = configuredAgents.map((agent) => ({
@@ -273,34 +274,24 @@ const syncConfiguredAgentsOnInstall = (args) => Effect.gen(function* () {
273
274
  }));
274
275
  }
275
276
  else {
276
- outcomes = yield* applyProjectionPlansWithResults(configuredAgents.map((agent) => planSingletonProjection({
277
- unitId: "mcp-server:native-config-entry",
278
- targetFile: "mcp:configured-agents",
279
- contributor: args,
280
- adapter: {
281
- observe: () => Effect.succeed({
282
- unitId: "mcp-server:native-config-entry",
283
- path: `${agent.id}:${args.serverName}`,
284
- present: false,
285
- current: false,
286
- expectedContributors: [args.serverName],
287
- observedContributors: [],
288
- }),
289
- apply: () => Effect.gen(function* () {
290
- const outcome = yield* agent.addMcpServer({
291
- workspaceRoot: args.wsBaseDir,
292
- scope: args.scope,
293
- serverName: args.serverName,
294
- canonicalPath: args.canonicalPath,
295
- owner: args.owner,
296
- resolvedVersion: args.resolvedVersion,
297
- enabled: args.enabled,
298
- configValues: args.configValues,
299
- });
300
- return { agentId: agent.id, outcome };
301
- }),
277
+ const synced = yield* syncManifestMcpServerToAgents({
278
+ agentIds: configuredAgentIds,
279
+ workspaceRoot: args.wsBaseDir,
280
+ scope: args.scope,
281
+ serverName: args.serverName,
282
+ canonicalPath: args.canonicalPath,
283
+ owner: args.owner,
284
+ resolvedVersion: args.resolvedVersion,
285
+ enabled: args.enabled,
286
+ configValues: args.configValues,
287
+ });
288
+ outcomes = configuredAgentIds.map((agentId, index) => ({
289
+ agentId,
290
+ outcome: synced[index] ?? {
291
+ _tag: "failed",
292
+ reason: "Agent sync returned no outcome",
302
293
  },
303
- })));
294
+ }));
304
295
  }
305
296
  const misconfigured = Array.filter(outcomes, ({ outcome }) => outcome._tag === "misconfigured");
306
297
  if (misconfigured.length > 0) {
@@ -12,10 +12,10 @@ import * as Effect from "effect/Effect";
12
12
  import * as Layer from "effect/Layer";
13
13
  import * as Option from "effect/Option";
14
14
  import { McpInstallStateMissing, McpRegistryOnlyInstall } from "./errors.js";
15
- import { applyProjectionPlans, planSingletonProjection } from "@agentxm/workspace-projection";
15
+ import { applyProjectionPlans, inspectMcpServerAcrossAgents, planSingletonProjection, } from "@agentxm/workspace-projection";
16
16
  import { McpConfigIoFailed, removeMcpServerFromManifest } from "@agentxm/agent-integration";
17
17
  import { NO_MATERIALIZATION_OBSERVATION } from "../manager-contract.js";
18
- import { McpServerManager } from "../managers.js";
18
+ import { McpServerManager, } from "../managers.js";
19
19
  import { configuredMcpServersToDiskRefs } from "../extensions/materializable-from-disk.js";
20
20
  import { mcpRegistryResolutionKey, WorkspaceMutations } from "@agentxm/workspace-state";
21
21
  import { canReuseInstalledPackage } from "../extensions/canonical-directory.js";
@@ -159,6 +159,57 @@ export const McpServerManagerLive = Layer.effect(McpServerManager, Effect.gen(fu
159
159
  });
160
160
  const materializeUninstall = makeMaterializeRemoval(false);
161
161
  const materializeDeactivate = makeMaterializeRemoval(true);
162
+ const configuredAgentOutcomesForEntry = Effect.fn("McpServerManager.configuredAgentOutcomesForEntry")(function* ({ name, entry, state, }) {
163
+ const configuredAgentIds = yield* ws.getConfiguredAgents();
164
+ const canonical = entry.kind === "inline"
165
+ ? Option.none()
166
+ : (yield* acceptedCanonicalObservation({
167
+ workspace: ws,
168
+ type: "mcp-server",
169
+ name,
170
+ })).pipe(Option.flatMap(({ observation }) => Option.fromUndefinedOr(observation.path)));
171
+ const inspections = yield* inspectMcpServerAcrossAgents({
172
+ workspaceRoot: baseDir,
173
+ scope: ws.scope,
174
+ agentIds: configuredAgentIds,
175
+ serverName: name,
176
+ entry: { ...entry, enabled: true },
177
+ canonicalPaths: Option.match(canonical, { onNone: () => [], onSome: (value) => [value] }),
178
+ state,
179
+ });
180
+ return inspections.map((inspection) => ({
181
+ extensionType: "mcp-server",
182
+ name,
183
+ agentId: inspection.agentId,
184
+ outcome: inspection.status === "match"
185
+ ? state
186
+ : inspection.status === "unsupported"
187
+ ? "unsupported"
188
+ : inspection.status === "blocked"
189
+ ? "blocked"
190
+ : "failed",
191
+ reasonCode: inspection.status === "match"
192
+ ? "supported"
193
+ : inspection.status === "absent"
194
+ ? "projection-missing"
195
+ : inspection.status === "drift"
196
+ ? "stale-projection"
197
+ : `mcp-${inspection.status}`,
198
+ reason: inspection.reason ??
199
+ (inspection.status === "match"
200
+ ? `${inspection.agentId} has a matching MCP projection.`
201
+ : inspection.status === "absent"
202
+ ? `The expected ${inspection.agentId} projection is missing.`
203
+ : inspection.status === "drift"
204
+ ? `The expected ${inspection.agentId} projection is stale.`
205
+ : `MCP projection status is ${inspection.status}.`),
206
+ ...(inspection.path.length === 0 ? {} : { path: inspection.path }),
207
+ }));
208
+ });
209
+ const configuredAgentOutcomes = (state) => Effect.gen(function* () {
210
+ const entries = yield* ws.getConfiguredMcpServerEntries();
211
+ return (yield* Effect.forEach(Object.entries(entries).filter(([, entry]) => state === "projected" || entry.enabled), ([name, entry]) => configuredAgentOutcomesForEntry({ name, entry, state }), { concurrency: "unbounded" })).flat();
212
+ });
162
213
  return {
163
214
  type: "mcp-server",
164
215
  isInstalled: Effect.fn("McpServerManager.isInstalled")(function* ({ target, }) {
@@ -187,6 +238,8 @@ export const McpServerManagerLive = Layer.effect(McpServerManager, Effect.gen(fu
187
238
  }),
188
239
  materializeUninstall,
189
240
  materializeDeactivate,
241
+ configuredAgentOutcomes,
242
+ configuredAgentOutcomesForEntry,
190
243
  upsertSettingsEntry: ({ ref, versionRange, materialization, }) => {
191
244
  if (ref.refType !== "registry")
192
245
  return Effect.void.pipe(Effect.withSpan("McpServerManager.upsertSettingsEntry"));
package/package.json CHANGED
@@ -4,26 +4,27 @@
4
4
  "url": "https://github.com/agentxm/axm/issues"
5
5
  },
6
6
  "dependencies": {
7
- "@agentxm/agent-integration": "^0.29.1",
8
- "@agentxm/extension-content": "^0.29.1",
9
- "@agentxm/extension-model": "^0.29.1",
10
- "@agentxm/extension-resolution": "^0.29.1",
11
- "@agentxm/extension-sources": "^0.29.1",
12
- "@agentxm/registry-client": "^0.29.1",
13
- "@agentxm/workspace-operations": "^0.29.1",
14
- "@agentxm/workspace-projection": "^0.29.1",
15
- "@agentxm/workspace-state": "^0.29.1",
16
- "@agentxm/workspace-transactions": "^0.29.1",
7
+ "@agentxm/agent-integration": "^0.29.4",
8
+ "@agentxm/extension-content": "^0.29.4",
9
+ "@agentxm/extension-model": "^0.29.4",
10
+ "@agentxm/extension-resolution": "^0.29.4",
11
+ "@agentxm/extension-sources": "^0.29.4",
12
+ "@agentxm/registry-client": "^0.29.4",
13
+ "@agentxm/workspace-operations": "^0.29.4",
14
+ "@agentxm/workspace-projection": "^0.29.4",
15
+ "@agentxm/workspace-state": "^0.29.4",
16
+ "@agentxm/workspace-transactions": "^0.29.4",
17
17
  "@napi-rs/keyring": "^1.3.0",
18
- "effect": "4.0.0-rc.112"
18
+ "effect": "4.0.0-rc.115"
19
19
  },
20
20
  "description": "AXM extension materialization: the per-extension-type manager contract and implementations, canonical package staging, registry materialization, and the install/uninstall/authored closure recipes for the axm CLI. Unstable and unsupported — use the axm.sh CLI.",
21
21
  "devDependencies": {
22
- "@effect/platform-node": "4.0.0-rc.112",
23
- "@effect/vitest": "4.0.0-rc.112",
22
+ "@effect/platform-node": "4.0.0-rc.115",
23
+ "@effect/vitest": "4.0.0-rc.115",
24
+ "@fast-check/vitest": "^0.5.0",
24
25
  "@typescript/native": "npm:typescript@^7.0.2",
25
26
  "typescript": "npm:@typescript/typescript6@^6.0.2",
26
- "vitest": "^4.1.10",
27
+ "vitest": "^5.0.0",
27
28
  "yaml": "^2.9.0"
28
29
  },
29
30
  "engines": {
@@ -66,5 +67,5 @@
66
67
  },
67
68
  "sideEffects": false,
68
69
  "type": "module",
69
- "version": "0.29.1"
70
+ "version": "0.29.4"
70
71
  }