@vaultcompass/vault-guard 1.4.0 → 1.4.2
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/dist/cli-entry.js +6 -0
- package/dist/cli.js +2 -41
- package/dist/commands/data.js +24 -31
- package/dist/commands/proxy.js +12 -2
- package/dist/commands/statusline.js +8 -16
- package/dist/commands/suggest-model.js +4 -16
- package/dist/init/templates.d.ts +1 -1
- package/dist/init/templates.js +3 -2
- package/dist/version.d.ts +18 -0
- package/dist/version.js +60 -0
- package/package.json +3 -3
package/dist/cli-entry.js
CHANGED
|
@@ -8,6 +8,12 @@ if (nodeMajor < 22) {
|
|
|
8
8
|
'Some features may not work correctly.');
|
|
9
9
|
}
|
|
10
10
|
const program = (0, cli_1.buildCli)();
|
|
11
|
+
// npx (and some wrappers) forward a leading `--` into argv. Commander treats
|
|
12
|
+
// that as end-of-options, so `--format sarif` is ignored and text banners
|
|
13
|
+
// pollute machine-readable stdout. Drop a single leading separator.
|
|
14
|
+
if (process.argv[2] === '--') {
|
|
15
|
+
process.argv.splice(2, 1);
|
|
16
|
+
}
|
|
11
17
|
// Parse arguments and execute command
|
|
12
18
|
program.parseAsync().catch((error) => {
|
|
13
19
|
// Handle errors
|
package/dist/cli.js
CHANGED
|
@@ -1,41 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
3
|
exports.buildCli = buildCli;
|
|
37
|
-
const fs = __importStar(require("fs"));
|
|
38
|
-
const path = __importStar(require("path"));
|
|
39
4
|
const commander_1 = require("commander");
|
|
40
5
|
const scan_1 = require("./commands/scan");
|
|
41
6
|
const install_hook_1 = require("./commands/install-hook");
|
|
@@ -48,11 +13,7 @@ const proxy_1 = require("./commands/proxy");
|
|
|
48
13
|
const data_1 = require("./commands/data");
|
|
49
14
|
const config_1 = require("./commands/config");
|
|
50
15
|
const init_1 = require("./commands/init");
|
|
51
|
-
|
|
52
|
-
const pkgPath = path.join(__dirname, '..', 'package.json');
|
|
53
|
-
const raw = fs.readFileSync(pkgPath, 'utf-8');
|
|
54
|
-
return JSON.parse(raw).version;
|
|
55
|
-
}
|
|
16
|
+
const version_1 = require("./version");
|
|
56
17
|
function setExitCode(exitCode) {
|
|
57
18
|
if (exitCode !== 0) {
|
|
58
19
|
process.exitCode = exitCode;
|
|
@@ -63,7 +24,7 @@ function buildCli() {
|
|
|
63
24
|
program
|
|
64
25
|
.name('vault-guard')
|
|
65
26
|
.description('Security and optimization layer for AI-native coding')
|
|
66
|
-
.version(readCliVersion());
|
|
27
|
+
.version((0, version_1.readCliVersion)());
|
|
67
28
|
const configCmd = program.command('config').description('Inspect and validate Vault Guard configuration');
|
|
68
29
|
configCmd
|
|
69
30
|
.command('validate')
|
package/dist/commands/data.js
CHANGED
|
@@ -50,41 +50,36 @@ const vault_guard_telemetry_1 = require("@vaultcompass/vault-guard-telemetry");
|
|
|
50
50
|
async function dataStatusCommand(options = {}) {
|
|
51
51
|
const dbPath = options.dbPath ?? (0, vault_guard_telemetry_1.getDefaultDbPath)();
|
|
52
52
|
const asJson = Boolean(options.json);
|
|
53
|
-
|
|
53
|
+
const store = new vault_guard_telemetry_1.TelemetryStore(dbPath);
|
|
54
54
|
try {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
};
|
|
55
|
+
// TelemetryStore never throws; `data status` is specifically a telemetry
|
|
56
|
+
// diagnostic, so unlike scan/statusline/MCP (which just get zeroed
|
|
57
|
+
// no-op results) it keeps reporting "unavailable" explicitly via exit
|
|
58
|
+
// code 2 rather than silently showing an all-zero status that would be
|
|
59
|
+
// indistinguishable from "genuinely no usage yet".
|
|
60
|
+
if (!store.isAvailable()) {
|
|
61
|
+
const message = store.getUnavailableReason() ?? 'better-sqlite3 native bindings unavailable.';
|
|
62
|
+
const payload = { error: 'telemetry_unavailable', message, db_path: dbPath };
|
|
64
63
|
if (asJson) {
|
|
65
64
|
process.stdout.write(`${JSON.stringify(payload)}\n`);
|
|
66
65
|
}
|
|
67
66
|
else {
|
|
68
|
-
process.stderr.write(`vault-guard data status: telemetry unavailable — ${
|
|
67
|
+
process.stderr.write(`vault-guard data status: telemetry unavailable — ${message}\n` +
|
|
69
68
|
`expected db path: ${dbPath}\n`);
|
|
70
69
|
}
|
|
71
70
|
return 2;
|
|
72
71
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
72
|
+
const status = store.getDataStatus(dbPath);
|
|
73
|
+
if (asJson) {
|
|
74
|
+
process.stdout.write(`${JSON.stringify(status)}\n`);
|
|
75
|
+
return 0;
|
|
76
|
+
}
|
|
77
|
+
printStatusHuman(status);
|
|
78
|
+
return 0;
|
|
78
79
|
}
|
|
79
80
|
finally {
|
|
80
81
|
store.close();
|
|
81
82
|
}
|
|
82
|
-
if (asJson) {
|
|
83
|
-
process.stdout.write(`${JSON.stringify(status)}\n`);
|
|
84
|
-
return 0;
|
|
85
|
-
}
|
|
86
|
-
printStatusHuman(status);
|
|
87
|
-
return 0;
|
|
88
83
|
}
|
|
89
84
|
function printStatusHuman(s) {
|
|
90
85
|
const sizeKb = (s.db_size_bytes / 1024).toFixed(1);
|
|
@@ -250,18 +245,16 @@ async function confirmReset(confirmFn, files) {
|
|
|
250
245
|
async function dataExportCommand(options) {
|
|
251
246
|
const dbPath = options.dbPath ?? (0, vault_guard_telemetry_1.getDefaultDbPath)();
|
|
252
247
|
const format = options.format ?? 'json';
|
|
253
|
-
|
|
248
|
+
const store = new vault_guard_telemetry_1.TelemetryStore(dbPath);
|
|
254
249
|
try {
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
if (
|
|
259
|
-
|
|
250
|
+
// See dataStatusCommand: `data export` is a telemetry diagnostic, so it
|
|
251
|
+
// keeps reporting "unavailable" explicitly rather than silently writing
|
|
252
|
+
// an empty export file.
|
|
253
|
+
if (!store.isAvailable()) {
|
|
254
|
+
const message = store.getUnavailableReason() ?? 'better-sqlite3 native bindings unavailable.';
|
|
255
|
+
process.stderr.write(`vault-guard data export: telemetry unavailable — ${message}\n`);
|
|
260
256
|
return 2;
|
|
261
257
|
}
|
|
262
|
-
throw e;
|
|
263
|
-
}
|
|
264
|
-
try {
|
|
265
258
|
const usage = store.exportUsageEvents();
|
|
266
259
|
const sessions = store.exportSessionEvents();
|
|
267
260
|
if (format === 'jsonl') {
|
package/dist/commands/proxy.js
CHANGED
|
@@ -137,9 +137,19 @@ async function proxyCommand(opts) {
|
|
|
137
137
|
server.listen(port, host, () => resolve());
|
|
138
138
|
server.on('error', reject);
|
|
139
139
|
});
|
|
140
|
+
const telemetryAvailable = store.isAvailable();
|
|
140
141
|
process.stderr.write(`vault-guard proxy listening on http://${host}:${port}\n` +
|
|
141
|
-
`Forward Anthropic traffic here (e.g. ANTHROPIC_BASE_URL=http://${host}:${port})
|
|
142
|
-
|
|
142
|
+
`Forward Anthropic traffic here (e.g. ANTHROPIC_BASE_URL=http://${host}:${port}).` +
|
|
143
|
+
(telemetryAvailable
|
|
144
|
+
? ` Non-stream JSON responses log usage to ${path_1.default.join('~', '.vault-guard', 'usage.sqlite')}.\n`
|
|
145
|
+
: '\n'));
|
|
146
|
+
if (!telemetryAvailable) {
|
|
147
|
+
// Telemetry degrades silently to a no-op store when better-sqlite3 is
|
|
148
|
+
// unavailable (packages/telemetry/src/store.ts); the banner above must
|
|
149
|
+
// not claim usage is being logged when it is not. One notice, matching
|
|
150
|
+
// the MCP server's wording style (see server.ts's getTelemetry()).
|
|
151
|
+
process.stderr.write(`vault-guard proxy: telemetry unavailable, usage will NOT be recorded: ${store.getUnavailableReason() ?? 'better-sqlite3 native bindings unavailable.'}\n`);
|
|
152
|
+
}
|
|
143
153
|
if (options.allowEnvFallback) {
|
|
144
154
|
process.stderr.write(`⚠️ --allow-env-fallback is active: requests without x-api-key will use ` +
|
|
145
155
|
`ANTHROPIC_API_KEY from the proxy host's environment.\n`);
|
|
@@ -2,23 +2,15 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.statuslineCommand = statuslineCommand;
|
|
4
4
|
const vault_guard_telemetry_1 = require("@vaultcompass/vault-guard-telemetry");
|
|
5
|
+
// TelemetryStore never throws (a missing/incompatible better-sqlite3 native
|
|
6
|
+
// binding degrades it to a no-op that reports zeroed stats), so this command
|
|
7
|
+
// never needs to special-case "telemetry unavailable": it always constructs,
|
|
8
|
+
// always prints something, and never prints an unavailability warning on
|
|
9
|
+
// every invocation (statusline can be invoked by an editor every few
|
|
10
|
+
// seconds; see @vaultcompass/vault-guard-telemetry's store.ts for the
|
|
11
|
+
// single, opt-in (VG_DEBUG=1) debug notice logged once per process instead).
|
|
5
12
|
function statuslineCommand(asJson) {
|
|
6
|
-
|
|
7
|
-
try {
|
|
8
|
-
store = new vault_guard_telemetry_1.TelemetryStore();
|
|
9
|
-
}
|
|
10
|
-
catch (e) {
|
|
11
|
-
if (e instanceof vault_guard_telemetry_1.TelemetryUnavailableError) {
|
|
12
|
-
if (asJson) {
|
|
13
|
-
process.stdout.write(`${JSON.stringify({ error: 'telemetry_unavailable', message: e.message })}\n`);
|
|
14
|
-
}
|
|
15
|
-
else {
|
|
16
|
-
process.stderr.write(`vault-guard statusline: telemetry unavailable — ${e.message}\n`);
|
|
17
|
-
}
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
throw e;
|
|
21
|
-
}
|
|
13
|
+
const store = new vault_guard_telemetry_1.TelemetryStore();
|
|
22
14
|
try {
|
|
23
15
|
const payload = store.getStatuslinePayload();
|
|
24
16
|
if (asJson) {
|
|
@@ -2,23 +2,11 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.suggestModelCommand = suggestModelCommand;
|
|
4
4
|
const vault_guard_telemetry_1 = require("@vaultcompass/vault-guard-telemetry");
|
|
5
|
+
// TelemetryStore never throws: with better-sqlite3 unavailable,
|
|
6
|
+
// store.suggestModel() below returns { suggested_model: null, reason: '...',
|
|
7
|
+
// by_model: [] } rather than needing this command to special-case it.
|
|
5
8
|
function suggestModelCommand(options) {
|
|
6
|
-
|
|
7
|
-
try {
|
|
8
|
-
store = new vault_guard_telemetry_1.TelemetryStore();
|
|
9
|
-
}
|
|
10
|
-
catch (e) {
|
|
11
|
-
if (e instanceof vault_guard_telemetry_1.TelemetryUnavailableError) {
|
|
12
|
-
if (options.json) {
|
|
13
|
-
process.stdout.write(`${JSON.stringify({ error: 'telemetry_unavailable', message: e.message }, null, 2)}\n`);
|
|
14
|
-
}
|
|
15
|
-
else {
|
|
16
|
-
process.stderr.write(`vault-guard suggest-model: telemetry unavailable — ${e.message}\n`);
|
|
17
|
-
}
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
throw e;
|
|
21
|
-
}
|
|
9
|
+
const store = new vault_guard_telemetry_1.TelemetryStore();
|
|
22
10
|
try {
|
|
23
11
|
const s = store.suggestModel({ cwd: options.cwd, language: options.language });
|
|
24
12
|
if (options.json) {
|
package/dist/init/templates.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Stable init template version
|
|
1
|
+
/** Stable init template version; bump when file contents change materially. */
|
|
2
2
|
export declare const INIT_TEMPLATE_VERSION = "1";
|
|
3
3
|
export declare const MANIFEST_RELATIVE_PATH = ".vault-guard/manifest.json";
|
|
4
4
|
export declare const MANAGED_FILE_PATHS: readonly [".vault-guard.json", ".github/workflows/vault-guard.yml", ".vault-guard/mcp-snippet.json", ".vault-guard/agent-rules.md", ".vault-guard/manifest.json"];
|
package/dist/init/templates.js
CHANGED
|
@@ -7,7 +7,8 @@ exports.mcpSnippetJson = mcpSnippetJson;
|
|
|
7
7
|
exports.agentRulesMarkdown = agentRulesMarkdown;
|
|
8
8
|
exports.templateContentForPath = templateContentForPath;
|
|
9
9
|
exports.buildManifestContent = buildManifestContent;
|
|
10
|
-
|
|
10
|
+
const version_1 = require("../version");
|
|
11
|
+
/** Stable init template version; bump when file contents change materially. */
|
|
11
12
|
exports.INIT_TEMPLATE_VERSION = '1';
|
|
12
13
|
exports.MANIFEST_RELATIVE_PATH = '.vault-guard/manifest.json';
|
|
13
14
|
exports.MANAGED_FILE_PATHS = [
|
|
@@ -38,7 +39,7 @@ jobs:
|
|
|
38
39
|
runs-on: ubuntu-latest
|
|
39
40
|
steps:
|
|
40
41
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
41
|
-
- uses: vaultcompasshq/vault-guard@
|
|
42
|
+
- uses: vaultcompasshq/vault-guard@v${(0, version_1.readCliVersion)()}
|
|
42
43
|
with:
|
|
43
44
|
version: latest
|
|
44
45
|
path: .
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read the CLI's own package.json `version` at runtime.
|
|
3
|
+
*
|
|
4
|
+
* Resolves relative to *this module's own* compiled location, not the
|
|
5
|
+
* caller's, which is exactly why this lives in its own file rather than
|
|
6
|
+
* being duplicated per call site: `__dirname` here is always
|
|
7
|
+
* `<package root>/dist` once built (this file compiles to
|
|
8
|
+
* `dist/version.js`, directly under `dist/`, same as `dist/cli.js`) and
|
|
9
|
+
* always `<package root>/src` under ts-jest, so `path.join(__dirname, '..',
|
|
10
|
+
* 'package.json')` lands on `<package root>/package.json` either way,
|
|
11
|
+
* regardless of how deep the *caller* (e.g. `src/init/templates.ts`,
|
|
12
|
+
* compiled to `dist/init/templates.js`) sits.
|
|
13
|
+
*
|
|
14
|
+
* A static `import pkg from '../../package.json'` is not viable from
|
|
15
|
+
* `templates.ts`: that path resolves outside this package's
|
|
16
|
+
* `rootDir` (`./src`), which `tsc` rejects.
|
|
17
|
+
*/
|
|
18
|
+
export declare function readCliVersion(): string;
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.readCliVersion = readCliVersion;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
/**
|
|
40
|
+
* Read the CLI's own package.json `version` at runtime.
|
|
41
|
+
*
|
|
42
|
+
* Resolves relative to *this module's own* compiled location, not the
|
|
43
|
+
* caller's, which is exactly why this lives in its own file rather than
|
|
44
|
+
* being duplicated per call site: `__dirname` here is always
|
|
45
|
+
* `<package root>/dist` once built (this file compiles to
|
|
46
|
+
* `dist/version.js`, directly under `dist/`, same as `dist/cli.js`) and
|
|
47
|
+
* always `<package root>/src` under ts-jest, so `path.join(__dirname, '..',
|
|
48
|
+
* 'package.json')` lands on `<package root>/package.json` either way,
|
|
49
|
+
* regardless of how deep the *caller* (e.g. `src/init/templates.ts`,
|
|
50
|
+
* compiled to `dist/init/templates.js`) sits.
|
|
51
|
+
*
|
|
52
|
+
* A static `import pkg from '../../package.json'` is not viable from
|
|
53
|
+
* `templates.ts`: that path resolves outside this package's
|
|
54
|
+
* `rootDir` (`./src`), which `tsc` rejects.
|
|
55
|
+
*/
|
|
56
|
+
function readCliVersion() {
|
|
57
|
+
const pkgPath = path.join(__dirname, '..', 'package.json');
|
|
58
|
+
const raw = fs.readFileSync(pkgPath, 'utf-8');
|
|
59
|
+
return JSON.parse(raw).version;
|
|
60
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vaultcompass/vault-guard",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.2",
|
|
4
4
|
"description": "Block secrets at commit and in CI. Pre-commit hooks, SARIF output, and fast staged-file scans for AI-native workflows.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"chalk": "^4.1.2",
|
|
38
38
|
"commander": "^12.0.0",
|
|
39
|
-
"@vaultcompass/vault-guard-
|
|
40
|
-
"@vaultcompass/vault-guard-
|
|
39
|
+
"@vaultcompass/vault-guard-core": "1.4.2",
|
|
40
|
+
"@vaultcompass/vault-guard-telemetry": "1.4.2"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/jest": "^30.0.0",
|