@ontrails/trails 1.0.0-beta.12 → 1.0.0-beta.14

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 (150) hide show
  1. package/.turbo/turbo-lint.log +1 -1
  2. package/CHANGELOG.md +40 -12
  3. package/__tests__/examples.test.ts +14 -0
  4. package/dist/src/app.d.ts.map +1 -1
  5. package/dist/src/app.js +13 -2
  6. package/dist/src/app.js.map +1 -1
  7. package/dist/src/clack.d.ts +1 -1
  8. package/dist/src/clack.js +1 -1
  9. package/dist/src/cli.js +2 -2
  10. package/dist/src/cli.js.map +1 -1
  11. package/dist/src/trails/add-trail.js +13 -13
  12. package/dist/src/trails/add-trail.js.map +1 -1
  13. package/dist/src/trails/add-trailhead.d.ts +13 -0
  14. package/dist/src/trails/add-trailhead.d.ts.map +1 -0
  15. package/dist/src/trails/add-trailhead.js +88 -0
  16. package/dist/src/trails/add-trailhead.js.map +1 -0
  17. package/dist/src/trails/add-verify.js +10 -10
  18. package/dist/src/trails/add-verify.js.map +1 -1
  19. package/dist/src/trails/create-scaffold.js +26 -26
  20. package/dist/src/trails/create-scaffold.js.map +1 -1
  21. package/dist/src/trails/create.d.ts +6 -6
  22. package/dist/src/trails/create.d.ts.map +1 -1
  23. package/dist/src/trails/create.js +29 -29
  24. package/dist/src/trails/create.js.map +1 -1
  25. package/dist/src/trails/dev-clean.d.ts +9 -0
  26. package/dist/src/trails/dev-clean.d.ts.map +1 -0
  27. package/dist/src/trails/dev-clean.js +65 -0
  28. package/dist/src/trails/dev-clean.js.map +1 -0
  29. package/dist/src/trails/dev-reset.d.ts +6 -0
  30. package/dist/src/trails/dev-reset.d.ts.map +1 -0
  31. package/dist/src/trails/dev-reset.js +38 -0
  32. package/dist/src/trails/dev-reset.js.map +1 -0
  33. package/dist/src/trails/dev-stats.d.ts +7 -0
  34. package/dist/src/trails/dev-stats.d.ts.map +1 -0
  35. package/dist/src/trails/dev-stats.js +61 -0
  36. package/dist/src/trails/dev-stats.js.map +1 -0
  37. package/dist/src/trails/dev-support.d.ts +64 -0
  38. package/dist/src/trails/dev-support.d.ts.map +1 -0
  39. package/dist/src/trails/dev-support.js +178 -0
  40. package/dist/src/trails/dev-support.js.map +1 -0
  41. package/dist/src/trails/draft-promote.d.ts +18 -0
  42. package/dist/src/trails/draft-promote.d.ts.map +1 -0
  43. package/dist/src/trails/draft-promote.js +386 -0
  44. package/dist/src/trails/draft-promote.js.map +1 -0
  45. package/dist/src/trails/guide.d.ts +13 -3
  46. package/dist/src/trails/guide.d.ts.map +1 -1
  47. package/dist/src/trails/guide.js +21 -37
  48. package/dist/src/trails/guide.js.map +1 -1
  49. package/dist/src/trails/load-app.d.ts +3 -1
  50. package/dist/src/trails/load-app.d.ts.map +1 -1
  51. package/dist/src/trails/load-app.js +53 -10
  52. package/dist/src/trails/load-app.js.map +1 -1
  53. package/dist/src/trails/project.d.ts.map +1 -1
  54. package/dist/src/trails/project.js +14 -3
  55. package/dist/src/trails/project.js.map +1 -1
  56. package/dist/src/trails/survey.d.ts +4 -58
  57. package/dist/src/trails/survey.d.ts.map +1 -1
  58. package/dist/src/trails/survey.js +52 -173
  59. package/dist/src/trails/survey.js.map +1 -1
  60. package/dist/src/trails/topo-constants.d.ts +3 -0
  61. package/dist/src/trails/topo-constants.d.ts.map +1 -0
  62. package/dist/src/trails/topo-constants.js +3 -0
  63. package/dist/src/trails/topo-constants.js.map +1 -0
  64. package/dist/src/trails/topo-export.d.ts +18 -0
  65. package/dist/src/trails/topo-export.d.ts.map +1 -0
  66. package/dist/src/trails/topo-export.js +34 -0
  67. package/dist/src/trails/topo-export.js.map +1 -0
  68. package/dist/src/trails/topo-history.d.ts +24 -0
  69. package/dist/src/trails/topo-history.d.ts.map +1 -0
  70. package/dist/src/trails/topo-history.js +33 -0
  71. package/dist/src/trails/topo-history.js.map +1 -0
  72. package/dist/src/trails/topo-pin.d.ts +21 -0
  73. package/dist/src/trails/topo-pin.d.ts.map +1 -0
  74. package/dist/src/trails/topo-pin.js +35 -0
  75. package/dist/src/trails/topo-pin.js.map +1 -0
  76. package/dist/src/trails/topo-read-support.d.ts +54 -0
  77. package/dist/src/trails/topo-read-support.d.ts.map +1 -0
  78. package/dist/src/trails/topo-read-support.js +178 -0
  79. package/dist/src/trails/topo-read-support.js.map +1 -0
  80. package/dist/src/trails/topo-reports.d.ts +50 -0
  81. package/dist/src/trails/topo-reports.d.ts.map +1 -0
  82. package/dist/src/trails/topo-reports.js +122 -0
  83. package/dist/src/trails/topo-reports.js.map +1 -0
  84. package/dist/src/trails/topo-show.d.ts +23 -0
  85. package/dist/src/trails/topo-show.d.ts.map +1 -0
  86. package/dist/src/trails/topo-show.js +53 -0
  87. package/dist/src/trails/topo-show.js.map +1 -0
  88. package/dist/src/trails/topo-store-support.d.ts +13 -0
  89. package/dist/src/trails/topo-store-support.d.ts.map +1 -0
  90. package/dist/src/trails/topo-store-support.js +55 -0
  91. package/dist/src/trails/topo-store-support.js.map +1 -0
  92. package/dist/src/trails/topo-support.d.ts +87 -0
  93. package/dist/src/trails/topo-support.d.ts.map +1 -0
  94. package/dist/src/trails/topo-support.js +165 -0
  95. package/dist/src/trails/topo-support.js.map +1 -0
  96. package/dist/src/trails/topo-unpin.d.ts +15 -0
  97. package/dist/src/trails/topo-unpin.d.ts.map +1 -0
  98. package/dist/src/trails/topo-unpin.js +39 -0
  99. package/dist/src/trails/topo-unpin.js.map +1 -0
  100. package/dist/src/trails/topo-verify.d.ts +5 -0
  101. package/dist/src/trails/topo-verify.d.ts.map +1 -0
  102. package/dist/src/trails/topo-verify.js +28 -0
  103. package/dist/src/trails/topo-verify.js.map +1 -0
  104. package/dist/src/trails/topo.d.ts +5 -0
  105. package/dist/src/trails/topo.d.ts.map +1 -0
  106. package/dist/src/trails/topo.js +67 -0
  107. package/dist/src/trails/topo.js.map +1 -0
  108. package/dist/src/trails/warden.d.ts +1 -1
  109. package/dist/src/trails/warden.d.ts.map +1 -1
  110. package/dist/src/trails/warden.js +28 -27
  111. package/dist/src/trails/warden.js.map +1 -1
  112. package/dist/tsconfig.tsbuildinfo +1 -1
  113. package/package.json +8 -7
  114. package/src/__tests__/create.test.ts +35 -33
  115. package/src/__tests__/draft-promote.test.ts +144 -0
  116. package/src/__tests__/guide.test.ts +4 -4
  117. package/src/__tests__/load-app.test.ts +43 -0
  118. package/src/__tests__/survey.test.ts +140 -55
  119. package/src/__tests__/topo-dev.test.ts +424 -0
  120. package/src/__tests__/warden.test.ts +2 -2
  121. package/src/app.ts +24 -2
  122. package/src/clack.ts +1 -1
  123. package/src/cli.ts +2 -2
  124. package/src/trails/add-trail.ts +13 -13
  125. package/src/trails/{add-surface.ts → add-trailhead.ts} +39 -37
  126. package/src/trails/add-verify.ts +10 -10
  127. package/src/trails/create-scaffold.ts +28 -28
  128. package/src/trails/create.ts +42 -42
  129. package/src/trails/dev-clean.ts +73 -0
  130. package/src/trails/dev-reset.ts +44 -0
  131. package/src/trails/dev-stats.ts +64 -0
  132. package/src/trails/dev-support.ts +326 -0
  133. package/src/trails/draft-promote.ts +704 -0
  134. package/src/trails/guide.ts +29 -44
  135. package/src/trails/load-app.ts +76 -13
  136. package/src/trails/project.ts +17 -3
  137. package/src/trails/survey.ts +80 -279
  138. package/src/trails/topo-constants.ts +2 -0
  139. package/src/trails/topo-export.ts +39 -0
  140. package/src/trails/topo-history.ts +40 -0
  141. package/src/trails/topo-pin.ts +42 -0
  142. package/src/trails/topo-read-support.ts +332 -0
  143. package/src/trails/topo-reports.ts +221 -0
  144. package/src/trails/topo-show.ts +58 -0
  145. package/src/trails/topo-store-support.ts +96 -0
  146. package/src/trails/topo-support.ts +274 -0
  147. package/src/trails/topo-unpin.ts +51 -0
  148. package/src/trails/topo-verify.ts +29 -0
  149. package/src/trails/topo.ts +73 -0
  150. package/src/trails/warden.ts +33 -32
