@vyuhlabs/dxkit 2.22.0 → 2.23.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.
Files changed (69) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/dist/analyzers/correctness/run.d.ts +79 -0
  3. package/dist/analyzers/correctness/run.d.ts.map +1 -0
  4. package/dist/analyzers/correctness/run.js +173 -0
  5. package/dist/analyzers/correctness/run.js.map +1 -0
  6. package/dist/analyzers/correctness/surface-run.d.ts +73 -0
  7. package/dist/analyzers/correctness/surface-run.d.ts.map +1 -0
  8. package/dist/analyzers/correctness/surface-run.js +142 -0
  9. package/dist/analyzers/correctness/surface-run.js.map +1 -0
  10. package/dist/analyzers/correctness/surface.d.ts +69 -0
  11. package/dist/analyzers/correctness/surface.d.ts.map +1 -0
  12. package/dist/analyzers/correctness/surface.js +281 -0
  13. package/dist/analyzers/correctness/surface.js.map +1 -0
  14. package/dist/cli.d.ts.map +1 -1
  15. package/dist/cli.js +77 -4
  16. package/dist/cli.js.map +1 -1
  17. package/dist/languages/capabilities/correctness.d.ts +54 -0
  18. package/dist/languages/capabilities/correctness.d.ts.map +1 -0
  19. package/dist/languages/capabilities/correctness.js +20 -0
  20. package/dist/languages/capabilities/correctness.js.map +1 -0
  21. package/dist/languages/csharp.d.ts.map +1 -1
  22. package/dist/languages/csharp.js +84 -0
  23. package/dist/languages/csharp.js.map +1 -1
  24. package/dist/languages/go.d.ts.map +1 -1
  25. package/dist/languages/go.js +51 -0
  26. package/dist/languages/go.js.map +1 -1
  27. package/dist/languages/index.d.ts +11 -0
  28. package/dist/languages/index.d.ts.map +1 -1
  29. package/dist/languages/index.js +12 -0
  30. package/dist/languages/index.js.map +1 -1
  31. package/dist/languages/java.d.ts.map +1 -1
  32. package/dist/languages/java.js +12 -0
  33. package/dist/languages/java.js.map +1 -1
  34. package/dist/languages/jvm-build.d.ts +54 -0
  35. package/dist/languages/jvm-build.d.ts.map +1 -0
  36. package/dist/languages/jvm-build.js +245 -0
  37. package/dist/languages/jvm-build.js.map +1 -0
  38. package/dist/languages/kotlin.d.ts.map +1 -1
  39. package/dist/languages/kotlin.js +13 -0
  40. package/dist/languages/kotlin.js.map +1 -1
  41. package/dist/languages/python.d.ts.map +1 -1
  42. package/dist/languages/python.js +78 -0
  43. package/dist/languages/python.js.map +1 -1
  44. package/dist/languages/ruby.d.ts.map +1 -1
  45. package/dist/languages/ruby.js +64 -0
  46. package/dist/languages/ruby.js.map +1 -1
  47. package/dist/languages/rust.d.ts.map +1 -1
  48. package/dist/languages/rust.js +110 -0
  49. package/dist/languages/rust.js.map +1 -1
  50. package/dist/languages/types.d.ts +20 -0
  51. package/dist/languages/types.d.ts.map +1 -1
  52. package/dist/languages/typescript.d.ts.map +1 -1
  53. package/dist/languages/typescript.js +109 -0
  54. package/dist/languages/typescript.js.map +1 -1
  55. package/dist/loop/floor-gate.d.ts +54 -0
  56. package/dist/loop/floor-gate.d.ts.map +1 -0
  57. package/dist/loop/floor-gate.js +157 -0
  58. package/dist/loop/floor-gate.js.map +1 -0
  59. package/dist/loop/floor-state.d.ts +66 -0
  60. package/dist/loop/floor-state.d.ts.map +1 -0
  61. package/dist/loop/floor-state.js +138 -0
  62. package/dist/loop/floor-state.js.map +1 -0
  63. package/dist/loop/stop-gate.d.ts +2 -1
  64. package/dist/loop/stop-gate.d.ts.map +1 -1
  65. package/dist/loop/stop-gate.js +44 -6
  66. package/dist/loop/stop-gate.js.map +1 -1
  67. package/package.json +1 -1
  68. package/templates/.githooks/pre-push +10 -0
  69. package/templates/.github/workflows/dxkit-guardrails.yml +17 -0
