@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.
Files changed (58) hide show
  1. package/CHANGELOG.md +88 -0
  2. package/README.md +1 -1
  3. package/package.json +17 -17
  4. package/src/app.ts +4 -4
  5. package/src/cli.ts +1 -1
  6. package/src/completions.ts +1 -1
  7. package/src/mcp-app.ts +2 -2
  8. package/src/regrade/history.ts +148 -38
  9. package/src/regrade/plan-artifact.ts +31 -11
  10. package/src/release/native-bun-registry.ts +12 -1
  11. package/src/release/policy.ts +4 -1
  12. package/src/retired-topo-command.ts +1 -1
  13. package/src/run-watch.ts +1 -1
  14. package/src/run-wayfind-outline.ts +6 -2
  15. package/src/trails/adapter-check.ts +8 -8
  16. package/src/trails/add-surface.ts +2 -2
  17. package/src/trails/add-trail.ts +3 -3
  18. package/src/trails/add-verify.ts +2 -2
  19. package/src/trails/compile.ts +9 -9
  20. package/src/trails/completions-complete.ts +10 -10
  21. package/src/trails/completions.ts +2 -2
  22. package/src/trails/create-adapter.ts +185 -424
  23. package/src/trails/create-scaffold.ts +12 -12
  24. package/src/trails/create-versions.ts +8 -8
  25. package/src/trails/create.ts +35 -35
  26. package/src/trails/deprecate.ts +2 -2
  27. package/src/trails/dev-clean.ts +11 -11
  28. package/src/trails/dev-reset.ts +11 -11
  29. package/src/trails/dev-stats.ts +8 -8
  30. package/src/trails/dev-support.ts +1 -1
  31. package/src/trails/doctor.ts +4 -4
  32. package/src/trails/draft-promote.ts +3 -3
  33. package/src/trails/guide.ts +9 -9
  34. package/src/trails/load-app.ts +3 -3
  35. package/src/trails/regrade.ts +56 -27
  36. package/src/trails/release-check.ts +8 -8
  37. package/src/trails/release-smoke.ts +2 -2
  38. package/src/trails/revise.ts +2 -2
  39. package/src/trails/run-example.ts +9 -9
  40. package/src/trails/run-examples.ts +9 -9
  41. package/src/trails/run.ts +26 -26
  42. package/src/trails/survey.ts +45 -45
  43. package/src/trails/topo-activation.ts +2 -2
  44. package/src/trails/topo-history.ts +8 -8
  45. package/src/trails/topo-output-schemas.ts +5 -5
  46. package/src/trails/topo-pin.ts +6 -6
  47. package/src/trails/topo-read-support.ts +4 -3
  48. package/src/trails/topo-reports.ts +16 -16
  49. package/src/trails/topo-store-support.ts +18 -9
  50. package/src/trails/topo-support.ts +2 -2
  51. package/src/trails/topo-unpin.ts +12 -12
  52. package/src/trails/topo.ts +4 -4
  53. package/src/trails/validate.ts +2 -2
  54. package/src/trails/version-lifecycle-support.ts +17 -16
  55. package/src/trails/warden-guide.ts +8 -8
  56. package/src/trails/warden.ts +21 -21
  57. package/src/trails/wayfind-outline.ts +876 -0
  58. package/src/trails/wayfind.ts +74 -74
@@ -66,6 +66,7 @@ import {
66
66
  regradePlanArtifactSchema,
67
67
  regradePlanPathForPlan,
68
68
  regradeSourceHash,
69
+ regradeSourceHashMatches,
69
70
  rootRelativePath,
70
71
  } from '../regrade/plan-artifact.js';