@@ -0,0 +1,18 @@
1
+ export declare const draftPromoteTrail: import("@ontrails/core").Trail<{
2
+ fromId: string;
3
+ renameFiles: boolean;
4
+ toId: string;
5
+ appModule?: string | undefined;
6
+ rootDir?: string | undefined;
7
+ }, {
8
+ appModule: string | null;
9
+ message: string;
10
+ promotedEstablished: boolean;
11
+ remainingDraftIds: string[];
12
+ renamedFiles: {
13
+ from: string;
14
+ to: string;
15
+ }[];
16
+ updatedFiles: string[];
17
+ }>;
18
+ //# sourceMappingURL=draft-promote.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"draft-promote.d.ts","sourceRoot":"","sources":["../../../src/trails/draft-promote.ts"],"names":[],"mappings":"AAkpBA,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;EA6C5B,CAAC"}
@@ -0,0 +1,386 @@
1
+ import { existsSync, renameSync, statSync } from 'node:fs';
2
+ import { basename, dirname, join, relative } from 'node:path';
3
+ import { Result, ValidationError, analyzeDraftState, isDraftId, trail, } from '@ontrails/core';
4
+ import { DRAFT_FILE_PREFIX, findStringLiterals, isDraftMarkedFile, parse, stripDraftFileMarkers, } from '@ontrails/warden';
5
+ import { z } from 'zod';
6
+ import { loadApp } from './load-app.js';
7
+ import { findTopoPath } from './project.js';
8
+ const isManagedSourceFile = (match) => !match.endsWith('.d.ts') &&
9
+ !match.startsWith('node_modules/') &&
10
+ !match.startsWith('dist/') &&
11
+ !match.startsWith('.git/');
12
+ const collectTsFiles = (rootDir) => {
13
+ const files = [];
14
+ for (const match of new Bun.Glob('**/*.ts').scanSync({
15
+ cwd: rootDir,
16
+ dot: false,
17
+ onlyFiles: true,
18
+ })) {
19
+ if (isManagedSourceFile(match)) {
20
+ files.push(join(rootDir, match));
21
+ }
22
+ }
23
+ return files.toSorted();
24
+ };
25
+ const applyEdits = (sourceCode, edits) => {
26
+ let updated = sourceCode;
27
+ for (const edit of [...edits].toSorted((a, b) => b.start - a.start)) {
28
+ updated =
29
+ updated.slice(0, edit.start) + edit.replacement + updated.slice(edit.end);
30
+ }
31
+ return updated;
32
+ };
33
+ const literalQuote = (raw) => {
34
+ const [first] = raw;
35
+ return first === '"' || first === '`' ? first : "'";
36
+ };
37
+ const replaceQuotedLiteral = (sourceCode, start, end, nextValue) => {
38
+ const quote = literalQuote(sourceCode.slice(start, end));
39
+ return `${quote}${nextValue}${quote}`;
40
+ };
41
+ const replaceIdLiterals = (sourceCode, filePath, fromId, toId) => {
42
+ const ast = parse(filePath, sourceCode);
43
+ if (!ast) {
44
+ return { changed: false, nextSource: sourceCode };
45
+ }
46
+ const edits = findStringLiterals(ast, (value) => value === fromId).map((match) => ({
47
+ end: match.end,
48
+ replacement: replaceQuotedLiteral(sourceCode, match.start, match.end, toId),
49
+ start: match.start,
50
+ }));
51
+ if (edits.length === 0) {
52
+ return { changed: false, nextSource: sourceCode };
53
+ }
54
+ return {
55
+ changed: true,
56
+ nextSource: applyEdits(sourceCode, edits),
57
+ };
58
+ };
59
+ const hasDraftIds = (sourceCode, filePath) => {
60
+ const ast = parse(filePath, sourceCode);
61
+ if (!ast) {
62
+ return sourceCode.includes(DRAFT_FILE_PREFIX);
63
+ }
64
+ return findStringLiterals(ast, (value) => isDraftId(value)).length > 0;
65
+ };
66
+ const toJsPath = (filePath) => filePath.replace(/\.ts$/, '.js');
67
+ const toRelativeModulePath = (fromFile, toFile) => {
68
+ const rel = relative(dirname(fromFile), toJsPath(toFile)).replaceAll('\\', '/');
69
+ return rel.startsWith('.') ? rel : `./${rel}`;
70
+ };
71
+ const replaceLiteralValue = (sourceCode, filePath, currentValue, nextValue) => {
72
+ const ast = parse(filePath, sourceCode);
73
+ if (!ast) {
74
+ return { changed: false, nextSource: sourceCode };
75
+ }
76
+ const edits = findStringLiterals(ast, (value) => value === currentValue).map((match) => ({
77
+ end: match.end,
78
+ replacement: replaceQuotedLiteral(sourceCode, match.start, match.end, nextValue),
79
+ start: match.start,
80
+ }));
81
+ if (edits.length === 0) {
82
+ return { changed: false, nextSource: sourceCode };
83
+ }
84
+ return {
85
+ changed: true,
86
+ nextSource: applyEdits(sourceCode, edits),
87
+ };
88
+ };
89
+ const collectOutputId = (app, id) => app.get(id) ?? app.signals.get(id) ?? app.getProvision(id);
90
+ const toRelativeOutputPath = (rootDir, filePath) => relative(rootDir, filePath).replaceAll('\\', '/');
91
+ const toProjectModulePath = (sourceImport) => sourceImport.startsWith('./')
92
+ ? `./src/${sourceImport.slice(2)}`
93
+ : sourceImport;
94
+ const validatePromotionInput = (input) => {
95
+ if (!isDraftId(input.fromId)) {
96
+ return Result.err(new ValidationError(`fromId must use the reserved draft prefix: "${input.fromId}"`));
97
+ }
98
+ if (isDraftId(input.toId)) {
99
+ return Result.err(new ValidationError(`toId must be established, not draft: "${input.toId}"`));
100
+ }
101
+ return Result.ok();
102
+ };
103
+ const validatePromotionRoot = (rootDir) => {
104
+ if (!existsSync(rootDir)) {
105
+ return Result.err(new ValidationError(`rootDir does not exist: "${rootDir}"`));
106
+ }
107
+ if (!statSync(rootDir).isDirectory()) {
108
+ return Result.err(new ValidationError(`rootDir must be a directory: "${rootDir}"`));
109
+ }
110
+ return Result.ok();
111
+ };
112
+ const resolveValidatedPromotionRoot = (input, ctx) => {
113
+ const validation = validatePromotionInput(input);
114
+ if (validation.isErr()) {
115
+ return validation;
116
+ }
117
+ const rootDir = input.rootDir ?? ctx.cwd ?? process.cwd();
118
+ const rootValidation = validatePromotionRoot(rootDir);
119
+ if (rootValidation.isErr()) {
120
+ return rootValidation;
121
+ }
122
+ return Result.ok(rootDir);
123
+ };
124
+ const rewritePromotedSourceFiles = async (filePaths, fromId, toId, updatedSourceFiles) => {
125
+ for (const filePath of filePaths) {
126
+ const sourceCode = await Bun.file(filePath).text();
127
+ const replaced = replaceIdLiterals(sourceCode, filePath, fromId, toId);
128
+ if (!replaced.changed) {
129
+ continue;
130
+ }
131
+ await Bun.write(filePath, replaced.nextSource);
132
+ updatedSourceFiles.add(filePath);
133
+ }
134
+ };
135
+ const hasDraftIdsInFile = async (filePath) => {
136
+ const sourceCode = await Bun.file(filePath).text();
137
+ return hasDraftIds(sourceCode, filePath);
138
+ };
139
+ const buildPromotableFileRename = (filePath, fileName) => {
140
+ const nextFileName = stripDraftFileMarkers(fileName);
141
+ if (nextFileName === fileName) {
142
+ return Result.ok(null);
143
+ }
144
+ const nextPath = join(dirname(filePath), nextFileName);
145
+ if (nextPath !== filePath && existsSync(nextPath)) {
146
+ return Result.err(new ValidationError(`Cannot promote draft file "${filePath}" because "${nextPath}" already exists.`));
147
+ }
148
+ return Result.ok({ from: filePath, to: nextPath });
149
+ };
150
+ const collectPromotableFileRename = async (filePath) => {
151
+ if (!isDraftMarkedFile(filePath)) {
152
+ return Result.ok(null);
153
+ }
154
+ const fileName = basename(filePath);
155
+ if (!fileName) {
156
+ return Result.ok(null);
157
+ }
158
+ if (await hasDraftIdsInFile(filePath)) {
159
+ return Result.ok(null);
160
+ }
161
+ return buildPromotableFileRename(filePath, fileName);
162
+ };
163
+ /** Validate that no two renames target the same path and no target already exists. */
164
+ const validateRenameTargets = (renames) => {
165
+ const targets = new Set();
166
+ for (const r of renames) {
167
+ if (targets.has(r.to)) {
168
+ return Result.err(new ValidationError(`Duplicate rename target "${r.to}" — multiple draft files would be renamed to the same path`));
169
+ }
170
+ if (existsSync(r.to)) {
171
+ return Result.err(new ValidationError(`Rename target "${r.to}" already exists — cannot overwrite`));
172
+ }
173
+ targets.add(r.to);
174
+ }
175
+ return Result.ok();
176
+ };
177
+ const collectFileRenames = async (filePaths) => {
178
+ const renames = [];
179
+ for (const filePath of filePaths) {
180
+ const renameResult = await collectPromotableFileRename(filePath);
181
+ if (renameResult.isErr()) {
182
+ return renameResult;
183
+ }
184
+ if (renameResult.value !== null) {
185
+ renames.push(renameResult.value);
186
+ }
187
+ }
188
+ return Result.ok(renames);
189
+ };
190
+ const collectAndApplyFileRenames = async (filePaths) => {
191
+ const collected = await collectFileRenames(filePaths);
192
+ if (collected.isErr()) {
193
+ return collected;
194
+ }
195
+ const renames = collected.value;
196
+ const valid = validateRenameTargets(renames);
197
+ if (valid.isErr()) {
198
+ return valid;
199
+ }
200
+ for (const r of renames) {
201
+ renameSync(r.from, r.to);
202
+ }
203
+ return Result.ok(renames);
204
+ };
205
+ const applyRenameEffects = (updatedSourceFiles, renames) => {
206
+ for (const rename of renames) {
207
+ if (updatedSourceFiles.delete(rename.from)) {
208
+ updatedSourceFiles.add(rename.to);
209
+ }
210
+ }
211
+ };
212
+ const applyRelativeImportRename = (sourceCode, filePath, rename) => {
213
+ const currentValue = toRelativeModulePath(filePath, rename.from);
214
+ const nextValue = toRelativeModulePath(filePath, rename.to);
215
+ if (currentValue === nextValue) {
216
+ return { changed: false, sourceCode };
217
+ }
218
+ const replaced = replaceLiteralValue(sourceCode, filePath, currentValue, nextValue);
219
+ if (!replaced.changed) {
220
+ return { changed: false, sourceCode };
221
+ }
222
+ return { changed: true, sourceCode: replaced.nextSource };
223
+ };
224
+ const rewriteRelativeImportsForFile = (filePath, renames, sourceCode) => {
225
+ let nextSourceCode = sourceCode;
226
+ let changed = false;
227
+ for (const rename of renames) {
228
+ const updated = applyRelativeImportRename(nextSourceCode, filePath, rename);
229
+ if (!updated.changed) {
230
+ continue;
231
+ }
232
+ nextSourceCode = updated.sourceCode;
233
+ changed = true;
234
+ }
235
+ return { changed, sourceCode: nextSourceCode };
236
+ };
237
+ const updateRelativeImportsForFile = async (filePath, renames) => {
238
+ const sourceCode = await Bun.file(filePath).text();
239
+ const updated = rewriteRelativeImportsForFile(filePath, renames, sourceCode);
240
+ if (updated.changed) {
241
+ await Bun.write(filePath, updated.sourceCode);
242
+ return true;
243
+ }
244
+ return false;
245
+ };
246
+ const updateRelativeImports = async (filePaths, renames) => {
247
+ const updatedFiles = new Set();
248
+ for (const filePath of filePaths) {
249
+ const changed = await updateRelativeImportsForFile(filePath, renames);
250
+ if (changed) {
251
+ updatedFiles.add(filePath);
252
+ }
253
+ }
254
+ return [...updatedFiles].toSorted();
255
+ };
256
+ const rewritePromotionState = async (rootDir, input) => {
257
+ const initialFiles = collectTsFiles(rootDir);
258
+ const updatedSourceFiles = new Set();
259
+ await rewritePromotedSourceFiles(initialFiles, input.fromId, input.toId, updatedSourceFiles);
260
+ const renamesResult = input.renameFiles
261
+ ? await collectAndApplyFileRenames(initialFiles)
262
+ : Result.ok([]);
263
+ if (renamesResult.isErr()) {
264
+ return Result.err(renamesResult.error);
265
+ }
266
+ applyRenameEffects(updatedSourceFiles, renamesResult.value);
267
+ for (const f of await updateRelativeImports(collectTsFiles(rootDir), renamesResult.value)) {
268
+ updatedSourceFiles.add(f);
269
+ }
270
+ return Result.ok({ renames: renamesResult.value, updatedSourceFiles });
271
+ };
272
+ const resolvePromotionAppModule = async (input, rootDir) => {
273
+ const discoveredAppModule = await findTopoPath(rootDir);
274
+ return (input.appModule ??
275
+ (discoveredAppModule === null
276
+ ? null
277
+ : toProjectModulePath(discoveredAppModule)));
278
+ };
279
+ const loadVerifiedApp = async (appModule, rootDir) => {
280
+ if (appModule === null) {
281
+ return { appModule, loadError: null, loadedApp: undefined };
282
+ }
283
+ let loadError = null;
284
+ const loadedApp = await loadApp(appModule, rootDir, { fresh: true }).catch((error) => {
285
+ loadError = error instanceof Error ? error.message : String(error);
286
+ return undefined;
287
+ });
288
+ return { appModule, loadError, loadedApp };
289
+ };
290
+ const toRenamedFiles = (rootDir, renames) => renames.map((rename) => ({
291
+ from: toRelativeOutputPath(rootDir, rename.from),
292
+ to: toRelativeOutputPath(rootDir, rename.to),
293
+ }));
294
+ const toUpdatedFiles = (rootDir, updatedSourceFiles) => [...updatedSourceFiles]
295
+ .toSorted()
296
+ .map((filePath) => toRelativeOutputPath(rootDir, filePath));
297
+ const buildUnverifiedPromotionResult = (rootDir, loadError, renames, updatedSourceFiles, appModule) => Result.ok({
298
+ appModule,
299
+ message: loadError === null
300
+ ? 'Promotion rewrote source files, but no topo entrypoint could be loaded for verification.'
301
+ : `Promotion rewrote source files, but verification failed: ${loadError}`,
302
+ promotedEstablished: false,
303
+ remainingDraftIds: [],
304
+ renamedFiles: toRenamedFiles(rootDir, renames),
305
+ updatedFiles: toUpdatedFiles(rootDir, updatedSourceFiles),
306
+ });
307
+ const buildVerifiedPromotionResult = (rootDir, analysis, promotedEstablished, renames, updatedSourceFiles, appModule, toId) => {
308
+ const blockingFinding = analysis.findings.find((finding) => finding.id === toId);
309
+ return Result.ok({
310
+ appModule,
311
+ message: blockingFinding?.message ??
312
+ (promotedEstablished
313
+ ? `Promoted "${toId}" is now established.`
314
+ : `Promoted "${toId}" could not be verified as established.`),
315
+ promotedEstablished,
316
+ remainingDraftIds: [...analysis.declaredDraftIds].toSorted(),
317
+ renamedFiles: toRenamedFiles(rootDir, renames),
318
+ updatedFiles: toUpdatedFiles(rootDir, updatedSourceFiles),
319
+ });
320
+ };
321
+ const buildVerifiedPromotionResultFromApp = (rootDir, loadedApp, renames, updatedSourceFiles, appModule, toId) => {
322
+ const analysis = analyzeDraftState(loadedApp);
323
+ const promotedNode = collectOutputId(loadedApp, toId);
324
+ const promotedEstablished = promotedNode !== undefined && !analysis.contaminatedIds.has(toId);
325
+ return buildVerifiedPromotionResult(rootDir, analysis, promotedEstablished, renames, updatedSourceFiles, appModule, toId);
326
+ };
327
+ const promoteDraftState = async (input, ctx) => {
328
+ const rootDirResult = resolveValidatedPromotionRoot(input, ctx);
329
+ if (rootDirResult.isErr()) {
330
+ return rootDirResult;
331
+ }
332
+ const rewriteResult = await rewritePromotionState(rootDirResult.value, input);
333
+ if (rewriteResult.isErr()) {
334
+ return Result.err(rewriteResult.error);
335
+ }
336
+ const { renames, updatedSourceFiles } = rewriteResult.value;
337
+ const appModule = await resolvePromotionAppModule(input, rootDirResult.value);
338
+ const { loadError, loadedApp } = await loadVerifiedApp(appModule, rootDirResult.value);
339
+ return loadedApp
340
+ ? buildVerifiedPromotionResultFromApp(rootDirResult.value, loadedApp, renames, updatedSourceFiles, appModule, input.toId)
341
+ : buildUnverifiedPromotionResult(rootDirResult.value, loadError, renames, updatedSourceFiles, appModule);
342
+ };
343
+ export const draftPromoteTrail = trail('draft.promote', {
344
+ blaze: promoteDraftState,
345
+ description: 'Promote a draft id to an established id, rewrite inbound references, and verify the result against a fresh topo load.',
346
+ examples: [
347
+ {
348
+ error: 'ValidationError',
349
+ input: {
350
+ fromId: '_draft.entity.prepare',
351
+ renameFiles: true,
352
+ rootDir: './__does_not_exist__/draft-promote-example',
353
+ toId: 'entity.prepare',
354
+ },
355
+ name: 'Rejects a missing project root before any rewrite begins',
356
+ },
357
+ ],
358
+ input: z.object({
359
+ appModule: z
360
+ .string()
361
+ .optional()
362
+ .describe('Optional app module to verify after promotion'),
363
+ fromId: z.string().describe('Draft id to promote'),
364
+ renameFiles: z
365
+ .boolean()
366
+ .default(true)
367
+ .describe('Rename draft-marked files that no longer contain draft ids'),
368
+ rootDir: z.string().optional().describe('Project root directory'),
369
+ toId: z
370
+ .string()
371
+ .describe('Established id to write in place of the draft id'),
372
+ }),
373
+ intent: 'write',
374
+ output: z.object({
375
+ appModule: z.string().nullable(),
376
+ message: z.string(),
377
+ promotedEstablished: z.boolean(),
378
+ remainingDraftIds: z.array(z.string()),
379
+ renamedFiles: z.array(z.object({
380
+ from: z.string(),
381
+ to: z.string(),
382
+ })),
383
+ updatedFiles: z.array(z.string()),
384
+ }),
385
+ });
386
+ //# sourceMappingURL=draft-promote.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"draft-promote.js","sourceRoot":"","sources":["../../../src/trails/draft-promote.ts"],"names":[],"mappings":"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"}
@@ -3,9 +3,19 @@
3
3
  *
