@howlil/ez-agents 2.0.1 → 3.1.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.
Files changed (140) hide show
  1. package/README.md +72 -25
  2. package/README.zh-CN.md +84 -84
  3. package/agents/ez-ui-auditor.md +0 -2
  4. package/agents/ez-ui-checker.md +2 -4
  5. package/agents/ez-ui-researcher.md +0 -2
  6. package/bin/install.js +145 -102
  7. package/commands/ez/debug.md +1 -1
  8. package/commands/ez/map-codebase.md +1 -1
  9. package/commands/ez/reapply-patches.md +3 -3
  10. package/commands/ez/research-phase.md +1 -1
  11. package/{get-shit-done → ez-agents}/bin/ez-tools.cjs +1 -1
  12. package/{get-shit-done → ez-agents}/bin/lib/auth.cjs +2 -2
  13. package/{get-shit-done → ez-agents}/bin/lib/core.cjs +16 -16
  14. package/{get-shit-done → ez-agents}/bin/lib/init.cjs +20 -20
  15. package/{get-shit-done → ez-agents}/bin/lib/logger.cjs +2 -2
  16. package/{get-shit-done → ez-agents}/bin/lib/temp-file.cjs +2 -2
  17. package/{get-shit-done → ez-agents}/bin/lib/test-file-lock.cjs +1 -1
  18. package/{get-shit-done → ez-agents}/bin/lib/test-graceful.cjs +1 -1
  19. package/{get-shit-done → ez-agents}/bin/lib/test-logger.cjs +1 -1
  20. package/{get-shit-done → ez-agents}/bin/lib/test-temp-file.cjs +2 -2
  21. package/{get-shit-done → ez-agents}/workflows/add-phase.md +2 -2
  22. package/{get-shit-done → ez-agents}/workflows/audit-milestone.md +1 -1
  23. package/{get-shit-done → ez-agents}/workflows/complete-milestone.md +3 -3
  24. package/ez-agents/workflows/debug.md +0 -0
  25. package/{get-shit-done → ez-agents}/workflows/discovery-phase.md +5 -5
  26. package/{get-shit-done → ez-agents}/workflows/discuss-phase.md +2 -2
  27. package/{get-shit-done → ez-agents}/workflows/execute-phase.md +5 -5
  28. package/{get-shit-done → ez-agents}/workflows/execute-plan.md +10 -10
  29. package/{get-shit-done → ez-agents}/workflows/help.md +9 -9
  30. package/{get-shit-done → ez-agents}/workflows/insert-phase.md +2 -2
  31. package/{get-shit-done → ez-agents}/workflows/map-codebase.md +3 -3
  32. package/{get-shit-done → ez-agents}/workflows/new-milestone.md +4 -4
  33. package/{get-shit-done → ez-agents}/workflows/new-project.md +8 -8
  34. package/{get-shit-done → ez-agents}/workflows/plan-phase.md +9 -9
  35. package/{get-shit-done → ez-agents}/workflows/progress.md +2 -2
  36. package/{get-shit-done → ez-agents}/workflows/quick.md +10 -10
  37. package/{get-shit-done → ez-agents}/workflows/remove-phase.md +4 -4
  38. package/{get-shit-done → ez-agents}/workflows/research-phase.md +4 -4
  39. package/{get-shit-done → ez-agents}/workflows/resume-project.md +1 -1
  40. package/{get-shit-done → ez-agents}/workflows/set-profile.md +3 -3
  41. package/{get-shit-done → ez-agents}/workflows/transition.md +3 -3
  42. package/{get-shit-done → ez-agents}/workflows/ui-phase.md +12 -12
  43. package/{get-shit-done → ez-agents}/workflows/ui-review.md +6 -6
  44. package/{get-shit-done → ez-agents}/workflows/update.md +29 -29
  45. package/{get-shit-done → ez-agents}/workflows/validate-phase.md +5 -5
  46. package/{get-shit-done → ez-agents}/workflows/verify-phase.md +6 -6
  47. package/{get-shit-done → ez-agents}/workflows/verify-work.md +5 -5
  48. package/hooks/dist/ez-check-update.js +81 -0
  49. package/hooks/dist/ez-context-monitor.js +141 -0
  50. package/hooks/dist/ez-statusline.js +115 -0
  51. package/package.json +13 -3
  52. package/scripts/build-hooks.js +3 -3
  53. /package/{get-shit-done → ez-agents}/bin/lib/assistant-adapter.cjs +0 -0
  54. /package/{get-shit-done → ez-agents}/bin/lib/audit-exec.cjs +0 -0
  55. /package/{get-shit-done → ez-agents}/bin/lib/circuit-breaker.cjs +0 -0
  56. /package/{get-shit-done → ez-agents}/bin/lib/commands.cjs +0 -0
  57. /package/{get-shit-done → ez-agents}/bin/lib/config.cjs +0 -0
  58. /package/{get-shit-done → ez-agents}/bin/lib/file-lock.cjs +0 -0
  59. /package/{get-shit-done → ez-agents}/bin/lib/frontmatter.cjs +0 -0
  60. /package/{get-shit-done → ez-agents}/bin/lib/fs-utils.cjs +0 -0
  61. /package/{get-shit-done → ez-agents}/bin/lib/git-utils.cjs +0 -0
  62. /package/{get-shit-done → ez-agents}/bin/lib/health-check.cjs +0 -0
  63. /package/{get-shit-done → ez-agents}/bin/lib/index.cjs +0 -0
  64. /package/{get-shit-done → ez-agents}/bin/lib/milestone.cjs +0 -0
  65. /package/{get-shit-done → ez-agents}/bin/lib/model-provider.cjs +0 -0
  66. /package/{get-shit-done → ez-agents}/bin/lib/phase.cjs +0 -0
  67. /package/{get-shit-done → ez-agents}/bin/lib/retry.cjs +0 -0
  68. /package/{get-shit-done → ez-agents}/bin/lib/roadmap.cjs +0 -0
  69. /package/{get-shit-done → ez-agents}/bin/lib/safe-exec.cjs +0 -0
  70. /package/{get-shit-done → ez-agents}/bin/lib/safe-path.cjs +0 -0
  71. /package/{get-shit-done → ez-agents}/bin/lib/state.cjs +0 -0
  72. /package/{get-shit-done → ez-agents}/bin/lib/template.cjs +0 -0
  73. /package/{get-shit-done → ez-agents}/bin/lib/test-safe-exec.cjs +0 -0
  74. /package/{get-shit-done → ez-agents}/bin/lib/test-safe-path.cjs +0 -0
  75. /package/{get-shit-done → ez-agents}/bin/lib/timeout-exec.cjs +0 -0
  76. /package/{get-shit-done → ez-agents}/bin/lib/verify.cjs +0 -0
  77. /package/{get-shit-done → ez-agents}/references/checkpoints.md +0 -0
  78. /package/{get-shit-done → ez-agents}/references/continuation-format.md +0 -0
  79. /package/{get-shit-done → ez-agents}/references/decimal-phase-calculation.md +0 -0
  80. /package/{get-shit-done → ez-agents}/references/git-integration.md +0 -0
  81. /package/{get-shit-done → ez-agents}/references/git-planning-commit.md +0 -0
  82. /package/{get-shit-done → ez-agents}/references/model-profile-resolution.md +0 -0
  83. /package/{get-shit-done → ez-agents}/references/model-profiles.md +0 -0
  84. /package/{get-shit-done → ez-agents}/references/phase-argument-parsing.md +0 -0
  85. /package/{get-shit-done → ez-agents}/references/planning-config.md +0 -0
  86. /package/{get-shit-done → ez-agents}/references/questioning.md +0 -0
  87. /package/{get-shit-done → ez-agents}/references/tdd.md +0 -0
  88. /package/{get-shit-done → ez-agents}/references/ui-brand.md +0 -0
  89. /package/{get-shit-done → ez-agents}/references/verification-patterns.md +0 -0
  90. /package/{get-shit-done → ez-agents}/templates/DEBUG.md +0 -0
  91. /package/{get-shit-done → ez-agents}/templates/UAT.md +0 -0
  92. /package/{get-shit-done → ez-agents}/templates/UI-SPEC.md +0 -0
  93. /package/{get-shit-done → ez-agents}/templates/VALIDATION.md +0 -0
  94. /package/{get-shit-done → ez-agents}/templates/codebase/architecture.md +0 -0
  95. /package/{get-shit-done → ez-agents}/templates/codebase/concerns.md +0 -0
  96. /package/{get-shit-done → ez-agents}/templates/codebase/conventions.md +0 -0
  97. /package/{get-shit-done → ez-agents}/templates/codebase/integrations.md +0 -0
  98. /package/{get-shit-done → ez-agents}/templates/codebase/stack.md +0 -0
  99. /package/{get-shit-done → ez-agents}/templates/codebase/structure.md +0 -0
  100. /package/{get-shit-done → ez-agents}/templates/codebase/testing.md +0 -0
  101. /package/{get-shit-done → ez-agents}/templates/config.json +0 -0
  102. /package/{get-shit-done → ez-agents}/templates/context.md +0 -0
  103. /package/{get-shit-done → ez-agents}/templates/continue-here.md +0 -0
  104. /package/{get-shit-done → ez-agents}/templates/copilot-instructions.md +0 -0
  105. /package/{get-shit-done → ez-agents}/templates/debug-subagent-prompt.md +0 -0
  106. /package/{get-shit-done → ez-agents}/templates/discovery.md +0 -0
  107. /package/{get-shit-done → ez-agents}/templates/milestone-archive.md +0 -0
  108. /package/{get-shit-done → ez-agents}/templates/milestone.md +0 -0
  109. /package/{get-shit-done → ez-agents}/templates/phase-prompt.md +0 -0
  110. /package/{get-shit-done → ez-agents}/templates/planner-subagent-prompt.md +0 -0
  111. /package/{get-shit-done → ez-agents}/templates/project.md +0 -0
  112. /package/{get-shit-done → ez-agents}/templates/requirements.md +0 -0
  113. /package/{get-shit-done → ez-agents}/templates/research-project/ARCHITECTURE.md +0 -0
  114. /package/{get-shit-done → ez-agents}/templates/research-project/FEATURES.md +0 -0
  115. /package/{get-shit-done → ez-agents}/templates/research-project/PITFALLS.md +0 -0
  116. /package/{get-shit-done → ez-agents}/templates/research-project/STACK.md +0 -0
  117. /package/{get-shit-done → ez-agents}/templates/research-project/SUMMARY.md +0 -0
  118. /package/{get-shit-done → ez-agents}/templates/research.md +0 -0
  119. /package/{get-shit-done → ez-agents}/templates/retrospective.md +0 -0
  120. /package/{get-shit-done → ez-agents}/templates/roadmap.md +0 -0
  121. /package/{get-shit-done → ez-agents}/templates/state.md +0 -0
  122. /package/{get-shit-done → ez-agents}/templates/summary-complex.md +0 -0
  123. /package/{get-shit-done → ez-agents}/templates/summary-minimal.md +0 -0
  124. /package/{get-shit-done → ez-agents}/templates/summary-standard.md +0 -0
  125. /package/{get-shit-done → ez-agents}/templates/summary.md +0 -0
  126. /package/{get-shit-done → ez-agents}/templates/user-setup.md +0 -0
  127. /package/{get-shit-done → ez-agents}/templates/verification-report.md +0 -0
  128. /package/{get-shit-done → ez-agents}/workflows/add-tests.md +0 -0
  129. /package/{get-shit-done → ez-agents}/workflows/add-todo.md +0 -0
  130. /package/{get-shit-done → ez-agents}/workflows/autonomous.md +0 -0
  131. /package/{get-shit-done → ez-agents}/workflows/check-todos.md +0 -0
  132. /package/{get-shit-done → ez-agents}/workflows/cleanup.md +0 -0
  133. /package/{get-shit-done → ez-agents}/workflows/diagnose-issues.md +0 -0
  134. /package/{get-shit-done → ez-agents}/workflows/health.md +0 -0
  135. /package/{get-shit-done → ez-agents}/workflows/list-phase-assumptions.md +0 -0
  136. /package/{get-shit-done → ez-agents}/workflows/node-repair.md +0 -0
  137. /package/{get-shit-done → ez-agents}/workflows/pause-work.md +0 -0
  138. /package/{get-shit-done → ez-agents}/workflows/plan-milestone-gaps.md +0 -0
  139. /package/{get-shit-done → ez-agents}/workflows/settings.md +0 -0
  140. /package/{get-shit-done → ez-agents}/workflows/stats.md +0 -0
