@agentxm/workspace-state 0.28.4-bootstrap.0

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 (215) hide show
  1. package/LICENSE +110 -0
  2. package/README.md +11 -0
  3. package/dist/src/index.d.ts +72 -0
  4. package/dist/src/index.js +88 -0
  5. package/dist/src/knowledge/discovery-config.d.ts +12 -0
  6. package/dist/src/knowledge/discovery-config.js +9 -0
  7. package/dist/src/lockfile/accepted-registry-version.d.ts +12 -0
  8. package/dist/src/lockfile/accepted-registry-version.js +13 -0
  9. package/dist/src/lockfile/entry-fields.d.ts +189 -0
  10. package/dist/src/lockfile/entry-fields.js +89 -0
  11. package/dist/src/lockfile/errors.d.ts +48 -0
  12. package/dist/src/lockfile/errors.js +27 -0
  13. package/dist/src/lockfile/index.d.ts +18 -0
  14. package/dist/src/lockfile/index.js +16 -0
  15. package/dist/src/lockfile/lockfile.d.ts +2255 -0
  16. package/dist/src/lockfile/lockfile.js +235 -0
  17. package/dist/src/lockfile/resolved-version.d.ts +4 -0
  18. package/dist/src/lockfile/resolved-version.js +7 -0
  19. package/dist/src/lockfile/schema.d.ts +3062 -0
  20. package/dist/src/lockfile/schema.js +406 -0
  21. package/dist/src/schema/index.d.ts +3 -0
  22. package/dist/src/schema/index.js +2 -0
  23. package/dist/src/schema/read-and-validate-json-file.d.ts +20 -0
  24. package/dist/src/schema/read-and-validate-json-file.js +85 -0
  25. package/dist/src/schema/types.d.ts +26 -0
  26. package/dist/src/schema/types.js +2 -0
  27. package/dist/src/settings/errors.d.ts +22 -0
  28. package/dist/src/settings/errors.js +15 -0
  29. package/dist/src/settings/format-preserving-json.d.ts +40 -0
  30. package/dist/src/settings/format-preserving-json.js +80 -0
  31. package/dist/src/settings/index.d.ts +15 -0
  32. package/dist/src/settings/index.js +14 -0
  33. package/dist/src/settings/schema.d.ts +687 -0
  34. package/dist/src/settings/schema.js +977 -0
  35. package/dist/src/settings/settings.d.ts +38 -0
  36. package/dist/src/settings/settings.js +213 -0
  37. package/dist/src/testing.d.ts +17 -0
  38. package/dist/src/testing.js +17 -0
  39. package/dist/src/utils/atomic-write.d.ts +67 -0
  40. package/dist/src/utils/atomic-write.js +71 -0
  41. package/dist/src/utils/environment.d.ts +16 -0
  42. package/dist/src/utils/environment.js +19 -0
  43. package/dist/src/utils/path-safety.d.ts +25 -0
  44. package/dist/src/utils/path-safety.js +34 -0
  45. package/dist/src/utils/resolve-parent-symlinks.d.ts +16 -0
  46. package/dist/src/utils/resolve-parent-symlinks.js +36 -0
  47. package/dist/src/workspace/accepted-canonical-ref.d.ts +58 -0
  48. package/dist/src/workspace/accepted-canonical-ref.js +229 -0
  49. package/dist/src/workspace/artifact-change.d.ts +14 -0
  50. package/dist/src/workspace/artifact-change.js +18 -0
  51. package/dist/src/workspace/canonical-observation.d.ts +39 -0
  52. package/dist/src/workspace/canonical-observation.js +307 -0
  53. package/dist/src/workspace/configured-agent-outcome.d.ts +22 -0
  54. package/dist/src/workspace/configured-agent-outcome.js +33 -0
  55. package/dist/src/workspace/configured-agent-outcomes-provider.d.ts +50 -0
  56. package/dist/src/workspace/configured-agent-outcomes-provider.js +26 -0
  57. package/dist/src/workspace/configured-agent-outcomes.d.ts +48 -0
  58. package/dist/src/workspace/configured-agent-outcomes.js +113 -0
  59. package/dist/src/workspace/configured-entry-resolution/types.d.ts +32 -0
  60. package/dist/src/workspace/configured-entry-resolution/types.js +2 -0
  61. package/dist/src/workspace/configured-entry-resolution/workspace-ref.d.ts +32 -0
  62. package/dist/src/workspace/configured-entry-resolution/workspace-ref.js +176 -0
  63. package/dist/src/workspace/constants.d.ts +6 -0
  64. package/dist/src/workspace/constants.js +6 -0
  65. package/dist/src/workspace/create-symlink.d.ts +26 -0
  66. package/dist/src/workspace/create-symlink.js +87 -0
  67. package/dist/src/workspace/desired-pack-lock.d.ts +18 -0
  68. package/dist/src/workspace/desired-pack-lock.js +132 -0
  69. package/dist/src/workspace/desired-state-enabled.d.ts +18 -0
  70. package/dist/src/workspace/desired-state-enabled.js +16 -0
  71. package/dist/src/workspace/desired-state-graph.d.ts +114 -0
  72. package/dist/src/workspace/desired-state-graph.js +384 -0
  73. package/dist/src/workspace/desired-state-problem-text.d.ts +6 -0
  74. package/dist/src/workspace/desired-state-problem-text.js +27 -0
  75. package/dist/src/workspace/errors.d.ts +184 -0
  76. package/dist/src/workspace/errors.js +79 -0
  77. package/dist/src/workspace/extension-name.d.ts +28 -0
  78. package/dist/src/workspace/extension-name.js +66 -0
  79. package/dist/src/workspace/extension-paths.d.ts +82 -0
  80. package/dist/src/workspace/extension-paths.js +172 -0
  81. package/dist/src/workspace/footprint-recorder.d.ts +30 -0
  82. package/dist/src/workspace/footprint-recorder.js +32 -0
  83. package/dist/src/workspace/layout.d.ts +43 -0
  84. package/dist/src/workspace/layout.js +164 -0
  85. package/dist/src/workspace/lock-entry-to-ref.d.ts +40 -0
  86. package/dist/src/workspace/lock-entry-to-ref.js +433 -0
  87. package/dist/src/workspace/lock-entry-to-source-params.d.ts +26 -0
  88. package/dist/src/workspace/lock-entry-to-source-params.js +81 -0
  89. package/dist/src/workspace/locked-entries.d.ts +30 -0
  90. package/dist/src/workspace/locked-entries.js +34 -0
  91. package/dist/src/workspace/materialized-file-target.d.ts +14 -0
  92. package/dist/src/workspace/materialized-file-target.js +14 -0
  93. package/dist/src/workspace/materialized-tree.d.ts +23 -0
  94. package/dist/src/workspace/materialized-tree.js +90 -0
  95. package/dist/src/workspace/mcp-entry-semantics.d.ts +31 -0
  96. package/dist/src/workspace/mcp-entry-semantics.js +60 -0
  97. package/dist/src/workspace/observed-installed.d.ts +9 -0
  98. package/dist/src/workspace/observed-installed.js +9 -0
  99. package/dist/src/workspace/pack-manifest-content-identity.d.ts +12 -0
  100. package/dist/src/workspace/pack-manifest-content-identity.js +20 -0
  101. package/dist/src/workspace/pack-paths.d.ts +24 -0
  102. package/dist/src/workspace/pack-paths.js +16 -0
  103. package/dist/src/workspace/package-hash.d.ts +25 -0
  104. package/dist/src/workspace/package-hash.js +45 -0
  105. package/dist/src/workspace/paths.d.ts +24 -0
  106. package/dist/src/workspace/paths.js +52 -0
  107. package/dist/src/workspace/read-model/__fixtures__/builder.d.ts +199 -0
  108. package/dist/src/workspace/read-model/__fixtures__/builder.js +588 -0
  109. package/dist/src/workspace/read-model/__fixtures__/decoders.d.ts +15 -0
  110. package/dist/src/workspace/read-model/__fixtures__/decoders.js +15 -0
  111. package/dist/src/workspace/read-model/__fixtures__/occurrences.d.ts +72 -0
  112. package/dist/src/workspace/read-model/__fixtures__/occurrences.js +134 -0
  113. package/dist/src/workspace/read-model/__fixtures__/scenario-harness.d.ts +99 -0
  114. package/dist/src/workspace/read-model/__fixtures__/scenario-harness.js +142 -0
  115. package/dist/src/workspace/read-model/__fixtures__/test-layer.d.ts +60 -0
  116. package/dist/src/workspace/read-model/__fixtures__/test-layer.js +57 -0
  117. package/dist/src/workspace/read-model/agent-presence.d.ts +32 -0
  118. package/dist/src/workspace/read-model/agent-presence.js +21 -0
  119. package/dist/src/workspace/read-model/agent-root-resolver.d.ts +38 -0
  120. package/dist/src/workspace/read-model/agent-root-resolver.js +35 -0
  121. package/dist/src/workspace/read-model/agents/index.d.ts +38 -0
  122. package/dist/src/workspace/read-model/agents/index.js +45 -0
  123. package/dist/src/workspace/read-model/agents/shared.d.ts +27 -0
  124. package/dist/src/workspace/read-model/agents/shared.js +63 -0
  125. package/dist/src/workspace/read-model/agents/types.d.ts +133 -0
  126. package/dist/src/workspace/read-model/agents/types.js +51 -0
  127. package/dist/src/workspace/read-model/diagnostics.d.ts +18 -0
  128. package/dist/src/workspace/read-model/diagnostics.js +14 -0
  129. package/dist/src/workspace/read-model/discovery/index.d.ts +5 -0
  130. package/dist/src/workspace/read-model/discovery/index.js +5 -0
  131. package/dist/src/workspace/read-model/discovery/plugin-manifests.d.ts +16 -0
  132. package/dist/src/workspace/read-model/discovery/plugin-manifests.js +168 -0
  133. package/dist/src/workspace/read-model/discovery/skills.d.ts +58 -0
  134. package/dist/src/workspace/read-model/discovery/skills.js +263 -0
  135. package/dist/src/workspace/read-model/discovery/subagents.d.ts +37 -0
  136. package/dist/src/workspace/read-model/discovery/subagents.js +48 -0
  137. package/dist/src/workspace/read-model/errors.d.ts +93 -0
  138. package/dist/src/workspace/read-model/errors.js +30 -0
  139. package/dist/src/workspace/read-model/extensions/actual-helpers.d.ts +4 -0
  140. package/dist/src/workspace/read-model/extensions/actual-helpers.js +4 -0
  141. package/dist/src/workspace/read-model/extensions/hook.d.ts +104 -0
  142. package/dist/src/workspace/read-model/extensions/hook.js +119 -0
  143. package/dist/src/workspace/read-model/extensions/index.d.ts +19 -0
  144. package/dist/src/workspace/read-model/extensions/index.js +43 -0
  145. package/dist/src/workspace/read-model/extensions/indexByName.d.ts +31 -0
  146. package/dist/src/workspace/read-model/extensions/indexByName.js +30 -0
  147. package/dist/src/workspace/read-model/extensions/inventory.d.ts +99 -0
  148. package/dist/src/workspace/read-model/extensions/inventory.js +111 -0
  149. package/dist/src/workspace/read-model/extensions/knowledge.d.ts +101 -0
  150. package/dist/src/workspace/read-model/extensions/knowledge.js +121 -0
  151. package/dist/src/workspace/read-model/extensions/mcp-server.d.ts +106 -0
  152. package/dist/src/workspace/read-model/extensions/mcp-server.js +122 -0
  153. package/dist/src/workspace/read-model/extensions/pack.d.ts +104 -0
  154. package/dist/src/workspace/read-model/extensions/pack.js +123 -0
  155. package/dist/src/workspace/read-model/extensions/package-root.d.ts +39 -0
  156. package/dist/src/workspace/read-model/extensions/package-root.js +48 -0
  157. package/dist/src/workspace/read-model/extensions/projection.d.ts +137 -0
  158. package/dist/src/workspace/read-model/extensions/projection.js +180 -0
  159. package/dist/src/workspace/read-model/extensions/rule.d.ts +104 -0
  160. package/dist/src/workspace/read-model/extensions/rule.js +113 -0
  161. package/dist/src/workspace/read-model/extensions/skill.d.ts +170 -0
  162. package/dist/src/workspace/read-model/extensions/skill.js +148 -0
  163. package/dist/src/workspace/read-model/extensions/subagent.d.ts +97 -0
  164. package/dist/src/workspace/read-model/extensions/subagent.js +120 -0
  165. package/dist/src/workspace/read-model/scanners/agent-dir.d.ts +49 -0
  166. package/dist/src/workspace/read-model/scanners/agent-dir.js +180 -0
  167. package/dist/src/workspace/read-model/scanners/agent-root.d.ts +73 -0
  168. package/dist/src/workspace/read-model/scanners/agent-root.js +148 -0
  169. package/dist/src/workspace/read-model/scanners/agent-settings.d.ts +43 -0
  170. package/dist/src/workspace/read-model/scanners/agent-settings.js +54 -0
  171. package/dist/src/workspace/read-model/scanners/canonical-extensions.d.ts +48 -0
  172. package/dist/src/workspace/read-model/scanners/canonical-extensions.js +237 -0
  173. package/dist/src/workspace/read-model/scanners/fs-helpers.d.ts +63 -0
  174. package/dist/src/workspace/read-model/scanners/fs-helpers.js +106 -0
  175. package/dist/src/workspace/read-model/scanners/index.d.ts +15 -0
  176. package/dist/src/workspace/read-model/scanners/index.js +34 -0
  177. package/dist/src/workspace/read-model/scanners/mcp-config.d.ts +47 -0
  178. package/dist/src/workspace/read-model/scanners/mcp-config.js +212 -0
  179. package/dist/src/workspace/read-model/scanners/types.d.ts +170 -0
  180. package/dist/src/workspace/read-model/scanners/types.js +86 -0
  181. package/dist/src/workspace/read-model/service.d.ts +103 -0
  182. package/dist/src/workspace/read-model/service.js +391 -0
  183. package/dist/src/workspace/read-model/state.d.ts +35 -0
  184. package/dist/src/workspace/read-model/state.js +97 -0
  185. package/dist/src/workspace/read-model/types.d.ts +75 -0
  186. package/dist/src/workspace/read-model/types.js +26 -0
  187. package/dist/src/workspace/read-model-record-readers.d.ts +34 -0
  188. package/dist/src/workspace/read-model-record-readers.js +467 -0
  189. package/dist/src/workspace/read-model-record-rows.d.ts +45 -0
  190. package/dist/src/workspace/read-model-record-rows.js +33 -0
  191. package/dist/src/workspace/read-model-record-types.d.ts +45 -0
  192. package/dist/src/workspace/read-model-record-types.js +13 -0
  193. package/dist/src/workspace/remove-if-exists.d.ts +13 -0
  194. package/dist/src/workspace/remove-if-exists.js +26 -0
  195. package/dist/src/workspace/rendered-files.d.ts +53 -0
  196. package/dist/src/workspace/rendered-files.js +50 -0
  197. package/dist/src/workspace/scope-refusal.d.ts +26 -0
  198. package/dist/src/workspace/scope-refusal.js +29 -0
  199. package/dist/src/workspace/service-interface.d.ts +479 -0
  200. package/dist/src/workspace/service-interface.js +27 -0
  201. package/dist/src/workspace/service.d.ts +1665 -0
  202. package/dist/src/workspace/service.js +1263 -0
  203. package/dist/src/workspace/setup-scope-support.d.ts +27 -0
  204. package/dist/src/workspace/setup-scope-support.js +299 -0
  205. package/dist/src/workspace/skill-paths.d.ts +33 -0
  206. package/dist/src/workspace/skill-paths.js +14 -0
  207. package/dist/src/workspace/source-metadata.d.ts +7 -0
  208. package/dist/src/workspace/source-metadata.js +10 -0
  209. package/dist/src/workspace/source-to-lock-entry.d.ts +32 -0
  210. package/dist/src/workspace/source-to-lock-entry.js +68 -0
  211. package/dist/src/workspace/test-stubs.d.ts +144 -0
  212. package/dist/src/workspace/test-stubs.js +412 -0
  213. package/dist/src/workspace/transaction.d.ts +218 -0
  214. package/dist/src/workspace/transaction.js +177 -0
  215. package/package.json +57 -0
