fullcourtdefense-cli 1.21.35 → 1.21.36

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.
@@ -19,11 +19,17 @@ export declare function uninstallCmdGuardCommand(): Promise<void>;
19
19
  /** Refresh shared rules JSON when cmd guard is installed. */
20
20
  export declare function refreshCmdGuardRules(): void;
21
21
  /**
22
- * Self-heal a stale cmd-guard AutoRun: if the registry still references our
23
- * autorun script but the file was deleted (manual cleanup, interrupted
24
- * uninstall), EVERY cmd.exe on the machine errors on startup and — worse —
25
- * poisons `cmd /c` exit codes to 1, making healthy installs/commands look
26
- * failed. Strips only OUR fragment; a customer's own AutoRun entries survive.
27
- * Returns true when a repair was applied.
22
+ * Self-heal a stale/broken cmd-guard AutoRun. Two failure shapes are covered:
23
+ *
24
+ * 1. Registry references our autorun bat but the FILE was deleted (manual
25
+ * cleanup, interrupted uninstall) — every cmd.exe errors on startup and
26
+ * poisons `cmd /c` exit codes to 1.
27
+ * 2. The bat EXISTS but its doskey macros point at a node.exe or checker
28
+ * script that no longer exists (uninstall/upgrade removed the install
29
+ * root but left the per-user bat) — every wrapped command (docker, git,
30
+ * kubectl, …) fails with "cannot find the path specified".
31
+ *
32
+ * In both cases: strip OUR fragment from AutoRun (a customer's own entries
33
+ * survive) and delete our orphaned guard files. Returns true when repaired.
28
34
  */
29
35
  export declare function repairStaleCmdAutorun(): boolean;
@@ -142,6 +142,11 @@ function buildAutorunBat(nodePath) {
142
142
  'REM Remove permanently: fullcourtdefense uninstall-cmd-guard',
143
143
  'if defined FCD_CMD_AUTORUN_DONE goto :eof',
144
144
  'set FCD_CMD_AUTORUN_DONE=1',
145
+ // FAIL OPEN: if the runtime or checker is gone (uninstall/upgrade left this
146
+ // bat behind), register NO macros — wrapped commands (docker, git, kubectl…)
147
+ // must keep working natively. Never break the customer's tools.
148
+ `if not exist ${node} goto :eof`,
149
+ `if not exist ${guardJs} goto :eof`,
145
150
  ...doskeyLines,
146
151
  '',
147
152
  ].join('\r\n');
@@ -266,12 +271,26 @@ function refreshCmdGuardRules() {
266
271
  catch { /* best-effort */ }
267
272
  }
268
273
  /**
269
- * Self-heal a stale cmd-guard AutoRun: if the registry still references our
270
- * autorun script but the file was deleted (manual cleanup, interrupted
271
- * uninstall), EVERY cmd.exe on the machine errors on startup and — worse —
272
- * poisons `cmd /c` exit codes to 1, making healthy installs/commands look
273
- * failed. Strips only OUR fragment; a customer's own AutoRun entries survive.
274
- * Returns true when a repair was applied.
274
+ * The node.exe path baked into an installed autorun bat's doskey macros.
275
+ * Format written by buildAutorunBat: `doskey <cmd>="<node>" "<guardJs>" <cmd> $*`.
276
+ */
277
+ function autorunBatNodePath(batContent) {
278
+ const match = batContent.match(/^doskey\s+\S+="([^"]+)"\s/m);
279
+ return match ? match[1] : undefined;
280
+ }
281
+ /**
282
+ * Self-heal a stale/broken cmd-guard AutoRun. Two failure shapes are covered:
283
+ *
284
+ * 1. Registry references our autorun bat but the FILE was deleted (manual
285
+ * cleanup, interrupted uninstall) — every cmd.exe errors on startup and
286
+ * poisons `cmd /c` exit codes to 1.
287
+ * 2. The bat EXISTS but its doskey macros point at a node.exe or checker
288
+ * script that no longer exists (uninstall/upgrade removed the install
289
+ * root but left the per-user bat) — every wrapped command (docker, git,
290
+ * kubectl, …) fails with "cannot find the path specified".
291
+ *
292
+ * In both cases: strip OUR fragment from AutoRun (a customer's own entries
293
+ * survive) and delete our orphaned guard files. Returns true when repaired.
275
294
  */
