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

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 (155) hide show
  1. package/.turbo/turbo-lint.log +1 -1
  2. package/CHANGELOG.md +13 -0
  3. package/__tests__/examples.test.ts +29 -4
  4. package/dist/src/app.js +2 -2
  5. package/dist/src/app.js.map +1 -1
  6. package/dist/src/clack.d.ts +1 -1
  7. package/dist/src/clack.js +1 -1
  8. package/dist/src/cli.js +4 -3
  9. package/dist/src/cli.js.map +1 -1
  10. package/dist/src/trails/add-surface.d.ts +3 -3
  11. package/dist/src/trails/add-surface.d.ts.map +1 -1
  12. package/dist/src/trails/add-surface.js +46 -24
  13. package/dist/src/trails/add-surface.js.map +1 -1
  14. package/dist/src/trails/add-trail.d.ts +3 -1
  15. package/dist/src/trails/add-trail.d.ts.map +1 -1
  16. package/dist/src/trails/add-trail.js +38 -11
  17. package/dist/src/trails/add-trail.js.map +1 -1
  18. package/dist/src/trails/add-trailhead.d.ts +1 -1
  19. package/dist/src/trails/add-trailhead.d.ts.map +1 -1
  20. package/dist/src/trails/add-trailhead.js +4 -4
  21. package/dist/src/trails/add-verify.d.ts +1 -1
  22. package/dist/src/trails/add-verify.d.ts.map +1 -1
  23. package/dist/src/trails/add-verify.js +7 -6
  24. package/dist/src/trails/add-verify.js.map +1 -1
  25. package/dist/src/trails/create-scaffold.d.ts +1 -1
  26. package/dist/src/trails/create-scaffold.d.ts.map +1 -1
  27. package/dist/src/trails/create-scaffold.js +10 -3
  28. package/dist/src/trails/create-scaffold.js.map +1 -1
  29. package/dist/src/trails/create.d.ts +10 -14
  30. package/dist/src/trails/create.d.ts.map +1 -1
  31. package/dist/src/trails/create.js +42 -37
  32. package/dist/src/trails/create.js.map +1 -1
  33. package/dist/src/trails/dev-clean.d.ts +4 -4
  34. package/dist/src/trails/dev-clean.d.ts.map +1 -1
  35. package/dist/src/trails/dev-clean.js +22 -21
  36. package/dist/src/trails/dev-clean.js.map +1 -1
  37. package/dist/src/trails/dev-reset.d.ts +1 -1
  38. package/dist/src/trails/dev-reset.d.ts.map +1 -1
  39. package/dist/src/trails/dev-reset.js +3 -2
  40. package/dist/src/trails/dev-reset.js.map +1 -1
  41. package/dist/src/trails/dev-stats.d.ts +4 -4
  42. package/dist/src/trails/dev-stats.d.ts.map +1 -1
  43. package/dist/src/trails/dev-stats.js +19 -19
  44. package/dist/src/trails/dev-stats.js.map +1 -1
  45. package/dist/src/trails/dev-support.d.ts +17 -17
  46. package/dist/src/trails/dev-support.d.ts.map +1 -1
  47. package/dist/src/trails/dev-support.js +60 -57
  48. package/dist/src/trails/dev-support.js.map +1 -1
  49. package/dist/src/trails/draft-promote.d.ts +1 -1
  50. package/dist/src/trails/draft-promote.d.ts.map +1 -1
  51. package/dist/src/trails/draft-promote.js +30 -16
  52. package/dist/src/trails/draft-promote.js.map +1 -1
  53. package/dist/src/trails/guide.d.ts +2 -2
  54. package/dist/src/trails/guide.d.ts.map +1 -1
  55. package/dist/src/trails/guide.js +1 -4
  56. package/dist/src/trails/guide.js.map +1 -1
  57. package/dist/src/trails/load-app.d.ts +7 -1
  58. package/dist/src/trails/load-app.d.ts.map +1 -1
  59. package/dist/src/trails/load-app.js +374 -26
  60. package/dist/src/trails/load-app.js.map +1 -1
  61. package/dist/src/trails/survey.d.ts +5 -5
  62. package/dist/src/trails/survey.d.ts.map +1 -1
  63. package/dist/src/trails/survey.js +51 -29
  64. package/dist/src/trails/survey.js.map +1 -1
  65. package/dist/src/trails/topo-export.d.ts +5 -4
  66. package/dist/src/trails/topo-export.d.ts.map +1 -1
  67. package/dist/src/trails/topo-export.js +4 -7
  68. package/dist/src/trails/topo-export.js.map +1 -1
  69. package/dist/src/trails/topo-history.d.ts +6 -10
  70. package/dist/src/trails/topo-history.d.ts.map +1 -1
  71. package/dist/src/trails/topo-history.js +7 -8
  72. package/dist/src/trails/topo-history.js.map +1 -1
  73. package/dist/src/trails/topo-pin.d.ts +5 -9
  74. package/dist/src/trails/topo-pin.d.ts.map +1 -1
  75. package/dist/src/trails/topo-pin.js +5 -9
  76. package/dist/src/trails/topo-pin.js.map +1 -1
  77. package/dist/src/trails/topo-read-support.d.ts +12 -8
  78. package/dist/src/trails/topo-read-support.d.ts.map +1 -1
  79. package/dist/src/trails/topo-read-support.js +71 -82
  80. package/dist/src/trails/topo-read-support.js.map +1 -1
  81. package/dist/src/trails/topo-reports.d.ts +15 -11
  82. package/dist/src/trails/topo-reports.d.ts.map +1 -1
  83. package/dist/src/trails/topo-reports.js +40 -34
  84. package/dist/src/trails/topo-reports.js.map +1 -1
  85. package/dist/src/trails/topo-show.d.ts +4 -4
  86. package/dist/src/trails/topo-show.d.ts.map +1 -1
  87. package/dist/src/trails/topo-show.js +8 -12
  88. package/dist/src/trails/topo-show.js.map +1 -1
  89. package/dist/src/trails/topo-store-support.d.ts +2 -2
  90. package/dist/src/trails/topo-store-support.d.ts.map +1 -1
  91. package/dist/src/trails/topo-store-support.js +22 -22
  92. package/dist/src/trails/topo-store-support.js.map +1 -1
  93. package/dist/src/trails/topo-support.d.ts +19 -30
  94. package/dist/src/trails/topo-support.d.ts.map +1 -1
  95. package/dist/src/trails/topo-support.js +63 -96
  96. package/dist/src/trails/topo-support.js.map +1 -1
  97. package/dist/src/trails/topo-unpin.d.ts +9 -4
  98. package/dist/src/trails/topo-unpin.d.ts.map +1 -1
  99. package/dist/src/trails/topo-unpin.js +9 -4
  100. package/dist/src/trails/topo-unpin.js.map +1 -1
  101. package/dist/src/trails/topo-verify.d.ts +2 -2
  102. package/dist/src/trails/topo-verify.d.ts.map +1 -1
  103. package/dist/src/trails/topo-verify.js +1 -5
  104. package/dist/src/trails/topo-verify.js.map +1 -1
  105. package/dist/src/trails/topo.d.ts +2 -2
  106. package/dist/src/trails/topo.d.ts.map +1 -1
  107. package/dist/src/trails/topo.js +6 -10
  108. package/dist/src/trails/topo.js.map +1 -1
  109. package/dist/src/trails/warden.d.ts +3 -2
  110. package/dist/src/trails/warden.d.ts.map +1 -1
  111. package/dist/src/trails/warden.js +11 -2
  112. package/dist/src/trails/warden.js.map +1 -1
  113. package/dist/src/versions.d.ts +12 -0
  114. package/dist/src/versions.d.ts.map +1 -0
  115. package/dist/src/versions.js +23 -0
  116. package/dist/src/versions.js.map +1 -0
  117. package/dist/tsconfig.tsbuildinfo +1 -1
  118. package/package.json +8 -8
  119. package/src/__tests__/add-trail.test.ts +97 -0
  120. package/src/__tests__/create.test.ts +91 -27
  121. package/src/__tests__/guide.test.ts +10 -5
  122. package/src/__tests__/load-app.test.ts +365 -4
  123. package/src/__tests__/survey.test.ts +143 -67
  124. package/src/__tests__/topo-dev.test.ts +48 -46
  125. package/src/app.ts +2 -2
  126. package/src/clack.ts +1 -1
  127. package/src/cli.ts +4 -3
  128. package/src/trails/add-surface.ts +150 -0
  129. package/src/trails/add-trail.ts +46 -10
  130. package/src/trails/add-verify.ts +11 -6
  131. package/src/trails/create-scaffold.ts +16 -3
  132. package/src/trails/create.ts +76 -71
  133. package/src/trails/dev-clean.ts +25 -21
  134. package/src/trails/dev-reset.ts +3 -2
  135. package/src/trails/dev-stats.ts +22 -19
  136. package/src/trails/dev-support.ts +88 -86
  137. package/src/trails/draft-promote.ts +70 -35
  138. package/src/trails/guide.ts +1 -4
  139. package/src/trails/load-app.ts +511 -32
  140. package/src/trails/survey.ts +60 -35
  141. package/src/trails/topo-export.ts +5 -9
  142. package/src/trails/topo-history.ts +8 -10
  143. package/src/trails/topo-pin.ts +9 -13
  144. package/src/trails/topo-read-support.ts +103 -106
  145. package/src/trails/topo-reports.ts +54 -47
  146. package/src/trails/topo-show.ts +8 -12
  147. package/src/trails/topo-store-support.ts +36 -28
  148. package/src/trails/topo-support.ts +90 -134
  149. package/src/trails/topo-unpin.ts +11 -6
  150. package/src/trails/topo-verify.ts +1 -5
  151. package/src/trails/topo.ts +6 -10
  152. package/src/trails/warden.ts +12 -3
  153. package/src/versions.ts +43 -0
  154. package/tsconfig.tests.json +10 -0
  155. package/src/trails/add-trailhead.ts +0 -121