@@ -0,0 +1,281 @@
1
+ "use strict";
2
+ /**
3
+ * The correctness-floor SURFACE resolver — decides, per surface, whether the
4
+ * floor runs by default. This is the canonical resolver for the correctness
5
+ * capability (mirror of `resolveBaselineMode` for baseline modes, Rule 11): one
6
+ * function, one precedence order, so no two call sites drift on the default.
7
+ *
8
+ * Three surfaces run the floor, with different postures:
9
+ * - `loop-stop` — an autonomous loop's Stop-gate. ALWAYS default-on: an agent
10
+ * must never declare "done" on code that does not compile or whose tests
11
+ * fail. (An explicit flag/policy can still turn it off, but the default is
12
+ * on regardless of what CI the repo has.)
13
+ * - `pre-push` / `ci` — ADAPTIVE. If the repo already runs its tests in its own
14
+ * CI, dxkit's floor is redundant there, so it defaults to OPT-IN. If no
15
+ * test-running CI is detected, the floor defaults ON so pushes/PRs are still
16
+ * checked. When we cannot tell (a CI exists but its test step is opaque), we
17
+ * FAIL TOWARD ON — a redundant floor run is cheap; a missed regression is not.
18
+ *
19
+ * Precedence (highest first), mirroring the loop-preset + baseline-mode
20
+ * resolvers:
21
+ * 1. explicit `flag` argument (a `--correctness` / `--no-correctness` CLI flag)
22
+ * 2. `DXKIT_FLOOR_<SURFACE>` env var (benchmark / CI override)
23
+ * 3. `.dxkit/policy.json` → `correctness.surfaces.<surface>`
24
+ * 4. the surface's default (always-on for loop-stop; adaptive for pre-push/ci)
25
+ */
26
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
27
+ if (k2 === undefined) k2 = k;
28
+ var desc = Object.getOwnPropertyDescriptor(m, k);
29
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
30
+ desc = { enumerable: true, get: function() { return m[k]; } };
31
+ }
32
+ Object.defineProperty(o, k2, desc);
33
+ }) : (function(o, m, k, k2) {
34
+ if (k2 === undefined) k2 = k;
35
+ o[k2] = m[k];
36
+ }));
37
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
38
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
39
+ }) : function(o, v) {
40
+ o["default"] = v;
41
+ });
42
+ var __importStar = (this && this.__importStar) || (function () {
43
+ var ownKeys = function(o) {
44
+ ownKeys = Object.getOwnPropertyNames || function (o) {
45
+ var ar = [];
46
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
47
+ return ar;
48
+ };
49
+ return ownKeys(o);
50
+ };
51
+ return function (mod) {
52
+ if (mod && mod.__esModule) return mod;
53
+ var result = {};
54
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
55
+ __setModuleDefault(result, mod);
56
+ return result;
57
+ };
58
+ })();
59
+ Object.defineProperty(exports, "__esModule", { value: true });
60
+ exports.detectTestCi = detectTestCi;
61
+ exports.readSurfacePolicy = readSurfacePolicy;
62
+ exports.resolveCorrectnessSurface = resolveCorrectnessSurface;
63
+ const fs = __importStar(require("fs"));
64
+ const path = __importStar(require("path"));
65
+ const policy_1 = require("../../baseline/policy");
66
+ // ─── Test-CI detection ──────────────────────────────────────────────────────
67
+ /** CI config files we can read as text and scan for a test invocation. Ordered
68
+ * by ubiquity; GitHub Actions workflows are handled separately (a directory). */
69
+ const FLAT_CI_FILES = [
70
+ '.gitlab-ci.yml',
71
+ '.gitlab-ci.yaml',
72
+ 'Jenkinsfile',
73
+ '.circleci/config.yml',
74
+ 'azure-pipelines.yml',
75
+ 'azure-pipelines.yaml',
76
+ '.travis.yml',
77
+ 'bitbucket-pipelines.yml',
78
+ ];
79
+ /** Substrings that mark a real test invocation, unioned across ecosystems. Kept
80
+ * deliberately specific (a bare "test" would match too much) so a match is a
81
+ * confident "this CI runs tests" signal. */
82
+ const TEST_COMMAND_PATTERNS = [
83
+ /\bnpm (run )?test\b/,
84
+ /\byarn (run )?test\b/,
85
+ /\bpnpm (run )?test\b/,
86
+ /\bnpx (vitest|jest|mocha|ava|playwright)\b/,
87
+ /\b(vitest|jest|mocha|ava)\b/,
88
+ /\bpytest\b/,
89
+ /\bpython -m (pytest|unittest)\b/,
90
+ /\b(tox|nox)\b/,
91
+ /\bgo test\b/,
92
+ /\bcargo (test|nextest)\b/,
93
+ /\bmvn (.*\s)?(test|verify)\b/,
94
+ /\b(\.\/)?gradlew? (.*\s)?(test|check)\b/,
95
+ /\bdotnet test\b/,
96
+ /\b(bundle exec )?rspec\b/,
97
+ /\brake (.*\s)?test\b/,
98
+ /\bmake (.*\s)?test\b/,
99
+ /\bjust (.*\s)?test\b/,
100
+ ];
101
+ /** Is a workflow file one dxkit itself installed? Its own guardrail/floor CI is
102
+ * the surface being resolved, not a pre-existing test-CI, so it must not count
103
+ * as the repo "already testing in CI". */
104
+ function isDxkitAuthoredWorkflow(name) {
105
+ return name.startsWith('dxkit-');
106
+ }
107
+ function textRunsTests(text) {
108
+ return TEST_COMMAND_PATTERNS.some((re) => re.test(text));
109
+ }
110
+ function matchedTestCommand(text) {
111
+ for (const re of TEST_COMMAND_PATTERNS) {
112
+ const m = re.exec(text);
113
+ if (m)
114
+ return m[0];
115
+ }
116
+ return undefined;
117
+ }
118
+ /**
119
+ * Detect whether the repo runs its tests in its OWN CI. Reads GitHub Actions
120
+ * workflows (excluding dxkit-authored ones) plus the common flat CI configs,
121
+ * scanning for a test invocation:
122
+ * - a matching test command in any file → `has-test-ci`;
123
+ * - no CI config found at all → `no-test-ci` (dxkit's floor should default on);
124
+ * - CI config exists but no test command matched (opaque `make ci`, a called
125
+ * reusable workflow, etc.) → `uncertain` (fail toward on).
126
+ * Best-effort and never throws — an unreadable file is skipped.
127
+ */
128
+ function detectTestCi(cwd) {
129
+ let sawAnyCi = false;
130
+ // GitHub Actions workflows (a directory of yml/yaml files).
131
+ const wfDir = path.join(cwd, '.github', 'workflows');
132
+ let wfNames = [];
133
+ try {
134
+ wfNames = fs
135
+ .readdirSync(wfDir)
136
+ .filter((n) => (n.endsWith('.yml') || n.endsWith('.yaml')) && !isDxkitAuthoredWorkflow(n));
137
+ }
138
+ catch {
139
+ /* no workflows dir */
140
+ }
141
+ for (const name of wfNames) {
142
+ sawAnyCi = true;
143
+ let text;
144
+ try {
145
+ text = fs.readFileSync(path.join(wfDir, name), 'utf8');
146
+ }
147
+ catch {
148
+ continue;
149
+ }
150
+ if (textRunsTests(text)) {
151
+ return {
152
+ status: 'has-test-ci',
153
+ evidence: `.github/workflows/${name}: ${matchedTestCommand(text)}`,
154
+ };
155
+ }
156
+ }
157
+ // Flat CI config files.
158
+ for (const rel of FLAT_CI_FILES) {
159
+ let text;
160
+ try {
161
+ text = fs.readFileSync(path.join(cwd, rel), 'utf8');
162
+ }
163
+ catch {
164
+ continue;
165
+ }
166
+ sawAnyCi = true;
167
+ if (textRunsTests(text)) {
168
+ return { status: 'has-test-ci', evidence: `${rel}: ${matchedTestCommand(text)}` };
169
+ }
170
+ }
171
+ return sawAnyCi ? { status: 'uncertain' } : { status: 'no-test-ci' };
172
+ }
173
+ // ─── Policy + env reads ─────────────────────────────────────────────────────
174
+ /** Read `correctness.surfaces.<surface>` from `.dxkit/policy.json`. Best-effort:
175
+ * a missing / malformed file or absent block yields an empty map. */
176
+ function readSurfacePolicy(cwd) {
177
+ try {
178
+ const raw = fs.readFileSync(path.join(cwd, policy_1.DEFAULT_POLICY_FILENAME), 'utf8');
179
+ const parsed = JSON.parse(raw);
180
+ const surfaces = parsed.correctness?.surfaces;
181
+ if (!surfaces || typeof surfaces !== 'object')
182
+ return {};
183
+ const out = {};
184
+ for (const s of ['loop-stop', 'pre-push', 'ci']) {
185
+ if (typeof surfaces[s] === 'boolean')
186
+ out[s] = surfaces[s];
187
+ }
188
+ return out;
189
+ }
190
+ catch {
191
+ return {};
192
+ }
193
+ }
194
+ const ENV_VAR = {
195
+ 'loop-stop': 'DXKIT_FLOOR_LOOP',
196
+ 'pre-push': 'DXKIT_FLOOR_PREPUSH',
197
+ ci: 'DXKIT_FLOOR_CI',
198
+ };
199
+ /** Parse a truthy/falsy env override, or undefined when unset/unrecognized. */
200
+ function envOverride(surface) {
201
+ const raw = process.env[ENV_VAR[surface]];
202
+ if (raw === undefined)
203
+ return undefined;
204
+ const v = raw.trim().toLowerCase();
205
+ if (['1', 'true', 'on', 'yes'].includes(v))
206
+ return true;
207
+ if (['0', 'false', 'off', 'no'].includes(v))
208
+ return false;
209
+ return undefined;
210
+ }
211
+ /**
212
+ * Resolve whether the correctness floor is enabled on a surface. Pure aside from
213
+ * the default policy/env reads (both injectable); never throws.
214
+ */
215
+ function resolveCorrectnessSurface(opts) {
216
+ const { surface } = opts;
217
+ // 1. explicit CLI flag
218
+ if (opts.flag !== undefined) {
219
+ return {
220
+ surface,
221
+ enabled: opts.flag,
222
+ source: 'flag',
223
+ reason: `explicitly ${opts.flag ? 'enabled' : 'disabled'} via flag`,
224
+ };
225
+ }
226
+ // 2. env override
227
+ const env = envOverride(surface);
228
+ if (env !== undefined) {
229
+ return {
230
+ surface,
231
+ enabled: env,
232
+ source: 'env',
233
+ reason: `${env ? 'enabled' : 'disabled'} via ${ENV_VAR[surface]}`,
234
+ };
235
+ }
236
+ // 3. policy file
237
+ const policy = opts.policySurfaces ?? readSurfacePolicy(opts.cwd);
238
+ const pol = policy[surface];
239
+ if (pol !== undefined) {
240
+ return {
241
+ surface,
242
+ enabled: pol,
243
+ source: 'policy',
244
+ reason: `${pol ? 'enabled' : 'disabled'} via .dxkit/policy.json correctness.surfaces.${surface}`,
245
+ };
246
+ }
247
+ // 4. surface default
248
+ if (surface === 'loop-stop') {
249
+ return {
250
+ surface,
251
+ enabled: true,
252
+ source: 'always-on',
253
+ reason: 'loop Stop-gate runs the floor by default — an agent must not stop on broken code',
254
+ };
255
+ }
256
+ // pre-push / ci: adaptive on the repo's own test-CI
257
+ const det = (opts.detect ?? detectTestCi)(opts.cwd);
258
+ if (det.status === 'has-test-ci') {
259
+ return {
260
+ surface,
261
+ enabled: false,
262
+ source: 'adaptive-test-ci-detected',
263
+ reason: `opt-in — the repo already runs tests in CI (${det.evidence}); enable explicitly to also run dxkit's floor here`,
264
+ };
265
+ }
266
+ if (det.status === 'no-test-ci') {
267
+ return {
268
+ surface,
269
+ enabled: true,
270
+ source: 'adaptive-no-test-ci',
271
+ reason: 'no test-running CI detected — the floor runs by default so changes are still checked',
272
+ };
273
+ }
274
+ return {
275
+ surface,
276
+ enabled: true,
277
+ source: 'adaptive-uncertain',
278
+ reason: 'a CI exists but its test step is opaque — running the floor to be safe (fail toward on)',
279
+ };
280
+ }
281
+ //# sourceMappingURL=surface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surface.js","sourceRoot":"","sources":["../../../src/analyzers/correctness/surface.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AA4SA,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAo/DvD"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AA4SA,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAikEvD"}
package/dist/cli.js CHANGED
@@ -376,6 +376,9 @@ async function run(argv) {
376
376
  'added-by': { type: 'string' },
377
377
  mode: { type: 'string' },
378
378
  ref: { type: 'string' },
379
+ surface: { type: 'string' },
380
+ correctness: { type: 'boolean' },
381
+ 'no-correctness': { type: 'boolean' },
379
382
  'soon-days': { type: 'string' },
380
383
  'against-baseline': { type: 'boolean', default: false },
381
384
  'baseline-name': { type: 'string' },
@@ -1801,9 +1804,13 @@ async function run(argv) {
1801
1804
  `Expected one of: committed-full, committed-sanitized, ref-based.`);
1802
1805
  process.exit(1);
1803
1806
  }