4
4
  * Lists trails with descriptions and examples. Detailed guidance is planned for post-v1.
5
5
  */
6
- import type { Trail } from '@ontrails/core';
7
- export declare const guideTrail: Trail<{
6
+ export declare const guideTrail: import("@ontrails/core").Trail<{
8
7
  module: string;
9
8
  trailId?: string | undefined;
10
- }, object>;
9
+ }, {
10
+ description: string;
11
+ exampleCount: number;
12
+ id: string;
13
+ kind: string;
14
+ }[] | {
15
+ description: string | null;
16
+ detours: unknown;
17
+ examples: unknown[];
18
+ id: string;
19
+ kind: string;
20
+ }>;
11
21
  //# sourceMappingURL=guide.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"guide.d.ts","sourceRoot":"","sources":["../../../src/trails/guide.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAQ,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAkDlD,eAAO,MAAM,UAAU;;;UA+CrB,CAAC"}
1
+ {"version":3,"file":"guide.d.ts","sourceRoot":"","sources":["../../../src/trails/guide.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA0BH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;EA0DrB,CAAC"}
@@ -3,42 +3,37 @@
3
3
  *
4
4
  * Lists trails with descriptions and examples. Detailed guidance is planned for post-v1.
5
5
  */
6
- import { Result, trail } from '@ontrails/core';
6
+ import { NotFoundError, Result, trail } from '@ontrails/core';
7
7
  import { z } from 'zod';
8
8
  import { loadApp } from './load-app.js';
9
+ import { buildCurrentGuideEntries, buildCurrentTopoDetail, } from './topo-read-support.js';
9
10
  // ---------------------------------------------------------------------------
10
11
  // Helpers
11
12
  // ---------------------------------------------------------------------------
12
- const toGuideEntries = (app) => {
13
- const entries = [];
14
- for (const item of app.list()) {
15
- const raw = item;
16
- entries.push({
17
- description: typeof raw['description'] === 'string'
18
- ? raw['description']
19
- : '(no description)',
20
- exampleCount: Array.isArray(raw['examples'])
21
- ? raw['examples'].length
22
- : 0,
23
- id: item.id,
24
- kind: item.kind,
25
- });
26
- }
27
- return entries;
28
- };
29
- const toGuideDetail = (item) => ({
30
- description: item.description ?? null,
31
- detours: item.detours ?? null,
32
- examples: item.examples ?? [],
33
- id: item.id,
34
- kind: item.kind,
35
- });
36
13
  export const guideTrail = trail('guide', {
14
+ blaze: async (input, ctx) => {
15
+ const rootDir = ctx.cwd ?? '.';
16
+ const app = await loadApp(input.module, rootDir);
17
+ if (input.trailId) {
18
+ const detail = buildCurrentTopoDetail(app, input.trailId, { rootDir });
19
+ if (detail === undefined || detail.kind !== 'trail') {
20
+ return Result.err(new NotFoundError(`Trail not found: ${input.trailId}`));
21
+ }
22
+ return Result.ok({
23
+ description: detail.description,
24
+ detours: detail.detours,
25
+ examples: detail.examples,
26
+ id: detail.id,
27
+ kind: detail.kind,
28
+ });
29
+ }
30
+ return Result.ok(buildCurrentGuideEntries(app, { rootDir }));
31
+ },
37
32
  description: 'Runtime guidance for trails',
38
33
  examples: [
39
34
  {
40
35
  description: 'Lists all trails with descriptions and example counts',
41
- input: {},
36
+ input: { module: './src/app.ts' },
42
37
  name: 'List trail guidance',
43
38
  },
44
39
  ],
@@ -65,16 +60,5 @@ export const guideTrail = trail('guide', {
65
60
  kind: z.string(),
66
61
  }),
67
62
  ]),
68
- run: async (input, ctx) => {
69
- const app = await loadApp(input.module, ctx.cwd ?? '.');
70
- if (input.trailId) {
71
- const item = app.get(input.trailId);
72
- if (!item) {
73
- return Result.err(new Error(`Trail not found: ${input.trailId}`));
74
- }
75
- return Result.ok(toGuideDetail(item));
76
- }
77
- return Result.ok(toGuideEntries(app));
78
- },
79
63
  });
