@ontrails/trails 1.0.0-beta.39 → 1.0.0-beta.41
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.
- package/CHANGELOG.md +88 -0
- package/README.md +1 -1
- package/package.json +17 -17
- package/src/app.ts +4 -4
- package/src/cli.ts +1 -1
- package/src/completions.ts +1 -1
- package/src/mcp-app.ts +2 -2
- package/src/regrade/history.ts +148 -38
- package/src/regrade/plan-artifact.ts +31 -11
- package/src/release/native-bun-registry.ts +12 -1
- package/src/release/policy.ts +4 -1
- package/src/retired-topo-command.ts +1 -1
- package/src/run-watch.ts +1 -1
- package/src/run-wayfind-outline.ts +6 -2
- package/src/trails/adapter-check.ts +8 -8
- package/src/trails/add-surface.ts +2 -2
- package/src/trails/add-trail.ts +3 -3
- package/src/trails/add-verify.ts +2 -2
- package/src/trails/compile.ts +9 -9
- package/src/trails/completions-complete.ts +10 -10
- package/src/trails/completions.ts +2 -2
- package/src/trails/create-adapter.ts +185 -424
- package/src/trails/create-scaffold.ts +12 -12
- package/src/trails/create-versions.ts +8 -8
- package/src/trails/create.ts +35 -35
- package/src/trails/deprecate.ts +2 -2
- package/src/trails/dev-clean.ts +11 -11
- package/src/trails/dev-reset.ts +11 -11
- package/src/trails/dev-stats.ts +8 -8
- package/src/trails/dev-support.ts +1 -1
- package/src/trails/doctor.ts +4 -4
- package/src/trails/draft-promote.ts +3 -3
- package/src/trails/guide.ts +9 -9
- package/src/trails/load-app.ts +3 -3
- package/src/trails/regrade.ts +56 -27
- package/src/trails/release-check.ts +8 -8
- package/src/trails/release-smoke.ts +2 -2
- package/src/trails/revise.ts +2 -2
- package/src/trails/run-example.ts +9 -9
- package/src/trails/run-examples.ts +9 -9
- package/src/trails/run.ts +26 -26
- package/src/trails/survey.ts +45 -45
- package/src/trails/topo-activation.ts +2 -2
- package/src/trails/topo-history.ts +8 -8
- package/src/trails/topo-output-schemas.ts +5 -5
- package/src/trails/topo-pin.ts +6 -6
- package/src/trails/topo-read-support.ts +4 -3
- package/src/trails/topo-reports.ts +16 -16
- package/src/trails/topo-store-support.ts +18 -9
- package/src/trails/topo-support.ts +2 -2
- package/src/trails/topo-unpin.ts +12 -12
- package/src/trails/topo.ts +4 -4
- package/src/trails/validate.ts +2 -2
- package/src/trails/version-lifecycle-support.ts +17 -16
- package/src/trails/warden-guide.ts +8 -8
- package/src/trails/warden.ts +21 -21
- package/src/trails/wayfind-outline.ts +876 -0
- package/src/trails/wayfind.ts +74 -74
|
@@ -164,7 +164,7 @@ bun run guide
|
|
|
164
164
|
## Lexicon
|
|
165
165
|
|
|
166
166
|
- \`trail\`, not action or handler
|
|
167
|
-
- \`
|
|
167
|
+
- \`implementation\`, not handler or impl
|
|
168
168
|
- \`topo\`, not registry or collection
|
|
169
169
|
- \`compose\`, not follow
|
|
170
170
|
- \`surface\`, not transport
|
|
@@ -173,9 +173,9 @@ bun run guide
|
|
|
173
173
|
|
|
174
174
|
## Trail Rules
|
|
175
175
|
|
|
176
|
-
-
|
|
176
|
+
- Implementations return \`Result\`; never throw from trail logic.
|
|
177
177
|
- Use \`Result.ok()\` and \`Result.err()\`; branch with \`isOk()\`, \`isErr()\`, or \`match()\`.
|
|
178
|
-
- Keep trail logic surface-agnostic. Do not import CLI, MCP, HTTP, request, or response types into
|
|
178
|
+
- Keep trail logic surface-agnostic. Do not import CLI, MCP, HTTP, request, or response types into implementations.
|
|
179
179
|
- Public MCP or HTTP trails declare an \`output\` schema.
|
|
180
180
|
- Trails that compose other trails declare \`composes: [...]\` and invoke them with \`ctx.compose(...)\`.
|
|
181
181
|
- Trails that use infrastructure declare \`resources: [...]\` and access them through the resource helpers.
|
|
@@ -236,7 +236,7 @@ const generateHelloTrail = (): string =>
|
|
|
236
236
|
import { z } from 'zod';
|
|
237
237
|
|
|
238
238
|
export const hello = trail('hello', {
|
|
239
|
-
|
|
239
|
+
implementation: (input) => {
|
|
240
240
|
const name = input.name ?? 'world';
|
|
241
241
|
return Result.ok({ message: \`Hello, \${name}!\` });
|
|
242
242
|
},
|
|
@@ -277,7 +277,7 @@ const entitySchema = z.object({
|
|
|
277
277
|
});
|
|
278
278
|
|
|
279
279
|
export const show = trail('entity.show', {
|
|
280
|
-
|
|
280
|
+
implementation: (input, ctx) => {
|
|
281
281
|
const store = entityStore.from(ctx);
|
|
282
282
|
const entity = store.get(input.id);
|
|
283
283
|
if (!entity) {
|
|
@@ -300,7 +300,7 @@ export const show = trail('entity.show', {
|
|
|
300
300
|
});
|
|
301
301
|
|
|
302
302
|
export const add = trail('entity.add', {
|
|
303
|
-
|
|
303
|
+
implementation: (input, ctx) => {
|
|
304
304
|
const store = entityStore.from(ctx);
|
|
305
305
|
const entity = { id: randomUUID(), name: input.name };
|
|
306
306
|
store.add(entity);
|
|
@@ -322,7 +322,7 @@ export const add = trail('entity.add', {
|
|
|
322
322
|
});
|
|
323
323
|
|
|
324
324
|
export const list = trail('entity.list', {
|
|
325
|
-
|
|
325
|
+
implementation: (_input, ctx) => {
|
|
326
326
|
const store = entityStore.from(ctx);
|
|
327
327
|
return Result.ok({ entities: store.list() });
|
|
328
328
|
},
|
|
@@ -343,7 +343,7 @@ export const list = trail('entity.list', {
|
|
|
343
343
|
});
|
|
344
344
|
|
|
345
345
|
export const remove = trail('entity.delete', {
|
|
346
|
-
|
|
346
|
+
implementation: (input, ctx) => {
|
|
347
347
|
const store = entityStore.from(ctx);
|
|
348
348
|
const deleted = store.delete(input.id);
|
|
349
349
|
return Result.ok({ deleted, id: input.id });
|
|
@@ -372,7 +372,7 @@ const generateSearchTrail = (): string =>
|
|
|
372
372
|
import { z } from 'zod';
|
|
373
373
|
|
|
374
374
|
export const search = trail('search', {
|
|
375
|
-
|
|
375
|
+
implementation: () => {
|
|
376
376
|
return Result.ok({ results: [] });
|
|
377
377
|
},
|
|
378
378
|
description: 'Search entities by query',
|
|
@@ -396,7 +396,7 @@ const generateOnboardTrail = (): string =>
|
|
|
396
396
|
import { z } from 'zod';
|
|
397
397
|
|
|
398
398
|
export const onboard = trail('entity.onboard', {
|
|
399
|
-
|
|
399
|
+
implementation: async (input, ctx) => {
|
|
400
400
|
const result = await ctx.compose('entity.add', { name: input.name });
|
|
401
401
|
if (result.isErr()) {
|
|
402
402
|
return result;
|
|
@@ -569,7 +569,8 @@ const collectScaffoldOperations = (
|
|
|
569
569
|
// ---------------------------------------------------------------------------
|
|
570
570
|
|
|
571
571
|
export const createScaffold = trail('create.scaffold', {
|
|
572
|
-
|
|
572
|
+
description: 'Scaffold a new Trails project',
|
|
573
|
+
implementation: async (input) => {
|
|
573
574
|
const projectDirResult = resolveProjectDir(input.dir ?? '.', input.name);
|
|
574
575
|
if (projectDirResult.isErr()) {
|
|
575
576
|
return projectDirResult;
|
|
@@ -606,7 +607,6 @@ export const createScaffold = trail('create.scaffold', {
|
|
|
606
607
|
plannedOperations: plannedOperations.value,
|
|
607
608
|
} satisfies ScaffoldResult);
|
|
608
609
|
},
|
|
609
|
-
description: 'Scaffold a new Trails project',
|
|
610
610
|
input: z.object({
|
|
611
611
|
dir: z.string().optional().describe('Parent directory'),
|
|
612
612
|
dryRun: z
|
|
@@ -27,7 +27,14 @@ const createVersionsOutputSchema = z.object({
|
|
|
27
27
|
});
|
|
28
28
|
|
|
29
29
|
export const createVersionsTrail = trail('create.versions', {
|
|
30
|
-
|
|
30
|
+
description: 'Sync generated scaffold dependency versions',
|
|
31
|
+
examples: [
|
|
32
|
+
{
|
|
33
|
+
input: { check: true },
|
|
34
|
+
name: 'Verify generated scaffold versions are current',
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
implementation: async (input, ctx) => {
|
|
31
38
|
const rootDirResult = resolveTrailRootDir(input.rootDir, ctx.cwd);
|
|
32
39
|
if (rootDirResult.isErr()) {
|
|
33
40
|
return rootDirResult;
|
|
@@ -48,13 +55,6 @@ export const createVersionsTrail = trail('create.versions', {
|
|
|
48
55
|
);
|
|
49
56
|
}
|
|
50
57
|
},
|
|
51
|
-
description: 'Sync generated scaffold dependency versions',
|
|
52
|
-
examples: [
|
|
53
|
-
{
|
|
54
|
-
input: { check: true },
|
|
55
|
-
name: 'Verify generated scaffold versions are current',
|
|
56
|
-
},
|
|
57
|
-
],
|
|
58
58
|
input: createVersionsInputSchema,
|
|
59
59
|
intent: 'write',
|
|
60
60
|
output: createVersionsOutputSchema,
|
package/src/trails/create.ts
CHANGED
|
@@ -200,7 +200,41 @@ const writeReadme = async (
|
|
|
200
200
|
// ---------------------------------------------------------------------------
|
|
201
201
|
|
|
202
202
|
export const createTrail = trail('create', {
|
|
203
|
-
|
|
203
|
+
composes: ['create.scaffold', 'add.surface', 'add.verify'],
|
|
204
|
+
description: 'Create a new Trails project',
|
|
205
|
+
fields: {
|
|
206
|
+
starter: {
|
|
207
|
+
options: [
|
|
208
|
+
{
|
|
209
|
+
hint: 'One trail, one example',
|
|
210
|
+
label: 'Hello world',
|
|
211
|
+
value: 'hello',
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
hint: '4 trails, signal, store',
|
|
215
|
+
label: 'Entity CRUD',
|
|
216
|
+
value: 'entity',
|
|
217
|
+
},
|
|
218
|
+
{ hint: 'Just the structure', label: 'Empty', value: 'empty' },
|
|
219
|
+
],
|
|
220
|
+
},
|
|
221
|
+
surfaces: {
|
|
222
|
+
options: [
|
|
223
|
+
{ hint: 'Commander-based command line', label: 'CLI', value: 'cli' },
|
|
224
|
+
{
|
|
225
|
+
hint: 'Model Context Protocol for agents',
|
|
226
|
+
label: 'MCP',
|
|
227
|
+
value: 'mcp',
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
hint: 'Hono-powered HTTP endpoints',
|
|
231
|
+
label: 'HTTP',
|
|
232
|
+
value: 'http',
|
|
233
|
+
},
|
|
234
|
+
],
|
|
235
|
+
},
|
|
236
|
+
},
|
|
237
|
+
implementation: async (input: CreateInput, ctx) => {
|
|
204
238
|
if (!hasCompose(ctx)) {
|
|
205
239
|
return Result.err(new InternalError('create trail requires ctx.compose'));
|
|
206
240
|
}
|
|
@@ -257,40 +291,6 @@ export const createTrail = trail('create', {
|
|
|
257
291
|
|
|
258
292
|
return finishCreate();
|
|
259
293
|
},
|
|
260
|
-
composes: ['create.scaffold', 'add.surface', 'add.verify'],
|
|
261
|
-
description: 'Create a new Trails project',
|
|
262
|
-
fields: {
|
|
263
|
-
starter: {
|
|
264
|
-
options: [
|
|
265
|
-
{
|
|
266
|
-
hint: 'One trail, one example',
|
|
267
|
-
label: 'Hello world',
|
|
268
|
-
value: 'hello',
|
|
269
|
-
},
|
|
270
|
-
{
|
|
271
|
-
hint: '4 trails, signal, store',
|
|
272
|
-
label: 'Entity CRUD',
|
|
273
|
-
value: 'entity',
|
|
274
|
-
},
|
|
275
|
-
{ hint: 'Just the structure', label: 'Empty', value: 'empty' },
|
|
276
|
-
],
|
|
277
|
-
},
|
|
278
|
-
surfaces: {
|
|
279
|
-
options: [
|
|
280
|
-
{ hint: 'Commander-based command line', label: 'CLI', value: 'cli' },
|
|
281
|
-
{
|
|
282
|
-
hint: 'Model Context Protocol for agents',
|
|
283
|
-
label: 'MCP',
|
|
284
|
-
value: 'mcp',
|
|
285
|
-
},
|
|
286
|
-
{
|
|
287
|
-
hint: 'Hono-powered HTTP endpoints',
|
|
288
|
-
label: 'HTTP',
|
|
289
|
-
value: 'http',
|
|
290
|
-
},
|
|
291
|
-
],
|
|
292
|
-
},
|
|
293
|
-
},
|
|
294
294
|
input: z.object({
|
|
295
295
|
dir: z.string().optional().describe('Parent directory'),
|
|
296
296
|
name: z
|
package/src/trails/deprecate.ts
CHANGED
|
@@ -9,7 +9,8 @@ import {
|
|
|
9
9
|
|
|
10
10
|
export const deprecateTrail = trail('deprecate', {
|
|
11
11
|
args: ['target'],
|
|
12
|
-
|
|
12
|
+
description: 'Mark a historical trail version deprecated or archived',
|
|
13
|
+
implementation: async (input, ctx) =>
|
|
13
14
|
withLifecycleApp(input, ctx.cwd, async (_app, rootDir) => {
|
|
14
15
|
const target = parseLifecycleTarget(input.target);
|
|
15
16
|
if (target.isErr()) {
|
|
@@ -27,7 +28,6 @@ export const deprecateTrail = trail('deprecate', {
|
|
|
27
28
|
}
|
|
28
29
|
);
|
|
29
30
|
}),
|
|
30
|
-
description: 'Mark a historical trail version deprecated or archived',
|
|
31
31
|
input: z.object({
|
|
32
32
|
archive: z
|
|
33
33
|
.boolean()
|
package/src/trails/dev-clean.ts
CHANGED
|
@@ -9,7 +9,17 @@ import { resolveTrailRootDir } from './root-dir.js';
|
|
|
9
9
|
import { createIsolatedExampleInput } from './topo-support.js';
|
|
10
10
|
|
|
11
11
|
export const devCleanTrail = trail('dev.clean', {
|
|
12
|
-
|
|
12
|
+
description: 'Prune unpinned topo snapshots and old trace records',
|
|
13
|
+
examples: [
|
|
14
|
+
{
|
|
15
|
+
input: {
|
|
16
|
+
dryRun: true,
|
|
17
|
+
rootDir: createIsolatedExampleInput('dev-clean').rootDir,
|
|
18
|
+
},
|
|
19
|
+
name: 'Preview local cleanup',
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
implementation: (input, ctx) => {
|
|
13
23
|
if (input.dryRun !== true && input.yes !== true) {
|
|
14
24
|
return Result.err(
|
|
15
25
|
new ValidationError(
|
|
@@ -33,16 +43,6 @@ export const devCleanTrail = trail('dev.clean', {
|
|
|
33
43
|
})
|
|
34
44
|
);
|
|
35
45
|
},
|
|
36
|
-
description: 'Prune unpinned topo snapshots and old trace records',
|
|
37
|
-
examples: [
|
|
38
|
-
{
|
|
39
|
-
input: {
|
|
40
|
-
dryRun: true,
|
|
41
|
-
rootDir: createIsolatedExampleInput('dev-clean').rootDir,
|
|
42
|
-
},
|
|
43
|
-
name: 'Preview local cleanup',
|
|
44
|
-
},
|
|
45
|
-
],
|
|
46
46
|
input: z.object({
|
|
47
47
|
dryRun: z
|
|
48
48
|
.boolean()
|
package/src/trails/dev-reset.ts
CHANGED
|
@@ -6,7 +6,17 @@ import { resolveTrailRootDir } from './root-dir.js';
|
|
|
6
6
|
import { createIsolatedExampleInput } from './topo-support.js';
|
|
7
7
|
|
|
8
8
|
export const devResetTrail = trail('dev.reset', {
|
|
9
|
-
|
|
9
|
+
description: 'Remove local Trails database artifacts',
|
|
10
|
+
examples: [
|
|
11
|
+
{
|
|
12
|
+
input: {
|
|
13
|
+
dryRun: true,
|
|
14
|
+
rootDir: createIsolatedExampleInput('dev-reset').rootDir,
|
|
15
|
+
},
|
|
16
|
+
name: 'Preview local reset',
|
|
17
|
+
},
|
|
18
|
+
],
|
|
19
|
+
implementation: (input, ctx) => {
|
|
10
20
|
if (input.dryRun !== true && input.yes !== true) {
|
|
11
21
|
return Result.err(
|
|
12
22
|
new ValidationError(
|
|
@@ -22,16 +32,6 @@ export const devResetTrail = trail('dev.reset', {
|
|
|
22
32
|
const rootDir = rootDirResult.value;
|
|
23
33
|
return Result.ok(resetDevState({ dryRun: input.dryRun, rootDir }));
|
|
24
34
|
},
|
|
25
|
-
description: 'Remove local Trails database artifacts',
|
|
26
|
-
examples: [
|
|
27
|
-
{
|
|
28
|
-
input: {
|
|
29
|
-
dryRun: true,
|
|
30
|
-
rootDir: createIsolatedExampleInput('dev-reset').rootDir,
|
|
31
|
-
},
|
|
32
|
-
name: 'Preview local reset',
|
|
33
|
-
},
|
|
34
|
-
],
|
|
35
35
|
input: z.object({
|
|
36
36
|
dryRun: z
|
|
37
37
|
.boolean()
|
package/src/trails/dev-stats.ts
CHANGED
|
@@ -9,7 +9,14 @@ import { resolveTrailRootDir } from './root-dir.js';
|
|
|
9
9
|
import { createIsolatedExampleInput } from './topo-support.js';
|
|
10
10
|
|
|
11
11
|
export const devStatsTrail = trail('dev.stats', {
|
|
12
|
-
|
|
12
|
+
description: 'Show local Trails workspace state and retention',
|
|
13
|
+
examples: [
|
|
14
|
+
{
|
|
15
|
+
input: { rootDir: createIsolatedExampleInput('dev-stats').rootDir },
|
|
16
|
+
name: 'Show local dev state',
|
|
17
|
+
},
|
|
18
|
+
],
|
|
19
|
+
implementation: (input, ctx) => {
|
|
13
20
|
const rootDirResult = resolveTrailRootDir(input.rootDir, ctx.cwd);
|
|
14
21
|
if (rootDirResult.isErr()) {
|
|
15
22
|
return rootDirResult;
|
|
@@ -24,13 +31,6 @@ export const devStatsTrail = trail('dev.stats', {
|
|
|
24
31
|
})
|
|
25
32
|
);
|
|
26
33
|
},
|
|
27
|
-
description: 'Show local Trails workspace state and retention',
|
|
28
|
-
examples: [
|
|
29
|
-
{
|
|
30
|
-
input: { rootDir: createIsolatedExampleInput('dev-stats').rootDir },
|
|
31
|
-
name: 'Show local dev state',
|
|
32
|
-
},
|
|
33
|
-
],
|
|
34
34
|
input: z.object({
|
|
35
35
|
rootDir: z.string().optional().describe('Workspace root directory'),
|
|
36
36
|
snapshots: z
|
package/src/trails/doctor.ts
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
Result,
|
|
6
6
|
trail,
|
|
7
7
|
} from '@ontrails/core';
|
|
8
|
-
import { readTopoGraph } from '@ontrails/
|
|
8
|
+
import { readTopoGraph } from '@ontrails/topography';
|
|
9
9
|
import { z } from 'zod';
|
|
10
10
|
|
|
11
11
|
import {
|
|
@@ -30,7 +30,8 @@ const toDoctorSummaryError = (error: unknown): InternalError =>
|
|
|
30
30
|
: new InternalError(`Unable to derive doctor summary: ${String(error)}`);
|
|
31
31
|
|
|
32
32
|
export const doctorTrail = trail('doctor', {
|
|
33
|
-
|
|
33
|
+
description: 'Diagnose trail versioning lifecycle state',
|
|
34
|
+
implementation: async (input, ctx) =>
|
|
34
35
|
withLifecycleApp(input, ctx.cwd, async (app, rootDir) => {
|
|
35
36
|
const forceGraph = await readDoctorForceGraph(rootDir);
|
|
36
37
|
try {
|
|
@@ -45,7 +46,6 @@ export const doctorTrail = trail('doctor', {
|
|
|
45
46
|
return Result.err(toDoctorSummaryError(error));
|
|
46
47
|
}
|
|
47
48
|
}),
|
|
48
|
-
description: 'Diagnose trail versioning lifecycle state',
|
|
49
49
|
input: z.object({
|
|
50
50
|
module: z.string().optional().describe('Path to the app module'),
|
|
51
51
|
rootDir: z.string().optional().describe('Workspace root directory'),
|
|
@@ -61,7 +61,7 @@ export const doctorTrail = trail('doctor', {
|
|
|
61
61
|
change: z.enum(['modified', 'removed']),
|
|
62
62
|
detail: z.string(),
|
|
63
63
|
id: z.string(),
|
|
64
|
-
kind: z.enum(['
|
|
64
|
+
kind: z.enum(['entity', 'trail', 'signal', 'resource']),
|
|
65
65
|
reason: z.string().optional(),
|
|
66
66
|
scope: z.enum(['entry', 'graph']),
|
|
67
67
|
severity: z.literal('breaking'),
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
isDraftMarkedFile,
|
|
22
22
|
stripDraftFileMarkers,
|
|
23
23
|
} from '@ontrails/warden';
|
|
24
|
-
import { findStringLiterals, parse } from '@ontrails/
|
|
24
|
+
import { findStringLiterals, parse } from '@ontrails/source';
|
|
25
25
|
import { z } from 'zod';
|
|
26
26
|
|
|
27
27
|
import {
|
|
@@ -674,7 +674,7 @@ const resolvePromotionAppModule = async (
|
|
|
674
674
|
* @remarks
|
|
675
675
|
* The lease deletes its on-disk mirror on release. Any Topo consumption that
|
|
676
676
|
* may trigger deferred filesystem imports (for example inside a trail's
|
|
677
|
-
* `
|
|
677
|
+
* `implementation` or a lazy relative `import()`) must run before the lease is
|
|
678
678
|
* released, otherwise those resolutions race the mirror teardown. Collapsing
|
|
679
679
|
* consumption into the leased critical section keeps that contract
|
|
680
680
|
* structural rather than relying on the caller to discover it.
|
|
@@ -884,7 +884,6 @@ const promoteDraftState = async (
|
|
|
884
884
|
};
|
|
885
885
|
|
|
886
886
|
export const draftPromoteTrail = trail('draft.promote', {
|
|
887
|
-
blaze: promoteDraftState,
|
|
888
887
|
description:
|
|
889
888
|
'Promote a draft id to an established id, rewrite inbound references, and verify the result against a fresh topo load.',
|
|
890
889
|
examples: [
|
|
@@ -900,6 +899,7 @@ export const draftPromoteTrail = trail('draft.promote', {
|
|
|
900
899
|
name: 'Rejects a missing project root before any rewrite begins',
|
|
901
900
|
},
|
|
902
901
|
],
|
|
902
|
+
implementation: promoteDraftState,
|
|
903
903
|
input: z.object({
|
|
904
904
|
appModule: z
|
|
905
905
|
.string()
|
package/src/trails/guide.ts
CHANGED
|
@@ -50,7 +50,15 @@ type GuideTrailInput = z.output<typeof guideTrailInputSchema>;
|
|
|
50
50
|
// ---------------------------------------------------------------------------
|
|
51
51
|
|
|
52
52
|
export const guideTrail = trail('guide', {
|
|
53
|
-
|
|
53
|
+
description: 'Runtime guidance for trails',
|
|
54
|
+
examples: [
|
|
55
|
+
{
|
|
56
|
+
description: 'Lists all trails with descriptions and example counts',
|
|
57
|
+
input: createIsolatedExampleInput('guide-list'),
|
|
58
|
+
name: 'List trail guidance',
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
implementation: async (input: GuideTrailInput, ctx) =>
|
|
54
62
|
withFreshOperatorApp<GuideTrailOutput>(input, ctx, ({ lease, rootDir }) => {
|
|
55
63
|
if (input.trailId) {
|
|
56
64
|
const detail = deriveCurrentTopoDetail(lease.app, input.trailId, {
|
|
@@ -76,14 +84,6 @@ export const guideTrail = trail('guide', {
|
|
|
76
84
|
mode: 'list' as const,
|
|
77
85
|
});
|
|
78
86
|
}),
|
|
79
|
-
description: 'Runtime guidance for trails',
|
|
80
|
-
examples: [
|
|
81
|
-
{
|
|
82
|
-
description: 'Lists all trails with descriptions and example counts',
|
|
83
|
-
input: createIsolatedExampleInput('guide-list'),
|
|
84
|
-
name: 'List trail guidance',
|
|
85
|
-
},
|
|
86
|
-
],
|
|
87
87
|
input: guideTrailInputSchema,
|
|
88
88
|
intent: 'read',
|
|
89
89
|
output: z.discriminatedUnion('mode', [
|
package/src/trails/load-app.ts
CHANGED
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
} from '@ontrails/core';
|
|
27
27
|
import type { Topo } from '@ontrails/core';
|
|
28
28
|
import { resolveTrailsOverlays } from '@ontrails/adapter-kit';
|
|
29
|
-
import type { TopoGraphOverlayRegistration } from '@ontrails/
|
|
29
|
+
import type { TopoGraphOverlayRegistration } from '@ontrails/topography';
|
|
30
30
|
import { findAppModule } from '@ontrails/cli';
|
|
31
31
|
|
|
32
32
|
import {
|
|
@@ -75,7 +75,7 @@ const getImportScanner = (loader: TranspilerLoader): Bun.Transpiler => {
|
|
|
75
75
|
* @remarks
|
|
76
76
|
* A fresh-loaded module may expose functions whose deferred relative imports
|
|
77
77
|
* are resolved only when those functions run (for example inside a trail's
|
|
78
|
-
* `
|
|
78
|
+
* `implementation`). If we deleted the mirror tree immediately after the initial
|
|
79
79
|
* `import()` resolved, those later resolutions would hit an ENOENT. We keep
|
|
80
80
|
* the mirrors on disk and clean them up once, on process exit.
|
|
81
81
|
*/
|
|
@@ -964,7 +964,7 @@ const mirrorFreshImportGraph = async (
|
|
|
964
964
|
* filesystem imports are mirrored into the fresh temp root. The mirror tree
|
|
965
965
|
* is retained for the lifetime of the process so that deferred relative
|
|
966
966
|
* `import()`/`require()` calls originating from the loaded module (e.g.
|
|
967
|
-
* inside a trail's `
|
|
967
|
+
* inside a trail's `implementation`) can still resolve. If the graph walk itself
|
|
968
968
|
* fails, the partially-written mirror is removed immediately so failed
|
|
969
969
|
* loads do not leak disk space.
|
|
970
970
|
*/
|