fullcourtdefense-cli 1.17.1 → 1.18.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.
@@ -35,7 +35,6 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.discoverCommand = discoverCommand;
37
37
  exports.runDiscoverUpload = runDiscoverUpload;
38
- const crypto = __importStar(require("crypto"));
39
38
  const fs = __importStar(require("fs"));
40
39
  const os = __importStar(require("os"));
41
40
  const path = __importStar(require("path"));
@@ -52,6 +51,7 @@ const discoverBlastRadius_1 = require("./discoverBlastRadius");
52
51
  const discoverSecrets_1 = require("./discoverSecrets");
53
52
  const windowsAudit_1 = require("./windowsAudit");
54
53
  const discoveryMarker_1 = require("../discoveryMarker");
54
+ const machineIdentity_1 = require("../machineIdentity");
55
55
  const DEFAULT_API_URL = 'https://api.fullcourtdefense.ai';
56
56
  function parseSurfaces(args) {
57
57
  const raw = (args.surface || args.type || 'mcp').toLowerCase().trim();
@@ -93,9 +93,17 @@ function redactCommandArgs(args) {
93
93
  }
94
94
  return out;
95
95
  }
96
+ /**
97
+ * The SAME stable hardware id used at enrollment (MachineGuid / IOPlatformUUID
98
+ * / machine-id, sha256 → 32 hex chars). Discovery uploads MUST carry this id:
99
+ * the fleet console attaches scan evidence to the enrolled machine strictly by
100
+ * machineId, so a divergent id here makes the machine page show "Never
101
+ * scanned" while the data sits under a ghost host record. (Pre-1.18 releases
102
+ * hashed hostname+username into a 16-char fingerprint — the backend still
103
+ * recognizes those as legacy and matches them by hostname.)
104
+ */
96
105
  function machineFingerprint() {
97
- const seed = [os.hostname(), os.userInfo().username, os.platform(), os.arch()].join('|');
98
- return crypto.createHash('sha256').update(seed).digest('hex').slice(0, 16);
106
+ return (0, machineIdentity_1.getMachineIdentity)().machineId;
99
107
  }
100
108
  /** Detect ephemeral CI runners so they are never listed as user machines in the fleet. */
101
109
  function isCiEnvironment() {
@@ -613,6 +621,8 @@ function proxyStatusLabel(status) {
613
621
  return 'Proxied';
614
622
  if (status === 'direct')
615
623
  return 'Direct — needs gateway';
624
+ if (status === 'reference')
625
+ return 'Reference config — not loaded by any AI client';
616
626
  return 'Unknown';
617
627
  }
618
628
  function sanitizeSecretForUpload(finding) {
@@ -1036,7 +1046,9 @@ async function discoverCommand(args, config) {
1036
1046
  console.log('');
1037
1047
  if (clientCoverage.length > 0) {
1038
1048
  for (const row of clientCoverage) {
1039
- const gateway = row.mcpGatewayInstalled ? `${COLOR.green}gateway ✓${COLOR.reset}` : `${COLOR.red}no gateway${COLOR.reset}`;
1049
+ const gateway = (0, discoverProxy_1.isReferenceConfigSource)(row.client)
1050
+ ? `${COLOR.gray}reference only — not loaded by any AI client${COLOR.reset}`
1051
+ : row.mcpGatewayInstalled ? `${COLOR.green}gateway ✓${COLOR.reset}` : `${COLOR.red}no gateway${COLOR.reset}`;
1040
1052
  console.log(` ${COLOR.dim}•${COLOR.reset} ${row.client} — ${row.mcpServerCount} MCP · ${gateway}`);
1041
1053
  }
1042
1054
  console.log('');
@@ -1,4 +1,5 @@
1
- export type DesktopProxyStatus = 'fcd_gateway' | 'proxied' | 'direct' | 'unknown';
1
+ export type DesktopProxyStatus = 'fcd_gateway' | 'proxied' | 'direct' | 'reference' | 'unknown';
2
+ export declare function isReferenceConfigSource(source: string): boolean;
2
3
  export declare const FCD_GATEWAY_SERVER_NAMES: Set<string>;
3
4
  export declare const FCD_HOOK_MARKER = "--fcd-managed true";
4
5
  export declare const FCD_HOOK_TAG = "fullcourtdefense";
@@ -34,6 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.FCD_HOOK_TAG = exports.FCD_HOOK_MARKER = exports.FCD_GATEWAY_SERVER_NAMES = void 0;
37
+ exports.isReferenceConfigSource = isReferenceConfigSource;
37
38
  exports.isFcdGatewayServer = isFcdGatewayServer;
38
39
  exports.extractGatewayDownstream = extractGatewayDownstream;
39
40
  exports.buildGatewayWrapIndex = buildGatewayWrapIndex;
@@ -44,6 +45,18 @@ exports.buildClientCoverage = buildClientCoverage;
44
45
  const fs = __importStar(require("fs"));
45
46
  const os = __importStar(require("os"));
46
47
  const path = __importStar(require("path"));
48
+ /**
49
+ * Config sources that no AI client actually loads. A plain `mcp.json` at a
50
+ * repo root is documentation/sample material — Cursor, Claude Code, VS Code,
51
+ * Windsurf, etc. all read their own dot-folder configs, never this file.
52
+ * Servers found there are inventory-worthy (they show what a repo references)
53
+ * but are not live attack surface, so they classify as 'reference' instead of
54
+ * 'direct' and must never count toward the machine's exposed status.
55
+ */
56
+ const REFERENCE_CONFIG_SOURCES = new Set(['Repo (mcp.json)']);
57
+ function isReferenceConfigSource(source) {
58
+ return REFERENCE_CONFIG_SOURCES.has(source);
59
+ }
47
60
  exports.FCD_GATEWAY_SERVER_NAMES = new Set([
48
61
  'agentguard-gateway',
49
62
  'fullcourtdefense-gateway',
@@ -157,6 +170,8 @@ function buildGatewayWrapIndex(servers) {
157
170
  return wrapsByConfig;
158
171
  }
159
172
  function classifyProxyStatus(server, wrapsByConfig) {
173
+ if (isReferenceConfigSource(server.source))
174
+ return 'reference';
160
175
  if (isFcdGatewayServer(server))
161
176
  return 'fcd_gateway';
162
177
  const wrapped = wrapsByConfig.get(server.configPath.toLowerCase());
package/dist/version.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "1.17.1"
2
+ "version": "1.18.0"
3
3
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fullcourtdefense-cli",
3
- "version": "1.17.1",
3
+ "version": "1.18.0",
4
4
  "description": "Full Court Defense CLI — security scanning for AI agents from your terminal",
5
5
  "main": "dist/index.js",
6
6
  "bin": {