@vyuhlabs/dxkit 2.5.1 → 2.6.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/CHANGELOG.md +318 -0
- package/README.md +150 -28
- package/dist/allowlist/categories.d.ts +120 -0
- package/dist/allowlist/categories.d.ts.map +1 -0
- package/dist/allowlist/categories.js +194 -0
- package/dist/allowlist/categories.js.map +1 -0
- package/dist/allowlist/cli.d.ts +95 -0
- package/dist/allowlist/cli.d.ts.map +1 -0
- package/dist/allowlist/cli.js +454 -0
- package/dist/allowlist/cli.js.map +1 -0
- package/dist/allowlist/diff.d.ts +67 -0
- package/dist/allowlist/diff.d.ts.map +1 -0
- package/dist/allowlist/diff.js +147 -0
- package/dist/allowlist/diff.js.map +1 -0
- package/dist/allowlist/file.d.ts +249 -0
- package/dist/allowlist/file.d.ts.map +1 -0
- package/dist/allowlist/file.js +497 -0
- package/dist/allowlist/file.js.map +1 -0
- package/dist/allowlist/gather.d.ts +61 -0
- package/dist/allowlist/gather.d.ts.map +1 -0
- package/dist/allowlist/gather.js +143 -0
- package/dist/allowlist/gather.js.map +1 -0
- package/dist/allowlist/hint.d.ts +80 -0
- package/dist/allowlist/hint.d.ts.map +1 -0
- package/dist/allowlist/hint.js +271 -0
- package/dist/allowlist/hint.js.map +1 -0
- package/dist/allowlist/inline.d.ts +149 -0
- package/dist/allowlist/inline.d.ts.map +1 -0
- package/dist/allowlist/inline.js +306 -0
- package/dist/allowlist/inline.js.map +1 -0
- package/dist/analyzers/tools/tool-registry.d.ts.map +1 -1
- package/dist/analyzers/tools/tool-registry.js +25 -8
- package/dist/analyzers/tools/tool-registry.js.map +1 -1
- package/dist/baseline/baseline-file.d.ts +7 -0
- package/dist/baseline/baseline-file.d.ts.map +1 -1
- package/dist/baseline/baseline-file.js +22 -1
- package/dist/baseline/baseline-file.js.map +1 -1
- package/dist/baseline/check-renderers.d.ts +13 -1
- package/dist/baseline/check-renderers.d.ts.map +1 -1
- package/dist/baseline/check-renderers.js +67 -1
- package/dist/baseline/check-renderers.js.map +1 -1
- package/dist/baseline/check.d.ts +33 -7
- package/dist/baseline/check.d.ts.map +1 -1
- package/dist/baseline/check.js +90 -64
- package/dist/baseline/check.js.map +1 -1
- package/dist/baseline/create.d.ts +35 -7
- package/dist/baseline/create.d.ts.map +1 -1
- package/dist/baseline/create.js +43 -5
- package/dist/baseline/create.js.map +1 -1
- package/dist/baseline/entry-to-located.d.ts +6 -1
- package/dist/baseline/entry-to-located.d.ts.map +1 -1
- package/dist/baseline/entry-to-located.js +20 -2
- package/dist/baseline/entry-to-located.js.map +1 -1
- package/dist/baseline/finding-identity.d.ts.map +1 -1
- package/dist/baseline/finding-identity.js +15 -13
- package/dist/baseline/finding-identity.js.map +1 -1
- package/dist/baseline/modes.d.ts +140 -0
- package/dist/baseline/modes.d.ts.map +1 -0
- package/dist/baseline/modes.js +179 -0
- package/dist/baseline/modes.js.map +1 -0
- package/dist/baseline/policy.d.ts +64 -0
- package/dist/baseline/policy.d.ts.map +1 -1
- package/dist/baseline/policy.js +102 -1
- package/dist/baseline/policy.js.map +1 -1
- package/dist/baseline/producers/health.d.ts +2 -2
- package/dist/baseline/producers/health.d.ts.map +1 -1
- package/dist/baseline/producers/health.js.map +1 -1
- package/dist/baseline/producers/index.d.ts +11 -5
- package/dist/baseline/producers/index.d.ts.map +1 -1
- package/dist/baseline/producers/index.js +12 -9
- package/dist/baseline/producers/index.js.map +1 -1
- package/dist/baseline/producers/quality.d.ts +3 -3
- package/dist/baseline/producers/quality.d.ts.map +1 -1
- package/dist/baseline/producers/quality.js.map +1 -1
- package/dist/baseline/producers/secret-hmac.d.ts +2 -2
- package/dist/baseline/producers/secret-hmac.d.ts.map +1 -1
- package/dist/baseline/producers/secret-hmac.js.map +1 -1
- package/dist/baseline/producers/security.d.ts +2 -2
- package/dist/baseline/producers/security.d.ts.map +1 -1
- package/dist/baseline/producers/security.js.map +1 -1
- package/dist/baseline/producers/stale-allow.d.ts +70 -0
- package/dist/baseline/producers/stale-allow.d.ts.map +1 -0
- package/dist/baseline/producers/stale-allow.js +111 -0
- package/dist/baseline/producers/stale-allow.js.map +1 -0
- package/dist/baseline/producers/tests.d.ts +2 -2
- package/dist/baseline/producers/tests.d.ts.map +1 -1
- package/dist/baseline/producers/tests.js.map +1 -1
- package/dist/baseline/ref-baseline.d.ts +114 -0
- package/dist/baseline/ref-baseline.d.ts.map +1 -0
- package/dist/baseline/ref-baseline.js +260 -0
- package/dist/baseline/ref-baseline.js.map +1 -0
- package/dist/baseline/sanitize.d.ts +80 -0
- package/dist/baseline/sanitize.d.ts.map +1 -0
- package/dist/baseline/sanitize.js +91 -0
- package/dist/baseline/sanitize.js.map +1 -0
- package/dist/baseline/show.d.ts.map +1 -1
- package/dist/baseline/show.js +9 -3
- package/dist/baseline/show.js.map +1 -1
- package/dist/baseline/types.d.ts +73 -26
- package/dist/baseline/types.d.ts.map +1 -1
- package/dist/baseline/types.js +7 -1
- package/dist/baseline/types.js.map +1 -1
- package/dist/baseline/visibility.d.ts +61 -0
- package/dist/baseline/visibility.d.ts.map +1 -0
- package/dist/baseline/visibility.js +121 -0
- package/dist/baseline/visibility.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +154 -13
- package/dist/cli.js.map +1 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +0 -10
- package/dist/constants.js.map +1 -1
- package/dist/detect.d.ts.map +1 -1
- package/dist/detect.js +0 -15
- package/dist/detect.js.map +1 -1
- package/dist/doctor.d.ts +78 -1
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +590 -101
- package/dist/doctor.js.map +1 -1
- package/dist/generator.d.ts.map +1 -1
- package/dist/generator.js +15 -0
- package/dist/generator.js.map +1 -1
- package/dist/issue-cli.d.ts +62 -0
- package/dist/issue-cli.d.ts.map +1 -0
- package/dist/issue-cli.js +252 -0
- package/dist/issue-cli.js.map +1 -0
- package/dist/languages/csharp.d.ts.map +1 -1
- package/dist/languages/csharp.js +2 -0
- package/dist/languages/csharp.js.map +1 -1
- package/dist/languages/go.d.ts.map +1 -1
- package/dist/languages/go.js +2 -0
- package/dist/languages/go.js.map +1 -1
- package/dist/languages/index.d.ts +25 -0
- package/dist/languages/index.d.ts.map +1 -1
- package/dist/languages/index.js +44 -0
- package/dist/languages/index.js.map +1 -1
- package/dist/languages/java.d.ts.map +1 -1
- package/dist/languages/java.js +2 -0
- package/dist/languages/java.js.map +1 -1
- package/dist/languages/kotlin.d.ts.map +1 -1
- package/dist/languages/kotlin.js +2 -0
- package/dist/languages/kotlin.js.map +1 -1
- package/dist/languages/python.d.ts.map +1 -1
- package/dist/languages/python.js +11 -1
- package/dist/languages/python.js.map +1 -1
- package/dist/languages/ruby.d.ts.map +1 -1
- package/dist/languages/ruby.js +2 -0
- package/dist/languages/ruby.js.map +1 -1
- package/dist/languages/rust.d.ts.map +1 -1
- package/dist/languages/rust.js +2 -0
- package/dist/languages/rust.js.map +1 -1
- package/dist/languages/types.d.ts +45 -0
- package/dist/languages/types.d.ts.map +1 -1
- package/dist/languages/typescript.d.ts.map +1 -1
- package/dist/languages/typescript.js +2 -0
- package/dist/languages/typescript.js.map +1 -1
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +0 -5
- package/dist/prompts.js.map +1 -1
- package/dist/setup-branch-protection.d.ts +34 -0
- package/dist/setup-branch-protection.d.ts.map +1 -0
- package/dist/setup-branch-protection.js +190 -0
- package/dist/setup-branch-protection.js.map +1 -0
- package/dist/setup-gh.d.ts +75 -0
- package/dist/setup-gh.d.ts.map +1 -0
- package/dist/setup-gh.js +213 -0
- package/dist/setup-gh.js.map +1 -0
- package/dist/setup-prebuild.d.ts +34 -0
- package/dist/setup-prebuild.d.ts.map +1 -0
- package/dist/setup-prebuild.js +181 -0
- package/dist/setup-prebuild.js.map +1 -0
- package/dist/ship-installers.d.ts.map +1 -1
- package/dist/ship-installers.js +19 -4
- package/dist/ship-installers.js.map +1 -1
- package/dist/types.d.ts +24 -6
- package/dist/types.d.ts.map +1 -1
- package/dist/update.d.ts +41 -0
- package/dist/update.d.ts.map +1 -1
- package/dist/update.js +154 -15
- package/dist/update.js.map +1 -1
- package/dist/upgrade.d.ts +88 -0
- package/dist/upgrade.d.ts.map +1 -0
- package/dist/upgrade.js +324 -0
- package/dist/upgrade.js.map +1 -0
- package/package.json +1 -1
- package/templates/.claude/skills/dxkit-action/SKILL.md +111 -17
- package/templates/.claude/skills/dxkit-config/SKILL.md +7 -7
- package/templates/.claude/skills/dxkit-fix/SKILL.md +165 -0
- package/templates/.claude/skills/dxkit-hooks/SKILL.md +8 -8
- package/templates/.claude/skills/dxkit-init/SKILL.md +3 -3
- package/templates/.claude/skills/dxkit-learn/SKILL.md +9 -9
- package/templates/.claude/skills/dxkit-onboard/SKILL.md +274 -0
- package/templates/.claude/skills/dxkit-reports/SKILL.md +18 -18
- package/templates/.claude/skills/dxkit-update/SKILL.md +164 -0
- package/templates/.devcontainer/devcontainer.json +6 -15
- package/templates/.devcontainer/post-create.sh +19 -4
- package/dist/baseline/producers/licenses.d.ts +0 -23
- package/dist/baseline/producers/licenses.d.ts.map +0 -1
- package/dist/baseline/producers/licenses.js +0 -46
- package/dist/baseline/producers/licenses.js.map +0 -1
|
@@ -0,0 +1,497 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* On-disk allowlist file — `.dxkit/allowlist.json` + optional sidecar
|
|
4
|
+
* `.dxkit/allowlist-reasons.local.json`.
|
|
5
|
+
*
|
|
6
|
+
* The allowlist file is the durable contract for per-finding
|
|
7
|
+
* suppressions: customer has reviewed this fingerprint, categorized
|
|
8
|
+
* the reason, and accepts that the guardrail should let the finding
|
|
9
|
+
* pass on future runs.
|
|
10
|
+
*
|
|
11
|
+
* Identity is the 16-char hex fingerprint from
|
|
12
|
+
* `src/analyzers/tools/fingerprint.ts` (CLAUDE.md Rule 9). An entry
|
|
13
|
+
* matches a finding when their fingerprint strings are byte-equal.
|
|
14
|
+
*
|
|
15
|
+
* # Two modes, one schema
|
|
16
|
+
*
|
|
17
|
+
* The mode is recorded in `.dxkit/policy.json` (out of scope for this
|
|
18
|
+
* module — consumers pass it in via `AllowlistMode`). Both modes use
|
|
19
|
+
* the same `AllowlistFile` shape on disk; sanitized mode just drops
|
|
20
|
+
* the human-readable fields and pushes them to a sidecar:
|
|
21
|
+
*
|
|
22
|
+
* `'full'` — every field present on the entry. Default for
|
|
23
|
+
* private repos. The committed file carries the full audit trail.
|
|
24
|
+
*
|
|
25
|
+
* `'sanitized'` — entries carry `fingerprint + kind + category +
|
|
26
|
+
* addedAt + expiresAt + acknowledgedSeverity` only. The
|
|
27
|
+
* `reason` + `addedBy` fields live in the gitignored sidecar
|
|
28
|
+
* `.dxkit/allowlist-reasons.local.json`, keyed by fingerprint.
|
|
29
|
+
* Default for public repos. Loaders merge the sidecar back when
|
|
30
|
+
* present; readers tolerate its absence (no reason field, but
|
|
31
|
+
* the suppression still applies because matching is by
|
|
32
|
+
* fingerprint).
|
|
33
|
+
*
|
|
34
|
+
* # Validation surface
|
|
35
|
+
*
|
|
36
|
+
* `validateAllowlistFile` enforces every Sprint-0-locked rule:
|
|
37
|
+
* - `reason` is required (full mode) / required in sidecar
|
|
38
|
+
* (sanitized mode)
|
|
39
|
+
* - `category` is one of the five canonical values
|
|
40
|
+
* - `category` is valid for the entry's `kind`
|
|
41
|
+
* - `requiresExpiry(category)` ⇒ `expiresAt` is present + parseable
|
|
42
|
+
* - `acknowledgedSeverity` is required when `category` is
|
|
43
|
+
* `accepted-risk` AND `severity` is `high`/`critical`
|
|
44
|
+
*/
|
|
45
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
46
|
+
if (k2 === undefined) k2 = k;
|
|
47
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
48
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
49
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
50
|
+
}
|
|
51
|
+
Object.defineProperty(o, k2, desc);
|
|
52
|
+
}) : (function(o, m, k, k2) {
|
|
53
|
+
if (k2 === undefined) k2 = k;
|
|
54
|
+
o[k2] = m[k];
|
|
55
|
+
}));
|
|
56
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
57
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
58
|
+
}) : function(o, v) {
|
|
59
|
+
o["default"] = v;
|
|
60
|
+
});
|
|
61
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
62
|
+
var ownKeys = function(o) {
|
|
63
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
64
|
+
var ar = [];
|
|
65
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
66
|
+
return ar;
|
|
67
|
+
};
|
|
68
|
+
return ownKeys(o);
|
|
69
|
+
};
|
|
70
|
+
return function (mod) {
|
|
71
|
+
if (mod && mod.__esModule) return mod;
|
|
72
|
+
var result = {};
|
|
73
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
74
|
+
__setModuleDefault(result, mod);
|
|
75
|
+
return result;
|
|
76
|
+
};
|
|
77
|
+
})();
|
|
78
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
79
|
+
exports.ALL_MODES = exports.ALLOWLIST_REASONS_FILENAME = exports.ALLOWLIST_FILENAME = exports.ALLOWLIST_DIR = exports.ALLOWLIST_REASONS_SCHEMA_VERSION = exports.ALLOWLIST_SCHEMA_VERSION = void 0;
|
|
80
|
+
exports.pathForAllowlist = pathForAllowlist;
|
|
81
|
+
exports.pathForAllowlistReasons = pathForAllowlistReasons;
|
|
82
|
+
exports.emptyAllowlistFile = emptyAllowlistFile;
|
|
83
|
+
exports.loadAllowlist = loadAllowlist;
|
|
84
|
+
exports.loadAllowlistReasons = loadAllowlistReasons;
|
|
85
|
+
exports.saveAllowlist = saveAllowlist;
|
|
86
|
+
exports.findEntry = findEntry;
|
|
87
|
+
exports.addEntry = addEntry;
|
|
88
|
+
exports.removeEntry = removeEntry;
|
|
89
|
+
exports.matchesFinding = matchesFinding;
|
|
90
|
+
exports.isEntryActive = isEntryActive;
|
|
91
|
+
exports.daysUntilExpiry = daysUntilExpiry;
|
|
92
|
+
exports.auditAllowlist = auditAllowlist;
|
|
93
|
+
exports.pruneExpired = pruneExpired;
|
|
94
|
+
exports.validateAllowlistFile = validateAllowlistFile;
|
|
95
|
+
exports.validateAllowlistEntry = validateAllowlistEntry;
|
|
96
|
+
const fs = __importStar(require("fs"));
|
|
97
|
+
const path = __importStar(require("path"));
|
|
98
|
+
const categories_1 = require("./categories");
|
|
99
|
+
exports.ALLOWLIST_SCHEMA_VERSION = 'dxkit-allowlist/v1';
|
|
100
|
+
exports.ALLOWLIST_REASONS_SCHEMA_VERSION = 'dxkit-allowlist-reasons/v1';
|
|
101
|
+
exports.ALLOWLIST_DIR = '.dxkit';
|
|
102
|
+
exports.ALLOWLIST_FILENAME = 'allowlist.json';
|
|
103
|
+
exports.ALLOWLIST_REASONS_FILENAME = 'allowlist-reasons.local.json';
|
|
104
|
+
/**
|
|
105
|
+
* Single source of truth for mode values. The `AllowlistMode` union
|
|
106
|
+
* is derived from this array via `(typeof ...)[number]`, so adding
|
|
107
|
+
* a new mode means appending one string here — the runtime checks
|
|
108
|
+
* below pick it up via `ALL_MODES.includes(...)` without any
|
|
109
|
+
* literal-value drift between type and runtime.
|
|
110
|
+
*/
|
|
111
|
+
exports.ALL_MODES = ['full', 'sanitized'];
|
|
112
|
+
function pathForAllowlist(cwd) {
|
|
113
|
+
return path.join(cwd, exports.ALLOWLIST_DIR, exports.ALLOWLIST_FILENAME);
|
|
114
|
+
}
|
|
115
|
+
function pathForAllowlistReasons(cwd) {
|
|
116
|
+
return path.join(cwd, exports.ALLOWLIST_DIR, exports.ALLOWLIST_REASONS_FILENAME);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Create an empty allowlist file in the requested mode. Useful for
|
|
120
|
+
* the `vyuh-dxkit allowlist add` CLI path when no file exists yet.
|
|
121
|
+
*/
|
|
122
|
+
function emptyAllowlistFile(mode = 'full') {
|
|
123
|
+
return { schemaVersion: exports.ALLOWLIST_SCHEMA_VERSION, mode, entries: [] };
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Read the on-disk allowlist + (when present) merge the sidecar
|
|
127
|
+
* reasons. Returns `null` when the main file doesn't exist —
|
|
128
|
+
* callers treat that as "no allowlist configured."
|
|
129
|
+
*
|
|
130
|
+
* Throws on:
|
|
131
|
+
* - Malformed JSON in either file
|
|
132
|
+
* - Unrecognized `schemaVersion`
|
|
133
|
+
* - Root is not an object
|
|
134
|
+
*
|
|
135
|
+
* The sidecar's absence is NOT an error: customers in sanitized
|
|
136
|
+
* mode may have a committed allowlist on disk without the sidecar
|
|
137
|
+
* cloned (CI checkout, fresh teammate clone). The fingerprint-only
|
|
138
|
+
* file is still functional as a suppression list.
|
|
139
|
+
*/
|
|
140
|
+
function loadAllowlist(cwd) {
|
|
141
|
+
const filePath = pathForAllowlist(cwd);
|
|
142
|
+
if (!fs.existsSync(filePath))
|
|
143
|
+
return null;
|
|
144
|
+
const raw = fs.readFileSync(filePath, 'utf8');
|
|
145
|
+
let parsed;
|
|
146
|
+
try {
|
|
147
|
+
parsed = JSON.parse(raw);
|
|
148
|
+
}
|
|
149
|
+
catch (err) {
|
|
150
|
+
throw new Error(`allowlist file is not valid JSON: ${filePath} (${err.message})`);
|
|
151
|
+
}
|
|
152
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
153
|
+
throw new Error(`allowlist file root is not an object: ${filePath}`);
|
|
154
|
+
}
|
|
155
|
+
const obj = parsed;
|
|
156
|
+
if (obj.schemaVersion !== exports.ALLOWLIST_SCHEMA_VERSION) {
|
|
157
|
+
throw new Error(`allowlist file schemaVersion is ${JSON.stringify(obj.schemaVersion)}; ` +
|
|
158
|
+
`this dxkit understands ${JSON.stringify(exports.ALLOWLIST_SCHEMA_VERSION)} only ` +
|
|
159
|
+
`(${filePath})`);
|
|
160
|
+
}
|
|
161
|
+
if (!isAllowlistMode(obj.mode)) {
|
|
162
|
+
throw new Error(`allowlist file mode is ${JSON.stringify(obj.mode)}; ` +
|
|
163
|
+
`expected one of ${JSON.stringify(exports.ALL_MODES)} (${filePath})`);
|
|
164
|
+
}
|
|
165
|
+
if (!Array.isArray(obj.entries)) {
|
|
166
|
+
throw new Error(`allowlist file entries is not an array (${filePath})`);
|
|
167
|
+
}
|
|
168
|
+
const base = parsed;
|
|
169
|
+
if (base.mode === 'full')
|
|
170
|
+
return base;
|
|
171
|
+
// sanitized mode → merge sidecar if present
|
|
172
|
+
const sidecar = loadAllowlistReasons(cwd);
|
|
173
|
+
if (!sidecar)
|
|
174
|
+
return base;
|
|
175
|
+
return mergeReasons(base, sidecar);
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Load the gitignored reasons sidecar. Returns `null` when missing.
|
|
179
|
+
* Throws on malformed JSON or wrong schemaVersion.
|
|
180
|
+
*/
|
|
181
|
+
function loadAllowlistReasons(cwd) {
|
|
182
|
+
const filePath = pathForAllowlistReasons(cwd);
|
|
183
|
+
if (!fs.existsSync(filePath))
|
|
184
|
+
return null;
|
|
185
|
+
const raw = fs.readFileSync(filePath, 'utf8');
|
|
186
|
+
let parsed;
|
|
187
|
+
try {
|
|
188
|
+
parsed = JSON.parse(raw);
|
|
189
|
+
}
|
|
190
|
+
catch (err) {
|
|
191
|
+
throw new Error(`allowlist reasons sidecar is not valid JSON: ${filePath} (${err.message})`);
|
|
192
|
+
}
|
|
193
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
194
|
+
throw new Error(`allowlist reasons sidecar root is not an object: ${filePath}`);
|
|
195
|
+
}
|
|
196
|
+
const obj = parsed;
|
|
197
|
+
if (obj.schemaVersion !== exports.ALLOWLIST_REASONS_SCHEMA_VERSION) {
|
|
198
|
+
throw new Error(`allowlist reasons sidecar schemaVersion is ${JSON.stringify(obj.schemaVersion)}; ` +
|
|
199
|
+
`expected ${JSON.stringify(exports.ALLOWLIST_REASONS_SCHEMA_VERSION)} (${filePath})`);
|
|
200
|
+
}
|
|
201
|
+
if (!obj.reasons || typeof obj.reasons !== 'object' || Array.isArray(obj.reasons)) {
|
|
202
|
+
throw new Error(`allowlist reasons sidecar 'reasons' is not an object (${filePath})`);
|
|
203
|
+
}
|
|
204
|
+
return parsed;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Persist the allowlist to disk. Writes the sidecar separately in
|
|
208
|
+
* sanitized mode: the committed file gets the structural fields;
|
|
209
|
+
* the sidecar gets `reason` + `addedBy`.
|
|
210
|
+
*
|
|
211
|
+
* Validation runs before writing — invalid input throws and the
|
|
212
|
+
* file isn't touched. Use `validateAllowlistFile` directly when
|
|
213
|
+
* you want non-throwing error reporting.
|
|
214
|
+
*/
|
|
215
|
+
function saveAllowlist(cwd, file) {
|
|
216
|
+
const errors = validateAllowlistFile(file);
|
|
217
|
+
if (errors.length > 0) {
|
|
218
|
+
throw new Error(`allowlist file failed validation:\n` +
|
|
219
|
+
errors.map((e) => ` - ${e.field}: ${e.message}`).join('\n'));
|
|
220
|
+
}
|
|
221
|
+
if (file.mode === 'full') {
|
|
222
|
+
writeJsonPretty(pathForAllowlist(cwd), file);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
// sanitized mode: split entries → main + sidecar
|
|
226
|
+
const sanitizedEntries = [];
|
|
227
|
+
const reasons = {};
|
|
228
|
+
for (const entry of file.entries) {
|
|
229
|
+
sanitizedEntries.push(sanitizedEntry(entry));
|
|
230
|
+
if (entry.reason !== undefined && entry.addedBy !== undefined) {
|
|
231
|
+
reasons[entry.fingerprint] = { reason: entry.reason, addedBy: entry.addedBy };
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
const sanitizedFile = {
|
|
235
|
+
schemaVersion: file.schemaVersion,
|
|
236
|
+
mode: 'sanitized',
|
|
237
|
+
entries: sanitizedEntries,
|
|
238
|
+
};
|
|
239
|
+
const sidecar = {
|
|
240
|
+
schemaVersion: exports.ALLOWLIST_REASONS_SCHEMA_VERSION,
|
|
241
|
+
reasons,
|
|
242
|
+
};
|
|
243
|
+
writeJsonPretty(pathForAllowlist(cwd), sanitizedFile);
|
|
244
|
+
writeJsonPretty(pathForAllowlistReasons(cwd), sidecar);
|
|
245
|
+
}
|
|
246
|
+
/** Find an entry by fingerprint. */
|
|
247
|
+
function findEntry(file, fingerprint) {
|
|
248
|
+
return file.entries.find((e) => e.fingerprint === fingerprint);
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Add an entry. Returns a NEW `AllowlistFile` (immutable update).
|
|
252
|
+
* Throws if `entry.fingerprint` already exists.
|
|
253
|
+
*/
|
|
254
|
+
function addEntry(file, entry) {
|
|
255
|
+
if (findEntry(file, entry.fingerprint)) {
|
|
256
|
+
throw new Error(`allowlist already contains entry for fingerprint ${entry.fingerprint}; ` +
|
|
257
|
+
`use removeEntry first or update in place`);
|
|
258
|
+
}
|
|
259
|
+
return { ...file, entries: [...file.entries, entry] };
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Remove an entry by fingerprint. Returns a NEW `AllowlistFile`.
|
|
263
|
+
* Silently no-ops when the fingerprint isn't present (CLI surfaces
|
|
264
|
+
* the "not found" case through a separate read step).
|
|
265
|
+
*/
|
|
266
|
+
function removeEntry(file, fingerprint) {
|
|
267
|
+
return { ...file, entries: file.entries.filter((e) => e.fingerprint !== fingerprint) };
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Whether the allowlist suppresses a given finding. Pure
|
|
271
|
+
* fingerprint match. Expiry handling is layered on top by
|
|
272
|
+
* `isEntryActive` (kept separate so the guardrail can distinguish
|
|
273
|
+
* "matched but expired" from "no match").
|
|
274
|
+
*/
|
|
275
|
+
function matchesFinding(file, fingerprint) {
|
|
276
|
+
return findEntry(file, fingerprint) !== undefined;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Whether an entry is currently active (within its expiry window).
|
|
280
|
+
* Entries without `expiresAt` are always active. Entries past their
|
|
281
|
+
* expiry are inactive — guardrail treats the underlying finding as
|
|
282
|
+
* un-allowlisted and the next run flags the suppression as stale.
|
|
283
|
+
*/
|
|
284
|
+
function isEntryActive(entry, now = new Date()) {
|
|
285
|
+
if (!entry.expiresAt)
|
|
286
|
+
return true;
|
|
287
|
+
const today = now.toISOString().slice(0, 10);
|
|
288
|
+
return entry.expiresAt >= today;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Days remaining until an entry expires, or `null` when it has no
|
|
292
|
+
* expiry. Negative values mean already expired by that many days.
|
|
293
|
+
*/
|
|
294
|
+
function daysUntilExpiry(entry, now = new Date()) {
|
|
295
|
+
if (!entry.expiresAt)
|
|
296
|
+
return null;
|
|
297
|
+
const expiry = new Date(entry.expiresAt + 'T00:00:00Z');
|
|
298
|
+
const today = new Date(now.toISOString().slice(0, 10) + 'T00:00:00Z');
|
|
299
|
+
const msPerDay = 24 * 60 * 60 * 1000;
|
|
300
|
+
return Math.round((expiry.getTime() - today.getTime()) / msPerDay);
|
|
301
|
+
}
|
|
302
|
+
function auditAllowlist(file, options = {}) {
|
|
303
|
+
const now = options.now ?? new Date();
|
|
304
|
+
const horizon = options.soonToExpireDays ?? 14;
|
|
305
|
+
const expired = [];
|
|
306
|
+
const soonToExpire = [];
|
|
307
|
+
const missingRationale = [];
|
|
308
|
+
for (const entry of file.entries) {
|
|
309
|
+
const days = daysUntilExpiry(entry, now);
|
|
310
|
+
if (days !== null && days < 0) {
|
|
311
|
+
expired.push(entry);
|
|
312
|
+
}
|
|
313
|
+
else if (days !== null && days <= horizon) {
|
|
314
|
+
soonToExpire.push({ entry, daysRemaining: days });
|
|
315
|
+
}
|
|
316
|
+
if (!entry.reason || entry.reason.trim().length === 0) {
|
|
317
|
+
// In sanitized mode the reason may legitimately live in the
|
|
318
|
+
// gitignored sidecar; flag here so the caller can decide
|
|
319
|
+
// whether to treat it as a real audit item or just an
|
|
320
|
+
// "unavailable locally" notice.
|
|
321
|
+
missingRationale.push(entry);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return { expired, soonToExpire, missingRationale };
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Remove expired entries from the file. Returns a new file (immutable)
|
|
328
|
+
* plus the list of removed entries so the CLI can render what changed.
|
|
329
|
+
* Pure function — no I/O.
|
|
330
|
+
*/
|
|
331
|
+
function pruneExpired(file, now = new Date()) {
|
|
332
|
+
const removed = [];
|
|
333
|
+
const keptEntries = [];
|
|
334
|
+
for (const entry of file.entries) {
|
|
335
|
+
if (isEntryActive(entry, now)) {
|
|
336
|
+
keptEntries.push(entry);
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
removed.push(entry);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
return { kept: { ...file, entries: keptEntries }, removed };
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Validate every entry in the file against the canonical taxonomy
|
|
346
|
+
* + Sprint-0-locked rules. Pure function; returns an array of
|
|
347
|
+
* `ValidationError` rather than throwing so callers can render
|
|
348
|
+
* structured error messages.
|
|
349
|
+
*/
|
|
350
|
+
function validateAllowlistFile(file) {
|
|
351
|
+
const errors = [];
|
|
352
|
+
if (file.schemaVersion !== exports.ALLOWLIST_SCHEMA_VERSION) {
|
|
353
|
+
errors.push({
|
|
354
|
+
field: 'schemaVersion',
|
|
355
|
+
message: `expected ${JSON.stringify(exports.ALLOWLIST_SCHEMA_VERSION)}, got ${JSON.stringify(file.schemaVersion)}`,
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
if (!isAllowlistMode(file.mode)) {
|
|
359
|
+
errors.push({
|
|
360
|
+
field: 'mode',
|
|
361
|
+
message: `expected one of ${JSON.stringify(exports.ALL_MODES)}, got ${JSON.stringify(file.mode)}`,
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
const seen = new Set();
|
|
365
|
+
for (const entry of file.entries) {
|
|
366
|
+
if (seen.has(entry.fingerprint)) {
|
|
367
|
+
errors.push({
|
|
368
|
+
fingerprint: entry.fingerprint,
|
|
369
|
+
field: 'fingerprint',
|
|
370
|
+
message: `duplicate fingerprint`,
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
seen.add(entry.fingerprint);
|
|
374
|
+
for (const err of validateAllowlistEntry(entry, file.mode))
|
|
375
|
+
errors.push(err);
|
|
376
|
+
}
|
|
377
|
+
return errors;
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Validate a single entry. Exposed independently so the CLI's
|
|
381
|
+
* `allowlist add` can pre-flight before mutating the file.
|
|
382
|
+
*/
|
|
383
|
+
function validateAllowlistEntry(entry, mode) {
|
|
384
|
+
const errors = [];
|
|
385
|
+
const fp = entry.fingerprint;
|
|
386
|
+
if (!fp || typeof fp !== 'string' || !/^[0-9a-f]{16}$/.test(fp)) {
|
|
387
|
+
errors.push({
|
|
388
|
+
fingerprint: fp,
|
|
389
|
+
field: 'fingerprint',
|
|
390
|
+
message: 'must be a 16-char lowercase hex string',
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
if (!categories_1.ALL_CATEGORIES.includes(entry.category)) {
|
|
394
|
+
errors.push({
|
|
395
|
+
fingerprint: fp,
|
|
396
|
+
field: 'category',
|
|
397
|
+
message: `must be one of ${JSON.stringify(categories_1.ALL_CATEGORIES)}; got ${JSON.stringify(entry.category)}`,
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
if (!(0, categories_1.isCategoryValidForKind)(entry.kind, entry.category)) {
|
|
401
|
+
errors.push({
|
|
402
|
+
fingerprint: fp,
|
|
403
|
+
field: 'category',
|
|
404
|
+
message: `category ${JSON.stringify(entry.category)} does not apply to kind ${JSON.stringify(entry.kind)}`,
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
// reason: required in full mode; sidecar-owned in sanitized mode (so
|
|
408
|
+
// the entry on disk legitimately omits it). The CLI write path emits
|
|
409
|
+
// a separate validation pass for the sidecar.
|
|
410
|
+
if (mode === 'full') {
|
|
411
|
+
if (entry.reason === undefined || entry.reason === null) {
|
|
412
|
+
errors.push({ fingerprint: fp, field: 'reason', message: 'required in full mode' });
|
|
413
|
+
}
|
|
414
|
+
else if (typeof entry.reason !== 'string' || entry.reason.trim().length === 0) {
|
|
415
|
+
errors.push({
|
|
416
|
+
fingerprint: fp,
|
|
417
|
+
field: 'reason',
|
|
418
|
+
message: 'must be a non-empty string',
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
if (entry.addedBy === undefined || entry.addedBy === null) {
|
|
422
|
+
errors.push({ fingerprint: fp, field: 'addedBy', message: 'required in full mode' });
|
|
423
|
+
}
|
|
424
|
+
else if (typeof entry.addedBy !== 'string' || entry.addedBy.trim().length === 0) {
|
|
425
|
+
errors.push({
|
|
426
|
+
fingerprint: fp,
|
|
427
|
+
field: 'addedBy',
|
|
428
|
+
message: 'must be a non-empty string',
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
if (!entry.addedAt || !/^\d{4}-\d{2}-\d{2}$/.test(entry.addedAt)) {
|
|
433
|
+
errors.push({
|
|
434
|
+
fingerprint: fp,
|
|
435
|
+
field: 'addedAt',
|
|
436
|
+
message: 'must be ISO date YYYY-MM-DD',
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
if ((0, categories_1.requiresExpiry)(entry.category)) {
|
|
440
|
+
if (!entry.expiresAt) {
|
|
441
|
+
errors.push({
|
|
442
|
+
fingerprint: fp,
|
|
443
|
+
field: 'expiresAt',
|
|
444
|
+
message: `required for category ${JSON.stringify(entry.category)}`,
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
if (entry.expiresAt !== undefined && !/^\d{4}-\d{2}-\d{2}$/.test(entry.expiresAt)) {
|
|
449
|
+
errors.push({
|
|
450
|
+
fingerprint: fp,
|
|
451
|
+
field: 'expiresAt',
|
|
452
|
+
message: 'must be ISO date YYYY-MM-DD when present',
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
// Note on acknowledgedSeverity: the rule "accepted-risk on a
|
|
456
|
+
// high/critical finding requires acknowledgedSeverity" can't be
|
|
457
|
+
// enforced from inside this validator — the finding's severity
|
|
458
|
+
// doesn't live on the on-disk entry. The CLI's `allowlist add`
|
|
459
|
+
// path enforces it at write time when the finding is in scope.
|
|
460
|
+
return errors;
|
|
461
|
+
}
|
|
462
|
+
// ─── Internals ───────────────────────────────────────────────────────────
|
|
463
|
+
function isAllowlistMode(value) {
|
|
464
|
+
return typeof value === 'string' && exports.ALL_MODES.includes(value);
|
|
465
|
+
}
|
|
466
|
+
function writeJsonPretty(filePath, value) {
|
|
467
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
468
|
+
fs.writeFileSync(filePath, JSON.stringify(value, null, 2) + '\n', 'utf8');
|
|
469
|
+
}
|
|
470
|
+
function sanitizedEntry(entry) {
|
|
471
|
+
// Strip `reason` + `addedBy`; everything else stays on disk in the
|
|
472
|
+
// committed file. The fingerprint contract preserves matching.
|
|
473
|
+
// We intentionally rebuild via property assignment rather than
|
|
474
|
+
// destructuring so the optional-undefined fields don't survive
|
|
475
|
+
// serialization as explicit `null`s.
|
|
476
|
+
const out = {
|
|
477
|
+
fingerprint: entry.fingerprint,
|
|
478
|
+
kind: entry.kind,
|
|
479
|
+
category: entry.category,
|
|
480
|
+
addedAt: entry.addedAt,
|
|
481
|
+
...(entry.expiresAt !== undefined ? { expiresAt: entry.expiresAt } : {}),
|
|
482
|
+
...(entry.acknowledgedSeverity !== undefined
|
|
483
|
+
? { acknowledgedSeverity: entry.acknowledgedSeverity }
|
|
484
|
+
: {}),
|
|
485
|
+
};
|
|
486
|
+
return out;
|
|
487
|
+
}
|
|
488
|
+
function mergeReasons(file, sidecar) {
|
|
489
|
+
const merged = file.entries.map((entry) => {
|
|
490
|
+
const r = sidecar.reasons[entry.fingerprint];
|
|
491
|
+
if (!r)
|
|
492
|
+
return entry;
|
|
493
|
+
return { ...entry, reason: r.reason, addedBy: r.addedBy };
|
|
494
|
+
});
|
|
495
|
+
return { ...file, entries: merged };
|
|
496
|
+
}
|
|
497
|
+
//# sourceMappingURL=file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.js","sourceRoot":"","sources":["../../src/allowlist/file.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inline allowlist annotation gather pass.
|
|
3
|
+
*
|
|
4
|
+
* Walks the source tree looking for `<lineComment> dxkit-allow:<category>`
|
|
5
|
+
* comments and records each occurrence as a `(file, line, category)`
|
|
6
|
+
* tuple. The `stale-allow` producer uses this list together with the
|
|
7
|
+
* current scan's secret/code/config findings to detect orphaned
|
|
8
|
+
* annotations — annotations whose underlying finding is no longer
|
|
9
|
+
* present, which the developer should remove.
|
|
10
|
+
*
|
|
11
|
+
* Architectural posture:
|
|
12
|
+
*
|
|
13
|
+
* - File walk goes through the canonical `walkSourceFiles` helper
|
|
14
|
+
* so `.gitignore` + `.dxkit-ignore` + bundled defaults are
|
|
15
|
+
* honored uniformly. No custom recursion / exclusion logic
|
|
16
|
+
* (per CLAUDE.md G_v4_7).
|
|
17
|
+
* - Per-language comment marker comes from each pack's
|
|
18
|
+
* `LanguageSupport.commentSyntax` via the inline annotation
|
|
19
|
+
* parser. No hardcoded `'//'` / `'#'` literals in this module
|
|
20
|
+
* (arch-check rule 2 enforces).
|
|
21
|
+
* - Annotation parsing reuses `parseAnnotation` from `inline.ts`
|
|
22
|
+
* — single source of grammar truth.
|
|
23
|
+
*
|
|
24
|
+
* Test files ARE walked (intentional — annotations often live in
|
|
25
|
+
* test fixtures suppressing scanner findings against deliberate
|
|
26
|
+
* placeholder credentials). Auto-generated files are NOT walked
|
|
27
|
+
* (the developer doesn't author annotations in generated code, and
|
|
28
|
+
* `walkSourceFiles` already excludes them by default).
|
|
29
|
+
*/
|
|
30
|
+
import { type AnnotationPosition } from './inline';
|
|
31
|
+
export interface InlineAllowlistOccurrence {
|
|
32
|
+
/** Project-relative POSIX path. */
|
|
33
|
+
readonly file: string;
|
|
34
|
+
/** 1-based line number where the annotation comment LIVES. For
|
|
35
|
+
* above-line annotations the value is the line just before the
|
|
36
|
+
* finding's target; for same-line it's the finding's own line. */
|
|
37
|
+
readonly line: number;
|
|
38
|
+
/** Category named in the annotation (`test-fixture` / `false-positive` /
|
|
39
|
+
* etc.). Free-form at gather level; the producer cross-checks
|
|
40
|
+
* against the canonical `AllowlistCategory` union. */
|
|
41
|
+
readonly category: string;
|
|
42
|
+
/** Where the annotation sits relative to the suppressed line. */
|
|
43
|
+
readonly position: AnnotationPosition;
|
|
44
|
+
}
|
|
45
|
+
export interface GatherInlineOpts {
|
|
46
|
+
/** Walk test files too. Default: true (test fixtures legitimately
|
|
47
|
+
* carry intentional placeholders + suppressions). */
|
|
48
|
+
readonly includeTests?: boolean;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Walk source files under `cwd` and collect every inline allowlist
|
|
52
|
+
* annotation occurrence. Cheap on small repos; on large ones the
|
|
53
|
+
* `walkSourceFiles` cache amortizes the cost across multiple gather
|
|
54
|
+
* passes within a single baseline-create run.
|
|
55
|
+
*
|
|
56
|
+
* Returns occurrences in stable order (file path lexicographic, then
|
|
57
|
+
* line ascending) so downstream deterministic-output requirements
|
|
58
|
+
* are satisfied automatically.
|
|
59
|
+
*/
|
|
60
|
+
export declare function gatherInlineAllowlistAnnotations(cwd: string, opts?: GatherInlineOpts): InlineAllowlistOccurrence[];
|
|
61
|
+
//# sourceMappingURL=gather.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gather.d.ts","sourceRoot":"","sources":["../../src/allowlist/gather.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAOH,OAAO,EAA+C,KAAK,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAEhG,MAAM,WAAW,yBAAyB;IACxC,mCAAmC;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;uEAEmE;IACnE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;2DAEuD;IACvD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,iEAAiE;IACjE,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAC;CACvC;AAED,MAAM,WAAW,gBAAgB;IAC/B;0DACsD;IACtD,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;CACjC;AAED;;;;;;;;;GASG;AACH,wBAAgB,gCAAgC,CAC9C,GAAG,EAAE,MAAM,EACX,IAAI,GAAE,gBAAqB,GAC1B,yBAAyB,EAAE,CA+C7B"}
|