@lorepack/cli 0.0.0-stage → 0.1.0-alpha.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 (229) hide show
  1. package/dist/.tsbuildinfo +1 -0
  2. package/dist/commands/activate.d.ts +20 -0
  3. package/dist/commands/activate.d.ts.map +1 -0
  4. package/dist/commands/activate.js +171 -0
  5. package/dist/commands/activate.js.map +1 -0
  6. package/dist/commands/build.d.ts +3 -0
  7. package/dist/commands/build.d.ts.map +1 -0
  8. package/dist/commands/build.js +53 -0
  9. package/dist/commands/build.js.map +1 -0
  10. package/dist/commands/config.d.ts +14 -0
  11. package/dist/commands/config.d.ts.map +1 -0
  12. package/dist/commands/config.js +109 -0
  13. package/dist/commands/config.js.map +1 -0
  14. package/dist/commands/connect.d.ts +5 -0
  15. package/dist/commands/connect.d.ts.map +1 -0
  16. package/dist/commands/connect.js +196 -0
  17. package/dist/commands/connect.js.map +1 -0
  18. package/dist/commands/deploy.d.ts +14 -0
  19. package/dist/commands/deploy.d.ts.map +1 -0
  20. package/dist/commands/deploy.js +248 -0
  21. package/dist/commands/deploy.js.map +1 -0
  22. package/dist/commands/dev.d.ts +25 -0
  23. package/dist/commands/dev.d.ts.map +1 -0
  24. package/dist/commands/dev.js +227 -0
  25. package/dist/commands/dev.js.map +1 -0
  26. package/dist/commands/diff.d.ts +3 -0
  27. package/dist/commands/diff.d.ts.map +1 -0
  28. package/dist/commands/diff.js +75 -0
  29. package/dist/commands/diff.js.map +1 -0
  30. package/dist/commands/doctor.d.ts +14 -0
  31. package/dist/commands/doctor.d.ts.map +1 -0
  32. package/dist/commands/doctor.js +96 -0
  33. package/dist/commands/doctor.js.map +1 -0
  34. package/dist/commands/export.d.ts +3 -0
  35. package/dist/commands/export.d.ts.map +1 -0
  36. package/dist/commands/export.js +126 -0
  37. package/dist/commands/export.js.map +1 -0
  38. package/dist/commands/index.d.ts +8 -0
  39. package/dist/commands/index.d.ts.map +1 -0
  40. package/dist/commands/index.js +51 -0
  41. package/dist/commands/index.js.map +1 -0
  42. package/dist/commands/init.d.ts +3 -0
  43. package/dist/commands/init.d.ts.map +1 -0
  44. package/dist/commands/init.js +95 -0
  45. package/dist/commands/init.js.map +1 -0
  46. package/dist/commands/inspect.d.ts +15 -0
  47. package/dist/commands/inspect.d.ts.map +1 -0
  48. package/dist/commands/inspect.js +527 -0
  49. package/dist/commands/inspect.js.map +1 -0
  50. package/dist/commands/mcp.d.ts +12 -0
  51. package/dist/commands/mcp.d.ts.map +1 -0
  52. package/dist/commands/mcp.js +219 -0
  53. package/dist/commands/mcp.js.map +1 -0
  54. package/dist/commands/pack.d.ts +9 -0
  55. package/dist/commands/pack.d.ts.map +1 -0
  56. package/dist/commands/pack.js +57 -0
  57. package/dist/commands/pack.js.map +1 -0
  58. package/dist/commands/plan.d.ts +3 -0
  59. package/dist/commands/plan.d.ts.map +1 -0
  60. package/dist/commands/plan.js +44 -0
  61. package/dist/commands/plan.js.map +1 -0
  62. package/dist/commands/prune.d.ts +7 -0
  63. package/dist/commands/prune.d.ts.map +1 -0
  64. package/dist/commands/prune.js +341 -0
  65. package/dist/commands/prune.js.map +1 -0
  66. package/dist/commands/search.d.ts +3 -0
  67. package/dist/commands/search.d.ts.map +1 -0
  68. package/dist/commands/search.js +84 -0
  69. package/dist/commands/search.js.map +1 -0
  70. package/dist/commands/serve.d.ts +20 -0
  71. package/dist/commands/serve.d.ts.map +1 -0
  72. package/dist/commands/serve.js +66 -0
  73. package/dist/commands/serve.js.map +1 -0
  74. package/dist/commands/status.d.ts +3 -0
  75. package/dist/commands/status.d.ts.map +1 -0
  76. package/dist/commands/status.js +27 -0
  77. package/dist/commands/status.js.map +1 -0
  78. package/dist/commands/target.d.ts +71 -0
  79. package/dist/commands/target.d.ts.map +1 -0
  80. package/dist/commands/target.js +945 -0
  81. package/dist/commands/target.js.map +1 -0
  82. package/dist/entry.d.ts +3 -0
  83. package/dist/entry.d.ts.map +1 -0
  84. package/dist/entry.js +19 -0
  85. package/dist/entry.js.map +1 -0
  86. package/dist/framework/context.d.ts +49 -0
  87. package/dist/framework/context.d.ts.map +1 -0
  88. package/dist/framework/context.js +47 -0
  89. package/dist/framework/context.js.map +1 -0
  90. package/dist/framework/exit.d.ts +36 -0
  91. package/dist/framework/exit.d.ts.map +1 -0
  92. package/dist/framework/exit.js +57 -0
  93. package/dist/framework/exit.js.map +1 -0
  94. package/dist/framework/metadata.d.ts +38 -0
  95. package/dist/framework/metadata.d.ts.map +1 -0
  96. package/dist/framework/metadata.js +47 -0
  97. package/dist/framework/metadata.js.map +1 -0
  98. package/dist/framework/program.d.ts +47 -0
  99. package/dist/framework/program.d.ts.map +1 -0
  100. package/dist/framework/program.js +189 -0
  101. package/dist/framework/program.js.map +1 -0
  102. package/dist/index.d.ts +7 -0
  103. package/dist/index.d.ts.map +1 -0
  104. package/dist/index.js +7 -0
  105. package/dist/index.js.map +1 -0
  106. package/dist/migrations/README.md +7 -0
  107. package/dist/migrations/build/0001_catalog.sql +85 -0
  108. package/dist/migrations/build/0002_tables.sql +43 -0
  109. package/dist/migrations/build/0003_table-cell-range.sql +13 -0
  110. package/dist/migrations/build/0004_chunk-page.sql +11 -0
  111. package/dist/migrations/state/0001_state.sql +40 -0
  112. package/dist/public-entry.js +38563 -0
  113. package/dist/public-entry.js.map +7 -0
  114. package/dist/public-index.js +36428 -0
  115. package/dist/public-index.js.map +7 -0
  116. package/dist/services/build.d.ts +48 -0
  117. package/dist/services/build.d.ts.map +1 -0
  118. package/dist/services/build.js +499 -0
  119. package/dist/services/build.js.map +1 -0
  120. package/dist/services/builds.d.ts +40 -0
  121. package/dist/services/builds.d.ts.map +1 -0
  122. package/dist/services/builds.js +184 -0
  123. package/dist/services/builds.js.map +1 -0
  124. package/dist/services/cancellation.d.ts +27 -0
  125. package/dist/services/cancellation.d.ts.map +1 -0
  126. package/dist/services/cancellation.js +41 -0
  127. package/dist/services/cancellation.js.map +1 -0
  128. package/dist/services/cloudflare-target.d.ts +38 -0
  129. package/dist/services/cloudflare-target.d.ts.map +1 -0
  130. package/dist/services/cloudflare-target.js +471 -0
  131. package/dist/services/cloudflare-target.js.map +1 -0
  132. package/dist/services/comparer.d.ts +15 -0
  133. package/dist/services/comparer.d.ts.map +1 -0
  134. package/dist/services/comparer.js +43 -0
  135. package/dist/services/comparer.js.map +1 -0
  136. package/dist/services/config-resolve.d.ts +60 -0
  137. package/dist/services/config-resolve.d.ts.map +1 -0
  138. package/dist/services/config-resolve.js +178 -0
  139. package/dist/services/config-resolve.js.map +1 -0
  140. package/dist/services/deploy.d.ts +70 -0
  141. package/dist/services/deploy.d.ts.map +1 -0
  142. package/dist/services/deploy.js +260 -0
  143. package/dist/services/deploy.js.map +1 -0
  144. package/dist/services/dev-session.d.ts +52 -0
  145. package/dist/services/dev-session.d.ts.map +1 -0
  146. package/dist/services/dev-session.js +102 -0
  147. package/dist/services/dev-session.js.map +1 -0
  148. package/dist/services/doctor.d.ts +35 -0
  149. package/dist/services/doctor.d.ts.map +1 -0
  150. package/dist/services/doctor.js +389 -0
  151. package/dist/services/doctor.js.map +1 -0
  152. package/dist/services/export.d.ts +20 -0
  153. package/dist/services/export.d.ts.map +1 -0
  154. package/dist/services/export.js +129 -0
  155. package/dist/services/export.js.map +1 -0
  156. package/dist/services/init.d.ts +46 -0
  157. package/dist/services/init.d.ts.map +1 -0
  158. package/dist/services/init.js +231 -0
  159. package/dist/services/init.js.map +1 -0
  160. package/dist/services/packing.d.ts +25 -0
  161. package/dist/services/packing.d.ts.map +1 -0
  162. package/dist/services/packing.js +69 -0
  163. package/dist/services/packing.js.map +1 -0
  164. package/dist/services/parse-cache.d.ts +47 -0
  165. package/dist/services/parse-cache.d.ts.map +1 -0
  166. package/dist/services/parse-cache.js +65 -0
  167. package/dist/services/parse-cache.js.map +1 -0
  168. package/dist/services/project.d.ts +49 -0
  169. package/dist/services/project.d.ts.map +1 -0
  170. package/dist/services/project.js +119 -0
  171. package/dist/services/project.js.map +1 -0
  172. package/dist/services/remote-prune.d.ts +7 -0
  173. package/dist/services/remote-prune.d.ts.map +1 -0
  174. package/dist/services/remote-prune.js +34 -0
  175. package/dist/services/remote-prune.js.map +1 -0
  176. package/dist/services/retention.d.ts +20 -0
  177. package/dist/services/retention.d.ts.map +1 -0
  178. package/dist/services/retention.js +106 -0
  179. package/dist/services/retention.js.map +1 -0
  180. package/dist/services/revalidate.d.ts +36 -0
  181. package/dist/services/revalidate.d.ts.map +1 -0
  182. package/dist/services/revalidate.js +73 -0
  183. package/dist/services/revalidate.js.map +1 -0
  184. package/dist/services/search.d.ts +25 -0
  185. package/dist/services/search.d.ts.map +1 -0
  186. package/dist/services/search.js +88 -0
  187. package/dist/services/search.js.map +1 -0
  188. package/dist/services/serving.d.ts +70 -0
  189. package/dist/services/serving.d.ts.map +1 -0
  190. package/dist/services/serving.js +240 -0
  191. package/dist/services/serving.js.map +1 -0
  192. package/dist/services/status.d.ts +54 -0
  193. package/dist/services/status.d.ts.map +1 -0
  194. package/dist/services/status.js +203 -0
  195. package/dist/services/status.js.map +1 -0
  196. package/dist/services/studio-assets.d.ts +13 -0
  197. package/dist/services/studio-assets.d.ts.map +1 -0
  198. package/dist/services/studio-assets.js +94 -0
  199. package/dist/services/studio-assets.js.map +1 -0
  200. package/dist/services/studio-diagnostics.d.ts +28 -0
  201. package/dist/services/studio-diagnostics.d.ts.map +1 -0
  202. package/dist/services/studio-diagnostics.js +88 -0
  203. package/dist/services/studio-diagnostics.js.map +1 -0
  204. package/dist/services/studio-endpoints.d.ts +61 -0
  205. package/dist/services/studio-endpoints.d.ts.map +1 -0
  206. package/dist/services/studio-endpoints.js +88 -0
  207. package/dist/services/studio-endpoints.js.map +1 -0
  208. package/dist/services/studio-mutations.d.ts +32 -0
  209. package/dist/services/studio-mutations.d.ts.map +1 -0
  210. package/dist/services/studio-mutations.js +149 -0
  211. package/dist/services/studio-mutations.js.map +1 -0
  212. package/dist/services/versions.d.ts +38 -0
  213. package/dist/services/versions.d.ts.map +1 -0
  214. package/dist/services/versions.js +46 -0
  215. package/dist/services/versions.js.map +1 -0
  216. package/dist/services/watch.d.ts +103 -0
  217. package/dist/services/watch.d.ts.map +1 -0
  218. package/dist/services/watch.js +420 -0
  219. package/dist/services/watch.js.map +1 -0
  220. package/package.json +73 -4
  221. package/studio-dist/assets/ibm-plex-mono-latin-400-normal-Dm_PoFIZ.woff2 +0 -0
  222. package/studio-dist/assets/ibm-plex-mono-latin-500-normal-C_OblDzq.woff2 +0 -0
  223. package/studio-dist/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
  224. package/studio-dist/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
  225. package/studio-dist/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
  226. package/studio-dist/assets/index-BuAYbQVX.js +66 -0
  227. package/studio-dist/assets/index-C_3XEUt4.css +1 -0
  228. package/studio-dist/index.html +30 -0
  229. package/README.md +0 -3
