Skip to content

Unify installation & kill prompt fragmentation - #524

Closed
namastex888 wants to merge 7 commits into
mainfrom
dev
Closed

namastex888 wants to merge 7 commits into
mainfrom
dev

Conversation

@namastex888

@namastex888 namastex888 commented Mar 10, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Delete dead code: removed genie install command, install-genie-cli.sh, and CLI router entry
  • Orchestration prompt to ~/.claude/rules/: moved TEAM_LEAD_PROMPT from filesystem-loaded .md (broken in production bundles) to auto-injected rules file via install.sh and smart-install.js
  • promptMode setting: configurable 'append' (default, --append-system-prompt) vs 'system' (--system-prompt) in ~/.genie/config.json
  • Zero-touch install.sh: curl | bash does everything with zero interaction — installs tmux, creates config, injects orchestration prompt, sets tmux defaults, installs Claude Code plugin
  • smart-install.js maintenance: gains inlined orchestration prompt injection, default config creation, and tmux base-index setup on version change
  • Dead code cleanup: removed unused system-detect exports left behind by prerequisites check removal

Test plan

  • bun run check passes (typecheck + lint + dead-code + 534 tests)
  • bun run build succeeds (0.41 MB bundle)
  • No import.meta.url for TEAM_LEAD_PROMPT.md in bundle
  • No orchestration prompt content in bundle (lives in ~/.claude/rules/ now)
  • promptMode: 'append' produces --append-system-prompt flag
  • promptMode: 'system' produces --system-prompt flag
  • Independent reviewer returned SHIP verdict with zero CRITICAL/HIGH gaps

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Streamlined zero-interaction installation process with automatic tmux configuration
    • New prompt mode configuration option (append or system) for controlling prompt injection behavior
  • Bug Fixes

    • Automatic repair of broken symlinks during installation
  • Refactor

    • System prompts now auto-injected at install time instead of loaded at runtime

@coderabbitai

coderabbitai Bot commented Mar 10, 2026 •

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 815ef857-ee59-45be-a15e-caa1a619d41b

📥 Commits

Reviewing files that changed from the base of the PR and between 855db91 and 5316f18.