80
64
  //# sourceMappingURL=guide.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"guide.js","sourceRoot":"","sources":["../../../src/trails/guide.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"guide.js","sourceRoot":"","sources":["../../../src/trails/guide.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EACL,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAahC,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,EAAE;IACvC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QAC1B,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC;QAC/B,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAEjD,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAClB,MAAM,MAAM,GAAG,sBAAsB,CAAC,GAAG,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;YACvE,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBACpD,OAAO,MAAM,CAAC,GAAG,CACf,IAAI,aAAa,CAAC,oBAAoB,KAAK,CAAC,OAAO,EAAE,CAAC,CACvD,CAAC;YACJ,CAAC;YACD,OAAO,MAAM,CAAC,EAAE,CAAC;gBACf,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,EAAE,EAAE,MAAM,CAAC,EAAE;gBACb,IAAI,EAAE,MAAM,CAAC,IAAI;aAClB,CAAC,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAC,EAAE,CACd,wBAAwB,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,CAAiB,CAC3D,CAAC;IACJ,CAAC;IACD,WAAW,EAAE,6BAA6B;IAC1C,QAAQ,EAAE;QACR;YACE,WAAW,EAAE,uDAAuD;YACpE,KAAK,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE;YACjC,IAAI,EAAE,qBAAqB;SAC5B;KACF;IACD,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;QACd,MAAM,EAAE,CAAC;aACN,MAAM,EAAE;aACR,OAAO,CAAC,cAAc,CAAC;aACvB,QAAQ,CAAC,wBAAwB,CAAC;QACrC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;KAC1E,CAAC;IACF,MAAM,EAAE,MAAM;IACd,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC;QACd,CAAC,CAAC,KAAK,CACL,CAAC,CAAC,MAAM,CAAC;YACP,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;YACvB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;YACxB,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;YACd,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;SACjB,CAAC,CACH;QACD,CAAC,CAAC,MAAM,CAAC;YACP,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YAClC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;YAC/B,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;YAC9B,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;YACd,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;SACjB,CAAC;KACH,CAAC;CACH,CAAC,CAAC"}