@@ -0,0 +1,32 @@
1
+ import { type LoadedConfig } from '@lorepack/core';
2
+ /**
3
+ * The four things Studio can change, and the boundary that keeps them local.
4
+ *
5
+ * **Model-facing MCP tools stay strictly read-only** (architecture 19.4). These are Studio
6
+ * endpoints: loopback-bound, origin-validated, and never registered on a remote deployment.
7
+ * That separation is the whole reason they live here in the CLI rather than in
8
+ * `@lorepack/runtime`, which also compiles for the Worker: a route that does not exist in
9
+ * that package cannot be exposed by it, however the Worker is configured.
10
+ *
11
+ * Every one of them goes through the same code path the CLI uses, so a build activated from
12
+ * a browser and a build activated from a terminal are the same operation with the same
13
+ * pre-flight and the same lock.
14
+ */
15
+ export declare function createBuildsEndpoint(config: LoadedConfig): () => Promise<unknown>;
16
+ /**
17
+ * Moves the active pointer, with the pre-flight that makes it safe.
18
+ *
19
+ * `assertActivatable` runs **before** the pointer moves, so a corrupt build fails with the
20
+ * previous one still serving rather than after it has been made live. Architecture 18.4:
21
+ * activation is a pointer change and never recompiles, which is also why this is quick enough
22
+ * to do from a browser without a progress indicator.
23
+ */
24
+ export declare function createActivateEndpoint(config: LoadedConfig): (request: unknown) => Promise<unknown>;
25
+ /**
26
+ * The previous verified build, chosen the same way `lorepack rollback` chooses it.
27
+ *
28
+ * Rollback is a pointer change that never recompiles, which is what makes it cheap and safe,
29
+ * and is why Studio does not style it as destructive.
30
+ */
31
+ export declare function createRollbackEndpoint(config: LoadedConfig): (request: unknown) => Promise<unknown>;
32
+ //# sourceMappingURL=studio-mutations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"studio-mutations.d.ts","sourceRoot":"","sources":["../../src/services/studio-mutations.ts"],"names":[],"mappings":"AAGA,OAAO,EAAgC,KAAK,YAAY,EAAa,MAAM,gBAAgB,CAAC;AAS5F;;;;;;;;;;;;GAYG;AAEH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,CAsBjF;AAqBD;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,YAAY,GACnB,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAgCxC;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,YAAY,GACnB,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CA2CxC"}
@@ -0,0 +1,149 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { ProjectLock } from '@lorepack/backend-local';
4
+ import { LORE_DIRECTORY, LoreError } from '@lorepack/core';
5
+ import { assertActivatable, buildDirectory, openStateStore, previousBuild, resolveBuildId, } from './builds.js';
6
+ /**
7
+ * The four things Studio can change, and the boundary that keeps them local.
8
+ *
9
+ * **Model-facing MCP tools stay strictly read-only** (architecture 19.4). These are Studio
10
+ * endpoints: loopback-bound, origin-validated, and never registered on a remote deployment.
11
+ * That separation is the whole reason they live here in the CLI rather than in
12
+ * `@lorepack/runtime`, which also compiles for the Worker: a route that does not exist in
13
+ * that package cannot be exposed by it, however the Worker is configured.
14
+ *
15
+ * Every one of them goes through the same code path the CLI uses, so a build activated from
16
+ * a browser and a build activated from a terminal are the same operation with the same
17
+ * pre-flight and the same lock.
18
+ */
19
+ export function createBuildsEndpoint(config) {
20
+ const loreDirectory = join(config.projectRoot, LORE_DIRECTORY);
21
+ return async () => {
22
+ const state = openStateStore(loreDirectory);
23
+ try {
24
+ const active = state.current();
25
+ return {
26
+ activeBuildId: active?.buildId ?? null,
27
+ builds: state.listBuilds().map((build) => ({
28
+ buildId: build.buildId,
29
+ createdAt: build.createdAt,
30
+ state: build.state,
31
+ active: build.buildId === active?.buildId,
32
+ counts: build.counts,
33
+ capabilities: capabilitiesOf(loreDirectory, build.buildId),
34
+ })),
35
+ };
36
+ }
37
+ finally {
38
+ state.close();
39
+ }
40
+ };
41
+ }
42
+ /**
43
+ * A build's capabilities, read from its manifest.
44
+ *
45
+ * The manifest is a small JSON file, so this stays a file read per build rather than opening
46
+ * a database per row. `null` rather than an empty list when it cannot be read: a build whose
47
+ * manifest is missing has unknown capabilities, and an empty list would state that it has
48
+ * none, which is a different and false claim.
49
+ */
50
+ function capabilitiesOf(loreDirectory, buildId) {
51
+ try {
52
+ const manifest = JSON.parse(readFileSync(join(buildDirectory(loreDirectory, buildId), 'manifest.json'), 'utf8'));
53
+ return Array.isArray(manifest.capabilities) ? manifest.capabilities : null;
54
+ }
55
+ catch {
56
+ return null;
57
+ }
58
+ }
59
+ /**
60
+ * Moves the active pointer, with the pre-flight that makes it safe.
61
+ *
62
+ * `assertActivatable` runs **before** the pointer moves, so a corrupt build fails with the
63
+ * previous one still serving rather than after it has been made live. Architecture 18.4:
64
+ * activation is a pointer change and never recompiles, which is also why this is quick enough
65
+ * to do from a browser without a progress indicator.
66
+ */
67
+ export function createActivateEndpoint(config) {
68
+ return async (request) => {
69
+ const reference = readBuildReference(request);
70
+ const loreDirectory = join(config.projectRoot, LORE_DIRECTORY);
71
+ const lock = new ProjectLock(join(loreDirectory, 'lock'));
72
+ const state = openStateStore(loreDirectory);
73
+ try {
74
+ const builds = state.listBuilds();
75
+ const target = resolveBuildId(builds, reference);
76
+ const summary = builds.find((build) => build.buildId === target);
77
+ if (summary === undefined) {
78
+ throw new LoreError('LORE_E_BUILD_NOT_FOUND', `No build ${reference}.`, {
79
+ remediation: 'Choose a build from the history on this page.',
80
+ subject: reference,
81
+ });
82
+ }
83
+ assertActivatable(loreDirectory, summary);
84
+ const active = state.current();
85
+ if (active?.buildId === target) {
86
+ return { buildId: target, generation: active.generation, changed: false };
87
+ }
88
+ // Held only across the pointer change itself, which is one transaction.
89
+ const generation = await lock.withLock(() => state.activate(target));
90
+ return { buildId: target, generation, changed: true };
91
+ }
92
+ finally {
93
+ state.close();
94
+ }
95
+ };
96
+ }
97
+ /**
98
+ * The previous verified build, chosen the same way `lorepack rollback` chooses it.
99
+ *
100
+ * Rollback is a pointer change that never recompiles, which is what makes it cheap and safe,
101
+ * and is why Studio does not style it as destructive.
102
+ */
103
+ export function createRollbackEndpoint(config) {
104
+ return async (request) => {
105
+ const loreDirectory = join(config.projectRoot, LORE_DIRECTORY);
106
+ const lock = new ProjectLock(join(loreDirectory, 'lock'));
107
+ const state = openStateStore(loreDirectory);
108
+ try {
109
+ const builds = state.listBuilds();
110
+ const active = state.current();
111
+ const target = previousBuild(builds, active?.buildId ?? null);
112
+ // Studio names the build it is about to return to, and the history can move between
113
+ // rendering that name and confirming it: a rebuild finishing in the next terminal is
114
+ // enough. Rather than silently acting on a different build than the one confirmed, the
115
+ // stale confirmation is refused and the reader gets to look again.
116
+ const expected = request?.expect;
117
+ if (typeof expected === 'string' && expected !== target) {
118
+ // An argument that no longer holds, rather than a broken build: the caller can fix
119
+ // this by looking again, which is what separates a 400 from a 500.
120
+ throw new LoreError('LORE_E_INVALID_ARGUMENT', 'The build history changed while this confirmation was open.', {
121
+ remediation: `Rolling back now would return to ${target}, not ${expected}. Check the history and confirm again.`,
122
+ subject: expected,
123
+ });
124
+ }
125
+ const summary = builds.find((build) => build.buildId === target);
126
+ if (summary === undefined) {
127
+ throw new LoreError('LORE_E_BUILD_NOT_FOUND', 'There is no earlier build to return to.', {
128
+ remediation: 'Build again, and this project will have a version to roll back to.',
129
+ });
130
+ }
131
+ assertActivatable(loreDirectory, summary);
132
+ const generation = await lock.withLock(() => state.activate(target));
133
+ return { buildId: target, generation, changed: true };
134
+ }
135
+ finally {
136
+ state.close();
137
+ }
138
+ };
139
+ }
140
+ function readBuildReference(request) {
141
+ const build = request?.build;
142
+ if (typeof build !== 'string' || build.trim() === '') {
143
+ throw new LoreError('LORE_E_INVALID_ARGUMENT', 'No build was named.', {
144
+ remediation: 'Send a build id or a unique prefix of one.',
145
+ });
146
+ }
147
+ return build;
148
+ }
149
+ //# sourceMappingURL=studio-mutations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"studio-mutations.js","sourceRoot":"","sources":["../../src/services/studio-mutations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAgB,cAAc,EAAqB,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC5F,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,aAAa,EACb,cAAc,GACf,MAAM,aAAa,CAAC;AAErB;;;;;;;;;;;;GAYG;AAEH,MAAM,UAAU,oBAAoB,CAAC,MAAoB;IACvD,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;IAE/D,OAAO,KAAK,IAAI,EAAE;QAChB,MAAM,KAAK,GAAG,cAAc,CAAC,aAAa,CAAC,CAAC;QAC5C,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;YAC/B,OAAO;gBACL,aAAa,EAAE,MAAM,EAAE,OAAO,IAAI,IAAI;gBACtC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;oBACzC,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,SAAS,EAAE,KAAK,CAAC,SAAS;oBAC1B,KAAK,EAAE,KAAK,CAAC,KAAK;oBAClB,MAAM,EAAE,KAAK,CAAC,OAAO,KAAK,MAAM,EAAE,OAAO;oBACzC,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,YAAY,EAAE,cAAc,CAAC,aAAa,EAAE,KAAK,CAAC,OAAO,CAAC;iBAC3D,CAAC,CAAC;aACJ,CAAC;QACJ,CAAC;gBAAS,CAAC;YACT,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,cAAc,CAAC,aAAqB,EAAE,OAAgB;IAC7D,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CACzB,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,aAAa,EAAE,OAAO,CAAC,EAAE,eAAe,CAAC,EAAE,MAAM,CAAC,CACtD,CAAC;QAChC,OAAO,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAE,QAAQ,CAAC,YAAyB,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3F,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CACpC,MAAoB;IAEpB,OAAO,KAAK,EAAE,OAAO,EAAE,EAAE;QACvB,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;QAC9C,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;QAC/D,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;QAC1D,MAAM,KAAK,GAAG,cAAc,CAAC,aAAa,CAAC,CAAC;QAE5C,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,EAAE,CAAC;YAClC,MAAM,MAAM,GAAG,cAAc,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;YACjD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC;YACjE,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;gBAC1B,MAAM,IAAI,SAAS,CAAC,wBAAwB,EAAE,YAAY,SAAS,GAAG,EAAE;oBACtE,WAAW,EAAE,+CAA+C;oBAC5D,OAAO,EAAE,SAAS;iBACnB,CAAC,CAAC;YACL,CAAC;YAED,iBAAiB,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;YAE1C,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;YAC/B,IAAI,MAAM,EAAE,OAAO,KAAK,MAAM,EAAE,CAAC;gBAC/B,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;YAC5E,CAAC;YAED,wEAAwE;YACxE,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;YACrE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QACxD,CAAC;gBAAS,CAAC;YACT,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CACpC,MAAoB;IAEpB,OAAO,KAAK,EAAE,OAAO,EAAE,EAAE;QACvB,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;QAC/D,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;QAC1D,MAAM,KAAK,GAAG,cAAc,CAAC,aAAa,CAAC,CAAC;QAE5C,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,EAAE,CAAC;YAClC,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,IAAI,IAAI,CAAC,CAAC;YAE9D,oFAAoF;YACpF,qFAAqF;YACrF,uFAAuF;YACvF,mEAAmE;YACnE,MAAM,QAAQ,GAAI,OAAuC,EAAE,MAAM,CAAC;YAClE,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;gBACxD,mFAAmF;gBACnF,mEAAmE;gBACnE,MAAM,IAAI,SAAS,CACjB,yBAAyB,EACzB,6DAA6D,EAC7D;oBACE,WAAW,EAAE,oCAAoC,MAAM,SAAS,QAAQ,wCAAwC;oBAChH,OAAO,EAAE,QAAQ;iBAClB,CACF,CAAC;YACJ,CAAC;YAED,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC;YACjE,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;gBAC1B,MAAM,IAAI,SAAS,CAAC,wBAAwB,EAAE,yCAAyC,EAAE;oBACvF,WAAW,EAAE,oEAAoE;iBAClF,CAAC,CAAC;YACL,CAAC;YACD,iBAAiB,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;YAE1C,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;YACrE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QACxD,CAAC;gBAAS,CAAC;YACT,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,OAAgB;IAC1C,MAAM,KAAK,GAAI,OAAsC,EAAE,KAAK,CAAC;IAC7D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACrD,MAAM,IAAI,SAAS,CAAC,yBAAyB,EAAE,qBAAqB,EAAE;YACpE,WAAW,EAAE,4CAA4C;SAC1D,CAAC,CAAC;IACL,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { SCHEMA_VERSION } from '@lorepack/core';
2
+ /**
3
+ * Versions that affect build output, in one place.
4
+ *
5
+ * The lockfile, the manifest and the build id all read from here, so they cannot disagree
6
+ * about which compiler or parser produced a build.
7
+ */
8
+ export declare const COMPILER_VERSION: '0.1.0';
9
+ /**
10
+ * Re-exported, not declared. It lives in core because the storage backend has to check a
11
+ * build's schema before reading it, and `backend-local` may not import the CLI.
12
+ */
13
+ export { SCHEMA_VERSION };
14
+ /**
15
+ * Every registered parser and its version, derived rather than listed.
16
+ *
17
+ * This was a hand-written literal naming markdown and text until #234, which is how the five
18
+ * parsers Phase 5 added came to be absent from the build id entirely. Bumping the XLSX
19
+ * parser's version and rebuilding a project full of spreadsheets produced a byte-identical
20
+ * build id, so a parser fix could not invalidate the artifacts it changed, and `lorepack diff`
21
+ * saw no difference between two builds whose content differed. Deriving from `PARSERS` makes
22
+ * registering a parser and recording its version one act instead of two.
23
+ *
24
+ * **Every registered parser, not only the ones a project happened to use.** The alternative
25
+ * is tempting, because it means adding a parser to Lorepack cannot disturb the id of a
26
+ * project containing no files of that type. It is rejected for two reasons. The lockfile is
27
+ * written during planning, before anything is parsed, so the contributing set is not known at
28
+ * the point this is needed. And the stability it buys is imaginary: `compilerVersion` is
29
+ * already a build id input, and a release that adds a parser bumps it, so every id moves
30
+ * regardless.
31
+ */
32
+ export declare function parserVersions(): Record<string, string>;
33
+ export declare function lockInputs(): {
34
+ compilerVersion: string;
35
+ schemaVersion: number;
36
+ parserVersions: Record<string, string>;
37
+ };
38
+ //# sourceMappingURL=versions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"versions.d.ts","sourceRoot":"","sources":["../../src/services/versions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGhD;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,EAAG,OAAgB,CAAC;AAEjD;;;GAGG;AACH,OAAO,EAAE,cAAc,EAAE,CAAC;AAE1B;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAIvD;AAED,wBAAgB,UAAU,IAAI;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC,CAMA"}
@@ -0,0 +1,46 @@
1
+ import { SCHEMA_VERSION } from '@lorepack/core';
2
+ import { PARSERS } from '@lorepack/parsers';
3
+ /**
4
+ * Versions that affect build output, in one place.
5
+ *
6
+ * The lockfile, the manifest and the build id all read from here, so they cannot disagree
7
+ * about which compiler or parser produced a build.
8
+ */
9
+ export const COMPILER_VERSION = '0.1.0';
10
+ /**
11
+ * Re-exported, not declared. It lives in core because the storage backend has to check a
12
+ * build's schema before reading it, and `backend-local` may not import the CLI.
13
+ */
14
+ export { SCHEMA_VERSION };
15
+ /**
16
+ * Every registered parser and its version, derived rather than listed.
17
+ *
18
+ * This was a hand-written literal naming markdown and text until #234, which is how the five
19
+ * parsers Phase 5 added came to be absent from the build id entirely. Bumping the XLSX
20
+ * parser's version and rebuilding a project full of spreadsheets produced a byte-identical
21
+ * build id, so a parser fix could not invalidate the artifacts it changed, and `lorepack diff`
22
+ * saw no difference between two builds whose content differed. Deriving from `PARSERS` makes
23
+ * registering a parser and recording its version one act instead of two.
24
+ *
25
+ * **Every registered parser, not only the ones a project happened to use.** The alternative
26
+ * is tempting, because it means adding a parser to Lorepack cannot disturb the id of a
27
+ * project containing no files of that type. It is rejected for two reasons. The lockfile is
28
+ * written during planning, before anything is parsed, so the contributing set is not known at
29
+ * the point this is needed. And the stability it buys is imaginary: `compilerVersion` is
30
+ * already a build id input, and a release that adds a parser bumps it, so every id moves
31
+ * regardless.
32
+ */
33
+ export function parserVersions() {
34
+ const versions = {};
35
+ for (const parser of PARSERS)
36
+ versions[parser.id] = parser.version;
37
+ return versions;
38
+ }
39
+ export function lockInputs() {
40
+ return {
41
+ compilerVersion: COMPILER_VERSION,
42
+ schemaVersion: SCHEMA_VERSION,
43
+ parserVersions: parserVersions(),
44
+ };
45
+ }
46
+ //# sourceMappingURL=versions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"versions.js","sourceRoot":"","sources":["../../src/services/versions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE5C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,OAAgB,CAAC;AAEjD;;;GAGG;AACH,OAAO,EAAE,cAAc,EAAE,CAAC;AAE1B;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAC5C,KAAK,MAAM,MAAM,IAAI,OAAO;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC;IACnE,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,UAAU;IAKxB,OAAO;QACL,eAAe,EAAE,gBAAgB;QACjC,aAAa,EAAE,cAAc;QAC7B,cAAc,EAAE,cAAc,EAAE;KACjC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,103 @@
1
+ import { type LoadedConfig, type SourceState } from '@lorepack/core';
2
+ /**
3
+ * Watching the sources, where the watcher is an accelerator and never the truth.
4
+ *
5
+ * Architecture 24.5 is blunt about this and 12.11 encodes it as an algorithm: filesystem
6
+ * events are a hint that something *may* have changed, and content hashes decide whether
7
+ * anything did. Every step below exists because some real editor or filesystem breaks the
8
+ * naive version:
9
+ *
10
+ * 1. the initial scan is the build the supervisor already ran;
11
+ * 2. start the watcher;
12
+ * 3. **reconcile after `ready`**, because a file written between the scan and the watcher
13
+ * becoming ready belongs to neither and would be missed forever;
14
+ * 4. coalesce events over a debounce window, since one save is many events;
15
+ * 5. wait for size and modification time to stop moving, because editors write in chunks
16
+ * and a hash taken mid-write is a hash of half a file;
17
+ * 6. fingerprint the content;
18
+ * 7. do nothing when the content is unchanged, which is what a touch or an atomic rename
19
+ * of identical bytes produces;
20
+ * 8. build a candidate;
21
+ * 9. activate only after validation, which `runBuild` already guarantees.
22
+ *
23
+ * The watcher also answers `freshness()` for the server, which is the hook #112 named: a
24
+ * supervisor that is already watching knows whether the sources moved, so the server it
25
+ * supervises should stop paying for an interval scan to find out.
26
+ */
27
+ export interface WatchOptions {
28
+ readonly config: LoadedConfig;
29
+ /**
30
+ * Builds and activates. Given a signal that aborts when a newer change arrives, so a
31
+ * superseded candidate is cancelled rather than finished and thrown away.
32
+ */
33
+ readonly rebuild: (signal: AbortSignal) => Promise<{
34
+ readonly created: boolean;
35
+ }>;
36
+ readonly warn: (text: string) => void;
37
+ /** How long to coalesce events before acting. */
38
+ readonly debounceMs?: number;
39
+ /** How long size and mtime must hold still before the content is trusted. */
40
+ readonly stabilityMs?: number;
41
+ /** Polling interval for the stability wait. */
42
+ readonly pollMs?: number;
43
+ /**
44
+ * How often to reconcile from disk regardless of what the event stream said.
45
+ *
46
+ * Architecture 12.3 and #54's design notes: a periodic full reconciliation catches missed
47
+ * events without polling constantly. It is cheap because it prescreens on sizes and
48
+ * modification times and only hashes when that moved.
49
+ *
50
+ * This is not belt and braces. Windows delivered no usable event for an ordinary append
51
+ * in CI, and a watcher whose correctness depends on the event stream would simply have
52
+ * gone on serving the old build. The stream is an accelerator; this is the floor.
53
+ */
54
+ readonly reconcileIntervalMs?: number;
55
+ }
56
+ export interface Watching {
57
+ /**
58
+ * Freshness from watcher state, costing no filesystem work.
59
+ *
60
+ * This is the whole point of handing it to the server. The polling revalidator exists
61
+ * because `lorepack serve` has no better information; a supervisor that is watching does.
62
+ */
63
+ freshness(): Promise<SourceState>;
64
+ close(): Promise<void>;
65
+ /** Resolves once the watcher is ready and the reconciliation scan has finished. */
66
+ readonly ready: Promise<void>;
67
+ /** Rebuilds actually performed, for the tests that assert one save is one rebuild. */
68
+ readonly rebuilds: number;
69
+ /** Times a change turned out to be no change, which is a visible outcome, not a silence. */
70
+ readonly noOps: number;
71
+ /**
72
+ * What the watcher is doing right now, for Studio's Diagnostics route.
73
+ *
74
+ * Useful precisely when something feels stuck: "the watcher saw your edit four seconds ago
75
+ * and the last rebuild took 90 ms" and "the watcher has seen nothing since you started"
76
+ * are different problems, and without this they look identical from the browser.
77
+ */
78
+ status(): WatchStatus;
79
+ }
80
+ export interface WatchStatus {
81
+ readonly state: SourceState;
82
+ /** Files currently watched, as chokidar counts them. */
83
+ readonly watchedPaths: number;
84
+ readonly lastEventAt: string | null;
85
+ readonly lastRebuild: {
86
+ readonly at: string;
87
+ readonly durationMs: number;
88
+ /** False when the rebuild found nothing to change, which is a result, not a failure. */
89
+ readonly created: boolean;
90
+ readonly failed: boolean;
91
+ } | null;
92
+ readonly rebuilds: number;
93
+ readonly noOps: number;
94
+ }
95
+ export declare const WATCH_DEFAULTS: {
96
+ readonly debounceMs: 150;
97
+ readonly stabilityMs: 120;
98
+ readonly pollMs: 40;
99
+ readonly reconcileIntervalMs: 2000;
100
+ };
101
+ export declare function startWatching(options: WatchOptions): Watching;
102
+ export declare function resolveRealPath(path: string): string;
103
+ //# sourceMappingURL=watch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/services/watch.ts"],"names":[],"mappings":"AAGA,OAAO,EAAgC,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAKnG;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC;QAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAClF,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,iDAAiD;IACjD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,6EAA6E;IAC7E,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,+CAA+C;IAC/C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;CACvC;AAED,MAAM,WAAW,QAAQ;IACvB;;;;;OAKG;IACH,SAAS,IAAI,OAAO,CAAC,WAAW,CAAC,CAAC;IAClC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,mFAAmF;IACnF,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,sFAAsF;IACtF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,4FAA4F;IAC5F,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;;;;;;OAMG;IACH,MAAM,IAAI,WAAW,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,wDAAwD;IACxD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,WAAW,EAAE;QACpB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;QAC5B,wFAAwF;QACxF,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;QAC1B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;KAC1B,GAAG,IAAI,CAAC;IACT,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,cAAc;aACzB,UAAU,EAAE,GAAG;aACf,WAAW,EAAE,GAAG;aAChB,MAAM,EAAE,EAAE;aACV,mBAAmB,EAAE,IAAI;CACjB,CAAC;AAEX,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,QAAQ,CAkT7D;AAgHD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMpD"}