package/bin/install.js CHANGED
@@ -14,11 +14,11 @@ const dim = '\x1b[2m';
14
14
  const reset = '\x1b[0m';
15
15
 
16
16
  // Codex config.toml constants
17
- const EZ_CODEX_MARKER = '# EZ Agents Agent Configuration \u2014 managed by ez-agents installer';
17
+ const EZ_CODEX_MARKER = '# EZ_Agents Agent Configuration \u2014 managed by ez-agents installer';
18
18
 
19
19
  // Copilot instructions marker constants
20
- const EZ_COPILOT_INSTRUCTIONS_MARKER = '<!-- EZ Agents Configuration \u2014 managed by ez-agents installer -->';
21
- const EZ_COPILOT_INSTRUCTIONS_CLOSE_MARKER = '<!-- /EZ Agents Configuration -->';
20
+ const EZ_COPILOT_INSTRUCTIONS_MARKER = '<!-- EZ_Agents Configuration \u2014 managed by ez-agents installer -->';
21
+ const EZ_COPILOT_INSTRUCTIONS_CLOSE_MARKER = '<!-- /EZ_Agents Configuration -->';
22
22
 
23
23
  const CODEX_AGENT_SANDBOX = {
24
24
  'ez-executor': 'workspace-write',
@@ -256,7 +256,7 @@ const banner = '\n' +
256
256
  ' ███████╗██╔╝╚██╗\n' +
257
257
  ' ╚══════╝╚═╝ ╚═╝' + reset + '\n' +
258
258
  '\n' +
259
- ' EZ Agents ' + dim + 'v' + pkg.version + reset + '\n' +
259
+ ' EZ_Agents ' + dim + 'v' + pkg.version + reset + '\n' +
260
260
  ' ' + dim + 'Multi-Model Edition' + reset + '\n' +
261
261
  ' A meta-prompting, context engineering and spec-driven\n' +
262
262
  ' development system for Claude Code, OpenCode, Gemini, Codex, Copilot,\n' +
@@ -299,7 +299,7 @@ if (hasUninstall) {
299
299
 
300
300
  // Show help if requested
301
301
  if (hasHelp) {
302
- console.log(` ${yellow}Usage:${reset} npx ez-agents [options]\n\n ${yellow}Options:${reset}\n ${cyan}-g, --global${reset} Install globally (to config directory)\n ${cyan}-l, --local${reset} Install locally (to current directory)\n ${cyan}--claude${reset} Install for Claude Code only\n ${cyan}--opencode${reset} Install for OpenCode only\n ${cyan}--gemini${reset} Install for Gemini only\n ${cyan}--codex${reset} Install for Codex only\n ${cyan}--copilot${reset} Install for Copilot only\n ${cyan}--all${reset} Install for all runtimes\n ${cyan}-u, --uninstall${reset} Uninstall EZ Agents (remove all EZ Agents files)\n ${cyan}-c, --config-dir <path>${reset} Specify custom config directory\n ${cyan}-h, --help${reset} Show this help message\n ${cyan}--force-statusline${reset} Replace existing statusline config\n\n ${yellow}Examples:${reset}\n ${dim}# Interactive install (prompts for runtime and location)${reset}\n npx ez-agents\n\n ${dim}# Install for Claude Code globally${reset}\n npx ez-agents --claude --global\n\n ${dim}# Install for all runtimes globally${reset}\n npx ez-agents --all --global\n\n ${dim}# Uninstall EZ Agents globally${reset}\n npx ez-agents --all --global --uninstall\n\n ${yellow}Notes:${reset}\n The --config-dir option is useful when you have multiple configurations.\n It takes priority over CLAUDE_CONFIG_DIR / GEMINI_CONFIG_DIR / CODEX_HOME / COPILOT_CONFIG_DIR environment variables.\n`);
302
+ console.log(` ${yellow}Usage:${reset} npx ez-agents [options]\n\n ${yellow}Options:${reset}\n ${cyan}-g, --global${reset} Install globally (to config directory)\n ${cyan}-l, --local${reset} Install locally (to current directory)\n ${cyan}--claude${reset} Install for Claude Code only\n ${cyan}--opencode${reset} Install for OpenCode only\n ${cyan}--gemini${reset} Install for Gemini only\n ${cyan}--codex${reset} Install for Codex only\n ${cyan}--copilot${reset} Install for Copilot only\n ${cyan}--all${reset} Install for all runtimes\n ${cyan}-u, --uninstall${reset} Uninstall EZ_Agents (remove all EZ_Agents files)\n ${cyan}-c, --config-dir <path>${reset} Specify custom config directory\n ${cyan}-h, --help${reset} Show this help message\n ${cyan}--force-statusline${reset} Replace existing statusline config\n\n ${yellow}Examples:${reset}\n ${dim}# Interactive install (prompts for runtime and location)${reset}\n npx ez-agents\n\n ${dim}# Install for Claude Code globally${reset}\n npx ez-agents --claude --global\n\n ${dim}# Install for all runtimes globally${reset}\n npx ez-agents --all --global\n\n ${dim}# Uninstall EZ_Agents globally${reset}\n npx ez-agents --all --global --uninstall\n\n ${yellow}Notes:${reset}\n The --config-dir option is useful when you have multiple configurations.\n It takes priority over CLAUDE_CONFIG_DIR / GEMINI_CONFIG_DIR / CODEX_HOME / COPILOT_CONFIG_DIR environment variables.\n\n ${yellow}Model Providers:${reset}\n Qwen, Kimi, OpenAI, and Anthropic are model providers configured in settings.json,\n not separate CLI runtimes. See README.md for model configuration.\n`);
303
303
  process.exit(0);
304
304
  }
305
305
 
@@ -666,7 +666,7 @@ function getCodexSkillAdapterHeader(skillName) {
666
666
  - If no arguments are present, treat \`{{EZ_ARGS}}\` as empty.
667
667
 
668
668
  ## B. AskUserQuestion → request_user_input Mapping
669
- EZ Agents workflows use \`AskUserQuestion\` (Claude Code syntax). Translate to Codex \`request_user_input\`:
669
+ EZ_Agents workflows use \`AskUserQuestion\` (Claude Code syntax). Translate to Codex \`request_user_input\`:
670
670
 
671
671
  Parameter mapping:
672
672
  - \`header\` → \`header\`
@@ -684,12 +684,12 @@ Execute mode fallback:
684
684
  - When \`request_user_input\` is rejected (Execute mode), present a plain-text numbered list and pick a reasonable default.
685
685
 
686
686
  ## C. Task() → spawn_agent Mapping
687
- EZ Agents workflows use \`Task(...)\` (Claude Code syntax). Translate to Codex collaboration tools:
687
+ EZ_Agents workflows use \`Task(...)\` (Claude Code syntax). Translate to Codex collaboration tools:
688
688
 
689
689
  Direct mapping:
690
690
  - \`Task(subagent_type="X", prompt="Y")\` → \`spawn_agent(agent_type="X", message="Y")\`
691
691
  - \`Task(model="...")\` → omit (Codex uses per-role config, not inline model selection)
692
- - \`fork_context: false\` by default — EZ Agents agents load their own context via \`<files_to_read>\` blocks
692
+ - \`fork_context: false\` by default — EZ_Agents agents load their own context via \`<files_to_read>\` blocks
693
693
 
694
694
  Parallel fan-out:
695
695
  - Spawn multiple agents → collect agent IDs → \`wait(ids)\` for all to complete
@@ -703,7 +703,7 @@ Result parsing:
703
703
  function convertClaudeCommandToCodexSkill(content, skillName) {
704
704
  const converted = convertClaudeToCodexMarkdown(content);
705
705
  const { frontmatter, body } = extractFrontmatterAndBody(converted);
706
- let description = `Run EZ Agents workflow ${skillName}.`;
706
+ let description = `Run EZ_Agents workflow ${skillName}.`;
707
707
  if (frontmatter) {
708
708
  const maybeDescription = extractFrontmatterField(frontmatter, 'description');
709
709
  if (maybeDescription) {
@@ -764,7 +764,7 @@ function generateCodexAgentToml(agentName, agentContent) {
764
764
  }
765
765
 
766
766
  /**
767
- * Generate the EZ Agents config block for Codex config.toml.
767
+ * Generate the EZ_Agents config block for Codex config.toml.
768
768
  * @param {Array<{name: string, description: string}>} agents
769
769
  */
770
770
  function generateCodexConfigBlock(agents) {
@@ -784,16 +784,16 @@ function generateCodexConfigBlock(agents) {
784
784
  }
785
785
 
786
786
  /**
787
- * Strip EZ Agents sections from Codex config.toml content.
787
+ * Strip EZ_Agents sections from Codex config.toml content.
788
788
  * Returns cleaned content, or null if file would be empty.
789
789
  */
790
- function stripGsdFromCodexConfig(content) {
790
+ function stripEzAgentsFromCodexConfig(content) {
791
791
  const markerIndex = content.indexOf(EZ_CODEX_MARKER);
792
792
 
793
793
  if (markerIndex !== -1) {
794
- // Has EZ Agents marker — remove everything from marker to EOF
794
+ // Has EZ_Agents marker — remove everything from marker to EOF
795
795
  let before = content.substring(0, markerIndex).trimEnd();
796
- // Also strip EZ Agents-injected feature keys above the marker (Case 3 inject)
796
+ // Also strip EZ-injected feature keys above the marker (Case 3 inject)
797
797
  before = before.replace(/^multi_agent\s*=\s*true\s*\n?/m, '');
798
798
  before = before.replace(/^default_mode_request_user_input\s*=\s*true\s*\n?/m, '');
799
799
  before = before.replace(/^\[features\]\s*\n(?=\[|$)/m, '');
@@ -802,7 +802,7 @@ function stripGsdFromCodexConfig(content) {
802
802
  return before + '\n';
803
803
  }
804
804
 
805
- // No marker but may have EZ Agents-injected feature keys
805
+ // No marker but may have EZ-injected feature keys
806
806
  let cleaned = content;
807
807
  cleaned = cleaned.replace(/^multi_agent\s*=\s*true\s*\n?/m, '');
808
808
  cleaned = cleaned.replace(/^default_mode_request_user_input\s*=\s*true\s*\n?/m, '');
@@ -824,56 +824,56 @@ function stripGsdFromCodexConfig(content) {
824
824
  }
825
825
 
826
826
  /**
827
- * Merge EZ Agents config block into an existing or new config.toml.
828
- * Three cases: new file, existing with EZ Agents marker, existing without marker.
827
+ * Merge EZ_Agents config block into an existing or new config.toml.
828
+ * Three cases: new file, existing with EZ_Agents marker, existing without marker.
829
829
  */
830
- function mergeCodexConfig(configPath, gsdBlock) {
830
+ function mergeCodexConfig(configPath, EZ_AgentsBlock) {
831
831
  // Case 1: No config.toml — create fresh
832
832
  if (!fs.existsSync(configPath)) {
833
- fs.writeFileSync(configPath, gsdBlock + '\n');
833
+ fs.writeFileSync(configPath, EZ_AgentsBlock + '\n');
834
834
  return;
835
835
  }
836
836
 
837
837
  const existing = fs.readFileSync(configPath, 'utf8');
838
838
  const markerIndex = existing.indexOf(EZ_CODEX_MARKER);
839
839
 
840
- // Case 2: Has EZ Agents marker — truncate and re-append
840
+ // Case 2: Has EZ_Agents marker — truncate and re-append
841
841
  if (markerIndex !== -1) {
842
842
  let before = existing.substring(0, markerIndex).trimEnd();
843
843
  if (before) {
844
- // Strip any EZ Agents-managed sections that leaked above the marker from previous installs
844
+ // Strip any EZ-managed sections that leaked above the marker from previous installs
845
845
  before = before.replace(/^\[agents\.ez-[^\]]+\]\n(?:(?!\[)[^\n]*\n?)*/gm, '');
846
846
  before = before.replace(/^\[agents\]\n(?:(?!\[)[^\n]*\n?)*/m, '');
847
847
  before = before.replace(/\n{3,}/g, '\n\n').trimEnd();
848
848
 
849
- fs.writeFileSync(configPath, before + '\n\n' + gsdBlock + '\n');
849
+ fs.writeFileSync(configPath, before + '\n\n' + EZ_AgentsBlock + '\n');
850
850
  } else {
851
- fs.writeFileSync(configPath, gsdBlock + '\n');
851
+ fs.writeFileSync(configPath, EZ_AgentsBlock + '\n');
852
852
  }
853
853
  return;
854
854
  }
855
855
 
856
- // Case 3: No marker — append EZ Agents block
856
+ // Case 3: No marker — append EZ_Agents block
857
857
  let content = existing;
858
- content = content.trimEnd() + '\n\n' + gsdBlock + '\n';
858
+ content = content.trimEnd() + '\n\n' + EZ_AgentsBlock + '\n';
859
859
 
860
860
  fs.writeFileSync(configPath, content);
861
861
  }
862
862
 
863
863
  /**
864
- * Merge EZ Agents instructions into copilot-instructions.md.
864
+ * Merge EZ_Agents instructions into copilot-instructions.md.
865
865
  * Three cases: new file, existing with markers, existing without markers.
866
866
  * @param {string} filePath - Full path to copilot-instructions.md
867
- * @param {string} gsdContent - Template content (without markers)
867
+ * @param {string} EZ_AgentsContent - Template content (without markers)
868
868
  */
869
- function mergeCopilotInstructions(filePath, gsdContent) {
870
- const gsdBlock = EZ_COPILOT_INSTRUCTIONS_MARKER + '\n' +
871
- gsdContent.trim() + '\n' +
869
+ function mergeCopilotInstructions(filePath, EZ_AgentsContent) {
870
+ const EZ_AgentsBlock = EZ_COPILOT_INSTRUCTIONS_MARKER + '\n' +
871
+ EZ_AgentsContent.trim() + '\n' +
872
872
  EZ_COPILOT_INSTRUCTIONS_CLOSE_MARKER;
873
873
 
874
874
  // Case 1: No file — create fresh
875
875
  if (!fs.existsSync(filePath)) {
876
- fs.writeFileSync(filePath, gsdBlock + '\n');
876
+ fs.writeFileSync(filePath, EZ_AgentsBlock + '\n');
877
877
  return;
878
878
  }
879
879
 
@@ -881,13 +881,13 @@ function mergeCopilotInstructions(filePath, gsdContent) {
881
881
  const openIndex = existing.indexOf(EZ_COPILOT_INSTRUCTIONS_MARKER);
882
882
  const closeIndex = existing.indexOf(EZ_COPILOT_INSTRUCTIONS_CLOSE_MARKER);
883
883
 
884
- // Case 2: Has EZ Agents markers — replace between markers
884
+ // Case 2: Has EZ_Agents markers — replace between markers
885
885
  if (openIndex !== -1 && closeIndex !== -1) {
886
886
  const before = existing.substring(0, openIndex).trimEnd();
887
887
  const after = existing.substring(closeIndex + EZ_COPILOT_INSTRUCTIONS_CLOSE_MARKER.length).trimStart();
888
888
  let newContent = '';
889
889
  if (before) newContent += before + '\n\n';
890
- newContent += gsdBlock;
890
+ newContent += EZ_AgentsBlock;
891
891
  if (after) newContent += '\n\n' + after;
892
892
  newContent += '\n';
893
893
  fs.writeFileSync(filePath, newContent);
@@ -895,17 +895,17 @@ function mergeCopilotInstructions(filePath, gsdContent) {
895
895
  }
896
896
 
897
897
  // Case 3: No markers — append at end
898
- const content = existing.trimEnd() + '\n\n' + gsdBlock + '\n';
898
+ const content = existing.trimEnd() + '\n\n' + EZ_AgentsBlock + '\n';
899
899
  fs.writeFileSync(filePath, content);
900
900
  }
901
901
 
902
902
  /**
903
- * Strip EZ Agents section from copilot-instructions.md content.
904
- * Returns cleaned content, or null if file should be deleted (was GSD-only).
903
+ * Strip EZ_Agents section from copilot-instructions.md content.
904
+ * Returns cleaned content, or null if file should be deleted (was EZ-only).
905
905
  * @param {string} content - File content
906
906
  * @returns {string|null} - Cleaned content or null if empty
907
907
  */
908
- function stripGsdFromCopilotInstructions(content) {
908
+ function stripEzAgentsFromCopilotInstructions(content) {
909
909
  const openIndex = content.indexOf(EZ_COPILOT_INSTRUCTIONS_MARKER);
910
910
  const closeIndex = content.indexOf(EZ_COPILOT_INSTRUCTIONS_CLOSE_MARKER);
911
911
 
@@ -930,7 +930,7 @@ function installCodexConfig(targetDir, agentsSrc) {
930
930
  const agentsTomlDir = path.join(targetDir, 'agents');
931
931
  fs.mkdirSync(agentsTomlDir, { recursive: true });
932
932
 
933
- const agentEntries = fs.readdirSync(agentsSrc).filter(f => f.startsWith('gsd-') && f.endsWith('.md'));
933
+ const agentEntries = fs.readdirSync(agentsSrc).filter(f => f.startsWith('EZ-') && f.endsWith('.md'));
934
934
  const agents = [];
935
935
 
936
936
  // Compute the Codex pathPrefix for replacing .claude paths
@@ -952,8 +952,8 @@ function installCodexConfig(targetDir, agentsSrc) {
952
952
  fs.writeFileSync(path.join(agentsTomlDir, `${name}.toml`), tomlContent);
953
953
  }
954
954
 
955
- const gsdBlock = generateCodexConfigBlock(agents);
956
- mergeCodexConfig(configPath, gsdBlock);
955
+ const EZ_AgentsBlock = generateCodexConfigBlock(agents);
956
+ mergeCodexConfig(configPath, EZ_AgentsBlock);
957
957
 
958
958
  return agents.length;
959
959
  }
@@ -1062,7 +1062,7 @@ function convertClaudeToGeminiAgent(content) {
1062
1062
  // Escape ${VAR} patterns in agent body for Gemini CLI compatibility.
1063
1063
  // Gemini's templateString() treats all ${word} patterns as template variables
1064
1064
  // and throws "Template validation failed: Missing required input parameters"
1065
- // when they can't be resolved. EZ Agents agents use ${PHASE}, ${PLAN}, etc. as
1065
+ // when they can't be resolved. EZ_Agents agents use ${PHASE}, ${PLAN}, etc. as
1066
1066
  // shell variables in bash code blocks — convert to $VAR (no braces) which
1067
1067
  // is equivalent bash and invisible to Gemini's /\$\{(\w+)\}/g regex.
1068
1068
  const escapedBody = body.replace(/\$\{(\w+)\}/g, '$$$1');
@@ -1543,8 +1543,8 @@ function cleanupOrphanedHooks(settings) {
1543
1543
  }
1544
1544
 
1545
1545
  /**
1546
- * Uninstall EZ Agents from the specified directory for a specific runtime
1547
- * Removes only EZ Agents-specific files/directories, preserves user content
1546
+ * Uninstall EZ_Agents from the specified directory for a specific runtime
1547
+ * Removes only EZ-specific files/directories, preserves user content
1548
1548
  * @param {boolean} isGlobal - Whether to uninstall from global or local
1549
1549
  * @param {string} runtime - Target runtime ('claude', 'opencode', 'gemini', 'codex', 'copilot')
1550
1550
  */
@@ -1569,7 +1569,7 @@ function uninstall(isGlobal, runtime = 'claude') {
1569
1569
  if (runtime === 'codex') runtimeLabel = 'Codex';
1570
1570
  if (runtime === 'copilot') runtimeLabel = 'Copilot';
1571
1571
 
1572
- console.log(` Uninstalling EZ Agents from ${cyan}${runtimeLabel}${reset} at ${cyan}${locationLabel}${reset}\n`);
1572
+ console.log(` Uninstalling EZ_Agents from ${cyan}${runtimeLabel}${reset} at ${cyan}${locationLabel}${reset}\n`);
1573
1573
 
1574
1574
  // Check if target directory exists
1575
1575
  if (!fs.existsSync(targetDir)) {
@@ -1592,7 +1592,7 @@ function uninstall(isGlobal, runtime = 'claude') {
1592
1592
  removedCount++;
1593
1593
  }
1594
1594
  }
1595
- console.log(` ${green}✓${reset} Removed EZ Agents commands from command/`);
1595
+ console.log(` ${green}✓${reset} Removed EZ_Agents commands from command/`);
1596
1596
  }
1597
1597
  } else if (isCodex) {
1598
1598
  // Codex: remove skills/ez-*/SKILL.md skill directories
@@ -1633,16 +1633,16 @@ function uninstall(isGlobal, runtime = 'claude') {
1633
1633
  const configPath = path.join(targetDir, 'config.toml');
1634
1634
  if (fs.existsSync(configPath)) {
1635
1635
  const content = fs.readFileSync(configPath, 'utf8');
1636
- const cleaned = stripGsdFromCodexConfig(content);
1636
+ const cleaned = stripEzAgentsFromCodexConfig(content);
1637
1637
  if (cleaned === null) {
1638
1638
  // File is empty after stripping — delete it
1639
1639
  fs.unlinkSync(configPath);
1640
1640
  removedCount++;
1641
- console.log(` ${green}✓${reset} Removed config.toml (was EZ Agents-only)`);
1641
+ console.log(` ${green}✓${reset} Removed config.toml (was EZ-only)`);
1642
1642
  } else if (cleaned !== content) {
1643
1643
  fs.writeFileSync(configPath, cleaned);
1644
1644
  removedCount++;
1645
- console.log(` ${green}✓${reset} Cleaned EZ Agents sections from config.toml`);
1645
+ console.log(` ${green}✓${reset} Cleaned EZ_Agents sections from config.toml`);
1646
1646
  }
1647
1647
  }
1648
1648
  } else if (isCopilot) {
@@ -1667,15 +1667,15 @@ function uninstall(isGlobal, runtime = 'claude') {
1667
1667
  const instructionsPath = path.join(targetDir, 'copilot-instructions.md');
1668
1668
  if (fs.existsSync(instructionsPath)) {
1669
1669
  const content = fs.readFileSync(instructionsPath, 'utf8');
1670
- const cleaned = stripGsdFromCopilotInstructions(content);
1670
+ const cleaned = stripEzAgentsFromCopilotInstructions(content);
1671
1671
  if (cleaned === null) {
1672
1672
  fs.unlinkSync(instructionsPath);
1673
1673
  removedCount++;
1674
- console.log(` ${green}✓${reset} Removed copilot-instructions.md (was EZ Agents-only)`);
1674
+ console.log(` ${green}✓${reset} Removed copilot-instructions.md (was EZ-only)`);
1675
1675
  } else if (cleaned !== content) {
1676
1676
  fs.writeFileSync(instructionsPath, cleaned);
1677
1677
  removedCount++;
1678
- console.log(` ${green}✓${reset} Cleaned EZ Agents section from copilot-instructions.md`);
1678
+ console.log(` ${green}✓${reset} Cleaned EZ_Agents section from copilot-instructions.md`);
1679
1679
  }
1680
1680
  }
1681
1681
  } else {
@@ -1687,15 +1687,15 @@ function uninstall(isGlobal, runtime = 'claude') {
1687
1687
  }
1688
1688
  }
1689
1689
 
1690
- // 2. Remove get-shit-done directory
1691
- const ezDir = path.join(targetDir, 'get-shit-done');
1690
+ // 2. Remove ez-agents directory
1691
+ const ezDir = path.join(targetDir, 'ez-agents');
1692
1692
  if (fs.existsSync(ezDir)) {
1693
1693
  fs.rmSync(ezDir, { recursive: true });
1694
1694
  removedCount++;
1695
- console.log(` ${green}✓${reset} Removed get-shit-done/`);
1695
+ console.log(` ${green}✓${reset} Removed ez-agents/`);
1696
1696
  }
1697
1697
 
1698
- // 3. Remove EZ Agents agents (ez-*.md files only)
1698
+ // 3. Remove EZ_Agents agents (ez-*.md files only)
1699
1699
  const agentsDir = path.join(targetDir, 'agents');
1700
1700
  if (fs.existsSync(agentsDir)) {
1701
1701
  const files = fs.readdirSync(agentsDir);
@@ -1708,7 +1708,7 @@ function uninstall(isGlobal, runtime = 'claude') {
1708
1708
  }
1709
1709
  if (agentCount > 0) {
1710
1710
  removedCount++;
1711
- console.log(` ${green}✓${reset} Removed ${agentCount} EZ Agents agents`);
1711
+ console.log(` ${green}✓${reset} Removed ${agentCount} EZ_Agents agents`);
1712
1712
  }
1713
1713
  }
1714
1714
 
@@ -1836,7 +1836,7 @@ function uninstall(isGlobal, runtime = 'claude') {
1836
1836
  if (config.permission[permType]) {
1837
1837
  const keys = Object.keys(config.permission[permType]);
1838
1838
  for (const key of keys) {
1839
- if (key.includes('get-shit-done')) {
1839
+ if (key.includes('ez-agents')) {
1840
1840
  delete config.permission[permType][key];
1841
1841
  modified = true;
1842
1842
  }
@@ -1864,11 +1864,11 @@ function uninstall(isGlobal, runtime = 'claude') {
1864
1864
  }
1865
1865
 
1866
1866
  if (removedCount === 0) {
1867
- console.log(` ${yellow}⚠${reset} No EZ Agents files found to remove.`);
1867
+ console.log(` ${yellow}⚠${reset} No EZ_Agents files found to remove.`);
1868
1868
  }
1869
1869
 
1870
1870
  console.log(`
1871
- ${green}Done!${reset} EZ Agents has been uninstalled from ${runtimeLabel}.
1871
+ ${green}Done!${reset} EZ_Agents has been uninstalled from ${runtimeLabel}.
1872
1872
  Your other files and settings have been preserved.
1873
1873
  `);
1874
1874
  }
@@ -1936,7 +1936,7 @@ function parseJsonc(content) {
1936
1936
 
1937
1937
  /**
1938
1938
  * Configure OpenCode permissions to allow reading EZ reference docs
1939
- * This prevents permission prompts when EZ accesses the get-shit-done directory
1939
+ * This prevents permission prompts when EZ accesses the ez-agents directory
1940
1940
  * @param {boolean} isGlobal - Whether this is a global or local install
1941
1941
  */
1942
1942
  function configureOpencodePermissions(isGlobal = true) {
@@ -1974,8 +1974,8 @@ function configureOpencodePermissions(isGlobal = true) {
1974
1974
  // Use ~ shorthand if it's in the default location, otherwise use full path
1975
1975
  const defaultConfigDir = path.join(os.homedir(), '.config', 'opencode');
1976
1976
  const ezPath = opencodeConfigDir === defaultConfigDir
1977
- ? '~/.config/opencode/get-shit-done/*'
1978
- : `${opencodeConfigDir.replace(/\\/g, '/')}/get-shit-done/*`;
1977
+ ? '~/.config/opencode/ez-agents/*'
1978
+ : `${opencodeConfigDir.replace(/\\/g, '/')}/ez-agents/*`;
1979
1979
 
1980
1980
  let modified = false;
1981
1981
 
@@ -2003,7 +2003,7 @@ function configureOpencodePermissions(isGlobal = true) {
2003
2003
 
2004
2004
  // Write config back
2005
2005
  fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n');
2006
- console.log(` ${green}✓${reset} Configured read permission for EZ Agents docs`);
2006
+ console.log(` ${green}✓${reset} Configured read permission for EZ_Agents docs`);
2007
2007
  }
2008
2008
 
2009
2009
  /**
@@ -2086,7 +2086,7 @@ function writeManifest(configDir, runtime = 'claude') {
2086
2086
  const isOpencode = runtime === 'opencode';
2087
2087
  const isCodex = runtime === 'codex';
2088
2088
  const isCopilot = runtime === 'copilot';
2089
- const ezDir = path.join(configDir, 'get-shit-done');
2089
+ const ezDir = path.join(configDir, 'ez-agents');
2090
2090
  const commandsDir = path.join(configDir, 'commands', 'ez');
2091
2091
  const opencodeCommandDir = path.join(configDir, 'command');
2092
2092
  const codexSkillsDir = path.join(configDir, 'skills');
@@ -2095,7 +2095,7 @@ function writeManifest(configDir, runtime = 'claude') {
2095
2095
 
2096
2096
  const ezHashes = generateManifest(ezDir);
2097
2097
  for (const [rel, hash] of Object.entries(ezHashes)) {
2098
- manifest.files['get-shit-done/' + rel] = hash;
2098
+ manifest.files['ez-agents/' + rel] = hash;
2099
2099
  }
2100
2100
  if (!isOpencode && !isCodex && !isCopilot && fs.existsSync(commandsDir)) {
2101
2101
  const cmdHashes = generateManifest(commandsDir);
@@ -2132,7 +2132,7 @@ function writeManifest(configDir, runtime = 'claude') {
2132
2132
  }
2133
2133
 
2134
2134
  /**
2135
- * Detect user-modified EZ Agents files by comparing against install manifest.
2135
+ * Detect user-modified EZ_Agents files by comparing against install manifest.
2136
2136
  * Backs up modified files to ez-local-patches/ for reapply after update.
2137
2137
  */
2138
2138
  function saveLocalPatches(configDir) {
@@ -2239,7 +2239,7 @@ function install(isGlobal, runtime = 'claude') {
2239
2239
  // Track installation failures
2240
2240
  const failures = [];
2241
2241
 
2242
- // Save any locally modified EZ Agents files before they get wiped
2242
+ // Save any locally modified EZ_Agents files before they get wiped
2243
2243
  saveLocalPatches(targetDir);
2244
2244
 
2245
2245
  // Clean up orphaned files from previous versions
@@ -2309,14 +2309,14 @@ function install(isGlobal, runtime = 'claude') {
2309
2309
  console.log(` ${green}✓${reset} Installed ez-agents-update command`);
2310
2310
  }
2311
2311
 
2312
- // Copy get-shit-done skill with path replacement
2313
- const skillSrc = path.join(src, 'get-shit-done');
2314
- const skillDest = path.join(targetDir, 'get-shit-done');
2312
+ // Copy ez-agents skill with path replacement
2313
+ const skillSrc = path.join(src, 'ez-agents');
2314
+ const skillDest = path.join(targetDir, 'ez-agents');
2315
2315
  copyWithPathReplacement(skillSrc, skillDest, pathPrefix, runtime, false, isGlobal);
2316
- if (verifyInstalled(skillDest, 'get-shit-done')) {
2317
- console.log(` ${green}✓${reset} Installed get-shit-done`);
2316
+ if (verifyInstalled(skillDest, 'ez-agents')) {
2317
+ console.log(` ${green}✓${reset} Installed ez-agents`);
2318
2318
  } else {
2319
- failures.push('get-shit-done');
2319
+ failures.push('ez-agents');
2320
2320
  }
2321
2321
 
2322
2322
  // Copy agents to agents directory
@@ -2325,7 +2325,7 @@ function install(isGlobal, runtime = 'claude') {
2325
2325
  const agentsDest = path.join(targetDir, 'agents');
2326
2326
  fs.mkdirSync(agentsDest, { recursive: true });
2327
2327
 
2328
- // Remove old EZ Agents agents (ez-*.md) before copying new ones
2328
+ // Remove old EZ_Agents agents (ez-*.md) before copying new ones
2329
2329
  if (fs.existsSync(agentsDest)) {
2330
2330
  for (const file of fs.readdirSync(agentsDest)) {
2331
2331
  if (file.startsWith('ez-') && file.endsWith('.md')) {
@@ -2370,7 +2370,7 @@ function install(isGlobal, runtime = 'claude') {
2370
2370
 
2371
2371
  // Copy CHANGELOG.md
2372
2372
  const changelogSrc = path.join(src, 'CHANGELOG.md');
2373
- const changelogDest = path.join(targetDir, 'get-shit-done', 'CHANGELOG.md');
2373
+ const changelogDest = path.join(targetDir, 'ez-agents', 'CHANGELOG.md');
2374
2374
  if (fs.existsSync(changelogSrc)) {
2375
2375
  fs.copyFileSync(changelogSrc, changelogDest);
2376
2376
  if (verifyFileInstalled(changelogDest, 'CHANGELOG.md')) {
@@ -2381,7 +2381,7 @@ function install(isGlobal, runtime = 'claude') {
2381
2381
  }
2382
2382
 
2383
2383
  // Write VERSION file
2384
- const versionDest = path.join(targetDir, 'get-shit-done', 'VERSION');
2384
+ const versionDest = path.join(targetDir, 'ez-agents', 'VERSION');
2385
2385
  fs.writeFileSync(versionDest, pkg.version);
2386
2386
  if (verifyFileInstalled(versionDest, 'VERSION')) {
2387
2387
  console.log(` ${green}✓${reset} Wrote VERSION (${pkg.version})`);
@@ -2482,7 +2482,7 @@ function install(isGlobal, runtime = 'claude') {
2482
2482
 
2483
2483
  if (isCopilot) {
2484
2484
  // Generate copilot-instructions.md
2485
- const templatePath = path.join(targetDir, 'get-shit-done', 'templates', 'copilot-instructions.md');
2485
+ const templatePath = path.join(targetDir, 'ez-agents', 'templates', 'copilot-instructions.md');
2486
2486
  const instructionsPath = path.join(targetDir, 'copilot-instructions.md');
2487
2487
  if (fs.existsSync(templatePath)) {
2488
2488
  const template = fs.readFileSync(templatePath, 'utf8');
@@ -2647,13 +2647,13 @@ function handleStatusline(settings, isInteractive, callback) {
2647
2647
  Your current statusline:
2648
2648
  ${dim}command: ${existingCmd}${reset}
2649
2649
 
2650
- EZ Agents includes a statusline showing:
2650
+ EZ_Agents includes a statusline showing:
2651
2651
  • Model name
2652
2652
  • Current task (from todo list)
2653
2653
  • Context window usage (color-coded)
2654
2654
 
2655
2655
  ${cyan}1${reset}) Keep existing
2656
- ${cyan}2${reset}) Replace with EZ Agents statusline
2656
+ ${cyan}2${reset}) Replace with EZ_Agents statusline
2657
2657
  `);
2658
2658
 
2659
2659
  rl.question(` Choice ${dim}[1]${reset}: `, (answer) => {
@@ -2687,7 +2687,10 @@ function promptRuntime(callback) {
2687
2687
  ${cyan}3${reset}) Gemini ${dim}(~/.gemini)${reset}
2688
2688
  ${cyan}4${reset}) Codex ${dim}(~/.codex)${reset}
2689
2689
  ${cyan}5${reset}) Copilot ${dim}(~/.copilot)${reset}
2690
- ${cyan}6${reset}) All
2690
+ ${cyan}6${reset}) All ${dim}(all 5 runtimes above)${reset}
2691
+
2692
+ ${dim}Note: Qwen, Kimi, and OpenAI are model providers configured within each runtime's settings,
2693
+ not separate CLI runtimes. See README.md for model configuration.${reset}
2691
2694
  `);
2692
2695
 
2693
2696
  rl.question(` Choice ${dim}[1]${reset}: `, (answer) => {
@@ -2756,7 +2759,7 @@ function promptLocation(runtimes) {
2756
2759
  }
2757
2760
 
2758
2761
  /**
2759
- * Install EZ Agents for all selected runtimes
2762
+ * Install EZ_Agents for all selected runtimes
2760
2763
  */
2761
2764
  function installAllRuntimes(runtimes, isGlobal, isInteractive) {
2762
2765
  const results = [];
@@ -2767,38 +2770,78 @@ function installAllRuntimes(runtimes, isGlobal, isInteractive) {
2767
2770
  }
2768
2771
 
2769
2772
  const statuslineRuntimes = ['claude', 'gemini'];
2770
- const primaryStatuslineResult = results.find(r => statuslineRuntimes.includes(r.runtime));
2771
-
2772
- const finalize = (shouldInstallStatusline) => {
2773
- for (const result of results) {
2774
- const useStatusline = statuslineRuntimes.includes(result.runtime) && shouldInstallStatusline;
2775
- finishInstall(
2776
- result.settingsPath,
2777
- result.settings,
2778
- result.statuslineCommand,
2779
- useStatusline,
2780
- result.runtime,
2781
- isGlobal
2782
- );
2783
- }
2773
+ const statuslineResults = results.filter(r => statuslineRuntimes.includes(r.runtime));
2774
+
2775
+ // Handle statusline per-runtime to avoid conflicts
2776
+ // Each runtime with settings.json gets its own statusline prompt
2777
+ const finalizePerRuntime = (runtimeResult, shouldInstallStatusline) => {
2778
+ const useStatusline = statuslineRuntimes.includes(runtimeResult.runtime) && shouldInstallStatusline;
2779
+ finishInstall(
2780
+ runtimeResult.settingsPath,
2781
+ runtimeResult.settings,
2782
+ runtimeResult.statuslineCommand,
2783
+ useStatusline,
2784
+ runtimeResult.runtime,
2785
+ isGlobal
2786
+ );
2784
2787
  };
2785
2788
 
2786
- if (primaryStatuslineResult) {
2787
- handleStatusline(primaryStatuslineResult.settings, isInteractive, finalize);
2789
+ if (statuslineResults.length === 0) {
2790
+ // No runtimes support statusline - finalize all without statusline
2791
+ for (const result of results) {
2792
+ finalizePerRuntime(result, false);
2793
+ }
2794
+ } else if (statuslineResults.length === 1) {
2795
+ // Single runtime with statusline support - prompt once
2796
+ const singleResult = statuslineResults[0];
2797
+ handleStatusline(singleResult.settings, isInteractive, (shouldInstall) => {
2798
+ finalizePerRuntime(singleResult, shouldInstall);
2799
+ // Finalize other runtimes without statusline
2800
+ for (const result of results) {
2801
+ if (!statuslineRuntimes.includes(result.runtime)) {
2802
+ finalizePerRuntime(result, false);
2803
+ }
2804
+ }
2805
+ });
2788
2806
  } else {
2789
- finalize(false);
2807
+ // Multiple runtimes with statusline support - prompt for each
2808
+ let currentIndex = 0;
2809
+ const statuslineChoices = new Array(statuslineResults.length).fill(false);
2810
+
2811
+ const promptNextStatusline = () => {
2812
+ if (currentIndex >= statuslineResults.length) {
2813
+ // All statusline prompts done - finalize all runtimes
2814
+ for (let i = 0; i < results.length; i++) {
2815
+ const result = results[i];
2816
+ const statuslineIndex = statuslineResults.findIndex(r => r.runtime === result.runtime);
2817
+ const shouldInstall = statuslineIndex !== -1 ? statuslineChoices[statuslineIndex] : false;
2818
+ finalizePerRuntime(result, shouldInstall);
2819
+ }
2820
+ return;
2821
+ }
2822
+
2823
+ const currentResult = statuslineResults[currentIndex];
2824
+ const currentRuntimeIndex = currentIndex;
2825
+ handleStatusline(currentResult.settings, isInteractive, (shouldInstall) => {
2826
+ statuslineChoices[currentRuntimeIndex] = shouldInstall;
2827
+ currentIndex++;
2828
+ promptNextStatusline();
2829
+ });
2830
+ };
2831
+
2832
+ promptNextStatusline();
2790
2833
  }
2791
2834
  }
2792
2835
 
2793
2836
  // Test-only exports — skip main logic when loaded as a module for testing
2794
- if (process.env.GSD_TEST_MODE) {
2837
+ if (process.env.EZ_AGENTS_TEST_MODE) {
2795
2838
  module.exports = {
2796
2839
  getCodexSkillAdapterHeader,
2797
2840
  convertClaudeToGeminiAgent,
2798
2841
  convertClaudeAgentToCodexAgent,
2799
2842
  generateCodexAgentToml,
2800
2843
  generateCodexConfigBlock,
2801
- stripGsdFromCodexConfig,
2844
+ stripEzAgentsFromCodexConfig,
2802
2845
  mergeCodexConfig,
2803
2846
  installCodexConfig,
2804
2847
  convertClaudeCommandToCodexSkill,
@@ -2816,7 +2859,7 @@ if (process.env.GSD_TEST_MODE) {
2816
2859
  EZ_COPILOT_INSTRUCTIONS_MARKER,
2817
2860
  EZ_COPILOT_INSTRUCTIONS_CLOSE_MARKER,
2818
2861
  mergeCopilotInstructions,
2819
- stripGsdFromCopilotInstructions,
2862
+ stripEzAgentsFromCopilotInstructions,
2820
2863
  writeManifest,
2821
2864
  reportLocalPatches,
2822
2865
  };
@@ -2859,4 +2902,4 @@ if (hasGlobal && hasLocal) {
2859
2902
  }
2860
2903
  }
2861
2904
 
2862
- } // end of else block for GSD_TEST_MODE
2905
+ } // end of else block for EZ_AGENTS_TEST_MODE
@@ -162,7 +162,7 @@ Task(
162
162
  <success_criteria>
163
163
  - [ ] Active sessions checked
164
164
  - [ ] Symptoms gathered (if new)
165
- - [ ] gsd-debugger spawned with context
165
+ - [ ] ez-debugger spawned with context
166
166
  - [ ] Checkpoints handled correctly
167
167
  - [ ] Root cause confirmed before fixing
168
168
  </success_criteria>
@@ -51,7 +51,7 @@ Check for .planning/STATE.md - loads context if project already initialized
51
51
  <process>
52
52
  1. Check if .planning/codebase/ already exists (offer to refresh or skip)
53
53
  2. Create .planning/codebase/ directory structure
54
- 3. Spawn 4 parallel gsd-codebase-mapper agents:
54
+ 3. Spawn 4 parallel ez-codebase-mapper agents:
55
55
  - Agent 1: tech focus → writes STACK.md, INTEGRATIONS.md
56
56
  - Agent 2: arch focus → writes ARCHITECTURE.md, STRUCTURE.md
57
57
  - Agent 3: quality focus → writes CONVENTIONS.md, TESTING.md