@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,412 @@
1
+ /**
2
+ * Default no-op stubs for workspace getter methods on WorkspaceMutationsService.
3
+ * Spread into test mocks to satisfy the interface without implementing every method.
4
+ *
5
+ * @internal Test-only. Not exported from the barrel.
6
+ */
7
+ import * as Effect from "effect/Effect";
8
+ import * as Option from "effect/Option";
9
+ import * as Schema from "effect/Schema";
10
+ import YAML from "yaml";
11
+ import { makeRegistryPackLockEntry as buildRegistryPackLockEntry, } from "../lockfile/index.js";
12
+ import { decodeExtensionNameSync, extensionTypes, parseSourceQualifiedRegistrySourcePatternParts, decodeHandleSync, } from "@agentxm/extension-model/unstable/extensions";
13
+ import { SourceHashSchema } from "@agentxm/extension-model/unstable/sources/source-hash";
14
+ import { TreeIntegritySchema } from "./materialized-tree.js";
15
+ import {} from "@agentxm/extension-model/unstable/extensions/installable-types";
16
+ import {} from "@agentxm/extension-model/unstable/extensions/handle";
17
+ import { decodeAbsolutePathSync, decodeRelativePathSync, } from "@agentxm/extension-model/unstable/path-types";
18
+ import { decodeVersionSync, } from "@agentxm/extension-model/unstable/version-constraints";
19
+ const emptyRows = () => Effect.succeed([]);
20
+ const emptyInventory = () => Effect.succeed({
21
+ items: [],
22
+ count: 0,
23
+ configuredCount: 0,
24
+ implicitCount: 0,
25
+ installedCount: 0,
26
+ unmanagedCount: 0,
27
+ });
28
+ const fs = (() => {
29
+ const module = process.getBuiltinModule("node:fs");
30
+ if (!module) {
31
+ throw new Error("node:fs builtin is unavailable");
32
+ }
33
+ return module;
34
+ })();
35
+ const path = (() => {
36
+ const module = process.getBuiltinModule("node:path");
37
+ if (!module) {
38
+ throw new Error("node:path builtin is unavailable");
39
+ }
40
+ return module;
41
+ })();
42
+ /**
43
+ * Build a `configured` read-model row. Tests that previously stubbed
44
+ * `getConfiguredSkills` with a `{ name: { source, enabled } }` map supply the
45
+ * same facts here and feed the result to {@link rowsFor}.
46
+ */
47
+ export const configuredRow = (args) => ({
48
+ type: args.type,
49
+ name: args.name,
50
+ source: args.source,
51
+ enabled: args.enabled ?? true,
52
+ packagingKind: args.packagingKind ?? "native",
53
+ lifecycle: "configured",
54
+ });
55
+ /** Build an `implicit` read-model row (pack member or lockfile-only entry). */
56
+ export const implicitRow = (args) => ({
57
+ type: args.type,
58
+ name: args.name,
59
+ source: Option.fromUndefinedOr(args.source),
60
+ enabled: true,
61
+ packagingKind: args.packagingKind ?? "native",
62
+ lifecycle: "implicit",
63
+ });
64
+ /** Build an `unmanaged` read-model row (observed on disk, unclaimed). */
65
+ export const unmanagedRow = (args) => ({
66
+ type: args.type,
67
+ name: args.name,
68
+ source: Option.none(),
69
+ enabled: true,
70
+ packagingKind: args.packagingKind ?? "non-native",
71
+ locations: args.locations ?? [],
72
+ agents: [],
73
+ ownershipEvidence: [],
74
+ lifecycle: "unmanaged",
75
+ });
76
+ /**
77
+ * Build a `records.rows` stub from per-type row lists. Types absent from the
78
+ * map yield an empty array, matching the real reader's totality.
79
+ */
80
+ export const rowsFor = (byType) => (type) => Effect.succeed(byType[type] ?? []);
81
+ /**
82
+ * No-op stubs for all read-model record getters. Spread into mock objects:
83
+ * ```ts
84
+ * const ws: WorkspaceMutationsService = {
85
+ * records: readModelRecordStubs,
86
+ * // your overrides
87
+ * };
88
+ * ```
89
+ */
90
+ export const readModelRecordStubs = {
91
+ getInventory: () => Effect.succeed({
92
+ items: [],
93
+ count: 0,
94
+ configuredCount: 0,
95
+ implicitCount: 0,
96
+ installedCount: 0,
97
+ unmanagedCount: 0,
98
+ }),
99
+ getExtensionInventory: emptyInventory,
100
+ rows: emptyRows,
101
+ };
102
+ /**
103
+ * Base workspace mock with no-op defaults for all methods.
104
+ * Tests should only override the methods they exercise.
105
+ *
106
+ * @example
107
+ * ```ts
108
+ * const ws = makeBaseWorkspaceMock("/tmp/axm", {
109
+ * setSkill: vi.fn(() => Effect.void),
110
+ * });
111
+ * ```
112
+ */
113
+ export const makeBaseWorkspaceMock = (axmDir = "/tmp/axm", overrides) => {
114
+ const baseDir = axmDir.replace(/\/\.axm$/, "") || "/tmp";
115
+ const { rows, records: recordOverrides, ...serviceOverrides } = overrides ?? {};
116
+ const records = {
117
+ ...readModelRecordStubs,
118
+ ...(rows === undefined ? {} : { rows }),
119
+ ...(recordOverrides ?? {}),
120
+ };
121
+ const emptyLocked = () => Effect.succeed({});
122
+ const configuredForType = (type) => {
123
+ const normalize = (effect) => effect.pipe(Effect.map((entries) => entries));
124
+ switch (type) {
125
+ case "skill":
126
+ return normalize((serviceOverrides.getConfiguredSkillEntries ?? emptyLocked)());
127
+ case "mcp-server":
128
+ return normalize((serviceOverrides.getConfiguredMcpServerEntries ?? emptyLocked)());
129
+ case "subagent":
130
+ return normalize((serviceOverrides.getConfiguredSubagentEntries ?? emptyLocked)());
131
+ case "pack":
132
+ return normalize((serviceOverrides.getConfiguredPackEntries ?? emptyLocked)());
133
+ case "rule":
134
+ return normalize((serviceOverrides.getConfiguredRuleEntries ?? emptyLocked)());
135
+ case "hook":
136
+ return normalize((serviceOverrides.getConfiguredHookEntries ?? emptyLocked)());
137
+ case "knowledge":
138
+ return normalize((serviceOverrides.getConfiguredKnowledgeEntries ?? emptyLocked)());
139
+ }
140
+ };
141
+ const sourceOf = (row) => row.lifecycle === "configured" ? row.source : Option.getOrUndefined(row.source);
142
+ const desiredEntriesForType = (type) => Effect.all({
143
+ rows: records.rows(type),
144
+ configured: configuredForType(type),
145
+ }).pipe(Effect.map(({ rows, configured }) => {
146
+ const entries = new Map();
147
+ for (const row of rows) {
148
+ const source = sourceOf(row);
149
+ if (source === undefined || row.lifecycle === "unmanaged")
150
+ continue;
151
+ entries.set(row.name, { name: row.name, source, enabled: row.enabled });
152
+ }
153
+ for (const [name, value] of Object.entries(configured)) {
154
+ if (entries.has(name) ||
155
+ typeof value !== "object" ||
156
+ value === null ||
157
+ !("source" in value) ||
158
+ typeof value.source !== "string") {
159
+ continue;
160
+ }
161
+ entries.set(name, {
162
+ name,
163
+ source: value.source,
164
+ enabled: !("enabled" in value) || typeof value.enabled !== "boolean" || value.enabled,
165
+ });
166
+ }
167
+ return [...entries.values()];
168
+ }));
169
+ const getSynthesizedDesiredStateGraph = () => Effect.gen(function* () {
170
+ const rowsByType = yield* Effect.forEach(extensionTypes, (type) => desiredEntriesForType(type).pipe(Effect.map((entries) => ({ type, entries }))));
171
+ const nodes = rowsByType.flatMap(({ type, entries }) => entries.map((entry) => {
172
+ const source = entry.source;
173
+ const parsed = parseSourceQualifiedRegistrySourcePatternParts(source);
174
+ const identity = parsed === undefined ? source : `${parsed.owner}/${parsed.type}/${parsed.name}`;
175
+ return {
176
+ type,
177
+ name: entry.name,
178
+ identity,
179
+ source,
180
+ enabled: entry.enabled,
181
+ constraints: parsed?.versionRange === undefined ? [] : [parsed.versionRange],
182
+ origins: [
183
+ {
184
+ type: "settings",
185
+ source,
186
+ enabled: entry.enabled,
187
+ },
188
+ ],
189
+ };
190
+ }));
191
+ return { complete: true, nodes, problems: [] };
192
+ });
193
+ const runTransaction = (args) => Effect.gen(function* () {
194
+ const value = yield* args.transition;
195
+ yield* args.validate(value);
196
+ return value;
197
+ });
198
+ // The mock acquires nothing: unit tests share literal workspace paths, and
199
+ // a real lock would contend across parallel test files. Tests exercising
200
+ // real transition semantics override this with the real acquirer.
201
+ const acquireTransition = () => Effect.succeed(Option.none());
202
+ const entryFrom = (read) => (name) => read().pipe(Effect.map((entries) => Option.fromUndefinedOr(entries[name])));
203
+ const lockedSkills = serviceOverrides.getLockedSkills ?? (() => Effect.succeed({}));
204
+ const lockedMcpServers = serviceOverrides.getLockedMcpServers ?? (() => Effect.succeed({}));
205
+ const lockedSubagents = serviceOverrides.getLockedSubagents ?? (() => Effect.succeed({}));
206
+ const lockedRules = serviceOverrides.getLockedRules ?? (() => Effect.succeed({}));
207
+ const lockedHooks = serviceOverrides.getLockedHooks ?? (() => Effect.succeed({}));
208
+ const lockedKnowledge = serviceOverrides.getLockedKnowledge ?? (() => Effect.succeed({}));
209
+ const lockedPacks = serviceOverrides.getLockedPacks ?? (() => Effect.succeed({}));
210
+ const base = {
211
+ scope: "project",
212
+ path: axmDir,
213
+ baseDir,
214
+ layout: {
215
+ scope: "project",
216
+ workspaceRoot: decodeAbsolutePathSync(path.resolve(baseDir)),
217
+ projectRoot: decodeAbsolutePathSync(path.resolve(baseDir)),
218
+ settingsPath: decodeAbsolutePathSync(path.resolve(baseDir, "axm.json")),
219
+ lockPath: decodeAbsolutePathSync(path.resolve(baseDir, "axm-lock.yaml")),
220
+ runtimeDir: decodeAbsolutePathSync(path.resolve(baseDir, ".axm")),
221
+ acquiredRoot: decodeAbsolutePathSync(path.resolve(baseDir, "agent_extensions")),
222
+ authoredRoot: (type) => decodeAbsolutePathSync(path.resolve(baseDir, type === "mcp-server" ? "mcps" : `${type}s`)),
223
+ },
224
+ records,
225
+ runTransaction,
226
+ acquireTransition,
227
+ getLockfileState: () => Effect.succeed("ok"),
228
+ getDesiredStateGraph: getSynthesizedDesiredStateGraph,
229
+ getConfiguredSources: () => Effect.succeed([]),
230
+ getConfiguredSourceByName: () => Effect.succeed(Option.none()),
231
+ getRegistrySourceHosts: () => Effect.succeed([]),
232
+ getConfiguredOwner: () => Effect.succeed(Option.none()),
233
+ getPublishDefaultVisibility: () => Effect.succeed(Option.none()),
234
+ getMinimumReleaseAge: () => Effect.succeed("24h"),
235
+ getMinimumReleaseAgeExclude: () => Effect.succeed([]),
236
+ addConfiguredSource: () => Effect.void,
237
+ getConfiguredSkillEntries: () => Effect.succeed({}),
238
+ getConfiguredRuleEntries: () => Effect.succeed({}),
239
+ getConfiguredHookEntries: () => Effect.succeed({}),
240
+ getLockedRules: lockedRules,
241
+ getLockedRuleEntry: entryFrom(lockedRules),
242
+ setRule: () => Effect.void,
243
+ setRuleLock: () => Effect.void,
244
+ removeRule: () => Effect.void,
245
+ removeRuleSettings: () => Effect.void,
246
+ removeRuleLock: () => Effect.void,
247
+ updateRuleEntry: () => Effect.void,
248
+ setRuleEntry: () => Effect.void,
249
+ getLockedHooks: lockedHooks,
250
+ getLockedHookEntry: entryFrom(lockedHooks),
251
+ setHook: () => Effect.void,
252
+ setHookLock: () => Effect.void,
253
+ removeHook: () => Effect.void,
254
+ removeHookSettings: () => Effect.void,
255
+ removeHookLock: () => Effect.void,
256
+ updateHookEntry: () => Effect.void,
257
+ setHookEntry: () => Effect.void,
258
+ getConfiguredKnowledgeEntries: () => Effect.succeed({}),
259
+ getKnowledgeDiscoveryConfig: () => Effect.succeed({ instructions: true }),
260
+ getLockedKnowledge: lockedKnowledge,
261
+ getLockedKnowledgeEntry: entryFrom(lockedKnowledge),
262
+ setKnowledge: () => Effect.void,
263
+ setKnowledgeLock: () => Effect.void,
264
+ removeKnowledge: () => Effect.void,
265
+ removeKnowledgeSettings: () => Effect.void,
266
+ removeKnowledgeLock: () => Effect.void,
267
+ updateKnowledgeEntry: () => Effect.void,
268
+ setKnowledgeEntry: () => Effect.void,
269
+ getConfiguredPackEntries: () => Effect.succeed({}),
270
+ getConfiguredAgents: () => Effect.succeed(["claude-code"]),
271
+ getInstructionsConfig: () => Effect.succeed(Option.none()),
272
+ setInstructionsConfig: () => Effect.void,
273
+ getConfiguredMcpServerEntries: () => Effect.succeed({}),
274
+ getLockedSkills: lockedSkills,
275
+ getLockedSkill: entryFrom(lockedSkills),
276
+ getSkillDir: () => Effect.succeed({
277
+ canonicalPath: `${axmDir}/extensions/agentxm/@test/skills/test`,
278
+ skillSrcPath: `${axmDir}/extensions/agentxm/@test/skills/test/src`,
279
+ }),
280
+ setSkill: () => Effect.void,
281
+ setSkillLock: () => Effect.void,
282
+ removeSkill: () => Effect.void,
283
+ removeSkillFromSettings: () => Effect.void,
284
+ updateSkillEntry: () => Effect.void,
285
+ setSkillEntry: () => Effect.void,
286
+ addConfiguredAgent: () => Effect.void,
287
+ removeConfiguredAgent: () => Effect.void,
288
+ getLockedPacks: lockedPacks,
289
+ getLockedPack: entryFrom(lockedPacks),
290
+ setPack: () => Effect.void,
291
+ setPackLock: () => Effect.void,
292
+ setPackEntry: () => Effect.void,
293
+ removePack: () => Effect.void,
294
+ getPackDir: () => Effect.succeed({ canonicalPath: `${axmDir}/extensions/agentxm/@test/packs/test` }),
295
+ getLockedSubagents: lockedSubagents,
296
+ getLockedSubagent: entryFrom(lockedSubagents),
297
+ getConfiguredSubagentEntries: () => Effect.succeed({}),
298
+ setSubagent: () => Effect.void,
299
+ setSubagentLock: () => Effect.void,
300
+ removeSubagent: () => Effect.void,
301
+ updateSubagentEntry: () => Effect.void,
302
+ setSubagentEntry: () => Effect.void,
303
+ removeSubagentSettings: () => Effect.void,
304
+ removeSubagentLock: () => Effect.void,
305
+ getLockedMcpServers: lockedMcpServers,
306
+ getLockedMcpServer: entryFrom(lockedMcpServers),
307
+ setMcpServer: () => Effect.void,
308
+ setMcpServerLock: () => Effect.void,
309
+ updateMcpServerEntry: () => Effect.void,
310
+ setMcpServerEntry: () => Effect.void,
311
+ removeMcpServer: () => Effect.void,
312
+ removeSkillLock: () => Effect.void,
313
+ removeMcpServerSettings: () => Effect.void,
314
+ removeMcpServerLock: () => Effect.void,
315
+ removePackSettings: () => Effect.void,
316
+ removePackLock: () => Effect.void,
317
+ isExtensionRequiredByInstalledPack: () => Effect.succeed(false),
318
+ };
319
+ return {
320
+ ...base,
321
+ ...serviceOverrides,
322
+ layout: serviceOverrides.layout ?? base.layout,
323
+ };
324
+ };
325
+ export const TEST_CONTENT_IDENTITY = Schema.decodeUnknownSync(SourceHashSchema)("test-content");
326
+ export const TEST_TREE_INTEGRITY = Schema.decodeUnknownSync(TreeIntegritySchema)(`sha256-tree-v1:${"0".repeat(64)}`);
327
+ const hasEntries = (value) => value !== undefined && Object.keys(value).length > 0;
328
+ export const writeWorkspaceFiles = (runtimeDir, opts = {}) => {
329
+ const settings = {
330
+ agents: [...(opts.agents ?? ["claude-code"])],
331
+ ...(opts.owner && { owner: opts.owner }),
332
+ ...(hasEntries(opts.skills) && { skills: opts.skills }),
333
+ ...(hasEntries(opts["mcps"]) && { mcps: opts["mcps"] }),
334
+ ...(hasEntries(opts.subagents) && { subagents: opts.subagents }),
335
+ ...(hasEntries(opts.rules) && { rules: opts.rules }),
336
+ ...(hasEntries(opts.packs) && { packs: opts.packs }),
337
+ ...(opts.sources && { sources: opts.sources }),
338
+ };
339
+ const lockfile = {
340
+ lockfileVersion: 6,
341
+ skills: opts.lockfileSkills ?? {},
342
+ ...(hasEntries(opts.lockfileMcpServers) && { mcps: opts.lockfileMcpServers }),
343
+ ...(hasEntries(opts.lockfileSubagents) && { subagents: opts.lockfileSubagents }),
344
+ ...(hasEntries(opts.lockfileRules) && { rules: opts.lockfileRules }),
345
+ ...(hasEntries(opts.lockfilePacks) && { packs: opts.lockfilePacks }),
346
+ };
347
+ const workspaceRoot = path.dirname(runtimeDir);
348
+ fs.mkdirSync(runtimeDir, { recursive: true });
349
+ fs.writeFileSync(path.join(workspaceRoot, "axm.json"), JSON.stringify(settings));
350
+ fs.writeFileSync(path.join(workspaceRoot, "axm-lock.yaml"), YAML.stringify(lockfile));
351
+ };
352
+ export const makeLocalSkillLockEntry = (opts) => ({
353
+ type: "local",
354
+ sourceType: "local",
355
+ sourceName: "local",
356
+ packageFormat: "agentxm",
357
+ extensionType: "skill",
358
+ workspaceName: decodeExtensionNameSync("installed"),
359
+ packageOwner: decodeHandleSync("@test"),
360
+ packageName: decodeExtensionNameSync("installed"),
361
+ path: decodeRelativePathSync(opts?.path ?? "installed"),
362
+ contentIdentity: TEST_CONTENT_IDENTITY,
363
+ treeIntegrity: TEST_TREE_INTEGRITY,
364
+ });
365
+ export const makeRegistrySkillLockEntry = (opts) => ({
366
+ type: "registry",
367
+ sourceType: "registry",
368
+ packageFormat: "agentxm",
369
+ endpoint: opts.endpoint ?? new URL("https://registry.agentxm.ai"),
370
+ extensionType: "skill",
371
+ workspaceName: decodeExtensionNameSync(opts.name),
372
+ owner: opts.owner,
373
+ name: decodeExtensionNameSync(opts.name),
374
+ resolvedVersion: opts.resolvedVersion ?? decodeVersionSync("1.0.0"),
375
+ integrity: opts.integrity ?? "sha512-AAAA==",
376
+ sourceName: opts.sourceName ?? "agentxm",
377
+ publisherBindingId: opts.publisherBindingId ?? "hbnd_test",
378
+ treeIntegrity: TEST_TREE_INTEGRITY,
379
+ });
380
+ export const makeRegistryMcpServerLockEntry = (opts) => ({
381
+ type: "registry",
382
+ sourceType: "registry",
383
+ packageFormat: "agentxm",
384
+ endpoint: opts.endpoint ?? new URL("https://registry.agentxm.ai"),
385
+ extensionType: "mcp-server",
386
+ workspaceName: decodeExtensionNameSync(opts.name),
387
+ owner: opts.owner,
388
+ name: decodeExtensionNameSync(opts.name),
389
+ resolvedVersion: opts.resolvedVersion ?? decodeVersionSync("1.0.0"),
390
+ integrity: opts.integrity ?? "sha512-AAAA==",
391
+ sourceName: opts.sourceName ?? "agentxm",
392
+ publisherBindingId: opts.publisherBindingId ?? "hbnd_test",
393
+ treeIntegrity: TEST_TREE_INTEGRITY,
394
+ });
395
+ export const makeRegistryPackLockEntry = (opts) => buildRegistryPackLockEntry({
396
+ sourceType: "registry",
397
+ packageFormat: "agentxm",
398
+ endpoint: opts.endpoint ?? new URL("https://registry.agentxm.ai"),
399
+ extensionType: "pack",
400
+ workspaceName: decodeExtensionNameSync(opts.name),
401
+ owner: opts.owner,
402
+ name: decodeExtensionNameSync(opts.name),
403
+ resolvedVersion: opts.resolvedVersion ?? decodeVersionSync("1.0.0"),
404
+ integrity: opts.integrity ?? "sha512-AAAA==",
405
+ sourceName: opts.sourceName ?? "agentxm",
406
+ publisherBindingId: opts.publisherBindingId ?? "hbnd_test",
407
+ manifestContentIdentity: opts.sourceHash === undefined
408
+ ? TEST_CONTENT_IDENTITY
409
+ : Schema.decodeUnknownSync(SourceHashSchema)(opts.sourceHash),
410
+ treeIntegrity: TEST_TREE_INTEGRITY,
411
+ });
412
+ //# sourceMappingURL=test-stubs.js.map
@@ -0,0 +1,218 @@
1
+ /**
2
+ * Workspace transaction state: the ambient authority context, the write
3
+ * registration primitives every workspace writer calls, and the typed
4
+ * failure vocabulary of the transaction and transition-lock machinery.
5
+ *
6
+ * This module owns the ambient transaction/closure references and the
7
+ * protection primitives (`protectWorkspacePath`, `protectCreatedAncestors`)
8
+ * that snapshot a path before its first mutation. The transaction runner and
9
+ * closure settlement mechanics that consume this context live in
10
+ * `./operations/transaction.ts`; the application error boundary owns the
11
+ * rendering, codes, and suggestions for every failure declared here.
12
+ *
13
+ * @experimental This API is unstable and may change without notice.
14
+ */
15
+ import type * as Cause from "effect/Cause";
16
+ import * as ServiceMap from "effect/Context";
17
+ import * as Effect from "effect/Effect";
18
+ import * as FileSystem from "effect/FileSystem";
19
+ import * as Option from "effect/Option";
20
+ import * as Path from "effect/Path";
21
+ import * as Semaphore from "effect/Semaphore";
22
+ /** One pre-mutation preimage of a protected path, keyed to its owning closure. */
23
+ export type Snapshot = {
24
+ readonly closure: string | undefined;
25
+ } & ({
26
+ readonly target: string;
27
+ readonly state: "absent";
28
+ } | {
29
+ readonly target: string;
30
+ readonly state: "copied";
31
+ readonly backup: string;
32
+ } | {
33
+ readonly target: string;
34
+ readonly state: "symlink";
35
+ readonly linkTarget: string;
36
+ });
37
+ /** A closure rollback that could not complete, recorded for the transaction end. */
38
+ export interface PendingClosureRestorationFailure {
39
+ readonly closureId: string;
40
+ readonly restorationCause: unknown;
41
+ readonly retained: ReadonlyArray<string>;
42
+ }
43
+ export interface WorkspaceTransactionContext {
44
+ readonly fs: FileSystem.FileSystem;
45
+ readonly path: Path.Path;
46
+ readonly workspaceDir: string;
47
+ /** Uniquely prefixed OS-temporary directory holding rollback snapshots. */
48
+ readonly snapshotStore: {
49
+ dir: string | undefined;
50
+ };
51
+ /** Per-closure first-touch dedupe; the key "" is the operation closure. */
52
+ readonly protectedTargets: Map<string, Set<string>>;
53
+ readonly snapshots: Array<Snapshot>;
54
+ readonly snapshotSemaphore: Semaphore.Semaphore;
55
+ /** Closure rollbacks that failed; the transaction fails typed at its end. */
56
+ readonly pendingRestorationFailures: Array<PendingClosureRestorationFailure>;
57
+ /** Monotonic backup-name counter: settlement drops entries, names never recur. */
58
+ readonly snapshotSequence: {
59
+ value: number;
60
+ };
61
+ }
62
+ export declare const CurrentWorkspaceTransaction: ServiceMap.Reference<Option.Option<WorkspaceTransactionContext>>;
63
+ /**
64
+ * The semantic closure whose mutations are currently executing. Snapshots
65
+ * taken while a closure is active belong to it: they are dropped when the
66
+ * closure settles and restored when it — and only it — rolls back. Snapshots
67
+ * taken outside any closure belong to the operation closure and are restored
68
+ * by the transaction's own failure handling.
69
+ */
70
+ export declare const CurrentWorkspaceClosure: ServiceMap.Reference<string | undefined>;
71
+ declare const WorkspaceRestorationIncomplete_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
72
+ readonly _tag: "WorkspaceRestorationIncomplete";
73
+ } & Readonly<A>;
74
+ /**
75
+ * Restoration did not complete: the typed fact the terminal resolution
76
+ * derives outcome, disposition, and exit status from. The pre-change
77
+ * snapshots survive in the OS-temporary snapshot directory; nothing about
78
+ * this failure persists in the workspace, and the next mutation converges
79
+ * from the current workspace state.
80
+ */
81
+ export declare class WorkspaceRestorationIncomplete extends WorkspaceRestorationIncomplete_base<{
82
+ readonly terminationCause: "failure" | "interruption";
83
+ readonly transitionCause: Cause.Cause<unknown>;
84
+ readonly restorationCause: unknown;
85
+ /** OS-temporary directory preserving the pre-change snapshots, when any were taken. */
86
+ readonly snapshotDir: string | undefined;
87
+ /** Protected paths, workspace-root-relative where possible, left as the failure left them. */
88
+ readonly retained: ReadonlyArray<string>;
89
+ /** Closures whose rollback did not complete, when closure-scoped. */
90
+ readonly closureIds?: ReadonlyArray<string>;
91
+ }> {
92
+ }
93
+ /** Identity an invocation records while it holds the workspace transition. */
94
+ export interface TransitionLockHolder {
95
+ readonly command: string;
96
+ readonly pid: number;
97
+ readonly candidateId?: string;
98
+ }
99
+ export interface TransitionContention {
100
+ /** The holder recorded by the invocation that owns the lock, when readable. */
101
+ readonly holder: Option.Option<TransitionLockHolder>;
102
+ readonly waitedMillis: number;
103
+ }
104
+ declare const WorkspaceSnapshotError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
105
+ readonly _tag: "WorkspaceSnapshotError";
106
+ } & Readonly<A>;
107
+ /**
108
+ * Registering a path with the active transaction failed: the pre-mutation
109
+ * preimage could not be taken, so the path was never mutated. `target` is the
110
+ * path being protected; the `create-store` step's message interpolates
111
+ * nothing.
112
+ */
113
+ export declare class WorkspaceSnapshotError extends WorkspaceSnapshotError_base<{
114
+ readonly target: string;
115
+ readonly step: "inspect-target" | "create-store" | "copy" | "inspect-ancestor";
116
+ readonly cause: unknown;
117
+ }> {
118
+ }
119
+ declare const WorkspaceDirectoryError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
120
+ readonly _tag: "WorkspaceDirectoryError";
121
+ } & Readonly<A>;
122
+ /** Preparing the workspace state directory for a transition failed. */
123
+ export declare class WorkspaceDirectoryError extends WorkspaceDirectoryError_base<{
124
+ readonly path: string;
125
+ readonly step: "inspect" | "create";
126
+ readonly cause: unknown;
127
+ }> {
128
+ }
129
+ declare const TransitionLockError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
130
+ readonly _tag: "TransitionLockError";
131
+ } & Readonly<A>;
132
+ /**
133
+ * Workspace transition-lock mechanics failed. `path` carries the fact each
134
+ * step's message interpolates: the scratch directory for `create-scratch`,
135
+ * the lock path otherwise. `missing-timestamp` has no underlying cause.
136
+ */
137
+ export declare class TransitionLockError extends TransitionLockError_base<{
138
+ readonly path: string;
139
+ readonly step: "create-scratch" | "acquire" | "record-holder" | "inspect-timestamp" | "missing-timestamp" | "preserve-timestamp" | "release";
140
+ readonly cause?: unknown;
141
+ }> {
142
+ }
143
+ declare const TransitionLockUnavailable_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
144
+ readonly _tag: "TransitionLockUnavailable";
145
+ } & Readonly<A>;
146
+ /**
147
+ * The bounded contention wait elapsed while another invocation held the
148
+ * workspace transition.
149
+ */
150
+ export declare class TransitionLockUnavailable extends TransitionLockUnavailable_base<{
151
+ readonly holder: TransitionLockHolder | undefined;
152
+ readonly waitedMillis: number;
153
+ }> {
154
+ }
155
+ declare const WorkspaceTransitionCompromised_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
156
+ readonly _tag: "WorkspaceTransitionCompromised";
157
+ } & Readonly<A>;
158
+ /**
159
+ * The hold is no longer provably owned: ownership could not be confirmed
160
+ * within the staleness window, so a contender may already have reclaimed the
161
+ * lock. Any further durable write by the original owner — mutation and
162
+ * restoration alike — could overwrite a successor's work.
163
+ */
164
+ export declare class WorkspaceTransitionCompromised extends WorkspaceTransitionCompromised_base<{
165
+ readonly workspaceDir: string;
166
+ readonly lockPath: string;
167
+ readonly cause: unknown;
168
+ }> {
169
+ }
170
+ declare const WorkspaceRestorationError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
171
+ readonly _tag: "WorkspaceRestorationError";
172
+ } & Readonly<A>;
173
+ /**
174
+ * One restoration step did not complete or verify. Never a channel failure:
175
+ * it travels as the `restorationCause` inside
176
+ * {@link WorkspaceRestorationIncomplete} and the pending closure records.
177
+ */
178
+ export declare class WorkspaceRestorationError extends WorkspaceRestorationError_base<{
179
+ readonly target: string;
180
+ readonly step: "stage" | "stopped" | "verify";
181
+ readonly cause: unknown;
182
+ }> {
183
+ }
184
+ /** Failures acquiring the workspace transition lock. */
185
+ export type WorkspaceTransitionAcquireFailure = WorkspaceDirectoryError | TransitionLockError;
186
+ /** Failures the transaction machinery itself produces, beside the transition's own. */
187
+ export type WorkspaceTransactionFailure = WorkspaceSnapshotError | WorkspaceDirectoryError | TransitionLockError | TransitionLockUnavailable | WorkspaceTransitionCompromised;
188
+ /**
189
+ * Snapshot one target into the active transaction context, deduplicating on
190
+ * first touch per closure. Shared by the registration primitives below and by
191
+ * the transaction runner claiming its declared targets.
192
+ */
193
+ export declare const protectInContext: (context: WorkspaceTransactionContext, target: string, closure: string | undefined) => Effect.Effect<void, WorkspaceSnapshotError>;
194
+ /** Snapshot a path before its first mutation when a workspace transaction is active. */
195
+ export declare const protectWorkspacePath: (target: string) => Effect.Effect<void, WorkspaceSnapshotError>;
196
+ /**
197
+ * Closure rollbacks that could not complete and verify, with the snapshot
198
+ * store that still preserves their pre-change bytes. Read at the end of a
199
+ * plan apply so the terminal resolution derives retained state from the
200
+ * in-memory facts alone. `None` outside a transaction.
201
+ */
202
+ export declare const readPendingClosureRestorationFailures: Effect.Effect<Option.Option<{
203
+ readonly failures: ReadonlyArray<{
204
+ readonly closureId: string;
205
+ readonly restorationCause: unknown;
206
+ readonly retained: ReadonlyArray<string>;
207
+ }>;
208
+ readonly snapshotDir: string | undefined;
209
+ }>>;
210
+ /**
211
+ * Protect the first ancestor a recursive directory creation is about to
212
+ * create, so restoration removes the created directory chain instead of
213
+ * leaving empty parents behind. No-op outside a transaction or when the
214
+ * directory already exists.
215
+ */
216
+ export declare const protectCreatedAncestors: (fs: FileSystem.FileSystem, path: Path.Path, directory: string) => Effect.Effect<void, WorkspaceSnapshotError>;
217
+ export {};
218
+ //# sourceMappingURL=transaction.d.ts.map