fullcourtdefense-cli 1.7.18 → 1.7.20

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.
@@ -3,6 +3,7 @@ export interface AgentCiArgs {
3
3
  failOn?: string;
4
4
  format?: string;
5
5
  upload?: string;
6
+ requireUpload?: string;
6
7
  requireGateway?: string;
7
8
  requireApprovalFor?: string;
8
9
  extraPath?: string;
@@ -268,6 +268,20 @@ function printSummary(report, failed, failOn) {
268
268
  if (report.findings.length > 20)
269
269
  console.log(`... and ${report.findings.length - 20} more findings`);
270
270
  }
271
+ function buildCiMetadata() {
272
+ return {
273
+ provider: process.env.GITHUB_ACTIONS === 'true' ? 'github_actions' : process.env.CI ? 'ci' : undefined,
274
+ repository: process.env.GITHUB_REPOSITORY,
275
+ ref: process.env.GITHUB_REF_NAME || process.env.GITHUB_HEAD_REF || process.env.GITHUB_REF,
276
+ sha: process.env.GITHUB_SHA,
277
+ runId: process.env.GITHUB_RUN_ID,
278
+ runUrl: process.env.GITHUB_SERVER_URL && process.env.GITHUB_REPOSITORY && process.env.GITHUB_RUN_ID
279
+ ? `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`
280
+ : undefined,
281
+ workflow: process.env.GITHUB_WORKFLOW,
282
+ job: process.env.GITHUB_JOB,
283
+ };
284
+ }
271
285
  async function agentCiCommand(args, config) {
272
286
  const failOn = (['critical', 'high', 'medium', 'low'].includes(String(args.failOn || '').toLowerCase())
273
287
  ? String(args.failOn).toLowerCase()
@@ -286,16 +300,45 @@ async function agentCiCommand(args, config) {
286
300
  else {
287
301
  printSummary(report, failed, failOn);
288
302
  }
289
- if (args.upload === 'true') {
303
+ const uploadRequested = args.upload === 'true' || args.requireUpload === 'true';
304
+ if (uploadRequested) {
290
305
  const creds = (0, config_1.resolveCliCredentials)(config, { apiKey: args.apiKey, apiUrl: args.apiUrl });
291
306
  if (creds.apiKey || (creds.shieldId && creds.shieldKey)) {
292
- await (0, discover_1.runDiscoverUpload)({ apiKey: args.apiKey, apiUrl: args.apiUrl, silent: true }, config).catch(error => {
293
- if (format === 'summary')
294
- console.error(`Upload skipped: ${error instanceof Error ? error.message : String(error)}`);
295
- });
307
+ try {
308
+ await (0, discover_1.runDiscoverUpload)({
309
+ apiKey: args.apiKey,
310
+ apiUrl: args.apiUrl,
311
+ silent: true,
312
+ connectorName: `Agent CI Gate${process.env.GITHUB_REPOSITORY ? ` · ${process.env.GITHUB_REPOSITORY}` : ''}`,
313
+ agentCiGate: {
314
+ status: failed ? 'fail' : 'pass',
315
+ score: report.score,
316
+ failOn,
317
+ findings: report.findings,
318
+ mcpServers: report.mcpServers.map(server => ({
319
+ name: server.name,
320
+ source: server.source,
321
+ filePath: server.filePath,
322
+ direct: server.direct,
323
+ protectedGateway: server.protectedGateway,
324
+ riskSignals: server.riskSignals,
325
+ })),
326
+ uploadedAt: new Date().toISOString(),
327
+ ci: buildCiMetadata(),
328
+ },
329
+ }, config);
330
+ console.error('AgentGuard evidence upload: uploaded to AI Fleet / discovery posture inventory.');
331
+ }
332
+ catch (error) {
333
+ console.error(`AgentGuard evidence upload: failed (${error instanceof Error ? error.message : String(error)})`);
334
+ if (args.requireUpload === 'true')
335
+ process.exit(1);
336
+ }
296
337
  }
297
- else if (format === 'summary') {
298
- console.error('Upload skipped: run fullcourtdefense login first or pass --api-key.');
338
+ else {
339
+ console.error('AgentGuard evidence upload: missing credentials. Run fullcourtdefense login or pass FULLCOURTDEFENSE_API_KEY.');
340
+ if (args.requireUpload === 'true')
341
+ process.exit(1);
299
342
  }
300
343
  }
301
344
  if (failed)
@@ -8,6 +8,7 @@ export interface DiscoverArgs {
8
8
  json?: string;
9
9
  upload?: string;
10
10
  connectorName?: string;
11
+ agentCiGate?: AgentCiGateUpload;
11
12
  extraPath?: string;
12
13
  deep?: string;
13
14
  silent?: string;
@@ -16,6 +17,39 @@ export interface DiscoverArgs {
16
17
  unschedule?: string;
17
18
  scheduleHour?: string;
18
19
  }
20
+ export interface AgentCiGateUpload {
21
+ status: 'pass' | 'fail';
22
+ score: number;
23
+ failOn: string;
24
+ findings: Array<{
25
+ id: string;
26
+ severity: string;
27
+ category: string;
28
+ title: string;
29
+ detail: string;
30
+ filePath?: string;
31
+ remediation: string;
32
+ }>;
33
+ mcpServers: Array<{
34
+ name: string;
35
+ source: string;
36
+ filePath: string;
37
+ direct: boolean;
38
+ protectedGateway: boolean;
39
+ riskSignals: string[];
40
+ }>;
41
+ uploadedAt: string;
42
+ ci?: {
43
+ provider?: string;
44
+ repository?: string;
45
+ ref?: string;
46
+ sha?: string;
47
+ runId?: string;
48
+ runUrl?: string;
49
+ workflow?: string;
50
+ job?: string;
51
+ };
52
+ }
19
53
  export interface DesktopDiscoveryHost {
20
54
  machineId: string;
21
55
  hostname: string;
@@ -32,4 +66,5 @@ export declare function runDiscoverUpload(args: {
32
66
  userEmail?: string;
33
67
  silent?: boolean;
34
68
  connectorName?: string;
69
+ agentCiGate?: AgentCiGateUpload;
35
70
  }, config: BotGuardConfig): Promise<void>;
@@ -511,6 +511,11 @@ async function upload(servers, host, clientCoverage, apiUrl, auth, connectorName
511
511
  } : undefined,
512
512
  secrets: extras?.secrets?.findings.slice(0, 100).map(sanitizeSecretForUpload),
513
513
  agentFiles: extras?.agentFiles?.slice(0, 100).map(sanitizeAgentFileForUpload),
514
+ agentCiGate: extras?.agentCiGate ? {
515
+ ...extras.agentCiGate,
516
+ findings: extras.agentCiGate.findings.slice(0, 100),
517
+ mcpServers: extras.agentCiGate.mcpServers.slice(0, 100),
518
+ } : undefined,
514
519
  scanScope: extras?.scanScope,
515
520
  servers: servers.map(s => ({
516
521
  serverName: s.serverName,
@@ -697,6 +702,7 @@ async function discoverCommand(args, config) {
697
702
  secrets,
698
703
  agentFiles,
699
704
  posture,
705
+ agentCiGate: args.agentCiGate,
700
706
  scanScope: {
701
707
  surfaces: [...surfaces],
702
708
  workingDirectory: cwd,
@@ -807,5 +813,6 @@ async function runDiscoverUpload(args, config) {
807
813
  apiUrl: args.apiUrl,
808
814
  userEmail: args.userEmail,
809
815
  connectorName: args.connectorName,
816
+ agentCiGate: args.agentCiGate,
810
817
  }, config);
811
818
  }
package/dist/index.js CHANGED
@@ -264,6 +264,7 @@ function printHelp() {
264
264
  --fail-on <severity> agent-ci fail threshold: critical, high, medium, low
265
265
  --require-gateway agent-ci requires risky MCP servers to use FCD gateway
266
266
  --require-approval-for agent-ci risky controls list, e.g. payment,delete,shell,secrets
267
+ --require-upload agent-ci fails if evidence cannot upload to AgentGuard UI
267
268
  --method <GET|POST> Local endpoint method
268
269
  --request-format <fmt> Local endpoint request format: custom or openai
269
270
  --auth-type <type> none, bearer, basic, api-key
@@ -502,6 +503,7 @@ async function main() {
502
503
  failOn: flags['fail-on'],
503
504
  format: flags.format,
504
505
  upload: flags.upload,
506
+ requireUpload: flags['require-upload'],
505
507
  requireGateway: flags['require-gateway'],
506
508
  requireApprovalFor: flags['require-approval-for'],
507
509
  extraPath: flags.path,
package/dist/version.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "1.7.18"
2
+ "version": "1.7.20"
3
3
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fullcourtdefense-cli",
3
- "version": "1.7.18",
3
+ "version": "1.7.20",
4
4
  "description": "Full Court Defense CLI — security scanning for AI agents from your terminal",
5
5
  "main": "dist/index.js",
6
6
  "bin": {