IDE Orchestration Mode

/ide opens a full-screen Python code editor for writing orchestration scripts. These scripts chain LLM calls into controllable, repeatable workflows with full tool-use capability (file read/write, bash execution). Scripts use standard Python syntax β€” no custom DSL.

Key Capabilities:


What Is IDE Mode?

IDE mode is a workflow authoring environment, not a traditional code editor. You write Python scripts that call injected async functions (llm_call, llm_confirm, llm_judge) to orchestrate LLM tasks. The editor compiles your script into LLM tool calls with full tool-use capability.

/ide                  β†’ Open draft list popup, select a draft to enter editor
/ide new <name>       β†’ Create a new draft and open blank editor
/ide rename <old> <new> β†’ Rename a draft
Ctrl+I               β†’ TUI shortcut to open draft list

Workflow Modes

Mode Action What Happens
Preview F5 Auto-format (black) β†’ AST static analysis β†’ show expanded steps in exec panel
Run F6 Validate β†’ save draft β†’ exit editor β†’ execute script in TUI
Save Draft Ctrl+S (1st) Save to draft file + auto-format
Exit with Code Ctrl+S (2nd) Save draft + exit editor with code for TUI execution
Exit Empty Esc Exit editor without saving

Injected Functions

IDE mode injects three async functions into the script scope. All can be used with await:

llm_call

Send a prompt to the LLM and get a response. Each call reuses a separate conversation history (via LLMBridge) so IDE conversations never pollute your main chat.

result = await llm_call("Refactor the UserService class to use dependency injection")
print(result)

The LLM has full tool-use capability β€” it can read files, execute bash commands, and write files. Tools execute automatically without permission prompts (IDE is an automation environment).

HYBRID execution: When run from the TUI (F6), llm_call routes through a message queue to the worker thread, which streams tokens directly to the TUI output. When run in isolation (F5 preview, CLI), it directly calls the LLM API.

Tool Execution: The LLM can use these tools automatically:

All tool calls execute without permission prompts in IDE mode.

llm_confirm

Present a confirmation prompt. Always returns True in the current implementation (auto-approved, no confirmation dialog).

approved = await llm_confirm("Should we proceed with the database migration?")
if approved:
    result = await llm_call("Apply the migration")

llm_judge

Have the LLM evaluate a natural-language condition against the recent conversation context. Returns a boolean. Context is automatically built from the last 4 messages (2 rounds) of the IDE conversation, truncated to 500 characters each.

is_valid = await llm_judge("Does the generated SQL follow PostgreSQL best practices?")
if is_valid:
    print("Approved")
else:
    print("Needs revision")

The judge uses a synchronous LLM call with temperature=0 for determinism. If the LLM call fails or returns an unparseable response, it degrades to returning True (safe fallback for manual confirmation).


Keyboard Shortcuts

Editor Shortcuts

Key Action
F5 Preview β€” auto-format (black) + AST static analysis + show expanded steps in exec panel
F6 Run β€” validate + save draft + exit editor for TUI execution
F9 Manual validation (check syntax + security without previewing)
Ctrl+S 1st press: save draft + auto-format; 2nd press: save + exit with code
Esc Exit editor without saving
Ctrl+Z Undo
Ctrl+R Redo
Tab Indent (4 spaces); with selection: indent all selected lines
Shift+Tab Dedent; with selection: dedent all selected lines
Ctrl+Space Manually trigger code completion menu
Enter Accept completion item (if menu active) or newline with auto-indent
Backspace / Delete If text selected: cut selection; otherwise: delete character
Ctrl+H Same as Backspace (many terminals map Backspace to Ctrl+H)

Clipboard

Key Action
Ctrl+C Copy selected text to system clipboard
Ctrl+V Paste from system clipboard

Execution Panel (visible after F5)

Key Action
Ctrl+P Copy entire exec panel output to clipboard
Esc Return focus from panel to editor
Up / Down Scroll panel by 1 line (when panel focused)
PageUp / PageDown Scroll panel by screen height (when panel focused)
Ctrl+Y / Ctrl+U Scroll panel up / down 10 lines (regardless of focus)
Ctrl+Home / Ctrl+End Scroll to top / bottom of panel (regardless of focus)
Ctrl+= / Ctrl+- Resize panel by 3 lines
Ctrl+Up / Ctrl+Down Resize panel by 10% of screen height
Double-click Toggle panel fullscreen / restore
Ctrl+Tab Switch focus between editor and exec panel

Safety Sandbox

IDE mode runs in a sandboxed environment with restricted capabilities.

Blocked Imports

The following modules are blocked. Detection uses AST-based analysis β€” it checks every import and from ... import statement at parse time, including submodule imports (e.g. os.path is blocked because os is in the list):

os, subprocess, shutil, socket, ctypes, sys, io

Attempting to import a blocked module raises a SecurityError with the exact line number. The security check is defined in py_runner.py and shared with validator.py as a single source of truth.

Allowed Operations


Execution Architecture

Preview (F5) β€” AST Static Analysis

Press F5 to see how your script compiles before running. The dry-run engine (dry_run.py):

  1. Parses the code with ast.parse()
  2. Walks the AST tree recursively through For/While/If/Try/With blocks
  3. Extracts llm_call("prompt") calls with line numbers
  4. Detects loop structures and counts iterations where statically determinable (range(N), list literals)
  5. Shows each step with line number, prompt text, and iteration markers
Script Analysis:
  L12  await llm_call("List all tables...")  [X 1]
  L18  await llm_call("Generate ALTER TABLE...")  [X 1]
  L25  await llm_judge("Does this SQL follow...")  [X 1]
  L30  [conditional] if is_valid: print approved

  Calls: 2 llm_call, 1 llm_judge
  Est. rounds: ~3

Iteration markers:

F-strings are converted to templates for preview (e.g., f"process {file}" becomes process {file}).

Auto-Format: Before preview, the editor automatically formats your code with black (if installed). If formatting changes the code, it's reflected in the editor buffer.

Run (F6) β€” Script Execution

Press F6 to run the script. The execution pipeline:

  1. Validate β€” PythonValidator checks syntax (ast.parse) and security (banned imports via AST walk)
  2. Save Draft β€” Script saved to ~/.niuma/projects/{project}/ide/{name}.py
  3. Exit Editor β€” Code passed to TUI as [["__f6_code__", code]]
  4. Execute β€” IDEExecutor.execute() runs in a daemon thread via py_runner.run_script()

The execution environment:

Execution Result

After script completion, a summary shows:

Error messages include line numbers for syntax errors, security violations, and runtime errors.

Error Handling


Editor Features

Visual Theme

The editor uses a clean light theme with syntax highlighting via Pygments (Python lexer):

Element Style
Editor background White (#ffffff)
Status bars (top/bottom) Blue (#2a5f8f) with white bold text
Line numbers Gray (#999999), current line dark bold (#333333)
Keywords Purple (#6f42c1) bold
Strings Red (#d73a49)
Comments Gray italic (#6a737d)
Function/variable names Blue (#005cc5)
Exec panel background Dark navy (#1a1a2e)

Code Completion

The editor provides intelligent code completion powered by Jedi:

Auto-Format

Drafts are formatted with black on F5 preview and Ctrl+S save. If black is not installed, formatting is silently skipped.

Status Bar

Execution Panel

The execution panel appears below the editor after pressing F5. It displays:

Panel Controls:


Draft Management

Scripts are saved as named drafts:

Draft List Controls

Key Action
Up / Down Navigate draft list
Enter Open selected draft in editor
d Delete selected draft
Esc / q Close draft list

Draft Templates

When creating a new draft with /ide new <name>, the editor opens with a default template:

# IDE orchestration script
# F5 to preview, F6 to run

await llm_call("Generate a simple hello world Python function")

This template demonstrates the basic llm_call syntax and includes comments explaining the workflow.


Example: Migration Script

# IDE orchestration script β€” database migration
# F5 to preview, F6 to run

# Step 1: Analyze current schema
schema = await llm_call("List all tables and columns in models/schema.py")
print("Current schema:\n", schema)

# Step 2: Generate migration SQL
migration = await llm_call(
    f"Generate ALTER TABLE SQL for adding 'created_at' column:\n{schema}"
)
print("Migration SQL:\n", migration)

# Step 3: Validate
is_valid = await llm_judge(
    "Does this SQL follow PostgreSQL best practices?"
)

if is_valid:
    print("Migration approved β€” ready to apply")
else:
    print("Migration needs revision β€” review the SQL")

Example: Multi-File Refactor

# Orchestration: extract auth logic into a separate module

# Step 1: Identify auth-related code
auth_files = await llm_call(
    "Find all files containing authentication logic (login, logout, token)"
)
print("Auth files:\n", auth_files)

# Step 2: Get confirmation
approved = await llm_confirm("Proceed with extracting auth module?")

if approved:
    # Step 3: Execute
    result = await llm_call(f"Refactor auth logic into auth/ package:\n{auth_files}")
    print("Result:\n", result)

Example: Loop Processing

# Orchestration: process multiple files in a loop

# Define files to process
files = ["config.json", "data.csv", "README.md"]

for file in files:
    # Analyze each file
    analysis = await llm_call(f"Analyze the structure of {file}")
    print(f"\n{file} analysis:\n", analysis)

    # Judge if file needs refactoring
    needs_refactor = await llm_judge(f"Does {file} need refactoring?")
    if needs_refactor:
        await llm_call(f"Refactor {file} for better readability")

Example: Conditional Workflow

# Orchestration: conditional logic based on LLM judgment

# Initial analysis
code_review = await llm_call("Review the authentication module for security issues")

# Judge severity
is_critical = await llm_judge("Are there critical security vulnerabilities?")

if is_critical:
    # Critical: fix immediately
    fix = await llm_call(f"Fix critical security issues:\n{code_review}")
    print("Critical fixes applied:\n", fix)
else:
    # Non-critical: log for later
    print("Non-critical issues found. Review later.")
    print(f"Issues:\n{code_review}")

When to Use IDE Mode

Good For Not Ideal For
Repeatable workflows Quick one-off edits
Multi-step pipelines Simple file changes
Audit trails (execution stats) Exploratory work
Complex conditional logic Tasks needing user-in-the-loop
Scripts with tool-use (file ops, bash) Single LLM calls
Loop processing multiple items Linear one-shot tasks