vigiles 33.3.0 → 34.0.0
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/action.yml +45 -8
- package/dist/cli-flag-check.js +1 -0
- package/dist/cli-main.js +177 -4
- package/dist/core/config-schema.d.ts +53 -34
- package/dist/core/config-schema.js +42 -0
- package/dist/core/presets.d.ts +44 -0
- package/dist/core/presets.js +44 -0
- package/dist/core/validate.js +1 -1
- package/dist/setup-plan.d.ts +93 -25
- package/dist/setup-plan.js +133 -67
- package/dist/vigilesrc.schema.json +6 -0
- package/package.json +1 -1
package/action.yml
CHANGED
|
@@ -19,9 +19,15 @@ inputs:
|
|
|
19
19
|
required: false
|
|
20
20
|
default: ""
|
|
21
21
|
version:
|
|
22
|
-
description:
|
|
22
|
+
description: >
|
|
23
|
+
Version of the vigiles npm package to run (e.g. '34', '34.1.2', 'latest').
|
|
24
|
+
Empty (the default) runs the vigiles THIS repo declares in package.json:
|
|
25
|
+
the installed copy when node_modules has it, else the version in
|
|
26
|
+
package-lock.json, else the declared range — and 'latest' only when the
|
|
27
|
+
repo does not declare vigiles. Use 'local' to run the action's own
|
|
28
|
+
checkout — for dogfooding via `uses: ./` in this repo's CI.
|
|
23
29
|
required: false
|
|
24
|
-
default: "
|
|
30
|
+
default: ""
|
|
25
31
|
max-rules:
|
|
26
32
|
description: "Maximum number of rules per spec file (maps to the CLI's --max-rules)."
|
|
27
33
|
required: false
|
|
@@ -109,17 +115,48 @@ runs:
|
|
|
109
115
|
fi
|
|
110
116
|
|
|
111
117
|
# Resolve the runner. 'local' runs the action's own build (CI
|
|
112
|
-
# dogfood via `uses: ./`);
|
|
113
|
-
# package at that version
|
|
114
|
-
#
|
|
115
|
-
|
|
118
|
+
# dogfood via `uses: ./`); an explicit version runs the published npm
|
|
119
|
+
# package at that version. EMPTY (the default) runs the vigiles this
|
|
120
|
+
# repo declares, so CI and a local `npx vigiles` are the same version
|
|
121
|
+
# rather than two pins that drift: the installed copy, else the
|
|
122
|
+
# lockfile's version, else the declared range; `latest` only when the
|
|
123
|
+
# repo does not declare vigiles at all.
|
|
124
|
+
version="${VIGILES_VERSION:-}"
|
|
116
125
|
if [[ "$version" == "local" ]]; then
|
|
117
126
|
runner=(node "${VIGILES_ACTION_PATH}/dist/cli.js")
|
|
118
|
-
|
|
127
|
+
from="the action's own checkout"
|
|
128
|
+
elif [[ -n "$version" ]]; then
|
|
119
129
|
runner=(npx --yes "vigiles@${version}")
|
|
130
|
+
from="the version input"
|
|
131
|
+
else
|
|
132
|
+
declared="$(node -e '
|
|
133
|
+
const fs = require("fs");
|
|
134
|
+
const read = (f) => { try { return JSON.parse(fs.readFileSync(f, "utf8")); } catch { return null; } };
|
|
135
|
+
const pkg = read("package.json") ?? {};
|
|
136
|
+
const spec = pkg.devDependencies?.vigiles ?? pkg.dependencies?.vigiles;
|
|
137
|
+
if (typeof spec !== "string") { console.log("none"); process.exit(0); }
|
|
138
|
+
if (fs.existsSync("node_modules/.bin/vigiles")) { console.log("installed"); process.exit(0); }
|
|
139
|
+
const lock = read("package-lock.json") ?? {};
|
|
140
|
+
const locked = lock.packages?.["node_modules/vigiles"]?.version ?? lock.dependencies?.vigiles?.version;
|
|
141
|
+
console.log(typeof locked === "string" ? "lock " + locked : "range " + spec);
|
|
142
|
+
' 2>/dev/null || echo none)"
|
|
143
|
+
case "$declared" in
|
|
144
|
+
installed)
|
|
145
|
+
runner=(npx --no-install vigiles)
|
|
146
|
+
from="this repo's installed vigiles" ;;
|
|
147
|
+
"lock "*)
|
|
148
|
+
runner=(npx --yes "vigiles@${declared#lock }")
|
|
149
|
+
from="package-lock.json" ;;
|
|
150
|
+
"range "*)
|
|
151
|
+
runner=(npx --yes "vigiles@${declared#range }")
|
|
152
|
+
from="the range package.json declares" ;;
|
|
153
|
+
*)
|
|
154
|
+
runner=(npx --yes "vigiles@latest")
|
|
155
|
+
from="latest (this repo does not declare vigiles)" ;;
|
|
156
|
+
esac
|
|
120
157
|
fi
|
|
121
158
|
|
|
122
|
-
echo "vigiles: ${runner[*]} ${args[*]}"
|
|
159
|
+
echo "vigiles: ${runner[*]} ${args[*]} (version from ${from})"
|
|
123
160
|
|
|
124
161
|
# Run, streaming to the log AND capturing for the summary/comment.
|
|
125
162
|
out="$(mktemp)"
|
package/dist/cli-flag-check.js
CHANGED
package/dist/cli-main.js
CHANGED
|
@@ -27,6 +27,7 @@ const generate_harness_js_1 = require("./core/generate-harness.js");
|
|
|
27
27
|
const capability_diff_js_1 = require("./core/capability-diff.js");
|
|
28
28
|
const validate_js_1 = require("./core/validate.js");
|
|
29
29
|
const eval_lock_js_1 = require("./eval-lock.js");
|
|
30
|
+
const zod_1 = require("zod");
|
|
30
31
|
const cli_flags_js_1 = require("./cli-flags.js");
|
|
31
32
|
const cli_commands_js_1 = require("./cli-commands.js");
|
|
32
33
|
const cli_flag_check_js_1 = require("./cli-flag-check.js");
|
|
@@ -2636,6 +2637,9 @@ function vigilesWorkflow(plan, harnesses, hasPackageJson) {
|
|
|
2636
2637
|
- uses: actions/setup-node@v4
|
|
2637
2638
|
with:
|
|
2638
2639
|
node-version: "20"
|
|
2640
|
+
# No \`version:\` on purpose: the Action runs the vigiles your
|
|
2641
|
+
# package.json declares, so CI and a local \`npx vigiles\` cannot
|
|
2642
|
+
# drift onto two different pins.
|
|
2639
2643
|
- uses: zernie/vigiles@v1
|
|
2640
2644
|
`
|
|
2641
2645
|
: "";
|
|
@@ -3036,6 +3040,9 @@ function redirectSyncToolTargets(cwd, targets) {
|
|
|
3036
3040
|
`staling the integrity hash.`);
|
|
3037
3041
|
return out;
|
|
3038
3042
|
}
|
|
3043
|
+
/** The two files `init`'s lint layer generates under `.vigiles/`. */
|
|
3044
|
+
const GENERATED_TYPES = ".vigiles/generated.d.ts";
|
|
3045
|
+
const GENERATED_SCHEMA = ".vigiles/schema.json";
|
|
3039
3046
|
/** Pillar 1 — specs + types + schema + compile. Scaffolds a spec for every
|
|
3040
3047
|
* instruction file (so `--lint` always delivers a spec), but never compiles
|
|
3041
3048
|
* OVER a hand-written file — that is left to the adopt-spec skill. */
|
|
@@ -3081,7 +3088,7 @@ async function setupPillar1(detected, targetValue, harnesses) {
|
|
|
3081
3088
|
const outDir = (0, node_path_1.resolve)(cwd, ".vigiles");
|
|
3082
3089
|
if (!(0, node_fs_1.existsSync)(outDir))
|
|
3083
3090
|
(0, node_fs_1.mkdirSync)(outDir, { recursive: true });
|
|
3084
|
-
(0, node_fs_1.writeFileSync)((0, node_path_1.resolve)(cwd,
|
|
3091
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.resolve)(cwd, GENERATED_TYPES), typesResult.dts);
|
|
3085
3092
|
for (const l of typesResult.linters) {
|
|
3086
3093
|
console.log(` ${l.linter}: ${String(l.rules.length)} rules`);
|
|
3087
3094
|
}
|
|
@@ -3089,14 +3096,14 @@ async function setupPillar1(detected, targetValue, harnesses) {
|
|
|
3089
3096
|
console.log(` npm scripts: ${String(typesResult.scripts.length)}`);
|
|
3090
3097
|
}
|
|
3091
3098
|
console.log("✓ Generated .vigiles/generated.d.ts");
|
|
3092
|
-
written.push(
|
|
3099
|
+
written.push(GENERATED_TYPES);
|
|
3093
3100
|
const schemaResult = (0, generate_schema_js_1.generateSchema)({
|
|
3094
3101
|
basePath: cwd,
|
|
3095
3102
|
linters: (0, validate_js_1.loadConfig)().linters,
|
|
3096
3103
|
});
|
|
3097
|
-
(0, node_fs_1.writeFileSync)((0, node_path_1.resolve)(cwd,
|
|
3104
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.resolve)(cwd, GENERATED_SCHEMA), schemaResult.json);
|
|
3098
3105
|
console.log("✓ Generated .vigiles/schema.json (YAML-LSP frontmatter schema)");
|
|
3099
|
-
written.push(
|
|
3106
|
+
written.push(GENERATED_SCHEMA);
|
|
3100
3107
|
// Compile — but NEVER overwrite an existing hand-written file during `init`:
|
|
3101
3108
|
// we compile only GREENFIELD targets (the file doesn't exist yet) and targets
|
|
3102
3109
|
// we already manage (carry our hash). An ADOPTED file is left untouched — the
|
|
@@ -3609,8 +3616,24 @@ function printSetupSummary(opts) {
|
|
|
3609
3616
|
console.log(`\n Commit:\n git add ${files.join(" ")} && git commit -m "Add vigiles"`);
|
|
3610
3617
|
}
|
|
3611
3618
|
}
|
|
3619
|
+
/** The project config file `init` reads and writes. */
|
|
3620
|
+
const VIGILESRC = ".vigilesrc.json";
|
|
3612
3621
|
async function setup(args) {
|
|
3613
3622
|
const parsed = (0, setup_plan_js_1.parseSetupArgs)(args);
|
|
3623
|
+
// An already-adopted repo gets the MINIMAL re-run unless a flag asks for more
|
|
3624
|
+
// (#338): re-running `init` to pick up one new piece must not also wire CI,
|
|
3625
|
+
// widen the rules, scaffold files or rewrite a pin. Decided from disk, before
|
|
3626
|
+
// any prompt — the minimal run asks nothing.
|
|
3627
|
+
const state = (0, setup_plan_js_1.adoptionState)({
|
|
3628
|
+
hasConfig: (0, node_fs_1.existsSync)((0, node_path_1.resolve)(process.cwd(), VIGILESRC)),
|
|
3629
|
+
specs: detectProject()
|
|
3630
|
+
.instructionFiles.filter((f) => f.hasSpec)
|
|
3631
|
+
.map((f) => `${f.path}.spec.ts`),
|
|
3632
|
+
});
|
|
3633
|
+
if ((0, setup_plan_js_1.rerunScope)(parsed, state) === "minimal" && state.kind === "adopted") {
|
|
3634
|
+
minimalRerun(parsed, state);
|
|
3635
|
+
return;
|
|
3636
|
+
}
|
|
3614
3637
|
// Plan: defaults → flags → interactive prompts (only a human at a TTY).
|
|
3615
3638
|
let plan = (0, setup_plan_js_1.resolvePlan)(parsed);
|
|
3616
3639
|
const prompted = (0, setup_plan_js_1.shouldPrompt)(parsed, process.stdin.isTTY ?? false);
|
|
@@ -3707,6 +3730,152 @@ async function setup(args) {
|
|
|
3707
3730
|
console.log("\nℹ Ran the standard setup. Already have a harness, or not a JS/Python repo, and want only the CI integrity gate (nothing installed)? Re-run `npx vigiles init --ci-only`.");
|
|
3708
3731
|
}
|
|
3709
3732
|
}
|
|
3733
|
+
/**
|
|
3734
|
+
* The minimal re-run on an adopted repo (#338): add what is missing AND safe and
|
|
3735
|
+
* local — the skill links and a missing devDependency — then say what a full
|
|
3736
|
+
* setup would add and the flag that does it. It writes NOTHING else: no CI
|
|
3737
|
+
* workflow, no `.vigilesrc.json` edit, no harness/schema scaffold, no spec for a
|
|
3738
|
+
* hand-written file, no edit to an existing version pin, no global install.
|
|
3739
|
+
* The decisions are pure (`setup-plan.ts`); this is the IO.
|
|
3740
|
+
*/
|
|
3741
|
+
function minimalRerun(parsed, state) {
|
|
3742
|
+
const plan = (0, setup_plan_js_1.resolvePlan)(parsed);
|
|
3743
|
+
const detected = detectProject();
|
|
3744
|
+
const harnesses = resolveHarnesses(parsed, detected, (0, adapter_registry_js_1.declaredHarnessNames)((0, validate_js_1.loadConfig)().harnesses));
|
|
3745
|
+
console.log(`vigiles is already set up here (found ${state.evidence}) — adding only what is missing.\n`);
|
|
3746
|
+
printDetection(detected, harnesses);
|
|
3747
|
+
const links = plan.plugin ? linkSkillsOnly(harnesses) : [];
|
|
3748
|
+
const devDep = plan.lint || plan.test ? addMissingVigilesDevDep() : [];
|
|
3749
|
+
const written = [...links, ...devDep];
|
|
3750
|
+
if (written.length === 0)
|
|
3751
|
+
console.log("\nNothing was missing.");
|
|
3752
|
+
const followUps = (0, setup_plan_js_1.fullSetupFollowUps)(fullSetupGap(plan, detected, harnesses));
|
|
3753
|
+
if (followUps.length > 0)
|
|
3754
|
+
console.log(`\n${followUps.join("\n")}`);
|
|
3755
|
+
if (written.length > 0)
|
|
3756
|
+
console.log(`\n Commit:\n git add ${written.join(" ")} && git commit -m "Update vigiles"`);
|
|
3757
|
+
}
|
|
3758
|
+
/**
|
|
3759
|
+
* Link the shipped skills for each harness that links them — the safe, local
|
|
3760
|
+
* half of `installPlugins`, without the global install or config wiring.
|
|
3761
|
+
* Returns the links created or rewritten.
|
|
3762
|
+
*/
|
|
3763
|
+
function linkSkillsOnly(harnesses) {
|
|
3764
|
+
return (0, setup_plan_js_1.planPluginInstall)(harnesses, { hasClaude: false }).flatMap((plan) => {
|
|
3765
|
+
const home = plan.linkSkills ? harnessSkillsHome(plan.harness) : null;
|
|
3766
|
+
if (home === null)
|
|
3767
|
+
return [];
|
|
3768
|
+
const outcome = linkVigilesSkills(home, process.cwd());
|
|
3769
|
+
console.log("");
|
|
3770
|
+
(0, skill_links_js_1.formatSkillLinks)(outcome).forEach((l) => {
|
|
3771
|
+
console.log(l);
|
|
3772
|
+
});
|
|
3773
|
+
return changedLinks(outcome);
|
|
3774
|
+
});
|
|
3775
|
+
}
|
|
3776
|
+
/** Add vigiles to `devDependencies` only when nothing declares it. */
|
|
3777
|
+
function addMissingVigilesDevDep() {
|
|
3778
|
+
const pkgPath = (0, node_path_1.resolve)(process.cwd(), PACKAGE_JSON);
|
|
3779
|
+
if (!(0, node_fs_1.existsSync)(pkgPath))
|
|
3780
|
+
return [];
|
|
3781
|
+
const pkg = readPackageJson(pkgPath);
|
|
3782
|
+
if (pkg === null || pkg.name === "vigiles")
|
|
3783
|
+
return [];
|
|
3784
|
+
const spec = vigilesDepSpec();
|
|
3785
|
+
const devDependencies = (0, setup_plan_js_1.missingVigilesDevDep)(pkg, spec);
|
|
3786
|
+
if (devDependencies === null)
|
|
3787
|
+
return [];
|
|
3788
|
+
(0, node_fs_1.writeFileSync)(pkgPath, JSON.stringify({ ...pkg, devDependencies }, null, 2) + "\n");
|
|
3789
|
+
console.log(`\n✓ Added vigiles@${spec} to devDependencies — run \`npm install\` to fetch it`);
|
|
3790
|
+
return [PACKAGE_JSON];
|
|
3791
|
+
}
|
|
3792
|
+
/**
|
|
3793
|
+
* The fields of package.json the dependency decisions read. LOOSE on purpose:
|
|
3794
|
+
* every other key is carried through untouched, because the result is written
|
|
3795
|
+
* back and a re-run must not drop a field it never looked at.
|
|
3796
|
+
*/
|
|
3797
|
+
const packageDepsSchema = zod_1.z.looseObject({
|
|
3798
|
+
name: zod_1.z.string().optional(),
|
|
3799
|
+
dependencies: zod_1.z.record(zod_1.z.string(), zod_1.z.string()).optional(),
|
|
3800
|
+
devDependencies: zod_1.z.record(zod_1.z.string(), zod_1.z.string()).optional(),
|
|
3801
|
+
});
|
|
3802
|
+
/** package.json parsed for its dependency fields; null when unreadable. */
|
|
3803
|
+
function readPackageJson(path) {
|
|
3804
|
+
try {
|
|
3805
|
+
const parsed = packageDepsSchema.safeParse(JSON.parse((0, node_fs_1.readFileSync)(path, "utf-8")));
|
|
3806
|
+
return parsed.success ? parsed.data : null;
|
|
3807
|
+
}
|
|
3808
|
+
catch {
|
|
3809
|
+
return null;
|
|
3810
|
+
}
|
|
3811
|
+
}
|
|
3812
|
+
/**
|
|
3813
|
+
* What a full setup would add here, read from disk — the input to the
|
|
3814
|
+
* follow-up lines. It mirrors the full path's own conditions (the plan's
|
|
3815
|
+
* layers, the existence checks those steps make), so the list names what
|
|
3816
|
+
* `--full` would actually do rather than everything it could.
|
|
3817
|
+
*/
|
|
3818
|
+
function fullSetupGap(plan, detected, harnesses) {
|
|
3819
|
+
const cwd = process.cwd();
|
|
3820
|
+
const has = (rel) => (0, node_fs_1.existsSync)((0, node_path_1.resolve)(cwd, rel));
|
|
3821
|
+
const config = readProjectConfig((0, node_path_1.resolve)(cwd, VIGILESRC));
|
|
3822
|
+
const pillar1 = plan.lint && plan.scaffoldSpecs;
|
|
3823
|
+
const unspecced = pillar1
|
|
3824
|
+
? [
|
|
3825
|
+
...determineTargets(detected, undefined, [...harnesses]),
|
|
3826
|
+
...discoverAdoptableSurfaces(cwd),
|
|
3827
|
+
].filter((t, i, all) => all.indexOf(t) === i && !has(`${t}.spec.ts`))
|
|
3828
|
+
: [];
|
|
3829
|
+
const pkg = has(PACKAGE_JSON)
|
|
3830
|
+
? readPackageJson((0, node_path_1.resolve)(cwd, PACKAGE_JSON))
|
|
3831
|
+
: null;
|
|
3832
|
+
const declared = pkg?.devDependencies?.vigiles ?? pkg?.dependencies?.vigiles ?? null;
|
|
3833
|
+
const spec = vigilesDepSpec();
|
|
3834
|
+
return {
|
|
3835
|
+
workflow: plan.gha && !has(".github/workflows/vigiles.yml"),
|
|
3836
|
+
config: configGap(config, plan.lint),
|
|
3837
|
+
harnessTest: plan.test && !has("vigiles.harness.mjs"),
|
|
3838
|
+
unspecced,
|
|
3839
|
+
generated: pillar1 && !(has(GENERATED_TYPES) && has(GENERATED_SCHEMA)),
|
|
3840
|
+
installs: plan.plugin ? fullInstallLines(harnesses) : [],
|
|
3841
|
+
devDep: declared !== null && declared !== spec && pkg?.name !== "vigiles"
|
|
3842
|
+
? { from: declared, to: spec }
|
|
3843
|
+
: null,
|
|
3844
|
+
};
|
|
3845
|
+
}
|
|
3846
|
+
/** Where `.vigilesrc.json` stands against the preset a full setup writes. */
|
|
3847
|
+
function configGap(config, lint) {
|
|
3848
|
+
if (config === null)
|
|
3849
|
+
return "missing";
|
|
3850
|
+
return config.extends === undefined && lint ? "no-preset" : "has-preset";
|
|
3851
|
+
}
|
|
3852
|
+
/** `.vigilesrc.json` as a plain object, or null when absent or unreadable. */
|
|
3853
|
+
function readProjectConfig(path) {
|
|
3854
|
+
if (!(0, node_fs_1.existsSync)(path))
|
|
3855
|
+
return null;
|
|
3856
|
+
try {
|
|
3857
|
+
const raw = JSON.parse((0, node_fs_1.readFileSync)(path, "utf-8"));
|
|
3858
|
+
return typeof raw === "object" && raw !== null && !Array.isArray(raw)
|
|
3859
|
+
? { ...raw }
|
|
3860
|
+
: null;
|
|
3861
|
+
}
|
|
3862
|
+
catch {
|
|
3863
|
+
return null;
|
|
3864
|
+
}
|
|
3865
|
+
}
|
|
3866
|
+
/** The per-machine installs and config wiring the full plugin step would run. */
|
|
3867
|
+
function fullInstallLines(harnesses) {
|
|
3868
|
+
return (0, setup_plan_js_1.planPluginInstall)(harnesses, { hasClaude: true }).flatMap((plan) => [
|
|
3869
|
+
...(plan.globalInstallCarriesHooks && plan.commands.length > 0
|
|
3870
|
+
? [
|
|
3871
|
+
`install the ${plan.harness} plugin for this machine (${plan.commands.join(" && ")}) and declare it in the project settings`,
|
|
3872
|
+
]
|
|
3873
|
+
: []),
|
|
3874
|
+
...(plan.vendors
|
|
3875
|
+
? [`wire vigiles's nudge hooks into the ${plan.harness} config`]
|
|
3876
|
+
: []),
|
|
3877
|
+
]);
|
|
3878
|
+
}
|
|
3710
3879
|
/** Canonical, de-duplicated harness names — the keys `harnesses` gets. */
|
|
3711
3880
|
function harnessConfigKeys(harnesses) {
|
|
3712
3881
|
return [...new Set(harnesses.map(adapter_registry_js_1.normalizeHarnessName))];
|
|
@@ -5446,6 +5615,10 @@ function capabilitiesOfReport(report, dialect) {
|
|
|
5446
5615
|
const COMMAND_HELP = {
|
|
5447
5616
|
init: {
|
|
5448
5617
|
usage: " vigiles init [flags] Set up this repo — specs, plugin, and CI.",
|
|
5618
|
+
detail: [
|
|
5619
|
+
" Already set up? A re-run only adds what is missing (skill links, the devDependency);",
|
|
5620
|
+
" --full run the whole setup again",
|
|
5621
|
+
],
|
|
5449
5622
|
},
|
|
5450
5623
|
compile: { usage: " vigiles compile [files...] Compile .spec.ts → .md" },
|
|
5451
5624
|
eject: {
|
|
@@ -69,20 +69,20 @@ export declare const vigilesConfigSchema: z.ZodObject<{
|
|
|
69
69
|
checkboxes: "checkboxes";
|
|
70
70
|
}>>>;
|
|
71
71
|
rules: z.ZodPrefault<z.ZodObject<{
|
|
72
|
-
"spec-refs": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
73
|
-
"orphan-docs": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
74
|
-
"duplicate-rules": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
75
|
-
"require-instructions-spec": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
76
|
-
"require-skill-spec": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
77
|
-
integrity: z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
78
|
-
coverage: z.ZodDefault<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
72
|
+
"spec-refs": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
73
|
+
"orphan-docs": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
74
|
+
"duplicate-rules": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
75
|
+
"require-instructions-spec": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
76
|
+
"require-skill-spec": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
77
|
+
integrity: z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
78
|
+
coverage: z.ZodDefault<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>, z.ZodTuple<[z.ZodLiteral<"warn">, z.ZodObject<{
|
|
79
79
|
linterRules: z.ZodOptional<z.ZodNumber>;
|
|
80
80
|
scripts: z.ZodOptional<z.ZodNumber>;
|
|
81
81
|
}, z.core.$strict>], null>, z.ZodTuple<[z.ZodLiteral<"error">, z.ZodObject<{
|
|
82
82
|
linterRules: z.ZodOptional<z.ZodNumber>;
|
|
83
83
|
scripts: z.ZodOptional<z.ZodNumber>;
|
|
84
84
|
}, z.core.$strict>], null>]>>;
|
|
85
|
-
"untested-skill": z.ZodDefault<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
85
|
+
"untested-skill": z.ZodDefault<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>, z.ZodTuple<[z.ZodLiteral<"warn">, z.ZodObject<{
|
|
86
86
|
include: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
87
87
|
exclude: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
88
88
|
testExtension: z.ZodOptional<z.ZodString>;
|
|
@@ -91,7 +91,7 @@ export declare const vigilesConfigSchema: z.ZodObject<{
|
|
|
91
91
|
exclude: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
92
92
|
testExtension: z.ZodOptional<z.ZodString>;
|
|
93
93
|
}, z.core.$strict>], null>]>>;
|
|
94
|
-
"untested-subagent": z.ZodDefault<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
94
|
+
"untested-subagent": z.ZodDefault<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>, z.ZodTuple<[z.ZodLiteral<"warn">, z.ZodObject<{
|
|
95
95
|
include: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
96
96
|
exclude: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
97
97
|
testExtension: z.ZodOptional<z.ZodString>;
|
|
@@ -100,7 +100,7 @@ export declare const vigilesConfigSchema: z.ZodObject<{
|
|
|
100
100
|
exclude: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
101
101
|
testExtension: z.ZodOptional<z.ZodString>;
|
|
102
102
|
}, z.core.$strict>], null>]>>;
|
|
103
|
-
"untested-hook": z.ZodDefault<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
103
|
+
"untested-hook": z.ZodDefault<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>, z.ZodTuple<[z.ZodLiteral<"warn">, z.ZodObject<{
|
|
104
104
|
include: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
105
105
|
exclude: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
106
106
|
testExtension: z.ZodOptional<z.ZodString>;
|
|
@@ -109,7 +109,7 @@ export declare const vigilesConfigSchema: z.ZodObject<{
|
|
|
109
109
|
exclude: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
110
110
|
testExtension: z.ZodOptional<z.ZodString>;
|
|
111
111
|
}, z.core.$strict>], null>]>>;
|
|
112
|
-
"untested-output-style": z.ZodDefault<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
112
|
+
"untested-output-style": z.ZodDefault<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>, z.ZodTuple<[z.ZodLiteral<"warn">, z.ZodObject<{
|
|
113
113
|
include: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
114
114
|
exclude: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
115
115
|
testExtension: z.ZodOptional<z.ZodString>;
|
|
@@ -118,29 +118,29 @@ export declare const vigilesConfigSchema: z.ZodObject<{
|
|
|
118
118
|
exclude: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
119
119
|
testExtension: z.ZodOptional<z.ZodString>;
|
|
120
120
|
}, z.core.$strict>], null>]>>;
|
|
121
|
-
"unmarked-refs": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
122
|
-
"subagent-tool-contract": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
123
|
-
"hook-events": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
124
|
-
"subagent-frontmatter": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
125
|
-
"mcp-config": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
126
|
-
"skill-frontmatter": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
127
|
-
"mcp-tool-resolves": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
128
|
-
"hook-script-exists": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
129
|
-
"prefer-compiled-hooks": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
130
|
-
"disallowed-tools-contract": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
131
|
-
"description-overlap": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
132
|
-
"skill-description-budget": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
133
|
-
"frontmatter-valid": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
134
|
-
"mcp-hook-target-resolves": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
135
|
-
"lethal-trifecta": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
136
|
-
"skill-resource-resolves": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
137
|
-
"skill-missing-fence": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
138
|
-
"plugin-dir-layout": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
139
|
-
"delegation-trifecta": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
140
|
-
"hook-block-ineffective": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
141
|
-
"hook-matcher": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
142
|
-
"doc-refs": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
143
|
-
"instruction-weight": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "
|
|
121
|
+
"unmarked-refs": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
122
|
+
"subagent-tool-contract": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
123
|
+
"hook-events": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
124
|
+
"subagent-frontmatter": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
125
|
+
"mcp-config": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
126
|
+
"skill-frontmatter": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
127
|
+
"mcp-tool-resolves": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
128
|
+
"hook-script-exists": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
129
|
+
"prefer-compiled-hooks": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
130
|
+
"disallowed-tools-contract": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
131
|
+
"description-overlap": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
132
|
+
"skill-description-budget": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
133
|
+
"frontmatter-valid": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
134
|
+
"mcp-hook-target-resolves": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
135
|
+
"lethal-trifecta": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
136
|
+
"skill-resource-resolves": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
137
|
+
"skill-missing-fence": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
138
|
+
"plugin-dir-layout": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
139
|
+
"delegation-trifecta": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
140
|
+
"hook-block-ineffective": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
141
|
+
"hook-matcher": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
142
|
+
"doc-refs": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
143
|
+
"instruction-weight": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
144
144
|
}, z.core.$strict>>;
|
|
145
145
|
files: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
146
146
|
maxRules: z.ZodOptional<z.ZodNumber>;
|
|
@@ -170,8 +170,27 @@ export declare const vigilesConfigSchema: z.ZodObject<{
|
|
|
170
170
|
apiVersion: z.ZodOptional<z.ZodNumber>;
|
|
171
171
|
}, z.core.$strict>>;
|
|
172
172
|
nudge: z.ZodOptional<z.ZodLiteral<"dismissed">>;
|
|
173
|
+
extends: z.ZodOptional<z.ZodEnum<{
|
|
174
|
+
"vigiles:recommended": "vigiles:recommended";
|
|
175
|
+
}>>;
|
|
173
176
|
$schema: z.ZodOptional<z.ZodString>;
|
|
174
177
|
}, z.core.$strict>;
|
|
178
|
+
/**
|
|
179
|
+
* Parse a raw `.vigilesrc.json` value — THE one entry point every reader uses.
|
|
180
|
+
*
|
|
181
|
+
* 🔴 THE PRESET IS MERGED INTO THE RAW INPUT, BEFORE THE SCHEMA, for one reason:
|
|
182
|
+
* after parsing, every rule carries a value (the schema fills each default), so
|
|
183
|
+
* "the user wrote `hook-events: warn`" and "nobody wrote it" are the same
|
|
184
|
+
* output, and an explicit downgrade could not win over the preset. Before
|
|
185
|
+
* parsing, the user's own `rules` keys are exactly what they wrote. So the
|
|
186
|
+
* preset's severities go UNDER them, and the schema then normalizes and
|
|
187
|
+
* validates the result as if the user had typed both.
|
|
188
|
+
*
|
|
189
|
+
* Only a recognized preset with an object (or absent) `rules` is expanded;
|
|
190
|
+
* anything else is passed through untouched for the schema to refuse with its
|
|
191
|
+
* own message, so a typo in `extends` is reported, never silently ignored.
|
|
192
|
+
*/
|
|
193
|
+
export declare function parseVigilesConfig(raw: unknown): Readonly<ReturnType<typeof vigilesConfigSchema.safeParse>>;
|
|
175
194
|
/**
|
|
176
195
|
* A `.vigilesrc.json` that cannot be honoured as written.
|
|
177
196
|
*
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.REPLACED_KEYS = exports.VigilesConfigError = exports.vigilesConfigSchema = exports.RULE_NAMES = void 0;
|
|
4
|
+
exports.parseVigilesConfig = parseVigilesConfig;
|
|
4
5
|
exports.replacedKeyMessage = replacedKeyMessage;
|
|
5
6
|
exports.formatConfigIssues = formatConfigIssues;
|
|
6
7
|
/**
|
|
@@ -48,6 +49,7 @@ exports.formatConfigIssues = formatConfigIssues;
|
|
|
48
49
|
*/
|
|
49
50
|
const zod_1 = require("zod");
|
|
50
51
|
const edit_distance_js_1 = require("./edit-distance.js");
|
|
52
|
+
const presets_js_1 = require("./presets.js");
|
|
51
53
|
// ---------------------------------------------------------------------------
|
|
52
54
|
// Primitives
|
|
53
55
|
// ---------------------------------------------------------------------------
|
|
@@ -232,6 +234,14 @@ exports.vigilesConfigSchema = zod_1.z
|
|
|
232
234
|
audit: zod_1.z.object({ measure: zod_1.z.boolean().optional() }).strict().optional(),
|
|
233
235
|
eval: zod_1.z.object({ apiVersion: zod_1.z.number().optional() }).strict().optional(),
|
|
234
236
|
nudge: zod_1.z.literal("dismissed").optional(),
|
|
237
|
+
/**
|
|
238
|
+
* A named preset whose rule severities apply UNDER `rules` — ESLint's
|
|
239
|
+
* `extends`. `"vigiles:recommended"` gates the structural group (see
|
|
240
|
+
* `./presets.ts`); an explicit `rules` entry overrides it. Applied by
|
|
241
|
+
* {@link parseVigilesConfig}, which is why this key is only VALIDATED here.
|
|
242
|
+
* Placed after the keys people misspell most: the "Known:" list is capped.
|
|
243
|
+
*/
|
|
244
|
+
extends: zod_1.z.enum(presets_js_1.PRESET_NAMES).optional(),
|
|
235
245
|
/**
|
|
236
246
|
* The editor's pointer at the published JSON Schema. Accepted, never read.
|
|
237
247
|
*
|
|
@@ -262,6 +272,38 @@ exports.vigilesConfigSchema = zod_1.z
|
|
|
262
272
|
$schema: zod_1.z.string().optional(),
|
|
263
273
|
})
|
|
264
274
|
.strict();
|
|
275
|
+
/**
|
|
276
|
+
* Parse a raw `.vigilesrc.json` value — THE one entry point every reader uses.
|
|
277
|
+
*
|
|
278
|
+
* 🔴 THE PRESET IS MERGED INTO THE RAW INPUT, BEFORE THE SCHEMA, for one reason:
|
|
279
|
+
* after parsing, every rule carries a value (the schema fills each default), so
|
|
280
|
+
* "the user wrote `hook-events: warn`" and "nobody wrote it" are the same
|
|
281
|
+
* output, and an explicit downgrade could not win over the preset. Before
|
|
282
|
+
* parsing, the user's own `rules` keys are exactly what they wrote. So the
|
|
283
|
+
* preset's severities go UNDER them, and the schema then normalizes and
|
|
284
|
+
* validates the result as if the user had typed both.
|
|
285
|
+
*
|
|
286
|
+
* Only a recognized preset with an object (or absent) `rules` is expanded;
|
|
287
|
+
* anything else is passed through untouched for the schema to refuse with its
|
|
288
|
+
* own message, so a typo in `extends` is reported, never silently ignored.
|
|
289
|
+
*/
|
|
290
|
+
function parseVigilesConfig(raw) {
|
|
291
|
+
return exports.vigilesConfigSchema.safeParse(withPresetRules(raw));
|
|
292
|
+
}
|
|
293
|
+
/** `raw` with its `extends` preset's rules placed under its own `rules`. */
|
|
294
|
+
function withPresetRules(raw) {
|
|
295
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw))
|
|
296
|
+
return raw;
|
|
297
|
+
const preset = "extends" in raw ? raw.extends : undefined;
|
|
298
|
+
const rules = "rules" in raw ? raw.rules : undefined;
|
|
299
|
+
if (!(0, presets_js_1.isPresetName)(preset))
|
|
300
|
+
return raw;
|
|
301
|
+
if (rules === undefined)
|
|
302
|
+
return { ...raw, rules: { ...(0, presets_js_1.presetRules)(preset) } };
|
|
303
|
+
if (typeof rules !== "object" || rules === null || Array.isArray(rules))
|
|
304
|
+
return raw;
|
|
305
|
+
return { ...raw, rules: { ...(0, presets_js_1.presetRules)(preset), ...rules } };
|
|
306
|
+
}
|
|
265
307
|
/**
|
|
266
308
|
* A `.vigilesrc.json` that cannot be honoured as written.
|
|
267
309
|
*
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Named rule PRESETS a `.vigilesrc.json` can `extends` — the ESLint
|
|
3
|
+
* `recommended` model, stored as data.
|
|
4
|
+
*
|
|
5
|
+
* 🔴 WHY A PRESET READ AT LOAD TIME, NOT RULE LINES WRITTEN AT SETUP TIME. Every
|
|
6
|
+
* rule's built-in default stays `warn` (`config-schema.ts`); the structural rules
|
|
7
|
+
* gate only because `init` turns them up. It used to do that by WRITING nine
|
|
8
|
+
* `"<rule>": "error"` lines into the new repo's config — a snapshot of the group
|
|
9
|
+
* on the day `init` ran. A repo adopted before a rule joined the group never got
|
|
10
|
+
* it from an upgrade, and re-running `init` to fetch it rewrote far more than
|
|
11
|
+
* the rule (#338). `"extends": "vigiles:recommended"` is resolved by the loader
|
|
12
|
+
* on every run, so the repo follows the group as the installed vigiles ships it,
|
|
13
|
+
* and an explicit `rules` entry still overrides it.
|
|
14
|
+
*
|
|
15
|
+
* ⚠️ ADDING A RULE HERE IS A BREAKING CHANGE (a `!` commit, a semver major): it
|
|
16
|
+
* can turn a consumer's CI red with no edit on their side. Removing one is not.
|
|
17
|
+
* ESLint treats `eslint:recommended` the same way.
|
|
18
|
+
*
|
|
19
|
+
* Harness-agnostic data: rule names only, no adapter fact.
|
|
20
|
+
*/
|
|
21
|
+
import type { RulesConfig } from "./types.js";
|
|
22
|
+
/**
|
|
23
|
+
* The rules `vigiles:recommended` raises to `error` — the FP-safe structural
|
|
24
|
+
* group: each one fires only on a genuine defect (a never-available or typo'd
|
|
25
|
+
* tool, a subagent missing `name`/`description`, a typo'd hook event, a dead hook
|
|
26
|
+
* script, a broken MCP reference, two skills that collide in the selector), so a
|
|
27
|
+
* well-formed harness stays green.
|
|
28
|
+
*
|
|
29
|
+
* Deliberately EXCLUDES the workflow rules (`require-instructions-spec`,
|
|
30
|
+
* `untested-*`): a clean repo fails those until the work is done, so they stay
|
|
31
|
+
* an explicit opt-in (`init --strict`).
|
|
32
|
+
*/
|
|
33
|
+
export declare const RECOMMENDED_RULES: readonly ["subagent-tool-contract", "subagent-frontmatter", "hook-events", "hook-script-exists", "mcp-config", "mcp-tool-resolves", "mcp-hook-target-resolves", "disallowed-tools-contract", "description-overlap"];
|
|
34
|
+
/** The preset names `extends` accepts. One today; the tuple is the enum. */
|
|
35
|
+
export declare const PRESET_NAMES: readonly ["vigiles:recommended"];
|
|
36
|
+
/** A preset name `extends` accepts. */
|
|
37
|
+
export type PresetName = (typeof PRESET_NAMES)[number];
|
|
38
|
+
/** The preset `init` writes. */
|
|
39
|
+
export declare const RECOMMENDED_PRESET: PresetName;
|
|
40
|
+
/** Whether a raw value names a preset. */
|
|
41
|
+
export declare function isPresetName(value: unknown): value is PresetName;
|
|
42
|
+
/** The rule severities a preset sets, in the config's raw spelling. */
|
|
43
|
+
export declare function presetRules(name: PresetName): Readonly<Partial<Record<keyof RulesConfig, "error">>>;
|
|
44
|
+
//# sourceMappingURL=presets.d.ts.map
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RECOMMENDED_PRESET = exports.PRESET_NAMES = exports.RECOMMENDED_RULES = void 0;
|
|
4
|
+
exports.isPresetName = isPresetName;
|
|
5
|
+
exports.presetRules = presetRules;
|
|
6
|
+
/**
|
|
7
|
+
* The rules `vigiles:recommended` raises to `error` — the FP-safe structural
|
|
8
|
+
* group: each one fires only on a genuine defect (a never-available or typo'd
|
|
9
|
+
* tool, a subagent missing `name`/`description`, a typo'd hook event, a dead hook
|
|
10
|
+
* script, a broken MCP reference, two skills that collide in the selector), so a
|
|
11
|
+
* well-formed harness stays green.
|
|
12
|
+
*
|
|
13
|
+
* Deliberately EXCLUDES the workflow rules (`require-instructions-spec`,
|
|
14
|
+
* `untested-*`): a clean repo fails those until the work is done, so they stay
|
|
15
|
+
* an explicit opt-in (`init --strict`).
|
|
16
|
+
*/
|
|
17
|
+
exports.RECOMMENDED_RULES = [
|
|
18
|
+
"subagent-tool-contract",
|
|
19
|
+
"subagent-frontmatter",
|
|
20
|
+
"hook-events",
|
|
21
|
+
"hook-script-exists",
|
|
22
|
+
"mcp-config",
|
|
23
|
+
"mcp-tool-resolves",
|
|
24
|
+
"mcp-hook-target-resolves",
|
|
25
|
+
"disallowed-tools-contract",
|
|
26
|
+
"description-overlap",
|
|
27
|
+
];
|
|
28
|
+
/** The preset names `extends` accepts. One today; the tuple is the enum. */
|
|
29
|
+
exports.PRESET_NAMES = ["vigiles:recommended"];
|
|
30
|
+
/** The preset `init` writes. */
|
|
31
|
+
exports.RECOMMENDED_PRESET = "vigiles:recommended";
|
|
32
|
+
/** What each preset sets, as the config would spell it. */
|
|
33
|
+
const PRESETS = {
|
|
34
|
+
"vigiles:recommended": Object.fromEntries(exports.RECOMMENDED_RULES.map((r) => [r, "error"])),
|
|
35
|
+
};
|
|
36
|
+
/** Whether a raw value names a preset. */
|
|
37
|
+
function isPresetName(value) {
|
|
38
|
+
return exports.PRESET_NAMES.some((n) => n === value);
|
|
39
|
+
}
|
|
40
|
+
/** The rule severities a preset sets, in the config's raw spelling. */
|
|
41
|
+
function presetRules(name) {
|
|
42
|
+
return PRESETS[name];
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=presets.js.map
|
package/dist/core/validate.js
CHANGED
|
@@ -147,7 +147,7 @@ function loadConfig(searchFrom, { onInvalid = "throw" } = {}) {
|
|
|
147
147
|
}
|
|
148
148
|
}
|
|
149
149
|
if (problems.length === 0) {
|
|
150
|
-
const parsed = config_schema_js_1.
|
|
150
|
+
const parsed = (0, config_schema_js_1.parseVigilesConfig)(raw);
|
|
151
151
|
if (parsed.success)
|
|
152
152
|
return parsed.data;
|
|
153
153
|
problems.push(...(0, config_schema_js_1.formatConfigIssues)(parsed.error.issues));
|
package/dist/setup-plan.d.ts
CHANGED
|
@@ -77,6 +77,11 @@ export interface ParsedSetupArgs {
|
|
|
77
77
|
* DISCOVERY row of `cohesive-feature-delivery`.
|
|
78
78
|
*/
|
|
79
79
|
ciOnly: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* `--full` — run the whole setup even on a repo that already uses vigiles.
|
|
82
|
+
* Without it, a re-run there is the minimal one (see {@link rerunScope}).
|
|
83
|
+
*/
|
|
84
|
+
full: boolean;
|
|
80
85
|
}
|
|
81
86
|
/** Parse `init` args into the choices the user pinned. The two pillars are
|
|
82
87
|
* selected with `--lint` / `--test`. */
|
|
@@ -87,29 +92,6 @@ export declare function parseSetupArgs(args: readonly string[]): ParsedSetupArgs
|
|
|
87
92
|
* raw files WITHOUT scaffolding a spec (gate-first-adoption). Non-interactive
|
|
88
93
|
* behaviour is unchanged: bare `init` (lint on) scaffolds as before. */
|
|
89
94
|
export declare function defaultPlan(strict?: boolean): SetupPlan;
|
|
90
|
-
/**
|
|
91
|
-
* Pure config-merge for what `vigiles init` writes to `.vigilesrc.json`: record
|
|
92
|
-
* the `harness` if absent, add strict rule severities if `--strict`, NEVER
|
|
93
|
-
* clobber an existing key. Returns the merged config, or `null` when nothing
|
|
94
|
-
* changed (so the IO layer skips the write). The IO (read/parse/write + the
|
|
95
|
-
* malformed-file guard) stays in cli.ts.
|
|
96
|
-
*/
|
|
97
|
-
/**
|
|
98
|
-
* The structural rules `init` gates BY DEFAULT (severity `error`, so a broken
|
|
99
|
-
* surface fails `vigiles lint`). Every one is HIGH-PRECISION / FP-safe — it fires
|
|
100
|
-
* only on a genuine defect (a never-available/typo'd tool, a subagent missing
|
|
101
|
-
* `name`/`description`, a typo'd hook event, a dead hook script, a broken MCP
|
|
102
|
-
* ref, two skills that collide in the selector) — so a well-formed plugin stays
|
|
103
|
-
* green and catching real breakage out of the box never cries wolf.
|
|
104
|
-
*
|
|
105
|
-
* Deliberately EXCLUDES `require-instructions-spec` and the workflow-forcing rules:
|
|
106
|
-
* those make a CLEAN repo fail (you simply haven't written the spec/test yet), so
|
|
107
|
-
* they stay opt-in under `--strict` (progressive adoption — see
|
|
108
|
-
* `STRICT_EXTRA_RULES`).
|
|
109
|
-
*
|
|
110
|
-
* This is the **`structural`** rule group (see research/install-enforcement-dx.md).
|
|
111
|
-
*/
|
|
112
|
-
export declare const STRUCTURAL_RULES: readonly ["subagent-tool-contract", "subagent-frontmatter", "hook-events", "hook-script-exists", "mcp-config", "mcp-tool-resolves", "mcp-hook-target-resolves", "disallowed-tools-contract", "description-overlap"];
|
|
113
95
|
/**
|
|
114
96
|
* The **`workflow`** group — the WORKFLOW-FORCING / opinionated tier `--strict`
|
|
115
97
|
* gates, which a clean repo can still fail because you haven't done the work yet:
|
|
@@ -135,7 +117,24 @@ export declare const WORKFLOW_RULES: readonly ["require-instructions-spec", "unt
|
|
|
135
117
|
* (research/install-enforcement-dx.md).
|
|
136
118
|
*/
|
|
137
119
|
export declare const NUDGE_RULES: readonly ["skill-description-budget", "frontmatter-valid", "skill-frontmatter", "prefer-compiled-hooks", "unmarked-refs", "lethal-trifecta", "skill-resource-resolves", "skill-missing-fence", "plugin-dir-layout", "delegation-trifecta", "hook-block-ineffective", "hook-matcher", "doc-refs"];
|
|
138
|
-
|
|
120
|
+
/**
|
|
121
|
+
* Pure config-merge for what `vigiles init` writes to `.vigilesrc.json`: record
|
|
122
|
+
* the harnesses if absent, gate the structural rules by EXTENDING the
|
|
123
|
+
* `vigiles:recommended` preset (never by writing each rule), add the workflow
|
|
124
|
+
* rules on `--strict`, and NEVER clobber an existing key or severity. Returns
|
|
125
|
+
* the merged config, or `null` when nothing changed (so the IO layer skips the
|
|
126
|
+
* write). The IO (read/parse/write + the malformed-file guard) stays in cli.ts.
|
|
127
|
+
*
|
|
128
|
+
* 🔴 THE PRESET, NOT NINE LINES (#338). Written lines are a snapshot of the
|
|
129
|
+
* structural group on the day `init` ran, so a repo adopted earlier never got a
|
|
130
|
+
* rule added to the group later; the preset is resolved by the loader on every
|
|
131
|
+
* run (`src/core/presets.ts`).
|
|
132
|
+
*
|
|
133
|
+
* `--report-only` is the exception and stays EXPLICIT: it promises that nothing
|
|
134
|
+
* fails CI, and extending a preset that later gains a rule at `error` would
|
|
135
|
+
* break that promise on an upgrade. So it writes the same rules at `warn`.
|
|
136
|
+
*/
|
|
137
|
+
export declare function mergeProjectConfig(existing: Readonly<Record<string, unknown>>, opts: Readonly<{
|
|
139
138
|
/** Canonical harness names this repo targets, in the order to declare them. */
|
|
140
139
|
harnesses: readonly string[];
|
|
141
140
|
strict: boolean;
|
|
@@ -144,7 +143,7 @@ export declare function mergeProjectConfig(existing: Record<string, unknown>, op
|
|
|
144
143
|
* concern, so a test-only setup (`init --test` / `--no-lint`) records the
|
|
145
144
|
* harness but writes NO lint rules. */
|
|
146
145
|
lint?: boolean;
|
|
147
|
-
}): Record<string, unknown> | null;
|
|
146
|
+
}>): Record<string, unknown> | null;
|
|
148
147
|
/**
|
|
149
148
|
* Whether to drop into interactive prompts: a human at a TTY who passed neither
|
|
150
149
|
* `--yes` nor an explicit `--target`, and who hasn't already pinned every choice
|
|
@@ -292,6 +291,75 @@ export declare function codexPluginHooks(): CodexPluginHook[];
|
|
|
292
291
|
* (and every other config key) untouched. Returns a new object.
|
|
293
292
|
*/
|
|
294
293
|
export declare function applyCodexPluginHooks(existing: Record<string, unknown>): Record<string, unknown>;
|
|
294
|
+
/**
|
|
295
|
+
* Whether this repo already uses vigiles, decided from what is ON DISK.
|
|
296
|
+
*
|
|
297
|
+
* 🔴 THE SIGNAL IS `.vigilesrc.json` OR A SPEC NEXT TO AN INSTRUCTION FILE, and
|
|
298
|
+
* deliberately NOT a `vigiles` devDependency: the documented first step on a new
|
|
299
|
+
* repo can be `npm i -D vigiles` followed by `npx vigiles init`, and that run
|
|
300
|
+
* must still be the full setup. Every `init` writes `.vigilesrc.json` (it records
|
|
301
|
+
* the harnesses even on a test-only run), and a hand-written one means the owner
|
|
302
|
+
* has already configured vigiles. A spec beside `CLAUDE.md`/`AGENTS.md` covers a
|
|
303
|
+
* repo adopted before the config file existed.
|
|
304
|
+
*/
|
|
305
|
+
export type AdoptionState = {
|
|
306
|
+
readonly kind: "fresh";
|
|
307
|
+
} | {
|
|
308
|
+
readonly kind: "adopted";
|
|
309
|
+
readonly evidence: string;
|
|
310
|
+
};
|
|
311
|
+
/** {@link AdoptionState} from the two disk facts that decide it. */
|
|
312
|
+
export declare function adoptionState(facts: Readonly<{
|
|
313
|
+
hasConfig: boolean;
|
|
314
|
+
specs: readonly string[];
|
|
315
|
+
}>): AdoptionState;
|
|
316
|
+
/**
|
|
317
|
+
* Which setup a run performs: the full one, or the minimal re-run (#338).
|
|
318
|
+
*
|
|
319
|
+
* MINIMAL only when the repo is adopted AND the run named nothing that asks for
|
|
320
|
+
* more. A flag that selects or widens the setup (`--full`, `--strict`,
|
|
321
|
+
* `--ci-only`, `--report-only`, `--force`, `--target=`, a positive `--lint` /
|
|
322
|
+
* `--test`) is an explicit request and keeps today's behaviour; the narrowing
|
|
323
|
+
* flags (`--no-*`, `--harness=`, `--yes`) do not, because they can only make a
|
|
324
|
+
* run do less.
|
|
325
|
+
*/
|
|
326
|
+
export declare function rerunScope(parsed: Readonly<ParsedSetupArgs>, state: AdoptionState): "full" | "minimal";
|
|
327
|
+
/**
|
|
328
|
+
* The `devDependencies` a minimal re-run writes, or null to leave package.json
|
|
329
|
+
* alone. It ADDS vigiles when no dependency field declares it and never edits an
|
|
330
|
+
* existing declaration: rewriting `^33.3.0` to `^33` loosens a pin the owner
|
|
331
|
+
* chose, and moving it between fields is a decision, not a missing piece.
|
|
332
|
+
*/
|
|
333
|
+
export declare function missingVigilesDevDep(pkg: Readonly<{
|
|
334
|
+
dependencies?: Readonly<Record<string, string>>;
|
|
335
|
+
devDependencies?: Readonly<Record<string, string>>;
|
|
336
|
+
}>, spec: string): Readonly<Record<string, string>> | null;
|
|
337
|
+
/** What a full setup would add on an adopted repo — the facts that decide it. */
|
|
338
|
+
export interface FullSetupGap {
|
|
339
|
+
/** `.github/workflows/vigiles.yml` is absent (and CI wiring is not opted out). */
|
|
340
|
+
readonly workflow: boolean;
|
|
341
|
+
/** `.vigilesrc.json`: absent, present without the preset, or already extending it. */
|
|
342
|
+
readonly config: "missing" | "no-preset" | "has-preset";
|
|
343
|
+
/** `vigiles.harness.mjs` is absent (and the test layer is not opted out). */
|
|
344
|
+
readonly harnessTest: boolean;
|
|
345
|
+
/** Instruction files and surfaces a full setup would adopt into a spec. */
|
|
346
|
+
readonly unspecced: readonly string[];
|
|
347
|
+
/** `.vigiles/generated.d.ts` / `.vigiles/schema.json` would be created. */
|
|
348
|
+
readonly generated: boolean;
|
|
349
|
+
/** The global plugin install / hook wiring a full setup would run, one line each. */
|
|
350
|
+
readonly installs: readonly string[];
|
|
351
|
+
/** The devDependency rewrite a full setup would make, if any. */
|
|
352
|
+
readonly devDep: Readonly<{
|
|
353
|
+
from: string;
|
|
354
|
+
to: string;
|
|
355
|
+
}> | null;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* The lines a minimal re-run prints about what it did NOT do: each thing a full
|
|
359
|
+
* setup would add here, then the flag that does it. Empty when nothing is
|
|
360
|
+
* missing, so a fully set-up repo is not told to run anything.
|
|
361
|
+
*/
|
|
362
|
+
export declare function fullSetupFollowUps(gap: FullSetupGap): readonly string[];
|
|
295
363
|
/**
|
|
296
364
|
* Resolve the final plan: defaults, then flags, then interactive answers (each
|
|
297
365
|
* layer overrides the previous only where it has an opinion). `--target` pins a
|
package/dist/setup-plan.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* on a prompt. See docs/agent-setup.md.
|
|
11
11
|
*/
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
exports.SHIPPED_SKILLS = exports.NUDGE_RULES = exports.WORKFLOW_RULES =
|
|
13
|
+
exports.SHIPPED_SKILLS = exports.NUDGE_RULES = exports.WORKFLOW_RULES = void 0;
|
|
14
14
|
exports.parseSetupArgs = parseSetupArgs;
|
|
15
15
|
exports.defaultPlan = defaultPlan;
|
|
16
16
|
exports.mergeProjectConfig = mergeProjectConfig;
|
|
@@ -21,7 +21,12 @@ exports.planPluginInstall = planPluginInstall;
|
|
|
21
21
|
exports.shouldRunGlobalInstall = shouldRunGlobalInstall;
|
|
22
22
|
exports.codexPluginHooks = codexPluginHooks;
|
|
23
23
|
exports.applyCodexPluginHooks = applyCodexPluginHooks;
|
|
24
|
+
exports.adoptionState = adoptionState;
|
|
25
|
+
exports.rerunScope = rerunScope;
|
|
26
|
+
exports.missingVigilesDevDep = missingVigilesDevDep;
|
|
27
|
+
exports.fullSetupFollowUps = fullSetupFollowUps;
|
|
24
28
|
exports.resolvePlan = resolvePlan;
|
|
29
|
+
const presets_js_1 = require("./core/presets.js");
|
|
25
30
|
function flagValue(args, prefix) {
|
|
26
31
|
return args.find((a) => a.startsWith(prefix))?.slice(prefix.length);
|
|
27
32
|
}
|
|
@@ -48,6 +53,7 @@ function parseSetupArgs(args) {
|
|
|
48
53
|
gha: args.includes("--no-gha") ? false : undefined,
|
|
49
54
|
plugin: args.includes("--no-plugin") ? false : undefined,
|
|
50
55
|
ciOnly: args.includes("--ci-only"),
|
|
56
|
+
full: args.includes("--full"),
|
|
51
57
|
};
|
|
52
58
|
}
|
|
53
59
|
/** The non-interactive defaults: both pillars, CI, and the plugin. `scaffoldSpecs`
|
|
@@ -66,39 +72,6 @@ function defaultPlan(strict = false) {
|
|
|
66
72
|
force: false,
|
|
67
73
|
};
|
|
68
74
|
}
|
|
69
|
-
/**
|
|
70
|
-
* Pure config-merge for what `vigiles init` writes to `.vigilesrc.json`: record
|
|
71
|
-
* the `harness` if absent, add strict rule severities if `--strict`, NEVER
|
|
72
|
-
* clobber an existing key. Returns the merged config, or `null` when nothing
|
|
73
|
-
* changed (so the IO layer skips the write). The IO (read/parse/write + the
|
|
74
|
-
* malformed-file guard) stays in cli.ts.
|
|
75
|
-
*/
|
|
76
|
-
/**
|
|
77
|
-
* The structural rules `init` gates BY DEFAULT (severity `error`, so a broken
|
|
78
|
-
* surface fails `vigiles lint`). Every one is HIGH-PRECISION / FP-safe — it fires
|
|
79
|
-
* only on a genuine defect (a never-available/typo'd tool, a subagent missing
|
|
80
|
-
* `name`/`description`, a typo'd hook event, a dead hook script, a broken MCP
|
|
81
|
-
* ref, two skills that collide in the selector) — so a well-formed plugin stays
|
|
82
|
-
* green and catching real breakage out of the box never cries wolf.
|
|
83
|
-
*
|
|
84
|
-
* Deliberately EXCLUDES `require-instructions-spec` and the workflow-forcing rules:
|
|
85
|
-
* those make a CLEAN repo fail (you simply haven't written the spec/test yet), so
|
|
86
|
-
* they stay opt-in under `--strict` (progressive adoption — see
|
|
87
|
-
* `STRICT_EXTRA_RULES`).
|
|
88
|
-
*
|
|
89
|
-
* This is the **`structural`** rule group (see research/install-enforcement-dx.md).
|
|
90
|
-
*/
|
|
91
|
-
exports.STRUCTURAL_RULES = [
|
|
92
|
-
"subagent-tool-contract",
|
|
93
|
-
"subagent-frontmatter",
|
|
94
|
-
"hook-events",
|
|
95
|
-
"hook-script-exists",
|
|
96
|
-
"mcp-config",
|
|
97
|
-
"mcp-tool-resolves",
|
|
98
|
-
"mcp-hook-target-resolves",
|
|
99
|
-
"disallowed-tools-contract",
|
|
100
|
-
"description-overlap",
|
|
101
|
-
];
|
|
102
75
|
/**
|
|
103
76
|
* The **`workflow`** group — the WORKFLOW-FORCING / opinionated tier `--strict`
|
|
104
77
|
* gates, which a clean repo can still fail because you haven't done the work yet:
|
|
@@ -147,41 +120,53 @@ exports.NUDGE_RULES = [
|
|
|
147
120
|
// than config. See docs/rules/doc-refs.md.
|
|
148
121
|
"doc-refs",
|
|
149
122
|
];
|
|
123
|
+
/**
|
|
124
|
+
* Pure config-merge for what `vigiles init` writes to `.vigilesrc.json`: record
|
|
125
|
+
* the harnesses if absent, gate the structural rules by EXTENDING the
|
|
126
|
+
* `vigiles:recommended` preset (never by writing each rule), add the workflow
|
|
127
|
+
* rules on `--strict`, and NEVER clobber an existing key or severity. Returns
|
|
128
|
+
* the merged config, or `null` when nothing changed (so the IO layer skips the
|
|
129
|
+
* write). The IO (read/parse/write + the malformed-file guard) stays in cli.ts.
|
|
130
|
+
*
|
|
131
|
+
* 🔴 THE PRESET, NOT NINE LINES (#338). Written lines are a snapshot of the
|
|
132
|
+
* structural group on the day `init` ran, so a repo adopted earlier never got a
|
|
133
|
+
* rule added to the group later; the preset is resolved by the loader on every
|
|
134
|
+
* run (`src/core/presets.ts`).
|
|
135
|
+
*
|
|
136
|
+
* `--report-only` is the exception and stays EXPLICIT: it promises that nothing
|
|
137
|
+
* fails CI, and extending a preset that later gains a rule at `error` would
|
|
138
|
+
* break that promise on an upgrade. So it writes the same rules at `warn`.
|
|
139
|
+
*/
|
|
150
140
|
function mergeProjectConfig(existing, opts) {
|
|
151
|
-
const config = { ...existing };
|
|
152
|
-
let changed = false;
|
|
153
141
|
// The NESTED key (#240). `init` writes the declaration with no roots — a repo
|
|
154
142
|
// whose surfaces sit where its harness reads them needs none, and a root is a
|
|
155
|
-
// fact only the owner knows.
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
config.rules = rules;
|
|
183
|
-
}
|
|
184
|
-
return changed ? config : null;
|
|
143
|
+
// fact only the owner knows.
|
|
144
|
+
const harnesses = existing.harnesses === undefined
|
|
145
|
+
? { harnesses: Object.fromEntries(opts.harnesses.map((h) => [h, {}])) }
|
|
146
|
+
: {};
|
|
147
|
+
const gate = opts.lint === false ? {} : lintGate(existing, opts);
|
|
148
|
+
const added = { ...harnesses, ...gate };
|
|
149
|
+
return Object.keys(added).length === 0 ? null : { ...existing, ...added };
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* The lint-layer keys `init` adds: `extends` and/or the `rules` it fills.
|
|
153
|
+
* Only the keys that CHANGE are returned, so an already-satisfied config
|
|
154
|
+
* yields `{}` and is not rewritten.
|
|
155
|
+
*/
|
|
156
|
+
function lintGate(existing, opts) {
|
|
157
|
+
const workflow = opts.strict ? exports.WORKFLOW_RULES : [];
|
|
158
|
+
const explicit = opts.reportOnly
|
|
159
|
+
? [...presets_js_1.RECOMMENDED_RULES, ...workflow]
|
|
160
|
+
: workflow;
|
|
161
|
+
const severity = opts.reportOnly ? "warn" : "error";
|
|
162
|
+
const before = (existing.rules ?? {});
|
|
163
|
+
// Never clobber a severity the user already set — only fill the undefined ones.
|
|
164
|
+
const filled = Object.fromEntries(explicit.filter((r) => before[r] === undefined).map((r) => [r, severity]));
|
|
165
|
+
const rules = Object.keys(filled).length === 0 ? {} : { rules: { ...before, ...filled } };
|
|
166
|
+
const preset = opts.reportOnly || existing.extends !== undefined
|
|
167
|
+
? {}
|
|
168
|
+
: { extends: presets_js_1.RECOMMENDED_PRESET };
|
|
169
|
+
return { ...preset, ...rules };
|
|
185
170
|
}
|
|
186
171
|
/**
|
|
187
172
|
* Whether to drop into interactive prompts: a human at a TTY who passed neither
|
|
@@ -288,7 +273,7 @@ function gateOnlyInvitation(plan) {
|
|
|
288
273
|
const gateOnly = !plan.plugin && !plan.scaffoldSpecs;
|
|
289
274
|
if (!gateOnly)
|
|
290
275
|
return null;
|
|
291
|
-
return "→ Want your agent to maintain this + measure whether your skills fire? Run `npx vigiles init` and choose 'full' (installs the skills). Optional — the gate above already works.";
|
|
276
|
+
return "→ Want your agent to maintain this + measure whether your skills fire? Run `npx vigiles init --full` and choose 'full' (installs the skills). Optional — the gate above already works.";
|
|
292
277
|
}
|
|
293
278
|
/**
|
|
294
279
|
* The SHIPPED consumer skills (the `skills/` dir, published via `plugin.json`) —
|
|
@@ -470,6 +455,87 @@ function applyCodexPluginHooks(existing) {
|
|
|
470
455
|
}
|
|
471
456
|
return { ...existing, hooks };
|
|
472
457
|
}
|
|
458
|
+
/** {@link AdoptionState} from the two disk facts that decide it. */
|
|
459
|
+
function adoptionState(facts) {
|
|
460
|
+
if (facts.hasConfig)
|
|
461
|
+
return { kind: "adopted", evidence: ".vigilesrc.json" };
|
|
462
|
+
const [spec] = facts.specs;
|
|
463
|
+
return spec === undefined
|
|
464
|
+
? { kind: "fresh" }
|
|
465
|
+
: { kind: "adopted", evidence: spec };
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* Which setup a run performs: the full one, or the minimal re-run (#338).
|
|
469
|
+
*
|
|
470
|
+
* MINIMAL only when the repo is adopted AND the run named nothing that asks for
|
|
471
|
+
* more. A flag that selects or widens the setup (`--full`, `--strict`,
|
|
472
|
+
* `--ci-only`, `--report-only`, `--force`, `--target=`, a positive `--lint` /
|
|
473
|
+
* `--test`) is an explicit request and keeps today's behaviour; the narrowing
|
|
474
|
+
* flags (`--no-*`, `--harness=`, `--yes`) do not, because they can only make a
|
|
475
|
+
* run do less.
|
|
476
|
+
*/
|
|
477
|
+
function rerunScope(parsed, state) {
|
|
478
|
+
if (state.kind === "fresh")
|
|
479
|
+
return "full";
|
|
480
|
+
const asksForMore = parsed.full ||
|
|
481
|
+
parsed.strict ||
|
|
482
|
+
parsed.ciOnly ||
|
|
483
|
+
parsed.reportOnly ||
|
|
484
|
+
parsed.force ||
|
|
485
|
+
parsed.target !== undefined ||
|
|
486
|
+
parsed.lint === true ||
|
|
487
|
+
parsed.test === true;
|
|
488
|
+
return asksForMore ? "full" : "minimal";
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* The `devDependencies` a minimal re-run writes, or null to leave package.json
|
|
492
|
+
* alone. It ADDS vigiles when no dependency field declares it and never edits an
|
|
493
|
+
* existing declaration: rewriting `^33.3.0` to `^33` loosens a pin the owner
|
|
494
|
+
* chose, and moving it between fields is a decision, not a missing piece.
|
|
495
|
+
*/
|
|
496
|
+
function missingVigilesDevDep(pkg, spec) {
|
|
497
|
+
const declared = pkg.dependencies?.vigiles !== undefined ||
|
|
498
|
+
pkg.devDependencies?.vigiles !== undefined;
|
|
499
|
+
return declared ? null : { ...pkg.devDependencies, vigiles: spec };
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* The lines a minimal re-run prints about what it did NOT do: each thing a full
|
|
503
|
+
* setup would add here, then the flag that does it. Empty when nothing is
|
|
504
|
+
* missing, so a fully set-up repo is not told to run anything.
|
|
505
|
+
*/
|
|
506
|
+
function fullSetupFollowUps(gap) {
|
|
507
|
+
const configLine = {
|
|
508
|
+
missing: `write .vigilesrc.json with your harnesses and "extends": "${presets_js_1.RECOMMENDED_PRESET}" (structural rules fail CI)`,
|
|
509
|
+
"no-preset": `add "extends": "${presets_js_1.RECOMMENDED_PRESET}" to .vigilesrc.json (structural rules fail CI)`,
|
|
510
|
+
"has-preset": null,
|
|
511
|
+
};
|
|
512
|
+
const items = [
|
|
513
|
+
gap.workflow
|
|
514
|
+
? "create .github/workflows/vigiles.yml (a CI workflow — new CI minutes)"
|
|
515
|
+
: null,
|
|
516
|
+
configLine[gap.config],
|
|
517
|
+
gap.harnessTest
|
|
518
|
+
? "scaffold vigiles.harness.mjs (a starter harness test)"
|
|
519
|
+
: null,
|
|
520
|
+
gap.unspecced.length > 0
|
|
521
|
+
? `write specs for ${String(gap.unspecced.length)} hand-written file(s): ${gap.unspecced.join(", ")}`
|
|
522
|
+
: null,
|
|
523
|
+
gap.generated
|
|
524
|
+
? "generate .vigiles/generated.d.ts and .vigiles/schema.json"
|
|
525
|
+
: null,
|
|
526
|
+
...gap.installs,
|
|
527
|
+
gap.devDep === null
|
|
528
|
+
? null
|
|
529
|
+
: `set the vigiles devDependency to ${gap.devDep.to} (yours: ${gap.devDep.from})`,
|
|
530
|
+
].filter((l) => l !== null);
|
|
531
|
+
return items.length === 0
|
|
532
|
+
? []
|
|
533
|
+
: [
|
|
534
|
+
"A full setup would also:",
|
|
535
|
+
...items.map((l) => ` - ${l}`),
|
|
536
|
+
"Run `npx vigiles init --full` for that (flags such as --no-gha still apply).",
|
|
537
|
+
];
|
|
538
|
+
}
|
|
473
539
|
/**
|
|
474
540
|
* Resolve the final plan: defaults, then flags, then interactive answers (each
|
|
475
541
|
* layer overrides the previous only where it has an opinion). `--target` pins a
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vigiles",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "34.0.0",
|
|
4
4
|
"description": "Audit, test and measure the harness your AI agent runs on — grade your CLAUDE.md / AGENTS.md, skills, subagents and hooks, run them against a scripted model, and measure whether they actually fire.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude-code",
|