1804
- if (!values.json)
1807
+ // Suppress the console header/info in --json AND --markdown: both are
1808
+ // machine-captured (piped to a file / a PR comment), so the ANSI-styled
1809
+ // console chrome would leak into the report.
1810
+ const quiet = !!values.json || !!values.markdown;
1811
+ if (!quiet)
1805
1812
  logger.header('vyuh-dxkit guardrail check');
1806
- if (!values.json)
1813
+ if (!quiet)
1807
1814
  logger.info(`Checking ${targetPath} against baseline...`);
1808
1815
  const startTime = Date.now();
1809
1816
  try {
@@ -1819,7 +1826,7 @@ async function run(argv) {
1819
1826
  cliMode: cliMode ?? undefined,
1820
1827
  cliRef: values.ref,
1821
1828
  });
1822
- if (!values.json)
1829
+ if (!quiet)
1823
1830
  logger.info(`Baseline ${result.mode.explanation}`);
1824
1831
  const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
1825
1832
  if (values.json) {
@@ -1840,6 +1847,54 @@ async function run(argv) {
1840
1847
  }
1841
1848
  break;
1842
1849
  }
1850
+ case 'floor': {
1851
+ const subCommand = positionals[1];
1852
+ if (subCommand !== 'check') {
1853
+ logger.fail(`Unknown floor subcommand: ${subCommand ?? '(missing)'}. ` +
1854
+ `Available: vyuh-dxkit floor check [path] [--surface pre-push|ci] [--base <ref>] ` +
1855
+ `[--correctness | --no-correctness] [--json]`);
1856
+ process.exit(1);
1857
+ }
1858
+ const targetPath = resolveRepoPath(positionals[2]);
1859
+ const surfaceRaw = values.surface ?? 'pre-push';
1860
+ if (surfaceRaw !== 'pre-push' && surfaceRaw !== 'ci') {
1861
+ logger.fail(`Unknown --surface value: ${surfaceRaw}. Expected one of: pre-push, ci.`);
1862
+ process.exit(1);
1863
+ }
1864
+ // --correctness / --no-correctness → the explicit enable/disable override.
1865
+ const flag = values.correctness ? true : values['no-correctness'] ? false : undefined;
1866
+ const { runFloorForSurface } = await Promise.resolve().then(() => __importStar(require('./analyzers/correctness/surface-run')));
1867
+ const outcome = runFloorForSurface({
1868
+ surface: surfaceRaw,
1869
+ cwd: targetPath,
1870
+ base: values.base,
1871
+ flag,
1872
+ });
1873
+ if (values.json) {
1874
+ await emitJson({
1875
+ surface: outcome.surface,
1876
+ enabled: outcome.enabled,
1877
+ ran: outcome.ran,
1878
+ blocks: outcome.blocks,
1879
+ reason: outcome.reason,
1880
+ checks: outcome.result?.checks ?? [],
1881
+ });
1882
+ }
1883
+ else {
1884
+ if (outcome.blocks) {
1885
+ logger.fail(outcome.summary);
1886
+ for (const c of outcome.result?.checks.filter((c) => c.status === 'fail') ?? []) {
1887
+ if (c.output)
1888
+ process.stdout.write(`\n[${c.pack} ${c.label}]\n${c.output}\n`);
1889
+ }
1890
+ }
1891
+ else {
1892
+ logger.success(outcome.summary);
1893
+ }
1894
+ }
1895
+ process.exit(outcome.blocks ? 1 : 0);
1896
+ break;
1897
+ }
1843
1898
  case 'setup-branch-protection': {
1844
1899
  const { runSetupBranchProtection } = await Promise.resolve().then(() => __importStar(require('./setup-branch-protection')));
1845
1900
  const requireReviewsRaw = values['require-reviews'];
@@ -2000,8 +2055,26 @@ async function run(argv) {
2000
2055
  await runLoopDoctor(cwd, { json: !!values.json });
2001
2056
  break;
2002
2057
  }
2058
+ if (sub === 'snapshot') {
2059
+ // Capture the correctness-floor entry snapshot — the already-broken set
2060
+ // on the current (pristine) tree — so later Stops block only on
2061
+ // NET-NEW failures. Run at loop activation, before the agent changes
2062
+ // anything, or the recorded set won't be genuinely pre-existing.
2063
+ const { captureFloorSnapshot } = await Promise.resolve().then(() => __importStar(require('./loop/floor-gate')));
2064
+ const { describeCorrectnessFloor } = await Promise.resolve().then(() => __importStar(require('./analyzers/correctness/run')));
2065
+ const result = captureFloorSnapshot(cwd);
2066
+ if (result === null) {
2067
+ logger.info('No active language pack provides a correctness floor — nothing to snapshot.');
2068
+ break;
2069
+ }
2070
+ const failing = result.checks.filter((c) => c.status === 'fail').length;
2071
+ logger.success(`Captured correctness-floor entry snapshot (${result.checks.length} check(s), ` +
2072
+ `${failing} already failing). ${describeCorrectnessFloor(result)}`);
2073
+ break;
2074
+ }
2003
2075
  logger.fail(`Unknown loop subcommand: ${sub ?? '(missing)'}. ` +
2004
- `Available: vyuh-dxkit loop ledger [show | summarize | clear], vyuh-dxkit loop doctor`);
2076
+ `Available: vyuh-dxkit loop ledger [show | summarize | clear], ` +
2077
+ `vyuh-dxkit loop doctor, vyuh-dxkit loop snapshot`);
2005
2078
  process.exit(1);
2006
2079
  break;
2007
2080
  }