@ontrails/trails 1.0.0-beta.3 → 1.0.0-beta.32
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 +975 -0
- package/README.md +27 -0
- package/package.json +30 -7
- package/src/app.ts +125 -2
- package/src/cli.ts +345 -11
- package/src/completions.ts +240 -0
- package/src/lifecycle-source-io.ts +33 -0
- package/src/load-app-mirror.ts +202 -0
- package/src/local-state-io.ts +173 -0
- package/src/mcp-app.ts +40 -0
- package/src/mcp-options.ts +77 -0
- package/src/mcp.ts +8 -0
- package/src/project-writes.ts +377 -0
- package/src/regrade/config.ts +152 -0
- package/src/release/bindings.ts +39 -0
- package/src/release/check.ts +844 -0
- package/src/release/config.ts +63 -0
- package/src/release/contract-facts.ts +425 -0
- package/src/release/index.ts +125 -0
- package/src/release/native-bun-publish.ts +651 -0
- package/src/release/native-bun-registry.ts +754 -0
- package/src/release/pack-coherence.ts +455 -0
- package/src/release/packed-artifacts-smoke.ts +236 -0
- package/src/release/policy.ts +1684 -0
- package/src/release/semver.ts +104 -0
- package/src/release/smoke.ts +46 -0
- package/src/release/wayfinder-dogfood-smoke.ts +760 -0
- package/src/retired-topo-command.ts +36 -0
- package/src/run-adapter-check.ts +76 -0
- package/src/run-collision.ts +126 -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-release-check.ts +74 -0
- package/src/run-schema.ts +41 -0
- package/src/run-trace.ts +273 -0
- package/src/run-warden.ts +39 -0
- package/src/run-watch.ts +432 -0
- package/src/run-wayfind-outline.ts +166 -0
- package/src/scaffold-version-sync.ts +183 -0
- package/src/scaffold-versions.generated.ts +12 -0
- package/src/trails/adapter-check.ts +244 -0
- package/src/trails/add-surface.ts +94 -40
- package/src/trails/add-trail.ts +79 -41
- package/src/trails/add-verify.ts +95 -25
- package/src/trails/compile.ts +59 -0
- package/src/trails/completions-complete.ts +165 -0
- package/src/trails/completions.ts +47 -0
- package/src/trails/create-adapter.ts +1024 -0
- package/src/trails/create-scaffold.ts +399 -104
- package/src/trails/create-versions.ts +62 -0
- package/src/trails/create.ts +186 -72
- package/src/trails/deprecate.ts +59 -0
- package/src/trails/dev-clean.ts +82 -0
- package/src/trails/dev-reset.ts +50 -0
- package/src/trails/dev-stats.ts +72 -0
- package/src/trails/dev-support.ts +360 -0
- package/src/trails/doctor.ts +77 -0
- package/src/trails/draft-promote.ts +949 -0
- package/src/trails/guide.ts +71 -69
- package/src/trails/load-app.ts +1142 -16
- package/src/trails/operator-context.ts +66 -0
- package/src/trails/project.ts +17 -3
- package/src/trails/regrade.ts +292 -0
- package/src/trails/release-check.ts +105 -0
- package/src/trails/release-smoke.ts +48 -0
- package/src/trails/revise.ts +53 -0
- package/src/trails/root-dir.ts +21 -0
- package/src/trails/run-example.ts +475 -0
- package/src/trails/run-examples.ts +129 -0
- package/src/trails/run.ts +434 -0
- package/src/trails/scaffold-json.ts +58 -0
- package/src/trails/survey.ts +896 -227
- package/src/trails/topo-activation.ts +14 -0
- package/src/trails/topo-constants.ts +2 -0
- package/src/trails/topo-history.ts +47 -0
- package/src/trails/topo-output-schemas.ts +259 -0
- package/src/trails/topo-pin.ts +38 -0
- package/src/trails/topo-read-support.ts +363 -0
- package/src/trails/topo-reports.ts +809 -0
- package/src/trails/topo-store-support.ts +307 -0
- package/src/trails/topo-support.ts +219 -0
- package/src/trails/topo-unpin.ts +61 -0
- package/src/trails/topo.ts +92 -0
- package/src/trails/validate.ts +27 -0
- package/src/trails/version-lifecycle-support.ts +935 -0
- package/src/trails/warden-guide.ts +134 -0
- package/src/trails/warden.ts +198 -58
- package/src/trails/wayfind.ts +1001 -0
- package/src/versions.ts +31 -0
- 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 -6
- 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 -11
- 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 -13
- 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 -88
- package/dist/src/trails/add-surface.js.map +0 -1
- package/dist/src/trails/add-trail.d.ts +0 -11
- package/dist/src/trails/add-trail.d.ts.map +0 -1
- package/dist/src/trails/add-trail.js +0 -85
- package/dist/src/trails/add-trail.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 -67
- 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 -288
- package/dist/src/trails/create-scaffold.js.map +0 -1
- package/dist/src/trails/create.d.ts +0 -22
- package/dist/src/trails/create.d.ts.map +0 -1
- package/dist/src/trails/create.js +0 -121
- package/dist/src/trails/create.js.map +0 -1
- package/dist/src/trails/guide.d.ts +0 -11
- package/dist/src/trails/guide.d.ts.map +0 -1
- package/dist/src/trails/guide.js +0 -80
- package/dist/src/trails/guide.js.map +0 -1
- package/dist/src/trails/load-app.d.ts +0 -4
- package/dist/src/trails/load-app.d.ts.map +0 -1
- package/dist/src/trails/load-app.js +0 -24
- 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 -43
- package/dist/src/trails/project.js.map +0 -1
- package/dist/src/trails/survey.d.ts +0 -33
- package/dist/src/trails/survey.d.ts.map +0 -1
- package/dist/src/trails/survey.js +0 -225
- package/dist/src/trails/survey.js.map +0 -1
- package/dist/src/trails/warden.d.ts +0 -19
- package/dist/src/trails/warden.d.ts.map +0 -1
- package/dist/src/trails/warden.js +0 -88
- package/dist/src/trails/warden.js.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/src/__tests__/create.test.ts +0 -349
- package/src/__tests__/guide.test.ts +0 -91
- package/src/__tests__/load-app.test.ts +0 -15
- package/src/__tests__/survey.test.ts +0 -161
- package/src/__tests__/warden.test.ts +0 -74
- package/tsconfig.json +0 -9
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import type { FieldOverride } from '@ontrails/core';
|
|
2
|
+
import { Result, trail } from '@ontrails/core';
|
|
3
|
+
import {
|
|
4
|
+
buildWardenGuideManifest,
|
|
5
|
+
formatWardenGuide,
|
|
6
|
+
wardenDepthValues,
|
|
7
|
+
wardenFixClasses,
|
|
8
|
+
wardenFixSafeties,
|
|
9
|
+
wardenGuideFormatValues,
|
|
10
|
+
wardenRuleConcerns,
|
|
11
|
+
wardenRuleLifecycleStates,
|
|
12
|
+
wardenRuleScopes,
|
|
13
|
+
wardenRuleTiers,
|
|
14
|
+
} from '@ontrails/warden';
|
|
15
|
+
import { z } from 'zod';
|
|
16
|
+
|
|
17
|
+
const wardenGuidanceLinkSchema = z.object({
|
|
18
|
+
label: z.string(),
|
|
19
|
+
path: z.string().optional(),
|
|
20
|
+
url: z.string().optional(),
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const wardenGuidanceSchema = z.object({
|
|
24
|
+
commands: z.array(z.string()).readonly().optional(),
|
|
25
|
+
docs: z.array(wardenGuidanceLinkSchema).readonly().optional(),
|
|
26
|
+
relatedRules: z.array(z.string()).readonly().optional(),
|
|
27
|
+
steps: z.array(z.string()).readonly().optional(),
|
|
28
|
+
summary: z.string(),
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const wardenRuleGuideEntrySchema = z.object({
|
|
32
|
+
concern: z.enum(wardenRuleConcerns),
|
|
33
|
+
depth: z.enum(wardenDepthValues),
|
|
34
|
+
description: z.string(),
|
|
35
|
+
docs: z.array(wardenGuidanceLinkSchema).readonly(),
|
|
36
|
+
fix: z
|
|
37
|
+
.object({
|
|
38
|
+
class: z.enum(wardenFixClasses),
|
|
39
|
+
safety: z.enum(wardenFixSafeties),
|
|
40
|
+
scanTargets: z
|
|
41
|
+
.object({
|
|
42
|
+
exclude: z.array(z.string()).readonly().optional(),
|
|
43
|
+
extensions: z.array(z.string()).readonly().optional(),
|
|
44
|
+
})
|
|
45
|
+
.optional(),
|
|
46
|
+
})
|
|
47
|
+
.optional(),
|
|
48
|
+
guidance: wardenGuidanceSchema.optional(),
|
|
49
|
+
id: z.string(),
|
|
50
|
+
invariant: z.string(),
|
|
51
|
+
lifecycle: z.object({
|
|
52
|
+
retireWhen: z.string().optional(),
|
|
53
|
+
state: z.enum(wardenRuleLifecycleStates),
|
|
54
|
+
}),
|
|
55
|
+
scope: z.enum(wardenRuleScopes),
|
|
56
|
+
severity: z.enum(['error', 'warn']),
|
|
57
|
+
tier: z.enum(wardenRuleTiers),
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const wardenGuideManifestSchema = z.object({
|
|
61
|
+
generatedFrom: z.object({
|
|
62
|
+
package: z.literal('@ontrails/warden'),
|
|
63
|
+
registries: z
|
|
64
|
+
.tuple([z.literal('wardenRules'), z.literal('wardenTopoRules')])
|
|
65
|
+
.readonly(),
|
|
66
|
+
source: z.literal('builtin-rule-metadata'),
|
|
67
|
+
}),
|
|
68
|
+
kind: z.literal('trails-warden-guide-manifest'),
|
|
69
|
+
ruleCount: z.number(),
|
|
70
|
+
rules: z.array(wardenRuleGuideEntrySchema).readonly(),
|
|
71
|
+
version: z.literal(1),
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const wardenGuideInputSchema = z.object({
|
|
75
|
+
guideFormat: z
|
|
76
|
+
.enum(wardenGuideFormatValues)
|
|
77
|
+
.default('markdown')
|
|
78
|
+
.describe('Guide output format'),
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const wardenGuideFields = {
|
|
82
|
+
guideFormat: {
|
|
83
|
+
aliases: true,
|
|
84
|
+
options: [
|
|
85
|
+
{
|
|
86
|
+
hint: 'Human-readable Warden guide',
|
|
87
|
+
label: 'Markdown',
|
|
88
|
+
value: 'markdown',
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
hint: 'Compact guidance for agent context',
|
|
92
|
+
label: 'Agent JSON',
|
|
93
|
+
value: 'agent-json',
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
hint: 'Full structured rule manifest',
|
|
97
|
+
label: 'Manifest',
|
|
98
|
+
value: 'manifest',
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
},
|
|
102
|
+
} satisfies Readonly<
|
|
103
|
+
Record<'guideFormat', FieldOverride & { readonly aliases: true }>
|
|
104
|
+
>;
|
|
105
|
+
|
|
106
|
+
export const wardenGuideTrail = trail('warden.guide', {
|
|
107
|
+
blaze: (input) => {
|
|
108
|
+
const manifest = buildWardenGuideManifest();
|
|
109
|
+
return Result.ok({
|
|
110
|
+
format: input.guideFormat,
|
|
111
|
+
formatted: formatWardenGuide(manifest, input.guideFormat),
|
|
112
|
+
manifest,
|
|
113
|
+
});
|
|
114
|
+
},
|
|
115
|
+
description: 'Project Warden rule guidance as markdown or JSON',
|
|
116
|
+
examples: [
|
|
117
|
+
{
|
|
118
|
+
input: { guideFormat: 'markdown' },
|
|
119
|
+
name: 'Markdown guide',
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
input: { guideFormat: 'agent-json' },
|
|
123
|
+
name: 'Agent JSON guide',
|
|
124
|
+
},
|
|
125
|
+
],
|
|
126
|
+
fields: wardenGuideFields,
|
|
127
|
+
input: wardenGuideInputSchema,
|
|
128
|
+
intent: 'read',
|
|
129
|
+
output: z.object({
|
|
130
|
+
format: z.enum(wardenGuideFormatValues),
|
|
131
|
+
formatted: z.string(),
|
|
132
|
+
manifest: wardenGuideManifestSchema,
|
|
133
|
+
}),
|
|
134
|
+
});
|
package/src/trails/warden.ts
CHANGED
|
@@ -1,104 +1,244 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `warden` trail -- Governance checks.
|
|
3
3
|
*
|
|
4
|
-
* Thin wrapper around
|
|
4
|
+
* Thin wrapper around the shared @ontrails/warden command surface.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { Result, trail } from '@ontrails/core';
|
|
8
8
|
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
diagnosticSchema,
|
|
10
|
+
runWardenCommand,
|
|
11
|
+
wardenDepthValues,
|
|
12
|
+
wardenDraftsValues,
|
|
13
|
+
wardenFailOnValues,
|
|
14
|
+
wardenFormatValues,
|
|
15
|
+
wardenLockValues,
|
|
14
16
|
} from '@ontrails/warden';
|
|
15
17
|
import { z } from 'zod';
|
|
16
18
|
|
|
17
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
createIsolatedExampleRoot,
|
|
21
|
+
writeIsolatedExampleTextFile,
|
|
22
|
+
} from '../local-state-io.js';
|
|
23
|
+
|
|
24
|
+
import { resolveTrailRootDir } from './root-dir.js';
|
|
18
25
|
|
|
19
26
|
// ---------------------------------------------------------------------------
|
|
20
27
|
// Trail definition
|
|
21
28
|
// ---------------------------------------------------------------------------
|
|
22
29
|
|
|
30
|
+
const wardenInputSchema = z.object({
|
|
31
|
+
adapterCheck: z
|
|
32
|
+
.boolean()
|
|
33
|
+
.default(false)
|
|
34
|
+
.describe('Run shared adapter authoring checks'),
|
|
35
|
+
apps: z
|
|
36
|
+
.array(z.string())
|
|
37
|
+
.optional()
|
|
38
|
+
.describe('App names or module paths to govern'),
|
|
39
|
+
cached: z.boolean().default(false).describe('Alias for --lock cached'),
|
|
40
|
+
ci: z.boolean().default(false).describe('Use the CI Warden preset'),
|
|
41
|
+
configPath: z.string().optional().describe('Path to trails.config.ts'),
|
|
42
|
+
depth: z
|
|
43
|
+
.enum(wardenDepthValues)
|
|
44
|
+
.optional()
|
|
45
|
+
.describe('Cumulative analysis depth'),
|
|
46
|
+
drafts: z.enum(wardenDraftsValues).optional().describe('Draft state mode'),
|
|
47
|
+
excludeDrafts: z
|
|
48
|
+
.boolean()
|
|
49
|
+
.default(false)
|
|
50
|
+
.describe('Alias for --drafts exclude'),
|
|
51
|
+
failOn: z.enum(wardenFailOnValues).optional().describe('Failure threshold'),
|
|
52
|
+
fix: z.boolean().default(false).describe('Apply safe source fixes'),
|
|
53
|
+
format: z.enum(wardenFormatValues).optional().describe('Output format'),
|
|
54
|
+
github: z.boolean().default(false).describe('Alias for --format github'),
|
|
55
|
+
includeDrafts: z
|
|
56
|
+
.boolean()
|
|
57
|
+
.default(false)
|
|
58
|
+
.describe('Alias for --drafts include'),
|
|
59
|
+
json: z.boolean().default(false).describe('Alias for --format json'),
|
|
60
|
+
lock: z.enum(wardenLockValues).optional().describe('Lockfile mode'),
|
|
61
|
+
noLockMutation: z
|
|
62
|
+
.boolean()
|
|
63
|
+
.default(false)
|
|
64
|
+
.describe('Suppress lockfile mutation'),
|
|
65
|
+
onlyDrafts: z.boolean().default(false).describe('Alias for --drafts only'),
|
|
66
|
+
prePush: z.boolean().default(false).describe('Use the pre-push preset'),
|
|
67
|
+
refresh: z.boolean().default(false).describe('Alias for --lock refresh'),
|
|
68
|
+
rootDir: z.string().optional().describe('Root directory to scan'),
|
|
69
|
+
scopeExclude: z
|
|
70
|
+
.array(z.string())
|
|
71
|
+
.optional()
|
|
72
|
+
.describe('Root-relative path globs that Warden should not govern'),
|
|
73
|
+
skipLock: z.boolean().default(false).describe('Alias for --lock skip'),
|
|
74
|
+
strict: z.boolean().default(false).describe('Alias for --fail-on warning'),
|
|
75
|
+
summary: z.boolean().default(false).describe('Alias for --format summary'),
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
type WardenTrailInput = z.infer<typeof wardenInputSchema>;
|
|
79
|
+
|
|
80
|
+
const createIsolatedWardenExampleRoot = (name: string): string => {
|
|
81
|
+
const rootDir = createIsolatedExampleRoot(
|
|
82
|
+
`warden-${name}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`
|
|
83
|
+
);
|
|
84
|
+
writeIsolatedExampleTextFile(rootDir, 'src/clean.ts', 'export {};\n');
|
|
85
|
+
return rootDir;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const pushFlag = (args: string[], condition: boolean, flag: string): void => {
|
|
89
|
+
if (condition) {
|
|
90
|
+
args.push(flag);
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const pushValue = (
|
|
95
|
+
args: string[],
|
|
96
|
+
flag: string,
|
|
97
|
+
value: string | undefined
|
|
98
|
+
): void => {
|
|
99
|
+
if (value !== undefined) {
|
|
100
|
+
args.push(flag, value);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const pushApps = (
|
|
105
|
+
args: string[],
|
|
106
|
+
apps: readonly string[] | undefined
|
|
107
|
+
): void => {
|
|
108
|
+
if (apps !== undefined && apps.length > 0) {
|
|
109
|
+
args.push('--apps', apps.join(','));
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const pushRepeatedValues = (
|
|
114
|
+
args: string[],
|
|
115
|
+
flag: string,
|
|
116
|
+
values: readonly string[] | undefined
|
|
117
|
+
): void => {
|
|
118
|
+
for (const value of values ?? []) {
|
|
119
|
+
args.push(flag, value);
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
export const buildWardenCommandArgs = (
|
|
124
|
+
input: WardenTrailInput
|
|
125
|
+
): readonly string[] => {
|
|
126
|
+
const args: string[] = [];
|
|
127
|
+
|
|
128
|
+
pushFlag(args, input.prePush, '--pre-push');
|
|
129
|
+
pushFlag(args, input.ci, '--ci');
|
|
130
|
+
pushValue(args, '--depth', input.depth);
|
|
131
|
+
if (input.strict) {
|
|
132
|
+
args.push('--strict');
|
|
133
|
+
} else {
|
|
134
|
+
pushValue(args, '--fail-on', input.failOn);
|
|
135
|
+
}
|
|
136
|
+
if (input.github) {
|
|
137
|
+
args.push('--github');
|
|
138
|
+
} else if (input.json) {
|
|
139
|
+
args.push('--json');
|
|
140
|
+
} else if (input.summary) {
|
|
141
|
+
args.push('--summary');
|
|
142
|
+
} else {
|
|
143
|
+
pushValue(args, '--format', input.format);
|
|
144
|
+
}
|
|
145
|
+
if (input.skipLock) {
|
|
146
|
+
args.push('--skip-lock');
|
|
147
|
+
} else if (input.refresh) {
|
|
148
|
+
args.push('--refresh');
|
|
149
|
+
} else if (input.cached) {
|
|
150
|
+
args.push('--cached');
|
|
151
|
+
} else {
|
|
152
|
+
pushValue(args, '--lock', input.lock);
|
|
153
|
+
}
|
|
154
|
+
if (input.onlyDrafts) {
|
|
155
|
+
args.push('--only-drafts');
|
|
156
|
+
} else if (input.excludeDrafts) {
|
|
157
|
+
args.push('--exclude-drafts');
|
|
158
|
+
} else if (input.includeDrafts) {
|
|
159
|
+
args.push('--include-drafts');
|
|
160
|
+
} else {
|
|
161
|
+
pushValue(args, '--drafts', input.drafts);
|
|
162
|
+
}
|
|
163
|
+
pushFlag(args, input.noLockMutation, '--no-lock-mutation');
|
|
164
|
+
pushFlag(args, input.fix, '--fix');
|
|
165
|
+
pushFlag(args, input.adapterCheck, '--adapter-check');
|
|
166
|
+
pushValue(args, '--config-path', input.configPath);
|
|
167
|
+
pushRepeatedValues(args, '--scope-exclude', input.scopeExclude);
|
|
168
|
+
pushApps(args, input.apps);
|
|
169
|
+
|
|
170
|
+
return args;
|
|
171
|
+
};
|
|
172
|
+
|
|
23
173
|
export const wardenTrail = trail('warden', {
|
|
174
|
+
blaze: async (input, ctx) => {
|
|
175
|
+
const rootDirResult = resolveTrailRootDir(input.rootDir, ctx.cwd);
|
|
176
|
+
if (rootDirResult.isErr()) {
|
|
177
|
+
return rootDirResult;
|
|
178
|
+
}
|
|
179
|
+
const rootDir = rootDirResult.value;
|
|
180
|
+
const result = await runWardenCommand({
|
|
181
|
+
args: buildWardenCommandArgs(input),
|
|
182
|
+
cwd: rootDir,
|
|
183
|
+
env: ctx.env ?? {},
|
|
184
|
+
});
|
|
185
|
+
const { report } = result;
|
|
186
|
+
|
|
187
|
+
return Result.ok({
|
|
188
|
+
diagnostics: [...report.diagnostics],
|
|
189
|
+
drift: report.drift,
|
|
190
|
+
errorCount: report.errorCount,
|
|
191
|
+
fixes: report.fixes,
|
|
192
|
+
formatted: result.output,
|
|
193
|
+
passed: report.passed,
|
|
194
|
+
warnCount: report.warnCount,
|
|
195
|
+
});
|
|
196
|
+
},
|
|
24
197
|
description: 'Run governance checks (lint + drift)',
|
|
25
198
|
examples: [
|
|
26
199
|
{
|
|
27
200
|
input: {
|
|
28
|
-
|
|
29
|
-
|
|
201
|
+
depth: 'source',
|
|
202
|
+
lock: 'skip',
|
|
203
|
+
rootDir: createIsolatedWardenExampleRoot('default'),
|
|
30
204
|
},
|
|
31
205
|
name: 'Default warden run',
|
|
32
206
|
},
|
|
33
207
|
{
|
|
34
208
|
input: {
|
|
209
|
+
depth: 'source',
|
|
35
210
|
format: 'github',
|
|
211
|
+
lock: 'skip',
|
|
212
|
+
rootDir: createIsolatedWardenExampleRoot('github'),
|
|
36
213
|
},
|
|
37
214
|
name: 'GitHub Actions annotations',
|
|
38
215
|
},
|
|
39
216
|
],
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
// oxlint-disable-next-line prefer-await-to-then -- catch converts rejection to undefined cleanly
|
|
43
|
-
const topo = await loadApp('./src/app.ts', rootDir).catch(
|
|
44
|
-
(): undefined => undefined
|
|
45
|
-
);
|
|
46
|
-
|
|
47
|
-
const report = await runWarden({
|
|
48
|
-
driftOnly: input.driftOnly,
|
|
49
|
-
lintOnly: input.lintOnly,
|
|
50
|
-
rootDir,
|
|
51
|
-
topo,
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
const formatters: Record<string, (r: typeof report) => string> = {
|
|
55
|
-
github: formatGitHubAnnotations,
|
|
56
|
-
json: formatJson,
|
|
57
|
-
summary: formatSummary,
|
|
58
|
-
text: formatWardenReport,
|
|
59
|
-
};
|
|
60
|
-
const formatter = formatters[input.format] ?? formatWardenReport;
|
|
61
|
-
const formatted = formatter(report);
|
|
62
|
-
|
|
63
|
-
return Result.ok({
|
|
64
|
-
diagnostics: report.diagnostics,
|
|
65
|
-
drift: report.drift,
|
|
66
|
-
errorCount: report.errorCount,
|
|
67
|
-
formatted,
|
|
68
|
-
passed: report.passed,
|
|
69
|
-
warnCount: report.warnCount,
|
|
70
|
-
});
|
|
71
|
-
},
|
|
72
|
-
input: z.object({
|
|
73
|
-
driftOnly: z.boolean().default(false).describe('Only run drift detection'),
|
|
74
|
-
format: z
|
|
75
|
-
.enum(['text', 'json', 'github', 'summary'])
|
|
76
|
-
.default('text')
|
|
77
|
-
.describe('Output format: text, json, github, or summary'),
|
|
78
|
-
lintOnly: z.boolean().default(false).describe('Only run lint rules'),
|
|
79
|
-
rootDir: z.string().optional().describe('Root directory to scan'),
|
|
80
|
-
}),
|
|
217
|
+
input: wardenInputSchema,
|
|
218
|
+
intent: 'write',
|
|
81
219
|
output: z.object({
|
|
82
220
|
diagnostics: z.array(
|
|
83
|
-
z.
|
|
84
|
-
filePath: z.string(),
|
|
85
|
-
line: z.number(),
|
|
86
|
-
message: z.string(),
|
|
87
|
-
rule: z.string(),
|
|
88
|
-
severity: z.enum(['error', 'warn']),
|
|
89
|
-
})
|
|
221
|
+
diagnosticSchema.extend({ topoName: z.string().optional() })
|
|
90
222
|
),
|
|
91
223
|
drift: z
|
|
92
224
|
.object({
|
|
225
|
+
blockedReason: z.string().optional(),
|
|
93
226
|
committedHash: z.string().nullable(),
|
|
94
227
|
currentHash: z.string(),
|
|
95
228
|
stale: z.boolean(),
|
|
96
229
|
})
|
|
97
230
|
.nullable(),
|
|
98
231
|
errorCount: z.number(),
|
|
232
|
+
fixes: z
|
|
233
|
+
.object({
|
|
234
|
+
applied: z.number(),
|
|
235
|
+
filesChanged: z.number(),
|
|
236
|
+
skipped: z.number(),
|
|
237
|
+
})
|
|
238
|
+
.optional(),
|
|
99
239
|
formatted: z.string(),
|
|
100
240
|
passed: z.boolean(),
|
|
101
241
|
warnCount: z.number(),
|
|
102
242
|
}),
|
|
103
|
-
|
|
243
|
+
permit: 'public',
|
|
104
244
|
});
|