@imdeadpool/guardex 5.0.4 → 5.0.5

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
@@ -238,6 +238,10 @@ npm pack --dry-run
238
238
 
239
239
  ## Release notes
240
240
 
241
+ ### v5.0.5
242
+
243
+ - Bumped package version from `5.0.4` to `5.0.5` so npm publish can proceed with the next patch release.
244
+
241
245
  ### v5.0.4
242
246
 
243
247
  - Bumped package version from `5.0.3` to `5.0.4` to stay one patch ahead of the current npm published version.
@@ -147,6 +147,10 @@ const CLI_COMMAND_DESCRIPTIONS = [
147
147
  ['help', 'Show this help output'],
148
148
  ['version', 'Print GuardeX version'],
149
149
  ];
150
+ const AGENT_BOT_DESCRIPTIONS = [
151
+ ['review', 'Monitor open PRs targeting current branch and dispatch codex-agent review flow'],
152
+ ['start', 'bash scripts/review-bot-watch.sh --interval 30'],
153
+ ];
150
154
 
151
155
  const AI_SETUP_PROMPT = `Use this exact checklist to setup GuardeX (Guardian T-Rex for your repo) in this repository for Codex or Claude.
152
156
 
@@ -261,9 +265,20 @@ function commandCatalogLines(indent = ' ') {
261
265
  );
262
266
  }
263
267
 
268
+ function agentBotCatalogLines(indent = ' ') {
269
+ const maxCommandLength = AGENT_BOT_DESCRIPTIONS.reduce(
270
+ (max, [command]) => Math.max(max, command.length),
271
+ 0,
272
+ );
273
+ return AGENT_BOT_DESCRIPTIONS.map(
274
+ ([command, description]) => `${indent}${command.padEnd(maxCommandLength + 2)}${description}`,
275
+ );
276
+ }
277
+
264
278
  function printToolLogsSummary() {
265
279
  const usageLine = ` $ ${SHORT_TOOL_NAME} <command> [options]`;
266
280
  const commandDetails = commandCatalogLines(' ');
281
+ const agentBotDetails = agentBotCatalogLines(' ');
267
282
 
268
283
  if (!supportsAnsiColors()) {
269
284
  console.log(`${TOOL_NAME}-tools logs:`);
@@ -273,12 +288,17 @@ function printToolLogsSummary() {
273
288
  for (const line of commandDetails) {
274
289
  console.log(line);
275
290
  }
291
+ console.log(' AGENT BOT');
292
+ for (const line of agentBotDetails) {
293
+ console.log(line);
294
+ }
276
295
  return;
277
296
  }
278
297
 
279
298
  const title = colorize(`${TOOL_NAME}-tools logs`, '1;36');
280
299
  const usageHeader = colorize('USAGE', '1');
281
300
  const commandsHeader = colorize('COMMANDS', '1');
301
+ const agentBotHeader = colorize('AGENT BOT', '1');
282
302
  const pipe = colorize('│', '90');
283
303
  const tee = colorize('├', '90');
284
304
  const corner = colorize('└', '90');
@@ -294,6 +314,14 @@ function printToolLogsSummary() {
294
314
  }
295
315
  console.log(` ${pipe}${line.slice(2)}`);
296
316
  }
317
+ console.log(` ${tee}─ ${agentBotHeader}`);
318
+ for (const line of agentBotDetails) {
319
+ if (!line) {
320
+ console.log(` ${pipe}`);
321
+ continue;
322
+ }
323
+ console.log(` ${pipe}${line.slice(2)}`);
324
+ }
297
325
  console.log(` ${corner}─ ${colorize(`Try '${TOOL_NAME} doctor' for one-step repair + verification.`, '2')}`);
298
326
  }
299
327
 
@@ -311,6 +339,9 @@ USAGE
311
339
  COMMANDS
312
340
  ${commandCatalogLines().join('\n')}
313
341
 
342
+ AGENT BOT
343
+ ${agentBotCatalogLines().join('\n')}
344
+
314
345
  NOTES
315
346
  - Running ${TOOL_NAME} with no command defaults to: ${SHORT_TOOL_NAME} status
316
347
  - Short alias: ${SHORT_TOOL_NAME}
@@ -1499,6 +1530,88 @@ function uniquePreserveOrder(items) {
1499
1530
  return result;
1500
1531
  }
1501
1532
 
1533
+ function readConfiguredProtectedBranches(repoRoot) {
1534
+ const result = gitRun(repoRoot, ['config', '--get', GIT_PROTECTED_BRANCHES_KEY], { allowFailure: true });
1535
+ if (result.status !== 0) {
1536
+ return null;
1537
+ }
1538
+ const parsed = uniquePreserveOrder(parseBranchList(result.stdout.trim()));
1539
+ if (parsed.length === 0) {
1540
+ return null;
1541
+ }
1542
+ return parsed;
1543
+ }
1544
+
1545
+ function listLocalUserBranches(repoRoot) {
1546
+ const result = gitRun(repoRoot, ['for-each-ref', '--format=%(refname:short)', 'refs/heads'], { allowFailure: true });
1547
+ const branchNames = result.status === 0
1548
+ ? uniquePreserveOrder(
1549
+ String(result.stdout || '')
1550
+ .split('\n')
1551
+ .map((item) => item.trim())
1552
+ .filter(Boolean),
1553
+ )
1554
+ : [];
1555
+
1556
+ const additionalUserBranches = branchNames.filter(
1557
+ (branchName) =>
1558
+ !branchName.startsWith('agent/') &&
1559
+ !DEFAULT_PROTECTED_BRANCHES.includes(branchName),
1560
+ );
1561
+ if (additionalUserBranches.length > 0) {
1562
+ return additionalUserBranches;
1563
+ }
1564
+
1565
+ const current = gitRun(repoRoot, ['branch', '--show-current'], { allowFailure: true });
1566
+ if (current.status !== 0) {
1567
+ return [];
1568
+ }
1569
+
1570
+ const branchName = String(current.stdout || '').trim();
1571
+ if (
1572
+ !branchName ||
1573
+ branchName.startsWith('agent/') ||
1574
+ DEFAULT_PROTECTED_BRANCHES.includes(branchName)
1575
+ ) {
1576
+ return [];
1577
+ }
1578
+
1579
+ return [branchName];
1580
+ }
1581
+
1582
+ function ensureSetupProtectedBranches(repoRoot, dryRun) {
1583
+ const localUserBranches = listLocalUserBranches(repoRoot);
1584
+ if (localUserBranches.length === 0) {
1585
+ return {
1586
+ status: 'unchanged',
1587
+ file: `git config ${GIT_PROTECTED_BRANCHES_KEY}`,
1588
+ note: 'no additional local user branches detected',
1589
+ };
1590
+ }
1591
+
1592
+ const configured = readConfiguredProtectedBranches(repoRoot);
1593
+ const currentBranches = configured || [...DEFAULT_PROTECTED_BRANCHES];
1594
+ const missingBranches = localUserBranches.filter((branchName) => !currentBranches.includes(branchName));
1595
+ if (missingBranches.length === 0) {
1596
+ return {
1597
+ status: 'unchanged',
1598
+ file: `git config ${GIT_PROTECTED_BRANCHES_KEY}`,
1599
+ note: 'local user branches already protected',
1600
+ };
1601
+ }
1602
+
1603
+ const nextBranches = uniquePreserveOrder([...currentBranches, ...missingBranches]);
1604
+ if (!dryRun) {
1605
+ writeProtectedBranches(repoRoot, nextBranches);
1606
+ }
1607
+
1608
+ return {
1609
+ status: dryRun ? 'would-update' : 'updated',
1610
+ file: `git config ${GIT_PROTECTED_BRANCHES_KEY}`,
1611
+ note: `added local user branch(es): ${missingBranches.join(', ')}`,
1612
+ };
1613
+ }
1614
+
1502
1615
  function readProtectedBranches(repoRoot) {
1503
1616
  const result = gitRun(repoRoot, ['config', '--get', GIT_PROTECTED_BRANCHES_KEY], { allowFailure: true });
1504
1617
  if (result.status !== 0) {
@@ -2768,6 +2881,7 @@ function setup(rawArgs) {
2768
2881
 
2769
2882
  assertProtectedMainWriteAllowed(options, 'setup');
2770
2883
  const installPayload = runInstallInternal(options);
2884
+ installPayload.operations.push(ensureSetupProtectedBranches(installPayload.repoRoot, Boolean(options.dryRun)));
2771
2885
  printOperations('Setup/install', installPayload, options.dryRun);
2772
2886
 
2773
2887
  const fixPayload = runFixInternal({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imdeadpool/guardex",
3
- "version": "5.0.4",
3
+ "version": "5.0.5",
4
4
  "description": "GuardeX: the Guardian T-Rex for your repo, with hardened multi-agent git guardrails.",
5
5
  "license": "MIT",
6
6
  "preferGlobal": true,