@ontrails/trails 1.0.0-beta.15 → 1.0.0-beta.17
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 +215 -2
- package/README.md +27 -0
- package/package.json +21 -8
- package/src/app.ts +15 -5
- package/src/cli.ts +303 -10
- package/src/completions.ts +240 -0
- package/src/load-app-mirror.ts +160 -0
- package/src/local-state-io.ts +153 -0
- package/src/project-writes.ts +320 -0
- package/src/run-collision.ts +125 -0
- package/src/run-completions-install.ts +179 -0
- package/src/run-example.ts +149 -0
- package/src/run-examples.ts +148 -0
- package/src/run-quiet.ts +75 -0
- package/src/run-trace.ts +273 -0
- package/src/run-warden.ts +39 -0
- package/src/run-watch.ts +432 -0
- package/src/scaffold-versions.generated.ts +12 -0
- package/src/trails/add-surface.ts +45 -23
- package/src/trails/add-trail.ts +27 -17
- package/src/trails/add-verify.ts +57 -17
- package/src/trails/completions-complete.ts +165 -0
- package/src/trails/completions.ts +47 -0
- package/src/trails/create-scaffold.ts +86 -33
- package/src/trails/create.ts +11 -3
- package/src/trails/dev-clean.ts +6 -1
- package/src/trails/dev-reset.ts +6 -1
- package/src/trails/dev-stats.ts +6 -1
- package/src/trails/dev-support.ts +29 -17
- package/src/trails/draft-promote.ts +289 -80
- package/src/trails/guide.ts +54 -34
- package/src/trails/load-app.ts +251 -56
- package/src/trails/root-dir.ts +21 -0
- package/src/trails/run-example.ts +482 -0
- package/src/trails/run-examples.ts +141 -0
- package/src/trails/run.ts +403 -0
- package/src/trails/survey.ts +534 -200
- package/src/trails/topo-activation.ts +385 -0
- package/src/trails/topo-compile.ts +55 -0
- package/src/trails/topo-history.ts +6 -1
- package/src/trails/topo-output-schemas.ts +219 -0
- package/src/trails/topo-pin.ts +19 -6
- package/src/trails/topo-read-support.ts +171 -228
- package/src/trails/topo-reports.ts +587 -25
- package/src/trails/topo-store-support.ts +43 -19
- package/src/trails/topo-support.ts +18 -28
- package/src/trails/topo-unpin.ts +6 -1
- package/src/trails/topo-verify.ts +18 -5
- package/src/trails/topo.ts +60 -23
- package/src/trails/warden-guide.ts +121 -0
- package/src/trails/warden.ts +137 -56
- package/src/versions.ts +3 -18
- package/.turbo/turbo-build.log +0 -1
- package/.turbo/turbo-lint.log +0 -3
- package/.turbo/turbo-typecheck.log +0 -1
- package/__tests__/examples.test.ts +0 -45
- package/dist/bin/trails.d.ts +0 -3
- package/dist/bin/trails.d.ts.map +0 -1
- package/dist/bin/trails.js +0 -4
- package/dist/bin/trails.js.map +0 -1
- package/dist/src/app.d.ts +0 -2
- package/dist/src/app.d.ts.map +0 -1
- package/dist/src/app.js +0 -22
- package/dist/src/app.js.map +0 -1
- package/dist/src/clack.d.ts +0 -9
- package/dist/src/clack.d.ts.map +0 -1
- package/dist/src/clack.js +0 -84
- package/dist/src/clack.js.map +0 -1
- package/dist/src/cli.d.ts +0 -2
- package/dist/src/cli.d.ts.map +0 -1
- package/dist/src/cli.js +0 -14
- package/dist/src/cli.js.map +0 -1
- package/dist/src/trails/add-surface.d.ts +0 -13
- package/dist/src/trails/add-surface.d.ts.map +0 -1
- package/dist/src/trails/add-surface.js +0 -110
- package/dist/src/trails/add-surface.js.map +0 -1
- package/dist/src/trails/add-trail.d.ts +0 -12
- package/dist/src/trails/add-trail.d.ts.map +0 -1
- package/dist/src/trails/add-trail.js +0 -104
- package/dist/src/trails/add-trail.js.map +0 -1
- package/dist/src/trails/add-trailhead.d.ts +0 -13
- package/dist/src/trails/add-trailhead.d.ts.map +0 -1
- package/dist/src/trails/add-trailhead.js +0 -88
- package/dist/src/trails/add-trailhead.js.map +0 -1
- package/dist/src/trails/add-verify.d.ts +0 -10
- package/dist/src/trails/add-verify.d.ts.map +0 -1
- package/dist/src/trails/add-verify.js +0 -68
- package/dist/src/trails/add-verify.js.map +0 -1
- package/dist/src/trails/create-scaffold.d.ts +0 -15
- package/dist/src/trails/create-scaffold.d.ts.map +0 -1
- package/dist/src/trails/create-scaffold.js +0 -295
- package/dist/src/trails/create-scaffold.js.map +0 -1
- package/dist/src/trails/create.d.ts +0 -18
- package/dist/src/trails/create.d.ts.map +0 -1
- package/dist/src/trails/create.js +0 -126
- package/dist/src/trails/create.js.map +0 -1
- package/dist/src/trails/dev-clean.d.ts +0 -9
- package/dist/src/trails/dev-clean.d.ts.map +0 -1
- package/dist/src/trails/dev-clean.js +0 -66
- package/dist/src/trails/dev-clean.js.map +0 -1
- package/dist/src/trails/dev-reset.d.ts +0 -6
- package/dist/src/trails/dev-reset.d.ts.map +0 -1
- package/dist/src/trails/dev-reset.js +0 -39
- package/dist/src/trails/dev-reset.js.map +0 -1
- package/dist/src/trails/dev-stats.d.ts +0 -7
- package/dist/src/trails/dev-stats.d.ts.map +0 -1
- package/dist/src/trails/dev-stats.js +0 -61
- package/dist/src/trails/dev-stats.js.map +0 -1
- package/dist/src/trails/dev-support.d.ts +0 -64
- package/dist/src/trails/dev-support.d.ts.map +0 -1
- package/dist/src/trails/dev-support.js +0 -181
- package/dist/src/trails/dev-support.js.map +0 -1
- package/dist/src/trails/draft-promote.d.ts +0 -18
- package/dist/src/trails/draft-promote.d.ts.map +0 -1
- package/dist/src/trails/draft-promote.js +0 -400
- package/dist/src/trails/draft-promote.js.map +0 -1
- package/dist/src/trails/guide.d.ts +0 -21
- package/dist/src/trails/guide.d.ts.map +0 -1
- package/dist/src/trails/guide.js +0 -61
- package/dist/src/trails/guide.js.map +0 -1
- package/dist/src/trails/load-app.d.ts +0 -12
- package/dist/src/trails/load-app.d.ts.map +0 -1
- package/dist/src/trails/load-app.js +0 -415
- package/dist/src/trails/load-app.js.map +0 -1
- package/dist/src/trails/project.d.ts +0 -8
- package/dist/src/trails/project.d.ts.map +0 -1
- package/dist/src/trails/project.js +0 -54
- package/dist/src/trails/project.js.map +0 -1
- package/dist/src/trails/survey.d.ts +0 -18
- package/dist/src/trails/survey.d.ts.map +0 -1
- package/dist/src/trails/survey.js +0 -234
- package/dist/src/trails/survey.js.map +0 -1
- package/dist/src/trails/topo-constants.d.ts +0 -3
- package/dist/src/trails/topo-constants.d.ts.map +0 -1
- package/dist/src/trails/topo-constants.js +0 -3
- package/dist/src/trails/topo-constants.js.map +0 -1
- package/dist/src/trails/topo-export.d.ts +0 -19
- package/dist/src/trails/topo-export.d.ts.map +0 -1
- package/dist/src/trails/topo-export.js +0 -31
- package/dist/src/trails/topo-export.js.map +0 -1
- package/dist/src/trails/topo-history.d.ts +0 -20
- package/dist/src/trails/topo-history.d.ts.map +0 -1
- package/dist/src/trails/topo-history.js +0 -32
- package/dist/src/trails/topo-history.js.map +0 -1
- package/dist/src/trails/topo-pin.d.ts +0 -17
- package/dist/src/trails/topo-pin.d.ts.map +0 -1
- package/dist/src/trails/topo-pin.js +0 -31
- package/dist/src/trails/topo-pin.js.map +0 -1
- package/dist/src/trails/topo-read-support.d.ts +0 -58
- package/dist/src/trails/topo-read-support.d.ts.map +0 -1
- package/dist/src/trails/topo-read-support.js +0 -167
- package/dist/src/trails/topo-read-support.js.map +0 -1
- package/dist/src/trails/topo-reports.d.ts +0 -54
- package/dist/src/trails/topo-reports.d.ts.map +0 -1
- package/dist/src/trails/topo-reports.js +0 -128
- package/dist/src/trails/topo-reports.js.map +0 -1
- package/dist/src/trails/topo-show.d.ts +0 -23
- package/dist/src/trails/topo-show.d.ts.map +0 -1
- package/dist/src/trails/topo-show.js +0 -49
- package/dist/src/trails/topo-show.js.map +0 -1
- package/dist/src/trails/topo-store-support.d.ts +0 -13
- package/dist/src/trails/topo-store-support.d.ts.map +0 -1
- package/dist/src/trails/topo-store-support.js +0 -55
- package/dist/src/trails/topo-store-support.js.map +0 -1
- package/dist/src/trails/topo-support.d.ts +0 -76
- package/dist/src/trails/topo-support.d.ts.map +0 -1
- package/dist/src/trails/topo-support.js +0 -132
- package/dist/src/trails/topo-support.js.map +0 -1
- package/dist/src/trails/topo-unpin.d.ts +0 -20
- package/dist/src/trails/topo-unpin.d.ts.map +0 -1
- package/dist/src/trails/topo-unpin.js +0 -44
- package/dist/src/trails/topo-unpin.js.map +0 -1
- package/dist/src/trails/topo-verify.d.ts +0 -5
- package/dist/src/trails/topo-verify.d.ts.map +0 -1
- package/dist/src/trails/topo-verify.js +0 -24
- package/dist/src/trails/topo-verify.js.map +0 -1
- package/dist/src/trails/topo.d.ts +0 -5
- package/dist/src/trails/topo.d.ts.map +0 -1
- package/dist/src/trails/topo.js +0 -63
- package/dist/src/trails/topo.js.map +0 -1
- package/dist/src/trails/warden.d.ts +0 -20
- package/dist/src/trails/warden.d.ts.map +0 -1
- package/dist/src/trails/warden.js +0 -98
- package/dist/src/trails/warden.js.map +0 -1
- package/dist/src/versions.d.ts +0 -12
- package/dist/src/versions.d.ts.map +0 -1
- package/dist/src/versions.js +0 -23
- package/dist/src/versions.js.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/src/__tests__/add-trail.test.ts +0 -97
- package/src/__tests__/create.test.ts +0 -415
- package/src/__tests__/draft-promote.test.ts +0 -144
- package/src/__tests__/guide.test.ts +0 -96
- package/src/__tests__/load-app.test.ts +0 -419
- package/src/__tests__/survey.test.ts +0 -377
- package/src/__tests__/topo-dev.test.ts +0 -426
- package/src/__tests__/warden.test.ts +0 -74
- package/src/trails/topo-export.ts +0 -35
- package/src/trails/topo-show.ts +0 -54
- package/tsconfig.json +0 -9
- package/tsconfig.tests.json +0 -10
|
@@ -5,19 +5,26 @@
|
|
|
5
5
|
* keeping module boundaries clean.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import
|
|
9
|
-
|
|
10
|
-
import type {
|
|
11
|
-
import {
|
|
12
|
-
createTopoSnapshot,
|
|
13
|
-
getStoredTopoExport,
|
|
14
|
-
} from '@ontrails/core/internal/topo-store';
|
|
8
|
+
import { Database } from 'bun:sqlite';
|
|
9
|
+
|
|
10
|
+
import type { Topo } from '@ontrails/core';
|
|
15
11
|
import {
|
|
16
|
-
openWriteTrailsDb,
|
|
17
12
|
deriveTrailsDir,
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
13
|
+
InternalError,
|
|
14
|
+
openWriteTrailsDb,
|
|
15
|
+
Result,
|
|
16
|
+
} from '@ontrails/core';
|
|
17
|
+
import type {
|
|
18
|
+
LockManifest,
|
|
19
|
+
TopoGraph,
|
|
20
|
+
TopoSnapshot,
|
|
21
|
+
} from '@ontrails/topographer';
|
|
22
|
+
import type { StoredTopoExport } from '@ontrails/topographer/backend-support';
|
|
23
|
+
import { writeLockManifest, writeTopoGraph } from '@ontrails/topographer';
|
|
24
|
+
import {
|
|
25
|
+
createStoredTopoSnapshot,
|
|
26
|
+
getStoredTopoExport,
|
|
27
|
+
} from '@ontrails/topographer/backend-support';
|
|
21
28
|
|
|
22
29
|
import type { TopoExportReport } from './topo-support.js';
|
|
23
30
|
import {
|
|
@@ -34,7 +41,7 @@ const persistAndReadStoredExport = (
|
|
|
34
41
|
{ snapshot: TopoSnapshot; storedExport: StoredTopoExport },
|
|
35
42
|
Error
|
|
36
43
|
> => {
|
|
37
|
-
const snapshotResult =
|
|
44
|
+
const snapshotResult = createStoredTopoSnapshot(db, app, {
|
|
38
45
|
...readGitState(rootDir),
|
|
39
46
|
...deriveTopoCounts(app),
|
|
40
47
|
});
|
|
@@ -59,23 +66,40 @@ const persistAndReadStoredExport = (
|
|
|
59
66
|
});
|
|
60
67
|
};
|
|
61
68
|
|
|
69
|
+
export const deriveCurrentTopoExport = (
|
|
70
|
+
app: Topo,
|
|
71
|
+
options?: { readonly rootDir?: string }
|
|
72
|
+
): Result<StoredTopoExport, Error> => {
|
|
73
|
+
const rootDir = deriveRootDir(options?.rootDir);
|
|
74
|
+
const db = new Database(':memory:');
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
const projected = persistAndReadStoredExport(app, db, rootDir);
|
|
78
|
+
return projected.isErr()
|
|
79
|
+
? projected
|
|
80
|
+
: Result.ok(projected.value.storedExport);
|
|
81
|
+
} finally {
|
|
82
|
+
db.close();
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
62
86
|
const writeStoredExportArtifacts = async (
|
|
63
87
|
storedExport: StoredTopoExport,
|
|
64
88
|
trailsDir: string
|
|
65
|
-
): Promise<Pick<TopoExportReport, 'hash' | 'lockPath' | '
|
|
66
|
-
const
|
|
67
|
-
JSON.parse(storedExport.
|
|
89
|
+
): Promise<Pick<TopoExportReport, 'hash' | 'lockPath' | 'topoPath'>> => {
|
|
90
|
+
const topoPath = await writeTopoGraph(
|
|
91
|
+
JSON.parse(storedExport.topoGraphJson) as TopoGraph,
|
|
68
92
|
{ dir: trailsDir }
|
|
69
93
|
);
|
|
70
|
-
const lockPath = await
|
|
71
|
-
JSON.parse(storedExport.
|
|
94
|
+
const lockPath = await writeLockManifest(
|
|
95
|
+
JSON.parse(storedExport.lockManifestJson) as LockManifest,
|
|
72
96
|
{ dir: trailsDir }
|
|
73
97
|
);
|
|
74
98
|
|
|
75
99
|
return {
|
|
76
|
-
hash: storedExport.
|
|
100
|
+
hash: storedExport.topoGraphHash,
|
|
77
101
|
lockPath,
|
|
78
|
-
|
|
102
|
+
topoPath,
|
|
79
103
|
};
|
|
80
104
|
};
|
|
81
105
|
|
|
@@ -1,18 +1,23 @@
|
|
|
1
|
-
import { existsSync
|
|
2
|
-
import { tmpdir } from 'node:os';
|
|
3
|
-
import { join } from 'node:path';
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
4
2
|
import { fileURLToPath } from 'node:url';
|
|
5
3
|
|
|
4
|
+
import { deriveTrailsDbPath } from '@ontrails/core';
|
|
5
|
+
import type { Topo } from '@ontrails/core';
|
|
6
6
|
import {
|
|
7
7
|
createTopoSnapshot as persistTopoSnapshot,
|
|
8
8
|
listTopoSnapshots as readTopoSnapshots,
|
|
9
9
|
pinTopoSnapshot,
|
|
10
10
|
unpinTopoSnapshot,
|
|
11
|
-
} from '@ontrails/
|
|
12
|
-
import type {
|
|
13
|
-
import { deriveTrailsDbPath } from '@ontrails/core/internal/trails-db';
|
|
11
|
+
} from '@ontrails/topographer';
|
|
12
|
+
import type { TopoSnapshot } from '@ontrails/topographer';
|
|
14
13
|
import { z } from 'zod';
|
|
15
14
|
|
|
15
|
+
import {
|
|
16
|
+
createIsolatedExampleRoot,
|
|
17
|
+
writeIsolatedExampleAppModule,
|
|
18
|
+
} from '../local-state-io.js';
|
|
19
|
+
|
|
20
|
+
import { requireTrailRootDir } from './root-dir.js';
|
|
16
21
|
import type { BriefReport, SurveyListReport } from './topo-reports.js';
|
|
17
22
|
|
|
18
23
|
/** Output schema for a topo snapshot record. Shared across topo trails. */
|
|
@@ -27,11 +32,13 @@ export const topoSnapshotOutput = z.object({
|
|
|
27
32
|
trailCount: z.number(),
|
|
28
33
|
});
|
|
29
34
|
|
|
30
|
-
export const DEFAULT_APP_MODULE = './src/app.ts';
|
|
31
35
|
export const DEFAULT_TOPO_HISTORY_LIMIT = 10;
|
|
32
36
|
export const LOCK_PATH = '.trails/trails.lock';
|
|
33
37
|
const EXAMPLE_APP_MODULE = fileURLToPath(new URL('../app.ts', import.meta.url));
|
|
34
38
|
|
|
39
|
+
const uniqueExampleRootName = (name: string): string =>
|
|
40
|
+
`${name}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
|
|
41
|
+
|
|
35
42
|
export interface TopoSummaryReport {
|
|
36
43
|
readonly app: BriefReport;
|
|
37
44
|
readonly dbPath: string;
|
|
@@ -51,8 +58,8 @@ export interface TopoHistoryReport {
|
|
|
51
58
|
export interface TopoExportReport {
|
|
52
59
|
readonly hash: string;
|
|
53
60
|
readonly lockPath: string;
|
|
54
|
-
readonly mapPath: string;
|
|
55
61
|
readonly snapshot: TopoSnapshot;
|
|
62
|
+
readonly topoPath: string;
|
|
56
63
|
}
|
|
57
64
|
|
|
58
65
|
export interface TopoVerifyReport {
|
|
@@ -62,7 +69,7 @@ export interface TopoVerifyReport {
|
|
|
62
69
|
readonly stale: false;
|
|
63
70
|
}
|
|
64
71
|
|
|
65
|
-
export const deriveRootDir = (cwd?: string): string => cwd
|
|
72
|
+
export const deriveRootDir = (cwd?: string): string => requireTrailRootDir(cwd);
|
|
66
73
|
|
|
67
74
|
const safeGit = (cwd: string, args: readonly string[]): string | undefined => {
|
|
68
75
|
const proc = Bun.spawnSync({
|
|
@@ -137,30 +144,13 @@ const buildSnapshotInput = (
|
|
|
137
144
|
export const createIsolatedExampleInput = (
|
|
138
145
|
name: string
|
|
139
146
|
): { readonly module: string; readonly rootDir: string } => {
|
|
140
|
-
const rootDir =
|
|
141
|
-
rmSync(rootDir, { force: true, recursive: true });
|
|
142
|
-
mkdirSync(rootDir, { recursive: true });
|
|
147
|
+
const rootDir = createIsolatedExampleRoot(uniqueExampleRootName(name));
|
|
143
148
|
return {
|
|
144
|
-
module: EXAMPLE_APP_MODULE,
|
|
149
|
+
module: writeIsolatedExampleAppModule(rootDir, EXAMPLE_APP_MODULE),
|
|
145
150
|
rootDir,
|
|
146
151
|
};
|
|
147
152
|
};
|
|
148
153
|
|
|
149
|
-
export const createCurrentTopoSnapshot = (
|
|
150
|
-
app: Topo,
|
|
151
|
-
options?: { readonly rootDir?: string }
|
|
152
|
-
): TopoSnapshot => {
|
|
153
|
-
const rootDir = deriveRootDir(options?.rootDir);
|
|
154
|
-
const result = persistTopoSnapshot(app, {
|
|
155
|
-
rootDir,
|
|
156
|
-
...buildSnapshotInput(app, rootDir),
|
|
157
|
-
});
|
|
158
|
-
if (result.isErr()) {
|
|
159
|
-
throw result.error;
|
|
160
|
-
}
|
|
161
|
-
return result.value;
|
|
162
|
-
};
|
|
163
|
-
|
|
164
154
|
export const listTopoHistory = (options?: {
|
|
165
155
|
readonly limit?: number;
|
|
166
156
|
readonly rootDir?: string;
|
package/src/trails/topo-unpin.ts
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
removePinnedTopoSnapshot,
|
|
7
7
|
topoSnapshotOutput,
|
|
8
8
|
} from './topo-support.js';
|
|
9
|
+
import { resolveTrailRootDir } from './root-dir.js';
|
|
9
10
|
|
|
10
11
|
export const topoUnpinTrail = trail('topo.unpin', {
|
|
11
12
|
blaze: (input, ctx) => {
|
|
@@ -17,7 +18,11 @@ export const topoUnpinTrail = trail('topo.unpin', {
|
|
|
17
18
|
);
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
const
|
|
21
|
+
const rootDirResult = resolveTrailRootDir(input.rootDir, ctx.cwd);
|
|
22
|
+
if (rootDirResult.isErr()) {
|
|
23
|
+
return Result.err(rootDirResult.error);
|
|
24
|
+
}
|
|
25
|
+
const rootDir = rootDirResult.value;
|
|
21
26
|
return Result.ok(
|
|
22
27
|
removePinnedTopoSnapshot({
|
|
23
28
|
dryRun: input.dryRun,
|
|
@@ -1,14 +1,27 @@
|
|
|
1
|
-
import { trail } from '@ontrails/core';
|
|
1
|
+
import { Result, trail } from '@ontrails/core';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { tryLoadFreshAppLease } from './load-app.js';
|
|
5
|
+
import { resolveTrailRootDir } from './root-dir.js';
|
|
5
6
|
import { verifyCurrentTopo } from './topo-read-support.js';
|
|
6
7
|
|
|
7
8
|
export const topoVerifyTrail = trail('topo.verify', {
|
|
8
9
|
blaze: async (input, ctx) => {
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
const rootDirResult = resolveTrailRootDir(input.rootDir, ctx.cwd);
|
|
11
|
+
if (rootDirResult.isErr()) {
|
|
12
|
+
return Result.err(rootDirResult.error);
|
|
13
|
+
}
|
|
14
|
+
const rootDir = rootDirResult.value;
|
|
15
|
+
const leaseResult = await tryLoadFreshAppLease(input.module, rootDir);
|
|
16
|
+
if (leaseResult.isErr()) {
|
|
17
|
+
return Result.err(leaseResult.error);
|
|
18
|
+
}
|
|
19
|
+
const lease = leaseResult.value;
|
|
20
|
+
try {
|
|
21
|
+
return await verifyCurrentTopo(lease.app, { rootDir });
|
|
22
|
+
} finally {
|
|
23
|
+
lease.release();
|
|
24
|
+
}
|
|
12
25
|
},
|
|
13
26
|
description: 'Verify that the committed lockfile matches the current topo',
|
|
14
27
|
input: z.object({
|
package/src/trails/topo.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { Result, trail } from '@ontrails/core';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { tryLoadFreshAppLease } from './load-app.js';
|
|
5
|
+
import { resolveTrailRootDir } from './root-dir.js';
|
|
6
|
+
import { activationOverviewOutput } from './topo-output-schemas.js';
|
|
5
7
|
import { buildTopoSummary } from './topo-read-support.js';
|
|
8
|
+
import { createIsolatedExampleInput } from './topo-support.js';
|
|
6
9
|
|
|
7
10
|
const summaryOutput = z.object({
|
|
8
11
|
app: z.object({
|
|
@@ -22,26 +25,48 @@ const summaryOutput = z.object({
|
|
|
22
25
|
}),
|
|
23
26
|
dbPath: z.string(),
|
|
24
27
|
list: z.object({
|
|
28
|
+
activation: activationOverviewOutput,
|
|
25
29
|
count: z.number(),
|
|
26
|
-
entries: z
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
entries: z
|
|
31
|
+
.array(
|
|
32
|
+
z.object({
|
|
33
|
+
activatedBy: z.array(z.string()).readonly(),
|
|
34
|
+
activates: z.array(z.string()).readonly(),
|
|
35
|
+
examples: z.number(),
|
|
36
|
+
id: z.string(),
|
|
37
|
+
kind: z.string(),
|
|
38
|
+
safety: z.string(),
|
|
39
|
+
})
|
|
40
|
+
)
|
|
41
|
+
.readonly(),
|
|
34
42
|
resourceCount: z.number(),
|
|
35
|
-
resources: z
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
resources: z
|
|
44
|
+
.array(
|
|
45
|
+
z.object({
|
|
46
|
+
description: z.string().nullable(),
|
|
47
|
+
health: z.enum(['available', 'none']),
|
|
48
|
+
id: z.string(),
|
|
49
|
+
kind: z.literal('resource'),
|
|
50
|
+
lifetime: z.literal('singleton'),
|
|
51
|
+
usedBy: z.array(z.string()).readonly(),
|
|
52
|
+
})
|
|
53
|
+
)
|
|
54
|
+
.readonly(),
|
|
55
|
+
signalCount: z.number(),
|
|
56
|
+
signals: z
|
|
57
|
+
.array(
|
|
58
|
+
z.object({
|
|
59
|
+
consumers: z.array(z.string()).readonly(),
|
|
60
|
+
description: z.string().nullable(),
|
|
61
|
+
examples: z.number(),
|
|
62
|
+
from: z.array(z.string()).readonly(),
|
|
63
|
+
id: z.string(),
|
|
64
|
+
kind: z.literal('signal'),
|
|
65
|
+
payloadSchema: z.boolean(),
|
|
66
|
+
producers: z.array(z.string()).readonly(),
|
|
67
|
+
})
|
|
68
|
+
)
|
|
69
|
+
.readonly(),
|
|
45
70
|
}),
|
|
46
71
|
lockExists: z.boolean(),
|
|
47
72
|
lockPath: z.string(),
|
|
@@ -49,14 +74,26 @@ const summaryOutput = z.object({
|
|
|
49
74
|
|
|
50
75
|
export const topoTrail = trail('topo', {
|
|
51
76
|
blaze: async (input, ctx) => {
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
77
|
+
const rootDirResult = resolveTrailRootDir(input.rootDir, ctx.cwd);
|
|
78
|
+
if (rootDirResult.isErr()) {
|
|
79
|
+
return Result.err(rootDirResult.error);
|
|
80
|
+
}
|
|
81
|
+
const rootDir = rootDirResult.value;
|
|
82
|
+
const leaseResult = await tryLoadFreshAppLease(input.module, rootDir);
|
|
83
|
+
if (leaseResult.isErr()) {
|
|
84
|
+
return Result.err(leaseResult.error);
|
|
85
|
+
}
|
|
86
|
+
const lease = leaseResult.value;
|
|
87
|
+
try {
|
|
88
|
+
return Result.ok(buildTopoSummary(lease.app, { rootDir }));
|
|
89
|
+
} finally {
|
|
90
|
+
lease.release();
|
|
91
|
+
}
|
|
55
92
|
},
|
|
56
93
|
description: 'Show the current topo summary and entry list',
|
|
57
94
|
examples: [
|
|
58
95
|
{
|
|
59
|
-
input:
|
|
96
|
+
input: createIsolatedExampleInput('topo-summary'),
|
|
60
97
|
name: 'Show the current topo summary',
|
|
61
98
|
},
|
|
62
99
|
],
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import type { FieldOverride } from '@ontrails/core';
|
|
2
|
+
import { Result, trail } from '@ontrails/core';
|
|
3
|
+
import {
|
|
4
|
+
buildWardenGuideManifest,
|
|
5
|
+
formatWardenGuide,
|
|
6
|
+
wardenDepthValues,
|
|
7
|
+
wardenGuideFormatValues,
|
|
8
|
+
wardenRuleConcerns,
|
|
9
|
+
wardenRuleLifecycleStates,
|
|
10
|
+
wardenRuleScopes,
|
|
11
|
+
wardenRuleTiers,
|
|
12
|
+
} from '@ontrails/warden';
|
|
13
|
+
import { z } from 'zod';
|
|
14
|
+
|
|
15
|
+
const wardenGuidanceLinkSchema = z.object({
|
|
16
|
+
label: z.string(),
|
|
17
|
+
path: z.string().optional(),
|
|
18
|
+
url: z.string().optional(),
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const wardenGuidanceSchema = z.object({
|
|
22
|
+
commands: z.array(z.string()).readonly().optional(),
|
|
23
|
+
docs: z.array(wardenGuidanceLinkSchema).readonly().optional(),
|
|
24
|
+
relatedRules: z.array(z.string()).readonly().optional(),
|
|
25
|
+
steps: z.array(z.string()).readonly().optional(),
|
|
26
|
+
summary: z.string(),
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const wardenRuleGuideEntrySchema = z.object({
|
|
30
|
+
concern: z.enum(wardenRuleConcerns),
|
|
31
|
+
depth: z.enum(wardenDepthValues),
|
|
32
|
+
description: z.string(),
|
|
33
|
+
docs: z.array(wardenGuidanceLinkSchema).readonly(),
|
|
34
|
+
guidance: wardenGuidanceSchema.optional(),
|
|
35
|
+
id: z.string(),
|
|
36
|
+
invariant: z.string(),
|
|
37
|
+
lifecycle: z.object({
|
|
38
|
+
retireWhen: z.string().optional(),
|
|
39
|
+
state: z.enum(wardenRuleLifecycleStates),
|
|
40
|
+
}),
|
|
41
|
+
scope: z.enum(wardenRuleScopes),
|
|
42
|
+
severity: z.enum(['error', 'warn']),
|
|
43
|
+
tier: z.enum(wardenRuleTiers),
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const wardenGuideManifestSchema = z.object({
|
|
47
|
+
generatedFrom: z.object({
|
|
48
|
+
package: z.literal('@ontrails/warden'),
|
|
49
|
+
registries: z.tuple([
|
|
50
|
+
z.literal('wardenRules'),
|
|
51
|
+
z.literal('wardenTopoRules'),
|
|
52
|
+
]),
|
|
53
|
+
source: z.literal('builtin-rule-metadata'),
|
|
54
|
+
}),
|
|
55
|
+
kind: z.literal('trails-warden-guide-manifest'),
|
|
56
|
+
ruleCount: z.number(),
|
|
57
|
+
rules: z.array(wardenRuleGuideEntrySchema).readonly(),
|
|
58
|
+
version: z.literal(1),
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const wardenGuideInputSchema = z.object({
|
|
62
|
+
guideFormat: z
|
|
63
|
+
.enum(wardenGuideFormatValues)
|
|
64
|
+
.default('markdown')
|
|
65
|
+
.describe('Guide output format'),
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const wardenGuideFields = {
|
|
69
|
+
guideFormat: {
|
|
70
|
+
aliases: true,
|
|
71
|
+
options: [
|
|
72
|
+
{
|
|
73
|
+
hint: 'Human-readable Warden guide',
|
|
74
|
+
label: 'Markdown',
|
|
75
|
+
value: 'markdown',
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
hint: 'Compact guidance for agent context',
|
|
79
|
+
label: 'Agent JSON',
|
|
80
|
+
value: 'agent-json',
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
hint: 'Full structured rule manifest',
|
|
84
|
+
label: 'Manifest',
|
|
85
|
+
value: 'manifest',
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
},
|
|
89
|
+
} satisfies Readonly<
|
|
90
|
+
Record<'guideFormat', FieldOverride & { readonly aliases: true }>
|
|
91
|
+
>;
|
|
92
|
+
|
|
93
|
+
export const wardenGuideTrail = trail('warden.guide', {
|
|
94
|
+
blaze: (input) => {
|
|
95
|
+
const manifest = buildWardenGuideManifest();
|
|
96
|
+
return Result.ok({
|
|
97
|
+
format: input.guideFormat,
|
|
98
|
+
formatted: formatWardenGuide(manifest, input.guideFormat),
|
|
99
|
+
manifest,
|
|
100
|
+
});
|
|
101
|
+
},
|
|
102
|
+
description: 'Project Warden rule guidance as markdown or JSON',
|
|
103
|
+
examples: [
|
|
104
|
+
{
|
|
105
|
+
input: { guideFormat: 'markdown' },
|
|
106
|
+
name: 'Markdown guide',
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
input: { guideFormat: 'agent-json' },
|
|
110
|
+
name: 'Agent JSON guide',
|
|
111
|
+
},
|
|
112
|
+
],
|
|
113
|
+
fields: wardenGuideFields,
|
|
114
|
+
input: wardenGuideInputSchema,
|
|
115
|
+
intent: 'read',
|
|
116
|
+
output: z.object({
|
|
117
|
+
format: z.enum(wardenGuideFormatValues),
|
|
118
|
+
formatted: z.string(),
|
|
119
|
+
manifest: wardenGuideManifestSchema,
|
|
120
|
+
}),
|
|
121
|
+
});
|