@undeemed/get-shit-done-codex 1.22.1 → 1.23.1

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
@@ -5,8 +5,9 @@ A meta-prompting, context engineering and spec-driven development system for [Op
5
5
  Fork of [get-shit-done](https://github.com/taches/get-shit-done) by TÂCHES, adapted for Codex CLI by [undeemed](https://github.com/undeemed).
6
6
 
7
7
  > [!CAUTION]
8
- > As of February 25, 2026, Codex is supported upstream. This fork remains focused on Codex-specific UX and compatibility with extra goodies.
8
+ > Codex is now supported upstream. This fork remains focused on Codex-specific UX, compatibility, and experimental features for personal use.
9
9
 
10
+ [![CI](https://github.com/undeemed/get-shit-done-codex/actions/workflows/ci.yml/badge.svg)](https://github.com/undeemed/get-shit-done-codex/actions/workflows/ci.yml)
10
11
  [![npm version](https://img.shields.io/npm/v/%40undeemed%2Fget-shit-done-codex?style=flat-square)](https://www.npmjs.com/package/@undeemed/get-shit-done-codex)
11
12
  [![License](https://img.shields.io/badge/license-MIT-green?style=flat-square)](LICENSE)
12
13
  ![npm Downloads](https://img.shields.io/npm/dt/@undeemed/get-shit-done-codex?style=flat-square)
@@ -46,6 +47,7 @@ npx @undeemed/get-shit-done-codex --global
46
47
  ```bash
47
48
  npx @undeemed/get-shit-done-codex --global # Install to ~/.codex/
48
49
  npx @undeemed/get-shit-done-codex --local # Install to current directory
50
+ npx @undeemed/get-shit-done-codex --path . # Install to a specific directory
49
51
  npx @undeemed/get-shit-done-codex --global --migrate # Clean up legacy prompts/
50
52
  npx @undeemed/get-shit-done-codex --verify --global # Check install integrity
51
53
  npx @undeemed/get-shit-done-codex --verify --repair --global # Auto-repair
package/bin/install.js CHANGED
@@ -41,6 +41,8 @@ const hasRepair = args.includes('--repair');
41
41
  const hasNoVersionCheck = args.includes('--no-version-check') || process.env.GSD_SKIP_VERSION_CHECK === '1';
42
42
  const hasMigrate = args.includes('--migrate');
43
43
  const hasSkipMigrate = args.includes('--skip-migrate') || args.includes('--no-migrate');
44
+ const pathIdx = args.indexOf('--path');
45
+ const customPath = pathIdx !== -1 && args[pathIdx + 1] ? args[pathIdx + 1] : null;
44
46
  const isInteractiveTerminal = Boolean(process.stdin.isTTY && process.stdout.isTTY);
45
47
  const codexMode = 'skills';
46
48
 
@@ -52,6 +54,7 @@ if (hasHelp) {
52
54
  ${yellow}Options:${reset}
53
55
  ${cyan}-g, --global${reset} Install globally (to ~/.codex/)
54
56
  ${cyan}-l, --local${reset} Install locally (to current directory)
57
+ ${cyan}--path <dir>${reset} Install into a specific directory
55
58
  ${cyan}--migrate${reset} Apply detected legacy surface cleanup without prompting
56
59
  ${cyan}--skip-migrate${reset} Keep legacy surface files when migration is detected
57
60
  ${cyan}--verify${reset} Verify current install integrity
@@ -66,6 +69,9 @@ if (hasHelp) {
66
69
  ${dim}# Install to current project only${reset}
67
70
  npx ${NPM_PACKAGE} --local
68
71
 
72
+ ${dim}# Install to a specific directory${reset}
73
+ npx ${NPM_PACKAGE} --path /path/to/project
74
+
69
75
  ${dim}# Verify global installation${reset}
70
76
  npx ${NPM_PACKAGE} --verify --global
71
77
 
@@ -103,7 +109,7 @@ function applyReplacements(content, pathPrefix) {
103
109
  content = content.replace(/Codex CLI/g, 'Codex CLI');
104
110
  content = content.replace(/Codex/g, 'Codex');
105
111
 
106
- content = content.replace(/\/gsd:/g, '/prompts:gsd-');
112
+ content = content.replace(/\/gsd:([a-z0-9-]*)/gi, (_, cmd) => `$gsd-${cmd.toLowerCase()}`);
107
113
 
108
114
  // Keep update workflows pointed to this fork's npm package/repo.
109
115
  content = content.replace(new RegExp(UPSTREAM_PACKAGE, 'g'), NPM_PACKAGE);
@@ -357,13 +363,24 @@ function showCachedVersionWarning() {
357
363
  }
358
364
  }
359
365
 
360
- function getInstallContext(isGlobal) {
361
- const codexDir = isGlobal ? path.join(os.homedir(), '.codex') : process.cwd();
362
- return {
363
- codexDir,
364
- locationLabel: isGlobal ? '~/.codex' : '.',
365
- pathPrefix: isGlobal ? '~/.codex/' : './',
366
- };
366
+ function getInstallContext(isGlobal, targetPath) {
367
+ let codexDir;
368
+ let locationLabel;
369
+ let pathPrefix;
370
+ if (targetPath) {
371
+ codexDir = path.resolve(targetPath);
372
+ locationLabel = targetPath;
373
+ pathPrefix = codexDir.endsWith(path.sep) ? codexDir : `${codexDir}${path.sep}`;
374
+ } else if (isGlobal) {
375
+ codexDir = path.join(os.homedir(), '.codex');
376
+ locationLabel = '~/.codex';
377
+ pathPrefix = '~/.codex/';
378
+ } else {
379
+ codexDir = process.cwd();
380
+ locationLabel = '.';
381
+ pathPrefix = './';
382
+ }
383
+ return { codexDir, locationLabel, pathPrefix };
367
384
  }
368
385
 
369
386
  function listPromptCommandFiles(promptsDir) {
@@ -388,9 +405,9 @@ function detectInstalledMode(promptCount, skillCount) {
388
405
  return 'none';
389
406
  }
390
407
 
391
- function verifyInstall(isGlobal) {
408
+ function verifyInstall(isGlobal, targetPath) {
392
409
  const src = path.join(__dirname, '..');
393
- const { codexDir, locationLabel } = getInstallContext(isGlobal);
410
+ const { codexDir, locationLabel } = getInstallContext(isGlobal, targetPath);
394
411
  const promptsDir = path.join(codexDir, 'prompts');
395
412
  const skillsDir = path.join(codexDir, 'skills');
396
413
  const workflowRoot = path.join(codexDir, 'get-shit-done');
@@ -447,9 +464,9 @@ function verifyInstall(isGlobal) {
447
464
  return { ok, detectedMode };
448
465
  }
449
466
 
450
- function installCore(isGlobal, migrationPlan, applyMigration, done = () => {}) {
467
+ function installCore(isGlobal, migrationPlan, applyMigration, done = () => {}, targetPath) {
451
468
  const src = path.join(__dirname, '..');
452
- const { codexDir, locationLabel, pathPrefix } = getInstallContext(isGlobal);
469
+ const { codexDir, locationLabel, pathPrefix } = getInstallContext(isGlobal, targetPath);
453
470
 
454
471
  console.log(` Installing to ${cyan}${locationLabel}${reset}\n`);
455
472
  fs.mkdirSync(codexDir, { recursive: true });
@@ -495,14 +512,15 @@ function installCore(isGlobal, migrationPlan, applyMigration, done = () => {}) {
495
512
  console.log(` ${green}✓${reset} Installed get-shit-done/ workflow files`);
496
513
  console.log(` ${green}✓${reset} Wrote get-shit-done/VERSION (${pkg.version})`);
497
514
 
515
+ const displayRoot = locationLabel.endsWith('/') ? locationLabel.slice(0, -1) : locationLabel;
498
516
  console.log(`
499
517
  ${green}Done!${reset}
500
518
 
501
519
  ${yellow}For Codex (CLI + Desktop):${reset}
502
- - AGENTS.md: ${cyan}${codexDir}/AGENTS.md${reset}
503
- - Native skills: ${cyan}${codexDir}/skills/gsd-*/SKILL.md${reset}
504
- - Config: ${cyan}${codexDir}/.codex/config.toml${reset}
505
- - Agent defs: ${cyan}${codexDir}/agents/gsd-*.md${reset}
520
+ - AGENTS.md: ${cyan}${displayRoot}/AGENTS.md${reset}
521
+ - Native skills: ${cyan}${displayRoot}/skills/gsd-*/SKILL.md${reset}
522
+ - Config: ${cyan}${displayRoot}/.codex/config.toml${reset}
523
+ - Agent defs: ${cyan}${displayRoot}/agents/gsd-*.md${reset}
506
524
 
507
525
  ${yellow}Getting Started:${reset}
508
526
  1. Run ${cyan}codex${reset} (CLI) or ${cyan}codex app${reset} (Desktop)
@@ -546,12 +564,12 @@ function installCore(isGlobal, migrationPlan, applyMigration, done = () => {}) {
546
564
  }
547
565
  }
548
566
 
549
- function install(isGlobal, done = () => {}) {
550
- const { codexDir } = getInstallContext(isGlobal);
567
+ function install(isGlobal, done = () => {}, targetPath) {
568
+ const { codexDir } = getInstallContext(isGlobal, targetPath);
551
569
  const migrationPlan = detectMigrationPlan(codexDir);
552
570
 
553
571
  if (!migrationPlan.hasChanges) {
554
- installCore(isGlobal, migrationPlan, false, done);
572
+ installCore(isGlobal, migrationPlan, false, done, targetPath);
555
573
  return;
556
574
  }
557
575
 
@@ -560,13 +578,13 @@ function install(isGlobal, done = () => {}) {
560
578
 
561
579
  if (hasMigrate) {
562
580
  console.log(` ${green}✓${reset} Migration approved by --migrate`);
563
- installCore(isGlobal, migrationPlan, true, done);
581
+ installCore(isGlobal, migrationPlan, true, done, targetPath);
564
582
  return;
565
583
  }
566
584
 
567
585
  if (hasSkipMigrate) {
568
586
  console.log(` ${yellow}Skipping migration due to --skip-migrate.${reset}`);
569
- installCore(isGlobal, migrationPlan, false, done);
587
+ installCore(isGlobal, migrationPlan, false, done, targetPath);
570
588
  return;
571
589
  }
572
590
 
@@ -589,7 +607,7 @@ function install(isGlobal, done = () => {}) {
589
607
  if (!applyMigration) {
590
608
  console.log(` ${yellow}Keeping legacy files.${reset}`);
591
609
  }
592
- installCore(isGlobal, migrationPlan, applyMigration, done);
610
+ installCore(isGlobal, migrationPlan, applyMigration, done, targetPath);
593
611
  });
594
612
  }
595
613
 
@@ -614,8 +632,14 @@ function promptLocation(done) {
614
632
  });
615
633
  }
616
634
 
617
- if (hasGlobal && hasLocal) {
618
- console.error(` ${yellow}Cannot specify both --global and --local${reset}`);
635
+ const locationFlagCount = [hasGlobal, hasLocal, !!customPath].filter(Boolean).length;
636
+ if (locationFlagCount > 1) {
637
+ console.error(` ${yellow}Cannot specify more than one of --global, --local, and --path${reset}`);
638
+ process.exit(1);
639
+ }
640
+
641
+ if (pathIdx !== -1 && !customPath) {
642
+ console.error(` ${yellow}--path requires a directory argument${reset}`);
619
643
  process.exit(1);
620
644
  }
621
645
 
@@ -634,21 +658,23 @@ if (!hasNoVersionCheck && !hasVerify) {
634
658
  }
635
659
 
636
660
  if (hasVerify) {
637
- const isGlobal = hasLocal ? false : true;
638
- let result = verifyInstall(isGlobal);
661
+ const isGlobal = customPath ? false : (hasLocal ? false : true);
662
+ let result = verifyInstall(isGlobal, customPath);
639
663
 
640
664
  if (!result.ok && hasRepair) {
641
665
  console.log(`\n ${yellow}Repairing install...${reset}\n`);
642
666
  install(isGlobal, () => {
643
667
  console.log('');
644
- const repaired = verifyInstall(isGlobal);
668
+ const repaired = verifyInstall(isGlobal, customPath);
645
669
  process.exit(repaired.ok ? 0 : 1);
646
- });
670
+ }, customPath);
647
671
  } else {
648
672
  process.exit(result.ok ? 0 : 1);
649
673
  }
650
674
  } else {
651
- if (hasGlobal) {
675
+ if (customPath) {
676
+ install(false, () => {}, customPath);
677
+ } else if (hasGlobal) {
652
678
  install(true);
653
679
  } else if (hasLocal) {
654
680
  install(false);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@undeemed/get-shit-done-codex",
3
- "version": "1.22.1",
4
- "description": "A meta-prompting, context engineering and spec-driven development system for OpenAI Codex (CLI and Desktop). Fork of get-shit-done by TÂCHES, adapted for Codex by undeemed.",
3
+ "version": "1.23.1",
4
+ "description": "A meta-prompting, context engineering and spec-driven development system for OpenAI Codex (CLI and Desktop). Fork of get-shit-done by TÂCHES, adapted for Codex.",
5
5
  "bin": {
6
6
  "get-shit-done-codex": "bin/install.js"
7
7
  },