@agentxm/workspace-configuration 0.28.12 → 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.
Files changed (38) hide show
  1. package/dist/src/errors.d.ts +29 -0
  2. package/dist/src/errors.js +68 -0
  3. package/dist/src/index.d.ts +17 -12
  4. package/dist/src/index.js +28 -11
  5. package/dist/src/inline-mcp/add-inline-mcp-server.d.ts +63 -0
  6. package/dist/src/inline-mcp/add-inline-mcp-server.js +253 -0
  7. package/dist/src/{inline-mcp.d.ts → inline-mcp/definition.d.ts} +3 -3
  8. package/dist/src/{inline-mcp.js → inline-mcp/definition.js} +2 -2
  9. package/dist/src/instructions/manage-instructions.d.ts +125 -0
  10. package/dist/src/instructions/manage-instructions.js +361 -0
  11. package/dist/src/mcp-import/apply.d.ts +33 -0
  12. package/dist/src/{mcp-import.js → mcp-import/apply.js} +8 -50
  13. package/dist/src/mcp-import/import-mcp-servers.d.ts +49 -0
  14. package/dist/src/mcp-import/import-mcp-servers.js +117 -0
  15. package/dist/src/{mcp-import-preflight.d.ts → mcp-import/preflight.d.ts} +1 -1
  16. package/dist/src/{mcp-import-preflight.js → mcp-import/preflight.js} +2 -2
  17. package/dist/src/membership/agent-lifecycle.d.ts +20 -0
  18. package/dist/src/membership/agent-lifecycle.js +33 -0
  19. package/dist/src/membership/atomic-membership.d.ts +41 -0
  20. package/dist/src/membership/atomic-membership.js +125 -0
  21. package/dist/src/membership/configure-agents.d.ts +197 -0
  22. package/dist/src/membership/configure-agents.js +395 -0
  23. package/dist/src/membership/validate-agent-ids.d.ts +16 -0
  24. package/dist/src/membership/validate-agent-ids.js +85 -0
  25. package/dist/src/{initialization-interaction.d.ts → setup/initialization-interaction.d.ts} +1 -1
  26. package/dist/src/{initialization.d.ts → setup/initialization.d.ts} +11 -11
  27. package/dist/src/{initialization.js → setup/initialization.js} +3 -3
  28. package/dist/src/setup/setup-workspace.d.ts +264 -0
  29. package/dist/src/setup/setup-workspace.js +512 -0
  30. package/dist/src/testing.d.ts +95 -4
  31. package/dist/src/testing.js +215 -4
  32. package/package.json +11 -9
  33. package/dist/src/instruction-reconciliation.d.ts +0 -57
  34. package/dist/src/instruction-reconciliation.js +0 -93
  35. package/dist/src/mcp-import.d.ts +0 -40
  36. package/dist/src/membership.d.ts +0 -29
  37. package/dist/src/membership.js +0 -162
  38. /package/dist/src/{initialization-interaction.js → setup/initialization-interaction.js} +0 -0
@@ -8,6 +8,16 @@
8
8
  * @experimental This API is unstable and may change without notice.
9
9
  */
10
10
  import * as Schema from "effect/Schema";
