Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ export NVIDIA_API_KEY=nvapi-...

| Doc | Contents |
|-----|----------|
| **[HOW_TO_USE.md](docs/HOW_TO_USE.md)** | **Detailed premium startup, commands, and layouts guide** |
| **[GUIDE.md](docs/GUIDE.md)** | Full command reference + working playbooks + diagrams |
| [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) | System design |
| [docs/SESSIONS.md](docs/SESSIONS.md) | Session memory |
Expand Down
47 changes: 47 additions & 0 deletions docs/HOW_TO_USE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# How to Use ArrowCode

Welcome to **ArrowCode**, a premium, high-performance multi-agent terminal coding harness. ArrowCode cleanly overtakes your terminal screen, offering an immersive, glitch-free interactive development environment tailored to modern engineering workflows.

---

## Immersive Control Loop

When you open ArrowCode, it takes over the terminal window, hiding standard shell scrollback history to keep your focus perfectly locked. On exiting, your previous shell canvas is fully restored.

1. **The Startup Screen**:
- Offers cursor-based navigation (Arrow keys + Enter) to start a new worktree, resume a session, view history, or quit.
- Includes standard system shortcuts:
- `ctrl+w`: Start a new session / worktree.
- `ctrl+s`: Resume your previous session.
- `ctrl+q`: Gracefully quit the application and restore terminal.

2. **Core Operational Loop**:
- **`/plan [goal]`**: Start drafting an execution strategy for your target task.
- **Clarifying Questions**: ArrowCode's Orchestrator raises questions to eliminate ambiguity before touching any code.
- **`/confirm`**: Approves the compiled plan and kicks off parallel execution across main agents & spawnable worker swarms.
- **`/accept`**: Finalizes the changes, persists the session state, and cleanly logs out.

---

## Commands Catalog

| Command | Action / Explanation |
|---|---|
| `/help` | View help details and interactive command overlays. |
| `/plan [goal]` | Kick off the planning phase for a feature or bugfix. |
| `/confirm` | Approve the plan and begin automatic code construction and tests. |
| `/accept` | Conclude and save the session successfully. |
| `/reject [note]` | Decline the proposed changes and ask the agents to refine the result. |
| `/stop` | Freeze all currently running background execution runs immediately. |
| `/undo` | Walk back to the previous workspace checkpoint safely. |
| `/yolo` | Toggle automatic execution approval for all file edits and bash tools. |
| `/settings` | Open the full-screen terminal configuration dashboard. |
| `/exit` | Exit ArrowCode and cleanly restore your standard shell history. |

---

## Layout Modes

ArrowCode supports two beautiful premium layout experiences:
- **Classic Mode (Default)**: A clean minimalist chat pane showing elegant streaming conversation with a low-noise single-line status representing active agents (**ORCH**, **FE**, **BE**, **QA**).
- **Dashboard Mode**: An advanced 2x2 terminal overlay showing live agent terminals, a swarm map tree, plan checklists, active file tree, and code diff highlights. Run `/swarm` (or `/layout`) to toggle layouts instantly.
7 changes: 7 additions & 0 deletions src/brand/banner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ export const BANNER_COMPACT = `
`.replace(/^\n/, "");

/** Clean line-art mark for small terminals / headers */
export const PREMIUM_MINIMAL_ASCII = `
▞▀▖
▚▄▘▛▀▖▛▀▖▞▀▖▌ ▌▞▀▖
▞ ▖▙▄▘▙▄▘▌ ▌▐▐ ▌▌ ▌
▚▄▘▛ ▘▛ ▘▚▄▘ ▘ ▘▚▄▘
`.trim();

export const MARK = `
/\\
/ \\ ARROWCODE
Expand Down
146 changes: 32 additions & 114 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,123 +259,41 @@ async function main() {
console.log("\n[metrics]", harness.metricsLine());
process.exit(0);
} else {
// CLI Interactive Session (like Claude Code) is now the default!
const readline = await import("node:readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});

console.log("\n================================================================");
console.log(" /\\");
console.log(" / \\ ARROWCODE Interactive CLI");
console.log(" / /\\ \\ swarm coding harness");
console.log(" /______\\ ORCH · FE · BE · QA");
console.log("================================================================\n");
console.log(" Welcome! You are in the interactive CLI mode (similar to Claude Code).");
console.log(" - Type standard prompt to chat with the agents.");
console.log(" - Use /plan <goal> to propose a new plan.");
console.log(" - Use /add <filepath> to attach a file to the context.");
console.log(" - Use /swarm to launch the fullscreen dashboard TUI.");
console.log(" - Use /confirm to approve and execute the current plan.");
console.log(" - Use /accept to finish and save changes.");
console.log(" - Use /help to see all available commands.");
console.log(" - Type /exit or /quit to quit.\n");

const attachedFiles: { path: string; content: string }[] = [];

const promptUser = () => {
rl.question("arrowcode> ", async (answer) => {
const line = answer.trim();
if (!line) {
promptUser();
return;
}
if (line === "/exit" || line === "/quit") {
rl.close();
process.exit(0);
}

let cmdLine = line;
if (cmdLine.startsWith(".")) {
cmdLine = "/" + cmdLine.slice(1);
}
// Enter alternate screen buffer to cleanly overtake the whole terminal canvas
// and hide scrollback history while running.
process.stdout.write("\x1b[?1049h\x1b[H");

if (cmdLine === "/swarm") {
rl.close();
console.log("\nLaunching Multi-Agent Swarm TUI Dashboard...");
const { render } = await import("ink");
const { App } = await import("./tui/App");
const { waitUntilExit } = render(
React.createElement(App, {
harness,
config: cfg,
initialPrompt: undefined,
}),
{ exitOnCtrlC: true },
);
await waitUntilExit();
process.exit(0);
}

if (cmdLine.startsWith("/add ")) {
const filePath = cmdLine.slice(5).trim();
try {
const absolutePath = harness.workspace.resolve(filePath, { mustExist: true });
const fs = await import("node:fs");
const content = fs.readFileSync(absolutePath, "utf8");
const lineCount = content.split("\n").length;
attachedFiles.push({ path: filePath, content });
console.log(`[system] Attached file ${filePath} (${lineCount} lines)`);
} catch (err: any) {
console.log(`[system] Error: Failed to attach file: ${err.message}`);
}
promptUser();
return;
}

if (cmdLine.startsWith("/")) {
// Dispatch command
const [cmd, ..._rest] = cmdLine.slice(1).split(/\s+/);
const { dispatchCommand } = await import("./commands/registry");
const exitAlternateScreen = () => {
process.stdout.write("\x1b[?1049l\x1b[?25h");
};

let modifiedCmdLine = cmdLine;
if (cmd === "plan" && attachedFiles.length > 0) {
const attachmentBlock = attachedFiles
.map((f) => `=== ATTACHED FILE: ${f.path} ===\n${f.content}\n===============================`)
.join("\n\n");
modifiedCmdLine = `/plan ${attachmentBlock}\n\nUser Request:\n${cmdLine.slice(5).trim()}`;
attachedFiles.length = 0;
}
process.on("exit", exitAlternateScreen);
process.on("SIGINT", () => {
exitAlternateScreen();
process.exit(130);
});
process.on("uncaughtException", (err) => {
exitAlternateScreen();
console.error(err);
process.exit(1);
});

const res = await dispatchCommand(modifiedCmdLine, {
harness,
setYolo: () => {},
getYolo: () => false,
});
if (res.type === "exit") {
rl.close();
process.exit(0);
}
if (res && "message" in res && res.message) {
console.log(`[system] ${res.message}`);
}
} else {
let payload = line;
if (attachedFiles.length > 0) {
const attachmentBlock = attachedFiles
.map((f) => `=== ATTACHED FILE: ${f.path} ===\n${f.content}\n===============================`)
.join("\n\n");
payload = `${attachmentBlock}\n\nUser Prompt:\n${line}`;
attachedFiles.length = 0;
}
await harness.chat(payload);
}
promptUser();
});
};
promptUser();
return;
try {
const { render } = await import("ink");
const { App } = await import("./tui/App");
const { waitUntilExit } = render(
React.createElement(App, {
harness,
config: cfg,
initialPrompt: undefined,
}),
{ exitOnCtrlC: true },
);
await waitUntilExit();
} finally {
exitAlternateScreen();
}
process.exit(0);
}
}

Expand Down
Loading
Loading