⛔ Files ignored due to path filters (3)
  • TEAM_LEAD_PROMPT.md is excluded by !*.md
  • plugins/genie/scripts/smart-install.js is excluded by !plugins/genie/scripts/**
  • plugins/genie/scripts/src/install-genie-cli.sh is excluded by !plugins/genie/scripts/**
📒 Files selected for processing (12)
  • .genie/wishes/unify-install-kill-fragmentation/WISH.md
  • install.sh
  • src/genie-commands/__tests__/tui.test.ts
  • src/genie-commands/install.ts
  • src/genie-commands/setup.ts
  • src/genie-commands/tui.ts
  • src/genie.ts
  • src/lib/genie-config.ts
  • src/lib/system-detect.ts
  • src/lib/team-lead-command.ts
  • src/term-commands/msg.test.ts
  • src/types/genie-config.ts

📝 Walkthrough

Walkthrough

This PR removes the interactive installation command and filesystem-based team lead prompt loading, replacing them with auto-injected orchestration rules written to ~/.claude/rules/genie-orchestration.md. It introduces a configurable promptMode (append/system) to control system prompt CLI flag behavior, removes OS/distro detection code, and converts installation to a non-interactive automated flow.

Changes

Cohort / File(s) Summary
Installation Script Refactoring
install.sh
Added helper functions: inject_orchestration_prompt(), create_default_config(), install_tmux_if_needed(), configure_tmux_defaults(). Converted interactive plugin installation to non-interactive flow; automatic repair of broken symlinks; orchestration prompt auto-injected; tmux config automated; success messaging updated.
Installation Command Removal
src/genie-commands/install.ts, src/genie.ts
Removed entire installCommand export and all prerequisite-checking/installation logic (~337 lines). Deleted CLI router entry for "install" subcommand, eliminating "genie install" functionality.
Prompt Mode Configuration
src/types/genie-config.ts, src/genie-commands/setup.ts
Added promptMode field to GenieConfigSchema with enum ['append', 'system'] defaulting to 'append'. Removed prerequisites check from setup flow; added configurePromptMode() to interactively select prompt injection strategy.
Team Lead Prompt Handling
src/lib/team-lead-command.ts, src/genie-commands/tui.ts
Removed runtime filesystem loading of team lead prompt. buildTeamLeadCommand() now resolves promptMode dynamically and selects --system-prompt vs --append-system-prompt flag. persistSystemPrompt() writes only provided content. Updated warning message to indicate orchestration-rules-only operation.
System Detection Cleanup
src/lib/system-detect.ts
Removed all OS/distro detection types (OSType, LinuxDistro, PackageManager, SystemInfo, PrerequisiteStatus) and related functions (getOSType(), detectSystem(), checkAllPrerequisites(), etc.); retained checkCommand() only.
Config Exports
src/lib/genie-config.ts
Exported loadGenieConfigSync() for external module use; no behavioral changes.
Test Updates
src/genie-commands/__tests__/tui.test.ts, src/term-commands/msg.test.ts
Updated assertions to expect --append-system-prompt flag as default (when promptMode is 'append'); added test for --system-prompt when promptMode is 'system'.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: unifying the installation process and eliminating prompt fragmentation by moving orchestration prompts from runtime filesystem loading to install-time injection.
Docstring Coverage ✅ Passed Docstring coverage is 82.61% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dev

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly refactors the Genie CLI installation and configuration mechanisms to provide a more robust and user-friendly experience. The primary goal is to eliminate fragmentation and silent failures by unifying installation paths, automating prerequisite setup, and ensuring the critical AI orchestration prompt is consistently loaded. These changes aim to make the initial setup process seamless and reduce potential configuration issues for both new and existing users.

Highlights

  • Unified Zero-Touch Installation: The installation process has been streamlined significantly, enabling a zero-touch curl | bash experience. This includes automatic installation of tmux, creation of default configuration, injection of the orchestration prompt, setting tmux defaults, and installing the Claude Code plugin without user interaction.
  • Orchestration Prompt Relocation: The TEAM_LEAD_PROMPT content, which guides AI agents to use the Genie CLI, has been moved from a filesystem-loaded Markdown file to an auto-injected rules file (~/.claude/rules/genie-orchestration.md). This ensures it's always loaded by Claude Code, resolving issues with production bundles.
  • Configurable Prompt Mode: A new promptMode setting has been introduced in ~/.genie/config.json, allowing users to choose between 'append' (default, using --append-system-prompt) and 'system' (using --system-prompt) for how system prompts are injected into Claude Code.
  • Dead Code Removal: The redundant genie install command and the install-genie-cli.sh script have been removed, simplifying the codebase and reducing maintenance overhead.
  • Enhanced smart-install.js: The smart-install.js script now includes logic for inlining the orchestration prompt, creating default configurations, and setting tmux base-index upon version changes, improving marketplace installation reliability.
Changelog
  • .genie/wishes/unify-install-kill-fragmentation/WISH.md
    • Added a new wish document detailing the rationale, scope, decisions, and execution plan for unifying installation and prompt fragmentation.
  • TEAM_LEAD_PROMPT.md
    • Updated with a header comment indicating its role as the source of truth for content injected into ~/.claude/rules/genie-orchestration.md by installation scripts.
  • install.sh
    • Removed all interactive confirmation prompts, making the script zero-touch.
    • Added inject_orchestration_prompt() function to write the orchestration prompt to ~/.claude/rules/genie-orchestration.md.
    • Added create_default_config() function to create ~/.genie/config.json with default settings if it doesn't exist.
    • Added install_tmux_if_needed() function to automatically install tmux.
    • Added configure_tmux_defaults() function to set tmux base-index options in ~/.tmux.conf.
    • Modified offer_claude_plugin(), offer_openclaw_plugin(), and offer_codex_skills() to install plugins/skills directly without confirmation.
    • Updated print_success() and output_agent_prompt() messages to reflect the new zero-touch installation and provide clear next steps.
  • plugins/genie/.claude-plugin/plugin.json
    • Added skills, hooks, agents, and settings fields to the plugin manifest, pointing to their respective paths.
  • plugins/genie/scripts/smart-install.js
    • Added ORCHESTRATION_PROMPT constant with the inlined orchestration prompt content.
    • Implemented injectOrchestrationPrompt() to write the prompt to ~/.claude/rules/genie-orchestration.md on version change or if missing.
    • Implemented createDefaultConfig() to create ~/.genie/config.json if it doesn't exist.
    • Implemented ensureTmuxDefaults() to configure tmux base-index settings on version change.
    • Integrated these new functions into the main installation flow, guarded by version checks.
  • plugins/genie/scripts/src/install-genie-cli.sh
    • Removed the script, as its functionality is now integrated into install.sh and smart-install.js.
  • src/genie-commands/tests/tui.test.ts
    • Updated test assertions to expect --append-system-prompt instead of --system-prompt for default prompt mode.
  • src/genie-commands/install.ts
    • Removed the installCommand file, deprecating the genie install CLI command.
  • src/genie-commands/setup.ts
    • Removed the checkPrerequisites() function, as prerequisite checks are now handled by the unified installation scripts.
    • Added configurePromptMode() to allow users to select between 'append' and 'system' prompt modes during setup.
    • Updated the setup flow to include the new configurePromptMode step.
    • Modified the summary output to display the configured promptMode.
  • src/genie-commands/tui.ts
    • Updated a warning message regarding missing AGENTS.md to be an informational message, reflecting that orchestration rules are now always present via ~/.claude/rules/.
  • src/genie.ts
    • Removed the import of installCommand and the install command definition from the CLI router.
  • src/lib/genie-config.ts
    • Exported loadGenieConfigSync to allow other modules to synchronously load the Genie configuration.
  • src/lib/system-detect.ts
    • Removed various system detection functions and interfaces (OSType, LinuxDistro, PackageManager, SystemInfo, PrerequisiteStatus, getOSType, matchDistro, parseOsRelease, commandExists, detectPackageManager, detectSystem, checkAllPrerequisites, getDistroDisplayName) that were previously used by the removed install.ts command.
  • src/lib/team-lead-command.ts
    • Removed getTeamLeadPrompt() function and related imports (existsSync, readFileSync, dirname, fileURLToPath).
    • Updated persistSystemPrompt() to only write the AGENTS.md content, noting that the team-lead orchestration prompt is now injected via ~/.claude/rules/.
    • Modified buildTeamLeadCommand() to read the promptMode from the Genie configuration and use either --append-system-prompt or --system-prompt accordingly.
  • src/term-commands/msg.test.ts
    • Updated test assertions for buildTeamLeadCommand to expect --append-system-prompt by default.
    • Added a new test case to verify that --system-prompt is used when promptMode is set to 'system'.
  • src/types/genie-config.ts
    • Added promptMode field to GenieConfigSchema with a default value of 'append', allowing configuration of how system prompts are handled.
Activity
  • The pull request description indicates that an independent reviewer returned a 'SHIP' verdict with zero CRITICAL/HIGH gaps, suggesting a thorough review has already taken place.
  • The PR was generated using Claude Code, indicating AI assistance in its creation.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review


P2 Badge Reorder marker update before prompt version check

injectOrchestrationPrompt() is called after installDeps(), but installDeps() rewrites ~/.genie/.install-version to the current plugin version first. Because injectOrchestrationPrompt() compares marker version to plugin version, upgrades with an existing genie-orchestration.md file will see versions as equal and skip rewriting, so prompt content changes in newer plugin versions will never propagate for existing users.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

const teamLeadPrompt = getTeamLeadPrompt();
const fullPrompt = [systemPrompt, teamLeadPrompt].filter(Boolean).join('\n\n');
if (!fullPrompt) return null;
if (!systemPrompt) return null;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve orchestration prompt when no AGENTS.md is present

This change drops the built-in TEAM_LEAD_PROMPT.md fallback and now returns early when systemPrompt is missing, so team-lead launches can run with no orchestration prompt at all. That is a regression for update/install paths that do not execute install.sh or smart-install.js (for example genie update via bun install -g / npm install -g), because those paths do not create ~/.claude/rules/genie-orchestration.md; in that case Claude starts without the mandatory genie CLI instructions.

Useful? React with 👍 / 👎.

// Ignore
}

if (currentVersion === pluginVersion) return;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Fix tmux-defaults guard so install path can execute

ensureTmuxDefaults() exits when marker and plugin versions match, but that check runs after installDeps() has already updated the marker to the current version. In the normal install/upgrade path where needsInstall() is true, this makes the function return immediately and never write base-index defaults, so marketplace installs silently miss the tmux configuration this commit intends to enforce.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/genie-commands/__tests__/tui.test.ts (1)

63-68: 🧹 Nitpick | 🔵 Trivial

Stale test comment.

The comment says "buildTeamLeadCommand always loads TEAM_LEAD_PROMPT.md if it exists" but the implementation no longer does this. The orchestration prompt is now injected at install-time into ~/.claude/rules/. Update the comment to reflect current behavior.

Proposed fix
   test('without explicit system prompt still includes --system-prompt from team-lead prompt', () => {
     const cmd = buildClaudeCommand('genie');
-    // buildTeamLeadCommand always loads TEAM_LEAD_PROMPT.md if it exists
-    // In test env it may or may not exist, but the flag structure is correct
+    // Without a systemPrompt argument, no prompt flag is emitted.
+    // Orchestration rules are injected at install-time into ~/.claude/rules/
     expect(cmd).toContain('--team-name');
   });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/genie-commands/__tests__/tui.test.ts` around lines 63 - 68, Update the
stale test comment in the test for buildClaudeCommand: replace the line stating
"buildTeamLeadCommand always loads TEAM_LEAD_PROMPT.md if it exists" with a
current explanation that orchestration/team-lead prompts are injected at
install-time into the ~/.claude/rules/ directory (and therefore may or may not
be present in the test environment), so the test only asserts the flag structure
(e.g., that buildClaudeCommand('genie') includes '--team-name'); keep the rest
of the test unchanged and reference buildClaudeCommand and buildTeamLeadCommand
in the updated comment.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@install.sh`:
- Around line 868-884: The configure_tmux_defaults function currently exits if
any "base-index" is found but unconditionally writes both settings, so a missing
"pane-base-index" may never be added; update configure_tmux_defaults to detect
each setting separately (e.g., test grep -q for "set -g base-index" and for
"setw -g pane-base-index") and only append the specific missing lines to
$HOME/.tmux.conf instead of bailing out or appending both unconditionally; keep
the function name configure_tmux_defaults and the tmux_conf variable usage so
the change is localized.
- Around line 931-943: The script calls inject_orchestration_prompt twice in the
run_install flow; remove the redundant invocation so the orchestration prompt is
injected only once (keep the single call that logically follows locating the
package directory and/or the header "Configuring Claude Code..."); update the
run_install sequence to call inject_orchestration_prompt a single time and
ensure surrounding steps (locate_package_dir, error handling, log "Package
directory: $PKG_DIR", and header "Configuring Claude Code...") remain intact.
- Around line 508-589: The file contains a duplicate definition of the function
inject_orchestration_prompt which is shadowed by an identical definition later,
making the first one dead code; remove the entire first
inject_orchestration_prompt function block (the one that creates
~/.claude/rules/genie-orchestration.md and writes the HEREDOC) so only the later
definition remains, ensuring no other callers rely on the removed copy and that
the remaining inject_orchestration_prompt provides the intended behavior.

In `@plugins/genie/.claude-plugin/plugin.json`:
- Around line 11-14: The manifest plugin.json references missing paths (keys
"skills", "hooks", "agents", and "settings") inside
plugins/genie/.claude-plugin; either create the referenced items or remove the
manifest entries: add a skills directory (./skills) with at least an index or
README, add hooks/hooks.json (or a hooks directory with the expected
hooks.json), add an agents directory (./agents) with the required agent files,
and/or add settings.json with the plugin settings; alternatively delete the
corresponding keys ("skills", "hooks", "agents", "settings") from plugin.json if
those features are not used so the manifest no longer points to non-existent
files.

---

Outside diff comments:
In `@src/genie-commands/__tests__/tui.test.ts`:
- Around line 63-68: Update the stale test comment in the test for
buildClaudeCommand: replace the line stating "buildTeamLeadCommand always loads
TEAM_LEAD_PROMPT.md if it exists" with a current explanation that
orchestration/team-lead prompts are injected at install-time into the
~/.claude/rules/ directory (and therefore may or may not be present in the test
environment), so the test only asserts the flag structure (e.g., that
buildClaudeCommand('genie') includes '--team-name'); keep the rest of the test
unchanged and reference buildClaudeCommand and buildTeamLeadCommand in the
updated comment.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 49a1e415-b518-43ca-bf55-037eefd25d87

📥 Commits

Reviewing files that changed from the base of the PR and between 79e364d and 855db91.

⛔ Files ignored due to path filters (3)
  • TEAM_LEAD_PROMPT.md is excluded by !*.md
  • plugins/genie/scripts/smart-install.js is excluded by !plugins/genie/scripts/**
  • plugins/genie/scripts/src/install-genie-cli.sh is excluded by !plugins/genie/scripts/**
📒 Files selected for processing (13)
  • .genie/wishes/unify-install-kill-fragmentation/WISH.md
  • install.sh
  • plugins/genie/.claude-plugin/plugin.json
  • src/genie-commands/__tests__/tui.test.ts
  • src/genie-commands/install.ts
  • src/genie-commands/setup.ts
  • src/genie-commands/tui.ts
  • src/genie.ts
  • src/lib/genie-config.ts
  • src/lib/system-detect.ts
  • src/lib/team-lead-command.ts
  • src/term-commands/msg.test.ts
  • src/types/genie-config.ts
💤 Files with no reviewable changes (3)
  • src/genie.ts
  • src/lib/system-detect.ts
  • src/genie-commands/install.ts

Comment thread install.sh
Comment on lines +508 to +589
inject_orchestration_prompt() {
local rules_dir="$HOME/.claude/rules"
local dest="$rules_dir/genie-orchestration.md"

mkdir -p "$rules_dir"

cat > "$dest" <<'ORCHESTRATION_HEREDOC'
<!-- SOURCE OF TRUTH: This content is injected into ~/.claude/rules/genie-orchestration.md
by install.sh and smart-install.js. Edits here must be copied to both scripts. -->
<GENIE_CLI>
# Genie CLI — MANDATORY Agent Orchestration

You are a team-lead in a **genie-managed environment**. ALL agent spawning, messaging, and team management MUST go through the genie CLI via Bash.

## CRITICAL: NEVER Use These Native Tools

NEVER use the `Agent` tool to spawn agents or subagents. Use `genie agent spawn` instead.
NEVER use `SendMessage` to communicate with agents. Use `genie send` instead.
NEVER use `TeamCreate` or `TeamDelete`. Use `genie team ensure` / `genie team delete` instead.

If you catch yourself about to use Agent, SendMessage, TeamCreate, or TeamDelete — STOP and use the genie CLI equivalent below.

## Agents

```bash
# Spawn an agent (ALWAYS use this instead of Agent tool)
genie agent spawn --role <role> # implementor, tests, review, fix, refactor
genie agent spawn --role <role> --skill <skill> # With specific skill

# Monitor
genie agent list # List all agents
genie agent dashboard # Live dashboard
genie agent history <agent> # Session history
genie agent read <agent> --follow # Tail terminal output

# Control
genie agent kill <id> # Force kill
genie agent suspend <id> # Suspend (preserves session)
genie agent exec <agent> "<cmd>" # Run command in agent pane
genie agent answer <agent> <choice> # Answer prompt (1-9 or text:...)
```

## Messaging

```bash
# Send message to an agent (ALWAYS use this instead of SendMessage)
genie send "<text>" --to <agent> # Send to specific agent
genie inbox <agent> # View agent inbox
genie inbox <agent> --unread # Unread only
```

## Teams

```bash
genie team ensure <name> # Ensure team exists (creates if needed)
genie team list # List teams
genie team delete <name> # Delete team
```

## Typical Flow

```bash
# 1. Spawn an agent
genie agent spawn --role implementor

# 2. Monitor
genie agent list

# 3. Send instructions
genie send "Implement endpoint X" --to <agent-name>

# 4. Check progress
genie agent history <agent-name>

# 5. Shut down
genie agent kill <agent-id>
```
</GENIE_CLI>
ORCHESTRATION_HEREDOC

success "Orchestration prompt written to $dest"
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Dead code: duplicate function definition.

This inject_orchestration_prompt function (lines 508-589) is never executed because it's shadowed by the identical function defined again at lines 740-819. The static analyzer flagged this as SC2329.

Remove this first definition to eliminate dead code.

Proposed fix
-# ─────────────────────────────────────────────────────────────────────────────
-# Orchestration Prompt Injection
-# ─────────────────────────────────────────────────────────────────────────────
-
-inject_orchestration_prompt() {
-    local rules_dir="$HOME/.claude/rules"
-    local dest="$rules_dir/genie-orchestration.md"
-
-    mkdir -p "$rules_dir"
-
-    cat > "$dest" <<'ORCHESTRATION_HEREDOC'
-<!-- SOURCE OF TRUTH: This content is injected into ~/.claude/rules/genie-orchestration.md
-     by install.sh and smart-install.js. Edits here must be copied to both scripts. -->
-<GENIE_CLI>
-# Genie CLI — MANDATORY Agent Orchestration
-...
-</GENIE_CLI>
-ORCHESTRATION_HEREDOC
-
-    success "Orchestration prompt written to $dest"
-}

(Remove entire function block from lines 504-589)

🧰 Tools
🪛 Shellcheck (0.11.0)

[info] 508-589: This function is never invoked. Check usage (or ignored if invoked indirectly).

(SC2329)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@install.sh` around lines 508 - 589, The file contains a duplicate definition
of the function inject_orchestration_prompt which is shadowed by an identical
definition later, making the first one dead code; remove the entire first
inject_orchestration_prompt function block (the one that creates
~/.claude/rules/genie-orchestration.md and writes the HEREDOC) so only the later
definition remains, ensuring no other callers rely on the removed copy and that
the remaining inject_orchestration_prompt provides the intended behavior.

Comment thread install.sh
Comment on lines +868 to +884
configure_tmux_defaults() {
local tmux_conf="$HOME/.tmux.conf"

if [[ -f "$tmux_conf" ]] && grep -q "base-index" "$tmux_conf"; then
info "tmux base-index already configured"
return 0
fi

cat >> "$tmux_conf" <<'TMUX_EOF'

# Genie defaults (required for agent orchestration)
set -g base-index 0
setw -g pane-base-index 0
TMUX_EOF

success "tmux defaults written to $tmux_conf"
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Potential duplicate pane-base-index line in tmux config.

The check at line 871 only looks for base-index, but the append block writes both base-index and pane-base-index. If a user has set -g base-index 0 but not pane-base-index, the function bails early and doesn't add pane-base-index. Conversely, if user has pane-base-index but not base-index, both lines get appended.

Consider checking for both or documenting the expected behavior.

Proposed fix
 configure_tmux_defaults() {
     local tmux_conf="$HOME/.tmux.conf"
 
-    if [[ -f "$tmux_conf" ]] && grep -q "base-index" "$tmux_conf"; then
+    if [[ -f "$tmux_conf" ]] && grep -q "base-index" "$tmux_conf" && grep -q "pane-base-index" "$tmux_conf"; then
         info "tmux base-index already configured"
         return 0
     fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
configure_tmux_defaults() {
local tmux_conf="$HOME/.tmux.conf"
if [[ -f "$tmux_conf" ]] && grep -q "base-index" "$tmux_conf"; then
info "tmux base-index already configured"
return 0
fi
cat >> "$tmux_conf" <<'TMUX_EOF'
# Genie defaults (required for agent orchestration)
set -g base-index 0
setw -g pane-base-index 0
TMUX_EOF
success "tmux defaults written to $tmux_conf"
}
configure_tmux_defaults() {
local tmux_conf="$HOME/.tmux.conf"
if [[ -f "$tmux_conf" ]] && grep -q "base-index" "$tmux_conf" && grep -q "pane-base-index" "$tmux_conf"; then
info "tmux base-index already configured"
return 0
fi
cat >> "$tmux_conf" <<'TMUX_EOF'
# Genie defaults (required for agent orchestration)
set -g base-index 0
setw -g pane-base-index 0
TMUX_EOF
success "tmux defaults written to $tmux_conf"
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@install.sh` around lines 868 - 884, The configure_tmux_defaults function
currently exits if any "base-index" is found but unconditionally writes both
settings, so a missing "pane-base-index" may never be added; update
configure_tmux_defaults to detect each setting separately (e.g., test grep -q
for "set -g base-index" and for "setw -g pane-base-index") and only append the
specific missing lines to $HOME/.tmux.conf instead of bailing out or appending
both unconditionally; keep the function name configure_tmux_defaults and the
tmux_conf variable usage so the change is localized.

Comment thread install.sh
Comment on lines +931 to +943
# ─── Inject orchestration prompt into ~/.claude/rules/ ───
inject_orchestration_prompt

# ─── Locate package directory ───
if ! locate_package_dir; then
error "Could not locate Genie package directory"
exit 1
fi
log "Package directory: $PKG_DIR"

# ─── Orchestration Prompt ───
header "Configuring Claude Code..."
inject_orchestration_prompt

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Duplicate invocation of inject_orchestration_prompt.

inject_orchestration_prompt is called twice in run_install:

  • Line 932: inject_orchestration_prompt
  • Line 943: inject_orchestration_prompt

Both calls write the same content to the same file. Remove one of them.

Proposed fix
     # ─── Genie CLI Install/Update ───
     header "Installing Genie CLI..."
     install_genie_cli
 
-    # ─── Inject orchestration prompt into ~/.claude/rules/ ───
-    inject_orchestration_prompt
-
     # ─── Locate package directory ───
     if ! locate_package_dir; then
         error "Could not locate Genie package directory"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# ─── Inject orchestration prompt into ~/.claude/rules/ ───
inject_orchestration_prompt
# ─── Locate package directory ───
if ! locate_package_dir; then
error "Could not locate Genie package directory"
exit 1
fi
log "Package directory: $PKG_DIR"
# ─── Orchestration Prompt ───
header "Configuring Claude Code..."
inject_orchestration_prompt
# ─── Locate package directory ───
if ! locate_package_dir; then
error "Could not locate Genie package directory"
exit 1
fi
log "Package directory: $PKG_DIR"
# ─── Orchestration Prompt ───
header "Configuring Claude Code..."
inject_orchestration_prompt
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@install.sh` around lines 931 - 943, The script calls
inject_orchestration_prompt twice in the run_install flow; remove the redundant
invocation so the orchestration prompt is injected only once (keep the single
call that logically follows locating the package directory and/or the header
"Configuring Claude Code..."); update the run_install sequence to call
inject_orchestration_prompt a single time and ensure surrounding steps
(locate_package_dir, error handling, log "Package directory: $PKG_DIR", and
header "Configuring Claude Code...") remain intact.

Comment on lines +11 to +14
"skills": "./skills",
"hooks": "./hooks/hooks.json",
"agents": "./agents",
"settings": "./settings.json"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify plugin manifest paths exist
cd plugins/genie/.claude-plugin

echo "Checking skills directory..."
ls -la skills 2>&1 || echo "NOT FOUND: skills"

echo "Checking hooks/hooks.json..."
ls -la hooks/hooks.json 2>&1 || echo "NOT FOUND: hooks/hooks.json"

echo "Checking agents directory..."
ls -la agents 2>&1 || echo "NOT FOUND: agents"

echo "Checking settings.json..."
ls -la settings.json 2>&1 || echo "NOT FOUND: settings.json"

Repository: automagik-dev/genie

Length of output: 497


Create missing plugin paths or remove manifest references.

The manifest fields reference paths that do not exist:

  • ./skills (directory missing)
  • ./hooks/hooks.json (file missing)
  • ./agents (directory missing)
  • ./settings.json (file missing)

These paths must be created in plugins/genie/.claude-plugin/ or the corresponding manifest entries removed if they are not intended to be used.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/genie/.claude-plugin/plugin.json` around lines 11 - 14, The manifest
plugin.json references missing paths (keys "skills", "hooks", "agents", and
"settings") inside plugins/genie/.claude-plugin; either create the referenced
items or remove the manifest entries: add a skills directory (./skills) with at
least an index or README, add hooks/hooks.json (or a hooks directory with the
expected hooks.json), add an agents directory (./agents) with the required agent
files, and/or add settings.json with the plugin settings; alternatively delete
the corresponding keys ("skills", "hooks", "agents", "settings") from
plugin.json if those features are not used so the manifest no longer points to
non-existent files.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request effectively unifies the installation process and resolves issues with prompt fragmentation, making install.sh zero-touch and removing the genie install command. However, a critical security concern was identified: the automatic loading of AGENTS.md from the current working directory could lead to indirect prompt injection attacks if the tool is run in an untrusted repository. A warning has been suggested to mitigate this risk. Additionally, there are areas with code duplication and logic in shell and JS scripts that could be more robust, impacting maintainability and correctness.

Comment thread src/genie-commands/tui.ts
Comment on lines 198 to 201
const systemPrompt = getAgentsSystemPrompt();
if (!systemPrompt) {
console.warn('Warning: No AGENTS.md found in current directory. Launching without --system-prompt.');
console.warn('Info: No AGENTS.md found in current directory. Team-lead will use orchestration rules only.');
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

The genie CLI automatically reads the content of AGENTS.md from the current working directory and uses it as a system prompt for Claude Code. Since Claude Code is launched with the --dangerously-skip-permissions flag (as seen in src/lib/team-lead-command.ts), it has unrestricted access to the user's shell. An attacker can place a malicious AGENTS.md file in a repository, and if a user runs genie in that directory, the attacker can manipulate the LLM to execute arbitrary commands on the user's system. This is a form of Indirect Prompt Injection.

    const systemPrompt = getAgentsSystemPrompt();
    if (systemPrompt) {
      console.warn('Warning: Loading system prompt from local AGENTS.md. Ensure you trust this directory.');
    } else {
      console.warn('Info: No AGENTS.md found in current directory. Team-lead will use orchestration rules only.');
    }

Comment thread install.sh
Comment on lines +871 to +874
if [[ -f "$tmux_conf" ]] && grep -q "base-index" "$tmux_conf"; then
info "tmux base-index already configured"
return 0
fi

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The check grep -q "base-index" "$tmux_conf" is not robust. It will match pane-base-index and will not add the settings if pane-base-index is already present but base-index is not. It also doesn't check for the correct value (0) or if the line is commented out. This could lead to an incomplete tmux configuration.

A more specific check for each setting would be more reliable.

Suggested change
if [[ -f "$tmux_conf" ]] && grep -q "base-index" "$tmux_conf"; then
info "tmux base-index already configured"
return 0
fi
if [[ -f "$tmux_conf" ]] && grep -q "^\s*set\s*-g\s*base-index\s*0" "$tmux_conf" 2>/dev/null && grep -q "^\s*setw\s*-g\s*pane-base-index\s*0" "$tmux_conf" 2>/dev/null; then
info "tmux base-index already configured"
return 0
fi

Comment on lines +400 to +404
if (!contents.includes('base-index 0')) {
const append = '\n# Genie defaults\nset -g base-index 0\nsetw -g pane-base-index 0\n';
writeFileSync(tmuxConf, contents + append, 'utf-8');
console.error('Added tmux base-index defaults to ~/.tmux.conf');
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The check !contents.includes('base-index 0') is not robust and can lead to an incorrect or duplicated tmux configuration. For example:

  1. It doesn't check for pane-base-index 0. If pane-base-index 0 is present but base-index 0 is not, this check will fail, and the entire block will be appended, duplicating pane-base-index 0.
  2. If the user has base-index 1, this check will also fail and append the block, leading to conflicting settings.

Consider checking for each setting individually before appending to make this function more reliable.

  let toAppend = '';
  if (!contents.includes('base-index 0')) {
    toAppend += '\nset -g base-index 0';
  }
  if (!contents.includes('pane-base-index 0')) {
    toAppend += '\nsetw -g pane-base-index 0';
  }

  if (toAppend) {
    const header = '\n# Genie defaults\n';
    writeFileSync(tmuxConf, contents + header + toAppend.trim() + '\n', 'utf-8');
    console.error('Added tmux base-index defaults to ~/.tmux.conf');
  }

Comment thread install.sh
Comment on lines +740 to +819
inject_orchestration_prompt() {
local rules_dir="$HOME/.claude/rules"
local rules_file="$rules_dir/genie-orchestration.md"

mkdir -p "$rules_dir"

cat > "$rules_file" <<'ORCHESTRATION_EOF'
<GENIE_CLI>
# Genie CLI — MANDATORY Agent Orchestration

You are a team-lead in a **genie-managed environment**. ALL agent spawning, messaging, and team management MUST go through the genie CLI via Bash.

## CRITICAL: NEVER Use These Native Tools

NEVER use the `Agent` tool to spawn agents or subagents. Use `genie agent spawn` instead.
NEVER use `SendMessage` to communicate with agents. Use `genie send` instead.
NEVER use `TeamCreate` or `TeamDelete`. Use `genie team ensure` / `genie team delete` instead.

If you catch yourself about to use Agent, SendMessage, TeamCreate, or TeamDelete — STOP and use the genie CLI equivalent below.

## Agents

```bash
# Spawn an agent (ALWAYS use this instead of Agent tool)
genie agent spawn --role <role> # implementor, tests, review, fix, refactor
genie agent spawn --role <role> --skill <skill> # With specific skill

# Monitor
genie agent list # List all agents
genie agent dashboard # Live dashboard
genie agent history <agent> # Session history
genie agent read <agent> --follow # Tail terminal output

# Control
genie agent kill <id> # Force kill
genie agent suspend <id> # Suspend (preserves session)
genie agent exec <agent> "<cmd>" # Run command in agent pane
genie agent answer <agent> <choice> # Answer prompt (1-9 or text:...)
```

## Messaging

```bash
# Send message to an agent (ALWAYS use this instead of SendMessage)
genie send "<text>" --to <agent> # Send to specific agent
genie inbox <agent> # View agent inbox
genie inbox <agent> --unread # Unread only
```

## Teams

```bash
genie team ensure <name> # Ensure team exists (creates if needed)
genie team list # List teams
genie team delete <name> # Delete team
```

## Typical Flow

```bash
# 1. Spawn an agent
genie agent spawn --role implementor

# 2. Monitor
genie agent list

# 3. Send instructions
genie send "Implement endpoint X" --to <agent-name>

# 4. Check progress
genie agent history <agent-name>

# 5. Shut down
genie agent kill <agent-id>
```
</GENIE_CLI>
ORCHESTRATION_EOF

success "Orchestration prompt written to $rules_file"
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This function inject_orchestration_prompt is defined twice in this file. The first definition is on lines 508-589. This second definition is a duplicate and should be removed to avoid confusion and maintenance issues.

Comment thread install.sh

# ─── Orchestration Prompt ───
header "Configuring Claude Code..."
inject_orchestration_prompt

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The inject_orchestration_prompt function is called twice within the run_install function. The first call is on line 932. This second call is redundant and can be removed.

* Ensure tmux base-index defaults are set in ~/.tmux.conf
* Only runs when version changes (or file missing).
*/
function ensureTmuxDefaults() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The version checking logic to decide whether to perform an action is duplicated here and in the injectOrchestrationPrompt function (lines 327-343). This could be extracted into a helper function to improve maintainability and reduce redundancy.

