@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,248 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { createPlan, readLockfile, renderPlan } from '@lorepack/compiler';
4
+ import { buildManifestSchema, LORE_DIRECTORY, LoreError, loadConfig, } from '@lorepack/core';
5
+ import { runBuild } from '../services/build.js';
6
+ import { buildDirectory as localBuildDirectory } from '../services/builds.js';
7
+ import { resolveCloudflareTarget, resolveCloudflareTargetWithAdapter, } from '../services/cloudflare-target.js';
8
+ import { readReceipt, receiptPath, runDeploy } from '../services/deploy.js';
9
+ import { readActiveBuild, readPreviousBuild } from '../services/project.js';
10
+ import { readStatus } from '../services/status.js';
11
+ import { lockInputs } from '../services/versions.js';
12
+ const TEST_ALLOW_HOOKS_ENV = 'LORE_TEST_ALLOW_HOOKS';
13
+ const TEST_FAIL_AFTER_PROJECT_ENV = 'LORE_TEST_FAIL_DEPLOY_AFTER_PROJECT';
14
+ export function deployCommand(options = {}) {
15
+ return {
16
+ name: 'deploy',
17
+ description: 'Project a build onto a remote target and activate it after verification.',
18
+ arguments: [{ name: 'target', description: 'which target to deploy to', required: false }],
19
+ flags: [
20
+ { flags: '--dry-run', description: 'show the deploy plan and change nothing remotely' },
21
+ { flags: '--no-build', description: 'refuse when sources are dirty or unbuilt' },
22
+ { flags: '--yes', description: 'apply without asking' },
23
+ { flags: '--resume <receipt-id>', description: 'continue an interrupted deploy' },
24
+ {
25
+ flags: '--allow-capability-loss <capability>',
26
+ description: 'accept one named capability the target cannot serve',
27
+ },
28
+ ],
29
+ handler: async (args, flags, context) => {
30
+ const config = loadConfig({ cwd: context.options.cwd });
31
+ const targetName = resolveTargetName(args[0]);
32
+ const target = options.resolveTarget === undefined
33
+ ? await resolveTarget(targetName, config.projectRoot, config.configPath, options.cloudflareAdapter)
34
+ : await options.resolveTarget(targetName, {
35
+ projectRoot: config.projectRoot,
36
+ configPath: config.configPath,
37
+ });
38
+ const resume = typeof flags.resume === 'string'
39
+ ? readReceipt(config.projectRoot, flags.resume)
40
+ : undefined;
41
+ if (resume !== undefined && resume.target !== target.id) {
42
+ throw new LoreError('LORE_E_INVALID_ARGUMENT', `Receipt ${resume.receiptId} belongs to ${resume.target}, not ${target.id}.`, {
43
+ remediation: `Resume with \`lorepack deploy ${resume.target} --resume ${resume.receiptId}\`, or start a new deploy.`,
44
+ subject: resume.receiptId,
45
+ });
46
+ }
47
+ const preparation = await prepareBuild({
48
+ configRoot: config.projectRoot,
49
+ config,
50
+ flags,
51
+ context,
52
+ ...(resume === undefined ? {} : { resume }),
53
+ });
54
+ const deployPlan = await target.plan({
55
+ projectName: config.config.name,
56
+ buildId: preparation.buildId,
57
+ buildDirectory: preparation.buildDirectory,
58
+ buildCapabilities: preparation.buildCapabilities,
59
+ });
60
+ const planLines = [...preparation.localPlanLines, renderDeployPlan(deployPlan)].filter((line) => line !== '');
61
+ const planText = planLines.join('\n\n');
62
+ if (flags.yes !== true && flags.dryRun !== true) {
63
+ const confirmed = await (options.confirm ?? confirmDeploy)(planText, context);
64
+ if (!confirmed)
65
+ return { human: `${planText}\n\nCancelled. Nothing was changed.` };
66
+ }
67
+ const accepted = normalizeCapabilityLoss(flags.allowCapabilityLoss);
68
+ const afterProject = testAfterProjectHookFromEnv();
69
+ const result = await runDeploy({
70
+ target,
71
+ projectRoot: config.projectRoot,
72
+ projectName: config.config.name,
73
+ buildId: preparation.buildId,
74
+ buildDirectory: preparation.buildDirectory,
75
+ buildCapabilities: preparation.buildCapabilities,
76
+ plan: deployPlan,
77
+ progress: context.progress,
78
+ dryRun: flags.dryRun === true,
79
+ ...(afterProject === undefined ? {} : { afterProject }),
80
+ ...(resume === undefined ? {} : { resume }),
81
+ ...(accepted.length === 0 ? {} : { allowCapabilityLoss: accepted }),
82
+ }).catch((error) => {
83
+ const original = LoreError.from(error);
84
+ const receiptId = error instanceof LoreError && typeof error.details?.receiptId === 'string'
85
+ ? error.details.receiptId
86
+ : resume?.receiptId;
87
+ if (receiptId === undefined)
88
+ throw error;
89
+ throw new LoreError('LORE_E_REMOTE_DEPLOY', original.message, {
90
+ remediation: `${original.remediation ?? 'The previous remote build is still serving.'} Resume with \`lorepack deploy ${target.id} --resume ${receiptId}\`.`,
91
+ ...(original.details === undefined ? {} : { details: original.details }),
92
+ ...(original.subject === undefined ? {} : { subject: original.subject }),
93
+ ...(original.cause === undefined ? {} : { cause: original.cause }),
94
+ });
95
+ });
96
+ return {
97
+ human: `${planText}\n\n${renderDeployResult(config.projectRoot, result.receipt, result.dryRun)}`,
98
+ json: result.receipt,
99
+ };
100
+ },
101
+ };
102
+ }
103
+ async function prepareBuild(options) {
104
+ if (options.resume !== undefined) {
105
+ return readBuildInputs(options.configRoot, options.resume.buildId);
106
+ }
107
+ const status = await readStatus({ config: options.config, progress: options.context.progress });
108
+ const noBuild = options.flags.build === false;
109
+ const needsBuild = status.sourceState === 'dirty' || status.sourceState === 'unbuilt';
110
+ if (needsBuild && noBuild) {
111
+ throw new LoreError('LORE_E_INVALID_ARGUMENT', 'The sources are not already built, and --no-build was given.', {
112
+ remediation: status.sourceState === 'unbuilt'
113
+ ? 'Run `lorepack build`, or omit `--no-build` so `lorepack deploy` can build first.'
114
+ : 'Run `lorepack build`, or omit `--no-build` so `lorepack deploy` can rebuild first.',
115
+ });
116
+ }
117
+ const localPlanLines = [];
118
+ if (needsBuild) {
119
+ const { state, previous } = readPreviousBuild(options.config);
120
+ try {
121
+ const local = await createPlan({
122
+ config: options.config,
123
+ previous,
124
+ previousLock: readLockfile(options.config.projectRoot),
125
+ lockInputs: lockInputs(),
126
+ progress: options.context.progress,
127
+ });
128
+ localPlanLines.push(renderPlan(local.plan));
129
+ }
130
+ finally {
131
+ state?.close();
132
+ }
133
+ const built = await runBuild({
134
+ config: options.config,
135
+ progress: options.context.progress,
136
+ activate: true,
137
+ ...(options.context.signal === undefined ? {} : { signal: options.context.signal }),
138
+ });
139
+ return {
140
+ ...readBuildInputs(options.configRoot, built.buildId),
141
+ localPlanLines,
142
+ };
143
+ }
144
+ const active = readActiveBuild(join(options.config.projectRoot, LORE_DIRECTORY));
145
+ if (active === null) {
146
+ throw new LoreError('LORE_E_BUILD_NOT_FOUND', 'This project has no active build to deploy.', {
147
+ remediation: 'Run `lorepack build` first, or omit `--no-build` so `lorepack deploy` can build one.',
148
+ });
149
+ }
150
+ return {
151
+ ...readBuildInputs(options.configRoot, active.buildId),
152
+ localPlanLines,
153
+ };
154
+ }
155
+ function readBuildInputs(projectRoot, buildId) {
156
+ const loreDirectory = join(projectRoot, LORE_DIRECTORY);
157
+ const buildDirectory = localBuildDirectory(loreDirectory, buildId);
158
+ const manifestPath = join(buildDirectory, 'manifest.json');
159
+ if (!existsSync(manifestPath)) {
160
+ throw new LoreError('LORE_E_BUILD_NOT_FOUND', `Build ${buildId} has no manifest.`, {
161
+ remediation: 'Run `lorepack build` again to recreate it before deploying.',
162
+ subject: buildId,
163
+ });
164
+ }
165
+ const manifest = buildManifestSchema.parse(JSON.parse(readFileSync(manifestPath, 'utf8')));
166
+ return {
167
+ buildId,
168
+ buildDirectory,
169
+ buildCapabilities: manifest.capabilities,
170
+ localPlanLines: [],
171
+ };
172
+ }
173
+ function testAfterProjectHookFromEnv() {
174
+ if (process.env[TEST_ALLOW_HOOKS_ENV] !== '1')
175
+ return undefined;
176
+ if (process.env[TEST_FAIL_AFTER_PROJECT_ENV] !== '1')
177
+ return undefined;
178
+ return (receipt) => {
179
+ throw new LoreError('LORE_E_REMOTE_DEPLOY', 'Forced test failure after candidate projection.', {
180
+ remediation: 'This test hook stops the deploy after candidate projection. Resume with the recorded receipt id.',
181
+ details: { receiptId: receipt.receiptId },
182
+ });
183
+ };
184
+ }
185
+ function renderDeployPlan(plan) {
186
+ const lines = [
187
+ `Target: ${plan.display?.targetLabel ?? plan.target}`,
188
+ `Build: ${plan.input.buildId}`,
189
+ ];
190
+ if (plan.display === undefined) {
191
+ lines.push(`Capabilities: ${plan.input.buildCapabilities.join(', ')}`);
192
+ }
193
+ lines.push('', 'Resources', ...prefixPlanLines(plan.display?.resourceLines ?? ['Resolved by the selected deployment target.']), '', 'Projection', ...prefixPlanLines(plan.display?.projectionLines ?? [
194
+ 'Project the sealed build as a candidate and verify it before activation.',
195
+ ]), '', 'Activation', ...prefixPlanLines(plan.display?.activationLines ?? [
196
+ 'Switch the active pointer only after candidate verification and smoke confirmation.',
197
+ ]));
198
+ return lines.join('\n');
199
+ }
200
+ function prefixPlanLines(lines) {
201
+ return lines.map((line) => ` ${line}`);
202
+ }
203
+ function renderDeployResult(projectRoot, receipt, dryRun) {
204
+ if (dryRun) {
205
+ return ['Dry run only. Nothing remote was changed.', `Receipt id: ${receipt.receiptId}`].join('\n');
206
+ }
207
+ return [
208
+ `Deployed ${receipt.buildId} to ${receipt.target}.`,
209
+ `Endpoint: ${receipt.endpoint ?? 'unknown'}`,
210
+ `Active build: ${receipt.buildId}`,
211
+ `Receipt: ${receiptPath(projectRoot, receipt.receiptId)}`,
212
+ ].join('\n');
213
+ }
214
+ function normalizeCapabilityLoss(raw) {
215
+ if (raw === undefined)
216
+ return [];
217
+ if (Array.isArray(raw))
218
+ return raw.map((value) => String(value));
219
+ return [String(raw)];
220
+ }
221
+ function resolveTargetName(raw) {
222
+ return raw === undefined || raw.trim() === '' ? 'cloudflare' : raw.trim();
223
+ }
224
+ async function resolveTarget(name, projectRoot, _configPath, cloudflareAdapter) {
225
+ if (name !== 'cloudflare') {
226
+ throw new LoreError('LORE_E_INVALID_ARGUMENT', `Unknown deploy target ${name}.`, {
227
+ remediation: 'Use `cloudflare`. Additional targets are not implemented in v0.1.',
228
+ subject: name,
229
+ });
230
+ }
231
+ return cloudflareAdapter === undefined
232
+ ? await resolveCloudflareTarget(projectRoot)
233
+ : await resolveCloudflareTargetWithAdapter(projectRoot, cloudflareAdapter);
234
+ }
235
+ async function confirmDeploy(plan, context) {
236
+ if (!context.streams.isTty) {
237
+ throw new LoreError('LORE_E_INVALID_ARGUMENT', 'Deploy confirmation requires a terminal when --yes is not given.', {
238
+ remediation: 'Re-run with `--yes` in CI or another non-interactive environment.',
239
+ });
240
+ }
241
+ context.write(`${plan}\n\nDeploy this build? [y/N] `);
242
+ const answer = await new Promise((resolve) => {
243
+ process.stdin.setEncoding('utf8');
244
+ process.stdin.once('data', (chunk) => resolve(String(chunk)));
245
+ });
246
+ return /^y(es)?\s*$/i.test(answer.trim());
247
+ }
248
+ //# sourceMappingURL=deploy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { CommandDefinition } from '../framework/program.js';
2
+ /**
3
+ * `lorepack dev [path]`: a folder becomes a running, connected context runtime, asking nothing.
4
+ *
5
+ * This is the headline command (architecture 2.2, 6.2), and its whole design is an ordering
6
+ * decision: **validate, then inspect, then mutate**. Section 6.2 lists the seven steps in
7
+ * that order for a reason. A run that discovers on step five that this Node build has no
8
+ * FTS5 has already written files into someone's directory to learn it.
9
+ *
10
+ * So the order below is load-bearing rather than incidental:
11
+ *
12
+ * 1. capability validation, which touches nothing;
13
+ * 2. inspection, which reads the directory and writes nothing;
14
+ * 3. atomic init, which writes and says exactly what it wrote;
15
+ * 4. build and activate;
16
+ * 5. serve;
17
+ * 6. print how to connect.
18
+ *
19
+ * It supervises rather than reimplements. Init comes from the same module `lorepack init` uses,
20
+ * the build from the same `runBuild` that `lorepack build` calls, and the server from
21
+ * `services/serving.ts`, which is where `lorepack serve` gets it too. A second implementation of
22
+ * any of them would be a second behaviour for a user to discover.
23
+ */
24
+ export declare function devCommand(): CommandDefinition;
25
+ //# sourceMappingURL=dev.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,yBAAyB,CAAC;AAYhF;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,wBAAgB,UAAU,IAAI,iBAAiB,CAoG9C"}
@@ -0,0 +1,227 @@
1
+ import { isAbsolute, resolve } from 'node:path';
2
+ import { assertFts5Available } from '@lorepack/backend-local';
3
+ import { count, LoreError, loadConfig } from '@lorepack/core';
4
+ import { runBuild } from '../services/build.js';
5
+ import { assertNoLiveSession, DEV_PORT, removeReceipt, writeReceipt, } from '../services/dev-session.js';
6
+ import { enclosingProject, planInit, runInit } from '../services/init.js';
7
+ import { parsePort, startServing, untilInterrupted } from '../services/serving.js';
8
+ import { startWatching } from '../services/watch.js';
9
+ /**
10
+ * `lorepack dev [path]`: a folder becomes a running, connected context runtime, asking nothing.
11
+ *
12
+ * This is the headline command (architecture 2.2, 6.2), and its whole design is an ordering
13
+ * decision: **validate, then inspect, then mutate**. Section 6.2 lists the seven steps in
14
+ * that order for a reason. A run that discovers on step five that this Node build has no
15
+ * FTS5 has already written files into someone's directory to learn it.
16
+ *
17
+ * So the order below is load-bearing rather than incidental:
18
+ *
19
+ * 1. capability validation, which touches nothing;
20
+ * 2. inspection, which reads the directory and writes nothing;
21
+ * 3. atomic init, which writes and says exactly what it wrote;
22
+ * 4. build and activate;
23
+ * 5. serve;
24
+ * 6. print how to connect.
25
+ *
26
+ * It supervises rather than reimplements. Init comes from the same module `lorepack init` uses,
27
+ * the build from the same `runBuild` that `lorepack build` calls, and the server from
28
+ * `services/serving.ts`, which is where `lorepack serve` gets it too. A second implementation of
29
+ * any of them would be a second behaviour for a user to discover.
30
+ */
31
+ export function devCommand() {
32
+ return {
33
+ name: 'dev',
34
+ description: 'Turn a folder into a running context runtime. Builds, serves, and connects.',
35
+ arguments: [{ name: 'path', description: 'project directory (default: .)', required: false }],
36
+ flags: [
37
+ { flags: '--port <number>', description: `port to listen on (default ${DEV_PORT})` },
38
+ { flags: '--host <address>', description: 'address to bind (default 127.0.0.1)' },
39
+ {
40
+ flags: '--yes',
41
+ description: 'accept defaults without asking (the default path asks nothing)',
42
+ },
43
+ { flags: '--allow-large-project', description: 'continue past the supported file count' },
44
+ ],
45
+ handler: async (args, flags, context) => {
46
+ const directory = resolveDirectory(args[0], context);
47
+ // Step 1. Before anything is written. Node itself is checked in the entry point, which
48
+ // is earlier still; this is the capability that a supported Node can nonetheless lack,
49
+ // because a build linked against a shared SQLite may omit FTS5.
50
+ assertFts5Available();
51
+ // Steps 2 and 3. `planInit` reads and writes nothing, so a directory that cannot be
52
+ // initialized is refused before it is touched.
53
+ const initialized = autoInit(directory, context);
54
+ const config = loadConfig({ cwd: directory });
55
+ // Before building or binding anything: two supervisors on one project would both
56
+ // watch, both rebuild, and take turns losing the build lock. A receipt whose process
57
+ // is gone is cleared here rather than treated as an obstacle.
58
+ assertNoLiveSession(config);
59
+ // Step 4. The same builder `lorepack build` runs, with its stage table on the same bus, so
60
+ // a slow parse shows a moving count here exactly as it does there (architecture 6.4).
61
+ const built = await runBuild({
62
+ config,
63
+ progress: context.progress,
64
+ activate: true,
65
+ allowLargeProject: flags.allowLargeProject === true,
66
+ ...(context.signal === undefined ? {} : { signal: context.signal }),
67
+ });
68
+ // Step 5. Watching starts before serving, so the server can be handed the watcher's
69
+ // answer about freshness instead of polling for it. Architecture 12.11 step 3 runs
70
+ // inside this: a reconciliation scan once the watcher is ready, closing the race
71
+ // between the build above and the first event below.
72
+ const watching = startWatching({
73
+ config,
74
+ warn: context.warn,
75
+ rebuild: async (signal) => {
76
+ const result = await runBuild({
77
+ config,
78
+ progress: context.progress,
79
+ activate: true,
80
+ signal,
81
+ });
82
+ return { created: result.created };
83
+ },
84
+ });
85
+ const host = typeof flags.host === 'string' ? flags.host : '127.0.0.1';
86
+ const server = await startServing({
87
+ config,
88
+ host,
89
+ // Architecture 15.3 fixes the preferred dev port, which is not the one `lorepack serve`
90
+ // uses: a dev session and a read-only server are different things and a developer
91
+ // may want both at once.
92
+ port: flags.port === undefined ? DEV_PORT : parsePort(flags.port),
93
+ warn: context.warn,
94
+ studio: true,
95
+ // The hook #112 named. A supervisor that is watching the filesystem already knows
96
+ // whether the sources moved, so the server stops paying for an interval scan.
97
+ freshness: () => watching.freshness(),
98
+ // The same knowledge, in full, for Studio's Diagnostics route. "Nothing has happened
99
+ // since you started" and "your edit was seen and the rebuild failed" look identical
100
+ // from a browser without it.
101
+ watchStatus: () => watching.status(),
102
+ });
103
+ // Written once the port is known and the build is activated, so it never advertises a
104
+ // session that does not exist yet.
105
+ writeReceipt(config, {
106
+ port: server.port,
107
+ pid: process.pid,
108
+ startedAt: new Date().toISOString(),
109
+ buildId: server.buildId,
110
+ host,
111
+ });
112
+ // Step 6.
113
+ context.write(`${render({ initialized, built, url: server.url, studio: server.studio, projectRoot: config.projectRoot, name: config.config.name })}\n`);
114
+ await untilInterrupted(context.warn);
115
+ await shutdown(config, watching, server, context.warn);
116
+ return { human: '', json: undefined };
117
+ },
118
+ };
119
+ }
120
+ /** How long a drain may take before the process stops waiting for it. */
121
+ const SHUTDOWN_TIMEOUT_MS = 10_000;
122
+ /**
123
+ * The documented stop sequence, in order, with a bound on the whole thing.
124
+ *
125
+ * The order is the correctness argument. The watcher goes first so a rebuild in flight is
126
+ * cancelled and its candidate discarded before anything else moves: `runBuild` removes its
127
+ * own incomplete candidate, so activation never sees it and the build that was active
128
+ * stays active (architecture 6.9). The server drains next, finishing requests already in
129
+ * flight rather than cutting them off. Only then are the databases released, because a
130
+ * request still running would otherwise reach a closed handle.
131
+ *
132
+ * The receipt is removed last and unconditionally. A session that is stopping has already
133
+ * stopped being useful to anyone reading it, and leaving one behind makes the next
134
+ * `lorepack dev` refuse to start for a process that no longer exists.
135
+ *
136
+ * The timeout exists because a wedged request must not be able to hold the process open
137
+ * forever. Section 15.3's contract is that Ctrl-C ends the session; it does not promise to
138
+ * wait indefinitely for a socket that will never close.
139
+ */
140
+ async function shutdown(config, watching, server, warn) {
141
+ const bounded = async () => {
142
+ await watching.close();
143
+ await server.close();
144
+ };
145
+ try {
146
+ await Promise.race([
147
+ bounded(),
148
+ new Promise((_, reject) => setTimeout(() => reject(new Error('timed out')), SHUTDOWN_TIMEOUT_MS)),
149
+ ]);
150
+ }
151
+ catch {
152
+ warn(`Shutdown took longer than ${SHUTDOWN_TIMEOUT_MS} ms. Exiting anyway.\n`);
153
+ }
154
+ finally {
155
+ removeReceipt(config);
156
+ }
157
+ }
158
+ /**
159
+ * Writes the configuration a project needs, only when it does not have one.
160
+ *
161
+ * Returns null when the project was already configured, which is the re-run path: section
162
+ * 6.2 promises a second `lorepack dev` skips init and rebuilds only what changed, and the build
163
+ * step below is already incremental, so there is nothing else to do about it.
164
+ */
165
+ function autoInit(directory, context) {
166
+ const planned = planInit({ directory, force: false });
167
+ if (planned.alreadyInitialized)
168
+ return null;
169
+ // Refused for the same reason `lorepack init` refuses it: a project inside a project produces
170
+ // two builds over overlapping sources, and neither is wrong in a way anyone can see.
171
+ const enclosing = enclosingProject(directory);
172
+ if (enclosing !== null) {
173
+ throw new LoreError('LORE_E_INVALID_ARGUMENT', `${directory} is already inside a Lorepack project rooted at ${enclosing}.`, {
174
+ remediation: 'Nested projects are not supported. Run `lorepack dev` in the existing project instead.',
175
+ });
176
+ }
177
+ const result = runInit({ directory, force: false });
178
+ if (result.written.length > 0) {
179
+ // Section 6.2 step 4 makes this an answer, not a diagnostic: someone pointed a command
180
+ // at their directory and is owed a plain list of what appeared in it. So stdout, above
181
+ // the stage table, in the order it happened.
182
+ context.write(`Created:\n${result.written.map((file) => ` + ${file}`).join('\n')}\n\n`);
183
+ }
184
+ return result;
185
+ }
186
+ /**
187
+ * The first-run block of architecture 6.4, containing every line whose subject exists.
188
+ *
189
+ * The Studio line arrived with #64 and is printed only when the assets are actually there.
190
+ * A package installed without them is a broken install rather than a mode, and printing a
191
+ * URL that answers 404 would be worse than saying nothing.
192
+ *
193
+ * The `Connect now` list names the connectors that exist, and nothing else. Codex arrived
194
+ * with #80 and VS Code with #81. #53 carries the amendment recording this.
195
+ */
196
+ function render(rendered) {
197
+ const { built } = rendered;
198
+ const lines = ['', `Build ${built.buildId.slice(0, 17)}`];
199
+ lines.push(built.reusedArtifacts === 0
200
+ ? `Reused 0 artifacts (first build)`
201
+ : `Reused ${count(built.reusedArtifacts, 'artifact')}`);
202
+ if (built.warnings > 0) {
203
+ lines.push(`Warnings ${count(built.warnings, 'warning')}; run \`lorepack inspect warnings\``);
204
+ }
205
+ // Studio first, because it is the line a person opens. The order matches 6.4.
206
+ if (rendered.studio)
207
+ lines.push(`Studio ${rendered.url}`);
208
+ lines.push(`HTTP ${rendered.url}/v1`);
209
+ lines.push(`MCP HTTP ${rendered.url}/mcp`);
210
+ // Quoted, because a project path with a space in it is ordinary on every platform and the
211
+ // line is meant to be pasted (#61 owns the general version of this).
212
+ lines.push(`MCP stdio lorepack mcp --project "${rendered.projectRoot}"`);
213
+ lines.push('');
214
+ lines.push('Connect now:');
215
+ lines.push(' lorepack connect claude-code');
216
+ lines.push(' lorepack connect codex');
217
+ lines.push(' lorepack connect vscode');
218
+ lines.push('');
219
+ lines.push('Watching for changes. Press Ctrl-C to stop.');
220
+ return lines.join('\n');
221
+ }
222
+ function resolveDirectory(argument, context) {
223
+ if (argument === undefined)
224
+ return context.options.cwd;
225
+ return isAbsolute(argument) ? resolve(argument) : resolve(context.options.cwd, argument);
226
+ }
227
+ //# sourceMappingURL=dev.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { CommandDefinition } from '../framework/program.js';
2
+ export declare function diffCommand(): CommandDefinition;
3
+ //# sourceMappingURL=diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/commands/diff.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,yBAAyB,CAAC;AAGhF,wBAAgB,WAAW,IAAI,iBAAiB,CA2C/C"}
@@ -0,0 +1,75 @@
1
+ import { join } from 'node:path';
2
+ import { diffBuilds, renderDiff } from '@lorepack/compiler';
3
+ import { LORE_DIRECTORY, LoreError, loadConfig } from '@lorepack/core';
4
+ import { openStateStore, readSnapshot, resolveBuildId } from '../services/builds.js';
5
+ export function diffCommand() {
6
+ return {
7
+ name: 'diff',
8
+ description: 'Compare two builds. Reads build data only, never the sources.',
9
+ arguments: [
10
+ { name: 'from', description: 'build to compare from', required: false },
11
+ { name: 'to', description: 'build to compare to', required: false },
12
+ ],
13
+ handler: (args, _flags, context) => {
14
+ const config = loadConfig({ cwd: context.options.cwd });
15
+ const loreDirectory = join(config.projectRoot, LORE_DIRECTORY);
16
+ const state = openStateStore(loreDirectory);
17
+ try {
18
+ const builds = state.listBuilds();
19
+ const active = state.current();
20
+ const [fromReference, toReference] = args;
21
+ // No arguments compares the active build against its neighbour in history; one
22
+ // argument compares that build to the active one. Both are the question a user
23
+ // actually has.
24
+ const history = builds.map((build) => build.buildId);
25
+ const { from, to } = fromReference === undefined && toReference === undefined
26
+ ? neighbourOf(history, active?.buildId ?? firstOr(history.at(0)))
27
+ : {
28
+ to: toReference !== undefined
29
+ ? resolveBuildId(builds, toReference)
30
+ : (active?.buildId ?? firstOr(history.at(0))),
31
+ from: fromReference !== undefined
32
+ ? resolveBuildId(builds, fromReference)
33
+ : (active?.buildId ?? firstOr(history.at(0))),
34
+ };
35
+ const diff = diffBuilds(readSnapshot(loreDirectory, from), readSnapshot(loreDirectory, to));
36
+ return { human: renderDiff(diff), json: diff };
37
+ }
38
+ finally {
39
+ state.close();
40
+ }
41
+ },
42
+ };
43
+ }
44
+ function firstOr(buildId) {
45
+ if (buildId === undefined) {
46
+ throw new LoreError('LORE_E_BUILD_NOT_FOUND', 'This project has no builds to compare.', {
47
+ remediation: 'Run `lorepack build` to create one.',
48
+ });
49
+ }
50
+ return buildId;
51
+ }
52
+ /**
53
+ * The pair a bare `lorepack diff` compares: the active build and the build beside it.
54
+ *
55
+ * History is newest first, so ordinarily that is the build after the target, and the diff
56
+ * reads "what the last build changed". After a rollback the active build is the oldest, and
57
+ * there is nothing after it. That used to be reported as "there is only one build", which
58
+ * `lorepack builds` contradicted on the line above (#176), and the suggested fix was to change
59
+ * a source when the build the user wanted already existed.
60
+ *
61
+ * So it looks the other way instead, and the diff reads "what moving forward would change".
62
+ * Both directions answer the same question, which is what the neighbouring build differs by,
63
+ * and the rendering names both ids so the direction is never guessed.
64
+ */
65
+ function neighbourOf(history, target) {
66
+ const index = history.indexOf(target);
67
+ const older = index === -1 ? undefined : history[index + 1];
68
+ if (older !== undefined)
69
+ return { from: older, to: target };
70
+ const newer = index <= 0 ? undefined : history[index - 1];
71
+ if (newer !== undefined)
72
+ return { from: target, to: newer };
73
+ throw new LoreError('LORE_E_BUILD_NOT_FOUND', 'There is only one build, so there is nothing to compare it against.', { remediation: 'Change a source and run `lorepack build`, then diff again.' });
74
+ }
75
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/commands/diff.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { CommandDefinition } from '../framework/program.js';
2
+ /**
3
+ * `lorepack doctor`: when something is wrong, one command names it and says what to do.
4
+ *
5
+ * Architecture 6.5 and 6.9. Everything here is read-only, so it is safe to run at any time,
6
+ * including against a project that is mid-build, and it works in a directory that is not a
7
+ * project at all: reporting the environment is useful before there is anything to configure.
8
+ *
9
+ * The checks themselves live in `services/doctor.ts` because Phase 4's Studio Diagnostics
10
+ * route (#69) renders the same results over HTTP, and two implementations of "what is wrong
11
+ * with this environment" would be two answers to one question.
12
+ */
13
+ export declare function doctorCommand(): CommandDefinition;
14
+ //# sourceMappingURL=doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,yBAAyB,CAAC;AAIhF;;;;;;;;;;GAUG;AAEH,wBAAgB,aAAa,IAAI,iBAAiB,CAgCjD"}