@@ -1,4 +1,6 @@
1
1
  import type { Topo } from '@ontrails/core';
2
2
  /** Load a Topo export from a module path relative to cwd. */
3
- export declare const loadApp: (modulePath: string, cwd: string) => Promise<Topo>;
3
+ export declare const loadApp: (modulePath: string, cwd: string, options?: {
4
+ fresh?: boolean | undefined;
5
+ }) => Promise<Topo>;
4
6
  //# sourceMappingURL=load-app.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"load-app.d.ts","sourceRoot":"","sources":["../../../src/trails/load-app.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAgB3C,6DAA6D;AAC7D,eAAO,MAAM,OAAO,GAClB,YAAY,MAAM,EAClB,KAAK,MAAM,KACV,OAAO,CAAC,IAAI,CAad,CAAC"}
1
+ {"version":3,"file":"load-app.d.ts","sourceRoot":"","sources":["../../../src/trails/load-app.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAuE3C,6DAA6D;AAC7D,eAAO,MAAM,OAAO,GAClB,YAAY,MAAM,EAClB,KAAK,MAAM,EACX,UAAS;IAAE,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAAO,KAC5C,OAAO,CAAC,IAAI,CAmBd,CAAC"}
@@ -1,19 +1,62 @@
1
- import { isAbsolute, resolve } from 'node:path';
2
- import { pathToFileURL } from 'node:url';
1
+ import { existsSync, rmSync } from 'node:fs';
2
+ import { basename, dirname, isAbsolute, join, resolve } from 'node:path';
3
+ import { fileURLToPath, pathToFileURL } from 'node:url';
3
4
  const URL_SCHEME = /^[a-zA-Z][a-zA-Z\d+.-]*:/;
4
- /** Resolve a module path from cwd so CLI defaults behave like shell paths. */
5
- const resolveModuleSpecifier = (modulePath, cwd) => {
6
- if (URL_SCHEME.test(modulePath)) {
7
- return modulePath;
8
- }
5
+ const resolveUrlModulePath = (modulePath) => {
6
+ const url = new URL(modulePath);
7
+ return url.protocol === 'file:' ? fileURLToPath(url) : modulePath;
8
+ };
9
+ const resolveFilesystemModulePath = (modulePath, cwd) => {
9
10
  const absolutePath = isAbsolute(modulePath)
10
11
  ? modulePath
11
12
  : resolve(cwd, modulePath);
12
- return pathToFileURL(absolutePath).href;
13
+ if (!absolutePath.endsWith('.js') || existsSync(absolutePath)) {
14
+ return absolutePath;
15
+ }
16
+ const tsPath = absolutePath.replace(/\.js$/, '.ts');
17
+ return existsSync(tsPath) ? tsPath : absolutePath;
18
+ };
19
+ /** Resolve a module path from cwd so CLI defaults behave like shell paths. */
20
+ const resolveAbsoluteModulePath = (modulePath, cwd) => URL_SCHEME.test(modulePath)
21
+ ? resolveUrlModulePath(modulePath)
22
+ : resolveFilesystemModulePath(modulePath, cwd);
23
+ const freshModuleCopyPath = (absolutePath) => join(dirname(absolutePath), `.__fresh-${Date.now()}-${Math.random().toString(36).slice(2)}-${basename(absolutePath)}`);
24
+ /**
25
+ * Import a module bypassing the ESM cache for the entry file.
26
+ *
27
+ * @remarks
28
+ * Cache-busting applies to the entry module only. Transitive imports resolved
29
+ * by the entry file are still served from Bun's module cache. This is
30
+ * acceptable for the draft promotion workflow (the only caller) because
31
+ * promotion changes which modules the entry file imports, not the modules
32
+ * themselves. If a deeper cache-bust is needed in the future, consider
33
+ * Bun's `Loader.registry` or a full process restart.
34
+ */
35
+ const importFreshModule = async (modulePath, cwd) => {
36
+ const absolutePath = resolveAbsoluteModulePath(modulePath, cwd);
37
+ if (URL_SCHEME.test(absolutePath) && !absolutePath.startsWith('/')) {
38
+ const url = new URL(absolutePath);
39
+ url.searchParams.set('t', Date.now().toString());
40
+ return (await import(url.href));
41
+ }
42
+ const freshPath = freshModuleCopyPath(absolutePath);
43
+ await Bun.write(freshPath, await Bun.file(absolutePath).text());
44
+ try {
45
+ return (await import(pathToFileURL(freshPath).href));
46
+ }
47
+ finally {
48
+ rmSync(freshPath, { force: true });
49
+ }
13
50
  };
14
51
  /** Load a Topo export from a module path relative to cwd. */
15
- export const loadApp = async (modulePath, cwd) => {
16
- const mod = (await import(resolveModuleSpecifier(modulePath, cwd)));
52
+ export const loadApp = async (modulePath, cwd, options = {}) => {
53
+ const resolvedModulePath = resolveAbsoluteModulePath(modulePath, cwd);
54
+ const mod = options.fresh === true
55
+ ? await importFreshModule(modulePath, cwd)
56
+ : (await import(URL_SCHEME.test(resolvedModulePath) &&
57
+ !resolvedModulePath.startsWith('/')
58
+ ? new URL(resolvedModulePath).href
59
+ : pathToFileURL(resolvedModulePath).href));
17
60
  const app = (mod['default'] ?? mod['app']);
18
61
  if (!app?.trails) {
19
62
  throw new Error(`Could not find a Topo export in "${modulePath}". ` +