automagik-genie and others added 7 commits March 10, 2026 02:04
Remove `genie install` CLI command, its implementation in
`src/genie-commands/install.ts`, and the defunct shell script
`plugins/genie/scripts/src/install-genie-cli.sh`. The `shortcuts install`
subcommand is unaffected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move TEAM_LEAD_PROMPT.md delivery from runtime filesystem path resolution
(which breaks in production bundles) to install-time injection via
install.sh. The prompt is now written to ~/.claude/rules/genie-orchestration.md
which Claude Code auto-loads every session.

- Add inject_orchestration_prompt() to install.sh with full prompt content
- Call inject_orchestration_prompt() in run_install() after install_genie_cli
- Remove getTeamLeadPrompt() from team-lead-command.ts (no more import.meta.url)
- Simplify persistSystemPrompt() to only write AGENTS.md content (systemPrompt)
- Remove unused fileURLToPath, dirname, existsSync, readFileSync imports
- Add source-of-truth comment header to TEAM_LEAD_PROMPT.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove confirm() calls from install flow; keep definitions for uninstall
- check_and_repair_symlink: auto-repair broken symlinks without asking
- offer_claude_plugin/openclaw/codex_skills: install directly, no prompt
- Add inject_orchestration_prompt(): writes TEAM_LEAD_PROMPT to
  ~/.claude/rules/genie-orchestration.md
- Add install_tmux_if_needed(): installs tmux via package manager if absent
- Add create_default_config(): creates ~/.genie/config.json with defaults
  (promptMode: append, version: 2)
- Add configure_tmux_defaults(): appends base-index 0 to ~/.tmux.conf
- Update run_install(): calls new functions, removes INTERACTIVE branch
- Update print_success(): shows genie launch command and /onboarding hint
- Update output_agent_prompt(): reflects new next-steps

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ystem-prompt

Adds configurable promptMode ('append'|'system') to GenieConfigSchema.
Default 'append' preserves CC default prompt; 'system' replaces it.
Wires into buildTeamLeadCommand, setup wizard, and updates all tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… setup

- Inlines TEAM_LEAD_PROMPT as constant in smart-install.js (no fs dependency)
- Writes ~/.claude/rules/genie-orchestration.md on version change
- Creates ~/.genie/config.json with defaults if missing
- Ensures tmux base-index 0 in ~/.tmux.conf
- Fixes misleading tui.ts warning about missing system prompt

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… removal

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
All 6 execution groups complete, all success criteria met.
534/534 tests pass, bun run check exits 0, build succeeds.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants