@ontrails/warden 1.0.0-beta.12 → 1.0.0-beta.13

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 (182) hide show
  1. package/CHANGELOG.md +51 -31
  2. package/README.md +17 -17
  3. package/dist/cli.d.ts +1 -1
  4. package/dist/cli.d.ts.map +1 -1
  5. package/dist/cli.js +14 -10
  6. package/dist/cli.js.map +1 -1
  7. package/dist/drift.d.ts +6 -6
  8. package/dist/drift.d.ts.map +1 -1
  9. package/dist/drift.js +8 -8
  10. package/dist/drift.js.map +1 -1
  11. package/dist/formatters.js +2 -2
  12. package/dist/formatters.js.map +1 -1
  13. package/dist/index.d.ts +4 -4
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +5 -5
  16. package/dist/index.js.map +1 -1
  17. package/dist/rules/ast.d.ts +15 -11
  18. package/dist/rules/ast.d.ts.map +1 -1
  19. package/dist/rules/ast.js +34 -30
  20. package/dist/rules/ast.js.map +1 -1
  21. package/dist/rules/context-no-trailhead-types.d.ts +12 -0
  22. package/dist/rules/context-no-trailhead-types.d.ts.map +1 -0
  23. package/dist/rules/context-no-trailhead-types.js +96 -0
  24. package/dist/rules/context-no-trailhead-types.js.map +1 -0
  25. package/dist/rules/cross-declarations.d.ts +13 -0
  26. package/dist/rules/cross-declarations.d.ts.map +1 -0
  27. package/dist/rules/cross-declarations.js +264 -0
  28. package/dist/rules/cross-declarations.js.map +1 -0
  29. package/dist/rules/follow-declarations.d.ts +1 -1
  30. package/dist/rules/follow-declarations.js +5 -5
  31. package/dist/rules/follow-declarations.js.map +1 -1
  32. package/dist/rules/implementation-returns-result.d.ts +2 -2
  33. package/dist/rules/implementation-returns-result.js +6 -6
  34. package/dist/rules/implementation-returns-result.js.map +1 -1
  35. package/dist/rules/index.d.ts +4 -4
  36. package/dist/rules/index.d.ts.map +1 -1
  37. package/dist/rules/index.js +12 -12
  38. package/dist/rules/index.js.map +1 -1
  39. package/dist/rules/no-direct-impl-in-route.d.ts +4 -4
  40. package/dist/rules/no-direct-impl-in-route.js +14 -14
  41. package/dist/rules/no-direct-impl-in-route.js.map +1 -1
  42. package/dist/rules/no-direct-implementation-call.d.ts +3 -3
  43. package/dist/rules/no-direct-implementation-call.js +7 -7
  44. package/dist/rules/no-direct-implementation-call.js.map +1 -1
  45. package/dist/rules/no-sync-result-assumption.d.ts +1 -1
  46. package/dist/rules/no-sync-result-assumption.js +5 -5
  47. package/dist/rules/no-sync-result-assumption.js.map +1 -1
  48. package/dist/rules/no-throw-in-detour-target.js +2 -2
  49. package/dist/rules/no-throw-in-detour-target.js.map +1 -1
  50. package/dist/rules/no-throw-in-implementation.d.ts +1 -1
  51. package/dist/rules/no-throw-in-implementation.js +3 -3
  52. package/dist/rules/no-throw-in-implementation.js.map +1 -1
  53. package/dist/rules/provision-declarations.d.ts +14 -0
  54. package/dist/rules/provision-declarations.d.ts.map +1 -0
  55. package/dist/rules/provision-declarations.js +344 -0
  56. package/dist/rules/provision-declarations.js.map +1 -0
  57. package/dist/rules/provision-exists.d.ts +6 -0
  58. package/dist/rules/provision-exists.d.ts.map +1 -0
  59. package/dist/rules/provision-exists.js +89 -0
  60. package/dist/rules/provision-exists.js.map +1 -0
  61. package/dist/rules/service-declarations.d.ts +7 -5
  62. package/dist/rules/service-declarations.d.ts.map +1 -1
  63. package/dist/rules/service-declarations.js +106 -103
  64. package/dist/rules/service-declarations.js.map +1 -1
  65. package/dist/rules/service-exists.d.ts +3 -1
  66. package/dist/rules/service-exists.d.ts.map +1 -1
  67. package/dist/rules/service-exists.js +35 -33
  68. package/dist/rules/service-exists.js.map +1 -1
  69. package/dist/rules/specs.d.ts +1 -1
  70. package/dist/rules/specs.d.ts.map +1 -1
  71. package/dist/rules/specs.js +1 -1
  72. package/dist/rules/specs.js.map +1 -1
  73. package/dist/rules/types.d.ts +2 -2
  74. package/dist/rules/types.d.ts.map +1 -1
  75. package/dist/trails/context-no-surface-types.trail.js +1 -1
  76. package/dist/trails/context-no-trailhead-types.trail.d.ts +13 -0
  77. package/dist/trails/context-no-trailhead-types.trail.d.ts.map +1 -0
  78. package/dist/trails/context-no-trailhead-types.trail.js +21 -0
  79. package/dist/trails/context-no-trailhead-types.trail.js.map +1 -0
  80. package/dist/trails/cross-declarations.trail.d.ts +13 -0
  81. package/dist/trails/cross-declarations.trail.d.ts.map +1 -0
  82. package/dist/trails/cross-declarations.trail.js +22 -0
  83. package/dist/trails/cross-declarations.trail.js.map +1 -0
  84. package/dist/trails/follow-declarations.trail.js +1 -1
  85. package/dist/trails/implementation-returns-result.trail.js +1 -1
  86. package/dist/trails/index.d.ts +4 -4
  87. package/dist/trails/index.d.ts.map +1 -1
  88. package/dist/trails/index.js +4 -4
  89. package/dist/trails/index.js.map +1 -1
  90. package/dist/trails/no-direct-impl-in-route.trail.js +4 -4
  91. package/dist/trails/no-direct-impl-in-route.trail.js.map +1 -1
  92. package/dist/trails/no-direct-implementation-call.trail.js +2 -2
  93. package/dist/trails/no-direct-implementation-call.trail.js.map +1 -1
  94. package/dist/trails/no-sync-result-assumption.trail.js +2 -2
  95. package/dist/trails/no-sync-result-assumption.trail.js.map +1 -1
  96. package/dist/trails/no-throw-in-detour-target.trail.d.ts +1 -1
  97. package/dist/trails/no-throw-in-detour-target.trail.js +1 -1
  98. package/dist/trails/no-throw-in-implementation.trail.js +1 -1
  99. package/dist/trails/prefer-schema-inference.trail.js +1 -1
  100. package/dist/trails/provision-declarations.trail.d.ts +13 -0
  101. package/dist/trails/provision-declarations.trail.d.ts.map +1 -0
  102. package/dist/trails/provision-declarations.trail.js +25 -0
  103. package/dist/trails/provision-declarations.trail.js.map +1 -0
  104. package/dist/trails/provision-exists.trail.d.ts +15 -0
  105. package/dist/trails/provision-exists.trail.d.ts.map +1 -0
  106. package/dist/trails/provision-exists.trail.js +27 -0
  107. package/dist/trails/provision-exists.trail.js.map +1 -0
  108. package/dist/trails/run.d.ts +2 -2
  109. package/dist/trails/run.d.ts.map +1 -1
  110. package/dist/trails/run.js +6 -6
  111. package/dist/trails/run.js.map +1 -1
  112. package/dist/trails/schema.d.ts +1 -1
  113. package/dist/trails/schema.js +2 -2
  114. package/dist/trails/schema.js.map +1 -1
  115. package/dist/trails/service-declarations.trail.d.ts +13 -0
  116. package/dist/trails/service-declarations.trail.d.ts.map +1 -1
  117. package/dist/trails/service-declarations.trail.js +9 -7
  118. package/dist/trails/service-declarations.trail.js.map +1 -1
  119. package/dist/trails/service-exists.trail.d.ts +17 -0
  120. package/dist/trails/service-exists.trail.d.ts.map +1 -1
  121. package/dist/trails/service-exists.trail.js +10 -8
  122. package/dist/trails/service-exists.trail.js.map +1 -1
  123. package/dist/trails/valid-describe-refs.trail.d.ts +1 -1
  124. package/dist/trails/valid-detour-refs.trail.d.ts +1 -1
  125. package/dist/trails/valid-detour-refs.trail.js +2 -2
  126. package/dist/trails/wrap-rule.js +14 -14
  127. package/dist/trails/wrap-rule.js.map +1 -1
  128. package/package.json +1 -1
  129. package/src/__tests__/cli.test.ts +8 -8
  130. package/src/__tests__/{follow-declarations.test.ts → cross-declarations.test.ts} +78 -78
  131. package/src/__tests__/drift.test.ts +5 -5
  132. package/src/__tests__/formatters.test.ts +2 -2
  133. package/src/__tests__/implementation-returns-result.test.ts +11 -11
  134. package/src/__tests__/no-direct-implementation-call.test.ts +10 -10
  135. package/src/__tests__/no-sync-result-assumption.test.ts +6 -6
  136. package/src/__tests__/no-throw-in-detour-target.test.ts +6 -6
  137. package/src/__tests__/prefer-schema-inference.test.ts +4 -4
  138. package/src/__tests__/provision-declarations.test.ts +318 -0
  139. package/src/__tests__/provision-exists.test.ts +122 -0
  140. package/src/__tests__/rules.test.ts +38 -38
  141. package/src/__tests__/valid-describe-refs.test.ts +4 -4
  142. package/src/__tests__/wrap-rule.test.ts +4 -4
  143. package/src/cli.ts +17 -13
  144. package/src/drift.ts +12 -12
  145. package/src/formatters.ts +2 -2
  146. package/src/index.ts +8 -8
  147. package/src/rules/ast.ts +36 -31
  148. package/src/rules/{context-no-surface-types.ts → context-no-trailhead-types.ts} +8 -8
  149. package/src/rules/{follow-declarations.ts → cross-declarations.ts} +63 -56
  150. package/src/rules/implementation-returns-result.ts +6 -6
  151. package/src/rules/index.ts +12 -12
  152. package/src/rules/no-direct-impl-in-route.ts +17 -17
  153. package/src/rules/no-direct-implementation-call.ts +7 -7
  154. package/src/rules/no-sync-result-assumption.ts +5 -5
  155. package/src/rules/no-throw-in-detour-target.ts +2 -2
  156. package/src/rules/no-throw-in-implementation.ts +3 -3
  157. package/src/rules/{service-declarations.ts → provision-declarations.ts} +145 -129
  158. package/src/rules/{service-exists.ts → provision-exists.ts} +51 -46
  159. package/src/rules/specs.ts +4 -4
  160. package/src/rules/types.ts +2 -2
  161. package/src/trails/{context-no-surface-types.trail.ts → context-no-trailhead-types.trail.ts} +5 -5
  162. package/src/trails/cross-declarations.trail.ts +22 -0
  163. package/src/trails/implementation-returns-result.trail.ts +1 -1
  164. package/src/trails/index.ts +4 -4
  165. package/src/trails/no-direct-impl-in-route.trail.ts +4 -4
  166. package/src/trails/no-direct-implementation-call.trail.ts +2 -2
  167. package/src/trails/no-sync-result-assumption.trail.ts +2 -2
  168. package/src/trails/no-throw-in-detour-target.trail.ts +1 -1
  169. package/src/trails/no-throw-in-implementation.trail.ts +1 -1
  170. package/src/trails/prefer-schema-inference.trail.ts +1 -1
  171. package/src/trails/provision-declarations.trail.ts +25 -0
  172. package/src/trails/provision-exists.trail.ts +27 -0
  173. package/src/trails/run.ts +7 -7
  174. package/src/trails/schema.ts +2 -2
  175. package/src/trails/valid-detour-refs.trail.ts +2 -2
  176. package/src/trails/wrap-rule.ts +17 -17
  177. package/tsconfig.tsbuildinfo +1 -1
  178. package/src/__tests__/service-declarations.test.ts +0 -318
  179. package/src/__tests__/service-exists.test.ts +0 -122
  180. package/src/trails/follow-declarations.trail.ts +0 -22
  181. package/src/trails/service-declarations.trail.ts +0 -25
  182. package/src/trails/service-exists.trail.ts +0 -27
@@ -9,7 +9,7 @@ trail("entity.show", {
9
9
  input: z.object({
10
10
  query: z.string().describe("Search query. @see entity.search"),
11
11
  }),
12
- run: (input) => Result.ok(input),
12
+ blaze: (input) => Result.ok(input),
13
13
  })`;
14
14
 
15
15
  const diagnostics = validDescribeRefs.check(code, 'src/entity.ts');
@@ -23,14 +23,14 @@ trail("entity.show", {
23
23
  const code = `
24
24
  trail("entity.search", {
25
25
  input: z.object({ query: z.string() }),
26
- run: (input) => Result.ok(input),
26
+ blaze: (input) => Result.ok(input),
27
27
  })
28
28
 
29
29
  trail("entity.show", {
30
30
  input: z.object({
31
31
  query: z.string().describe("Search query. @see entity.search"),
32
32
  }),
33
- run: (input) => Result.ok(input),
33
+ blaze: (input) => Result.ok(input),
34
34
  })`;
35
35
 
36
36
  const diagnostics = validDescribeRefs.check(code, 'src/entity.ts');
@@ -44,7 +44,7 @@ trail("entity.show", {
44
44
  input: z.object({
45
45
  query: z.string().describe("Search query. @see entity.search"),
46
46
  }),
47
- run: (input) => Result.ok(input),
47
+ blaze: (input) => Result.ok(input),
48
48
  })`;