71
72
  import type {
@@ -1480,7 +1481,7 @@ const planStatusForReport = (
1480
1481
  artifact: RegradePlanArtifact,
1481
1482
  report: RegradeReport
1482
1483
  ): 'active' | 'stale' =>
1483
- artifact.sourceHash === regradeSourceHash(report) ? 'active' : 'stale';
1484
+ regradeSourceHashMatches(artifact.sourceHash, report) ? 'active' : 'stale';
1484
1485
 
1485
1486
  const regradePlanGateContext = (
1486
1487
  report: RegradeReport
@@ -2573,6 +2574,7 @@ const runPreviewRegradePlan = async (
2573
2574
 
2574
2575
  const writeRegradeHistory = (params: {
2575
2576
  readonly artifact: RegradePlanArtifact;
2577
+ readonly completedReport: RegradeReport;
2576
2578
  readonly planPath: string;
2577
2579
  readonly report: RegradeReport;
2578
2580
  readonly rootDir: string;
@@ -2596,6 +2598,7 @@ const writeRegradeHistory = (params: {
2596
2598
  }
2597
2599
  const appended = appendRegradeHistoryRun({
2598
2600
  artifact: params.artifact,
2601
+ completedReport: params.completedReport,
2599
2602
  report: params.report,
2600
2603
  rootDir: params.rootDir,
2601
2604
  });
@@ -2630,6 +2633,24 @@ const writeRegradeHistory = (params: {
2630
2633
  return appended;
2631
2634
  };
2632
2635
 
2636
+ const historyReportForAppliedPlan = (
2637
+ dryRunReport: RegradeReport,
2638
+ appliedReport: RegradeReport
2639
+ ): RegradeReport => ({
2640
+ ...dryRunReport,
2641
+ ...(appliedReport.apply === undefined ? {} : { apply: appliedReport.apply }),
2642
+ ...(dryRunReport.run === undefined
2643
+ ? {}
2644
+ : {
2645
+ run: {
2646
+ ...dryRunReport.run,
2647
+ report:
2648
+ appliedReport.run?.report ??
2649
+ transitionRunReportForRegradeReport(appliedReport),
2650
+ },
2651
+ }),
2652
+ });
2653
+
2633
2654
  const runApplyRegradePlan = async (
2634
2655
  input: RegradeApplyPlanInput,
2635
2656
  rootDir: string,
@@ -2686,14 +2707,22 @@ const runApplyRegradePlan = async (
2686
2707
  if (applied.isErr()) {
2687
2708
  return applied;
2688
2709
  }
2689
- // The recorded run evidence is the freshness-gated dry-run report: its
2690
- // source hash is the lock state this run ran against (the staleness gate
2691
- // holds it equal to the plan's own sourceHash), and unlike the post-apply
2692
- // rescan it preserves the rewrite entries the run graduated.
2710
+ const completionReport = await runPlanArtifactDryRun({
2711
+ artifact: loaded.value.artifact,
2712
+ includeEntries: input.includeEntries,
2713
+ rootDir,
2714
+ });
2715
+ if (completionReport.isErr()) {
2716
+ return completionReport;
2717
+ }
2718
+ // Keep the pre-apply occurrence evidence that explains what this run changed,
2719
+ // while carrying the completed counters and a separate post-apply source
2720
+ // stamp so a later no-op apply can still be recognized as a replay.
2693
2721
  const history = writeRegradeHistory({
2694
2722
  artifact: loaded.value.artifact,
2723
+ completedReport: completionReport.value,
2695
2724
  planPath: loaded.value.path,
2696
- report: dryRunReport.value,
2725
+ report: historyReportForAppliedPlan(dryRunReport.value, applied.value),
2697
2726
  rootDir,
2698
2727
  });
2699
2728
  if (history.isErr()) {
@@ -2828,7 +2857,8 @@ const runClassModeRegrade = (
2828
2857
 
2829
2858
  export const regradeTrail = trail('regrade', {
2830
2859
  args: ['from', 'to'],
2831
- blaze: async (input, ctx) => {
2860
+ description: 'Run downstream migration checks and safe rewrites',
2861
+ implementation: async (input, ctx) => {
2832
2862
  const rootDirResult = resolveTrailRootDir(input.rootDir, ctx.cwd);
2833
2863
  if (rootDirResult.isErr()) {
2834
2864
  return rootDirResult;
@@ -2865,7 +2895,6 @@ export const regradeTrail = trail('regrade', {
2865
2895
  }
2866
2896
  return Result.ok(outputResult.value);
2867
2897
  },
2868
- description: 'Run downstream migration checks and safe rewrites',
2869
2898
  input: regradeInputSchema,
2870
2899
  intent: 'write',
2871
2900
  output: regradeReportOutput,
@@ -2874,7 +2903,9 @@ export const regradeTrail = trail('regrade', {
2874
2903
 
2875
2904
  export const planRegradeTrail = trail('plan.regrade', {
2876
2905
  args: ['from', 'to'],
2877
- blaze: async (input, ctx) => {
2906
+ cli: { path: ['regrade', 'plan'] },
2907
+ description: 'Write or update a reviewed Regrade plan',
2908
+ implementation: async (input, ctx) => {
2878
2909
  const rootDirResult = resolveTrailRootDir(input.rootDir, ctx.cwd);
2879
2910
  if (rootDirResult.isErr()) {
2880
2911
  return rootDirResult;
@@ -2910,8 +2941,6 @@ export const planRegradeTrail = trail('plan.regrade', {
2910
2941
  }
2911
2942
  return Result.ok(output.data);
2912
2943
  },
2913
- cli: { path: ['regrade', 'plan'] },
2914
- description: 'Write or update a reviewed Regrade plan',
2915
2944
  input: regradePlanInputSchema,
2916
2945
  intent: 'write',
2917
2946
  output: regradePlanArtifactSchema,
@@ -2919,7 +2948,9 @@ export const planRegradeTrail = trail('plan.regrade', {
2919
2948
  });
2920
2949
 
2921
2950
  export const listRegradesTrail = trail('list.regrades', {
2922
- blaze: async (input, ctx) => {
2951
+ cli: { path: ['regrade', 'plans'] },
2952
+ description: 'List active Regrade plans and freshness status',
2953
+ implementation: async (input, ctx) => {
2923
2954
  const rootDirResult = resolveTrailRootDir(input.rootDir, ctx.cwd);
2924
2955
  if (rootDirResult.isErr()) {
2925
2956
  return rootDirResult;
@@ -2930,8 +2961,6 @@ export const listRegradesTrail = trail('list.regrades', {
2930
2961
  }
2931
2962
  return Result.ok(result.value);
2932
2963
  },
2933
- cli: { path: ['regrade', 'plans'] },
2934
- description: 'List active Regrade plans and freshness status',
2935
2964
  input: z.object({
2936
2965
  rootDir: z.string().optional().describe('Workspace root directory'),
2937
2966
  }),
@@ -2941,7 +2970,9 @@ export const listRegradesTrail = trail('list.regrades', {
2941
2970
  });
2942
2971
 
2943
2972
  export const checkRegradeTrail = trail('check.regrade', {
2944
- blaze: async (input, ctx) => {
2973
+ cli: { path: ['regrade', 'check'] },
2974
+ description: 'Check a saved Regrade plan gate without writing source',
2975
+ implementation: async (input, ctx) => {
2945
2976
  const rootDirResult = resolveTrailRootDir(input.rootDir, ctx.cwd);
2946
2977
  if (rootDirResult.isErr()) {
2947
2978
  return rootDirResult;
@@ -2967,8 +2998,6 @@ export const checkRegradeTrail = trail('check.regrade', {
2967
2998
  }
2968
2999
  return Result.ok(output.value);
2969
3000
  },
2970
- cli: { path: ['regrade', 'check'] },
2971
- description: 'Check a saved Regrade plan gate without writing source',
2972
3001
  input: regradePlanReferenceInputSchema,
2973
3002
  intent: 'read',
2974
3003
  output: regradeCheckOutputSchema,
@@ -2976,7 +3005,9 @@ export const checkRegradeTrail = trail('check.regrade', {
2976
3005
  });
2977
3006
 
2978
3007
  export const previewRegradeTrail = trail('preview.regrade', {
2979
- blaze: async (input, ctx) => {
3008
+ cli: { path: ['regrade', 'preview'] },
3009
+ description: 'Preview a saved Regrade plan without writing source',
3010
+ implementation: async (input, ctx) => {
2980
3011
  const rootDirResult = resolveTrailRootDir(input.rootDir, ctx.cwd);
2981
3012
  if (rootDirResult.isErr()) {
2982
3013
  return rootDirResult;
@@ -2991,8 +3022,6 @@ export const previewRegradeTrail = trail('preview.regrade', {
2991
3022
  }
2992
3023
  return Result.ok(output.value);
2993
3024
  },
2994
- cli: { path: ['regrade', 'preview'] },
2995
- description: 'Preview a saved Regrade plan without writing source',
2996
3025
  input: regradePlanReferenceInputSchema,
2997
3026
  intent: 'read',
2998
3027
  output: regradeReportOutput,
@@ -3000,7 +3029,9 @@ export const previewRegradeTrail = trail('preview.regrade', {
3000
3029
  });
3001
3030
 
3002
3031
  export const applyRegradeTrail = trail('apply.regrade', {
3003
- blaze: async (input, ctx) => {
3032
+ cli: { path: ['regrade', 'apply'] },
3033
+ description: 'Apply a saved Regrade plan and move it to history',
3034
+ implementation: async (input, ctx) => {
3004
3035
  const rootDirResult = resolveTrailRootDir(input.rootDir, ctx.cwd);
3005
3036
  if (rootDirResult.isErr()) {
3006
3037
  return rootDirResult;
@@ -3019,8 +3050,6 @@ export const applyRegradeTrail = trail('apply.regrade', {
3019
3050
  }
3020
3051
  return Result.ok(output.value);
3021
3052
  },
3022
- cli: { path: ['regrade', 'apply'] },
3023
- description: 'Apply a saved Regrade plan and move it to history',
3024
3053
  input: regradeApplyPlanInputSchema,
3025
3054
  intent: 'write',
3026
3055
  output: regradeReportOutput,
@@ -3029,7 +3058,10 @@ export const applyRegradeTrail = trail('apply.regrade', {
3029
3058
 
3030
3059
  export const adjustRegradeTrail = trail('adjust.regrade', {
3031
3060
  args: ['transition'],
3032
- blaze: async (input, ctx) => {
3061
+ cli: { path: ['regrade', 'adjust'] },
3062
+ description:
3063
+ 'Pull a graduated Regrade transition back to an active plan for adjustment',
3064
+ implementation: async (input, ctx) => {
3033
3065
  const rootDirResult = resolveTrailRootDir(input.rootDir, ctx.cwd);
3034
3066
  if (rootDirResult.isErr()) {
3035
3067
  return rootDirResult;
@@ -3052,9 +3084,6 @@ export const adjustRegradeTrail = trail('adjust.regrade', {
3052
3084
  }
3053
3085
  return Result.ok(output.data);
3054
3086
  },
3055
- cli: { path: ['regrade', 'adjust'] },
3056
- description:
3057
- 'Pull a graduated Regrade transition back to an active plan for adjustment',
3058
3087
  input: regradeAdjustInputSchema,
3059
3088
  intent: 'write',
3060
3089
  output: regradePlanArtifactSchema,
@@ -62,7 +62,14 @@ const releaseCheckOutputSchema = z.object({
62
62
  });
63
63
 
64
64
  export const releaseCheckTrail = trail('release.check', {
65
- blaze: async (input, ctx) => {
65
+ description: 'Check branch-local release rules',
66
+ examples: [
67
+ {
68
+ input: { baseRef: 'HEAD' },
69
+ name: 'Check release rules from the current HEAD',
70
+ },
71
+ ],
72
+ implementation: async (input, ctx) => {
66
73
  const rootDirResult = resolveTrailRootDir(input.rootDir, ctx.cwd);
67
74
  if (rootDirResult.isErr()) {
68
75
  return rootDirResult;
@@ -91,13 +98,6 @@ export const releaseCheckTrail = trail('release.check', {
91
98
  );
92
99
  }
93
100
  },
94
- description: 'Check branch-local release rules',
95
- examples: [
96
- {
97
- input: { baseRef: 'HEAD' },
98
- name: 'Check release rules from the current HEAD',
99
- },
100
- ],
101
101
  input: releaseCheckInputSchema,
102
102
  intent: 'read',
103
103
  output: releaseCheckOutputSchema,
@@ -29,7 +29,8 @@ const releaseSmokeOutputSchema = z.object({
29
29
  });
30
30
 
31
31
  export const releaseSmokeTrail = trail('release.smoke', {
32
- blaze: async (input) => {
32
+ description: 'Run local release confidence smoke checks',
33
+ implementation: async (input) => {
33
34
  try {
34
35
  const check = releaseSmokeCheckSchema.parse(input.check);
35
36
  return Result.ok(await runReleaseSmoke(check));
@@ -41,7 +42,6 @@ export const releaseSmokeTrail = trail('release.smoke', {
41
42
  );
42
43
  }
43
44
  },
44
- description: 'Run local release confidence smoke checks',
45
45
  input: releaseSmokeInputSchema,
46
46
  intent: 'read',
47
47
  output: releaseSmokeOutputSchema,
@@ -11,7 +11,8 @@ import {
11
11
 
12
12
  export const reviseTrail = trail('revise', {
13
13
  args: ['target'],
14
- blaze: async (input, ctx) =>
14
+ description: 'Scaffold the next trail version entry',
15
+ implementation: async (input, ctx) =>
15
16
  withLifecycleApp(input, ctx.cwd, async (app, rootDir) => {
16
17
  const target = parseLifecycleTarget(input.target);
17
18
  if (target.isErr()) {
@@ -32,7 +33,6 @@ export const reviseTrail = trail('revise', {
32
33
  }
33
34
  return reviseTrailSource(rootDir, found.value, input.as);
34
35
  }),
35
- description: 'Scaffold the next trail version entry',
36
36
  input: z.object({
37
37
  as: z
38
38
  .enum(['revision', 'fork'])
@@ -439,7 +439,15 @@ type RunExampleTrailInput = z.output<typeof runExampleTrailInputSchema>;
439
439
 
440
440
  export const runExampleTrail = trail('run.example', {
441
441
  args: ['id', 'exampleName'],
442
- blaze: async (input: RunExampleTrailInput, ctx) =>
442
+ description: 'Run a named example on a trail and compare actual vs expected',
443
+ examples: [
444
+ {
445
+ description: 'Run a named example on a target trail',
446
+ input: buildHappyExampleInput(),
447
+ name: 'Run named example',
448
+ },
449
+ ],
450
+ implementation: async (input: RunExampleTrailInput, ctx) =>
443
451
  withOperatorRootDir(input, ctx, async (rootDir) => {
444
452
  const moduleResolution = await resolveRunModulePath(
445
453
  rootDir,
@@ -460,14 +468,6 @@ export const runExampleTrail = trail('run.example', {
460
468
  )
461
469
  );
462
470
  }),
463
- description: 'Run a named example on a trail and compare actual vs expected',
464
- examples: [
465
- {
466
- description: 'Run a named example on a target trail',
467
- input: buildHappyExampleInput(),
468
- name: 'Run named example',
469
- },
470
- ],
471
471
  input: runExampleTrailInputSchema,
472
472
  intent: 'write',
473
473
  output: runExampleComparisonSchema,
@@ -99,7 +99,15 @@ type RunExamplesTrailInput = z.output<typeof runExamplesTrailInputSchema>;
99
99
 
100
100
  export const runExamplesTrail = trail('run.examples', {
101
101
  args: ['id'],
102
- blaze: async (input: RunExamplesTrailInput, ctx) =>
102
+ description: "List a trail's examples without executing it",
103
+ examples: [
104
+ {
105
+ description: 'List examples authored on a target trail',
106
+ input: buildHappyExampleInput(),
107
+ name: 'List trail examples',
108
+ },
109
+ ],
110
+ implementation: async (input: RunExamplesTrailInput, ctx) =>
103
111
  withOperatorRootDir(input, ctx, async (rootDir) => {
104
112
  const moduleResolution = await resolveRunModulePath(
105
113
  rootDir,
@@ -115,14 +123,6 @@ export const runExamplesTrail = trail('run.examples', {
115
123
  buildExamplesListing(lease.app, input.id)
116
124
  );
117
125
  }),
118
- description: "List a trail's examples without executing it",
119
- examples: [
120
- {
121
- description: 'List examples authored on a target trail',
122
- input: buildHappyExampleInput(),
123
- name: 'List trail examples',
124
- },
125
- ],
126
126
  input: runExamplesTrailInputSchema,
127
127
  intent: 'read',
128
128
  output: runExamplesListingSchema,
package/src/trails/run.ts CHANGED
@@ -37,11 +37,11 @@ import {
37
37
  run,
38
38
  trail,
39
39
  } from '@ontrails/core';
40
- import { buildWorkspaceTrailIndex } from '@ontrails/topographer';
40
+ import { buildWorkspaceTrailIndex } from '@ontrails/topography';
41
41
  import type {
42
42
  WorkspaceTrailCollision,
43
43
  WorkspaceTrailEntry,
44
- } from '@ontrails/topographer';
44
+ } from '@ontrails/topography';
45
45
  import { z } from 'zod';
46
46
 
47
47
  import {
@@ -371,7 +371,30 @@ const resolveInnerTrailInput = (
371
371
 
372
372
  export const runTrail = trail('run', {
373
373
  args: ['id'],
374
- blaze: async (input: RunTrailInput, ctx) =>
374
+ description:
375
+ 'Resolve a trail by ID in the current app and execute it through the shared pipeline',
376
+ examples: [
377
+ {
378
+ description:
379
+ 'Resolve and execute a trail by ID, returning the inner trail Result value',
380
+ input: buildHappyExampleInput(),
381
+ name: 'Run trail by ID',
382
+ },
383
+ {
384
+ description: 'Reject an unknown trail ID with NotFoundError',
385
+ error: 'NotFoundError',
386
+ input: buildNotFoundExampleInput(),
387
+ name: 'Reject unknown trail ID',
388
+ },
389
+ {
390
+ description:
391
+ 'Reject an ambiguous trail ID without --app with AmbiguousError so non-TTY callers see exit code 1',
392
+ error: 'AmbiguousError',
393
+ input: buildAmbiguousExampleInput(),
394
+ name: 'Reject ambiguous trail ID without --app',
395
+ },
396
+ ],
397
+ implementation: async (input: RunTrailInput, ctx) =>
375
398
  withOperatorRootDir(input, ctx, async (rootDir) => {
376
399
  const innerInput = resolveInnerTrailInput(input);
377
400
  if (innerInput.isErr()) {
@@ -404,29 +427,6 @@ export const runTrail = trail('run', {
404
427
  });
405
428
  });
406
429
  }),
407
- description:
408
- 'Resolve a trail by ID in the current app and execute it through the shared pipeline',
409
- examples: [
410
- {
411
- description:
412
- 'Resolve and execute a trail by ID, returning the inner trail Result value',
413
- input: buildHappyExampleInput(),
414
- name: 'Run trail by ID',
415
- },
416
- {
417
- description: 'Reject an unknown trail ID with NotFoundError',
418
- error: 'NotFoundError',
419
- input: buildNotFoundExampleInput(),
420
- name: 'Reject unknown trail ID',
421
- },
422
- {
423
- description:
424
- 'Reject an ambiguous trail ID without --app with AmbiguousError so non-TTY callers see exit code 1',
425
- error: 'AmbiguousError',
426
- input: buildAmbiguousExampleInput(),
427
- name: 'Reject ambiguous trail ID without --app',
428
- },
429
- ],
430
430
  input: runTrailInputSchema,
431
431
  intent: 'write',
432
432
  output: innerTrailResultSchema,
@@ -20,7 +20,7 @@ import type {
20
20
  DiffResult,
21
21
  TopoGraph,
22
22
  TopoGraphOverlayRegistration,
23
- } from '@ontrails/topographer';
23
+ } from '@ontrails/topography';
24
24
  import {
25
25
  createTopoStore,
26
26
  deriveTopoGraphDiff,
@@ -28,7 +28,7 @@ import {
28
28
  resolveTopoGraphVersionReference,
29
29
  TOPO_GRAPH_SCHEMA_VERSION,
30
30
  readTopoGraph,
31
- } from '@ontrails/topographer';
31
+ } from '@ontrails/topography';
32
32
  import { z } from 'zod';
33
33
 
34
34
  import { writeIsolatedExampleJsonFile } from '../local-state-io.js';
@@ -275,14 +275,14 @@ const visibleDetailSeverity = (detail: string): DiffSeverity => {
275
275
  return status === 'archived' ? 'info' : 'warning';
276
276
  }
277
277
  if (
278
- /^Version \d+ (?:kind changed:|Required (?:input|contour) field ".+" added|(?:Input|Output|Contour) field ".+" (?:removed|type changed:|changed from optional to required))/.test(
278
+ /^Version \d+ (?:kind changed:|Required (?:input|entity) field ".+" added|(?:Input|Output|Entity) field ".+" (?:removed|type changed:|changed from optional to required))/.test(
279
279
  detail
280
280
  )
281
281
  ) {
282
282
  return 'breaking';
283
283
  }
284
284
  if (
285
- /^Version \d+ (?:marker changed:|Optional (?:input|contour) field ".+" added|Output field ".+" added)/.test(
285
+ /^Version \d+ (?:marker changed:|Optional (?:input|entity) field ".+" added|Output field ".+" added)/.test(
286
286
  detail
287
287
  )
288
288
  ) {
@@ -669,7 +669,7 @@ const diffEntryOutput = z.object({
669
669
  change: z.enum(['added', 'removed', 'modified']),
670
670
  details: z.array(z.string()).readonly(),
671
671
  id: z.string(),
672
- kind: z.enum(['contour', 'trail', 'signal', 'resource']),
672
+ kind: z.enum(['entity', 'trail', 'signal', 'resource']),
673
673
  severity: z.enum(['info', 'warning', 'breaking']),
674
674
  });
675
675
 
@@ -729,16 +729,6 @@ const surveyMatchOutput = z.discriminatedUnion('kind', [
729
729
 
730
730
  export const surveyTrail = trail('survey', {
731
731
  args: ['id'],
732
- blaze: async (input, ctx) =>
733
- withResolvedSurveyApp(input, ctx.cwd, (app, rootDir, overlays) =>
734
- dispatchSurvey(
735
- app,
736
- input,
737
- rootDir,
738
- overlays,
739
- readSurfaceLayerNamesFromContext(ctx)
740
- )
741
- ),
742
732
  description: 'Full topo introspection',
743
733
  examples: [
744
734
  {
@@ -752,6 +742,16 @@ export const surveyTrail = trail('survey', {
752
742
  name: 'Lookup by ID',
753
743
  },
754
744
  ],
745
+ implementation: async (input, ctx) =>
746
+ withResolvedSurveyApp(input, ctx.cwd, (app, rootDir, overlays) =>
747
+ dispatchSurvey(
748
+ app,
749
+ input,
750
+ rootDir,
751
+ overlays,
752
+ readSurfaceLayerNamesFromContext(ctx)
753
+ )
754
+ ),
755
755
  input: z.object({
756
756
  id: z
757
757
  .string()
@@ -809,10 +809,6 @@ export const surveyTrail = trail('survey', {
809
809
  });
810
810
 
811
811
  export const surveyBriefTrail = trail('survey.brief', {
812
- blaze: async (input, ctx) =>
813
- withResolvedSurveyApp(input, ctx.cwd, (app, rootDir) =>
814
- Result.ok(deriveCurrentTopoBrief(app, { rootDir }))
815
- ),
816
812
  description: 'Summarize topo capabilities',
817
813
  examples: [
818
814
  {
@@ -821,16 +817,16 @@ export const surveyBriefTrail = trail('survey.brief', {
821
817
  name: 'Brief capability report',
822
818
  },
823
819
  ],
820
+ implementation: async (input, ctx) =>
821
+ withResolvedSurveyApp(input, ctx.cwd, (app, rootDir) =>
822
+ Result.ok(deriveCurrentTopoBrief(app, { rootDir }))
823
+ ),
824
824
  input: moduleInputSchema,
825
825
  intent: 'read',
826
826
  output: briefReportSchema,
827
827
  });
828
828
 
829
829
  export const surveySurfacesTrail = trail('survey.surfaces', {
830
- blaze: async (input, ctx) =>
831
- withResolvedSurveyApp(input, ctx.cwd, (app) =>
832
- buildSurveySurfaceInventory(app)
833
- ),
834
830
  description: 'Inventory shipped surface projections',
835
831
  examples: [
836
832
  {
@@ -839,6 +835,10 @@ export const surveySurfacesTrail = trail('survey.surfaces', {
839
835
  name: 'Shipped surface inventory',
840
836
  },
841
837
  ],
838
+ implementation: async (input, ctx) =>
839
+ withResolvedSurveyApp(input, ctx.cwd, (app) =>
840
+ buildSurveySurfaceInventory(app)
841
+ ),
842
842
  input: moduleInputSchema,
843
843
  intent: 'read',
844
844
  output: shippedSurfaceInventoryOutput,
@@ -846,10 +846,6 @@ export const surveySurfacesTrail = trail('survey.surfaces', {
846
846
 
847
847
  export const surveyDiffTrail = trail('survey.diff', {
848
848
  args: ['target'],
849
- blaze: async (input, ctx) =>
850
- withResolvedSurveyApp(input, ctx.cwd, (app, rootDir) =>
851
- buildSurveyDiff(app, rootDir, input)
852
- ),
853
849
  description: 'Diff the current topo against a saved TopoGraph',
854
850
  examples: [
855
851
  {
@@ -883,6 +879,10 @@ export const surveyDiffTrail = trail('survey.diff', {
883
879
  name: 'Reject empty breaking-only target',
884
880
  },
885
881
  ],
882
+ implementation: async (input, ctx) =>
883
+ withResolvedSurveyApp(input, ctx.cwd, (app, rootDir) =>
884
+ buildSurveyDiff(app, rootDir, input)
885
+ ),
886
886
  input: diffInputSchema,
887
887
  intent: 'read',
888
888
  output: diffOutput,
@@ -890,16 +890,6 @@ export const surveyDiffTrail = trail('survey.diff', {
890
890
 
891
891
  export const surveyTrailDetailTrail = trail('survey.trail', {
892
892
  args: ['id'],
893
- blaze: async (input, ctx) =>
894
- withResolvedSurveyApp(input, ctx.cwd, (app, rootDir, overlays) =>
895
- buildSurveyTrailDetail(
896
- app,
897
- input.id,
898
- rootDir,
899
- overlays,
900
- readSurfaceLayerNamesFromContext(ctx)
901
- )
902
- ),
903
893
  description: 'Inspect one trail by ID',
904
894
  examples: [
905
895
  {
@@ -911,6 +901,16 @@ export const surveyTrailDetailTrail = trail('survey.trail', {
911
901
  name: 'Trail detail',
912
902
  },
913
903
  ],
904
+ implementation: async (input, ctx) =>
905
+ withResolvedSurveyApp(input, ctx.cwd, (app, rootDir, overlays) =>
906
+ buildSurveyTrailDetail(
907
+ app,
908
+ input.id,
909
+ rootDir,
910
+ overlays,
911
+ readSurfaceLayerNamesFromContext(ctx)
912
+ )
913
+ ),
914
914
  input: detailInputSchema,
915
915
  intent: 'read',
916
916
  output: trailDetailOutput,
@@ -918,10 +918,6 @@ export const surveyTrailDetailTrail = trail('survey.trail', {
918
918
 
919
919
  export const surveyResourceTrail = trail('survey.resource', {
920
920
  args: ['id'],
921
- blaze: async (input, ctx) =>
922
- withResolvedSurveyApp(input, ctx.cwd, (app, rootDir) =>
923
- buildSurveyResourceDetail(app, input.id, rootDir)
924
- ),
925
921
  description: 'Inspect one resource by ID',
926
922
  examples: [
927
923
  {
@@ -934,6 +930,10 @@ export const surveyResourceTrail = trail('survey.resource', {
934
930
  name: 'Resource detail',
935
931
  },
936
932
  ],
933
+ implementation: async (input, ctx) =>
934
+ withResolvedSurveyApp(input, ctx.cwd, (app, rootDir) =>
935
+ buildSurveyResourceDetail(app, input.id, rootDir)
936
+ ),
937
937
  input: detailInputSchema,
938
938
  intent: 'read',
939
939
  output: resourceDetailOutput,
@@ -941,10 +941,6 @@ export const surveyResourceTrail = trail('survey.resource', {
941
941
 
942
942
  export const surveySignalTrail = trail('survey.signal', {
943
943
  args: ['id'],
944
- blaze: async (input, ctx) =>
945
- withResolvedSurveyApp(input, ctx.cwd, (app, rootDir) =>
946
- buildSurveySignalDetail(app, input.id, rootDir)
947
- ),
948
944
  description: 'Inspect one signal by ID',
949
945
  examples: [
950
946
  {
@@ -957,6 +953,10 @@ export const surveySignalTrail = trail('survey.signal', {
957
953
  name: 'Signal detail',
958
954
  },
959
955
  ],
956
+ implementation: async (input, ctx) =>
957
+ withResolvedSurveyApp(input, ctx.cwd, (app, rootDir) =>
958
+ buildSurveySignalDetail(app, input.id, rootDir)
959
+ ),
960
960
  input: detailInputSchema,
961
961
  intent: 'read',
962
962
  output: signalDetailOutput,
@@ -2,7 +2,7 @@ export {
2
2
  deriveActivationGraph,
3
3
  deriveDeclaredTrailActivation,
4
4
  deriveSignalActivationRelations,
5
- } from '@ontrails/topographer';
5
+ } from '@ontrails/topography';
6
6
  export type {
7
7
  ActivationChainReport,
8
8
  ActivationEdgeReport,
@@ -11,4 +11,4 @@ export type {
11
11
  ActivationSourceReport,
12
12
  SignalActivationRelations,
13
13
  TrailActivationReport,
14
- } from '@ontrails/topographer';
14
+ } from '@ontrails/topography';
@@ -20,14 +20,6 @@ const topoHistoryTrailInputSchema = z.object({
20
20
  type TopoHistoryTrailInput = z.output<typeof topoHistoryTrailInputSchema>;
21
21
 
22
22
  export const topoHistoryTrail = trail('topo.history', {
23
- blaze: (input: TopoHistoryTrailInput, ctx) => {
24
- const rootDirResult = resolveTrailRootDir(input.rootDir, ctx.cwd);
25
- if (rootDirResult.isErr()) {
26
- return rootDirResult;
27
- }
28
- const rootDir = rootDirResult.value;
29
- return Result.ok(listTopoHistory({ limit: input.limit, rootDir }));
30
- },
31
23
  description: 'List saved topo snapshots, including pinned references',
32
24
  examples: [
33
25
  {
@@ -35,6 +27,14 @@ export const topoHistoryTrail = trail('topo.history', {
35
27
  name: 'Show topo history',
36
28
  },
37
29
  ],
30
+ implementation: (input: TopoHistoryTrailInput, ctx) => {
31
+ const rootDirResult = resolveTrailRootDir(input.rootDir, ctx.cwd);
32
+ if (rootDirResult.isErr()) {
33
+ return rootDirResult;
34
+ }
35
+ const rootDir = rootDirResult.value;
36
+ return Result.ok(listTopoHistory({ limit: input.limit, rootDir }));
37
+ },
38
38
  input: topoHistoryTrailInputSchema,
39
39
  intent: 'read',
40
40
  output: z.object({