forge-workflow 1.1.3 → 1.2.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.
@@ -12,7 +12,9 @@
12
12
  "Bash(git add:*)",
13
13
  "Bash(git commit:*)",
14
14
  "Bash(git push)",
15
- "Bash(\"C:\\\\Program Files\\\\nodejs\\\\npm.cmd\" pkg fix)"
15
+ "Bash(\"C:\\\\Program Files\\\\nodejs\\\\npm.cmd\" pkg fix)",
16
+ "WebFetch(domain:www.aihero.dev)",
17
+ "Bash(\"C:\\\\Program Files\\\\nodejs\\\\npm.cmd\" version minor --no-git-tag-version)"
16
18
  ]
17
19
  }
18
20
  }
package/bin/forge.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * Forge v1.1.3 - Universal AI Agent Workflow
4
+ * Forge v1.2.0 - Universal AI Agent Workflow
5
5
  * https://github.com/harshanandak/forge
6
6
  *
7
7
  * Usage:
@@ -591,6 +591,27 @@ function writeEnvTokens(tokens, preserveExisting = true) {
591
591
  }
592
592
 
593
593
  // Detect existing project installation status
594
+ // Helper function for yes/no prompts with validation
595
+ async function askYesNo(question, prompt, defaultNo = true) {
596
+ const defaultText = defaultNo ? '[n]' : '[y]';
597
+ while (true) {
598
+ const answer = await question(`${prompt} (y/n) ${defaultText}: `);
599
+ const normalized = answer.trim().toLowerCase();
600
+
601
+ // Handle empty input (use default)
602
+ if (normalized === '') return defaultNo ? false : true;
603
+
604
+ // Accept yes variations
605
+ if (normalized === 'y' || normalized === 'yes') return true;
606
+
607
+ // Accept no variations
608
+ if (normalized === 'n' || normalized === 'no') return false;
609
+
610
+ // Invalid input - re-prompt
611
+ console.log(' Please enter y or n');
612
+ }
613
+ }
614
+
594
615
  function detectProjectStatus() {
595
616
  const status = {
596
617
  type: 'fresh', // 'fresh', 'upgrade', or 'partial'
@@ -604,10 +625,10 @@ function detectProjectStatus() {
604
625
  // Determine installation type
605
626
  if (status.hasAgentsMd && status.hasClaudeCommands && status.hasDocsWorkflow) {
606
627
  status.type = 'upgrade'; // Full forge installation exists
607
- } else if (status.hasAgentsMd || status.hasClaudeCommands || status.hasEnvLocal) {
608
- status.type = 'partial'; // Some files exist
628
+ } else if (status.hasClaudeCommands || status.hasEnvLocal) {
629
+ status.type = 'partial'; // Agent-specific files exist (not just base files from postinstall)
609
630
  }
610
- // else: 'fresh' - new installation
631
+ // else: 'fresh' - new installation (or just postinstall baseline with AGENTS.md)
611
632
 
612
633
  // Parse existing env vars if .env.local exists
613
634
  if (status.hasEnvLocal) {
@@ -641,8 +662,8 @@ async function configureExternalServices(rl, question, selectedAgents = [], proj
641
662
  }
642
663
  console.log('');
643
664
 
644
- const reconfigure = await question('Reconfigure external services? (y/n) [n]: ');
645
- if (reconfigure.toLowerCase() !== 'y' && reconfigure.toLowerCase() !== 'yes') {
665
+ const reconfigure = await askYesNo(question, 'Reconfigure external services?', true);
666
+ if (!reconfigure) {
646
667
  console.log('');
647
668
  console.log('Keeping existing configuration.');
648
669
  return;
@@ -654,9 +675,9 @@ async function configureExternalServices(rl, question, selectedAgents = [], proj
654
675
  console.log('(You can also add them later to .env.local)');
655
676
  console.log('');
656
677
 
657
- const configure = await question('Configure external services? (y/n): ');
678
+ const configure = await askYesNo(question, 'Configure external services?', false);
658
679
 
659
- if (configure.toLowerCase() !== 'y' && configure.toLowerCase() !== 'yes') {
680
+ if (!configure) {
660
681
  console.log('');
661
682
  console.log('Skipping external services. You can configure them later by editing .env.local');
662
683
  return;
@@ -867,7 +888,7 @@ function showBanner(subtitle = 'Universal AI Agent Workflow') {
867
888
  console.log(' ██╔══╝ ██║ ██║██╔══██╗██║ ██║██╔══╝ ');
868
889
  console.log(' ██║ ╚██████╔╝██║ ██║╚██████╔╝███████╗');
869
890
  console.log(' ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝');
870
- console.log(' v1.1.3');
891
+ console.log(' v1.2.0');
871
892
  console.log('');
872
893
  if (subtitle) {
873
894
  console.log(` ${subtitle}`);
@@ -876,6 +897,23 @@ function showBanner(subtitle = 'Universal AI Agent Workflow') {
876
897
 
877
898
  // Minimal installation (postinstall)
878
899
  function minimalInstall() {
900
+ // Check if this looks like a project (has package.json)
901
+ const hasPackageJson = fs.existsSync(path.join(projectRoot, 'package.json'));
902
+
903
+ if (!hasPackageJson) {
904
+ console.log('');
905
+ console.log(' ✅ Forge installed successfully!');
906
+ console.log('');
907
+ console.log(' To set up in a project:');
908
+ console.log(' cd your-project');
909
+ console.log(' npx forge setup');
910
+ console.log('');
911
+ console.log(' Or specify a project directory:');
912
+ console.log(' npx forge setup --path ./my-project');
913
+ console.log('');
914
+ return;
915
+ }
916
+
879
917
  showBanner();
880
918
  console.log('');
881
919
 
@@ -1125,6 +1163,11 @@ async function interactiveSetup() {
1125
1163
 
1126
1164
  showBanner('Agent Configuration');
1127
1165
 
1166
+ // Show target directory
1167
+ console.log(` Target directory: ${process.cwd()}`);
1168
+ console.log(' (Use --path <dir> to change target directory)');
1169
+ console.log('');
1170
+
1128
1171
  // Check prerequisites first
1129
1172
  checkPrerequisites();
1130
1173
  console.log('');
@@ -1161,8 +1204,8 @@ async function interactiveSetup() {
1161
1204
 
1162
1205
  // Ask about overwriting AGENTS.md if it exists
1163
1206
  if (projectStatus.hasAgentsMd) {
1164
- const overwriteAgents = await question('Found existing AGENTS.md. Overwrite? (y/n) [n]: ');
1165
- if (overwriteAgents.toLowerCase() !== 'y' && overwriteAgents.toLowerCase() !== 'yes') {
1207
+ const overwriteAgents = await askYesNo(question, 'Found existing AGENTS.md. Overwrite?', true);
1208
+ if (!overwriteAgents) {
1166
1209
  skipFiles.agentsMd = true;
1167
1210
  console.log(' Keeping existing AGENTS.md');
1168
1211
  } else {
@@ -1172,8 +1215,8 @@ async function interactiveSetup() {
1172
1215
 
1173
1216
  // Ask about overwriting .claude/commands/ if it exists
1174
1217
  if (projectStatus.hasClaudeCommands) {
1175
- const overwriteCommands = await question('Found existing .claude/commands/. Overwrite? (y/n) [n]: ');
1176
- if (overwriteCommands.toLowerCase() !== 'y' && overwriteCommands.toLowerCase() !== 'yes') {
1218
+ const overwriteCommands = await askYesNo(question, 'Found existing .claude/commands/. Overwrite?', true);
1219
+ if (!overwriteCommands) {
1177
1220
  skipFiles.claudeCommands = true;
1178
1221
  console.log(' Keeping existing .claude/commands/');
1179
1222
  } else {
@@ -1305,7 +1348,7 @@ async function interactiveSetup() {
1305
1348
  // =============================================
1306
1349
  console.log('');
1307
1350
  console.log('==============================================');
1308
- console.log(' Forge v1.1.3 Setup Complete!');
1351
+ console.log(' Forge v1.2.0 Setup Complete!');
1309
1352
  console.log('==============================================');
1310
1353
  console.log('');
1311
1354
  console.log('What\'s installed:');
@@ -1526,7 +1569,7 @@ async function quickSetup(selectedAgents, skipExternal) {
1526
1569
  // Final summary
1527
1570
  console.log('');
1528
1571
  console.log('==============================================');
1529
- console.log(' Forge v1.1.3 Quick Setup Complete!');
1572
+ console.log(' Forge v1.2.0 Quick Setup Complete!');
1530
1573
  console.log('==============================================');
1531
1574
  console.log('');
1532
1575
  console.log('Next steps:');
@@ -1564,6 +1607,11 @@ async function interactiveSetupWithFlags(flags) {
1564
1607
 
1565
1608
  showBanner('Agent Configuration');
1566
1609
 
1610
+ // Show target directory
1611
+ console.log(` Target directory: ${process.cwd()}`);
1612
+ console.log(' (Use --path <dir> to change target directory)');
1613
+ console.log('');
1614
+
1567
1615
  // Check prerequisites first
1568
1616
  checkPrerequisites();
1569
1617
  console.log('');
@@ -1600,8 +1648,8 @@ async function interactiveSetupWithFlags(flags) {
1600
1648
 
1601
1649
  // Ask about overwriting AGENTS.md if it exists
1602
1650
  if (projectStatus.hasAgentsMd) {
1603
- const overwriteAgents = await question('Found existing AGENTS.md. Overwrite? (y/n) [n]: ');
1604
- if (overwriteAgents.toLowerCase() !== 'y' && overwriteAgents.toLowerCase() !== 'yes') {
1651
+ const overwriteAgents = await askYesNo(question, 'Found existing AGENTS.md. Overwrite?', true);
1652
+ if (!overwriteAgents) {
1605
1653
  skipFiles.agentsMd = true;
1606
1654
  console.log(' Keeping existing AGENTS.md');
1607
1655
  } else {
@@ -1611,8 +1659,8 @@ async function interactiveSetupWithFlags(flags) {
1611
1659
 
1612
1660
  // Ask about overwriting .claude/commands/ if it exists
1613
1661
  if (projectStatus.hasClaudeCommands) {
1614
- const overwriteCommands = await question('Found existing .claude/commands/. Overwrite? (y/n) [n]: ');
1615
- if (overwriteCommands.toLowerCase() !== 'y' && overwriteCommands.toLowerCase() !== 'yes') {
1662
+ const overwriteCommands = await askYesNo(question, 'Found existing .claude/commands/. Overwrite?', true);
1663
+ if (!overwriteCommands) {
1616
1664
  skipFiles.claudeCommands = true;
1617
1665
  console.log(' Keeping existing .claude/commands/');
1618
1666
  } else {
@@ -1749,7 +1797,7 @@ async function interactiveSetupWithFlags(flags) {
1749
1797
  // =============================================
1750
1798
  console.log('');
1751
1799
  console.log('==============================================');
1752
- console.log(' Forge v1.1.3 Setup Complete!');
1800
+ console.log(' Forge v1.2.0 Setup Complete!');
1753
1801
  console.log('==============================================');
1754
1802
  console.log('');
1755
1803
  console.log('What\'s installed:');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forge-workflow",
3
- "version": "1.1.3",
3
+ "version": "1.2.0",
4
4
  "description": "9-stage TDD workflow for ALL AI coding agents (Claude, Cursor, Windsurf, Kilo, OpenCode, Copilot, Cline, Roo, Aider, Continue, Antigravity)",
5
5
  "bin": {
6
6
  "forge": "bin/forge.js"