@ontrails/trails 1.0.0-beta.4 → 1.0.0-beta.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1104 -4
- package/README.md +27 -0
- package/package.json +31 -7
- package/src/app.ts +147 -3
- 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 +42 -0
- package/src/mcp-options.ts +91 -0
- package/src/mcp.ts +8 -0
- package/src/project-writes.ts +377 -0
- package/src/regrade/config.ts +152 -0
- package/src/regrade/history.ts +430 -0
- package/src/regrade/live-api-preserve.ts +8 -0
- package/src/regrade/plan-artifact.ts +285 -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 +142 -0
- package/src/release/lock-roundtrip-smoke.ts +230 -0
- package/src/release/native-bun-publish.ts +651 -0
- package/src/release/native-bun-registry.ts +765 -0
- package/src/release/notes-cli.ts +171 -0
- package/src/release/notes.ts +390 -0
- package/src/release/pack-coherence.ts +455 -0
- package/src/release/packed-artifacts-smoke.ts +236 -0
- package/src/release/policy.ts +1687 -0
- package/src/release/semver.ts +104 -0
- package/src/release/smoke.ts +56 -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 +74 -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 +170 -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 +99 -45
- package/src/trails/add-trail.ts +84 -37
- package/src/trails/add-verify.ts +100 -30
- package/src/trails/compile.ts +58 -0
- package/src/trails/completions-complete.ts +165 -0
- package/src/trails/completions.ts +47 -0
- package/src/trails/create-adapter.ts +785 -0
- package/src/trails/create-scaffold.ts +401 -106
- 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 +70 -68
- package/src/trails/load-app.ts +1123 -15
- package/src/trails/operator-context.ts +66 -0
- package/src/trails/project.ts +17 -3
- package/src/trails/regrade.ts +3091 -0
- package/src/trails/release-check.ts +105 -0
- package/src/trails/release-smoke.ts +49 -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 +877 -214
- 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 +368 -0
- package/src/trails/topo-reports.ts +809 -0
- package/src/trails/topo-store-support.ts +325 -0
- package/src/trails/topo-support.ts +220 -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 +936 -0
- package/src/trails/warden-guide.ts +134 -0
- package/src/trails/warden.ts +198 -58
- package/src/trails/wayfind-outline.ts +876 -0
- package/src/trails/wayfind.ts +1053 -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 -10
- package/dist/src/trails/add-trail.d.ts.map +0 -1
- package/dist/src/trails/add-trail.js +0 -77
- 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 -31
- package/dist/src/trails/survey.d.ts.map +0 -1
- package/dist/src/trails/survey.js +0 -221
- 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 -159
- 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
|
+
description: 'Project Warden rule guidance as markdown or JSON',
|
|
108
|
+
examples: [
|
|
109
|
+
{
|
|
110
|
+
input: { guideFormat: 'markdown' },
|
|
111
|
+
name: 'Markdown guide',
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
input: { guideFormat: 'agent-json' },
|
|
115
|
+
name: 'Agent JSON guide',
|
|
116
|
+
},
|
|
117
|
+
],
|
|
118
|
+
fields: wardenGuideFields,
|
|
119
|
+
implementation: (input) => {
|
|
120
|
+
const manifest = buildWardenGuideManifest();
|
|
121
|
+
return Result.ok({
|
|
122
|
+
format: input.guideFormat,
|
|
123
|
+
formatted: formatWardenGuide(manifest, input.guideFormat),
|
|
124
|
+
manifest,
|
|
125
|
+
});
|
|
126
|
+
},
|
|
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', {
|
|
24
174
|
description: 'Run governance checks (lint + drift)',
|
|
25
175
|
examples: [
|
|
26
176
|
{
|
|
27
177
|
input: {
|
|
28
|
-
|
|
29
|
-
|
|
178
|
+
depth: 'source',
|
|
179
|
+
lock: 'skip',
|
|
180
|
+
rootDir: createIsolatedWardenExampleRoot('default'),
|
|
30
181
|
},
|
|
31
182
|
name: 'Default warden run',
|
|
32
183
|
},
|
|
33
184
|
{
|
|
34
185
|
input: {
|
|
186
|
+
depth: 'source',
|
|
35
187
|
format: 'github',
|
|
188
|
+
lock: 'skip',
|
|
189
|
+
rootDir: createIsolatedWardenExampleRoot('github'),
|
|
36
190
|
},
|
|
37
191
|
name: 'GitHub Actions annotations',
|
|
38
192
|
},
|
|
39
193
|
],
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
194
|
+
implementation: async (input, ctx) => {
|
|
195
|
+
const rootDirResult = resolveTrailRootDir(input.rootDir, ctx.cwd);
|
|
196
|
+
if (rootDirResult.isErr()) {
|
|
197
|
+
return rootDirResult;
|
|
198
|
+
}
|
|
199
|
+
const rootDir = rootDirResult.value;
|
|
200
|
+
const result = await runWardenCommand({
|
|
201
|
+
args: buildWardenCommandArgs(input),
|
|
202
|
+
cwd: rootDir,
|
|
203
|
+
env: ctx.env ?? {},
|
|
204
|
+
});
|
|
205
|
+
const { report } = result;
|
|
206
|
+
|
|
207
|
+
return Result.ok({
|
|
208
|
+
diagnostics: [...report.diagnostics],
|
|
209
|
+
drift: report.drift,
|
|
210
|
+
errorCount: report.errorCount,
|
|
211
|
+
fixes: report.fixes,
|
|
212
|
+
formatted: result.output,
|
|
213
|
+
passed: report.passed,
|
|
214
|
+
warnCount: report.warnCount,
|
|
215
|
+
});
|
|
216
|
+
},
|
|
217
|
+
input: wardenInputSchema,
|
|
218
|
+
intent: 'write',
|
|
50
219
|
output: z.object({
|
|
51
220
|
diagnostics: z.array(
|
|
52
|
-
z.
|
|
53
|
-
filePath: z.string(),
|
|
54
|
-
line: z.number(),
|
|
55
|
-
message: z.string(),
|
|
56
|
-
rule: z.string(),
|
|
57
|
-
severity: z.enum(['error', 'warn']),
|
|
58
|
-
})
|
|
221
|
+
diagnosticSchema.extend({ topoName: z.string().optional() })
|
|
59
222
|
),
|
|
60
223
|
drift: z
|
|
61
224
|
.object({
|
|
225
|
+
blockedReason: z.string().optional(),
|
|
62
226
|
committedHash: z.string().nullable(),
|
|
63
227
|
currentHash: z.string(),
|
|
64
228
|
stale: z.boolean(),
|
|
65
229
|
})
|
|
66
230
|
.nullable(),
|
|
67
231
|
errorCount: z.number(),
|
|
232
|
+
fixes: z
|
|
233
|
+
.object({
|
|
234
|
+
applied: z.number(),
|
|
235
|
+
filesChanged: z.number(),
|
|
236
|
+
skipped: z.number(),
|
|
237
|
+
})
|
|
238
|
+
.optional(),
|
|
68
239
|
formatted: z.string(),
|
|
69
240
|
passed: z.boolean(),
|
|
70
241
|
warnCount: z.number(),
|
|
71
242
|
}),
|
|
72
|
-
|
|
73
|
-
const rootDir = input.rootDir ?? ctx.cwd ?? process.cwd();
|
|
74
|
-
// oxlint-disable-next-line prefer-await-to-then -- catch converts rejection to undefined cleanly
|
|
75
|
-
const topo = await loadApp('./src/app.ts', rootDir).catch(
|
|
76
|
-
(): undefined => undefined
|
|
77
|
-
);
|
|
78
|
-
|
|
79
|
-
const report = await runWarden({
|
|
80
|
-
driftOnly: input.driftOnly,
|
|
81
|
-
lintOnly: input.lintOnly,
|
|
82
|
-
rootDir,
|
|
83
|
-
topo,
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
const formatters: Record<string, (r: typeof report) => string> = {
|
|
87
|
-
github: formatGitHubAnnotations,
|
|
88
|
-
json: formatJson,
|
|
89
|
-
summary: formatSummary,
|
|
90
|
-
text: formatWardenReport,
|
|
91
|
-
};
|
|
92
|
-
const formatter = formatters[input.format] ?? formatWardenReport;
|
|
93
|
-
const formatted = formatter(report);
|
|
94
|
-
|
|
95
|
-
return Result.ok({
|
|
96
|
-
diagnostics: report.diagnostics,
|
|
97
|
-
drift: report.drift,
|
|
98
|
-
errorCount: report.errorCount,
|
|
99
|
-
formatted,
|
|
100
|
-
passed: report.passed,
|
|
101
|
-
warnCount: report.warnCount,
|
|
102
|
-
});
|
|
103
|
-
},
|
|
243
|
+
permit: 'public',
|
|
104
244
|
});
|