11
+ import { StepFailure, type ApprovalRecoveryMissing, type CandidateFingerprintFailed, type PlanInteractionFailed } from "@agentxm/workspace-operations";
12
+ import type { InvalidAgentId, LockfileValidationError, WorkspaceSettingsReadFailure, WorkspaceStateMutationFailure } from "@agentxm/workspace-state";
13
+ import type { WorkspaceRestorationIncomplete, WorkspaceTransactionFailure, WorkspaceTransitionAcquireFailure } from "@agentxm/workspace-transactions";
14
+ /**
15
+ * Every failure resolving a prepared change through the plan pipeline can
16
+ * surface: the workspace reads the candidate revalidates against, the
17
+ * approval and interaction refusals, and the transition the apply could not
18
+ * acquire. Step failures are carried inside the resolution, not raised.
19
+ */
20
+ export type WorkspaceConfigurationExecutionFailure = ApprovalRecoveryMissing | CandidateFingerprintFailed | LockfileValidationError | PlanInteractionFailed | WorkspaceSettingsReadFailure | WorkspaceTransitionAcquireFailure;
11
21
  declare const WorkspaceConfigurationFailed_base: Schema.Class<WorkspaceConfigurationFailed, Schema.TaggedStruct<"WorkspaceConfigurationFailed", {
12
22
  readonly category: Schema.Literals<readonly ["conflict", "internal", "usage", "validation"]>;
13
23
  readonly detail: Schema.String;
@@ -26,5 +36,24 @@ declare const WorkspaceConfigurationFailed_base: Schema.Class<WorkspaceConfigura
26
36
  */
27
37
  export declare class WorkspaceConfigurationFailed extends WorkspaceConfigurationFailed_base {
28
38
  }
39
+ /**
40
+ * Serialize a workspace-configuration failure into the plan-step vocabulary.
41
+ * The producer already chose the category and the sentence, so both carry
42
+ * over unchanged and the boundary renders the same words whether the failure
43
+ * surfaced from a step or from `prepare`.
44
+ */
45
+ export declare const configurationFailedToStepFailure: (failure: WorkspaceConfigurationFailed) => StepFailure;
46
+ /**
47
+ * Every failure a workspace change this feature plans can surface: the
48
+ * workspace's own read and write failures, the transaction machinery's, and
49
+ * a step that already speaks the serialized vocabulary.
50
+ */
51
+ export type WorkspaceChangeFailure = InvalidAgentId | StepFailure | WorkspaceRestorationIncomplete | WorkspaceStateMutationFailure | WorkspaceTransactionFailure;
52
+ /**
53
+ * Serialize a workspace change failure into the plan-step vocabulary. Read
54
+ * and transaction failures keep the sentences the capability already chose,
55
+ * so a failure reads the same wherever it was produced.
56
+ */
57
+ export declare const workspaceChangeFailedToStepFailure: (failure: WorkspaceChangeFailure) => StepFailure;
29
58
  export {};
30
59
  //# sourceMappingURL=errors.d.ts.map
@@ -8,6 +8,7 @@
8
8
  * @experimental This API is unstable and may change without notice.
9
9
  */
10
10
  import * as Schema from "effect/Schema";
11
+ import { StepFailure, restorationIncompleteToStepFailure, workspaceStateReadFailureToStepFailure, workspaceTransactionFailureToStepFailure, } from "@agentxm/workspace-operations";
11
12
  const CarriedSuggestedActionSchema = Schema.Struct({
12
13
  description: Schema.String,
13
14
  cmd: Schema.optional(Schema.String),
@@ -26,4 +27,71 @@ export class WorkspaceConfigurationFailed extends Schema.TaggedError()("Workspac
26
27
  cause: Schema.optional(Schema.Unknown),
27
28
  }) {
28
29
  }
30
+ /**
31
+ * Serialize a workspace-configuration failure into the plan-step vocabulary.
32
+ * The producer already chose the category and the sentence, so both carry
33
+ * over unchanged and the boundary renders the same words whether the failure
34
+ * surfaced from a step or from `prepare`.
35
+ */
36
+ export const configurationFailedToStepFailure = (failure) => new StepFailure({
37
+ category: failure.category,
38
+ detail: failure.detail,
39
+ ...(failure.suggestions === undefined ? {} : { suggestions: failure.suggestions }),
40
+ ...(failure.cause === undefined ? {} : { cause: failure.cause }),
41
+ });
42
+ /**
43
+ * Serialize a workspace change failure into the plan-step vocabulary. Read
44
+ * and transaction failures keep the sentences the capability already chose,
45
+ * so a failure reads the same wherever it was produced.
46
+ */
47
+ export const workspaceChangeFailedToStepFailure = (failure) => {
48
+ switch (failure._tag) {
49
+ case "StepFailure":
50
+ return failure;
51
+ case "SettingsDecodeError":
52
+ case "SettingsIoError":
53
+ case "SettingsParseError":
54
+ case "LockfileDecodeError":
55
+ case "LockfileIoError":
56
+ case "LockfileParseError":
57
+ case "LockfileVersionUnsupported":
58
+ case "WorkspaceRootEscape":
59
+ return workspaceStateReadFailureToStepFailure(failure);
60
+ case "TransitionLockError":
61
+ case "TransitionLockUnavailable":
62
+ case "WorkspaceDirectoryError":
63
+ case "WorkspaceSnapshotError":
64
+ case "WorkspaceTransitionCompromised":
65
+ return workspaceTransactionFailureToStepFailure(failure);
66
+ case "WorkspaceRestorationIncomplete":
67
+ return restorationIncompleteToStepFailure(failure);
68
+ case "InvalidAgentId":
69
+ return new StepFailure({
70
+ category: "validation",
71
+ detail: `Unknown agent ID: ${failure.agentId}`,
72
+ suggestions: [
73
+ { description: "Inspect supported agent IDs.", cmd: "axm agents list --available" },
74
+ ],
75
+ cause: failure.cause,
76
+ });
77
+ case "SettingsWriteError":
78
+ return new StepFailure({
79
+ category: "internal",
80
+ detail: `Workspace settings at ${failure.path} could not be written`,
81
+ cause: failure.cause,
82
+ });
83
+ case "LockfileWriteError":
84
+ return new StepFailure({
85
+ category: "internal",
86
+ detail: `Workspace lockfile at ${failure.path} could not be written`,
87
+ cause: failure.cause,
88
+ });
89
+ case "LockfileValidationError":
90
+ return new StepFailure({
91
+ category: "validation",
92
+ detail: `Workspace lockfile at ${failure.path} could not be validated`,
93
+ cause: failure.cause,
94
+ });
95
+ }
96
+ };
29
97
  //# sourceMappingURL=errors.js.map
@@ -1,18 +1,23 @@
1
1
  /**
2
- * Workspace-configuration feature: workspace initialization and setup flows,
3
- * configured-agent membership policy, instruction-management policy over the
4
- * kernel's instruction semantics, and inline workspace MCP capability policy.
2
+ * Workspace-configuration feature: setting up a workspace, deciding which
3
+ * coding agents it configures, managing instruction-file propagation, and
4
+ * defining MCP servers inline in the workspace's own settings.
5
5
  *
6
6
  * @experimental This API is unstable and may change without notice.
7
7
  * @packageDocumentation
8
8
  */
9
- export { WorkspaceConfigurationFailed } from "./errors.js";
10
- export { bootstrapWorkspace, initializeProjectWorkspace, ensureUserWorkspaceInitialized, ensureProjectWorkspaceInitialized, type SetupAgentCandidate, } from "./initialization.js";
11
- export type { InstructionSourceChoice, SetupAgentScan, SetupPlanRow, WorkspaceInitializationInteractionService, } from "./initialization-interaction.js";
12
- export { WorkspaceInitializationCancelled, WorkspaceInitializationInteraction, } from "./initialization-interaction.js";
13
- export { activeInstructionsConfig, disableInstructionManagement, instructionReconciliationReadiness, instructionStateIsCurrent, observeInstructions, reconcileInstructionTransition, removeInstructionTargetsFor, type InstructionReadinessFailure, } from "./instruction-reconciliation.js";
14
- export { dedupe, makeAtomicMembershipSteps, validateAgentIds } from "./membership.js";
15
- export { makeInlineMcpDefinition, matchesInlineMcpEntry, parseInlineMcpEnv, parseInlineMcpHeaders, splitCommand, validateInlineMcpRemoteUrl, } from "./inline-mcp.js";
16
- export { preflightMcpImports, type InlineMcpDefinition, type McpImportAdoption, type McpImportCandidate, type McpImportFinding, type McpImportPreflight, type McpImportSource, } from "./mcp-import-preflight.js";
17
- export { applyMcpImport, collectMcpImportSources, removeConvertedMcpConfig } from "./mcp-import.js";
9
+ export { WorkspaceConfigurationFailed, configurationFailedToStepFailure } from "./errors.js";
10
+ export { bootstrapWorkspace, initializeProjectWorkspace, ensureUserWorkspaceInitialized, ensureProjectWorkspaceInitialized, type SetupAgentCandidate, } from "./setup/initialization.js";
11
+ export type { InstructionSourceChoice, SetupAgentScan, SetupPlanRow, WorkspaceInitializationInteractionService, } from "./setup/initialization-interaction.js";
12
+ export { WorkspaceInitializationCancelled, WorkspaceInitializationInteraction, } from "./setup/initialization-interaction.js";
13
+ export { SetupOutcomeSchema, SetupWorkspace, prepareSetupWorkspace, previewOrApplySetupWorkspace, previewAgentDefault, reportSetupWorkspace, type BundledSkillReport, type SetupApprovalRequired, type SetupArtifactTarget, type SetupOutcome, type SetupPlanStep, type SetupReportFailure, type SetupReportRequest, type SetupTransition, type SetupWorkspaceCandidate, type SetupWorkspaceFailure, type SetupWorkspaceRequest, } from "./setup/setup-workspace.js";
14
+ export { agentLifecycle, isCatalogAgentId, isRetiredAgent, lifecycleWarning, } from "./membership/agent-lifecycle.js";
15
+ export { dedupe, validateAgentIds } from "./membership/validate-agent-ids.js";
16
+ export { ConfigureAgents, ConfiguredAgentInventorySchema, listConfiguredAgents, prepareAddConfiguredAgents, prepareRemoveConfiguredAgents, previewOrApplyAddConfiguredAgents, previewOrApplyRemoveConfiguredAgents, type AddConfiguredAgentsCandidate, type AddConfiguredAgentsRequest, type ConfigureAgentsFailure, type ConfiguredAgentInventory, type ConfiguredAgentRow, type ConfiguredAgentsUnchanged, type DepartingAgentReconciliation, type ListConfiguredAgentsRequest, type MembershipExecutionRequirements, type MembershipReconciliation, type RemoveConfiguredAgentsCandidate, type RemoveConfiguredAgentsRequest, } from "./membership/configure-agents.js";
17
+ export { InstructionsStatusSchema, ManageInstructions, instructionsStatus, prepareManageInstructions, previewOrApplyManageInstructions, type InstructionsStatus, type InstructionsUnchanged, type ManageInstructionsCandidate, type ManageInstructionsRequest, type ManageInstructionsRequirements, } from "./instructions/manage-instructions.js";
18
+ export { makeInlineMcpDefinition, matchesInlineMcpEntry, parseInlineMcpEnv, parseInlineMcpHeaders, splitCommand, validateInlineMcpRemoteUrl, } from "./inline-mcp/definition.js";
19
+ export { AddInlineMcpServer, prepareAddInlineMcpServer, previewOrApplyAddInlineMcpServer, type AddInlineMcpServerCandidate, type AddInlineMcpServerRequest, type AddInlineMcpServerRequirements, type InlineMcpServerUnchanged, } from "./inline-mcp/add-inline-mcp-server.js";
20
+ export { preflightMcpImports, type InlineMcpDefinition, type McpImportAdoption, type McpImportCandidate, type McpImportFinding, type McpImportPreflight, type McpImportSource, } from "./mcp-import/preflight.js";
21
+ export { applyMcpImport, collectMcpImportSources } from "./mcp-import/apply.js";
22
+ export { ImportMcpServers, prepareImportMcpServers, previewOrApplyImportMcpServers, type ImportMcpServersCandidate, type ImportMcpServersRequirements, } from "./mcp-import/import-mcp-servers.js";
18
23
  //# sourceMappingURL=index.d.ts.map
package/dist/src/index.js CHANGED
@@ -1,17 +1,34 @@
1
1
  /**
2
- * Workspace-configuration feature: workspace initialization and setup flows,
3
- * configured-agent membership policy, instruction-management policy over the
4
- * kernel's instruction semantics, and inline workspace MCP capability policy.
2
+ * Workspace-configuration feature: setting up a workspace, deciding which
3
+ * coding agents it configures, managing instruction-file propagation, and
4
+ * defining MCP servers inline in the workspace's own settings.
5
5
  *
6
6
  * @experimental This API is unstable and may change without notice.
7
7
  * @packageDocumentation
8
8
  */
9
- export { WorkspaceConfigurationFailed } from "./errors.js";
10
- export { bootstrapWorkspace, initializeProjectWorkspace, ensureUserWorkspaceInitialized, ensureProjectWorkspaceInitialized, } from "./initialization.js";
11
- export { WorkspaceInitializationCancelled, WorkspaceInitializationInteraction, } from "./initialization-interaction.js";
12
- export { activeInstructionsConfig, disableInstructionManagement, instructionReconciliationReadiness, instructionStateIsCurrent, observeInstructions, reconcileInstructionTransition, removeInstructionTargetsFor, } from "./instruction-reconciliation.js";
13
- export { dedupe, makeAtomicMembershipSteps, validateAgentIds } from "./membership.js";
14
- export { makeInlineMcpDefinition, matchesInlineMcpEntry, parseInlineMcpEnv, parseInlineMcpHeaders, splitCommand, validateInlineMcpRemoteUrl, } from "./inline-mcp.js";
15
- export { preflightMcpImports, } from "./mcp-import-preflight.js";
16
- export { applyMcpImport, collectMcpImportSources, removeConvertedMcpConfig } from "./mcp-import.js";
9
+ export { WorkspaceConfigurationFailed, configurationFailedToStepFailure } from "./errors.js";
10
+ // -----------------------------------------------------------------------------
11
+ // Setup
12
+ // -----------------------------------------------------------------------------
13
+ export { bootstrapWorkspace, initializeProjectWorkspace, ensureUserWorkspaceInitialized, ensureProjectWorkspaceInitialized, } from "./setup/initialization.js";
14
+ export { WorkspaceInitializationCancelled, WorkspaceInitializationInteraction, } from "./setup/initialization-interaction.js";
15
+ export { SetupOutcomeSchema, SetupWorkspace, prepareSetupWorkspace, previewOrApplySetupWorkspace, previewAgentDefault, reportSetupWorkspace, } from "./setup/setup-workspace.js";
16
+ // -----------------------------------------------------------------------------
17
+ // Configured-agent membership
18
+ // -----------------------------------------------------------------------------
19
+ export { agentLifecycle, isCatalogAgentId, isRetiredAgent, lifecycleWarning, } from "./membership/agent-lifecycle.js";
20
+ export { dedupe, validateAgentIds } from "./membership/validate-agent-ids.js";
21
+ export { ConfigureAgents, ConfiguredAgentInventorySchema, listConfiguredAgents, prepareAddConfiguredAgents, prepareRemoveConfiguredAgents, previewOrApplyAddConfiguredAgents, previewOrApplyRemoveConfiguredAgents, } from "./membership/configure-agents.js";
22
+ // -----------------------------------------------------------------------------
23
+ // Instruction-file management
24
+ // -----------------------------------------------------------------------------
25
+ export { InstructionsStatusSchema, ManageInstructions, instructionsStatus, prepareManageInstructions, previewOrApplyManageInstructions, } from "./instructions/manage-instructions.js";
26
+ // -----------------------------------------------------------------------------
27
+ // Inline MCP servers
28
+ // -----------------------------------------------------------------------------
29
+ export { makeInlineMcpDefinition, matchesInlineMcpEntry, parseInlineMcpEnv, parseInlineMcpHeaders, splitCommand, validateInlineMcpRemoteUrl, } from "./inline-mcp/definition.js";
30
+ export { AddInlineMcpServer, prepareAddInlineMcpServer, previewOrApplyAddInlineMcpServer, } from "./inline-mcp/add-inline-mcp-server.js";
31
+ export { preflightMcpImports, } from "./mcp-import/preflight.js";
32
+ export { applyMcpImport, collectMcpImportSources } from "./mcp-import/apply.js";
33
+ export { ImportMcpServers, prepareImportMcpServers, previewOrApplyImportMcpServers, } from "./mcp-import/import-mcp-servers.js";
17
34
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Inline MCP servers: an MCP server this workspace defines in its own
3
+ * settings rather than acquiring as a package.
4
+ *
5
+ * An inline entry is authored, not resolved: the workspace is the authority
6
+ * for what it says, so adding one records the definition and projects it to
7
+ * every configured agent, and never records an accepted resolution. Repeating
8
+ * an add that already matches the recorded entry changes nothing.
9
+ *
10
+ * @experimental This API is unstable and may change without notice.
11
+ */
12
+ import * as Effect from "effect/Effect";
13
+ import * as FileSystem from "effect/FileSystem";
14
+ import * as Path from "effect/Path";
15
+ import { NativeWriteAuthority } from "@agentxm/agent-integration";
16
+ import type { WorkspaceScope } from "@agentxm/extension-model/unstable/workspace-scope";
17
+ import { OperationJournal, ResolvePlanInteraction, type OperationResolution, type PlanExecution } from "@agentxm/workspace-operations";
18
+ import { ConfiguredAgentOutcomesProvider, WorkspaceMutations, type WorkspaceStateReadFailure } from "@agentxm/workspace-state";
19
+ import { FootprintRecorder, WorkspaceTransactionScope } from "@agentxm/workspace-transactions";
20
+ import { WorkspaceConfigurationFailed, type WorkspaceConfigurationExecutionFailure } from "../errors.js";
21
+ import type { InlineMcpDefinition } from "../mcp-import/preflight.js";
22
+ export interface AddInlineMcpServerRequest {
23
+ readonly name: string;
24
+ /** Inline stdio command line, such as `npx -y linear-mcp-server`. */
25
+ readonly command?: string;
26
+ /** Inline remote streamable-HTTP URL. */
27
+ readonly url?: string;
28
+ /** `NAME` or `NAME=VALUE` inputs; a bare name becomes an environment reference. */
29
+ readonly env: ReadonlyArray<string>;
30
+ /** `Name:Value` headers for a remote server. */
31
+ readonly headers: ReadonlyArray<string>;
32
+ }
33
+ export interface AddInlineMcpServerCandidate {
34
+ readonly _tag: "AddInlineMcpServer";
35
+ readonly name: string;
36
+ readonly definition: InlineMcpDefinition;
37
+ readonly env: Readonly<Record<string, string>>;
38
+ /** Whether the settings file already carries an entry under this name. */
39
+ readonly replacesExistingEntry: boolean;
40
+ readonly scope: WorkspaceScope;
41
+ }
42
+ /** The recorded entry already says exactly what the request asked for. */
43
+ export interface InlineMcpServerUnchanged {
44
+ readonly _tag: "Unchanged";
45
+ readonly name: string;
46
+ readonly message: string;
47
+ }
48
+ /**
49
+ * Settle an inline add: exactly one transport, validated inputs, and a
50
+ * definition the workspace can record. A request whose recorded entry already
51
+ * matches is reported as unchanged.
52
+ */
53
+ export declare const prepareAddInlineMcpServer: (request: AddInlineMcpServerRequest) => Effect.Effect<AddInlineMcpServerCandidate | InlineMcpServerUnchanged, WorkspaceConfigurationFailed | WorkspaceStateReadFailure, WorkspaceMutations>;
54
+ /** Every service an inline MCP change and its plan resolution need. */
55
+ export type AddInlineMcpServerRequirements = ConfiguredAgentOutcomesProvider | FileSystem.FileSystem | FootprintRecorder | NativeWriteAuthority | OperationJournal | Path.Path | ResolvePlanInteraction | WorkspaceMutations | WorkspaceTransactionScope;
56
+ /** Preview or apply a settled inline add: record the entry, then project it. */
57
+ export declare const previewOrApplyAddInlineMcpServer: (candidate: AddInlineMcpServerCandidate, execution: PlanExecution) => Effect.Effect<OperationResolution<void>, WorkspaceConfigurationExecutionFailure, AddInlineMcpServerRequirements>;
58
+ /** The inline MCP capability use case. */
59
+ export declare const AddInlineMcpServer: {
60
+ readonly prepare: (request: AddInlineMcpServerRequest) => Effect.Effect<AddInlineMcpServerCandidate | InlineMcpServerUnchanged, WorkspaceConfigurationFailed | WorkspaceStateReadFailure, WorkspaceMutations>;
61
+ readonly previewOrApply: (candidate: AddInlineMcpServerCandidate, execution: PlanExecution) => Effect.Effect<OperationResolution<void>, WorkspaceConfigurationExecutionFailure, AddInlineMcpServerRequirements>;
62
+ };
63
+ //# sourceMappingURL=add-inline-mcp-server.d.ts.map
@@ -0,0 +1,253 @@
1
+ /**
2
+ * Inline MCP servers: an MCP server this workspace defines in its own
3
+ * settings rather than acquiring as a package.
4
+ *
5
+ * An inline entry is authored, not resolved: the workspace is the authority
6
+ * for what it says, so adding one records the definition and projects it to
7
+ * every configured agent, and never records an accepted resolution. Repeating
8
+ * an add that already matches the recorded entry changes nothing.
9
+ *
10
+ * @experimental This API is unstable and may change without notice.
11
+ */
12
+ import * as Effect from "effect/Effect";
13
+ import * as FileSystem from "effect/FileSystem";
14
+ import * as Option from "effect/Option";
15
+ import * as Path from "effect/Path";
16
+ import { NativeWriteAuthority, syncInlineMcpServerToAgents, } from "@agentxm/agent-integration";
17
+ import { OperationJournal, ResolvePlanInteraction, StepFailure, operationPresentation, prepareExecutionCandidate, resolveExecutionCandidate, } from "@agentxm/workspace-operations";
18
+ import { ConfiguredAgentOutcomesProvider, WorkspaceMutations, } from "@agentxm/workspace-state";
19
+ import { FootprintRecorder, WorkspaceTransactionScope } from "@agentxm/workspace-transactions";
20
+ import { WorkspaceConfigurationFailed, workspaceChangeFailedToStepFailure, } from "../errors.js";
21
+ import { makeInlineMcpDefinition, matchesInlineMcpEntry, parseInlineMcpEnv, parseInlineMcpHeaders, validateInlineMcpRemoteUrl, } from "./definition.js";
22
+ const plural = (count, singular) => `${String(count)} ${singular}${count === 1 ? "" : "s"}`;
23
+ const settingsDisplayPath = (scope) => scope === "project" ? "axm.json" : ".axm/workspace/axm.json";
24
+ /**
25
+ * Serialize a native-format failure. Every member of the family names the
26
+ * fact that stopped it, so the sentence carries over rather than being
27
+ * replaced by a generic one the person cannot act on.
28
+ */
29
+ const nativeFailureToStepFailure = (failure) => {
30
+ switch (failure._tag) {
31
+ case "McpEntryUnmanaged":
32
+ return new StepFailure({
33
+ category: "conflict",
34
+ detail: `MCP server ${failure.serverName} in ${failure.configPath} is not AXM-managed`,
35
+ cause: failure,
36
+ });
37
+ case "McpOwnershipMarkerInvalid":
38
+ return new StepFailure({
39
+ category: "conflict",
40
+ detail: `MCP server ${failure.serverName} carries ${failure.state} AXM ownership markers`,
41
+ cause: failure,
42
+ });
43
+ case "McpSharedTargetConflict":
44
+ return new StepFailure({ category: "conflict", detail: failure.reason, cause: failure });
45
+ case "NativeWriteRefused":
46
+ return new StepFailure({
47
+ category: "conflict",
48
+ detail: `Native MCP configuration at ${failure.path} could not be protected`,
49
+ cause: failure,
50
+ });
51
+ case "TransientBackupFailed":
52
+ return new StepFailure({
53
+ category: "internal",
54
+ detail: "A native MCP configuration backup could not be taken",
55
+ cause: failure,
56
+ });
57
+ case "WriteBackupRetained":
58
+ return new StepFailure({
59
+ category: "internal",
60
+ detail: `${nativeFailureToStepFailure(failure.failure).detail}; the original content is preserved at ${failure.backupPath}`,
61
+ cause: failure,
62
+ });
63
+ default:
64
+ return new StepFailure({ category: "conflict", detail: failure.detail, cause: failure });
65
+ }
66
+ };
67
+ /**
68
+ * Settle an inline add: exactly one transport, validated inputs, and a
69
+ * definition the workspace can record. A request whose recorded entry already
70
+ * matches is reported as unchanged.
71
+ */
72
+ export const prepareAddInlineMcpServer = (request) => Effect.gen(function* () {
73
+ if (request.command === undefined && request.url === undefined) {
74
+ return yield* new WorkspaceConfigurationFailed({
75
+ category: "usage",
76
+ detail: `mcps add only configures inline MCP servers. Use axm mcps install ${request.name} for package or source locators.`,
77
+ suggestions: [
78
+ {
79
+ description: "Install the MCP server package",
80
+ cmd: `axm mcps install ${request.name}`,
81
+ },
82
+ ],
83
+ });
84
+ }
85
+ if (request.command !== undefined && request.url !== undefined) {
86
+ return yield* new WorkspaceConfigurationFailed({
87
+ category: "usage",
88
+ detail: "Use exactly one of --command or --url.",
89
+ });
90
+ }
91
+ const workspace = yield* WorkspaceMutations;
92
+ const env = yield* parseInlineMcpEnv(request.env);
93
+ const headers = yield* parseInlineMcpHeaders(request.headers);
94
+ if (request.url !== undefined)
95
+ yield* validateInlineMcpRemoteUrl(request.url);
96
+ const definition = yield* makeInlineMcpDefinition({
97
+ command: request.command,
98
+ url: request.url,
99
+ }, headers);
100
+ const configured = yield* workspace.getConfiguredMcpServerEntries();
101
+ const existing = configured[request.name];
102
+ if (matchesInlineMcpEntry({ existing, definition, env })) {
103
+ return {
104
+ _tag: "Unchanged",
105
+ name: request.name,
106
+ message: `MCP server ${request.name} is already configured`,
107
+ };
108
+ }
109
+ return {
110
+ _tag: "AddInlineMcpServer",
111
+ name: request.name,
112
+ definition,
113
+ env,
114
+ replacesExistingEntry: existing !== undefined,
115
+ scope: workspace.scope,
116
+ };
117
+ });
118
+ const configArtifact = (scope, change) => ({
119
+ path: settingsDisplayPath(scope),
120
+ scope,
121
+ change,
122
+ targets: [{ path: settingsDisplayPath(scope), change }],
123
+ });
124
+ const recordStep = (candidate) => ({
125
+ label: `Configure ${candidate.name}`,
126
+ readiness: "ready",
127
+ run: Effect.gen(function* () {
128
+ const workspace = yield* WorkspaceMutations;
129
+ yield* workspace
130
+ .setMcpServerEntry(candidate.name, {
131
+ kind: "inline",
132
+ ...(candidate.definition.type === "stdio"
133
+ ? { command: candidate.definition.command, args: candidate.definition.args }
134
+ : { url: candidate.definition.url, headers: candidate.definition.headers }),
135
+ env: candidate.env,
136
+ enabled: true,
137
+ })
138
+ .pipe(Effect.mapError(workspaceChangeFailedToStepFailure));
139
+ return {
140
+ result: "success",
141
+ message: `Configured ${candidate.name}`,
142
+ artifact: configArtifact(candidate.scope, candidate.replacesExistingEntry ? "updated" : "created"),
143
+ };
144
+ }),
145
+ });
146
+ /**
147
+ * Project the recorded entry into every configured agent's native MCP
148
+ * configuration. An agent that refuses the write is reported as a warning
149
+ * rather than failing the change: the workspace's own record is authoritative
150
+ * and the next reconciliation retries the projection.
151
+ */
152
+ const projectStep = (candidate) => ({
153
+ label: `Sync ${candidate.name} to configured agents`,
154
+ readiness: "ready",
155
+ run: Effect.gen(function* () {
156
+ const workspace = yield* WorkspaceMutations;
157
+ const entries = yield* workspace
158
+ .getConfiguredMcpServerEntries()
159
+ .pipe(Effect.mapError(workspaceChangeFailedToStepFailure));
160
+ const entry = entries[candidate.name];
161
+ if (entry === undefined) {
162
+ return {
163
+ result: "success",
164
+ message: `${candidate.name} is not configured`,
165
+ };
166
+ }
167
+ const agentIds = yield* workspace
168
+ .getConfiguredAgents()
169
+ .pipe(Effect.mapError(workspaceChangeFailedToStepFailure));
170
+ const outcomes = yield* syncInlineMcpServerToAgents(agentIds, {
171
+ workspaceRoot: workspace.baseDir,
172
+ serverName: candidate.name,
173
+ entry,
174
+ scope: workspace.scope,
175
+ }).pipe(Effect.mapError(nativeFailureToStepFailure));
176
+ const warningDetails = outcomes.flatMap((outcome, index) => {
177
+ const agentId = agentIds[index] ?? "unknown";
178
+ return outcome._tag === "success"
179
+ ? (outcome.warnings ?? []).map((warning) => `${agentId}: ${warning}`)
180
+ : [`${agentId}: ${outcome.reason}`];
181
+ });
182
+ const successfulAgentIds = outcomes.flatMap((outcome, index) => {
183
+ const agentId = agentIds[index];
184
+ return outcome._tag === "success" && agentId !== undefined ? [agentId] : [];
185
+ });
186
+ const groupedTargets = new Map();
187
+ outcomes.forEach((outcome, index) => {
188
+ const agentId = agentIds[index];
189
+ if (outcome._tag !== "success" || agentId === undefined)
190
+ return;
191
+ (outcome.targets ?? []).forEach((target) => {
192
+ const grouped = groupedTargets.get(target.path);
193
+ if (grouped === undefined) {
194
+ groupedTargets.set(target.path, {
195
+ path: target.path,
196
+ change: target.change,
197
+ agentIds: [agentId],
198
+ });
199
+ return;
200
+ }
201
+ grouped.agentIds.push(agentId);
202
+ if (grouped.change !== "created" && target.change === "created") {
203
+ grouped.change = "created";
204
+ }
205
+ });
206
+ });
207
+ const syncTargets = [...groupedTargets.values()].map((target) => ({
208
+ path: target.path,
209
+ change: target.change,
210
+ agentIds: target.agentIds,
211
+ }));
212
+ const artifact = successfulAgentIds.length === 0
213
+ ? undefined
214
+ : {
215
+ path: syncTargets.length === 1
216
+ ? (syncTargets[0]?.path ?? ".mcp.json")
217
+ : "agent MCP configs",
218
+ scope: candidate.scope,
219
+ agents: successfulAgentIds,
220
+ change: syncTargets.some((target) => target.change === "created")
221
+ ? "created"
222
+ : "updated",
223
+ fileCount: syncTargets.length,
224
+ targets: syncTargets,
225
+ };
226
+ return {
227
+ result: "success",
228
+ message: warningDetails.length === 0
229
+ ? `Synced ${candidate.name} to ${plural(successfulAgentIds.length, "agent")}`
230
+ : `Synced ${candidate.name} to ${plural(successfulAgentIds.length, "agent")} with ${plural(warningDetails.length, "warning")}`,
231
+ ...(warningDetails.length > 0 ? { warnings: warningDetails } : {}),
232
+ ...(artifact === undefined ? {} : { artifact }),
233
+ };
234
+ }),
235
+ });
236
+ /** Preview or apply a settled inline add: record the entry, then project it. */
237
+ export const previewOrApplyAddInlineMcpServer = (candidate, execution) => Effect.gen(function* () {
238
+ const plan = {
239
+ _tag: "Plan",
240
+ name: "Add MCP server",
241
+ description: Option.some(`Configure ${candidate.name} and sync agent MCP configs`),
242
+ presentation: operationPresentation({ imperative: "configure", past: "Configured", gerund: "Configuring" }, "mcp-server"),
243
+ jobs: [{ concurrency: 1, steps: [recordStep(candidate), projectStep(candidate)] }],
244
+ };
245
+ const prepared = yield* prepareExecutionCandidate(plan);
246
+ return yield* resolveExecutionCandidate(prepared, execution);
247
+ });
248
+ /** The inline MCP capability use case. */
249
+ export const AddInlineMcpServer = {
250
+ prepare: prepareAddInlineMcpServer,
251
+ previewOrApply: previewOrApplyAddInlineMcpServer,
252
+ };
253
+ //# sourceMappingURL=add-inline-mcp-server.js.map
@@ -8,8 +8,8 @@
8
8
  */
9
9
  import * as Effect from "effect/Effect";
10
10
  import type { McpServerEntry } from "@agentxm/workspace-state";
11
- import { WorkspaceConfigurationFailed } from "./errors.js";
12
- import type { InlineMcpDefinition } from "./mcp-import-preflight.js";
11
+ import { WorkspaceConfigurationFailed } from "../errors.js";
12
+ import type { InlineMcpDefinition } from "../mcp-import/preflight.js";
13
13
  export declare const splitCommand: (value: string) => ReadonlyArray<string>;
14
14
  export declare const parseInlineMcpEnv: (values: ReadonlyArray<string>) => Effect.Effect<Readonly<Record<string, string>>, WorkspaceConfigurationFailed>;
15
15
  export declare const parseInlineMcpHeaders: (values: ReadonlyArray<string>) => Effect.Effect<Readonly<Record<string, string>>, WorkspaceConfigurationFailed>;
@@ -24,4 +24,4 @@ export declare const makeInlineMcpDefinition: (args: {
24
24
  readonly command: string | undefined;
25
25
  readonly url: string | undefined;
26
26
  }, headers: Readonly<Record<string, string>>) => Effect.Effect<InlineMcpDefinition, WorkspaceConfigurationFailed>;
27
- //# sourceMappingURL=inline-mcp.d.ts.map
27
+ //# sourceMappingURL=definition.d.ts.map
@@ -7,7 +7,7 @@
7
7
  * @experimental This API is unstable and may change without notice.
8
8
  */
9
9
  import * as Effect from "effect/Effect";
10
- import { WorkspaceConfigurationFailed } from "./errors.js";
10
+ import { WorkspaceConfigurationFailed } from "../errors.js";
11
11
  export const splitCommand = (value) => value.match(/(?:[^\s"']+|"[^"]*"|'[^']*')+/g)?.map((part) => {
12
12
  if ((part.startsWith('"') && part.endsWith('"')) ||
13
13
  (part.startsWith("'") && part.endsWith("'"))) {
@@ -128,4 +128,4 @@ export const makeInlineMcpDefinition = (args, headers) => Effect.gen(function* (
128
128
  detail: "Provide --command or --url for inline MCP servers.",
129
129
  });
130
130
  });
131
- //# sourceMappingURL=inline-mcp.js.map
131
+ //# sourceMappingURL=definition.js.map