@imdeadpool/guardex 7.0.20 → 7.0.22

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/src/context.js CHANGED
@@ -71,7 +71,7 @@ const REQUIRED_SYSTEM_TOOLS = [
71
71
  },
72
72
  ];
73
73
  const MAINTAINER_RELEASE_REPO = path.resolve(
74
- process.env.GUARDEX_RELEASE_REPO || path.resolve(PACKAGE_ROOT),
74
+ process.env.GUARDEX_RELEASE_REPO || PACKAGE_ROOT,
75
75
  );
76
76
  const NPM_BIN = process.env.GUARDEX_NPM_BIN || 'npm';
77
77
  const OPENSPEC_BIN = process.env.GUARDEX_OPENSPEC_BIN || 'openspec';
@@ -242,13 +242,24 @@ const GITIGNORE_MARKER_START = '# multiagent-safety:START';
242
242
  const GITIGNORE_MARKER_END = '# multiagent-safety:END';
243
243
  const CODEX_WORKTREE_RELATIVE_DIR = path.join('.omx', 'agent-worktrees');
244
244
  const CLAUDE_WORKTREE_RELATIVE_DIR = path.join('.omc', 'agent-worktrees');
245
+ const SHARED_VSCODE_SETTINGS_RELATIVE = path.posix.join('.vscode', 'settings.json');
246
+ const REPO_SCAN_IGNORED_FOLDERS_SETTING = 'git.repositoryScanIgnoredFolders';
245
247
  const AGENT_WORKTREE_RELATIVE_DIRS = [
246
248
  CODEX_WORKTREE_RELATIVE_DIR,
247
249
  CLAUDE_WORKTREE_RELATIVE_DIR,
248
250
  ];
