codegate-ai 0.10.0 → 0.11.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 CHANGED
@@ -135,10 +135,12 @@ See the [Configuration](#configuration) section for full settings and examples.
135
135
  | `--force` | Skip interactive confirmations. |
136
136
  | `--include-user-scope` | Force-enable user/home AI tool config paths for this run (useful if config disables user-scope scanning). |
137
137
  | `--collect <mode>` | Collection scope mode (`default`, `project`, `user`, `explicit`, `all`). Repeatable. |
138
+ | `--collect-kind <kind>` | Restrict collection to specific artifact kinds (`workflows`, `actions`, `dependabot`). Repeatable. |
138
139
  | `--strict-collection` | Treat parse failures in collected inputs as high-severity findings. |
139
140
  | `--persona <type>` | Audit sensitivity (`regular`, `pedantic`, `auditor`). |
140
141
  | `--runtime-mode <mode>` | Runtime mode for optional online audits (`offline`, `online`, `online-no-audits`). |
141
142
  | `--workflow-audits` | Enable CI/CD audit pack for GitHub workflow, action, and Dependabot inputs. |
143
+ | `--skill <name>` | Select one skill directory when scanning a skills-index repo URL that contains multiple skills. |
142
144
  | `--reset-state` | Clear persisted scan-state history and exit. |
143
145
 
144
146
  Examples:
@@ -154,7 +156,9 @@ codegate scan . --remediate
154
156
  codegate scan . --fix-safe
155
157
  codegate scan . --remediate --dry-run --patch
156
158
  codegate scan . --workflow-audits --collect project --persona auditor --runtime-mode online
159
+ codegate scan . --workflow-audits --collect project --collect-kind workflows
157
160
  codegate scan . --workflow-audits --strict-collection
161
+ codegate scan https://github.com/owner/repo --skill security-review
158
162
  codegate scan . --reset-state
159
163
  ```
160
164
 
@@ -259,12 +263,27 @@ Behavior:
259
263
 
260
264
  Wrapper flags (consumed by CodeGate, not forwarded):
261
265
 
262
- - `--cg-force`
263
- - `--cg-deep`
264
- - `--cg-no-tui`
265
- - `--cg-include-user-scope`
266
- - `--cg-format <type>`
267
- - `--cg-config <path>`
266
+ | Flag | Purpose |
267
+ | -------------------------- | ----------------------------------------------------------------------------------------- |
268
+ | `--cg-force` | Continue install when preflight scan fails or returns blocking findings. |
269
+ | `--cg-deep` | Enable Layer 3 deep analysis during wrapper preflight scan. |
270
+ | `--cg-no-tui` | Disable TUI and interactive prompts for wrapper preflight scan. |
271
+ | `--cg-verbose` | Enable extended terminal output during wrapper preflight scan. |
272
+ | `--cg-include-user-scope` | Include user/home config surfaces in wrapper preflight scan. |
273
+ | `--cg-collect <mode>` | Preflight collection mode (`default`, `project`, `user`, `explicit`, `all`). Repeatable. |
274
+ | `--cg-collect-kind <kind>` | Preflight collection kind (`workflows`, `actions`, `dependabot`). Repeatable. |
275
+ | `--cg-strict-collection` | Treat parse failures in preflight-collected inputs as high-severity findings. |
276
+ | `--cg-persona <type>` | Preflight audit persona (`regular`, `pedantic`, `auditor`). |
277
+ | `--cg-runtime-mode <mode>` | Preflight runtime mode (`offline`, `online`, `online-no-audits`). |
278
+ | `--cg-workflow-audits` | Enable workflow audit pack for preflight scans. |
279
+ | `--cg-format <type>` | Set preflight output format: `terminal`, `json`, `sarif`, `markdown`, `html`. |
280
+ | `--cg-config <path>` | Use a specific CodeGate config file for wrapper preflight scan. |
281
+ | `--` | Stop wrapper-option parsing and pass all following args to the wrapped installer command. |
282
+
283
+ Inspect command help for complete usage:
284
+
285
+ - `codegate skills --help`
286
+ - `codegate clawhub --help`
268
287
 
269
288
  Examples:
270
289
 
@@ -272,9 +291,23 @@ Examples:
272
291
  codegate skills add https://github.com/vercel-labs/skills --skill find-skills
273
292
  codegate skills add https://github.com/owner/repo --skill security-review --cg-force
274
293
  codegate skills add https://github.com/owner/repo --skill security-review --cg-deep
294
+ codegate skills add https://github.com/owner/repo --skill security-review --cg-workflow-audits --cg-collect project
295
+ codegate skills add https://github.com/owner/repo --skill security-review --cg-collect-kind workflows
296
+ codegate skills add https://github.com/owner/repo --skill security-review --cg-strict-collection --cg-persona auditor
297
+ codegate skills add https://github.com/owner/repo --skill security-review --cg-runtime-mode online
298
+ codegate skills add https://github.com/owner/repo --skill security-review --cg-format json
299
+ codegate skills add https://github.com/owner/repo --skill security-review --cg-config ~/.codegate/config.json
300
+ codegate skills add https://github.com/owner/repo --skill security-review -- --registry custom
275
301
  codegate clawhub install security-auditor
276
302
  codegate clawhub install security-auditor --version 1.0.0
277
303
  codegate clawhub install security-auditor --cg-deep
304
+ codegate clawhub install security-auditor --cg-workflow-audits --cg-collect project
305
+ codegate clawhub install security-auditor --cg-collect-kind workflows
306
+ codegate clawhub install security-auditor --cg-strict-collection --cg-persona auditor
307
+ codegate clawhub install security-auditor --cg-runtime-mode online
308
+ codegate clawhub install security-auditor --cg-no-tui --cg-format json
309
+ codegate clawhub install security-auditor --cg-config ~/.codegate/config.json
310
+ codegate clawhub install security-auditor -- --registry https://registry.clawhub.ai
278
311
  codegate clawhub search security
279
312
  ```
280
313
 
package/dist/cli.js CHANGED
@@ -31,6 +31,26 @@ function isNoTuiEnabled(options) {
31
31
  function renderExampleHelp(lines) {
32
32
  return ["", "Examples:", ...lines.map((line) => ` ${line}`)].join("\n");
33
33
  }
34
+ function renderWrapperOptionsHelp() {
35
+ return [
36
+ "",
37
+ "CodeGate wrapper options (consumed by CodeGate, not forwarded to the wrapped CLI):",
38
+ " --cg-force continue install when preflight is warning/error",
39
+ " --cg-deep enable Layer 3 deep analysis during preflight",
40
+ " --cg-no-tui disable TUI and interactive prompts for preflight",
41
+ " --cg-verbose show extended terminal output during preflight",
42
+ " --cg-include-user-scope include user/home config paths in preflight scan",
43
+ " --cg-collect <mode> preflight collection mode (repeatable): default|project|user|explicit|all",
44
+ " --cg-collect-kind <kind> preflight collection kind (repeatable): workflows|actions|dependabot",
45
+ " --cg-strict-collection treat preflight parse failures as high severity",
46
+ " --cg-persona <type> preflight audit sensitivity: regular|pedantic|auditor",
47
+ " --cg-runtime-mode <mode> preflight runtime mode: offline|online|online-no-audits",
48
+ " --cg-workflow-audits enable workflow audit pack during preflight",
49
+ " --cg-format <type> preflight report format: terminal|json|sarif|markdown|html",
50
+ " --cg-config <path> use a specific CodeGate config file for preflight",
51
+ " -- pass subsequent args through to wrapped CLI unchanged",
52
+ ].join("\n");
53
+ }
34
54
  export function isDirectCliInvocation(importMetaUrl, argv1, deps = {}) {
35
55
  if (!argv1) {
36
56
  return false;
@@ -460,9 +480,11 @@ function addSkillsCommand(program, version, deps) {
460
480
  .description("Wrap npx skills with CodeGate preflight scanning for installs")
461
481
  .allowUnknownOption(true)
462
482
  .allowExcessArguments(true)
483
+ .addHelpText("after", renderWrapperOptionsHelp())
463
484
  .addHelpText("after", renderExampleHelp([
464
485
  "codegate skills add vercel-labs/skills --skill find-skills",
465
486
  "codegate skills add https://github.com/owner/repo --skill security-review",
487
+ "codegate skills add owner/repo --skill demo --cg-workflow-audits --cg-collect project",
466
488
  "codegate skills add owner/repo --skill demo --cg-deep",
467
489
  "codegate skills find security",
468
490
  "codegate skills add owner/repo --skill demo --cg-force",
@@ -504,9 +526,11 @@ function addClawhubCommand(program, version, deps) {
504
526
  .description("Wrap npx clawhub with CodeGate preflight scanning for installs")
505
527
  .allowUnknownOption(true)
506
528
  .allowExcessArguments(true)
529
+ .addHelpText("after", renderWrapperOptionsHelp())
507
530
  .addHelpText("after", renderExampleHelp([
508
531
  "codegate clawhub install security-auditor",
509
532
  "codegate clawhub install security-auditor --version 1.0.0",
533
+ "codegate clawhub install security-auditor --cg-workflow-audits --cg-collect project",
510
534
  "codegate clawhub install security-auditor --cg-deep",
511
535
  "codegate clawhub search security",
512
536
  "codegate clawhub install security-auditor --cg-force",
@@ -1,4 +1,4 @@
1
- import { type CodeGateConfig, type OutputFormat, type ResolveConfigOptions } from "../config.js";
1
+ import { type AuditPersona, type CodeGateConfig, type OutputFormat, type ResolveConfigOptions, type RuntimeMode, type ScanCollectionKind, type ScanCollectionMode } from "../config.js";
2
2
  import { type ResolvedScanTarget } from "../scan-target.js";
3
3
  import type { CodeGateReport } from "../types/report.js";
4
4
  import { type ScanAnalysisDeps, type ScanRunnerInput } from "./scan-command.js";
@@ -10,7 +10,14 @@ export interface ClawhubWrapperRuntimeOptions {
10
10
  force: boolean;
11
11
  deep: boolean;
12
12
  noTui: boolean;
13
+ verbose: boolean;
13
14
  includeUserScope: boolean;
15
+ strictCollection: boolean;
16
+ workflowAudits: boolean;
17
+ collect: ScanCollectionMode[];
18
+ collectKinds: ScanCollectionKind[];
19
+ persona?: AuditPersona;
20
+ runtimeMode?: RuntimeMode;
14
21
  format?: OutputFormat;
15
22
  configPath?: string;
16
23
  }
@@ -3,7 +3,7 @@ import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:
3
3
  import { tmpdir } from "node:os";
4
4
  import { dirname, join, resolve } from "node:path";
5
5
  import { createInterface } from "node:readline/promises";
6
- import { OUTPUT_FORMATS, } from "../config.js";
6
+ import { PERSONAS, RUNTIME_MODES, SCAN_COLLECTION_KINDS, SCAN_COLLECTION_MODES, OUTPUT_FORMATS, } from "../config.js";
7
7
  import { resolveScanTarget } from "../scan-target.js";
8
8
  import { runScanAnalysis } from "./scan-command.js";
9
9
  import { renderByFormat, summarizeRequestedTargetFindings } from "./scan-command/helpers.js";
@@ -40,6 +40,38 @@ function parseOutputFormat(value) {
40
40
  }
41
41
  return matched;
42
42
  }
43
+ function parseCollectionMode(value) {
44
+ const normalized = value.trim().toLowerCase();
45
+ const matched = SCAN_COLLECTION_MODES.find((mode) => mode === normalized);
46
+ if (!matched) {
47
+ throw new Error(`Unsupported --cg-collect value "${value}". Valid values: ${SCAN_COLLECTION_MODES.join(", ")}.`);
48
+ }
49
+ return matched;
50
+ }
51
+ function parseCollectionKind(value) {
52
+ const normalized = value.trim().toLowerCase();
53
+ const matched = SCAN_COLLECTION_KINDS.find((kind) => kind === normalized);
54
+ if (!matched) {
55
+ throw new Error(`Unsupported --cg-collect-kind value "${value}". Valid values: ${SCAN_COLLECTION_KINDS.join(", ")}.`);
56
+ }
57
+ return matched;
58
+ }
59
+ function parsePersona(value) {
60
+ const normalized = value.trim().toLowerCase();
61
+ const matched = PERSONAS.find((persona) => persona === normalized);
62
+ if (!matched) {
63
+ throw new Error(`Unsupported --cg-persona value "${value}". Valid values: ${PERSONAS.join(", ")}.`);
64
+ }
65
+ return matched;
66
+ }
67
+ function parseRuntimeMode(value) {
68
+ const normalized = value.trim().toLowerCase();
69
+ const matched = RUNTIME_MODES.find((mode) => mode === normalized);
70
+ if (!matched) {
71
+ throw new Error(`Unsupported --cg-runtime-mode value "${value}". Valid values: ${RUNTIME_MODES.join(", ")}.`);
72
+ }
73
+ return matched;
74
+ }
43
75
  function isLikelyHttpUrl(value) {
44
76
  return /^https?:\/\//iu.test(value);
45
77
  }
@@ -383,7 +415,14 @@ export function parseClawhubInvocation(rawArgs, context) {
383
415
  force: false,
384
416
  deep: false,
385
417
  noTui: false,
418
+ verbose: false,
386
419
  includeUserScope: false,
420
+ strictCollection: false,
421
+ workflowAudits: false,
422
+ collect: [],
423
+ collectKinds: [],
424
+ persona: undefined,
425
+ runtimeMode: undefined,
387
426
  format: undefined,
388
427
  configPath: undefined,
389
428
  };
@@ -409,10 +448,22 @@ export function parseClawhubInvocation(rawArgs, context) {
409
448
  wrapper.noTui = true;
410
449
  continue;
411
450
  }
451
+ if (token === "--cg-verbose") {
452
+ wrapper.verbose = true;
453
+ continue;
454
+ }
412
455
  if (token === "--cg-include-user-scope") {
413
456
  wrapper.includeUserScope = true;
414
457
  continue;
415
458
  }
459
+ if (token === "--cg-strict-collection") {
460
+ wrapper.strictCollection = true;
461
+ continue;
462
+ }
463
+ if (token === "--cg-workflow-audits") {
464
+ wrapper.workflowAudits = true;
465
+ continue;
466
+ }
416
467
  if (token === "--cg-format" || token.startsWith("--cg-format=")) {
417
468
  const [value, consumedIndex] = parseWrapperOptionValue(rawArgs, index, "--cg-format");
418
469
  wrapper.format = parseOutputFormat(value);
@@ -425,6 +476,36 @@ export function parseClawhubInvocation(rawArgs, context) {
425
476
  index = consumedIndex;
426
477
  continue;
427
478
  }
479
+ if (token === "--cg-collect" || token.startsWith("--cg-collect=")) {
480
+ const [value, consumedIndex] = parseWrapperOptionValue(rawArgs, index, "--cg-collect");
481
+ const mode = parseCollectionMode(value);
482
+ if (!wrapper.collect.includes(mode)) {
483
+ wrapper.collect.push(mode);
484
+ }
485
+ index = consumedIndex;
486
+ continue;
487
+ }
488
+ if (token === "--cg-collect-kind" || token.startsWith("--cg-collect-kind=")) {
489
+ const [value, consumedIndex] = parseWrapperOptionValue(rawArgs, index, "--cg-collect-kind");
490
+ const kind = parseCollectionKind(value);
491
+ if (!wrapper.collectKinds.includes(kind)) {
492
+ wrapper.collectKinds.push(kind);
493
+ }
494
+ index = consumedIndex;
495
+ continue;
496
+ }
497
+ if (token === "--cg-persona" || token.startsWith("--cg-persona=")) {
498
+ const [value, consumedIndex] = parseWrapperOptionValue(rawArgs, index, "--cg-persona");
499
+ wrapper.persona = parsePersona(value);
500
+ index = consumedIndex;
501
+ continue;
502
+ }
503
+ if (token === "--cg-runtime-mode" || token.startsWith("--cg-runtime-mode=")) {
504
+ const [value, consumedIndex] = parseWrapperOptionValue(rawArgs, index, "--cg-runtime-mode");
505
+ wrapper.runtimeMode = parseRuntimeMode(value);
506
+ index = consumedIndex;
507
+ continue;
508
+ }
428
509
  if (token.startsWith("--cg-")) {
429
510
  throw new Error(`Unknown CodeGate wrapper option: ${token}`);
430
511
  }
@@ -529,9 +610,24 @@ export async function executeClawhubWrapper(input, deps) {
529
610
  scanTarget: resolvedTarget.scanTarget,
530
611
  cli: cliConfig,
531
612
  });
532
- const config = parsed.wrapper.includeUserScope
533
- ? { ...baseConfig, scan_user_scope: true }
534
- : baseConfig;
613
+ const config = {
614
+ ...baseConfig,
615
+ scan_user_scope: parsed.wrapper.includeUserScope === true ? true : (baseConfig.scan_user_scope ?? false),
616
+ scan_collection_modes: parsed.wrapper.collect.length > 0
617
+ ? parsed.wrapper.collect
618
+ : baseConfig.scan_collection_modes,
619
+ scan_collection_kinds: parsed.wrapper.collectKinds.length > 0
620
+ ? parsed.wrapper.collectKinds
621
+ : baseConfig.scan_collection_kinds,
622
+ strict_collection: parsed.wrapper.strictCollection === true ? true : (baseConfig.strict_collection ?? false),
623
+ persona: parsed.wrapper.persona ?? baseConfig.persona,
624
+ runtime_mode: parsed.wrapper.runtimeMode ?? baseConfig.runtime_mode,
625
+ workflow_audits: {
626
+ enabled: parsed.wrapper.workflowAudits === true
627
+ ? true
628
+ : (baseConfig.workflow_audits?.enabled ?? false),
629
+ },
630
+ };
535
631
  const { report, deepScanNotes } = await runScanAnalysis({
536
632
  version: input.version,
537
633
  scanTarget: resolvedTarget.scanTarget,
@@ -541,8 +637,14 @@ export async function executeClawhubWrapper(input, deps) {
541
637
  options: {
542
638
  noTui,
543
639
  format: parsed.wrapper.format,
640
+ verbose: parsed.wrapper.verbose,
544
641
  force: parsed.wrapper.force,
545
642
  includeUserScope: parsed.wrapper.includeUserScope,
643
+ collect: parsed.wrapper.collect.length > 0 ? parsed.wrapper.collect : undefined,
644
+ strictCollection: parsed.wrapper.strictCollection,
645
+ persona: parsed.wrapper.persona,
646
+ runtimeMode: parsed.wrapper.runtimeMode,
647
+ workflowAudits: parsed.wrapper.workflowAudits,
546
648
  deep: parsed.wrapper.deep,
547
649
  },
548
650
  }, {
@@ -1,4 +1,4 @@
1
- import { type CodeGateConfig, type OutputFormat, type ResolveConfigOptions } from "../config.js";
1
+ import { type AuditPersona, type CodeGateConfig, type OutputFormat, type ResolveConfigOptions, type RuntimeMode, type ScanCollectionKind, type ScanCollectionMode } from "../config.js";
2
2
  import { type ResolvedScanTarget } from "../scan-target.js";
3
3
  import { type ScanAnalysisDeps, type ScanRunnerInput } from "./scan-command.js";
4
4
  import type { CodeGateReport } from "../types/report.js";
@@ -6,7 +6,14 @@ export interface SkillsWrapperRuntimeOptions {
6
6
  force: boolean;
7
7
  deep: boolean;
8
8
  noTui: boolean;
9
+ verbose: boolean;
9
10
  includeUserScope: boolean;
11
+ strictCollection: boolean;
12
+ workflowAudits: boolean;
13
+ collect: ScanCollectionMode[];
14
+ collectKinds: ScanCollectionKind[];
15
+ persona?: AuditPersona;
16
+ runtimeMode?: RuntimeMode;
10
17
  format?: OutputFormat;
11
18
  configPath?: string;
12
19
  }
@@ -2,7 +2,7 @@ import { spawnSync } from "node:child_process";
2
2
  import { existsSync } from "node:fs";
3
3
  import { createInterface } from "node:readline/promises";
4
4
  import { resolve } from "node:path";
5
- import { OUTPUT_FORMATS, } from "../config.js";
5
+ import { PERSONAS, RUNTIME_MODES, SCAN_COLLECTION_KINDS, SCAN_COLLECTION_MODES, OUTPUT_FORMATS, } from "../config.js";
6
6
  import { renderByFormat, summarizeRequestedTargetFindings } from "./scan-command/helpers.js";
7
7
  import { resolveScanTarget } from "../scan-target.js";
8
8
  import { runScanAnalysis } from "./scan-command.js";
@@ -33,6 +33,38 @@ function parseOutputFormat(value) {
33
33
  }
34
34
  return matched;
35
35
  }
36
+ function parseCollectionMode(value) {
37
+ const normalized = value.trim().toLowerCase();
38
+ const matched = SCAN_COLLECTION_MODES.find((mode) => mode === normalized);
39
+ if (!matched) {
40
+ throw new Error(`Unsupported --cg-collect value "${value}". Valid values: ${SCAN_COLLECTION_MODES.join(", ")}.`);
41
+ }
42
+ return matched;
43
+ }
44
+ function parseCollectionKind(value) {
45
+ const normalized = value.trim().toLowerCase();
46
+ const matched = SCAN_COLLECTION_KINDS.find((kind) => kind === normalized);
47
+ if (!matched) {
48
+ throw new Error(`Unsupported --cg-collect-kind value "${value}". Valid values: ${SCAN_COLLECTION_KINDS.join(", ")}.`);
49
+ }
50
+ return matched;
51
+ }
52
+ function parsePersona(value) {
53
+ const normalized = value.trim().toLowerCase();
54
+ const matched = PERSONAS.find((persona) => persona === normalized);
55
+ if (!matched) {
56
+ throw new Error(`Unsupported --cg-persona value "${value}". Valid values: ${PERSONAS.join(", ")}.`);
57
+ }
58
+ return matched;
59
+ }
60
+ function parseRuntimeMode(value) {
61
+ const normalized = value.trim().toLowerCase();
62
+ const matched = RUNTIME_MODES.find((mode) => mode === normalized);
63
+ if (!matched) {
64
+ throw new Error(`Unsupported --cg-runtime-mode value "${value}". Valid values: ${RUNTIME_MODES.join(", ")}.`);
65
+ }
66
+ return matched;
67
+ }
36
68
  function isLikelyGitSshSource(value) {
37
69
  return /^git@[^:]+:.+/iu.test(value) || /^ssh:\/\//iu.test(value);
38
70
  }
@@ -179,7 +211,14 @@ export function parseSkillsInvocation(rawArgs, context) {
179
211
  force: false,
180
212
  deep: false,
181
213
  noTui: false,
214
+ verbose: false,
182
215
  includeUserScope: false,
216
+ strictCollection: false,
217
+ workflowAudits: false,
218
+ collect: [],
219
+ collectKinds: [],
220
+ persona: undefined,
221
+ runtimeMode: undefined,
183
222
  format: undefined,
184
223
  configPath: undefined,
185
224
  };
@@ -205,10 +244,22 @@ export function parseSkillsInvocation(rawArgs, context) {
205
244
  wrapper.noTui = true;
206
245
  continue;
207
246
  }
247
+ if (token === "--cg-verbose") {
248
+ wrapper.verbose = true;
249
+ continue;
250
+ }
208
251
  if (token === "--cg-include-user-scope") {
209
252
  wrapper.includeUserScope = true;
210
253
  continue;
211
254
  }
255
+ if (token === "--cg-strict-collection") {
256
+ wrapper.strictCollection = true;
257
+ continue;
258
+ }
259
+ if (token === "--cg-workflow-audits") {
260
+ wrapper.workflowAudits = true;
261
+ continue;
262
+ }
212
263
  if (token === "--cg-format" || token.startsWith("--cg-format=")) {
213
264
  const [value, consumedIndex] = parseWrapperOptionValue(rawArgs, index, "--cg-format");
214
265
  wrapper.format = parseOutputFormat(value);
@@ -221,6 +272,36 @@ export function parseSkillsInvocation(rawArgs, context) {
221
272
  index = consumedIndex;
222
273
  continue;
223
274
  }
275
+ if (token === "--cg-collect" || token.startsWith("--cg-collect=")) {
276
+ const [value, consumedIndex] = parseWrapperOptionValue(rawArgs, index, "--cg-collect");
277
+ const mode = parseCollectionMode(value);
278
+ if (!wrapper.collect.includes(mode)) {
279
+ wrapper.collect.push(mode);
280
+ }
281
+ index = consumedIndex;
282
+ continue;
283
+ }
284
+ if (token === "--cg-collect-kind" || token.startsWith("--cg-collect-kind=")) {
285
+ const [value, consumedIndex] = parseWrapperOptionValue(rawArgs, index, "--cg-collect-kind");
286
+ const kind = parseCollectionKind(value);
287
+ if (!wrapper.collectKinds.includes(kind)) {
288
+ wrapper.collectKinds.push(kind);
289
+ }
290
+ index = consumedIndex;
291
+ continue;
292
+ }
293
+ if (token === "--cg-persona" || token.startsWith("--cg-persona=")) {
294
+ const [value, consumedIndex] = parseWrapperOptionValue(rawArgs, index, "--cg-persona");
295
+ wrapper.persona = parsePersona(value);
296
+ index = consumedIndex;
297
+ continue;
298
+ }
299
+ if (token === "--cg-runtime-mode" || token.startsWith("--cg-runtime-mode=")) {
300
+ const [value, consumedIndex] = parseWrapperOptionValue(rawArgs, index, "--cg-runtime-mode");
301
+ wrapper.runtimeMode = parseRuntimeMode(value);
302
+ index = consumedIndex;
303
+ continue;
304
+ }
224
305
  if (token.startsWith("--cg-")) {
225
306
  throw new Error(`Unknown CodeGate wrapper option: ${token}`);
226
307
  }
@@ -322,9 +403,24 @@ export async function executeSkillsWrapper(input, deps) {
322
403
  scanTarget: resolvedTarget.scanTarget,
323
404
  cli: cliConfig,
324
405
  });
325
- const config = parsed.wrapper.includeUserScope
326
- ? { ...baseConfig, scan_user_scope: true }
327
- : baseConfig;
406
+ const config = {
407
+ ...baseConfig,
408
+ scan_user_scope: parsed.wrapper.includeUserScope === true ? true : (baseConfig.scan_user_scope ?? false),
409
+ scan_collection_modes: parsed.wrapper.collect.length > 0
410
+ ? parsed.wrapper.collect
411
+ : baseConfig.scan_collection_modes,
412
+ scan_collection_kinds: parsed.wrapper.collectKinds.length > 0
413
+ ? parsed.wrapper.collectKinds
414
+ : baseConfig.scan_collection_kinds,
415
+ strict_collection: parsed.wrapper.strictCollection === true ? true : (baseConfig.strict_collection ?? false),
416
+ persona: parsed.wrapper.persona ?? baseConfig.persona,
417
+ runtime_mode: parsed.wrapper.runtimeMode ?? baseConfig.runtime_mode,
418
+ workflow_audits: {
419
+ enabled: parsed.wrapper.workflowAudits === true
420
+ ? true
421
+ : (baseConfig.workflow_audits?.enabled ?? false),
422
+ },
423
+ };
328
424
  const { report, deepScanNotes } = await runScanAnalysis({
329
425
  version: input.version,
330
426
  scanTarget: resolvedTarget.scanTarget,
@@ -334,8 +430,14 @@ export async function executeSkillsWrapper(input, deps) {
334
430
  options: {
335
431
  noTui,
336
432
  format: parsed.wrapper.format,
433
+ verbose: parsed.wrapper.verbose,
337
434
  force: parsed.wrapper.force,
338
435
  includeUserScope: parsed.wrapper.includeUserScope,
436
+ collect: parsed.wrapper.collect.length > 0 ? parsed.wrapper.collect : undefined,
437
+ strictCollection: parsed.wrapper.strictCollection,
438
+ persona: parsed.wrapper.persona,
439
+ runtimeMode: parsed.wrapper.runtimeMode,
440
+ workflowAudits: parsed.wrapper.workflowAudits,
339
441
  skill: preferredSkill,
340
442
  deep: parsed.wrapper.deep,
341
443
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codegate-ai",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "description": "Pre-flight security scanner for AI coding tool configurations.",
5
5
  "license": "MIT",
6
6
  "type": "module",