49
49
 
50
50
  const diagnostics = validDescribeRefs.checkWithContext(
@@ -6,10 +6,10 @@ import { wrapRule } from '../trails/wrap-rule.js';
6
6
  import type { ProjectAwareWardenRule } from '../rules/types.js';
7
7
 
8
8
  describe('wrapRule', () => {
9
- test('preserves undefined knownServiceIds and defaults knownTrailIds to empty set', async () => {
9
+ test('preserves undefined knownProvisionIds and defaults knownTrailIds to empty set', async () => {
10
10
  let capturedContext:
11
11
  | {
12
- readonly knownServiceIds?: ReadonlySet<string>;
12
+ readonly knownProvisionIds?: ReadonlySet<string>;
13
13
  readonly knownTrailIds?: ReadonlySet<string>;
14
14
  }
15
15
  | undefined;
@@ -26,7 +26,7 @@ describe('wrapRule', () => {
26
26
  };
27
27
 
28
28
  const wrapped = wrapRule({ examples: [], rule });
29
- const result = await wrapped.run(
29
+ const result = await wrapped.blaze(
30
30
  { filePath: 'entity.ts', sourceCode: '' },
31
31
  createTrailContext()
32
32
  );
@@ -34,7 +34,7 @@ describe('wrapRule', () => {
34
34
  expect(result.isOk()).toBe(true);
35
35
  expect(result.unwrap()).toEqual({ diagnostics: [] });
36
36
  expect(capturedContext).toEqual({
37
- knownServiceIds: undefined,
37
+ knownProvisionIds: undefined,
38
38
  knownTrailIds: new Set<string>(),
39
39
  });
40
40
  });
package/src/cli.ts CHANGED
@@ -12,7 +12,7 @@ import type { Topo } from '@ontrails/core';
12
12
  import type { DriftResult } from './drift.js';
13
13
  import { checkDrift } from './drift.js';
14
14
  import {
15
- collectServiceDefinitionIds,
15
+ collectProvisionDefinitionIds,
16
16
  findConfigProperty,
17
17
  findTrailDefinitions,
18
18
  parse,
@@ -36,7 +36,7 @@ export interface WardenOptions {
36
36
  readonly lintOnly?: boolean | undefined;
37
37
  /** Only run drift detection, skip lint rules */
38
38
  readonly driftOnly?: boolean | undefined;
39
- /** App topology for drift detection. When provided, enables real surface lock comparison. */
39
+ /** App topology for drift detection. When provided, enables real trailhead lock comparison. */
40
40
  readonly topo?: Topo | undefined;
41
41
  }
42
42
 
@@ -133,17 +133,17 @@ const collectDetourTargetTrailIds = (
133
133
  }
134
134
  };
135
135
 
136
- const collectKnownServiceIds = (
136
+ const collectKnownProvisionIds = (
137
137
  sourceCode: string,
138
138
  filePath: string,
139
- knownServiceIds: Set<string>
139
+ knownProvisionIds: Set<string>
140
140
  ): void => {
141
141
  const ast = parse(filePath, sourceCode);
142
142
  if (!ast) {
143
143
  return;
144
144
  }
145
- for (const id of collectServiceDefinitionIds(ast)) {
146
- knownServiceIds.add(id);
145
+ for (const id of collectProvisionDefinitionIds(ast)) {
146
+ knownProvisionIds.add(id);
147
147
  }
148
148
  };
149
149
 
@@ -190,17 +190,21 @@ const collectTopoDetourTargetTrailIds = (
190
190
 
191
191
  const buildProjectContextFromTopo = (appTopo: Topo): ProjectContext => {
192
192
  const knownTrailIds = new Set<string>(appTopo.trails.keys());
193
- const knownServiceIds = new Set<string>(appTopo.services.keys());
193
+ const knownProvisionIds = new Set<string>(appTopo.provisions.keys());
194
194
  const detourTargetTrailIds = collectTopoDetourTargetTrailIds(appTopo);
195
195
 
196
- return { detourTargetTrailIds, knownServiceIds, knownTrailIds };
196
+ return {
197
+ detourTargetTrailIds,
198
+ knownProvisionIds,
199
+ knownTrailIds,
200
+ };
197
201
  };
198
202
 
199
203
  const buildProjectContextFromFiles = (
200
204
  sourceFiles: readonly SourceFile[]
201
205
  ): ProjectContext => {
202
206
  const knownTrailIds = new Set<string>();
203
- const knownServiceIds = new Set<string>();
207
+ const knownProvisionIds = new Set<string>();
204
208
  const detourTargetTrailIds = new Set<string>();
205
209
 
206
210
  for (const sourceFile of sourceFiles) {
@@ -209,10 +213,10 @@ const buildProjectContextFromFiles = (
209
213
  sourceFile.filePath,
210
214
  knownTrailIds
211
215
  );
212
- collectKnownServiceIds(
216
+ collectKnownProvisionIds(
213
217
  sourceFile.sourceCode,
214
218
  sourceFile.filePath,
215
- knownServiceIds
219
+ knownProvisionIds
216
220
  );
217
221
  collectDetourTargetTrailIds(
218
222
  sourceFile.sourceCode,
@@ -223,7 +227,7 @@ const buildProjectContextFromFiles = (
223
227
 
224
228
  return {
225
229
  detourTargetTrailIds,
226
- knownServiceIds,
230
+ knownProvisionIds,
227
231
  knownTrailIds,
228
232
  };
229
233
  };
@@ -324,7 +328,7 @@ const formatDriftSection = (drift: DriftResult | null): string[] => {
324
328
  return [];
325
329
  }
326
330
  const label = drift.stale
327
- ? 'Drift: surface.lock is stale (regenerate with `trails survey generate`)'
331
+ ? 'Drift: trailhead.lock is stale (regenerate with `trails survey generate`)'
328
332
  : 'Drift: clean';
329
333
  return [label, ''];
330
334
  };
package/src/drift.ts CHANGED
@@ -1,32 +1,32 @@
1
1
  /**
2
- * Surface lock drift detection.
2
+ * Trailhead lock drift detection.
3
3
  *
4
- * Compares the committed `surface.lock` hash against a freshly generated
5
- * surface map hash to detect when the trail topology has changed without
4
+ * Compares the committed `trailhead.lock` hash against a freshly generated
5
+ * trailhead map hash to detect when the trail topology has changed without
6
6
  * updating the lock file.
7
7
  */
8
8
 
9
9
  import type { Topo } from '@ontrails/core';
10
10
  import {
11
- generateSurfaceMap,
12
- hashSurfaceMap,
13
- readSurfaceLock,
11
+ generateTrailheadMap,
12
+ hashTrailheadMap,
13
+ readTrailheadLock,
14
14
  } from '@ontrails/schema';
15
15
 
16
16
  /**
17
- * Result of a drift check comparing committed surface.lock against the current state.
17
+ * Result of a drift check comparing committed trailhead.lock against the current state.
18
18
  */
19
19
  export interface DriftResult {
20
20
  /** Whether the committed lock is out of date */
21
21
  readonly stale: boolean;
22
- /** Hash from the committed surface.lock file, or null if not found */
22
+ /** Hash from the committed trailhead.lock file, or null if not found */
23
23
  readonly committedHash: string | null;
24
24
  /** Hash computed from the current trail topology */
25
25
  readonly currentHash: string;
26
26
  }
27
27
 
28
28
  /**
29
- * Check whether the committed surface.lock is stale compared to the current topology.
29
+ * Check whether the committed trailhead.lock is stale compared to the current topology.
30
30
  *
31
31
  * When no topo is provided, returns a clean result (no drift detectable without runtime info).
32
32
  */
@@ -38,9 +38,9 @@ export const checkDrift = async (
38
38
  return { committedHash: null, currentHash: 'unknown', stale: false };
39
39
  }
40
40
 
41
- const surfaceMap = generateSurfaceMap(topo);
42
- const currentHash = hashSurfaceMap(surfaceMap);
43
- const committedHash = await readSurfaceLock({ dir: rootDir });
41
+ const trailheadMap = generateTrailheadMap(topo);
42
+ const currentHash = hashTrailheadMap(trailheadMap);
43
+ const committedHash = await readTrailheadLock({ dir: rootDir });
44
44
 
45
45
  return {
46
46
  committedHash,
package/src/formatters.ts CHANGED
@@ -33,7 +33,7 @@ export const formatGitHubAnnotations = (report: WardenReport): string => {
33
33
 
34
34
  if (report.drift?.stale) {
35
35
  lines.push(
36
- '::error::drift: surface.lock is stale (regenerate with `trails survey generate`)'
36
+ '::error::drift: trailhead.lock is stale (regenerate with `trails survey generate`)'
37
37
  );
38
38
  }
39
39
 
@@ -88,7 +88,7 @@ const driftSection = (drift: WardenReport['drift']): readonly string[] => {
88
88
  return [
89
89
  '',
90
90
  '### Drift',
91
- '- surface.lock is stale (regenerate with `trails survey generate`)',
91
+ '- trailhead.lock is stale (regenerate with `trails survey generate`)',
92
92
  ];
93
93
  };
94
94
 
package/src/index.ts CHANGED
@@ -18,7 +18,7 @@ export type {
18
18
 
19
19
  // Individual rules
20
20
  export { noThrowInImplementation } from './rules/no-throw-in-implementation.js';
21
- export { contextNoSurfaceTypes } from './rules/context-no-surface-types.js';
21
+ export { contextNoTrailheadTypes } from './rules/context-no-trailhead-types.js';
22
22
  export { validDetourRefs } from './rules/valid-detour-refs.js';
23
23
  export { noDirectImplInRoute } from './rules/no-direct-impl-in-route.js';
24
24
  export { noDirectImplementationCall } from './rules/no-direct-implementation-call.js';
@@ -26,8 +26,8 @@ export { noSyncResultAssumption } from './rules/no-sync-result-assumption.js';
26
26
  export { implementationReturnsResult } from './rules/implementation-returns-result.js';
27
27
  export { noThrowInDetourTarget } from './rules/no-throw-in-detour-target.js';
28
28
  export { preferSchemaInference } from './rules/prefer-schema-inference.js';
29
- export { serviceDeclarations } from './rules/service-declarations.js';
30
- export { serviceExists } from './rules/service-exists.js';
29
+ export { provisionDeclarations } from './rules/provision-declarations.js';
30
+ export { provisionExists } from './rules/provision-exists.js';
31
31
  export { validDescribeRefs } from './rules/valid-describe-refs.js';
32
32
 
33
33
  // Rule registry
@@ -48,13 +48,13 @@ export {
48
48
  export type { DriftResult } from './drift.js';
49
49
  export { checkDrift } from './drift.js';
50
50
 
51
- // Trail layer
51
+ // Trail gate
52
52
  export { wardenTopo } from './trails/topo.js';
53
53
  export { runWardenTrails } from './trails/run.js';
54
54
  export {
55
- contextNoSurfaceTypesTrail,
55
+ contextNoTrailheadTypesTrail,
56
+ crossDeclarationsTrail,
56
57
  diagnosticSchema,
57
- followDeclarationsTrail,
58
58
  implementationReturnsResultTrail,
59
59
  noDirectImplInRouteTrail,
60
60
  noDirectImplementationCallTrail,
@@ -64,8 +64,8 @@ export {
64
64
  preferSchemaInferenceTrail,
65
65
  ruleInput,
66
66
  ruleOutput,
67
- serviceDeclarationsTrail,
68
- serviceExistsTrail,
67
+ provisionDeclarationsTrail,
68
+ provisionExistsTrail,
69
69
  validDescribeRefsTrail,
70
70
  validDetourRefsTrail,
71
71
  } from './trails/index.js';
package/src/rules/ast.ts CHANGED
@@ -92,7 +92,7 @@ const walkScopeInner: WalkFn = (node, visit) => {
92
92
  /**
93
93
  * Walk an AST node tree without descending into nested function scopes.
94
94
  * The root node is always traversed; only inner function boundaries are skipped.
95
- * Useful for service-access analysis where inner functions may shadow
95
+ * Useful for provision-access analysis where inner functions may shadow
96
96
  * the trail context parameter name.
97
97
  */
98
98
  export const walkScope: WalkFn = (node, visit) => {
@@ -166,11 +166,11 @@ export const extractFirstStringArg = (node: AstNode): string | null => {
166
166
  return extractStringLiteral(firstArg);
167
167
  };
168
168
 
169
- const isServiceCall = (node: AstNode | undefined): boolean =>
169
+ const isProvisionCall = (node: AstNode | undefined): boolean =>
170
170
  !!node &&
171
171
  node.type === 'CallExpression' &&
172
172
  identifierName((node as unknown as { callee?: AstNode }).callee) ===
173
- 'service';
173
+ 'provision';
174
174
 
175
175
  const extractBindingName = (node: AstNode | undefined): string | null => {
176
176
  if (!node) {
@@ -185,8 +185,8 @@ const extractBindingName = (node: AstNode | undefined): string | null => {
185
185
  return null;
186
186
  };
187
187
 
188
- /** Collect `const foo = service('id', ...)` bindings from a parsed file. */
189
- export const collectNamedServiceIds = (
188
+ /** Collect `const foo = provision('id', ...)` bindings from a parsed file. */
189
+ export const collectNamedProvisionIds = (
190
190
  ast: AstNode
191
191
  ): ReadonlyMap<string, string> => {
192
192
  const ids = new Map<string, string>();
@@ -200,28 +200,28 @@ export const collectNamedServiceIds = (
200
200
  readonly id?: AstNode;
201
201
  readonly init?: AstNode;
202
202
  };
203
- if (!isServiceCall(init)) {
203
+ if (!isProvisionCall(init)) {
204
204
  return;
205
205
  }
206
206
 
207
207
  const name = extractBindingName(id);
208
- const serviceId = init ? extractFirstStringArg(init) : null;
209
- if (name && serviceId) {
210
- ids.set(name, serviceId);
208
+ const provisionId = init ? extractFirstStringArg(init) : null;
209
+ if (name && provisionId) {
210
+ ids.set(name, provisionId);
211
211
  }
212
212
  });
213
213
 
214
214
  return ids;
215
215
  };
216
216
 
217
- /** Collect all inline `service('id', ...)` definition IDs from a parsed file. */
218
- export const collectServiceDefinitionIds = (
217
+ /** Collect all inline `provision('id', ...)` definition IDs from a parsed file. */
218
+ export const collectProvisionDefinitionIds = (
219
219
  ast: AstNode
220
220
  ): ReadonlySet<string> => {
221
221
  const ids = new Set<string>();
222
222
 
223
223
  walk(ast, (node) => {
224
- if (!isServiceCall(node)) {
224
+ if (!isProvisionCall(node)) {
225
225
  return;
226
226
  }
227
227
 
@@ -234,6 +234,11 @@ export const collectServiceDefinitionIds = (
234
234
  return ids;
235
235
  };
236
236
 
237
+ /** Backward-compatible aliases while the migration is in flight. */
238
+ export const collectNamedServiceIds = collectNamedProvisionIds;
239
+ /** Backward-compatible aliases while the migration is in flight. */
240
+ export const collectServiceDefinitionIds = collectProvisionDefinitionIds;
241
+
237
242
  // ---------------------------------------------------------------------------
238
243
  // Config property extraction helpers
239
244
  // ---------------------------------------------------------------------------
@@ -265,7 +270,7 @@ export const findConfigProperty = (
265
270
  export interface TrailDefinition {
266
271
  /** Trail ID string, e.g. "entity.show" */
267
272
  readonly id: string;
268
- /** "trail" or "event" */
273
+ /** "trail" or "signal" */
269
274
  readonly kind: string;
270
275
  /** The config object argument (second arg to trail() call) */
271
276
  readonly config: AstNode;
@@ -275,11 +280,11 @@ export interface TrailDefinition {
275
280
 
276
281
  /**
277
282
  * Find all `trail("id", { ... })`, `trail({ id: "x", ... })`, and
278
- * `event("id", { ... })` call sites.
283
+ * `signal("id", { ... })` call sites.
279
284
  *
280
285
  * Returns the trail ID, kind, and config object node for each definition.
281
286
  */
282
- const TRAIL_CALLEE_NAMES = new Set(['trail', 'event']);
287
+ const TRAIL_CALLEE_NAMES = new Set(['trail', 'signal']);
283
288
 
284
289
  const getTrailCalleeName = (node: AstNode): string | null => {
285
290
  if (node.type !== 'CallExpression') {
@@ -376,22 +381,22 @@ export const findTrailDefinitions = (ast: AstNode): TrailDefinition[] => {
376
381
  };
377
382
 
378
383
  // ---------------------------------------------------------------------------
379
- // Run body extraction
384
+ // Blaze body extraction
380
385
  // ---------------------------------------------------------------------------
381
386
 
382
387
  /**
383
- * Extract top-level `run:` property values from an ObjectExpression's direct properties.
388
+ * Extract top-level `blaze:` property values from an ObjectExpression's direct properties.
384
389
  *
385
- * Does not recurse into nested objects, so `metadata: { run: ... }` is ignored.
390
+ * Does not recurse into nested objects, so `meta: { blaze: ... }` is ignored.
386
391
  */
387
- const extractRunFromConfig = (config: AstNode): AstNode[] => {
392
+ const extractBlazeFromConfig = (config: AstNode): AstNode[] => {
388
393
  const bodies: AstNode[] = [];
389
394
  const properties = config['properties'] as readonly AstNode[] | undefined;
390
395
  if (!properties) {
391
396
  return bodies;
392
397
  }
393
398
  for (const prop of properties) {
394
- if (prop.type === 'Property' && prop.key?.name === 'run' && prop.value) {
399
+ if (prop.type === 'Property' && prop.key?.name === 'blaze' && prop.value) {
395
400
  bodies.push(prop.value);
396
401
  }
397
402
  }
@@ -399,22 +404,22 @@ const extractRunFromConfig = (config: AstNode): AstNode[] => {
399
404
  };
400
405
 
401
406
  /**
402
- * Find `run:` property values.
407
+ * Find `blaze:` property values.
403
408
  *
404
- * When given an ObjectExpression (trail config), returns only its direct `run:`
409
+ * When given an ObjectExpression (trail config), returns only its direct `blaze:`
405
410
  * properties. When given a full AST, finds trail definitions first and extracts
406
- * `run:` from each config — in both cases ignoring nested `run:` properties
407
- * (e.g. `metadata: { run: ... }`).
411
+ * `blaze:` from each config — in both cases ignoring nested `blaze:` properties
412
+ * (e.g. `meta: { blaze: ... }`).
408
413
  */
409
- export const findRunBodies = (node: AstNode): AstNode[] => {
414
+ export const findBlazeBodies = (node: AstNode): AstNode[] => {
410
415
  if (node.type === 'ObjectExpression') {
411
- return extractRunFromConfig(node);
416
+ return extractBlazeFromConfig(node);
412
417
  }
413
418
 
414
- // Full AST — find trail definitions and extract run from their configs
419
+ // Full AST — find trail definitions and extract blaze from their configs
415
420
  const bodies: AstNode[] = [];
416
421
  for (const def of findTrailDefinitions(node)) {
417
- bodies.push(...extractRunFromConfig(def.config));
422
+ bodies.push(...extractBlazeFromConfig(def.config));
418
423
  }
419
424
  return bodies;
420
425
  };
@@ -423,8 +428,8 @@ export const findRunBodies = (node: AstNode): AstNode[] => {
423
428
  // Misc helpers
424
429
  // ---------------------------------------------------------------------------
425
430
 
426
- /** Check if a node is a call to `.run()` on some object. */
427
- export const isRunCall = (node: AstNode): boolean => {
431
+ /** Check if a node is a call to `.blaze()` on some object. */
432
+ export const isBlazeCall = (node: AstNode): boolean => {
428
433
  if (node.type !== 'CallExpression') {
429
434
  return false;
430
435
  }
@@ -441,6 +446,6 @@ export const isRunCall = (node: AstNode): boolean => {
441
446
  const prop = (callee as unknown as { property?: AstNode }).property;
442
447
  return (
443
448
  prop?.type === 'Identifier' &&
444
- (prop as unknown as { name: string }).name === 'run'
449
+ (prop as unknown as { name: string }).name === 'blaze'
445
450
  );
446
451
  };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Detects imports of surface-specific modules and types in trail files.
2
+ * Detects imports of trailhead-specific modules and types in trail files.
3
3
  *
4
4
  * Uses AST parsing for accurate detection — no false positives from
5
5
  * imports in comments or strings.
@@ -49,7 +49,7 @@ const makeDiag = (
49
49
  filePath,
50
50
  line: offsetToLine(sourceCode, node.start),
51
51
  message,
52
- rule: 'context-no-surface-types',
52
+ rule: 'context-no-trailhead-types',
53
53
  severity: 'error',
54
54
  });
55
55
 
@@ -92,7 +92,7 @@ const checkSpecifiersForSurfaceTypes = (
92
92
  filePath,
93
93
  sourceCode,
94
94
  node,
95
- `Do not import surface type "${typeName}" in trail implementation files.`
95
+ `Do not import trailhead type "${typeName}" in trail implementation files.`
96
96
  );
97
97
  };
98
98
 
@@ -111,7 +111,7 @@ const classifyImport = (
111
111
  filePath,
112
112
  sourceCode,
113
113
  node,
114
- `Do not import from surface module "${moduleName}" in trail implementation files.`
114
+ `Do not import from trailhead module "${moduleName}" in trail implementation files.`
115
115
  );
116
116
  }
117
117
 
@@ -119,9 +119,9 @@ const classifyImport = (
119
119
  };
120
120
 
121
121
  /**
122
- * Detects imports of surface-specific types in trail implementation files.
122
+ * Detects imports of trailhead-specific types in trail implementation files.
123
123
  */
124
- export const contextNoSurfaceTypes: WardenRule = {
124
+ export const contextNoTrailheadTypes: WardenRule = {
125
125
  check(sourceCode: string, filePath: string): readonly WardenDiagnostic[] {
126
126
  if (!/\btrail\s*\(/.test(sourceCode)) {
127
127
  return [];
@@ -143,8 +143,8 @@ export const contextNoSurfaceTypes: WardenRule = {
143
143
  return diagnostics;
144
144
  },
145
145
  description:
146
- 'Disallow surface-specific type imports (Request, Response, McpSession, etc.) in trail implementation files.',
147
- name: 'context-no-surface-types',
146
+ 'Disallow trailhead-specific type imports (Request, Response, McpSession, etc.) in trail implementation files.',
147
+ name: 'context-no-trailhead-types',
148
148
 
149
149
  severity: 'error',
150
150
  };