create-next-hydra 0.3.0 → 0.4.1

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 (207) hide show
  1. package/README.md +126 -27
  2. package/dist/add-command.d.ts +11 -0
  3. package/dist/add-command.d.ts.map +1 -0
  4. package/dist/add-command.js +75 -0
  5. package/dist/addition.d.ts +67 -0
  6. package/dist/addition.d.ts.map +1 -0
  7. package/dist/addition.js +422 -0
  8. package/dist/application-git.d.ts +20 -0
  9. package/dist/application-git.d.ts.map +1 -0
  10. package/dist/application-git.js +57 -0
  11. package/dist/baseline.d.ts +22 -0
  12. package/dist/baseline.d.ts.map +1 -0
  13. package/dist/baseline.js +90 -0
  14. package/dist/cli.js +5 -18
  15. package/dist/commands.d.ts +22 -0
  16. package/dist/commands.d.ts.map +1 -0
  17. package/dist/commands.js +197 -0
  18. package/dist/composition-lint.d.ts +20 -0
  19. package/dist/composition-lint.d.ts.map +1 -0
  20. package/dist/composition-lint.js +288 -0
  21. package/dist/composition.d.ts +24 -0
  22. package/dist/composition.d.ts.map +1 -0
  23. package/dist/composition.js +420 -0
  24. package/dist/create-command.d.ts +21 -0
  25. package/dist/create-command.d.ts.map +1 -0
  26. package/dist/create-command.js +128 -0
  27. package/dist/demo-instrumentation.d.ts +5 -0
  28. package/dist/demo-instrumentation.d.ts.map +1 -0
  29. package/dist/demo-instrumentation.js +300 -0
  30. package/dist/environment.d.ts +7 -0
  31. package/dist/environment.d.ts.map +1 -0
  32. package/dist/environment.js +81 -0
  33. package/dist/errors.d.ts +156 -0
  34. package/dist/errors.d.ts.map +1 -0
  35. package/dist/errors.js +140 -0
  36. package/dist/file-policy.d.ts +6 -0
  37. package/dist/file-policy.d.ts.map +1 -0
  38. package/dist/file-policy.js +38 -0
  39. package/dist/files.d.ts +7 -0
  40. package/dist/files.d.ts.map +1 -0
  41. package/dist/files.js +66 -0
  42. package/dist/hosting.d.ts +5 -0
  43. package/dist/hosting.d.ts.map +1 -0
  44. package/dist/hosting.js +107 -0
  45. package/dist/index.d.ts +4 -6
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +17 -89
  48. package/dist/initialization.d.ts +14 -0
  49. package/dist/initialization.d.ts.map +1 -0
  50. package/dist/initialization.js +266 -0
  51. package/dist/lint-workspaces.d.ts +2 -0
  52. package/dist/lint-workspaces.d.ts.map +1 -0
  53. package/dist/lint-workspaces.js +62 -0
  54. package/dist/model.d.ts +143 -0
  55. package/dist/model.d.ts.map +1 -0
  56. package/dist/model.js +61 -0
  57. package/dist/package-catalog.d.ts +8 -0
  58. package/dist/package-catalog.d.ts.map +1 -0
  59. package/dist/package-catalog.js +61 -0
  60. package/dist/packages.d.ts +57 -0
  61. package/dist/packages.d.ts.map +1 -0
  62. package/dist/packages.js +237 -0
  63. package/dist/process-group.d.ts +5 -0
  64. package/dist/process-group.d.ts.map +1 -0
  65. package/dist/process-group.js +23 -0
  66. package/dist/reference-workspace-bindings.d.ts +38 -0
  67. package/dist/reference-workspace-bindings.d.ts.map +1 -0
  68. package/dist/reference-workspace-bindings.js +41 -0
  69. package/dist/reference-workspace.d.ts +6 -0
  70. package/dist/reference-workspace.d.ts.map +1 -0
  71. package/dist/reference-workspace.js +62 -0
  72. package/dist/registry.d.ts +187 -0
  73. package/dist/registry.d.ts.map +1 -0
  74. package/dist/registry.js +107 -0
  75. package/dist/runtime.d.ts +9 -0
  76. package/dist/runtime.d.ts.map +1 -0
  77. package/dist/runtime.js +22 -0
  78. package/dist/selection.d.ts +704 -0
  79. package/dist/selection.d.ts.map +1 -0
  80. package/dist/selection.js +424 -0
  81. package/dist/shadcn-protocol.d.ts +22 -0
  82. package/dist/shadcn-protocol.d.ts.map +1 -0
  83. package/dist/shadcn-protocol.js +13 -0
  84. package/dist/shadcn-worker.d.ts +2 -0
  85. package/dist/shadcn-worker.d.ts.map +1 -0
  86. package/dist/shadcn-worker.js +43 -0
  87. package/dist/shadcn.d.ts +22 -0
  88. package/dist/shadcn.d.ts.map +1 -0
  89. package/dist/shadcn.js +101 -0
  90. package/dist/source-changes.d.ts +55 -0
  91. package/dist/source-changes.d.ts.map +1 -0
  92. package/dist/source-changes.js +225 -0
  93. package/dist/source-inventory.d.ts +25 -0
  94. package/dist/source-inventory.d.ts.map +1 -0
  95. package/dist/source-inventory.js +212 -0
  96. package/dist/source-root.d.ts +4 -0
  97. package/dist/source-root.d.ts.map +1 -0
  98. package/dist/source-root.js +20 -0
  99. package/dist/staging.d.ts +19 -0
  100. package/dist/staging.d.ts.map +1 -0
  101. package/dist/staging.js +42 -0
  102. package/dist/tasks.d.ts +44 -0
  103. package/dist/tasks.d.ts.map +1 -0
  104. package/dist/tasks.js +137 -0
  105. package/dist/templates.d.ts +217 -0
  106. package/dist/templates.d.ts.map +1 -0
  107. package/dist/templates.js +161 -0
  108. package/dist/test-reference-workspace.d.ts +2 -0
  109. package/dist/test-reference-workspace.d.ts.map +1 -0
  110. package/dist/test-reference-workspace.js +6 -0
  111. package/dist/types.d.ts +2 -9
  112. package/dist/types.d.ts.map +1 -1
  113. package/dist/typescript-paths.d.ts +10 -0
  114. package/dist/typescript-paths.d.ts.map +1 -0
  115. package/dist/typescript-paths.js +52 -0
  116. package/dist/workspace-dependencies.d.ts +26 -0
  117. package/dist/workspace-dependencies.d.ts.map +1 -0
  118. package/dist/workspace-dependencies.js +478 -0
  119. package/dist/workspace-files.d.ts +24 -0
  120. package/dist/workspace-files.d.ts.map +1 -0
  121. package/dist/workspace-files.js +395 -0
  122. package/dist/workspace-lock.d.ts +12 -0
  123. package/dist/workspace-lock.d.ts.map +1 -0
  124. package/dist/workspace-lock.js +104 -0
  125. package/dist/workspace-snapshots.d.ts +24 -0
  126. package/dist/workspace-snapshots.d.ts.map +1 -0
  127. package/dist/workspace-snapshots.js +218 -0
  128. package/dist/workspace-sources.d.ts +27 -0
  129. package/dist/workspace-sources.d.ts.map +1 -0
  130. package/dist/workspace-sources.js +88 -0
  131. package/dist/workspace-state.d.ts +325 -0
  132. package/dist/workspace-state.d.ts.map +1 -0
  133. package/dist/workspace-state.js +571 -0
  134. package/dist/workspaces.d.ts +73 -0
  135. package/dist/workspaces.d.ts.map +1 -0
  136. package/dist/workspaces.js +396 -0
  137. package/package.json +25 -20
  138. package/schema/selection-definition.json +143 -4
  139. package/dist/clone.d.ts +0 -9
  140. package/dist/clone.d.ts.map +0 -1
  141. package/dist/clone.js +0 -19
  142. package/dist/composition/add.d.ts +0 -14
  143. package/dist/composition/add.d.ts.map +0 -1
  144. package/dist/composition/add.js +0 -484
  145. package/dist/composition/catalog.d.ts +0 -26
  146. package/dist/composition/catalog.d.ts.map +0 -1
  147. package/dist/composition/catalog.js +0 -317
  148. package/dist/composition/errors.d.ts +0 -5
  149. package/dist/composition/errors.d.ts.map +0 -1
  150. package/dist/composition/errors.js +0 -8
  151. package/dist/composition/format.d.ts +0 -6
  152. package/dist/composition/format.d.ts.map +0 -1
  153. package/dist/composition/format.js +0 -65
  154. package/dist/composition/install.d.ts +0 -16
  155. package/dist/composition/install.d.ts.map +0 -1
  156. package/dist/composition/install.js +0 -175
  157. package/dist/composition/packages.d.ts +0 -6
  158. package/dist/composition/packages.d.ts.map +0 -1
  159. package/dist/composition/packages.js +0 -55
  160. package/dist/composition/paths.d.ts +0 -4
  161. package/dist/composition/paths.d.ts.map +0 -1
  162. package/dist/composition/paths.js +0 -47
  163. package/dist/composition/planner.d.ts +0 -4
  164. package/dist/composition/planner.d.ts.map +0 -1
  165. package/dist/composition/planner.js +0 -366
  166. package/dist/composition/schema.d.ts +0 -294
  167. package/dist/composition/schema.d.ts.map +0 -1
  168. package/dist/composition/schema.js +0 -166
  169. package/dist/composition/types.d.ts +0 -111
  170. package/dist/composition/types.d.ts.map +0 -1
  171. package/dist/composition/types.js +0 -6
  172. package/dist/composition/typescript-paths.d.ts +0 -6
  173. package/dist/composition/typescript-paths.d.ts.map +0 -1
  174. package/dist/composition/typescript-paths.js +0 -157
  175. package/dist/composition/use.d.ts +0 -23
  176. package/dist/composition/use.d.ts.map +0 -1
  177. package/dist/composition/use.js +0 -187
  178. package/dist/composition/workspace.d.ts +0 -10
  179. package/dist/composition/workspace.d.ts.map +0 -1
  180. package/dist/composition/workspace.js +0 -210
  181. package/dist/constants.d.ts +0 -11
  182. package/dist/constants.d.ts.map +0 -1
  183. package/dist/constants.js +0 -39
  184. package/dist/fs-utils.d.ts +0 -9
  185. package/dist/fs-utils.d.ts.map +0 -1
  186. package/dist/fs-utils.js +0 -64
  187. package/dist/git.d.ts +0 -28
  188. package/dist/git.d.ts.map +0 -1
  189. package/dist/git.js +0 -107
  190. package/dist/instruction-renderer.d.ts +0 -17
  191. package/dist/instruction-renderer.d.ts.map +0 -1
  192. package/dist/instruction-renderer.js +0 -132
  193. package/dist/logger.d.ts +0 -13
  194. package/dist/logger.d.ts.map +0 -1
  195. package/dist/logger.js +0 -26
  196. package/dist/prompts.d.ts +0 -7
  197. package/dist/prompts.d.ts.map +0 -1
  198. package/dist/prompts.js +0 -54
  199. package/dist/sanitize.d.ts +0 -10
  200. package/dist/sanitize.d.ts.map +0 -1
  201. package/dist/sanitize.js +0 -110
  202. package/dist/scaffold.d.ts +0 -7
  203. package/dist/scaffold.d.ts.map +0 -1
  204. package/dist/scaffold.js +0 -330
  205. package/dist/version.d.ts +0 -2
  206. package/dist/version.d.ts.map +0 -1
  207. package/dist/version.js +0 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-state.d.ts","sourceRoot":"","sources":["../src/workspace-state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,571 @@