251
+ const MANAGED_REPO_SCAN_IGNORED_FOLDERS = [
252
+ '.omx/agent-worktrees',
253
+ '**/.omx/agent-worktrees',
254
+ '.omc/agent-worktrees',
255
+ '**/.omc/agent-worktrees',
256
+ ];
249
257
  const MANAGED_GITIGNORE_PATHS = [
250
258
  '.omx/',
251
259
  '.omc/',
260
+ '!.vscode/',
261
+ '.vscode/*',
262
+ '!.vscode/settings.json',
252
263
  'scripts/agent-session-state.js',
253
264
  'scripts/guardex-docker-loader.sh',
254
265
  'scripts/guardex-env.sh',
@@ -322,8 +333,8 @@ const SUGGESTIBLE_COMMANDS = [
322
333
  ];
323
334
  const CLI_COMMAND_DESCRIPTIONS = [
324
335
  ['status', 'Show GitGuardex CLI + service health without modifying files'],
325
- ['setup', 'Install, repair, and verify guardrails (flags: --repair, --install-only, --target)'],
326
- ['doctor', 'Repair drift + verify (auto-sandboxes on protected main)'],
336
+ ['setup', 'Install, repair, and verify guardrails (flags: --repair, --install-only, --target, --current)'],
337
+ ['doctor', 'Repair drift + verify (flags: --target, --current; auto-sandboxes on protected main)'],
327
338
  ['branch', 'CLI-owned branch workflow surface (start/finish/merge)'],
328
339
  ['locks', 'CLI-owned file lock surface (claim/allow-delete/release/status/validate)'],
329
340
  ['worktree', 'CLI-owned worktree cleanup surface (prune)'],
@@ -337,7 +348,7 @@ const CLI_COMMAND_DESCRIPTIONS = [
337
348
  ['cleanup', 'Prune merged/stale agent branches and worktrees'],
338
349
  ['release', 'Create or update the current GitHub release with README-generated notes'],
339
350
  ['agents', 'Start/stop repo-scoped review + cleanup bots'],
340
- ['prompt', 'Print AI setup checklist (--exec, --snippet)'],
351
+ ['prompt', 'Print AI setup checklist or named slices (--exec, --part, --list-parts, --snippet)'],
341
352
  ['report', 'Security/safety reports (e.g. OpenSSF scorecard)'],
342
353
  ['help', 'Show this help output'],
343
354
  ['version', 'Print GitGuardex version'],
@@ -358,6 +369,12 @@ const AGENT_BOT_DESCRIPTIONS = [
358
369
  const DOCTOR_AUTO_FINISH_DETAIL_LIMIT = 6;
359
370
  const DOCTOR_AUTO_FINISH_BRANCH_LABEL_MAX = 72;
360
371
  const DOCTOR_AUTO_FINISH_MESSAGE_MAX = 160;
372
+ const AI_SETUP_PART_ALIASES = new Map([
373
+ ['task', 'task-loop'],
374
+ ['loop', 'task-loop'],
375
+ ['reviewbot', 'review-bot'],
376
+ ['forksync', 'fork-sync'],
377
+ ]);
361
378
 
362
379
  function envFlagIsTruthy(raw) {
363
380
  const lowered = String(raw || '').trim().toLowerCase();
@@ -372,35 +389,176 @@ function defaultAgentWorktreeRelativeDir(env = process.env) {
372
389
  return isClaudeCodeSession(env) ? CLAUDE_WORKTREE_RELATIVE_DIR : CODEX_WORKTREE_RELATIVE_DIR;
373
390
  }
374
391
 
375
- const AI_SETUP_PROMPT = `GitGuardex (gx) setup checklist for Codex/Claude in this repo.
376
-
377
- 1) Install: ${GLOBAL_INSTALL_COMMAND} && gh --version
378
- 2) Bootstrap: gx setup
379
- 3) Repair: gx doctor
380
- 4) Task loop: gx branch start "<task>" "<agent>"
381
- then gx locks claim --branch "<agent-branch>" <file...> -> gx branch finish
382
- 5) Integrate: gx merge --branch <agent-a> --branch <agent-b>
383
- 6) Finish: gx finish --all
384
- 7) Cleanup: gx cleanup
385
- 8) OpenSpec: /opsx:propose -> /opsx:apply -> /opsx:archive
386
- 9) Optional: gx protect add release staging
387
- 10) Optional: gx sync --check && gx sync
388
- 11) Review bot: install https://github.com/apps/cr-gpt + set OPENAI_API_KEY
389
- 12) Fork sync: install https://github.com/apps/pull + cp .github/pull.yml.example .github/pull.yml
390
- `;
391
-
392
- const AI_SETUP_COMMANDS = `${GLOBAL_INSTALL_COMMAND}
393
- gh --version
394
- gx setup
395
- gx doctor
396
- gx branch start "<task>" "<agent>"
397
- gx locks claim --branch "<agent-branch>" <file...>
398
- gx merge --branch "<agent-a>" --branch "<agent-b>"
399
- gx finish --all
400
- gx cleanup
401
- gx protect add release staging
402
- gx sync --check && gx sync
403
- `;
392
+ const AI_SETUP_PARTS = [
393
+ {
394
+ name: 'install',
395
+ label: 'Install',
396
+ promptLines: [`${GLOBAL_INSTALL_COMMAND} && gh --version`],
397
+ execLines: [GLOBAL_INSTALL_COMMAND, 'gh --version'],
398
+ },
399
+ {
400
+ name: 'bootstrap',
401
+ label: 'Bootstrap',
402
+ promptLines: ['gx setup'],
403
+ execLines: ['gx setup'],
404
+ },
405
+ {
406
+ name: 'repair',
407
+ label: 'Repair',
408
+ promptLines: ['gx doctor'],
409
+ execLines: ['gx doctor'],
410
+ },
411
+ {
412
+ name: 'task-loop',
413
+ label: 'Task loop',
414
+ promptLines: [
415
+ 'gx branch start "<task>" "<agent>"',
416
+ 'then gx locks claim --branch "<agent-branch>" <file...> -> gx branch finish',
417
+ ],
418
+ execLines: [
419
+ 'gx branch start "<task>" "<agent>"',
420
+ 'gx locks claim --branch "<agent-branch>" <file...>',
421
+ ],
422
+ },
423
+ {
424
+ name: 'integrate',
425
+ label: 'Integrate',
426
+ promptLines: ['gx merge --branch <agent-a> --branch <agent-b>'],
427
+ execLines: ['gx merge --branch <agent-a> --branch <agent-b>'],
428
+ },
429
+ {
430
+ name: 'finish',
431
+ label: 'Finish',
432
+ promptLines: ['gx finish --all'],
433
+ execLines: ['gx finish --all'],
434
+ },
435
+ {
436
+ name: 'cleanup',
437
+ label: 'Cleanup',
438
+ promptLines: ['gx cleanup'],
439
+ execLines: ['gx cleanup'],
440
+ },
441
+ {
442
+ name: 'openspec',
443
+ label: 'OpenSpec',
444
+ promptLines: ['/opsx:propose -> /opsx:apply -> /opsx:archive'],
445
+ },
446
+ {
447
+ name: 'protect',
448
+ label: 'Protect',
449
+ promptLines: ['gx protect add release staging'],
450
+ execLines: ['gx protect add release staging'],
451
+ },
452
+ {
453
+ name: 'sync',
454
+ label: 'Sync',
455
+ promptLines: ['gx sync --check && gx sync'],
456
+ execLines: ['gx sync --check && gx sync'],
457
+ },
458
+ {
459
+ name: 'review-bot',
460
+ label: 'Review bot',
461
+ promptLines: ['install https://github.com/apps/cr-gpt + set OPENAI_API_KEY'],
462
+ },
463
+ {
464
+ name: 'fork-sync',
465
+ label: 'Fork sync',
466
+ promptLines: ['install https://github.com/apps/pull + cp .github/pull.yml.example .github/pull.yml'],
467
+ },
468
+ ];
469
+ const AI_SETUP_PARTS_BY_NAME = new Map(AI_SETUP_PARTS.map((part) => [part.name, part]));
470
+ const AI_SETUP_EXEC_PART_NAMES = AI_SETUP_PARTS
471
+ .filter((part) => Array.isArray(part.execLines))
472
+ .map((part) => part.name);
473
+
474
+ function normalizeAiSetupPartName(rawName) {
475
+ const normalized = String(rawName || '')
476
+ .trim()
477
+ .toLowerCase()
478
+ .replace(/_/g, '-');
479
+ return AI_SETUP_PART_ALIASES.get(normalized) || normalized;
480
+ }
481
+
482
+ function listAiSetupPartNames(options = {}) {
483
+ if (!options.execOnly) return AI_SETUP_PARTS.map((part) => part.name);
484
+ return AI_SETUP_EXEC_PART_NAMES.slice();
485
+ }
486
+
487
+ function parseAiSetupPartNames(rawValue) {
488
+ return String(rawValue || '')
489
+ .split(',')
490
+ .map((entry) => normalizeAiSetupPartName(entry))
491
+ .filter(Boolean);
492
+ }
493
+
494
+ function resolveAiSetupParts(rawPartNames, options = {}) {
495
+ const exec = Boolean(options.exec);
496
+ const requestedPartNames = Array.isArray(rawPartNames) ? rawPartNames : [];
497
+ const availablePartNames = listAiSetupPartNames();
498
+ const execCapablePartNames = listAiSetupPartNames({ execOnly: true });
499
+ const seen = new Set();
500
+ const resolved = [];
501
+
502
+ for (const rawName of requestedPartNames) {
503
+ const name = normalizeAiSetupPartName(rawName);
504
+ const part = AI_SETUP_PARTS_BY_NAME.get(name);
505
+ if (!part) {
506
+ throw new Error(
507
+ `Unknown prompt part: ${rawName}. Available parts: ${availablePartNames.join(', ')}`,
508
+ );
509
+ }
510
+ if (exec && !Array.isArray(part.execLines)) {
511
+ throw new Error(
512
+ `Prompt part '${name}' is not available with --exec. ` +
513
+ `Exec-capable parts: ${execCapablePartNames.join(', ')}`,
514
+ );
515
+ }
516
+ if (seen.has(name)) continue;
517
+ seen.add(name);
518
+ resolved.push(part);
519
+ }
520
+
521
+ return resolved;
522
+ }
523
+
524
+ function renderFullAiSetupPrompt() {
525
+ const lines = ['GitGuardex (gx) setup checklist for Codex/Claude in this repo.', ''];
526
+ const indentWidth = 18;
527
+
528
+ AI_SETUP_PARTS.forEach((part, index) => {
529
+ const [lead, ...tail] = part.promptLines;
530
+ const prefix = `${index + 1}) ${part.label}:`;
531
+ lines.push(`${prefix.padEnd(indentWidth)}${lead}`);
532
+ tail.forEach((line) => lines.push(`${' '.repeat(indentWidth)}${line}`));
533
+ });
534
+
535
+ return `${lines.join('\n')}\n`;
536
+ }
537
+
538
+ function renderPartialAiSetupPrompt(parts) {
539
+ return `${parts
540
+ .map((part) => `${part.label}:\n${part.promptLines.join('\n')}`)
541
+ .join('\n\n')}\n`;
542
+ }
543
+
544
+ function renderAiSetupCommands(parts) {
545
+ return `${parts.flatMap((part) => part.execLines).join('\n')}\n`;
546
+ }
547
+
548
+ function renderAiSetupPrompt(options = {}) {
549
+ const exec = Boolean(options.exec);
550
+ const requestedPartNames = Array.isArray(options.parts) ? options.parts : [];
551
+ if (requestedPartNames.length === 0) {
552
+ return exec
553
+ ? renderAiSetupCommands(resolveAiSetupParts(AI_SETUP_EXEC_PART_NAMES, { exec: true }))
554
+ : renderFullAiSetupPrompt();
555
+ }
556
+ const parts = resolveAiSetupParts(requestedPartNames, { exec });
557
+ return exec ? renderAiSetupCommands(parts) : renderPartialAiSetupPrompt(parts);
558
+ }
559
+
560
+ const AI_SETUP_PROMPT = renderAiSetupPrompt();
561
+ const AI_SETUP_COMMANDS = renderAiSetupPrompt({ exec: true });
404
562
 
405
563
  const SCORECARD_RISK_BY_CHECK = {
406
564
  'Dangerous-Workflow': 'Critical',
@@ -480,7 +638,10 @@ module.exports = {
480
638
  GITIGNORE_MARKER_END,
481
639
  CODEX_WORKTREE_RELATIVE_DIR,
482
640
  CLAUDE_WORKTREE_RELATIVE_DIR,
641
+ SHARED_VSCODE_SETTINGS_RELATIVE,
642
+ REPO_SCAN_IGNORED_FOLDERS_SETTING,
483
643
  AGENT_WORKTREE_RELATIVE_DIRS,
644
+ MANAGED_REPO_SCAN_IGNORED_FOLDERS,
484
645
  MANAGED_GITIGNORE_PATHS,
485
646
  REPO_SCAFFOLD_DIRECTORIES,
486
647
  OMX_SCAFFOLD_DIRECTORIES,
@@ -497,6 +658,9 @@ module.exports = {
497
658
  envFlagIsTruthy,
498
659
  isClaudeCodeSession,
499
660
  defaultAgentWorktreeRelativeDir,
661
+ listAiSetupPartNames,
662
+ parseAiSetupPartNames,
663
+ renderAiSetupPrompt,
500
664
  AI_SETUP_PROMPT,
501
665
  AI_SETUP_COMMANDS,
502
666
  SCORECARD_RISK_BY_CHECK,