@agentxm/workspace-state 0.28.4 → 0.28.6
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/index.d.ts +3 -2
- package/dist/src/index.js +3 -2
- package/dist/src/lockfile/lockfile.d.ts +3 -3
- package/dist/src/lockfile/schema.d.ts +5 -4
- package/dist/src/lockfile/schema.js +5 -4
- package/dist/src/settings/schema.d.ts +0 -10
- package/dist/src/settings/schema.js +1 -22
- package/dist/src/workspace/accepted-canonical-ref.d.ts +3 -3
- package/dist/src/workspace/accepted-canonical-ref.js +2 -2
- package/dist/src/workspace/canonical-observation.js +8 -5
- package/dist/src/workspace/configured-agent-outcomes.d.ts +0 -1
- package/dist/src/workspace/configured-agent-outcomes.js +0 -11
- package/dist/src/workspace/desired-state-graph.d.ts +13 -1
- package/dist/src/workspace/desired-state-graph.js +80 -10
- package/dist/src/workspace/mcp-entry-semantics.d.ts +2 -5
- package/dist/src/workspace/mcp-entry-semantics.js +2 -4
- package/dist/src/workspace/mcp-source-identity.d.ts +17 -0
- package/dist/src/workspace/mcp-source-identity.js +40 -0
- package/dist/src/workspace/read-model/__fixtures__/builder.js +1 -1
- package/dist/src/workspace/read-model/errors.d.ts +12 -2
- package/dist/src/workspace/read-model/errors.js +3 -0
- package/dist/src/workspace/read-model/extensions/mcp-server.js +46 -11
- package/dist/src/workspace/read-model/state.js +18 -2
- package/dist/src/workspace/read-model/types.d.ts +1 -1
- package/dist/src/workspace/read-model-record-readers.js +1 -7
- package/dist/src/workspace/service-interface.d.ts +9 -7
- package/dist/src/workspace/service.d.ts +241 -10
- package/dist/src/workspace/service.js +50 -18
- package/dist/src/workspace/test-stubs.js +3 -2
- package/package.json +5 -3
|
@@ -22,6 +22,7 @@ import * as Path from "effect/Path";
|
|
|
22
22
|
import * as Option from "effect/Option";
|
|
23
23
|
import type { Handle } from "@agentxm/extension-model/unstable/extensions/handle";
|
|
24
24
|
import { DesiredPackGraphIncomplete, InvalidAgentId, LockedSkillMissing, SettingsEntryMissing, WorkspaceNotInitialized } from "./errors.js";
|
|
25
|
+
import { LockfileVersionUnsupported } from "./read-model/errors.js";
|
|
25
26
|
import { LockfileValidationError } from "../lockfile/errors.js";
|
|
26
27
|
import { type HookEntry, type KnowledgeEntry, type InstructionsConfigValue, type McpServerEntry, type SkillEntry, type SubagentEntry, type PackEntry, type RuleEntry, type SourceHostConfig } from "../settings/index.js";
|
|
27
28
|
import { type ScopedReleaseAgeExcludePattern } from "@agentxm/extension-model/unstable/extensions/release-age";
|
|
@@ -36,8 +37,9 @@ export type WorkspaceLayerOptions = WorkspaceMutationsOptions;
|
|
|
36
37
|
/**
|
|
37
38
|
* Create the workspace mutations service from an existing workspace on disk.
|
|
38
39
|
*
|
|
39
|
-
* The workspace must already be initialized. Missing or invalid settings
|
|
40
|
-
* fast with a typed
|
|
40
|
+
* The workspace must already be initialized. Missing or invalid settings and
|
|
41
|
+
* invalid or unsupported lockfiles fail fast with a typed
|
|
42
|
+
* `WorkspaceMutationsError`. The two operations-side
|
|
41
43
|
* capabilities — the transaction runner and transition acquirer — are
|
|
42
44
|
* injected through `makeCapabilities`; the composition seam in
|
|
43
45
|
* `./operations/load-workspace.ts` supplies the live implementation.
|
|
@@ -52,7 +54,7 @@ export declare const makeWorkspaceMutations: (options: WorkspaceLayerOptions, ma
|
|
|
52
54
|
getLockfileState: () => Effect.Effect<LockfileState, LockfileValidationError | WorkspaceRootEscape>;
|
|
53
55
|
getDesiredStateGraph: (graphOptions?: Parameters<(graphOptions?: {
|
|
54
56
|
readonly prospectivePacks?: Parameters<typeof buildDesiredStateGraph>[0]["prospectivePacks"];
|
|
55
|
-
}) => Effect.Effect<import("./desired-state-graph.js").DesiredStateGraph,
|
|
57
|
+
}) => Effect.Effect<import("./desired-state-graph.js").DesiredStateGraph, import("./read-model/errors.js").SettingsIoError | import("./read-model/errors.js").SettingsParseError | import("./read-model/errors.js").SettingsDecodeError | import("./read-model/errors.js").LockfileIoError | import("./read-model/errors.js").LockfileParseError | import("./read-model/errors.js").LockfileDecodeError | LockfileVersionUnsupported | WorkspaceRootEscape, never>>[0]) => Effect.Effect<import("./desired-state-graph.js").DesiredStateGraph, import("./read-model/errors.js").SettingsIoError | import("./read-model/errors.js").SettingsParseError | import("./read-model/errors.js").SettingsDecodeError | import("./read-model/errors.js").LockfileIoError | import("./read-model/errors.js").LockfileParseError | import("./read-model/errors.js").LockfileDecodeError | LockfileVersionUnsupported | WorkspaceRootEscape, never>;
|
|
56
58
|
getConfiguredSources: () => Effect.Effect<ReadonlyArray<SourceHostConfig>, WorkspaceSettingsReadFailure>;
|
|
57
59
|
getConfiguredSourceByName: (name: string) => Effect.Effect<Option.Option<{
|
|
58
60
|
readonly name: string;
|
|
@@ -115,7 +117,6 @@ export declare const makeWorkspaceMutations: (options: WorkspaceLayerOptions, ma
|
|
|
115
117
|
readonly [x: string]: string;
|
|
116
118
|
};
|
|
117
119
|
readonly url?: string | undefined;
|
|
118
|
-
readonly agents?: readonly ("adal" | "aider-desk" | "amp" | "antigravity" | "antigravity-cli" | "augment" | "claude-code" | "cline" | "codearts-agent" | "codebuddy" | "codemaker" | "codestudio" | "codex" | "command-code" | "continue" | "cortex" | "crush" | "cursor" | "deepagents" | "devin" | "dexto" | "droid" | "firebender" | "forgecode" | "gemini-cli" | "github-copilot-cli" | "goose" | "grok-cli" | "hermes" | "ibm-bob" | "iflow-cli" | "junie" | "lingma" | "kilo" | "kimi-cli" | "kiro-cli" | "kode" | "mcpjam" | "minimax-code" | "mistral-vibe" | "mux" | "neovate" | "openclaw" | "opencode" | "openhands" | "ona" | "pi" | "pochi" | "qoder" | "qoder-cn" | "qwen-code" | "replit" | "roo" | "rovodev" | "tabnine-cli" | "trae-cn" | "trae" | "warp" | "windsurf" | "zencoder" | "zed" | "zenflow")[] | undefined;
|
|
119
120
|
readonly command?: string | undefined;
|
|
120
121
|
readonly args?: readonly string[] | undefined;
|
|
121
122
|
readonly headers?: {
|
|
@@ -130,7 +131,6 @@ export declare const makeWorkspaceMutations: (options: WorkspaceLayerOptions, ma
|
|
|
130
131
|
readonly kind: "inline";
|
|
131
132
|
readonly url?: string | undefined;
|
|
132
133
|
readonly source?: undefined;
|
|
133
|
-
readonly agents?: readonly ("adal" | "aider-desk" | "amp" | "antigravity" | "antigravity-cli" | "augment" | "claude-code" | "cline" | "codearts-agent" | "codebuddy" | "codemaker" | "codestudio" | "codex" | "command-code" | "continue" | "cortex" | "crush" | "cursor" | "deepagents" | "devin" | "dexto" | "droid" | "firebender" | "forgecode" | "gemini-cli" | "github-copilot-cli" | "goose" | "grok-cli" | "hermes" | "ibm-bob" | "iflow-cli" | "junie" | "lingma" | "kilo" | "kimi-cli" | "kiro-cli" | "kode" | "mcpjam" | "minimax-code" | "mistral-vibe" | "mux" | "neovate" | "openclaw" | "opencode" | "openhands" | "ona" | "pi" | "pochi" | "qoder" | "qoder-cn" | "qwen-code" | "replit" | "roo" | "rovodev" | "tabnine-cli" | "trae-cn" | "trae" | "warp" | "windsurf" | "zencoder" | "zed" | "zenflow")[] | undefined;
|
|
134
134
|
readonly command?: string | undefined;
|
|
135
135
|
readonly args?: readonly string[] | undefined;
|
|
136
136
|
readonly headers?: {
|
|
@@ -1534,7 +1534,7 @@ export declare const makeWorkspaceMutations: (options: WorkspaceLayerOptions, ma
|
|
|
1534
1534
|
readonly treeIntegrity: string & import("effect/Brand").Brand<"TreeIntegrity">;
|
|
1535
1535
|
};
|
|
1536
1536
|
}, LockfileReadError | WorkspaceRootEscape, never>;
|
|
1537
|
-
getLockedMcpServer: (
|
|
1537
|
+
getLockedMcpServer: (resolutionKey: string) => Effect.Effect<Option.Option<{
|
|
1538
1538
|
readonly type: "github";
|
|
1539
1539
|
readonly owner: string;
|
|
1540
1540
|
readonly sourceType: "github";
|
|
@@ -1650,8 +1650,239 @@ export declare const makeWorkspaceMutations: (options: WorkspaceLayerOptions, ma
|
|
|
1650
1650
|
readonly publisherBindingId: string;
|
|
1651
1651
|
readonly treeIntegrity: string & import("effect/Brand").Brand<"TreeIntegrity">;
|
|
1652
1652
|
}>, LockfileReadError | WorkspaceRootEscape, never>;
|
|
1653
|
-
|
|
1654
|
-
|
|
1653
|
+
getLockedMcpServerForConnection: (localName: string) => Effect.Effect<Option.None<{
|
|
1654
|
+
readonly type: "github";
|
|
1655
|
+
readonly owner: string;
|
|
1656
|
+
readonly sourceType: "github";
|
|
1657
|
+
readonly extensionType: "mcp-server";
|
|
1658
|
+
readonly sourceName: string;
|
|
1659
|
+
readonly packageFormat: "agentxm";
|
|
1660
|
+
readonly endpoint: URL;
|
|
1661
|
+
readonly workspaceName: string & import("effect/Brand").Brand<"ExtensionName">;
|
|
1662
|
+
readonly packageOwner: string & import("effect/Brand").Brand<"Handle">;
|
|
1663
|
+
readonly packageName: string & import("effect/Brand").Brand<"ExtensionName">;
|
|
1664
|
+
readonly repo: string;
|
|
1665
|
+
readonly resolvedCommit: string;
|
|
1666
|
+
readonly resolvedTree: string;
|
|
1667
|
+
readonly contentIdentity: string & import("effect/Brand").Brand<"SourceHash">;
|
|
1668
|
+
readonly treeIntegrity: string & import("effect/Brand").Brand<"TreeIntegrity">;
|
|
1669
|
+
readonly path?: string | undefined;
|
|
1670
|
+
readonly ref?: string | undefined;
|
|
1671
|
+
} | {
|
|
1672
|
+
readonly type: "gitlab";
|
|
1673
|
+
readonly owner: string;
|
|
1674
|
+
readonly sourceType: "gitlab";
|
|
1675
|
+
readonly extensionType: "mcp-server";
|
|
1676
|
+
readonly sourceName: string;
|
|
1677
|
+
readonly packageFormat: "agentxm";
|
|
1678
|
+
readonly endpoint: URL;
|
|
1679
|
+
readonly workspaceName: string & import("effect/Brand").Brand<"ExtensionName">;
|
|
1680
|
+
readonly packageOwner: string & import("effect/Brand").Brand<"Handle">;
|
|
1681
|
+
readonly packageName: string & import("effect/Brand").Brand<"ExtensionName">;
|
|
1682
|
+
readonly repo: string;
|
|
1683
|
+
readonly resolvedCommit: string;
|
|
1684
|
+
readonly resolvedTree: string;
|
|
1685
|
+
readonly contentIdentity: string & import("effect/Brand").Brand<"SourceHash">;
|
|
1686
|
+
readonly treeIntegrity: string & import("effect/Brand").Brand<"TreeIntegrity">;
|
|
1687
|
+
readonly path?: string | undefined;
|
|
1688
|
+
readonly ref?: string | undefined;
|
|
1689
|
+
} | {
|
|
1690
|
+
readonly type: "bitbucket";
|
|
1691
|
+
readonly owner: string;
|
|
1692
|
+
readonly sourceType: "bitbucket";
|
|
1693
|
+
readonly extensionType: "mcp-server";
|
|
1694
|
+
readonly sourceName: string;
|
|
1695
|
+
readonly packageFormat: "agentxm";
|
|
1696
|
+
readonly endpoint: URL;
|
|
1697
|
+
readonly workspaceName: string & import("effect/Brand").Brand<"ExtensionName">;
|
|
1698
|
+
readonly packageOwner: string & import("effect/Brand").Brand<"Handle">;
|
|
1699
|
+
readonly packageName: string & import("effect/Brand").Brand<"ExtensionName">;
|
|
1700
|
+
readonly repo: string;
|
|
1701
|
+
readonly resolvedCommit: string;
|
|
1702
|
+
readonly resolvedTree: string;
|
|
1703
|
+
readonly contentIdentity: string & import("effect/Brand").Brand<"SourceHash">;
|
|
1704
|
+
readonly treeIntegrity: string & import("effect/Brand").Brand<"TreeIntegrity">;
|
|
1705
|
+
readonly path?: string | undefined;
|
|
1706
|
+
readonly ref?: string | undefined;
|
|
1707
|
+
} | {
|
|
1708
|
+
readonly type: "azurerepos";
|
|
1709
|
+
readonly sourceType: "azurerepos";
|
|
1710
|
+
readonly extensionType: "mcp-server";
|
|
1711
|
+
readonly sourceName: string;
|
|
1712
|
+
readonly packageFormat: "agentxm";
|
|
1713
|
+
readonly endpoint: URL;
|
|
1714
|
+
readonly workspaceName: string & import("effect/Brand").Brand<"ExtensionName">;
|
|
1715
|
+
readonly packageOwner: string & import("effect/Brand").Brand<"Handle">;
|
|
1716
|
+
readonly packageName: string & import("effect/Brand").Brand<"ExtensionName">;
|
|
1717
|
+
readonly repo: string;
|
|
1718
|
+
readonly resolvedCommit: string;
|
|
1719
|
+
readonly resolvedTree: string;
|
|
1720
|
+
readonly contentIdentity: string & import("effect/Brand").Brand<"SourceHash">;
|
|
1721
|
+
readonly treeIntegrity: string & import("effect/Brand").Brand<"TreeIntegrity">;
|
|
1722
|
+
readonly organization: string;
|
|
1723
|
+
readonly project: string;
|
|
1724
|
+
readonly path?: string | undefined;
|
|
1725
|
+
readonly ref?: string | undefined;
|
|
1726
|
+
} | {
|
|
1727
|
+
readonly type: "git";
|
|
1728
|
+
readonly url: string;
|
|
1729
|
+
readonly sourceType: "git";
|
|
1730
|
+
readonly extensionType: "mcp-server";
|
|
1731
|
+
readonly sourceName: "git";
|
|
1732
|
+
readonly packageFormat: "agentxm";
|
|
1733
|
+
readonly workspaceName: string & import("effect/Brand").Brand<"ExtensionName">;
|
|
1734
|
+
readonly packageOwner: string & import("effect/Brand").Brand<"Handle">;
|
|
1735
|
+
readonly packageName: string & import("effect/Brand").Brand<"ExtensionName">;
|
|
1736
|
+
readonly resolvedCommit: string;
|
|
1737
|
+
readonly resolvedTree: string;
|
|
1738
|
+
readonly contentIdentity: string & import("effect/Brand").Brand<"SourceHash">;
|
|
1739
|
+
readonly treeIntegrity: string & import("effect/Brand").Brand<"TreeIntegrity">;
|
|
1740
|
+
readonly path?: string | undefined;
|
|
1741
|
+
readonly ref?: string | undefined;
|
|
1742
|
+
} | {
|
|
1743
|
+
readonly type: "local";
|
|
1744
|
+
readonly sourceType: "local";
|
|
1745
|
+
readonly sourceName: "local";
|
|
1746
|
+
readonly extensionType: "mcp-server";
|
|
1747
|
+
readonly workspaceName: string & import("effect/Brand").Brand<"ExtensionName">;
|
|
1748
|
+
readonly packageFormat: "agentxm";
|
|
1749
|
+
readonly packageOwner: string & import("effect/Brand").Brand<"Handle">;
|
|
1750
|
+
readonly packageName: string & import("effect/Brand").Brand<"ExtensionName">;
|
|
1751
|
+
readonly path: string;
|
|
1752
|
+
readonly contentIdentity: string & import("effect/Brand").Brand<"SourceHash">;
|
|
1753
|
+
readonly treeIntegrity: string & import("effect/Brand").Brand<"TreeIntegrity">;
|
|
1754
|
+
} | {
|
|
1755
|
+
readonly type: "registry";
|
|
1756
|
+
readonly sourceType: "registry";
|
|
1757
|
+
readonly endpoint: URL;
|
|
1758
|
+
readonly extensionType: "mcp-server";
|
|
1759
|
+
readonly workspaceName: string & import("effect/Brand").Brand<"ExtensionName">;
|
|
1760
|
+
readonly packageFormat: "agentxm";
|
|
1761
|
+
readonly owner: string & import("effect/Brand").Brand<"Handle">;
|
|
1762
|
+
readonly name: string & import("effect/Brand").Brand<"ExtensionName">;
|
|
1763
|
+
readonly resolvedVersion: string & import("effect/Brand").Brand<"Version">;
|
|
1764
|
+
readonly integrity: string;
|
|
1765
|
+
readonly sourceName: string;
|
|
1766
|
+
readonly publisherBindingId: string;
|
|
1767
|
+
readonly treeIntegrity: string & import("effect/Brand").Brand<"TreeIntegrity">;
|
|
1768
|
+
}> | Option.Some<{
|
|
1769
|
+
readonly type: "github";
|
|
1770
|
+
readonly owner: string;
|
|
1771
|
+
readonly sourceType: "github";
|
|
1772
|
+
readonly extensionType: "mcp-server";
|
|
1773
|
+
readonly sourceName: string;
|
|
1774
|
+
readonly packageFormat: "agentxm";
|
|
1775
|
+
readonly endpoint: URL;
|
|
1776
|
+
readonly workspaceName: string & import("effect/Brand").Brand<"ExtensionName">;
|
|
1777
|
+
readonly packageOwner: string & import("effect/Brand").Brand<"Handle">;
|
|
1778
|
+
readonly packageName: string & import("effect/Brand").Brand<"ExtensionName">;
|
|
1779
|
+
readonly repo: string;
|
|
1780
|
+
readonly resolvedCommit: string;
|
|
1781
|
+
readonly resolvedTree: string;
|
|
1782
|
+
readonly contentIdentity: string & import("effect/Brand").Brand<"SourceHash">;
|
|
1783
|
+
readonly treeIntegrity: string & import("effect/Brand").Brand<"TreeIntegrity">;
|
|
1784
|
+
readonly path?: string | undefined;
|
|
1785
|
+
readonly ref?: string | undefined;
|
|
1786
|
+
} | {
|
|
1787
|
+
readonly type: "gitlab";
|
|
1788
|
+
readonly owner: string;
|
|
1789
|
+
readonly sourceType: "gitlab";
|
|
1790
|
+
readonly extensionType: "mcp-server";
|
|
1791
|
+
readonly sourceName: string;
|
|
1792
|
+
readonly packageFormat: "agentxm";
|
|
1793
|
+
readonly endpoint: URL;
|
|
1794
|
+
readonly workspaceName: string & import("effect/Brand").Brand<"ExtensionName">;
|
|
1795
|
+
readonly packageOwner: string & import("effect/Brand").Brand<"Handle">;
|
|
1796
|
+
readonly packageName: string & import("effect/Brand").Brand<"ExtensionName">;
|
|
1797
|
+
readonly repo: string;
|
|
1798
|
+
readonly resolvedCommit: string;
|
|
1799
|
+
readonly resolvedTree: string;
|
|
1800
|
+
readonly contentIdentity: string & import("effect/Brand").Brand<"SourceHash">;
|
|
1801
|
+
readonly treeIntegrity: string & import("effect/Brand").Brand<"TreeIntegrity">;
|
|
1802
|
+
readonly path?: string | undefined;
|
|
1803
|
+
readonly ref?: string | undefined;
|
|
1804
|
+
} | {
|
|
1805
|
+
readonly type: "bitbucket";
|
|
1806
|
+
readonly owner: string;
|
|
1807
|
+
readonly sourceType: "bitbucket";
|
|
1808
|
+
readonly extensionType: "mcp-server";
|
|
1809
|
+
readonly sourceName: string;
|
|
1810
|
+
readonly packageFormat: "agentxm";
|
|
1811
|
+
readonly endpoint: URL;
|
|
1812
|
+
readonly workspaceName: string & import("effect/Brand").Brand<"ExtensionName">;
|
|
1813
|
+
readonly packageOwner: string & import("effect/Brand").Brand<"Handle">;
|
|
1814
|
+
readonly packageName: string & import("effect/Brand").Brand<"ExtensionName">;
|
|
1815
|
+
readonly repo: string;
|
|
1816
|
+
readonly resolvedCommit: string;
|
|
1817
|
+
readonly resolvedTree: string;
|
|
1818
|
+
readonly contentIdentity: string & import("effect/Brand").Brand<"SourceHash">;
|
|
1819
|
+
readonly treeIntegrity: string & import("effect/Brand").Brand<"TreeIntegrity">;
|
|
1820
|
+
readonly path?: string | undefined;
|
|
1821
|
+
readonly ref?: string | undefined;
|
|
1822
|
+
} | {
|
|
1823
|
+
readonly type: "azurerepos";
|
|
1824
|
+
readonly sourceType: "azurerepos";
|
|
1825
|
+
readonly extensionType: "mcp-server";
|
|
1826
|
+
readonly sourceName: string;
|
|
1827
|
+
readonly packageFormat: "agentxm";
|
|
1828
|
+
readonly endpoint: URL;
|
|
1829
|
+
readonly workspaceName: string & import("effect/Brand").Brand<"ExtensionName">;
|
|
1830
|
+
readonly packageOwner: string & import("effect/Brand").Brand<"Handle">;
|
|
1831
|
+
readonly packageName: string & import("effect/Brand").Brand<"ExtensionName">;
|
|
1832
|
+
readonly repo: string;
|
|
1833
|
+
readonly resolvedCommit: string;
|
|
1834
|
+
readonly resolvedTree: string;
|
|
1835
|
+
readonly contentIdentity: string & import("effect/Brand").Brand<"SourceHash">;
|
|
1836
|
+
readonly treeIntegrity: string & import("effect/Brand").Brand<"TreeIntegrity">;
|
|
1837
|
+
readonly organization: string;
|
|
1838
|
+
readonly project: string;
|
|
1839
|
+
readonly path?: string | undefined;
|
|
1840
|
+
readonly ref?: string | undefined;
|
|
1841
|
+
} | {
|
|
1842
|
+
readonly type: "git";
|
|
1843
|
+
readonly url: string;
|
|
1844
|
+
readonly sourceType: "git";
|
|
1845
|
+
readonly extensionType: "mcp-server";
|
|
1846
|
+
readonly sourceName: "git";
|
|
1847
|
+
readonly packageFormat: "agentxm";
|
|
1848
|
+
readonly workspaceName: string & import("effect/Brand").Brand<"ExtensionName">;
|
|
1849
|
+
readonly packageOwner: string & import("effect/Brand").Brand<"Handle">;
|
|
1850
|
+
readonly packageName: string & import("effect/Brand").Brand<"ExtensionName">;
|
|
1851
|
+
readonly resolvedCommit: string;
|
|
1852
|
+
readonly resolvedTree: string;
|
|
1853
|
+
readonly contentIdentity: string & import("effect/Brand").Brand<"SourceHash">;
|
|
1854
|
+
readonly treeIntegrity: string & import("effect/Brand").Brand<"TreeIntegrity">;
|
|
1855
|
+
readonly path?: string | undefined;
|
|
1856
|
+
readonly ref?: string | undefined;
|
|
1857
|
+
} | {
|
|
1858
|
+
readonly type: "local";
|
|
1859
|
+
readonly sourceType: "local";
|
|
1860
|
+
readonly sourceName: "local";
|
|
1861
|
+
readonly extensionType: "mcp-server";
|
|
1862
|
+
readonly workspaceName: string & import("effect/Brand").Brand<"ExtensionName">;
|
|
1863
|
+
readonly packageFormat: "agentxm";
|
|
1864
|
+
readonly packageOwner: string & import("effect/Brand").Brand<"Handle">;
|
|
1865
|
+
readonly packageName: string & import("effect/Brand").Brand<"ExtensionName">;
|
|
1866
|
+
readonly path: string;
|
|
1867
|
+
readonly contentIdentity: string & import("effect/Brand").Brand<"SourceHash">;
|
|
1868
|
+
readonly treeIntegrity: string & import("effect/Brand").Brand<"TreeIntegrity">;
|
|
1869
|
+
} | {
|
|
1870
|
+
readonly type: "registry";
|
|
1871
|
+
readonly sourceType: "registry";
|
|
1872
|
+
readonly endpoint: URL;
|
|
1873
|
+
readonly extensionType: "mcp-server";
|
|
1874
|
+
readonly workspaceName: string & import("effect/Brand").Brand<"ExtensionName">;
|
|
1875
|
+
readonly packageFormat: "agentxm";
|
|
1876
|
+
readonly owner: string & import("effect/Brand").Brand<"Handle">;
|
|
1877
|
+
readonly name: string & import("effect/Brand").Brand<"ExtensionName">;
|
|
1878
|
+
readonly resolvedVersion: string & import("effect/Brand").Brand<"Version">;
|
|
1879
|
+
readonly integrity: string;
|
|
1880
|
+
readonly sourceName: string;
|
|
1881
|
+
readonly publisherBindingId: string;
|
|
1882
|
+
readonly treeIntegrity: string & import("effect/Brand").Brand<"TreeIntegrity">;
|
|
1883
|
+
}>, import("./read-model/errors.js").SettingsIoError | import("./read-model/errors.js").SettingsParseError | import("./read-model/errors.js").SettingsDecodeError | LockfileReadError | WorkspaceRootEscape, never>;
|
|
1884
|
+
setMcpServer: ({ name, resolutionKey, lockEntry, versionRange, env, enabled, }: SetMcpServerArgs) => Effect.Effect<void, import("../settings/errors.ts").SettingsWriteError | import("./transaction.ts").WorkspaceSnapshotError | import("../lockfile/errors.js").LockfileWriteError | LockfileValidationError | SettingsReadError | LockfileReadError | WorkspaceRootEscape, never>;
|
|
1885
|
+
setMcpServerLock: ({ name: _name, resolutionKey, lockEntry }: SetMcpServerArgs) => Effect.Effect<void, import("../lockfile/errors.js").LockfileWriteError | LockfileValidationError | LockfileReadError | WorkspaceRootEscape, never>;
|
|
1655
1886
|
updateMcpServerEntry: (name: string, updater: (entry: McpServerEntry) => McpServerEntry) => Effect.Effect<void, import("../settings/errors.ts").SettingsWriteError | import("./transaction.ts").WorkspaceSnapshotError | SettingsEntryMissing | SettingsReadError | WorkspaceRootEscape, never>;
|
|
1656
1887
|
setMcpServerEntry: (name: string, entry: McpServerEntry) => Effect.Effect<void, import("../settings/errors.ts").SettingsWriteError | import("./transaction.ts").WorkspaceSnapshotError | SettingsReadError | WorkspaceRootEscape, never>;
|
|
1657
1888
|
removeMcpServer: (name: string) => Effect.Effect<void, import("../settings/errors.ts").SettingsWriteError | import("./transaction.ts").WorkspaceSnapshotError | import("../lockfile/errors.js").LockfileWriteError | LockfileValidationError | SettingsReadError | LockfileReadError | WorkspaceRootEscape, never>;
|
|
@@ -1660,6 +1891,6 @@ export declare const makeWorkspaceMutations: (options: WorkspaceLayerOptions, ma
|
|
|
1660
1891
|
removeMcpServerLock: (name: string) => Effect.Effect<void, import("../lockfile/errors.js").LockfileWriteError | LockfileValidationError | LockfileReadError | WorkspaceRootEscape, never>;
|
|
1661
1892
|
removePackSettings: (name: string) => Effect.Effect<void, import("../settings/errors.ts").SettingsWriteError | import("./transaction.ts").WorkspaceSnapshotError | SettingsReadError | WorkspaceRootEscape, never>;
|
|
1662
1893
|
removePackLock: (name: string) => Effect.Effect<void, import("../lockfile/errors.js").LockfileWriteError | LockfileValidationError | LockfileReadError | WorkspaceRootEscape, never>;
|
|
1663
|
-
isExtensionRequiredByInstalledPack: (target: ExtensionTarget) => Effect.Effect<boolean, DesiredPackGraphIncomplete |
|
|
1664
|
-
}, import("./errors.js").WorkspaceLayoutError | WorkspaceNotInitialized | WorkspaceSettingsReadFailure, FileSystem.FileSystem | Path.Path>;
|
|
1894
|
+
isExtensionRequiredByInstalledPack: (target: ExtensionTarget) => Effect.Effect<boolean, DesiredPackGraphIncomplete | import("./read-model/errors.js").SettingsIoError | import("./read-model/errors.js").SettingsParseError | import("./read-model/errors.js").SettingsDecodeError | import("./read-model/errors.js").LockfileIoError | import("./read-model/errors.js").LockfileParseError | import("./read-model/errors.js").LockfileDecodeError | LockfileVersionUnsupported | WorkspaceRootEscape, never>;
|
|
1895
|
+
}, import("./errors.js").WorkspaceLayoutError | WorkspaceNotInitialized | LockfileReadError | WorkspaceSettingsReadFailure, FileSystem.FileSystem | Path.Path>;
|
|
1665
1896
|
//# sourceMappingURL=service.d.ts.map
|
|
@@ -28,6 +28,7 @@ import { computePackPathsForLayout } from "./pack-paths.js";
|
|
|
28
28
|
import { sanitizeName } from "./extension-name.js";
|
|
29
29
|
import { ConfigurableAgentIdSchema, decodeExtensionNameSync, formatFqn, parseSourceQualifiedRegistrySourcePatternParts, } from "@agentxm/extension-model/unstable/extensions";
|
|
30
30
|
import { DesiredPackGraphIncomplete, InvalidAgentId, LockedSkillMissing, SettingsEntryMissing, WorkspaceNotInitialized, } from "./errors.js";
|
|
31
|
+
import { LockfileVersionUnsupported } from "./read-model/errors.js";
|
|
31
32
|
import { LockfileValidationError } from "../lockfile/errors.js";
|
|
32
33
|
import { createDefaultSettings, writeSettingsAtPath, } from "../settings/index.js";
|
|
33
34
|
import { DEFAULT_MINIMUM_RELEASE_AGE } from "@agentxm/registry-protocol/unstable/registry/release-age-policy";
|
|
@@ -71,15 +72,22 @@ const lockEntrySemanticallyEqual = (current, next) => current !== undefined && s
|
|
|
71
72
|
const skillLockEntrySemanticallyEqual = (current, next) => lockEntrySemanticallyEqual(current, next);
|
|
72
73
|
const preserveAcceptedResolutionOnNoop = (current, next) => (lockEntrySemanticallyEqual(current, next) && current !== undefined ? current : next);
|
|
73
74
|
const subagentLockEntrySemanticallyEqual = (current, next) => lockEntrySemanticallyEqual(current, next);
|
|
74
|
-
const requireInitializedWorkspace = (settingsPath, settings) => settings.pipe(Effect.flatMap(Option.match({
|
|
75
|
-
onNone: () => Effect.
|
|
75
|
+
const requireInitializedWorkspace = (settingsPath, settings, lockfile) => settings.pipe(Effect.flatMap(Option.match({
|
|
76
|
+
onNone: () => lockfile.pipe(Effect.matchEffect({
|
|
77
|
+
onFailure: (error) => error instanceof LockfileVersionUnsupported &&
|
|
78
|
+
error.observedVersion > error.supportedVersion
|
|
79
|
+
? Effect.fail(error)
|
|
80
|
+
: Effect.fail(new WorkspaceNotInitialized({ settingsPath })),
|
|
81
|
+
onSuccess: () => Effect.fail(new WorkspaceNotInitialized({ settingsPath })),
|
|
82
|
+
})),
|
|
76
83
|
onSome: () => Effect.void,
|
|
77
84
|
})));
|
|
78
85
|
/**
|
|
79
86
|
* Create the workspace mutations service from an existing workspace on disk.
|
|
80
87
|
*
|
|
81
|
-
* The workspace must already be initialized. Missing or invalid settings
|
|
82
|
-
* fast with a typed
|
|
88
|
+
* The workspace must already be initialized. Missing or invalid settings and
|
|
89
|
+
* invalid or unsupported lockfiles fail fast with a typed
|
|
90
|
+
* `WorkspaceMutationsError`. The two operations-side
|
|
83
91
|
* capabilities — the transaction runner and transition acquirer — are
|
|
84
92
|
* injected through `makeCapabilities`; the composition seam in
|
|
85
93
|
* `./operations/load-workspace.ts` supplies the live implementation.
|
|
@@ -112,7 +120,8 @@ export const makeWorkspaceMutations = (options, makeCapabilities) => Effect.gen(
|
|
|
112
120
|
const readSettingsCell = (dir, sharedScope) => makeWorkspaceReadModel(scopeForDir(dir, sharedScope)).pipe(Effect.flatMap((readModel) => readModel.state.settings), Effect.provide(contextEnv));
|
|
113
121
|
const readLockfileCell = (dir, sharedScope) => makeWorkspaceReadModel(scopeForDir(dir, sharedScope)).pipe(Effect.flatMap((readModel) => readModel.state.lockfile), Effect.map(Option.getOrElse(createEmptyLockfile)), Effect.provide(contextEnv));
|
|
114
122
|
if (options.allowUninitialized !== true) {
|
|
115
|
-
yield* requireInitializedWorkspace(settingsPath, readSettingsCell(workspaceDir));
|
|
123
|
+
yield* requireInitializedWorkspace(settingsPath, readSettingsCell(workspaceDir), readLockfileCell(workspaceDir));
|
|
124
|
+
yield* readLockfileCell(workspaceDir);
|
|
116
125
|
}
|
|
117
126
|
const projectSettings = yield* readSettingsCell(localRuntimeDir, "project").pipe(Effect.map(Option.getOrElse(() => createDefaultSettings())));
|
|
118
127
|
const userSettings = yield* readSettingsCell(userRuntimeDir, "user").pipe(Effect.map(Option.getOrElse(() => createDefaultSettings())));
|
|
@@ -161,15 +170,23 @@ export const makeWorkspaceMutations = (options, makeCapabilities) => Effect.gen(
|
|
|
161
170
|
}
|
|
162
171
|
// An unreadable or corrupt lockfile is actionable workspace state,
|
|
163
172
|
// not a violated invariant.
|
|
164
|
-
return yield* readLockfileSafe(workspaceDir).pipe(Effect.as("ok"), Effect.catchTag([
|
|
173
|
+
return yield* readLockfileSafe(workspaceDir).pipe(Effect.as("ok"), Effect.catchTag([
|
|
174
|
+
"LockfileIoError",
|
|
175
|
+
"LockfileParseError",
|
|
176
|
+
"LockfileDecodeError",
|
|
177
|
+
"LockfileVersionUnsupported",
|
|
178
|
+
], () => Effect.succeed("invalid")));
|
|
165
179
|
}).pipe(Effect.withSpan("WorkspaceMutations.getLockfileState"));
|
|
166
180
|
const readScopedContext = (f) => makeWorkspaceReadModel(scopeForDir(workspaceDir)).pipe(Effect.flatMap(f), Effect.provide(contextEnv));
|
|
167
181
|
const readDesiredStateGraph = (graphOptions) => Effect.gen(function* () {
|
|
168
182
|
const settings = yield* readSettingsSafe(workspaceDir);
|
|
183
|
+
const configuredSources = yield* getConfiguredSources();
|
|
184
|
+
const registryAuthorities = Object.fromEntries(configuredSources.flatMap((source) => source.type === "registry" ? [[source.name, source.location]] : []));
|
|
169
185
|
const graph = yield* buildDesiredStateGraph({
|
|
170
186
|
baseDir,
|
|
171
187
|
settings,
|
|
172
188
|
layout,
|
|
189
|
+
registryAuthorities,
|
|
173
190
|
...(graphOptions?.prospectivePacks === undefined
|
|
174
191
|
? {}
|
|
175
192
|
: { prospectivePacks: graphOptions.prospectivePacks }),
|
|
@@ -1083,14 +1100,21 @@ export const makeWorkspaceMutations = (options, makeCapabilities) => Effect.gen(
|
|
|
1083
1100
|
// MCP Server methods
|
|
1084
1101
|
// -----------------------------------------------------------------------
|
|
1085
1102
|
getLockedMcpServers: () => readLockfileSafe(workspaceDir).pipe(Effect.map((lf) => lf.mcpServers ?? {})),
|
|
1086
|
-
getLockedMcpServer: (
|
|
1087
|
-
|
|
1103
|
+
getLockedMcpServer: (resolutionKey) => readLockfileSafe(workspaceDir).pipe(Effect.map((lf) => Option.fromUndefinedOr((lf.mcpServers ?? {})[resolutionKey]))),
|
|
1104
|
+
getLockedMcpServerForConnection: (localName) => Effect.gen(function* () {
|
|
1105
|
+
const graph = yield* readDesiredStateGraph();
|
|
1106
|
+
const node = graph.nodes.find((candidate) => candidate.type === "mcp-server" && candidate.name === localName);
|
|
1107
|
+
if (node === undefined || node.authority === "inline")
|
|
1108
|
+
return Option.none();
|
|
1109
|
+
const lockfile = yield* readLockfileSafe(workspaceDir);
|
|
1110
|
+
return Option.fromUndefinedOr((lockfile.mcpServers ?? {})[node.identity]);
|
|
1111
|
+
}),
|
|
1112
|
+
setMcpServer: ({ name, resolutionKey, lockEntry, versionRange, env, enabled, }) => withMutex(Effect.gen(function* () {
|
|
1088
1113
|
// Update settings (uses "mcpServers" key)
|
|
1089
1114
|
const currentSettings = yield* readSettingsSafe(workspaceDir);
|
|
1090
1115
|
const currentMcpServers = currentSettings.mcpServers ?? {};
|
|
1091
1116
|
const currentEnabled = currentMcpServers[name]?.enabled ?? true;
|
|
1092
1117
|
const currentEnv = currentMcpServers[name]?.env ?? {};
|
|
1093
|
-
const currentAgents = currentMcpServers[name]?.agents;
|
|
1094
1118
|
const settingsEntry = {
|
|
1095
1119
|
kind: "sourced",
|
|
1096
1120
|
source: lockEntry.type === "registry"
|
|
@@ -1098,7 +1122,7 @@ export const makeWorkspaceMutations = (options, makeCapabilities) => Effect.gen(
|
|
|
1098
1122
|
const fqn = formatFqn({
|
|
1099
1123
|
owner: lockEntry.owner,
|
|
1100
1124
|
type: "mcp-server",
|
|
1101
|
-
name:
|
|
1125
|
+
name: lockEntry.name,
|
|
1102
1126
|
});
|
|
1103
1127
|
const locator = Option.isSome(versionRange)
|
|
1104
1128
|
? `${fqn}@${versionRange.value}`
|
|
@@ -1108,9 +1132,6 @@ export const makeWorkspaceMutations = (options, makeCapabilities) => Effect.gen(
|
|
|
1108
1132
|
: printSourceParams(lockEntryToSourceParams(lockEntry)),
|
|
1109
1133
|
enabled: enabled ?? currentEnabled,
|
|
1110
1134
|
env: env ?? currentEnv,
|
|
1111
|
-
...((agents ?? currentAgents) === undefined
|
|
1112
|
-
? {}
|
|
1113
|
-
: { agents: agents ?? currentAgents }),
|
|
1114
1135
|
};
|
|
1115
1136
|
const updatedSettings = {
|
|
1116
1137
|
...currentSettings,
|
|
@@ -1127,12 +1148,12 @@ export const makeWorkspaceMutations = (options, makeCapabilities) => Effect.gen(
|
|
|
1127
1148
|
...currentLockfile,
|
|
1128
1149
|
mcpServers: {
|
|
1129
1150
|
...currentLockedMcpServers,
|
|
1130
|
-
[
|
|
1151
|
+
[resolutionKey]: preserveAcceptedResolutionOnNoop(currentLockedMcpServers[resolutionKey], lockEntry),
|
|
1131
1152
|
},
|
|
1132
1153
|
};
|
|
1133
1154
|
yield* commitWorkspaceState(currentLockfile, updatedLockfile);
|
|
1134
1155
|
})).pipe(Effect.withSpan("WorkspaceMutations.setMcpServer")),
|
|
1135
|
-
setMcpServerLock: ({ name, lockEntry }) => withMutex(Effect.gen(function* () {
|
|
1156
|
+
setMcpServerLock: ({ name: _name, resolutionKey, lockEntry }) => withMutex(Effect.gen(function* () {
|
|
1136
1157
|
// Update lockfile only (skip settings) — used for pack dependencies
|
|
1137
1158
|
const currentLockfile = yield* readLockfileSafe(workspaceDir);
|
|
1138
1159
|
const currentLockedMcpServers = currentLockfile.mcpServers ?? {};
|
|
@@ -1140,7 +1161,7 @@ export const makeWorkspaceMutations = (options, makeCapabilities) => Effect.gen(
|
|
|
1140
1161
|
...currentLockfile,
|
|
1141
1162
|
mcpServers: {
|
|
1142
1163
|
...currentLockedMcpServers,
|
|
1143
|
-
[
|
|
1164
|
+
[resolutionKey]: preserveAcceptedResolutionOnNoop(currentLockedMcpServers[resolutionKey], lockEntry),
|
|
1144
1165
|
},
|
|
1145
1166
|
};
|
|
1146
1167
|
yield* commitWorkspaceState(currentLockfile, updatedLockfile);
|
|
@@ -1166,6 +1187,11 @@ export const makeWorkspaceMutations = (options, makeCapabilities) => Effect.gen(
|
|
|
1166
1187
|
yield* writeScopedSettings(updatedSettings).pipe(Effect.provide(fsLayer));
|
|
1167
1188
|
})),
|
|
1168
1189
|
removeMcpServer: (name) => withMutex(Effect.gen(function* () {
|
|
1190
|
+
const graph = yield* readDesiredStateGraph();
|
|
1191
|
+
const desiredNode = graph.nodes.find((node) => node.type === "mcp-server" && node.name === name);
|
|
1192
|
+
const closure = desiredNode === undefined || desiredNode.authority === "inline"
|
|
1193
|
+
? undefined
|
|
1194
|
+
: graph.mcpSourceClosures.find((candidate) => candidate.identity === desiredNode.identity);
|
|
1169
1195
|
// Update settings (uses "mcpServers" key)
|
|
1170
1196
|
const currentSettings = yield* readSettingsSafe(workspaceDir);
|
|
1171
1197
|
const currentMcpServers = currentSettings.mcpServers ?? {};
|
|
@@ -1182,8 +1208,14 @@ export const makeWorkspaceMutations = (options, makeCapabilities) => Effect.gen(
|
|
|
1182
1208
|
// Update lockfile (uses "mcpServers" key)
|
|
1183
1209
|
const currentLockfile = yield* readLockfileSafe(workspaceDir);
|
|
1184
1210
|
const currentLockedMcpServers = currentLockfile.mcpServers ?? {};
|
|
1185
|
-
|
|
1186
|
-
|
|
1211
|
+
const resolutionKey = desiredNode?.identity;
|
|
1212
|
+
const keepSharedResolution = closure !== undefined &&
|
|
1213
|
+
(closure.localNames.length > 1 ||
|
|
1214
|
+
closure.origins.some((origin) => origin.type === "pack"));
|
|
1215
|
+
if (resolutionKey !== undefined &&
|
|
1216
|
+
!keepSharedResolution &&
|
|
1217
|
+
resolutionKey in currentLockedMcpServers) {
|
|
1218
|
+
const { [resolutionKey]: __, ...remainingLockedMcpServers } = currentLockedMcpServers;
|
|
1187
1219
|
void __;
|
|
1188
1220
|
const updatedLockfile = {
|
|
1189
1221
|
...currentLockfile,
|
|
@@ -188,7 +188,7 @@ export const makeBaseWorkspaceMock = (axmDir = "/tmp/axm", overrides) => {
|
|
|
188
188
|
],
|
|
189
189
|
};
|
|
190
190
|
}));
|
|
191
|
-
return { complete: true, nodes, problems: [] };
|
|
191
|
+
return { complete: true, nodes, mcpSourceClosures: [], problems: [] };
|
|
192
192
|
});
|
|
193
193
|
const runTransaction = (args) => Effect.gen(function* () {
|
|
194
194
|
const value = yield* args.transition;
|
|
@@ -304,6 +304,7 @@ export const makeBaseWorkspaceMock = (axmDir = "/tmp/axm", overrides) => {
|
|
|
304
304
|
removeSubagentLock: () => Effect.void,
|
|
305
305
|
getLockedMcpServers: lockedMcpServers,
|
|
306
306
|
getLockedMcpServer: entryFrom(lockedMcpServers),
|
|
307
|
+
getLockedMcpServerForConnection: entryFrom(lockedMcpServers),
|
|
307
308
|
setMcpServer: () => Effect.void,
|
|
308
309
|
setMcpServerLock: () => Effect.void,
|
|
309
310
|
updateMcpServerEntry: () => Effect.void,
|
|
@@ -337,7 +338,7 @@ export const writeWorkspaceFiles = (runtimeDir, opts = {}) => {
|
|
|
337
338
|
...(opts.sources && { sources: opts.sources }),
|
|
338
339
|
};
|
|
339
340
|
const lockfile = {
|
|
340
|
-
lockfileVersion:
|
|
341
|
+
lockfileVersion: 7,
|
|
341
342
|
skills: opts.lockfileSkills ?? {},
|
|
342
343
|
...(hasEntries(opts.lockfileMcpServers) && { mcps: opts.lockfileMcpServers }),
|
|
343
344
|
...(hasEntries(opts.lockfileSubagents) && { subagents: opts.lockfileSubagents }),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentxm/workspace-state",
|
|
3
|
-
"version": "0.28.
|
|
3
|
+
"version": "0.28.6",
|
|
4
4
|
"description": "AXM workspace state kernel: settings, lockfile, read model, and desired-state vocabulary for the axm CLI. Unstable and unsupported — use the axm.sh CLI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "FSL-1.1-MIT",
|
|
@@ -18,10 +18,12 @@
|
|
|
18
18
|
"exports": {
|
|
19
19
|
".": {
|
|
20
20
|
"types": "./dist/src/index.d.ts",
|
|
21
|
+
"axm-source": "./src/index.ts",
|
|
21
22
|
"default": "./dist/src/index.js"
|
|
22
23
|
},
|
|
23
24
|
"./testing": {
|
|
24
25
|
"types": "./dist/src/testing.d.ts",
|
|
26
|
+
"axm-source": "./src/testing.ts",
|
|
25
27
|
"default": "./dist/src/testing.js"
|
|
26
28
|
}
|
|
27
29
|
},
|
|
@@ -43,8 +45,8 @@
|
|
|
43
45
|
"jsonc-parser": "^3.3.1",
|
|
44
46
|
"semver": "^7.8.5",
|
|
45
47
|
"yaml": "^2.9.0",
|
|
46
|
-
"@agentxm/extension-model": "^0.28.
|
|
47
|
-
"@agentxm/registry-protocol": "^0.28.
|
|
48
|
+
"@agentxm/extension-model": "^0.28.6",
|
|
49
|
+
"@agentxm/registry-protocol": "^0.28.6"
|
|
48
50
|
},
|
|
49
51
|
"devDependencies": {
|
|
50
52
|
"@effect/platform-node": "4.0.0-rc.112",
|