276
295
  function repairStaleCmdAutorun() {
277
296
  try {
@@ -280,8 +299,20 @@ function repairStaleCmdAutorun() {
280
299
  const current = readCurrentAutorun();
281
300
  if (!current.includes(AUTORUN_MARKER))
282
301
  return false;
283
- if (fs.existsSync(AUTORUN_BAT_PATH))
284
- return false;
302
+ if (fs.existsSync(AUTORUN_BAT_PATH)) {
303
+ // Bat present — only stale when its macro targets are gone.
304
+ let bat = '';
305
+ try {
306
+ bat = fs.readFileSync(AUTORUN_BAT_PATH, 'utf8');
307
+ }
308
+ catch {
309
+ return false;
310
+ }
311
+ const nodePath = autorunBatNodePath(bat);
312
+ const runtimeAlive = (!nodePath || fs.existsSync(nodePath)) && fs.existsSync(GUARD_JS_PATH);
313
+ if (runtimeAlive)
314
+ return false;
315
+ }
285
316
  const next = stripAutorunValue(current);
286
317
  if (next) {
287
318
  setRegString(CMD_AUTORUN_KEY, AUTORUN_VALUE, next);
@@ -291,6 +322,14 @@ function repairStaleCmdAutorun() {
291
322
  windowsHide: true, timeout: 10000, stdio: ['ignore', 'pipe', 'ignore'],
292
323
  });
293
324
  }
325
+ try {
326
+ fs.unlinkSync(AUTORUN_BAT_PATH);
327
+ }
328
+ catch { /* already gone */ }
329
+ try {
330
+ fs.unlinkSync(GUARD_JS_PATH);
331
+ }
332
+ catch { /* already gone */ }
294
333
  return true;
295
334
  }
296
335
  catch {
@@ -63,6 +63,7 @@ const integrity_1 = require("../integrity");
63
63
  const machineIdentity_1 = require("../machineIdentity");
64
64
  const discoveryMarker_1 = require("../discoveryMarker");
65
65
  const selfUpdate_1 = require("../selfUpdate");
66
+ const cmdGuard_1 = require("./cmdGuard");
66
67
  const machineActionVerify_1 = require("../machineActionVerify");
67
68
  const desktopChatGuard_1 = require("./desktopChatGuard");
68
69
  const honeypot_1 = require("../honeypot");
@@ -1032,6 +1033,11 @@ async function runDaemon(args, config) {
1032
1033
  // Converge pre-Node-updater machines onto the PowerShell-free updater task
1033
1034
  // (best-effort; needs an elevated daemon to rewrite a SYSTEM task).
1034
1035
  (0, selfUpdate_1.modernizeUpdaterTask)(log);
1036
+ // Heal a stale/broken cmd-guard AutoRun (bat deleted, or macros pointing at
1037
+ // a dead node.exe) so wrapped commands (docker, git, …) never stay broken.
1038
+ if ((0, cmdGuard_1.repairStaleCmdAutorun)()) {
1039
+ log('Repaired a stale cmd.exe AutoRun / doskey guard left by an earlier install.');
1040
+ }
1035
1041
  const watched = refreshWatchTargets();
1036
1042
  log(`Watching ${watched} config file(s) across ${watchers.size} director${watchers.size === 1 ? 'y' : 'ies'}.`);
1037
1043
  // First: if this boot IS the post-upgrade relaunch, confirm the pending
package/dist/version.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "1.21.35"
2
+ "version": "1.21.36"
3
3
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fullcourtdefense-cli",
3
- "version": "1.21.35",
3
+ "version": "1.21.36",
4
4
  "description": "Full Court Defense CLI — security scanning for AI agents from your terminal",
5
5
  "main": "dist/index.js",
6
6
  "bin": {