@@ -0,0 +1,229 @@
1
+ import * as Effect from "effect/Effect";
2
+ import * as FileSystem from "effect/FileSystem";
3
+ import * as Option from "effect/Option";
4
+ import * as Path from "effect/Path";
5
+ import { decodeExtensionNameSync } from "@agentxm/extension-model/unstable/extensions/common";
6
+ import { decodeHandleSync } from "@agentxm/extension-model/unstable/extensions/handle";
7
+ import { AcceptedResolutionMissing, InlineExtensionSourceMissing, SupersededCanonicalRemovalFailed, } from "./errors.js";
8
+ import { hookLockEntryToRef, knowledgeLockEntryToRef, mcpServerLockEntryToRef, packLockEntryToRef, ruleLockEntryToRef, skillLockEntryToRef, subagentLockEntryToRef, } from "./lock-entry-to-ref.js";
9
+ import { observeCanonicalExtension, } from "./canonical-observation.js";
10
+ import { computeExtensionPathsForLayout, extensionPathSourceFromLockEntry, } from "./extension-paths.js";
11
+ import { toExtensionTypePlural } from "@agentxm/extension-model/unstable/extensions/common";
12
+ import { protectWorkspacePath } from "./transaction.js";
13
+ import { resolveWorkspaceExtensionRef } from "./configured-entry-resolution/workspace-ref.js";
14
+ /** Canonical package AXM may delete when removing desired state. Authored source is durable. */
15
+ export const removableAcceptedCanonicalPath = (canonical) => Option.flatMap(canonical, (state) => state.desired.identity.startsWith("workspace:")
16
+ ? Option.none()
17
+ : Option.fromUndefinedOr(state.observation.path));
18
+ const getAcceptedResolution = (workspace, type, name) => {
19
+ const read = () => {
20
+ switch (type) {
21
+ case "skill":
22
+ return workspace.getLockedSkill(name);
23
+ case "mcp-server":
24
+ return workspace.getLockedMcpServer(name);
25
+ case "subagent":
26
+ return workspace.getLockedSubagent(name);
27
+ case "rule":
28
+ return workspace.getLockedRuleEntry(name);
29
+ case "hook":
30
+ return workspace.getLockedHookEntry(name);
31
+ case "knowledge":
32
+ return workspace.getLockedKnowledgeEntry(name);
33
+ case "pack":
34
+ return workspace.getLockedPack(name);
35
+ }
36
+ };
37
+ return read();
38
+ };
39
+ /** Exact acquired canonical path reconstructed directly from accepted lock authority. */
40
+ export const acceptedLockedCanonicalPath = (args) => Effect.gen(function* () {
41
+ const path = yield* Path.Path;
42
+ const accepted = yield* getAcceptedResolution(args.workspace, args.type, args.name);
43
+ return Option.map(accepted, (entry) => computeExtensionPathsForLayout(path.join, args.workspace.layout, extensionPathSourceFromLockEntry(entry), toExtensionTypePlural(args.type), entry.workspaceName).canonicalPath);
44
+ });
45
+ const workspaceNameFromRef = (ref) => {
46
+ switch (ref.type) {
47
+ case "skill":
48
+ return ref.skill.name;
49
+ case "mcp-server":
50
+ return ref.server.name;
51
+ case "subagent":
52
+ return ref.subagent.name;
53
+ case "rule":
54
+ return ref.rule.name;
55
+ case "hook":
56
+ return ref.hook.name;
57
+ case "knowledge":
58
+ return ref.knowledge.name;
59
+ case "pack":
60
+ return ref.pack.name;
61
+ }
62
+ };
63
+ /**
64
+ * Capture exact cleanup for a superseded accepted package. The old path is
65
+ * read before the lock transition; the returned effect runs afterward and
66
+ * removes only that path when the replacement canonical path differs.
67
+ */
68
+ export const prepareAcceptedCanonicalTransition = (args) => Effect.gen(function* () {
69
+ const fs = yield* FileSystem.FileSystem;
70
+ const path = yield* Path.Path;
71
+ const previous = yield* acceptedLockedCanonicalPath(args);
72
+ if (Option.isNone(previous))
73
+ return yield* Effect.succeed(Effect.void);
74
+ const next = computeExtensionPathsForLayout(path.join, args.workspace.layout, args.ref, toExtensionTypePlural(args.ref.type), workspaceNameFromRef(args.ref)).canonicalPath;
75
+ if (path.resolve(previous.value) === path.resolve(next)) {
76
+ return yield* Effect.succeed(Effect.void);
77
+ }
78
+ return yield* Effect.succeed(Effect.gen(function* () {
79
+ yield* protectWorkspacePath(previous.value);
80
+ yield* fs
81
+ .remove(previous.value, { recursive: true, force: true })
82
+ .pipe(Effect.mapError((cause) => new SupersededCanonicalRemovalFailed({ path: previous.value, cause })));
83
+ }));
84
+ });
85
+ const lockRefDeps = (workspace, path) => ({
86
+ baseDir: workspace.baseDir,
87
+ path,
88
+ scope: workspace.scope,
89
+ getConfiguredSourceByName: (name) => workspace.getConfiguredSourceByName(name),
90
+ });
91
+ const missingAccepted = (label, name) => new AcceptedResolutionMissing({ label, name });
92
+ const refFromAcceptedResolution = (workspace, type, name) => Effect.gen(function* () {
93
+ const path = yield* Path.Path;
94
+ const deps = lockRefDeps(workspace, path);
95
+ switch (type) {
96
+ case "skill": {
97
+ const entry = yield* workspace.getLockedSkill(name);
98
+ return yield* Option.match(entry, {
99
+ onNone: () => Effect.fail(missingAccepted("Skill", name)),
100
+ onSome: (value) => skillLockEntryToRef(name, value, deps),
101
+ });
102
+ }
103
+ case "mcp-server": {
104
+ const entry = yield* workspace.getLockedMcpServer(name);
105
+ return yield* Option.match(entry, {
106
+ onNone: () => Effect.fail(missingAccepted("MCP", name)),
107
+ onSome: (value) => mcpServerLockEntryToRef(name, value, deps),
108
+ });
109
+ }
110
+ case "subagent": {
111
+ const entry = yield* workspace.getLockedSubagent(name);
112
+ return yield* Option.match(entry, {
113
+ onNone: () => Effect.fail(missingAccepted("Subagent", name)),
114
+ onSome: (value) => subagentLockEntryToRef(name, value, deps),
115
+ });
116
+ }
117
+ case "rule": {
118
+ const entry = yield* workspace.getLockedRuleEntry(name);
119
+ return yield* Option.match(entry, {
120
+ onNone: () => Effect.fail(missingAccepted("Rule", name)),
121
+ onSome: (value) => ruleLockEntryToRef(name, value, deps),
122
+ });
123
+ }
124
+ case "hook": {
125
+ const entry = yield* workspace.getLockedHookEntry(name);
126
+ return yield* Option.match(entry, {
127
+ onNone: () => Effect.fail(missingAccepted("Hook", name)),
128
+ onSome: (value) => hookLockEntryToRef(name, value, deps),
129
+ });
130
+ }
131
+ case "knowledge": {
132
+ const entry = yield* workspace.getLockedKnowledgeEntry(name);
133
+ return yield* Option.match(entry, {
134
+ onNone: () => Effect.fail(missingAccepted("Knowledge", name)),
135
+ onSome: (value) => knowledgeLockEntryToRef(name, value, deps),
136
+ });
137
+ }
138
+ case "pack": {
139
+ const entry = yield* workspace.getLockedPack(name);
140
+ return yield* Option.match(entry, {
141
+ onNone: () => Effect.fail(missingAccepted("Pack", name)),
142
+ onSome: (value) => packLockEntryToRef(name, value, deps),
143
+ });
144
+ }
145
+ }
146
+ });
147
+ /** Reconstruct a ref directly from accepted lock authority without desired reachability. */
148
+ export const acceptedLockedResolutionRef = (args) => Effect.gen(function* () {
149
+ const accepted = yield* getAcceptedResolution(args.workspace, args.type, args.name);
150
+ if (Option.isNone(accepted))
151
+ return Option.none();
152
+ return Option.some(yield* refFromAcceptedResolution(args.workspace, args.type, args.name));
153
+ });
154
+ const refForDesired = (workspace, desired) => Effect.gen(function* () {
155
+ if (desired.source === undefined) {
156
+ return yield* new InlineExtensionSourceMissing({ name: desired.name });
157
+ }
158
+ if (desired.identity.startsWith("bundled:")) {
159
+ const path = yield* Path.Path;
160
+ return yield* resolveWorkspaceExtensionRef({
161
+ settingsName: desired.name,
162
+ source: "workspace",
163
+ expectedType: desired.type,
164
+ layout: workspace.layout,
165
+ scope: workspace.scope,
166
+ staticPackage: {
167
+ owner: decodeHandleSync("@agentxm"),
168
+ name: decodeExtensionNameSync(desired.name),
169
+ root: workspace.layout.scope === "project"
170
+ ? path.join(workspace.layout.acquiredRoot, "agentxm", "@agentxm", "skills", desired.name)
171
+ : path.join(workspace.layout.acquiredRoot, "agentxm", "@agentxm", "skills", desired.name),
172
+ },
173
+ });
174
+ }
175
+ if (desired.identity.startsWith("workspace:")) {
176
+ return yield* resolveWorkspaceExtensionRef({
177
+ settingsName: desired.name,
178
+ source: desired.source,
179
+ expectedType: desired.type,
180
+ layout: workspace.layout,
181
+ scope: workspace.scope,
182
+ });
183
+ }
184
+ return yield* refFromAcceptedResolution(workspace, desired.type, desired.name);
185
+ });
186
+ /**
187
+ * Reconstruct the immutable source reference recorded for a desired extension,
188
+ * even when its canonical materialization is absent or divergent.
189
+ */
190
+ export const acceptedResolutionRef = (args) => Effect.gen(function* () {
191
+ const graph = yield* args.workspace.getDesiredStateGraph();
192
+ const desired = graph.nodes.find((node) => node.type === args.type && node.name === args.name);
193
+ if (desired === undefined || desired.identity.startsWith("workspace:")) {
194
+ return Option.none();
195
+ }
196
+ return yield* acceptedLockedResolutionRef(args);
197
+ });
198
+ export const acceptedCanonicalObservation = ({ workspace, type, name, }) => Effect.gen(function* () {
199
+ const graph = yield* workspace.getDesiredStateGraph();
200
+ const desired = graph.nodes.find((node) => node.type === type && node.name === name);
201
+ if (desired === undefined)
202
+ return Option.none();
203
+ const accepted = yield* getAcceptedResolution(workspace, type, name);
204
+ const observation = yield* observeCanonicalExtension({
205
+ layout: workspace.layout,
206
+ desired,
207
+ accepted: Option.getOrUndefined(accepted),
208
+ });
209
+ return Option.some({
210
+ desired,
211
+ ...(Option.isSome(accepted) ? { accepted: accepted.value } : {}),
212
+ observation,
213
+ });
214
+ });
215
+ export const usableAcceptedCanonicalObservation = (args) => acceptedCanonicalObservation(args).pipe(Effect.map(Option.flatMap((value) => value.observation.status === "usable" && value.observation.path !== undefined
216
+ ? Option.some({
217
+ ...value,
218
+ observation: { ...value.observation, status: "usable", path: value.observation.path },
219
+ })
220
+ : Option.none())));
221
+ export const usableAcceptedCanonical = (args) => Effect.gen(function* () {
222
+ const canonical = yield* usableAcceptedCanonicalObservation(args);
223
+ if (Option.isNone(canonical))
224
+ return Option.none();
225
+ const ref = yield* refForDesired(args.workspace, canonical.value.desired);
226
+ return Option.some({ ...canonical.value, ref });
227
+ });
228
+ export const usableAcceptedCanonicalRef = (args) => usableAcceptedCanonical(args).pipe(Effect.map(Option.map((canonical) => canonical.ref)));
229
+ //# sourceMappingURL=accepted-canonical-ref.js.map
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Change classification for a workspace-managed artifact.
3
+ *
4
+ * Names how one on-disk artifact fared during an operation. Owned by the
5
+ * workspace state vocabulary so plan presentation, agent projection, and
6
+ * read-model consumers share one definition.
7
+ *
8
+ * @experimental This API is unstable and may change without notice.
9
+ * @packageDocumentation
10
+ */
11
+ import * as Schema from "effect/Schema";
12
+ export declare const ArtifactChangeSchema: Schema.Literals<readonly ["created", "updated", "unchanged", "removed"]>;
13
+ export type ArtifactChange = typeof ArtifactChangeSchema.Type;
14
+ //# sourceMappingURL=artifact-change.d.ts.map
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Change classification for a workspace-managed artifact.
3
+ *
4
+ * Names how one on-disk artifact fared during an operation. Owned by the
5
+ * workspace state vocabulary so plan presentation, agent projection, and
6
+ * read-model consumers share one definition.
7
+ *
8
+ * @experimental This API is unstable and may change without notice.
9
+ * @packageDocumentation
10
+ */
11
+ import * as Schema from "effect/Schema";
12
+ export const ArtifactChangeSchema = Schema.Literals([
13
+ "created",
14
+ "updated",
15
+ "unchanged",
16
+ "removed",
17
+ ]);
18
+ //# sourceMappingURL=artifact-change.js.map
@@ -0,0 +1,39 @@
1
+ import * as Effect from "effect/Effect";
2
+ import * as FileSystem from "effect/FileSystem";
3
+ import * as Path from "effect/Path";
4
+ import { type ExtensionType } from "@agentxm/extension-model/unstable/extensions";
5
+ import type { HookLockEntry, KnowledgeLockEntry, McpServerLockEntry, PackLockEntry, RuleLockEntry, SkillLockEntry, SubagentLockEntry } from "../lockfile/index.js";
6
+ import { type DesiredConstraintContributor, type DesiredExtensionNode } from "./desired-state-graph.js";
7
+ import type { WorkspaceLayout } from "./layout.js";
8
+ export type CanonicalObservationStatus = "not-applicable" | "missing" | "missing-resolution" | "constraint-mismatch" | "wrong-origin" | "corrupt" | "incomplete" | "locally-modified" | "materialization-mismatch" | "usable";
9
+ export type CanonicalConstraintContributor = DesiredConstraintContributor;
10
+ interface CanonicalObservationBase {
11
+ readonly type: ExtensionType;
12
+ readonly name: string;
13
+ readonly path?: string;
14
+ readonly contentIdentity?: string;
15
+ }
16
+ export interface CanonicalConstraintMismatchObservation extends CanonicalObservationBase {
17
+ readonly status: "constraint-mismatch";
18
+ readonly authority: {
19
+ readonly source: "desired-state-graph";
20
+ readonly identity: string;
21
+ readonly locator: string;
22
+ readonly constraints: ReadonlyArray<CanonicalConstraintContributor>;
23
+ };
24
+ readonly acceptedVersion?: string;
25
+ readonly observedVersion?: string;
26
+ }
27
+ export type CanonicalObservation = CanonicalConstraintMismatchObservation | (CanonicalObservationBase & {
28
+ readonly status: Exclude<CanonicalObservationStatus, "constraint-mismatch">;
29
+ });
30
+ interface ObserveCanonicalArgs {
31
+ readonly layout: WorkspaceLayout;
32
+ readonly desired: DesiredExtensionNode;
33
+ readonly accepted: AcceptedExtensionResolution | undefined;
34
+ }
35
+ export type AcceptedExtensionResolution = SkillLockEntry | McpServerLockEntry | SubagentLockEntry | RuleLockEntry | HookLockEntry | KnowledgeLockEntry | PackLockEntry;
36
+ export declare const canonicalPathForAcceptedExtension: (path: Path.Path, layout: WorkspaceLayout, desired: DesiredExtensionNode, accepted: AcceptedExtensionResolution | undefined) => string | undefined;
37
+ export declare const observeCanonicalExtension: ({ layout, desired, accepted, }: ObserveCanonicalArgs) => Effect.Effect<CanonicalObservation, never, FileSystem.FileSystem | Path.Path>;
38
+ export {};
39
+ //# sourceMappingURL=canonical-observation.d.ts.map
@@ -0,0 +1,307 @@
1
+ import * as Effect from "effect/Effect";
2
+ import * as FileSystem from "effect/FileSystem";
3
+ import * as Option from "effect/Option";
4
+ import * as Path from "effect/Path";
5
+ import * as Result from "effect/Result";
6
+ import * as Schema from "effect/Schema";
7
+ import * as semver from "semver";
8
+ import { computeMaterializedTreeIntegrity } from "./materialized-tree.js";
9
+ import { toExtensionTypePlural, } from "@agentxm/extension-model/unstable/extensions";
10
+ import { HookManifestSchema } from "@agentxm/extension-model/unstable/hooks/manifest-schema";
11
+ import { KnowledgeManifestSchema } from "@agentxm/extension-model/unstable/knowledge";
12
+ import { McpServerManifestSchema } from "@agentxm/extension-model/unstable/mcps/manifest-schema";
13
+ import { PackManifestSchema } from "@agentxm/extension-model/unstable/packs/manifest-schema";
14
+ import { RuleManifestSchema } from "@agentxm/extension-model/unstable/rules/manifest-schema";
15
+ import { parseSkillMd } from "@agentxm/registry-protocol/unstable/content";
16
+ import { SkillManifestSchema } from "@agentxm/extension-model/unstable/skills/manifest-schema";
17
+ import { SubagentManifestSchema } from "@agentxm/extension-model/unstable/subagents/manifest-schema";
18
+ import { printSourceParams } from "@agentxm/extension-model/unstable/sources/printer";
19
+ import { lockEntryToSourceParams } from "./lock-entry-to-source-params.js";
20
+ import { collectDesiredConstraintContributors, } from "./desired-state-graph.js";
21
+ import { computeExtensionPathsForLayout, extensionPathSourceFromLockEntry, } from "./extension-paths.js";
22
+ const MANIFEST_CONTRACTS = {
23
+ skill: { filename: "skill.json", schema: SkillManifestSchema },
24
+ "mcp-server": { filename: "mcp.json", schema: McpServerManifestSchema },
25
+ subagent: { filename: "subagent.json", schema: SubagentManifestSchema },
26
+ rule: { filename: "rule.json", schema: RuleManifestSchema },
27
+ hook: { filename: "hook.json", schema: HookManifestSchema },
28
+ knowledge: { filename: "knowledge.json", schema: KnowledgeManifestSchema },
29
+ pack: { filename: "pack.json", schema: PackManifestSchema },
30
+ };
31
+ export const canonicalPathForAcceptedExtension = (path, layout, desired, accepted) => {
32
+ if (desired.source === undefined)
33
+ return undefined;
34
+ if (desired.identity.startsWith("bundled:")) {
35
+ return path.join(layout.acquiredRoot, "agentxm", "@agentxm", "skills", desired.name);
36
+ }
37
+ if (desired.identity.startsWith("workspace:")) {
38
+ if (layout.scope === "project")
39
+ return path.join(layout.authoredRoot(desired.type), desired.name);
40
+ return undefined;
41
+ }
42
+ if (accepted === undefined)
43
+ return undefined;
44
+ const source = extensionPathSourceFromLockEntry(accepted);
45
+ return computeExtensionPathsForLayout(path.join, layout, source, toExtensionTypePlural(desired.type), accepted.workspaceName).canonicalPath;
46
+ };
47
+ const hasRequiredPayload = (fs, path, root, type, name) => {
48
+ switch (type) {
49
+ case "skill":
50
+ return Effect.map(Effect.all([fs.exists(path.join(root, "src", "SKILL.md"))]), (exists) => exists.some(Boolean));
51
+ case "subagent":
52
+ return fs.exists(path.join(root, "src", `${name}.md`));
53
+ case "rule":
54
+ case "hook":
55
+ case "knowledge":
56
+ return fs.exists(path.join(root, "src"));
57
+ case "mcp-server":
58
+ case "pack":
59
+ return Effect.succeed(true);
60
+ }
61
+ };
62
+ const parseJson = (raw) => {
63
+ try {
64
+ return JSON.parse(raw);
65
+ }
66
+ catch {
67
+ return undefined;
68
+ }
69
+ };
70
+ const constraintMismatchObservation = (args) => ({
71
+ type: args.desired.type,
72
+ name: args.desired.name,
73
+ status: "constraint-mismatch",
74
+ ...(args.canonicalPath === undefined ? {} : { path: args.canonicalPath }),
75
+ authority: {
76
+ source: "desired-state-graph",
77
+ identity: args.desired.identity,
78
+ locator: args.desired.source,
79
+ constraints: collectDesiredConstraintContributors(args.path, args.desired.origins),
80
+ },
81
+ ...(args.acceptedVersion === undefined ? {} : { acceptedVersion: args.acceptedVersion }),
82
+ ...(args.observedVersion === undefined ? {} : { observedVersion: args.observedVersion }),
83
+ });
84
+ export const observeCanonicalExtension = ({ layout, desired, accepted, }) => Effect.gen(function* () {
85
+ const fs = yield* FileSystem.FileSystem;
86
+ const path = yield* Path.Path;
87
+ if (desired.source === undefined) {
88
+ return {
89
+ type: desired.type,
90
+ name: desired.name,
91
+ status: "not-applicable",
92
+ };
93
+ }
94
+ const workspaceAuthored = desired.identity.startsWith("workspace:");
95
+ const bundled = desired.identity.startsWith("bundled:");
96
+ if (!workspaceAuthored && !bundled && accepted === undefined) {
97
+ return {
98
+ type: desired.type,
99
+ name: desired.name,
100
+ status: "missing-resolution",
101
+ };
102
+ }
103
+ const acceptedIdentity = accepted?.type === "registry"
104
+ ? `${accepted.owner}/${toExtensionTypePlural(desired.type)}/${accepted.name}`
105
+ : accepted === undefined
106
+ ? undefined
107
+ : printSourceParams(lockEntryToSourceParams(accepted));
108
+ if (!workspaceAuthored &&
109
+ !bundled &&
110
+ acceptedIdentity !== desired.identity &&
111
+ acceptedIdentity !== desired.source) {
112
+ return {
113
+ type: desired.type,
114
+ name: desired.name,
115
+ status: "wrong-origin",
116
+ };
117
+ }
118
+ const acceptedConstraintMismatch = !workspaceAuthored &&
119
+ desired.constraints.length > 0 &&
120
+ (accepted?.type !== "registry" ||
121
+ desired.constraints.some((constraint) => !semver.satisfies(accepted.resolvedVersion, constraint)));
122
+ const acceptedVersion = accepted?.type === "registry" ? accepted.resolvedVersion : undefined;
123
+ const root = canonicalPathForAcceptedExtension(path, layout, desired, accepted);
124
+ if (root === undefined) {
125
+ if (acceptedConstraintMismatch) {
126
+ return constraintMismatchObservation({
127
+ path,
128
+ desired,
129
+ ...(acceptedVersion === undefined ? {} : { acceptedVersion }),
130
+ });
131
+ }
132
+ return {
133
+ type: desired.type,
134
+ name: desired.name,
135
+ status: "wrong-origin",
136
+ };
137
+ }
138
+ const exists = yield* fs.exists(root).pipe(Effect.orElseSucceed(() => false));
139
+ if (!exists) {
140
+ if (acceptedConstraintMismatch) {
141
+ return constraintMismatchObservation({
142
+ path,
143
+ desired,
144
+ canonicalPath: root,
145
+ ...(acceptedVersion === undefined ? {} : { acceptedVersion }),
146
+ });
147
+ }
148
+ return { type: desired.type, name: desired.name, status: "missing", path: root };
149
+ }
150
+ if (accepted?.packageFormat === "agent-skill") {
151
+ if (acceptedConstraintMismatch) {
152
+ return constraintMismatchObservation({
153
+ path,
154
+ desired,
155
+ canonicalPath: root,
156
+ ...(acceptedVersion === undefined ? {} : { acceptedVersion }),
157
+ });
158
+ }
159
+ const skillMdPath = path.join(root, "SKILL.md");
160
+ const skillMdExists = yield* fs.exists(skillMdPath).pipe(Effect.orElseSucceed(() => false));
161
+ if (!skillMdExists) {
162
+ return { type: desired.type, name: desired.name, status: "incomplete", path: root };
163
+ }
164
+ const raw = yield* fs.readFileString(skillMdPath).pipe(Effect.result);
165
+ if (Result.isFailure(raw)) {
166
+ return { type: desired.type, name: desired.name, status: "corrupt", path: root };
167
+ }
168
+ if (Option.isNone(parseSkillMd(raw.success, accepted.packageName))) {
169
+ return { type: desired.type, name: desired.name, status: "corrupt", path: root };
170
+ }
171
+ const observedIntegrity = yield* Effect.result(computeMaterializedTreeIntegrity(root));
172
+ if (Result.isFailure(observedIntegrity) ||
173
+ observedIntegrity.success !== accepted.treeIntegrity) {
174
+ return {
175
+ type: desired.type,
176
+ name: desired.name,
177
+ status: "materialization-mismatch",
178
+ path: root,
179
+ };
180
+ }
181
+ return {
182
+ type: desired.type,
183
+ name: desired.name,
184
+ status: "usable",
185
+ path: root,
186
+ };
187
+ }
188
+ const contract = MANIFEST_CONTRACTS[desired.type];
189
+ const manifestPath = path.join(root, contract.filename);
190
+ const manifestExists = yield* fs.exists(manifestPath).pipe(Effect.orElseSucceed(() => false));
191
+ let manifestVersion;
192
+ {
193
+ if (!manifestExists) {
194
+ if (acceptedConstraintMismatch) {
195
+ return constraintMismatchObservation({
196
+ path,
197
+ desired,
198
+ canonicalPath: root,
199
+ ...(acceptedVersion === undefined ? {} : { acceptedVersion }),
200
+ });
201
+ }
202
+ return { type: desired.type, name: desired.name, status: "incomplete", path: root };
203
+ }
204
+ const raw = yield* fs.readFileString(manifestPath).pipe(Effect.result);
205
+ if (Result.isFailure(raw)) {
206
+ if (acceptedConstraintMismatch) {
207
+ return constraintMismatchObservation({
208
+ path,
209
+ desired,
210
+ canonicalPath: root,
211
+ ...(acceptedVersion === undefined ? {} : { acceptedVersion }),
212
+ });
213
+ }
214
+ return { type: desired.type, name: desired.name, status: "corrupt", path: root };
215
+ }
216
+ const parsed = parseJson(raw.success);
217
+ if (parsed === undefined) {
218
+ if (acceptedConstraintMismatch) {
219
+ return constraintMismatchObservation({
220
+ path,
221
+ desired,
222
+ canonicalPath: root,
223
+ ...(acceptedVersion === undefined ? {} : { acceptedVersion }),
224
+ });
225
+ }
226
+ return { type: desired.type, name: desired.name, status: "corrupt", path: root };
227
+ }
228
+ const decoded = Schema.decodeUnknownResult(contract.schema)(parsed);
229
+ if (Result.isFailure(decoded)) {
230
+ if (acceptedConstraintMismatch) {
231
+ return constraintMismatchObservation({
232
+ path,
233
+ desired,
234
+ canonicalPath: root,
235
+ ...(acceptedVersion === undefined ? {} : { acceptedVersion }),
236
+ });
237
+ }
238
+ return { type: desired.type, name: desired.name, status: "corrupt", path: root };
239
+ }
240
+ const expectedOwner = bundled
241
+ ? "@agentxm"
242
+ : workspaceAuthored
243
+ ? layout.owner
244
+ : accepted?.type === "registry"
245
+ ? accepted.owner
246
+ : accepted?.packageOwner;
247
+ const expectedName = bundled
248
+ ? desired.name
249
+ : workspaceAuthored
250
+ ? desired.name
251
+ : accepted?.type === "registry"
252
+ ? accepted.name
253
+ : accepted?.packageName;
254
+ if (typeof parsed !== "object" ||
255
+ parsed === null ||
256
+ !("owner" in parsed) ||
257
+ parsed.owner !== expectedOwner ||
258
+ !("name" in parsed) ||
259
+ parsed.name !== expectedName ||
260
+ !("type" in parsed) ||
261
+ parsed.type !== desired.type) {
262
+ return { type: desired.type, name: desired.name, status: "wrong-origin", path: root };
263
+ }
264
+ if (typeof parsed === "object" &&
265
+ parsed !== null &&
266
+ "version" in parsed &&
267
+ typeof parsed.version === "string") {
268
+ manifestVersion = parsed.version;
269
+ }
270
+ }
271
+ if (desired.constraints.length > 0 &&
272
+ (acceptedConstraintMismatch ||
273
+ (workspaceAuthored &&
274
+ (manifestVersion === undefined ||
275
+ desired.constraints.some((constraint) => !semver.satisfies(manifestVersion, constraint)))))) {
276
+ return constraintMismatchObservation({
277
+ path,
278
+ desired,
279
+ canonicalPath: root,
280
+ ...(acceptedVersion === undefined ? {} : { acceptedVersion }),
281
+ ...(manifestVersion === undefined ? {} : { observedVersion: manifestVersion }),
282
+ });
283
+ }
284
+ const payloadComplete = yield* hasRequiredPayload(fs, path, root, desired.type, desired.name).pipe(Effect.orElseSucceed(() => false));
285
+ if (!payloadComplete) {
286
+ return { type: desired.type, name: desired.name, status: "incomplete", path: root };
287
+ }
288
+ if (!workspaceAuthored && accepted !== undefined) {
289
+ const observedIntegrity = yield* Effect.result(computeMaterializedTreeIntegrity(root));
290
+ if (Result.isFailure(observedIntegrity) ||
291
+ observedIntegrity.success !== accepted.treeIntegrity) {
292
+ return {
293
+ type: desired.type,
294
+ name: desired.name,
295
+ status: "materialization-mismatch",
296
+ path: root,
297
+ };
298
+ }
299
+ }
300
+ return {
301
+ type: desired.type,
302
+ name: desired.name,
303
+ status: "usable",
304
+ path: root,
305
+ };
306
+ });
307
+ //# sourceMappingURL=canonical-observation.js.map
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Effective per-agent lifecycle outcome for a configured extension.
3
+ *
4
+ * Workspace-state vocabulary: the plan pipeline, agent projection, and the
5
+ * read-model inventory all report against this one shape.
6
+ *
7
+ * @experimental This API is unstable and may change without notice.
8
+ * @packageDocumentation
9
+ */
10
+ import * as Schema from "effect/Schema";
11
+ export declare const ConfiguredAgentOutcomeSchema: Schema.Struct<{
12
+ readonly extensionType: Schema.Literals<readonly ("skill" | "mcp-server" | "subagent" | "rule" | "hook" | "knowledge" | "pack")[]>;
13
+ readonly name: Schema.String;
14
+ readonly agentId: Schema.String;
15
+ readonly outcome: Schema.Literals<readonly ["projected", "current", "not-applicable", "unsupported", "blocked", "failed"]>;
16
+ readonly reasonCode: Schema.String;
17
+ readonly reason: Schema.String;
18
+ readonly mechanism: Schema.optional<Schema.String>;
19
+ readonly path: Schema.optional<Schema.String>;
20
+ }>;
21
+ export type ConfiguredAgentOutcome = typeof ConfiguredAgentOutcomeSchema.Type;
22
+ //# sourceMappingURL=configured-agent-outcome.d.ts.map
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Effective per-agent lifecycle outcome for a configured extension.
3
+ *
4
+ * Workspace-state vocabulary: the plan pipeline, agent projection, and the
5
+ * read-model inventory all report against this one shape.
6
+ *
7
+ * @experimental This API is unstable and may change without notice.
8
+ * @packageDocumentation
9
+ */
10
+ import * as Schema from "effect/Schema";
11
+ import { ExtensionTypeSchema } from "@agentxm/extension-model/unstable/extensions/common";
12
+ export const ConfiguredAgentOutcomeSchema = Schema.Struct({
13
+ extensionType: ExtensionTypeSchema,
14
+ name: Schema.String,
15
+ agentId: Schema.String,
16
+ outcome: Schema.Literals([
17
+ "projected",
18
+ "current",
19
+ "not-applicable",
20
+ "unsupported",
21
+ "blocked",
22
+ "failed",
23
+ ]),
24
+ reasonCode: Schema.String,
25
+ reason: Schema.String,
26
+ mechanism: Schema.optional(Schema.String),
27
+ path: Schema.optional(Schema.String),
28
+ }).annotate({
29
+ identifier: "ConfiguredAgentOutcome",
30
+ title: "Configured Agent Outcome",
31
+ description: "Effective lifecycle result for one configured agent and extension.",
32
+ });
33
+ //# sourceMappingURL=configured-agent-outcome.js.map