1
+ import { isDeepStrictEqual } from "node:util";
2
+ import { Context, Effect, FileSystem, Layer, Path, Ref, Schema } from "effect";
3
+ import { WorkspaceBusy, WorkspaceRecoveryRequired, WorkspaceStateInvalid, } from "./errors.js";
4
+ import { cacheDirectories, isEnvironmentFile } from "./file-policy.js";
5
+ import { relativeFile } from "./files.js";
6
+ import { validatePreservedFiles, workspaceSetting } from "./initialization.js";
7
+ import { FileOrigin } from "./model.js";
8
+ import { withWriteLock } from "./workspace-lock.js";
9
+ const Fingerprint = Schema.Struct({ hash: Schema.String, mode: Schema.Int });
10
+ export const sameFingerprint = (left, right) => left === null || right === null
11
+ ? left === right
12
+ : left.hash === right.hash && left.mode === right.mode;
13
+ const Entry = Schema.Struct({
14
+ applied: Fingerprint,
15
+ desired: Fingerprint,
16
+ origin: FileOrigin,
17
+ target: Schema.String,
18
+ });
19
+ const Intent = Schema.Struct({
20
+ after: Schema.NullOr(Fingerprint),
21
+ before: Schema.NullOr(Fingerprint),
22
+ desired: Schema.NullOr(Fingerprint),
23
+ origin: Schema.NullOr(FileOrigin),
24
+ target: Schema.String,
25
+ temporary: Schema.NullOr(Schema.String),
26
+ });
27
+ const Installation = Schema.Struct({
28
+ inputs: Schema.String,
29
+ lockfile: Fingerprint,
30
+ modules: Fingerprint,
31
+ toolchain: Schema.String,
32
+ virtualLock: Fingerprint,
33
+ });
34
+ const Snapshot = Schema.Struct({
35
+ commit: Schema.String,
36
+ filesRevision: Schema.Int,
37
+ origins: Schema.Array(Schema.Struct({ origin: FileOrigin, target: Schema.String })),
38
+ revision: Schema.Int,
39
+ });
40
+ const Initialization = Schema.Struct({
41
+ status: Schema.Literals(["planned", "started", "completed"]),
42
+ target: Schema.String,
43
+ });
44
+ const PreservedFiles = Schema.Array(Schema.String).pipe(Schema.withDecodingDefaultKey(Effect.succeed([])));
45
+ const Receipt = Schema.Struct({
46
+ directory: Schema.String,
47
+ entries: Schema.Array(Entry),
48
+ filesRevision: Schema.Int,
49
+ format: Schema.Literal("effect-workspace"),
50
+ installation: Schema.NullOr(Installation),
51
+ pending: Schema.NullOr(Schema.Union([
52
+ Schema.Struct({
53
+ files: Schema.Array(Intent),
54
+ initialization: Schema.Array(Initialization),
55
+ kind: Schema.Literal("files"),
56
+ preserved: PreservedFiles,
57
+ }),
58
+ Schema.Struct({
59
+ inputs: Schema.String,
60
+ kind: Schema.Literal("installation"),
61
+ stopped: Schema.Boolean,
62
+ }),
63
+ ])),
64
+ preserved: PreservedFiles,
65
+ revision: Schema.Int,
66
+ snapshot: Schema.NullOr(Snapshot),
67
+ sourceRoot: Schema.String,
68
+ version: Schema.Literal(1),
69
+ });
70
+ function validFingerprint(value) {
71
+ return (value === null ||
72
+ (/^[a-f0-9]{64}$/u.test(value.hash) &&
73
+ value.mode >= 0 &&
74
+ value.mode <= 0o777));
75
+ }
76
+ const validateOwnedTargets = (names, directory) => Effect.gen(function* () {
77
+ const invalid = () => new WorkspaceStateInvalid({ directory });
78
+ const targets = new Set(names);
79
+ if (targets.size !== names.length) {
80
+ return yield* invalid();
81
+ }
82
+ for (const name of names) {
83
+ const target = yield* relativeFile(name).pipe(Effect.mapError(invalid));
84
+ if (target !== name ||
85
+ target.startsWith(".workspace-composition") ||
86
+ workspaceSetting(target) ||
87
+ isEnvironmentFile(target) ||
88
+ target.split("/").some((part) => cacheDirectories.has(part))) {
89
+ return yield* invalid();
90
+ }
91
+ const parts = target.split("/");
92
+ for (let end = 1; end < parts.length; end += 1) {
93
+ const ancestor = parts.slice(0, end).join("/");
94
+ if (targets.has(ancestor) ||
95
+ workspaceSetting(ancestor) ||
96
+ isEnvironmentFile(ancestor)) {
97
+ return yield* invalid();
98
+ }
99
+ }
100
+ }
101
+ });
102
+ const validateFileIntent = (receipt) => Effect.gen(function* () {
103
+ if (receipt.pending?.kind !== "files") {
104
+ return;
105
+ }
106
+ const invalid = () => new WorkspaceStateInvalid({ directory: receipt.directory });
107
+ const { pending } = receipt;
108
+ const previous = new Map(receipt.entries
109
+ .filter((entry) => !pending.preserved.includes(entry.target))
110
+ .map((entry) => [entry.target, entry]));
111
+ const ownedTargets = receipt.pending.files.map((file) => file.target);
112
+ // Temporary siblings can look like runtime env files (for example
113
+ // .env.example.<uuid>.pending). Validate their exact derivation below;
114
+ // only final targets are subject to the owned-file classification.
115
+ yield* validateOwnedTargets([...ownedTargets, ...receipt.pending.preserved], receipt.directory);
116
+ yield* validatePreservedFiles(receipt.pending.preserved).pipe(Effect.mapError(invalid));
117
+ const allTargets = [
118
+ ...ownedTargets,
119
+ ...receipt.pending.files.flatMap((file) => file.temporary === null ? [] : [file.temporary]),
120
+ ...receipt.pending.initialization.map((file) => file.target),
121
+ ];
122
+ const targets = new Set(allTargets);
123
+ if (targets.size !== allTargets.length) {
124
+ return yield* invalid();
125
+ }
126
+ // Staging paths share the filesystem namespace, but are not application files.
127
+ // Their authority comes from the owned target and the operation ID below.
128
+ for (const target of allTargets) {
129
+ const parts = target.split("/");
130
+ for (let end = 1; end < parts.length; end += 1) {
131
+ if (targets.has(parts.slice(0, end).join("/"))) {
132
+ return yield* invalid();
133
+ }
134
+ }
135
+ }
136
+ for (const file of receipt.pending.initialization) {
137
+ const target = yield* relativeFile(file.target).pipe(Effect.mapError(invalid));
138
+ if (target !== file.target ||
139
+ (target !== ".gitignore" &&
140
+ !isEnvironmentFile(target) &&
141
+ !receipt.pending.preserved.includes(target)) ||
142
+ target.startsWith(".workspace-composition") ||
143
+ target.split("/").some((part) => cacheDirectories.has(part))) {
144
+ return yield* invalid();
145
+ }
146
+ const parts = target.split("/");
147
+ for (let end = 1; end < parts.length; end += 1) {
148
+ const ancestor = parts.slice(0, end).join("/");
149
+ if (targets.has(ancestor) ||
150
+ workspaceSetting(ancestor) ||
151
+ isEnvironmentFile(ancestor)) {
152
+ return yield* invalid();
153
+ }
154
+ }
155
+ }
156
+ for (const file of receipt.pending.files) {
157
+ const entry = previous.get(file.target);
158
+ if (![file.before, file.after, file.desired].every(validFingerprint) ||
159
+ (file.after === null) !== (file.desired === null) ||
160
+ (file.after === null) !== (file.origin === null) ||
161
+ (entry
162
+ ? !sameFingerprint(file.before, entry.applied) &&
163
+ !sameFingerprint(file.before, file.after)
164
+ : file.before !== null &&
165
+ !((receipt.preserved.includes(file.target) ||
166
+ (file.target === "turbo.json" &&
167
+ file.origin?.kind === "policy" &&
168
+ file.origin.policy === "application-tasks" &&
169
+ sameFingerprint(file.after, file.desired))) &&
170
+ sameFingerprint(file.before, file.after)))) {
171
+ return yield* invalid();
172
+ }
173
+ const replaces = file.before !== null &&
174
+ file.after !== null &&
175
+ !sameFingerprint(file.before, file.after);
176
+ if (replaces !== (file.temporary !== null) ||
177
+ (file.temporary !== null &&
178
+ (!file.temporary.startsWith(`${file.target}.`) ||
179
+ !/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}\.pending$/u.test(file.temporary.slice(file.target.length + 1))))) {
180
+ return yield* invalid();
181
+ }
182
+ previous.delete(file.target);
183
+ }
184
+ if (previous.size > 0) {
185
+ return yield* invalid();
186
+ }
187
+ });
188
+ const decodeReceipt = (identity, original, allowIncomplete = false) => Effect.gen(function* () {
189
+ if (original === null) {
190
+ return null;
191
+ }
192
+ const { directory, sourceRoot } = identity;
193
+ const invalid = () => new WorkspaceStateInvalid({ directory });
194
+ const decoded = yield* Schema.decodeEffect(Schema.fromJsonString(Receipt))(original, { onExcessProperty: "error" }).pipe(Effect.mapError(invalid));
195
+ if (decoded.directory !== directory ||
196
+ decoded.sourceRoot !== sourceRoot ||
197
+ decoded.revision < 1 ||
198
+ decoded.filesRevision < 0 ||
199
+ decoded.filesRevision > decoded.revision) {
200
+ return yield* invalid();
201
+ }
202
+ if (decoded.snapshot &&
203
+ (!/^[a-f0-9]{40}$/u.test(decoded.snapshot.commit) ||
204
+ decoded.snapshot.revision < 1 ||
205
+ decoded.snapshot.revision > decoded.revision ||
206
+ decoded.snapshot.filesRevision < 0 ||
207
+ decoded.snapshot.filesRevision > decoded.filesRevision)) {
208
+ return yield* invalid();
209
+ }
210
+ yield* validateOwnedTargets([...decoded.entries.map((entry) => entry.target), ...decoded.preserved], directory);
211
+ yield* validatePreservedFiles(decoded.preserved).pipe(Effect.mapError(invalid));
212
+ if (decoded.snapshot) {
213
+ yield* validateOwnedTargets(decoded.snapshot.origins.map((entry) => entry.target), directory);
214
+ }
215
+ for (const entry of decoded.entries) {
216
+ if (![entry.desired, entry.applied].every(validFingerprint)) {
217
+ return yield* invalid();
218
+ }
219
+ }
220
+ yield* validateFileIntent(decoded);
221
+ if (decoded.pending !== null && !allowIncomplete) {
222
+ return yield* new WorkspaceRecoveryRequired({ directory });
223
+ }
224
+ return decoded;
225
+ });
226
+ export class WorkspaceState extends Context.Service()("create-next-hydra/WorkspaceState") {
227
+ static layer = Layer.effect(WorkspaceState, Effect.gen(function* () {
228
+ const fs = yield* FileSystem.FileSystem;
229
+ const path = yield* Path.Path;
230
+ const withRead = (identity, use, options) => Effect.gen(function* () {
231
+ const directory = path.resolve(identity.directory);
232
+ const sourceRoot = path.resolve(identity.sourceRoot);
233
+ const receiptPath = path.join(directory, ".workspace-composition.json");
234
+ const lock = path.join(directory, ".workspace-composition.lock");
235
+ const assertIdle = Effect.gen(function* () {
236
+ if (yield* fs.exists(lock)) {
237
+ return yield* new WorkspaceBusy({ directory });
238
+ }
239
+ });
240
+ const read = Effect.gen(function* () {
241
+ return (yield* fs.exists(receiptPath))
242
+ ? yield* fs.readFileString(receiptPath)
243
+ : null;
244
+ });
245
+ yield* assertIdle;
246
+ const original = yield* read;
247
+ const decoded = yield* decodeReceipt({ directory, sourceRoot }, original, options?.allowIncomplete);
248
+ const result = yield* use({
249
+ directory,
250
+ entries: decoded?.entries ?? [],
251
+ filesRevision: decoded?.filesRevision ?? 0,
252
+ initialized: decoded !== null,
253
+ installation: decoded?.installation ?? null,
254
+ pending: decoded?.pending ?? null,
255
+ preserved: decoded?.preserved ?? [],
256
+ revision: decoded?.revision ?? 0,
257
+ snapshot: decoded?.snapshot ?? null,
258
+ });
259
+ yield* assertIdle;
260
+ if ((yield* read) !== original) {
261
+ return yield* new WorkspaceStateInvalid({ directory });
262
+ }
263
+ return result;
264
+ });
265
+ const withWrite = (identity, use, options) => {
266
+ const directory = path.resolve(identity.directory);
267
+ const sourceRoot = path.resolve(identity.sourceRoot);
268
+ const receiptPath = path.join(directory, ".workspace-composition.json");
269
+ const lock = path.join(directory, ".workspace-composition.lock");
270
+ const invalid = () => new WorkspaceStateInvalid({ directory });
271
+ return withWriteLock(directory, ({ writer, assertOwner, recoveryEvidence }) => Effect.gen(function* () {
272
+ const active = yield* Ref.make(true);
273
+ const original = (yield* fs.exists(receiptPath))
274
+ ? yield* fs.readFileString(receiptPath)
275
+ : null;
276
+ const decoded = yield* decodeReceipt({ directory, sourceRoot }, original, true);
277
+ const current = yield* Ref.make(decoded ?? {
278
+ directory,
279
+ entries: [],
280
+ filesRevision: 0,
281
+ format: "effect-workspace",
282
+ installation: null,
283
+ pending: null,
284
+ preserved: [],
285
+ revision: 0,
286
+ snapshot: null,
287
+ sourceRoot,
288
+ version: 1,
289
+ });
290
+ const expected = yield* Ref.make(original);
291
+ const record = (next) => Effect.gen(function* () {
292
+ yield* assertOwner;
293
+ if (!(yield* Ref.get(active))) {
294
+ return yield* invalid();
295
+ }
296
+ const observed = (yield* fs.exists(receiptPath))
297
+ ? yield* fs.readFileString(receiptPath)
298
+ : null;
299
+ if (observed !== (yield* Ref.get(expected))) {
300
+ return yield* invalid();
301
+ }
302
+ const text = yield* Schema.encodeEffect(Schema.fromJsonString(Receipt))(next).pipe(Effect.mapError(invalid));
303
+ // The lock owns this temporary file. Failed publication leaves it
304
+ // in place and prevents release, rather than discarding evidence.
305
+ const temporary = path.join(lock, "receipt.json");
306
+ yield* fs.writeFileString(temporary, text, {
307
+ flag: "wx",
308
+ mode: 0o600,
309
+ });
310
+ yield* fs.rename(temporary, receiptPath);
311
+ yield* Ref.set(expected, text);
312
+ yield* Ref.set(current, next);
313
+ }).pipe(Effect.uninterruptible);
314
+ const begin = (files, initialization, preserved = []) => Effect.gen(function* () {
315
+ const state = yield* Ref.get(current);
316
+ if (state.pending !== null) {
317
+ return yield* new WorkspaceRecoveryRequired({
318
+ directory,
319
+ });
320
+ }
321
+ const next = {
322
+ ...state,
323
+ pending: {
324
+ files,
325
+ initialization: initialization.map((target) => ({
326
+ status: "planned",
327
+ target,
328
+ })),
329
+ kind: "files",
330
+ preserved,
331
+ },
332
+ revision: state.revision + 1,
333
+ };
334
+ yield* validateFileIntent(next);
335
+ yield* record(next);
336
+ });
337
+ const recordInitialization = (target, status) => Effect.gen(function* () {
338
+ const state = yield* Ref.get(current);
339
+ const expectedStatus = status === "started" ? "planned" : "started";
340
+ if (state.pending?.kind !== "files" ||
341
+ state.pending.initialization.find((file) => file.target === target)?.status !== expectedStatus) {
342
+ return yield* invalid();
343
+ }
344
+ yield* record({
345
+ ...state,
346
+ pending: {
347
+ ...state.pending,
348
+ initialization: state.pending.initialization.map((file) => file.target === target ? { ...file, status } : file),
349
+ },
350
+ revision: state.revision + 1,
351
+ });
352
+ });
353
+ const initialize = (target, write) => Effect.gen(function* () {
354
+ yield* recordInitialization(target, "started");
355
+ const result = yield* write;
356
+ yield* recordInitialization(target, "completed");
357
+ return result;
358
+ }).pipe(Effect.uninterruptible);
359
+ const complete = Effect.gen(function* () {
360
+ const state = yield* Ref.get(current);
361
+ if (state.pending?.kind !== "files" ||
362
+ state.pending.initialization.some((file) => file.status !== "completed")) {
363
+ return yield* invalid();
364
+ }
365
+ const entries = state.pending.files.flatMap((file) => file.after === null ||
366
+ file.desired === null ||
367
+ file.origin === null
368
+ ? []
369
+ : [
370
+ {
371
+ applied: file.after,
372
+ desired: file.desired,
373
+ origin: file.origin,
374
+ target: file.target,
375
+ },
376
+ ]);
377
+ const previous = new Map(state.entries.map((entry) => [entry.target, entry]));
378
+ const changed = !isDeepStrictEqual(state.preserved, state.pending.preserved) ||
379
+ entries.length !== previous.size ||
380
+ entries.some((entry) => {
381
+ const old = previous.get(entry.target);
382
+ return (!old ||
383
+ !sameFingerprint(entry.applied, old.applied) ||
384
+ !sameFingerprint(entry.desired, old.desired) ||
385
+ !isDeepStrictEqual(entry.origin, old.origin));
386
+ });
387
+ yield* record({
388
+ ...state,
389
+ entries,
390
+ filesRevision: state.filesRevision + Number(changed),
391
+ pending: null,
392
+ preserved: state.pending.preserved,
393
+ revision: state.revision + 1,
394
+ });
395
+ });
396
+ const recoverFiles = (observed, expectedRevision) => Effect.gen(function* () {
397
+ const state = yield* Ref.get(current);
398
+ if (state.revision !== expectedRevision ||
399
+ state.pending?.kind !== "files" ||
400
+ observed.size !== state.pending.files.length) {
401
+ return yield* invalid();
402
+ }
403
+ const { pending } = state;
404
+ const previous = new Map(state.entries
405
+ .filter((entry) => !pending.preserved.includes(entry.target))
406
+ .map((entry) => [entry.target, entry]));
407
+ const entries = [];
408
+ for (const file of state.pending.files) {
409
+ const currentFile = observed.get(file.target);
410
+ if (currentFile === undefined) {
411
+ return yield* invalid();
412
+ }
413
+ if (sameFingerprint(currentFile, file.after)) {
414
+ if (file.after !== null &&
415
+ file.desired !== null &&
416
+ file.origin !== null) {
417
+ entries.push({
418
+ applied: file.after,
419
+ desired: file.desired,
420
+ origin: file.origin,
421
+ target: file.target,
422
+ });
423
+ }
424
+ }
425
+ else if (sameFingerprint(currentFile, file.before)) {
426
+ const entry = previous.get(file.target);
427
+ if (!sameFingerprint(currentFile, entry?.applied ?? null)) {
428
+ return yield* invalid();
429
+ }
430
+ if (entry) {
431
+ entries.push(entry);
432
+ }
433
+ }
434
+ else {
435
+ return yield* new WorkspaceRecoveryRequired({
436
+ directory,
437
+ });
438
+ }
439
+ previous.delete(file.target);
440
+ }
441
+ if (previous.size > 0) {
442
+ return yield* invalid();
443
+ }
444
+ yield* record({
445
+ ...state,
446
+ entries,
447
+ filesRevision: state.filesRevision + 1,
448
+ installation: null,
449
+ pending: null,
450
+ preserved: pending.preserved.filter((target) => !pending.initialization.some((file) => file.target === target &&
451
+ file.status !== "completed")),
452
+ revision: state.revision + 1,
453
+ });
454
+ });
455
+ const beginInstall = (inputs) => Effect.gen(function* () {
456
+ const state = yield* Ref.get(current);
457
+ if (state.pending !== null) {
458
+ return yield* invalid();
459
+ }
460
+ yield* record({
461
+ ...state,
462
+ pending: { inputs, kind: "installation", stopped: false },
463
+ revision: state.revision + 1,
464
+ });
465
+ yield* Ref.set(writer, true);
466
+ }).pipe(Effect.uninterruptible);
467
+ const installStopped = Effect.gen(function* () {
468
+ const state = yield* Ref.get(current);
469
+ if (state.pending?.kind !== "installation") {
470
+ return yield* invalid();
471
+ }
472
+ // Persist confirmed process completion before releasing the lease.
473
+ // An in-memory flag cannot justify recovery in another invocation.
474
+ yield* record({
475
+ ...state,
476
+ pending: { ...state.pending, stopped: true },
477
+ revision: state.revision + 1,
478
+ });
479
+ yield* Ref.set(writer, false);
480
+ }).pipe(Effect.uninterruptible);
481
+ const recoverInstall = (expectedRevision) => Effect.gen(function* () {
482
+ const state = yield* Ref.get(current);
483
+ if (state.revision !== expectedRevision ||
484
+ state.pending?.kind !== "installation" ||
485
+ !state.pending.stopped ||
486
+ (yield* Ref.get(writer))) {
487
+ return yield* invalid();
488
+ }
489
+ yield* record({
490
+ ...state,
491
+ installation: null,
492
+ pending: null,
493
+ revision: state.revision + 1,
494
+ });
495
+ });
496
+ const finishInstall = (installation, lockfile) => Effect.gen(function* () {
497
+ const state = yield* Ref.get(current);
498
+ if (state.pending?.kind !== "installation" ||
499
+ !state.pending.stopped ||
500
+ (yield* Ref.get(writer)) ||
501
+ (installation &&
502
+ installation.inputs !== state.pending.inputs)) {
503
+ return yield* invalid();
504
+ }
505
+ const previousLock = state.entries.find((entry) => entry.target === "pnpm-lock.yaml");
506
+ if (!previousLock) {
507
+ return yield* invalid();
508
+ }
509
+ yield* record({
510
+ ...state,
511
+ entries: state.entries.map((entry) => entry.target === "pnpm-lock.yaml"
512
+ ? { ...entry, applied: lockfile }
513
+ : entry),
514
+ filesRevision: state.filesRevision +
515
+ Number(!sameFingerprint(previousLock.applied, lockfile)),
516
+ installation,
517
+ pending: null,
518
+ revision: state.revision + 1,
519
+ });
520
+ });
521
+ return yield* use({
522
+ appliedEntries: Ref.get(current).pipe(Effect.map((state) => state.entries)),
523
+ begin,
524
+ beginInstall,
525
+ complete,
526
+ directory,
527
+ finishInstall,
528
+ initialize,
529
+ installStopped,
530
+ installation: Ref.get(current).pipe(Effect.map((state) => state.installation)),
531
+ observation: Ref.get(current).pipe(Effect.map((state) => ({
532
+ directory,
533
+ entries: state.entries,
534
+ filesRevision: state.filesRevision,
535
+ initialized: state.revision > 0,
536
+ installation: state.installation,
537
+ pending: state.pending,
538
+ preserved: state.preserved,
539
+ revision: state.revision,
540
+ snapshot: state.snapshot,
541
+ }))),
542
+ publishSnapshot: (commit, expectedRevision) => Effect.gen(function* () {
543
+ const state = yield* Ref.get(current);
544
+ if (state.pending !== null ||
545
+ state.revision !== expectedRevision ||
546
+ !/^[a-f0-9]{40}$/u.test(commit)) {
547
+ return yield* invalid();
548
+ }
549
+ yield* record({
550
+ ...state,
551
+ revision: state.revision + 1,
552
+ snapshot: {
553
+ commit,
554
+ filesRevision: state.filesRevision,
555
+ origins: state.entries.map(({ target, origin }) => ({
556
+ origin,
557
+ target,
558
+ })),
559
+ revision: state.revision + 1,
560
+ },
561
+ });
562
+ }),
563
+ recoverFiles,
564
+ recoverInstall,
565
+ recoveryEvidence,
566
+ }).pipe(Effect.ensuring(Ref.set(active, false)));
567
+ }), options).pipe(Effect.provideService(FileSystem.FileSystem, fs), Effect.provideService(Path.Path, path));
568
+ };
569
+ return WorkspaceState.of({ withRead, withWrite });
570
+ }));
571
+ }
@@ -0,0 +1,73 @@
1
+ import { Context, Effect, FileSystem, Layer, Path, Stream } from "effect";
2
+ import type { PlatformError } from "effect";
3
+ import { ChildProcessSpawner } from "effect/unstable/process";
4
+ import type { ExistingWorkspace } from "./addition.ts";
5
+ import type { ApplicationGitFailed } from "./application-git.ts";
6
+ import { Composition } from "./composition.ts";
7
+ import type { PreparationError as CompositionError } from "./composition.ts";
8
+ import { DestinationNotEmpty, InvalidComposition, MaterializationFailed, SourceChanged, WorkspaceUninitialized } from "./errors.ts";
9
+ import type { EnvironmentInitializationFailed } from "./errors.ts";
10
+ import type { ExplanationReport, CheckReport, DiffReport, MaterializationReport, SelectionRequest } from "./model.ts";
11
+ import { Shadcn } from "./shadcn.ts";
12
+ import { SourceChanges, SourceWatchFailure } from "./source-changes.ts";
13
+ import { SourceInventory } from "./source-inventory.ts";
14
+ import { WorkspaceDependencies } from "./workspace-dependencies.ts";
15
+ import type { DependencyOptions, DependencyError } from "./workspace-dependencies.ts";
16
+ import { WorkspaceFiles } from "./workspace-files.ts";
17
+ import type { WorkspaceFileError } from "./workspace-files.ts";
18
+ import { WorkspaceSnapshots } from "./workspace-snapshots.ts";
19
+ import type { SnapshotError } from "./workspace-snapshots.ts";
20
+ import { WorkspaceSources } from "./workspace-sources.ts";
21
+ import type { SourceRequest, SourceError } from "./workspace-sources.ts";
22
+ import { WorkspaceState } from "./workspace-state.ts";
23
+ import type { WorkspaceStateError } from "./workspace-state.ts";
24
+ type PreparationError = CompositionError | SourceError;
25
+ export interface FreshRequest {
26
+ readonly source: SourceRequest;
27
+ readonly destination: string;
28
+ readonly selection: SelectionRequest;
29
+ readonly name: string;
30
+ }
31
+ export interface NamedWorkspaceRef {
32
+ readonly sourceRoot: string;
33
+ readonly name: string;
34
+ }
35
+ export interface SyncOptions extends DependencyOptions {
36
+ readonly environment?: "preserve" | "copy-missing-local";
37
+ }
38
+ export interface NamedSyncOptions extends SyncOptions {
39
+ readonly breakLock?: string;
40
+ }
41
+ export interface FreshOptions extends SyncOptions {
42
+ readonly git?: "skip" | "initialize" | "commit";
43
+ }
44
+ export interface FreshWorkspace {
45
+ readonly materialize: (options: FreshOptions) => Effect.Effect<MaterializationReport, PreparationError | ApplicationGitFailed | DestinationNotEmpty | EnvironmentInitializationFailed | MaterializationFailed | PlatformError.PlatformError | DependencyError>;
46
+ }
47
+ export interface NamedWorkspace {
48
+ readonly watch: (options: SyncOptions) => Stream.Stream<WatchEvent, Effect.Error<ReturnType<NamedWorkspace["sync"]>> | SourceWatchFailure>;
49
+ readonly diff: Effect.Effect<DiffReport, WorkspaceFileError | WorkspaceStateError | SnapshotError | DestinationNotEmpty | SourceChanged | WorkspaceUninitialized>;
50
+ readonly check: Effect.Effect<CheckReport, PreparationError | WorkspaceFileError | WorkspaceStateError | DestinationNotEmpty>;
51
+ readonly explain: (target?: string) => Effect.Effect<ExplanationReport, PreparationError>;
52
+ readonly sync: (options: NamedSyncOptions) => Effect.Effect<MaterializationReport, Effect.Error<ReturnType<FreshWorkspace["materialize"]>> | WorkspaceFileError | WorkspaceStateError | SnapshotError>;
53
+ }
54
+ export type WatchEvent = {
55
+ readonly _tag: "Synchronized";
56
+ readonly result: MaterializationReport;
57
+ } | {
58
+ readonly _tag: "RefreshFailed";
59
+ readonly error: Effect.Error<ReturnType<NamedWorkspace["sync"]>>;
60
+ };
61
+ declare const Workspaces_base: Context.ServiceClass<Workspaces, "create-next-hydra/Workspaces", {
62
+ readonly existing: (request: {
63
+ readonly root: string;
64
+ }) => Effect.Effect<ExistingWorkspace>;
65
+ readonly discover: (sourceRoot: string) => Effect.Effect<readonly NamedWorkspaceRef[], PlatformError.PlatformError | InvalidComposition>;
66
+ readonly fresh: (request: FreshRequest) => Effect.Effect<FreshWorkspace>;
67
+ readonly named: (request: NamedWorkspaceRef) => Effect.Effect<NamedWorkspace, InvalidComposition>;
68
+ }>;
69
+ export declare class Workspaces extends Workspaces_base {
70
+ static readonly layer: Layer.Layer<Workspaces, never, FileSystem.FileSystem | Path.Path | Shadcn | ChildProcessSpawner.ChildProcessSpawner | WorkspaceState | WorkspaceDependencies | SourceInventory | WorkspaceSources | Composition | SourceChanges | WorkspaceSnapshots | WorkspaceFiles>;
71
+ }
72
+ export {};
73
+ //# sourceMappingURL=workspaces.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspaces.d.ts","sourceRoot":"","sources":["../src/workspaces.ts"],"names":[],"mappings":"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"}