@@ -1,22 +1,24 @@
1
1
  /**
2
2
  * `survey` trail -- Full topo introspection.
3
3
  *
4
- * Lists trails, shows detail for individual trails, generates trailhead maps,
4
+ * Lists trails, shows detail for individual trails, generates surface maps,
5
5
  * and diffs against previous versions.
6
6
  */
7
7
 
8
+ import { join } from 'node:path';
9
+
8
10
  import type { Topo } from '@ontrails/core';
9
11
  import { NotFoundError, Result, trail } from '@ontrails/core';
10
12
  import type { DiffResult } from '@ontrails/schema';
11
13
  import {
12
- diffTrailheadMaps,
13
- generateOpenApiSpec,
14
- generateTrailheadMap,
15
- readTrailheadMap,
14
+ deriveSurfaceMapDiff,
15
+ deriveOpenApiSpec,
16
+ deriveSurfaceMap,
17
+ readSurfaceMap,
16
18
  } from '@ontrails/schema';
17
19
  import { z } from 'zod';
18
20
 
19
- import { loadApp } from './load-app.js';
21
+ import { loadApp, loadFreshAppLease } from './load-app.js';
20
22
  import {
21
23
  buildCurrentTopoBrief,
22
24
  buildCurrentTopoDetail,
@@ -25,10 +27,10 @@ import {
25
27
  import { exportCurrentTopo } from './topo-store-support.js';
26
28
 
27
29
  export {
28
- formatProvisionDetail,
29
- generateBriefReport,
30
- generateSurveyList,
31
- generateTrailDetail,
30
+ deriveBriefReport,
31
+ deriveResourceDetail,
32
+ deriveSurveyList,
33
+ deriveTrailDetail,
32
34
  } from './topo-reports.js';
33
35
  export type {
34
36
  BriefReport,
@@ -49,19 +51,20 @@ const formatDiff = (diff: DiffResult): object => ({
49
51
 
50
52
  const buildSurveyDiff = async (
51
53
  app: Topo,
54
+ rootDir: string,
52
55
  breakingOnly: boolean
53
56
  ): Promise<Result<object, Error>> => {
54
- const currentMap = generateTrailheadMap(app);
55
- const previousMap = await readTrailheadMap();
57
+ const currentMap = deriveSurfaceMap(app);
58
+ const previousMap = await readSurfaceMap({ dir: join(rootDir, '.trails') });
56
59
  if (!previousMap) {
57
60
  return Result.err(
58
61
  new NotFoundError(
59
- 'No previous trailhead map found. Run `trails topo export` first.'
62
+ 'No saved surface map found. Run `trails topo export` first.'
60
63
  )
61
64
  );
62
65
  }
63
66
 
64
- const diff = diffTrailheadMaps(previousMap, currentMap);
67
+ const diff = deriveSurfaceMapDiff(previousMap, currentMap);
65
68
  return Result.ok(
66
69
  breakingOnly
67
70
  ? formatDiff({
@@ -84,7 +87,7 @@ const buildSurveyDetail = (
84
87
  return Result.ok(detail);
85
88
  }
86
89
  return Result.err(
87
- new NotFoundError(`Trail or provision not found: ${trailId}`)
90
+ new NotFoundError(`Trail or resource not found: ${trailId}`)
88
91
  );
89
92
  };
90
93
 
@@ -106,7 +109,7 @@ const buildSurveyGenerate = async (
106
109
  interface SurveyInput {
107
110
  breakingOnly: boolean;
108
111
  brief: boolean;
109
- diff?: string | undefined;
112
+ diffSaved: boolean;
110
113
  generate: boolean;
111
114
  openapi: boolean;
112
115
  trailId?: string | undefined;
@@ -117,14 +120,14 @@ type SurveyMode = 'brief' | 'detail' | 'diff' | 'generate' | 'list' | 'openapi';
117
120
  /** Ordered mode checks — first truthy predicate wins, otherwise 'list'. */
118
121
  const modeChecks: readonly [(input: SurveyInput) => boolean, SurveyMode][] = [
119
122
  [(i) => i.brief, 'brief'],
120
- [(i) => Boolean(i.diff), 'diff'],
123
+ [(i) => i.diffSaved, 'diff'],
121
124
  [(i) => Boolean(i.trailId), 'detail'],
122
125
  [(i) => i.generate, 'generate'],
123
126
  [(i) => i.openapi, 'openapi'],
124
127
  ];
125
128
 
126
129
  /** Determine which survey mode was requested, falling back to 'list'. */
127
- const resolveSurveyMode = (input: SurveyInput): SurveyMode =>
130
+ const deriveSurveyMode = (input: SurveyInput): SurveyMode =>
128
131
  modeChecks.find(([predicate]) => predicate(input))?.[1] ?? 'list';
129
132
 
130
133
  type SurveyHandler = (
@@ -139,11 +142,12 @@ const surveyHandlers: Record<SurveyMode, SurveyHandler> = {
139
142
  Result.ok(buildCurrentTopoBrief(app, { rootDir })),
140
143
  detail: (app, input, rootDir) =>
141
144
  buildSurveyDetail(app, input.trailId ?? '', rootDir),
142
- diff: (app, input) => buildSurveyDiff(app, input.breakingOnly),
145
+ diff: (app, input, rootDir) =>
146
+ buildSurveyDiff(app, rootDir, input.breakingOnly),
143
147
  generate: (app, _input, rootDir) => buildSurveyGenerate(app, rootDir),
144
148
  list: (app, _input, rootDir) =>
145
149
  Result.ok(buildCurrentTopoList(app, { rootDir })),
146
- openapi: (app) => Result.ok(generateOpenApiSpec(app)),
150
+ openapi: (app) => Result.ok(deriveOpenApiSpec(app)),
147
151
  };
148
152
 
149
153
  /** Dispatch to the appropriate survey sub-command based on input flags. */
@@ -152,7 +156,7 @@ const dispatchSurvey = (
152
156
  input: SurveyInput,
153
157
  rootDir: string
154
158
  ): Result<object, Error> | Promise<Result<object, Error>> => {
155
- const mode = resolveSurveyMode(input);
159
+ const mode = deriveSurveyMode(input);
156
160
  const handler = surveyHandlers[mode];
157
161
  return handler(app, input, rootDir);
158
162
  };
@@ -164,13 +168,34 @@ const dispatchSurvey = (
164
168
  export const surveyTrail = trail('survey', {
165
169
  blaze: async (input, ctx) => {
166
170
  const rootDir = ctx.cwd ?? '.';
171
+ const mode = deriveSurveyMode(input);
172
+ // Fresh load only for diffSaved: comparing against a previously-saved
173
+ // surface map requires the current app's source state, not any cached
174
+ // module graph that a prior import may have frozen. Other modes read
175
+ // the in-memory topo and benefit from the standard import cache.
176
+ //
177
+ // For diff specifically, use a disposable lease rather than retained
178
+ // fresh mirrors — the returned diff result is serialisable data, not
179
+ // a Topo reference with deferred imports, so the mirror can be
180
+ // released the moment dispatchSurvey returns. That keeps MCP/dev
181
+ // sessions that poll diff repeatedly from growing .trails-tmp/
182
+ // without bound.
183
+ if (mode === 'diff') {
184
+ const lease = await loadFreshAppLease(input.module, rootDir);
185
+ try {
186
+ return await dispatchSurvey(lease.app, input, rootDir);
187
+ } finally {
188
+ lease.release();
189
+ }
190
+ }
191
+
167
192
  const app = await loadApp(input.module, rootDir);
168
193
  return dispatchSurvey(app, input, rootDir);
169
194
  },
170
195
  description: 'Full topo introspection',
171
196
  examples: [
172
197
  {
173
- description: 'Lists all registered trails with safety and trailhead info',
198
+ description: 'Lists all registered trails with safety and surface info',
174
199
  input: { module: './src/app.ts' },
175
200
  name: 'List all trails',
176
201
  },
@@ -191,15 +216,15 @@ export const surveyTrail = trail('survey', {
191
216
  .default(false)
192
217
  .describe('Only show breaking changes'),
193
218
  brief: z.boolean().default(false).describe('Quick capability summary'),
194
- diff: z.string().optional().describe('Diff against a git ref'),
219
+ diffSaved: z
220
+ .boolean()
221
+ .default(false)
222
+ .describe('Diff against the saved local surface map'),
195
223
  generate: z
196
224
  .boolean()
197
225
  .default(false)
198
- .describe('Generate trailhead map and lock file'),
199
- module: z
200
- .string()
201
- .default('./src/app.ts')
202
- .describe('Path to the app module'),
226
+ .describe('Generate surface map and lock file'),
227
+ module: z.string().optional().describe('Path to the app module'),
203
228
  openapi: z.boolean().default(false).describe('Output OpenAPI 3.1 spec'),
204
229
  trailId: z.string().optional().describe('Trail ID for detail view'),
205
230
  }),
@@ -215,13 +240,13 @@ export const surveyTrail = trail('survey', {
215
240
  safety: z.string(),
216
241
  })
217
242
  ),
218
- provisionCount: z.number(),
219
- provisions: z.array(
243
+ resourceCount: z.number(),
244
+ resources: z.array(
220
245
  z.object({
221
246
  description: z.string().nullable(),
222
247
  health: z.enum(['available', 'none']),
223
248
  id: z.string(),
224
- kind: z.literal('provision'),
249
+ kind: z.literal('resource'),
225
250
  lifetime: z.literal('singleton'),
226
251
  usedBy: z.array(z.string()),
227
252
  })
@@ -233,11 +258,11 @@ export const surveyTrail = trail('survey', {
233
258
  detours: z.boolean(),
234
259
  examples: z.boolean(),
235
260
  outputSchemas: z.boolean(),
236
- provisions: z.boolean(),
261
+ resources: z.boolean(),
237
262
  signals: z.boolean(),
238
263
  }),
239
264
  name: z.string(),
240
- provisions: z.number(),
265
+ resources: z.number(),
241
266
  signals: z.number(),
242
267
  trails: z.number(),
243
268
  version: z.string(),
@@ -256,14 +281,14 @@ export const surveyTrail = trail('survey', {
256
281
  id: z.string(),
257
282
  intent: z.enum(['read', 'write', 'destroy']),
258
283
  kind: z.string(),
259
- provisions: z.array(z.string()),
284
+ resources: z.array(z.string()),
260
285
  safety: z.string(),
261
286
  }),
262
287
  z.object({
263
288
  description: z.string().nullable(),
264
289
  health: z.enum(['available', 'none']),
265
290
  id: z.string(),
266
- kind: z.literal('provision'),
291
+ kind: z.literal('resource'),
267
292
  lifetime: z.literal('singleton'),
268
293
  usedBy: z.array(z.string()),
269
294
  }),
@@ -4,9 +4,8 @@ import { z } from 'zod';
4
4
  import { loadApp } from './load-app.js';
5
5
  import { exportCurrentTopo } from './topo-store-support.js';
6
6
  import {
7
- DEFAULT_APP_MODULE,
8
- isolatedExampleInput,
9
- topoSaveOutput,
7
+ createIsolatedExampleInput,
8
+ topoSnapshotOutput,
10
9
  } from './topo-support.js';
11
10
 
12
11
  export const topoExportTrail = trail('topo.export', {
@@ -18,15 +17,12 @@ export const topoExportTrail = trail('topo.export', {
18
17
  description: 'Export the current topo to .trails artifacts',
19
18
  examples: [
20
19
  {
21
- input: isolatedExampleInput('topo-export'),
20
+ input: createIsolatedExampleInput('topo-export'),
22
21
  name: 'Write the current topo export',
23
22
  },
24
23
  ],
25
24
  input: z.object({
26
- module: z
27
- .string()
28
- .default(DEFAULT_APP_MODULE)
29
- .describe('Path to the app module'),
25
+ module: z.string().optional().describe('Path to the app module'),
30
26
  rootDir: z.string().optional().describe('Workspace root directory'),
31
27
  }),
32
28
  intent: 'write',
@@ -34,6 +30,6 @@ export const topoExportTrail = trail('topo.export', {
34
30
  hash: z.string(),
35
31
  lockPath: z.string(),
36
32
  mapPath: z.string(),
37
- save: topoSaveOutput,
33
+ snapshot: topoSnapshotOutput,
38
34
  }),
39
35
  });
@@ -3,10 +3,9 @@ import { z } from 'zod';
3
3
 
4
4
  import {
5
5
  DEFAULT_TOPO_HISTORY_LIMIT,
6
- isolatedExampleInput,
6
+ createIsolatedExampleInput,
7
7
  listTopoHistory,
8
- topoPinOutput,
9
- topoSaveOutput,
8
+ topoSnapshotOutput,
10
9
  } from './topo-support.js';
11
10
 
12
11
  export const topoHistoryTrail = trail('topo.history', {
@@ -14,10 +13,10 @@ export const topoHistoryTrail = trail('topo.history', {
14
13
  const rootDir = input.rootDir ?? ctx.cwd ?? process.cwd();
15
14
  return Result.ok(listTopoHistory({ limit: input.limit, rootDir }));
16
15
  },
17
- description: 'List saved topo metadata, including pins and recent autosaves',
16
+ description: 'List saved topo snapshots, including pinned references',
18
17
  examples: [
19
18
  {
20
- input: isolatedExampleInput('topo-history'),
19
+ input: createIsolatedExampleInput('topo-history'),
21
20
  name: 'Show topo history',
22
21
  },
23
22
  ],
@@ -25,16 +24,15 @@ export const topoHistoryTrail = trail('topo.history', {
25
24
  limit: z
26
25
  .number()
27
26
  .default(DEFAULT_TOPO_HISTORY_LIMIT)
28
- .describe('Maximum number of autosaves to return'),
27
+ .describe('Maximum number of snapshots to return'),
29
28
  rootDir: z.string().optional().describe('Workspace root directory'),
30
29
  }),
31
30
  intent: 'read',
32
31
  output: z.object({
33
32
  dbPath: z.string(),
34
33
  limit: z.number(),
35
- pinCount: z.number(),
36
- pins: z.array(topoPinOutput),
37
- saveCount: z.number(),
38
- saves: z.array(topoSaveOutput),
34
+ pinnedCount: z.number(),
35
+ snapshotCount: z.number(),
36
+ snapshots: z.array(topoSnapshotOutput),
39
37
  }),
40
38
  });
@@ -3,40 +3,36 @@ import { z } from 'zod';
3
3
 
4
4
  import { loadApp } from './load-app.js';
5
5
  import {
6
- DEFAULT_APP_MODULE,
7
- isolatedExampleInput,
8
- pinCurrentTopo,
9
- topoPinOutput,
10
- topoSaveOutput,
6
+ createIsolatedExampleInput,
7
+ pinCurrentTopoSnapshot,
8
+ topoSnapshotOutput,
11
9
  } from './topo-support.js';
12
10
 
13
11
  export const topoPinTrail = trail('topo.pin', {
14
12
  blaze: async (input, ctx) => {
15
13
  const rootDir = input.rootDir ?? ctx.cwd ?? process.cwd();
16
14
  const app = await loadApp(input.module, rootDir);
17
- return Result.ok(pinCurrentTopo(app, { name: input.name, rootDir }));
15
+ return Result.ok(
16
+ pinCurrentTopoSnapshot(app, { name: input.name, rootDir })
17
+ );
18
18
  },
19
19
  description: 'Pin the current topo under a durable name',
20
20
  examples: [
21
21
  {
22
22
  input: {
23
- ...isolatedExampleInput('topo-pin'),
23
+ ...createIsolatedExampleInput('topo-pin'),
24
24
  name: 'before-auth-refactor',
25
25
  },
26
26
  name: 'Pin the current topo',
27
27
  },
28
28
  ],
29
29
  input: z.object({
30
- module: z
31
- .string()
32
- .default(DEFAULT_APP_MODULE)
33
- .describe('Path to the app module'),
30
+ module: z.string().optional().describe('Path to the app module'),
34
31
  name: z.string().describe('Pin name'),
35
32
  rootDir: z.string().optional().describe('Workspace root directory'),
36
33
  }),
37
34
  intent: 'write',
38
35
  output: z.object({
39
- pin: topoPinOutput,
40
- save: topoSaveOutput,
36
+ snapshot: topoSnapshotOutput,
41
37
  }),
42
38
  });