@cybedefend/vibedefend 1.1.1 → 1.2.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/README.md +13 -4
- package/dist/clients/claude-code.js +6 -8
- package/dist/clients/claude-code.js.map +1 -1
- package/dist/clients/codex.js +6 -1
- package/dist/clients/codex.js.map +1 -1
- package/dist/clients/detect.js +5 -1
- package/dist/clients/detect.js.map +1 -1
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/diagnostics.js +5 -0
- package/dist/diagnostics.js.map +1 -1
- package/dist/doctor.js +13 -0
- package/dist/doctor.js.map +1 -1
- package/dist/hook-runner.js +537 -101
- package/dist/hooks/install.js +54 -9
- package/dist/hooks/install.js.map +1 -1
- package/dist/hooks/runtime/guard-violations-buffer.js +65 -15
- package/dist/hooks/runtime/guard-violations-buffer.js.map +1 -1
- package/dist/hooks/runtime/self-update-check.js +196 -0
- package/dist/hooks/runtime/self-update-check.js.map +1 -0
- package/dist/hooks/runtime/semver.js +34 -0
- package/dist/hooks/runtime/semver.js.map +1 -0
- package/dist/hooks/runtime/session-review.js +126 -40
- package/dist/hooks/runtime/session-review.js.map +1 -1
- package/dist/hooks/runtime/session-start.js +24 -0
- package/dist/hooks/runtime/session-start.js.map +1 -1
- package/dist/hooks/shim-entry.js +10 -0
- package/dist/hooks/shim-entry.js.map +1 -0
- package/dist/hooks/shim.js +66 -0
- package/dist/hooks/shim.js.map +1 -0
- package/dist/login.js +25 -5
- package/dist/login.js.map +1 -1
- package/dist/prompts.js +14 -2
- package/dist/prompts.js.map +1 -1
- package/dist/self-update.js +46 -21
- package/dist/self-update.js.map +1 -1
- package/dist/shim.js +40 -0
- package/dist/utils.js +5 -1
- package/dist/utils.js.map +1 -1
- package/package.json +1 -1
package/dist/hooks/install.js
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
import { copyFileSync, existsSync, rmSync } from 'node:fs';
|
|
18
18
|
import { dirname, join } from 'node:path';
|
|
19
19
|
import { fileURLToPath } from 'node:url';
|
|
20
|
+
import { detectInstallMode, resolveScriptPath, GLOBAL_MODES, } from '../self-update.js';
|
|
20
21
|
import { ensureDirFor, home, log, writeJson } from '../utils.js';
|
|
21
22
|
/** Top-level directory we own. */
|
|
22
23
|
export const VIBEDEFEND_DIR = home('.cybedefend');
|
|
@@ -48,6 +49,23 @@ function locateBundledRunner() {
|
|
|
48
49
|
}
|
|
49
50
|
return null;
|
|
50
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Resolve the bundled `shim.js` shipped alongside `hook-runner.js`.
|
|
54
|
+
* Same search strategy as `locateBundledRunner`. Returns null if absent.
|
|
55
|
+
*/
|
|
56
|
+
function locateBundledShim() {
|
|
57
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
58
|
+
const candidates = [
|
|
59
|
+
join(here, 'shim.js'),
|
|
60
|
+
join(here, '..', 'dist', 'shim.js'),
|
|
61
|
+
join(here, '..', '..', 'dist', 'shim.js'),
|
|
62
|
+
];
|
|
63
|
+
for (const c of candidates) {
|
|
64
|
+
if (existsSync(c))
|
|
65
|
+
return c;
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
51
69
|
/**
|
|
52
70
|
* Drop any legacy `~/.cybedefend/hooks/` directory (V1 bash scripts).
|
|
53
71
|
* Idempotent — silent no-op if the directory doesn't exist.
|
|
@@ -68,21 +86,36 @@ function removeLegacyHooks() {
|
|
|
68
86
|
*
|
|
69
87
|
* Steps:
|
|
70
88
|
* 1. Sweep legacy `~/.cybedefend/hooks/` if present.
|
|
71
|
-
* 2.
|
|
89
|
+
* 2. For global installs: copy `dist/shim.js` → `~/.cybedefend/hook-runner.js`
|
|
90
|
+
* and stamp `runnerSource` in the config so updates are live immediately.
|
|
91
|
+
* For non-global installs: copy the full runner (legacy behaviour) and
|
|
92
|
+
* force `autoUpdate: false`.
|
|
72
93
|
* 3. Write `~/.cybedefend/runtime-config.json` with the user's
|
|
73
94
|
* region + hook settings.
|
|
74
95
|
*
|
|
75
96
|
* Returns the destination paths so the caller can `log.hint(...)` them.
|
|
76
97
|
*/
|
|
77
|
-
export function installHookRuntime(opts) {
|
|
98
|
+
export function installHookRuntime(opts, deps = {}) {
|
|
78
99
|
removeLegacyHooks();
|
|
79
|
-
const
|
|
80
|
-
|
|
100
|
+
const installMode = deps.installMode ?? detectInstallMode(resolveScriptPath());
|
|
101
|
+
const locateRunner = deps.locateRunner ?? locateBundledRunner;
|
|
102
|
+
const locateShim = deps.locateShim ?? locateBundledShim;
|
|
103
|
+
const runnerSource = locateRunner();
|
|
104
|
+
if (runnerSource === null) {
|
|
81
105
|
throw new Error('Could not locate the bundled hook-runner.js. Did `pnpm run build` finish? ' +
|
|
82
106
|
'Expected to find it under <package>/dist/.');
|
|
83
107
|
}
|
|
84
|
-
|
|
85
|
-
|
|
108
|
+
const dir = deps.cybeDir ?? VIBEDEFEND_DIR;
|
|
109
|
+
const hookRunnerDest = join(dir, 'hook-runner.js');
|
|
110
|
+
const configDest = join(dir, 'runtime-config.json');
|
|
111
|
+
// Global installs get the stable shim + a stamped runnerSource so a later
|
|
112
|
+
// `npm i -g` is immediately live with no recopy. Non-global installs have
|
|
113
|
+
// no stable package path, so we keep the legacy full-copy behaviour and
|
|
114
|
+
// disable background auto-update.
|
|
115
|
+
const shimPath = locateShim();
|
|
116
|
+
const useShim = GLOBAL_MODES.has(installMode) && shimPath !== null;
|
|
117
|
+
ensureDirFor(hookRunnerDest);
|
|
118
|
+
copyFileSync(useShim ? shimPath : runnerSource, hookRunnerDest);
|
|
86
119
|
const runtimeConfig = {
|
|
87
120
|
region: {
|
|
88
121
|
id: opts.region.id,
|
|
@@ -95,11 +128,23 @@ export function installHookRuntime(opts) {
|
|
|
95
128
|
enableSessionReview: opts.hooks.enableSessionReview,
|
|
96
129
|
reviewThreshold: opts.hooks.reviewThreshold,
|
|
97
130
|
autoProposeMode: opts.hooks.autoProposeMode,
|
|
131
|
+
autoUpdate: useShim ? opts.hooks.autoUpdate : false,
|
|
98
132
|
},
|
|
99
133
|
installedVersion: opts.installedVersion,
|
|
134
|
+
...(useShim ? { runnerSource } : {}),
|
|
100
135
|
};
|
|
101
|
-
writeJson(
|
|
102
|
-
return { runnerPath:
|
|
136
|
+
writeJson(configDest, runtimeConfig);
|
|
137
|
+
return { runnerPath: hookRunnerDest, configPath: configDest };
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Quote a path for embedding in a hook `command` string, but ONLY when it
|
|
141
|
+
* contains whitespace. Both POSIX `sh` and Windows `cmd.exe` (which run the
|
|
142
|
+
* hook command) accept a double-quoted path, so a home directory with a
|
|
143
|
+
* space (e.g. `C:\\Users\\First Last\\...`) no longer splits mid-argument.
|
|
144
|
+
* Space-free paths are left untouched so the common command is unchanged.
|
|
145
|
+
*/
|
|
146
|
+
export function quoteCommandPath(p) {
|
|
147
|
+
return /\s/.test(p) ? `"${p}"` : p;
|
|
103
148
|
}
|
|
104
149
|
/**
|
|
105
150
|
* Compose the `command` field for a settings.json hook entry, targeting
|
|
@@ -107,7 +152,7 @@ export function installHookRuntime(opts) {
|
|
|
107
152
|
* touching the filesystem.
|
|
108
153
|
*/
|
|
109
154
|
export function hookCommand(subcommand) {
|
|
110
|
-
return `node ${HOOK_RUNNER_PATH} ${subcommand}`;
|
|
155
|
+
return `node ${quoteCommandPath(HOOK_RUNNER_PATH)} ${subcommand}`;
|
|
111
156
|
}
|
|
112
157
|
/**
|
|
113
158
|
* Marker used by every adapter's `dropOurs` to identify legacy AND new
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/hooks/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAIzC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGjE,kCAAkC;AAClC,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC;AAElD,0EAA0E;AAC1E,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC,aAAa,EAAE,gBAAgB,CAAC,CAAC;AAEtE,iEAAiE;AACjE,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,CACrC,aAAa,EACb,qBAAqB,CACtB,CAAC;AAEF,kEAAkE;AAClE,MAAM,gBAAgB,GAAG,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;AAEtD;;;;;;;GAOG;AACH,SAAS,mBAAmB;IAC1B,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,iEAAiE;IACjE,MAAM,UAAU,GAAG;QACjB,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC;QAC5B,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,gBAAgB,CAAC;QAC1C,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,gBAAgB,CAAC;KACjD,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,IAAI,UAAU,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,SAAS,iBAAiB;IACxB,IAAI,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACjC,IAAI,CAAC;YACH,MAAM,CAAC,gBAAgB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3D,GAAG,CAAC,IAAI,CAAC,kCAAkC,gBAAgB,EAAE,CAAC,CAAC;QACjE,CAAC;QAAC,MAAM,CAAC;YACP,kCAAkC;QACpC,CAAC;IACH,CAAC;AACH,CAAC;
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/hooks/install.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Violations (deny/warn outcomes) are appended as JSON lines to a local
|
|
5
5
|
* buffer file (`~/.cybedefend/guards-violations-buffer.jsonl`) and flushed
|
|
6
|
-
* to the gateway on demand
|
|
7
|
-
* `process.on('beforeExit')`).
|
|
6
|
+
* to the gateway on demand by the hook before it returns.
|
|
8
7
|
*
|
|
9
8
|
* Why JSONL + append semantics?
|
|
10
9
|
* - Append to a file is atomic at the OS level for small writes.
|
|
@@ -13,6 +12,17 @@
|
|
|
13
12
|
* - The hook NEVER blocks on the audit write — `bufferViolation` is
|
|
14
13
|
* synchronous (sync appendFileSync with minimal data).
|
|
15
14
|
*
|
|
15
|
+
* Per-project semantics:
|
|
16
|
+
* - Each buffered record carries its own `projectId`. When the buffer is
|
|
17
|
+
* flushed, records are grouped by `projectId` and each group is POSTed
|
|
18
|
+
* to its own project's endpoint. This is required because a developer
|
|
19
|
+
* may switch projects between hook invocations, and the user's Logto
|
|
20
|
+
* token (same across all their projects) can authorise calls to any
|
|
21
|
+
* project the Permify policy allows.
|
|
22
|
+
* - On partial failure (e.g. permission denied for one project, success
|
|
23
|
+
* for another) only the failed groups are kept in the buffer; the
|
|
24
|
+
* successful ones are purged.
|
|
25
|
+
*
|
|
16
26
|
* Violation semantics:
|
|
17
27
|
* - `deny` → outcome = 'denied'
|
|
18
28
|
* - `warn` → outcome = 'warned'
|
|
@@ -53,7 +63,7 @@ export function makeViolationsBuffer(opts = {}) {
|
|
|
53
63
|
content = readFileSync(bufferFile, 'utf8').trim();
|
|
54
64
|
}
|
|
55
65
|
catch {
|
|
56
|
-
return;
|
|
66
|
+
return;
|
|
57
67
|
}
|
|
58
68
|
if (!content)
|
|
59
69
|
return;
|
|
@@ -63,30 +73,70 @@ export function makeViolationsBuffer(opts = {}) {
|
|
|
63
73
|
if (!trimmed)
|
|
64
74
|
continue;
|
|
65
75
|
try {
|
|
66
|
-
|
|
76
|
+
const parsed = JSON.parse(trimmed);
|
|
77
|
+
// Drop records that pre-date the projectId field or are malformed
|
|
78
|
+
// beyond recovery — keeping them would block the flush forever
|
|
79
|
+
// since they cannot be addressed to a project.
|
|
80
|
+
if (typeof parsed.projectId === 'string' && parsed.projectId) {
|
|
81
|
+
records.push(parsed);
|
|
82
|
+
}
|
|
67
83
|
}
|
|
68
84
|
catch {
|
|
69
|
-
// Corrupt line —
|
|
85
|
+
// Corrupt line — drop it
|
|
70
86
|
}
|
|
71
87
|
}
|
|
72
|
-
if (records.length === 0)
|
|
88
|
+
if (records.length === 0) {
|
|
89
|
+
// Nothing salvageable — clear the file so corrupt content doesn't
|
|
90
|
+
// grow unboundedly.
|
|
91
|
+
try {
|
|
92
|
+
writeFileSync(bufferFile, '', 'utf8');
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
// Best-effort
|
|
96
|
+
}
|
|
73
97
|
return;
|
|
98
|
+
}
|
|
99
|
+
// Group by projectId, preserving original insertion order within each group.
|
|
100
|
+
const groups = new Map();
|
|
101
|
+
for (const r of records) {
|
|
102
|
+
const arr = groups.get(r.projectId);
|
|
103
|
+
if (arr)
|
|
104
|
+
arr.push(r);
|
|
105
|
+
else
|
|
106
|
+
groups.set(r.projectId, [r]);
|
|
107
|
+
}
|
|
74
108
|
const BATCH_SIZE = 100;
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
109
|
+
const failed = [];
|
|
110
|
+
for (const [projectId, group] of groups) {
|
|
111
|
+
let groupFailed = false;
|
|
112
|
+
for (let i = 0; i < group.length; i += BATCH_SIZE) {
|
|
113
|
+
const batch = group.slice(i, i + BATCH_SIZE);
|
|
114
|
+
try {
|
|
115
|
+
await postFn(ctx, projectId, batch);
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
groupFailed = true;
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
79
121
|
}
|
|
80
|
-
|
|
81
|
-
|
|
122
|
+
if (groupFailed) {
|
|
123
|
+
failed.push(...group);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// Rewrite the file with only the failed groups (or wipe it on full success).
|
|
127
|
+
try {
|
|
128
|
+
if (failed.length === 0) {
|
|
82
129
|
writeFileSync(bufferFile, '', 'utf8');
|
|
83
130
|
}
|
|
84
|
-
|
|
85
|
-
|
|
131
|
+
else {
|
|
132
|
+
const serialised = failed.map((r) => JSON.stringify(r)).join('\n') + '\n';
|
|
133
|
+
writeFileSync(bufferFile, serialised, 'utf8');
|
|
86
134
|
}
|
|
87
135
|
}
|
|
88
136
|
catch {
|
|
89
|
-
//
|
|
137
|
+
// Best-effort — if we can't rewrite, the worst case is that successful
|
|
138
|
+
// groups are re-flushed on the next attempt (the API push is idempotent
|
|
139
|
+
// at the (project_id, rule_id, target_hash, session_id) level).
|
|
90
140
|
}
|
|
91
141
|
}
|
|
92
142
|
return { bufferViolation, flushViolations };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guard-violations-buffer.js","sourceRoot":"","sources":["../../../src/hooks/runtime/guard-violations-buffer.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"guard-violations-buffer.js","sourceRoot":"","sources":["../../../src/hooks/runtime/guard-violations-buffer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Throttled, opt-out background self-update check. Runs once per session
|
|
3
|
+
* from the SessionStart hook. RETURNS a one-line notice to fold into the
|
|
4
|
+
* bootstrap body (or null) — it never writes to stdout itself (the caller
|
|
5
|
+
* emits once, so Codex's JSON envelope stays intact). Side effects: writes
|
|
6
|
+
* the throttle stamp and, when an update is due + enabled for a global
|
|
7
|
+
* install, spawns a DETACHED wrapper that runs the package-manager update
|
|
8
|
+
* and records the outcome to last-update.log.
|
|
9
|
+
*
|
|
10
|
+
* Source of truth: the npm registry (`/<pkg>/latest`). No gateway call.
|
|
11
|
+
*/
|
|
12
|
+
import { spawn } from 'node:child_process';
|
|
13
|
+
import { existsSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
14
|
+
import { homedir } from 'node:os';
|
|
15
|
+
import { join } from 'node:path';
|
|
16
|
+
import { ensureDirFor } from '../../utils.js';
|
|
17
|
+
import { isNewer } from './semver.js';
|
|
18
|
+
import { detectInstallMode, resolveScriptPath, GLOBAL_MODES, } from '../../self-update.js';
|
|
19
|
+
const PACKAGE_NAME = '@cybedefend/vibedefend';
|
|
20
|
+
const REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;
|
|
21
|
+
const THROTTLE_MS = 24 * 60 * 60 * 1000;
|
|
22
|
+
const FETCH_TIMEOUT_MS = 3000;
|
|
23
|
+
export async function selfUpdateCheck(deps) {
|
|
24
|
+
const now = deps.now ?? (() => Date.now());
|
|
25
|
+
const dir = deps.cybeDir ?? join(process.env.CYBEDEFEND_HOME ?? homedir(), '.cybedefend');
|
|
26
|
+
const throttlePath = join(dir, 'update-check.json');
|
|
27
|
+
const logPath = join(dir, 'last-update.log');
|
|
28
|
+
// Derive the install mode from the stable global runner path
|
|
29
|
+
// (`runnerSource`) when available — NOT from `resolveScriptPath()`, which at
|
|
30
|
+
// runtime returns the shim (`~/.cybedefend/hook-runner.js` → `'unknown'`,
|
|
31
|
+
// never a global mode, so the background update would never spawn).
|
|
32
|
+
const installMode = deps.installMode ??
|
|
33
|
+
(deps.runnerSource
|
|
34
|
+
? detectInstallMode(deps.runnerSource)
|
|
35
|
+
: detectInstallMode(resolveScriptPath()));
|
|
36
|
+
// Read + consume last-update.log (a prior background update's outcome),
|
|
37
|
+
// regardless of throttle — surface a failure as soon as possible.
|
|
38
|
+
const priorFailure = takeUpdateLogNotice(logPath);
|
|
39
|
+
const throttle = readThrottle(throttlePath);
|
|
40
|
+
if (throttle && now() - throttle.lastCheckedAt < THROTTLE_MS) {
|
|
41
|
+
return priorFailure;
|
|
42
|
+
}
|
|
43
|
+
const fetchLatest = deps.fetchLatest ?? defaultFetchLatest;
|
|
44
|
+
const latest = await fetchLatest();
|
|
45
|
+
// Stamp the check time regardless of fetch outcome so a flaky registry
|
|
46
|
+
// doesn't make every session hammer npm.
|
|
47
|
+
writeThrottle(throttlePath, { lastCheckedAt: now() });
|
|
48
|
+
if (!latest || !isNewer(latest, deps.installedVersion)) {
|
|
49
|
+
return priorFailure;
|
|
50
|
+
}
|
|
51
|
+
const updateNotice = applyOrNotify(deps, installMode, latest, logPath);
|
|
52
|
+
// Surface BOTH signals when present: a prior failure (its log was already
|
|
53
|
+
// consumed on read) AND the new pending update. They're independent.
|
|
54
|
+
return [priorFailure, updateNotice].filter(Boolean).join('\n') || null;
|
|
55
|
+
}
|
|
56
|
+
function applyOrNotify(deps, installMode, latest, logPath) {
|
|
57
|
+
const from = deps.installedVersion;
|
|
58
|
+
if (!deps.autoUpdate || !GLOBAL_MODES.has(installMode)) {
|
|
59
|
+
return `\u{1F6E1}️ vibedefend ${from} → ${latest} available — run \`vibedefend update --self\` to upgrade.`;
|
|
60
|
+
}
|
|
61
|
+
const spawnUpdate = deps.spawnUpdate ?? defaultSpawnUpdate;
|
|
62
|
+
spawnUpdate({
|
|
63
|
+
mode: installMode,
|
|
64
|
+
spec: `${PACKAGE_NAME}@${latest}`,
|
|
65
|
+
logPath,
|
|
66
|
+
from,
|
|
67
|
+
to: latest,
|
|
68
|
+
});
|
|
69
|
+
return `\u{1F6E1}️ vibedefend: updating in background ${from} → ${latest} (active next session).`;
|
|
70
|
+
}
|
|
71
|
+
function readThrottle(path) {
|
|
72
|
+
try {
|
|
73
|
+
if (!existsSync(path))
|
|
74
|
+
return null;
|
|
75
|
+
const data = JSON.parse(readFileSync(path, 'utf8'));
|
|
76
|
+
if (typeof data.lastCheckedAt !== 'number')
|
|
77
|
+
return null;
|
|
78
|
+
return { lastCheckedAt: data.lastCheckedAt };
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function writeThrottle(path, throttle) {
|
|
85
|
+
try {
|
|
86
|
+
ensureDirFor(path);
|
|
87
|
+
writeFileSync(path, JSON.stringify(throttle) + '\n');
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
/* best-effort */
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Read and CONSUME last-update.log (the prior background update's outcome).
|
|
95
|
+
* The log is always deleted on read — a failure is surfaced once, a stale
|
|
96
|
+
* success (or garbage) is simply dropped so it can't accumulate or re-nag.
|
|
97
|
+
* Returns a one-line notice only when the prior update failed.
|
|
98
|
+
*/
|
|
99
|
+
function takeUpdateLogNotice(logPath) {
|
|
100
|
+
try {
|
|
101
|
+
if (!existsSync(logPath))
|
|
102
|
+
return null;
|
|
103
|
+
let parsed = {};
|
|
104
|
+
try {
|
|
105
|
+
parsed = JSON.parse(readFileSync(logPath, 'utf8'));
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
parsed = {};
|
|
109
|
+
}
|
|
110
|
+
rmSync(logPath, { force: true }); // consume once, whatever the content
|
|
111
|
+
if (typeof parsed.exitCode === 'number' && parsed.exitCode !== 0) {
|
|
112
|
+
return `⚠ vibedefend: last auto-update to ${parsed.to ?? 'latest'} failed (exit ${parsed.exitCode}) — run \`vibedefend update --self\`.`;
|
|
113
|
+
}
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
async function defaultFetchLatest() {
|
|
121
|
+
try {
|
|
122
|
+
const res = await fetch(REGISTRY_URL, {
|
|
123
|
+
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
|
|
124
|
+
});
|
|
125
|
+
if (!res.ok)
|
|
126
|
+
return null;
|
|
127
|
+
const body = (await res.json());
|
|
128
|
+
return typeof body.version === 'string' ? body.version : null;
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Build the `node -e` wrapper script that runs the package-manager update and
|
|
136
|
+
* records the outcome (`{ from, to, exitCode, finishedAt }`) to last-update.log.
|
|
137
|
+
* Exported for tests. `shell: process.platform === 'win32'` so the
|
|
138
|
+
* `npm`/`pnpm`/`yarn` `.cmd` shims resolve on Windows; POSIX resolves the
|
|
139
|
+
* binaries directly (no shell layer). `node -e` runs as CommonJS, so `require`
|
|
140
|
+
* is available.
|
|
141
|
+
*/
|
|
142
|
+
export function buildUpdateWrapperScript(args) {
|
|
143
|
+
return `
|
|
144
|
+
const { spawnSync } = require('node:child_process');
|
|
145
|
+
const { writeFileSync } = require('node:fs');
|
|
146
|
+
const r = spawnSync(${JSON.stringify(args.pm)}, ${JSON.stringify(args.pmArgs)}, {
|
|
147
|
+
stdio: 'ignore',
|
|
148
|
+
shell: process.platform === 'win32',
|
|
149
|
+
});
|
|
150
|
+
try {
|
|
151
|
+
writeFileSync(${JSON.stringify(args.logPath)}, JSON.stringify({
|
|
152
|
+
from: ${JSON.stringify(args.from)},
|
|
153
|
+
to: ${JSON.stringify(args.to)},
|
|
154
|
+
exitCode: r.status == null ? 1 : r.status,
|
|
155
|
+
finishedAt: Date.now(),
|
|
156
|
+
}) + "\\n");
|
|
157
|
+
} catch {}
|
|
158
|
+
`;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Spawn a DETACHED, unref'd wrapper that runs the package-manager update and
|
|
162
|
+
* records its outcome. `windowsHide` prevents a console window flashing on
|
|
163
|
+
* Windows.
|
|
164
|
+
*/
|
|
165
|
+
function defaultSpawnUpdate(args) {
|
|
166
|
+
const { pm, pmArgs } = pmCommand(args.mode, args.spec);
|
|
167
|
+
const script = buildUpdateWrapperScript({
|
|
168
|
+
pm,
|
|
169
|
+
pmArgs,
|
|
170
|
+
logPath: args.logPath,
|
|
171
|
+
from: args.from,
|
|
172
|
+
to: args.to,
|
|
173
|
+
});
|
|
174
|
+
try {
|
|
175
|
+
const child = spawn(process.execPath, ['-e', script], {
|
|
176
|
+
detached: true,
|
|
177
|
+
stdio: 'ignore',
|
|
178
|
+
windowsHide: true,
|
|
179
|
+
});
|
|
180
|
+
child.unref();
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
/* best-effort — failure is invisible; the 24h retry covers it */
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
function pmCommand(mode, spec) {
|
|
187
|
+
switch (mode) {
|
|
188
|
+
case 'pnpm-global':
|
|
189
|
+
return { pm: 'pnpm', pmArgs: ['add', '-g', spec] };
|
|
190
|
+
case 'yarn-global':
|
|
191
|
+
return { pm: 'yarn', pmArgs: ['global', 'add', spec] };
|
|
192
|
+
default:
|
|
193
|
+
return { pm: 'npm', pmArgs: ['install', '-g', spec] };
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=self-update-check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"self-update-check.js","sourceRoot":"","sources":["../../../src/hooks/runtime/self-update-check.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal semver comparison for `x.y.z` version strings — no dependency,
|
|
3
|
+
* the CLI ships only what it needs. Tolerant: a leading `v` is stripped,
|
|
4
|
+
* prerelease/build suffixes are ignored, and any missing or non-numeric
|
|
5
|
+
* segment counts as 0, so a malformed input never throws (it simply
|
|
6
|
+
* compares as a low version).
|
|
7
|
+
*/
|
|
8
|
+
export function parseVersion(input) {
|
|
9
|
+
const cleaned = input.trim().replace(/^v/i, '');
|
|
10
|
+
const core = cleaned.split('-')[0].split('+')[0];
|
|
11
|
+
const parts = core.split('.');
|
|
12
|
+
const seg = (i) => {
|
|
13
|
+
const v = Number.parseInt(parts[i] ?? '0', 10);
|
|
14
|
+
return Number.isFinite(v) && v >= 0 ? v : 0;
|
|
15
|
+
};
|
|
16
|
+
return [seg(0), seg(1), seg(2)];
|
|
17
|
+
}
|
|
18
|
+
/** -1 if a<b, 0 if equal, 1 if a>b — by major, then minor, then patch. */
|
|
19
|
+
export function compareVersions(a, b) {
|
|
20
|
+
const pa = parseVersion(a);
|
|
21
|
+
const pb = parseVersion(b);
|
|
22
|
+
for (let i = 0; i < 3; i++) {
|
|
23
|
+
if (pa[i] < pb[i])
|
|
24
|
+
return -1;
|
|
25
|
+
if (pa[i] > pb[i])
|
|
26
|
+
return 1;
|
|
27
|
+
}
|
|
28
|
+
return 0;
|
|
29
|
+
}
|
|
30
|
+
/** True iff `latest` is strictly newer than `current`. */
|
|
31
|
+
export function isNewer(latest, current) {
|
|
32
|
+
return compareVersions(latest, current) > 0;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=semver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semver.js","sourceRoot":"","sources":["../../../src/hooks/runtime/semver.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAChD,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9B,MAAM,GAAG,GAAG,CAAC,CAAS,EAAU,EAAE;QAChC,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;QAC/C,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,CAAC,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAClC,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,eAAe,CAAC,CAAS,EAAE,CAAS;IAClD,MAAM,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;IAC3B,MAAM,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;IAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC,CAAC;QAC7B,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,OAAO,CAAC,MAAc,EAAE,OAAe;IACrD,OAAO,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;AAC9C,CAAC"}
|