ikie-cli 0.1.32 → 0.1.33

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.
package/README.md CHANGED
@@ -1,43 +1,189 @@
1
- # ikie
1
+ # Ikie
2
2
 
3
- **Agentic coding CLI** — your terminal AI pair programmer.
3
+ **Agentic coding CLI — your AI pair programmer in the terminal.**
4
+
5
+ Ikie reads, writes, and refactors code, runs commands, searches the web, and
6
+ drives multi-step engineering tasks autonomously — all from your shell, with a
7
+ polished interactive REPL and a one-shot mode for quick jobs.
4
8
 
5
9
  ```bash
6
10
  npm install -g ikie-cli
7
11
  ikie login
8
- ikie "write a rust web server"
12
+ ikie "write a rust web server with graceful shutdown"
9
13
  ```
10
14
 
11
- ## Features
15
+ ---
16
+
17
+ ## Highlights
18
+
19
+ - **Autonomous agent loop** — Ikie plans, edits files, runs builds/tests, reads
20
+ the errors, and self-corrects until the task is done.
21
+ - **Plan mode & agent mode** — research read-only and propose a plan, or execute
22
+ with full tool access. Toggle live with **Shift+Tab**.
23
+ - **28 built-in tools** — files, shell, search, git, web, memory, sub-agents.
24
+ - **Skills** — installable instruction packs that give Ikie expert knowledge for
25
+ a specific kind of task (UI/UX, research, framework conventions, …).
26
+ - **MCP support** — extend Ikie with Model Context Protocol servers (GitHub,
27
+ databases, browser automation, and any custom MCP).
28
+ - **Polished terminal UX** — markdown rendering, slash-command menu, 7 color
29
+ themes, image paste (Ctrl+V), session save/load, and live token/usage tracking.
30
+ - **Safe by default** — mutating actions ask for permission once (press `a` to
31
+ always-allow for the session); reads of secret files (`.env`, keys) are guarded.
12
32
 
13
- - 12 built-in tools: read/write/edit files, bash, search, grep, memory, agent spawn, web fetch & search
14
- - Interactive REPL with slash commands, markdown rendering, and session management
15
- - One-shot mode: `ikie "your prompt"`
16
- - Image paste support (Ctrl+V)
17
- - Theming (7 color schemes)
33
+ ---
18
34
 
19
35
  ## Quick start
20
36
 
21
37
  ```bash
22
- # Install
23
- npm install -g ikie
38
+ # 1. Install globally
39
+ npm install -g ikie-cli
24
40
 
25
- # Sign in to your ikie account
41
+ # 2. Sign in to your Ikie account
26
42
  ikie login
27
43
 
28
- # Start coding
29
- ikie "refactor this file and add tests"
44
+ # 3a. One-shot — run a single task and exit
45
+ ikie "add input validation to src/api/users.ts and write tests"
46
+
47
+ # 3b. Interactive — start a REPL session
48
+ ikie
49
+ ```
50
+
51
+ **Requirements:** Node.js 20+ and an Ikie account (`ikie login`).
52
+
53
+ ---
54
+
55
+ ## Modes
56
+
57
+ Ikie runs in one of two modes, shown in the prompt header:
58
+
59
+ | Mode | What it can do |
60
+ | --- | --- |
61
+ | **agent** *(default)* | Full access — edit files, run commands, everything. |
62
+ | **plan** | Read-only research. Ikie explores and proposes a plan but makes no changes until you approve. |
63
+
64
+ Switch any time with **Shift+Tab** (toggles in place), or with `/plan`, `/agent`,
65
+ and `/mode`. When a plan is approved, Ikie automatically switches to agent mode
66
+ and carries it out.
67
+
68
+ ---
69
+
70
+ ## Tools
71
+
72
+ Ikie has 28 built-in tools, grouped by purpose:
73
+
74
+ - **Files** — `read_file`, `write_file`, `edit_file` (surgical exact-string edits), `list_dir`
75
+ - **Search** — `search_files` (glob), `grep` (regex over contents)
76
+ - **Shell** — `bash` (builds, tests, package managers; `&` backgrounds long-running processes)
77
+ - **Git** — `git_status`, `git_diff`, `git_log`, `git_commit`, `git_branch`
78
+ - **Web** — `fetch_url` (read any page as text), `web_search` (no extra API key — your login is enough)
79
+ - **Memory** — `memory_write` (persist notes across sessions, project- or global-scoped)
80
+ - **Delegation** — `spawn_agent` (hand isolated/parallel work to a focused sub-agent), `ask_user`
81
+ - **Skills** — `use_skill`, `install_skill`, `remove_skill`
82
+ - **MCP** — `mcp_list`, `mcp_add`, `mcp_install`, `mcp_start`, `mcp_stop`, `mcp_call`, `mcp_uninstall`
83
+ - **Mode** — `switch_mode`
84
+
85
+ ---
86
+
87
+ ## Skills
88
+
89
+ Skills are curated instruction packs (and optional bundled scripts) that load on
90
+ demand when a task matches them. Install from a git URL or local path:
91
+
92
+ ```bash
93
+ ikie skills install https://github.com/user/some-skill.git
94
+ ikie skills list
95
+ ikie skills remove some-skill
96
+ ```
97
+
98
+ Inside a session, Ikie loads a matching skill automatically before doing the work.
99
+ You can also manage them with `/skills`.
100
+
101
+ ---
102
+
103
+ ## MCP (Model Context Protocol)
104
+
105
+ Extend Ikie with external MCP servers. Paste a Claude/Cline-style config and Ikie
106
+ will wire it up:
107
+
108
+ ```
109
+ claude mcp add magic --scope user --env API_KEY="…" -- npx -y @21st-dev/magic@latest
110
+ ```
111
+
112
+ Then start it and its tools become available:
113
+
114
+ ```
115
+ / (use the slash menu) → mcp_start magic
30
116
  ```
31
117
 
32
- ## Web access
118
+ Built-in MCPs include **filesystem**, **github**, **database** (SQLite/Postgres),
119
+ and **puppeteer** (browser automation).
120
+
121
+ ---
122
+
123
+ ## In-session commands
124
+
125
+ Type `/` to open the command menu. Highlights:
126
+
127
+ | Command | Description |
128
+ | --- | --- |
129
+ | `/help` | Show all commands |
130
+ | `/plan` · `/agent` · `/mode` | Switch or show mode *(Shift+Tab toggles)* |
131
+ | `/clear` | Clear conversation history |
132
+ | `/compact` | Summarize the conversation to free up context |
133
+ | `/session list\|load\|new\|delete` | Manage saved sessions |
134
+ | `/memory [save]` | View or save persistent notes |
135
+ | `/context` | Show the detected project context |
136
+ | `/model <name>` · `/models` | Switch or list models |
137
+ | `/settings [show\|model\|reset]` | View/change persisted settings |
138
+ | `/skills` | List, show, install, or remove skills |
139
+ | `/theme [name]` | Change the color theme |
140
+ | `/usage` · `/tokens` | Account usage/credit and token estimate |
141
+ | `/rpm <n>` | Set the model request-per-minute limit |
142
+ | `/onboarding` | Re-run the first-time tutorial |
143
+ | `!<cmd>` | Run a shell command directly (output lands in the session) |
144
+
145
+ ---
146
+
147
+ ## CLI usage
148
+
149
+ ```text
150
+ ikie "<message>" One-shot command
151
+ ikie Start an interactive session
152
+ ikie login Sign in to your Ikie account
153
+ ikie logout Sign out
154
+ ikie skills <…> Manage skills (list / install / remove)
155
+
156
+ Flags:
157
+ -m, --model <id> Use a specific model
158
+ -y, --yes Auto-approve all tool executions
159
+ --rpm <n> Max model requests per minute (default: 10)
160
+ --verbose Debug output
161
+ --onboarding Re-run first-time onboarding
162
+ -h, --help Show help
163
+ -v, --version Show version
164
+ ```
165
+
166
+ ---
167
+
168
+ ## Themes
169
+
170
+ Seven built-in color schemes: **nebula**, **cyberpunk**, **dracula**, **forest**,
171
+ **slate**, **amber**, and **aurora**. Switch with `/theme <name>`.
172
+
173
+ ---
174
+
175
+ ## Permissions & safety
33
176
 
34
- ikie can read pages and search the web:
177
+ - `bash`, `write_file`, and `edit_file` ask before running. Press `y` to allow
178
+ once, `a` to always-allow that tool for the session, `n`/`!` to deny.
179
+ - Reading project files is silent; reading credential files (`.env`, `.ssh`, keys,
180
+ `.npmrc`, …) prompts first.
181
+ - Ikie warns before any command that could terminate its own session by killing
182
+ processes on its host port.
183
+ - Run with `-y` / `--yes` to auto-approve everything (use with care).
35
184
 
36
- - **`fetch_url`** — read any page or URL (HTML is stripped to plain text).
37
- - **`web_search`** — search the web and get back titles, URLs, and snippets. Powered by the ikie
38
- server — no separate search API key needed; your ikie login is enough.
185
+ ---
39
186
 
40
- ## Requirements
187
+ ## License
41
188
 
42
- - Node.js 20+
43
- - An ikie account — sign in with `ikie login`
189
+ MIT — see [LICENSE](./LICENSE).
package/dist/agent.js CHANGED
@@ -1000,13 +1000,19 @@ to disambiguate. Make the smallest edit that fixes the root cause; don't reflow
1000
1000
  untouched code. Use \`write_file\` only for brand-new files or deliberate full rewrites,
1001
1001
  and always write the COMPLETE content.
1002
1002
 
1003
- **5. bash hygiene.** It's non-interactive (pass \`-y\`/\`--yes\`); quote paths with spaces;
1004
- chain with \`&&\` so a failure stops the chain; background long-running servers with a
1005
- trailing \`&\`; raise \`timeout_ms\` for slow installs. Check the exit code a non-zero
1006
- exit means it failed, so read the error rather than moving on. **Avoid killing
1007
- processes by port** (\`kill $(lsof -ti:PORT)\`, \`fuser -k\`): it can match ikie's own
1008
- connection and end the session target a specific PID, or stop the process you
1009
- started, instead.
1003
+ **5. bash hygiene.** By default it's non-interactive, so prefer flags that skip
1004
+ prompts (\`-y\`/\`--yes\`, or pass every option explicitly, e.g. \`create-next-app\`'s
1005
+ \`--ts --tailwind --eslint --app\`). But when a command shows an **interactive
1006
+ arrow-key menu or prompt that has no flag** (e.g. \`shadcn init\`'s component-library
1007
+ picker), do NOT keep retrying with piped input call bash with \`interactive: true\`.
1008
+ That hands the real terminal to the command so the **user answers directly**; output
1009
+ isn't captured, so afterward read any files it created to see the result. Also: quote
1010
+ paths with spaces; chain with \`&&\` so a failure stops the chain; background
1011
+ long-running servers with a trailing \`&\`; raise \`timeout_ms\` for slow installs. Check
1012
+ the exit code — a non-zero exit means it failed, so read the error rather than moving
1013
+ on. **Avoid killing processes by port** (\`kill $(lsof -ti:PORT)\`, \`fuser -k\`): it can
1014
+ match ikie's own connection and end the session — target a specific PID, or stop the
1015
+ process you started, instead.
1010
1016
 
1011
1017
  **6. Recover from errors deliberately.** When a tool fails, read the actual message,
1012
1018
  form a hypothesis, and change your approach — never re-run the identical failing call
@@ -1024,7 +1030,7 @@ only the non-obvious. Use \`ask_user\` only when truly blocked on a decision you
1024
1030
  - \`write_file\`: Create new files or full rewrites
1025
1031
  - \`edit_file\`: Replace exact strings (preferred for modifications)
1026
1032
  - \`bash\`: Run shell commands (build, test, git, etc.). Commands ending with & run detached in background.
1027
- **IMPORTANT:** The bash tool is non-interactive — it cannot handle prompts. For commands that ask questions (create-next-app, npm init, etc.), use \`--yes\`, \`-y\`, or pipe through \`yes\` to skip all prompts. For long-running downloads (npx installs), request \`timeout_ms\` up to 300000.
1033
+ **IMPORTANT:** By default it's non-interactive — for commands that ask questions (create-next-app, npm init, etc.), skip prompts with \`--yes\`/\`-y\` or explicit flags. For prompts with no flag (e.g. an arrow-key menu), set \`interactive: true\` so the user answers in the real terminal. For long-running downloads (npx installs), request \`timeout_ms\` up to 300000.
1028
1034
  - \`list_dir\`: Explore directory structure
1029
1035
  - \`search_files\`: Find files by glob pattern
1030
1036
  - \`grep\`: Search file contents by regex
package/dist/repl.js CHANGED
@@ -981,6 +981,16 @@ export async function startREPL(agent, config, projectContext, oneShot) {
981
981
  historySize: MAX_HISTORY,
982
982
  prompt: PROMPT,
983
983
  });
984
+ // Enable bracketed-paste mode so the terminal wraps pasted text in
985
+ // \x1b[200~ … \x1b[201~ markers. This lets a multi-chunk paste (a long
986
+ // paragraph the TTY delivers across several reads) be coalesced into ONE
987
+ // paste instead of being split into several. Disabled again on exit.
988
+ const setBracketedPaste = (on) => {
989
+ if (process.stdout.isTTY)
990
+ process.stdout.write(on ? '\x1b[?2004h' : '\x1b[?2004l');
991
+ };
992
+ setBracketedPaste(true);
993
+ process.on('exit', () => setBracketedPaste(false));
984
994
  let multilineBuffer = '';
985
995
  let busy = false;
986
996
  let ctrlCCount = 0;
@@ -1083,6 +1093,13 @@ export async function startREPL(agent, config, projectContext, oneShot) {
1083
1093
  const normalized = content.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
1084
1094
  if (!normalized)
1085
1095
  return;
1096
+ // Short, single-line pastes (a word, a path, a URL) belong inline as if
1097
+ // typed — only collapse multi-line or long pastes into a [Pasted #N] block.
1098
+ if (!normalized.includes('\n') && normalized.length <= 200) {
1099
+ forwardToReadline(Buffer.from(normalized, 'utf8'));
1100
+ updateMenu();
1101
+ return;
1102
+ }
1086
1103
  const token = `[Pasted #${++pasteSeq}: ${pasteSummary(normalized)}]`;
1087
1104
  pastedBlocks.set(token, normalized);
1088
1105
  rl.write(token);
@@ -1250,6 +1267,7 @@ export async function startREPL(agent, config, projectContext, oneShot) {
1250
1267
  rl.prompt();
1251
1268
  };
1252
1269
  rl.on('close', () => {
1270
+ setBracketedPaste(false);
1253
1271
  printGoodbye(sessionState, agent, config);
1254
1272
  process.exit(0);
1255
1273
  });
package/dist/tools.js CHANGED
@@ -64,6 +64,7 @@ export const TOOL_DEFS = [
64
64
  command: { type: 'string', description: 'Shell command' },
65
65
  timeout_ms: { type: 'number', description: 'Timeout ms (default 30000)' },
66
66
  cwd: { type: 'string', description: 'Working directory' },
67
+ interactive: { type: 'boolean', description: 'Set true for commands that need an interactive terminal — ones that show arrow-key menus or prompts that cannot be skipped with flags (e.g. `shadcn init`, `create-next-app`, `npm init` without -y). The command is connected to the real terminal so the USER answers the prompts directly. Output is shown live, not captured, so the result only reports the exit status — read any files it creates afterward.' },
67
68
  },
68
69
  required: ['command'],
69
70
  },
@@ -623,6 +624,9 @@ async function bash(input) {
623
624
  cwd = resolve(input.cwd);
624
625
  }
625
626
  const command = input.command.trim();
627
+ if (input.interactive) {
628
+ return bashInteractive(command, cwd);
629
+ }
626
630
  if (command.endsWith('&')) {
627
631
  const bgCmd = command.slice(0, -1).trim();
628
632
  try {
@@ -670,6 +674,64 @@ async function bash(input) {
670
674
  return `Exit ${e.code ?? 1}\n${parts.join('\n')}`;
671
675
  }
672
676
  }
677
+ /**
678
+ * Runs a command attached to the real terminal (stdio: 'inherit') so the USER
679
+ * can answer interactive prompts (arrow-key menus, y/N questions) that the
680
+ * non-interactive path cannot handle. Temporarily detaches the REPL's own stdin
681
+ * listeners and raw mode while the child owns the terminal, then restores them.
682
+ * Output is not captured — only the exit status is reported back to the agent.
683
+ */
684
+ function bashInteractive(command, cwd) {
685
+ return new Promise((resolvePromise) => {
686
+ const stdin = process.stdin;
687
+ const isTTY = Boolean(stdin.isTTY);
688
+ const wasRaw = isTTY ? Boolean(stdin.isRaw) : false;
689
+ // Save and detach whatever the REPL has on stdin (cancel handler, etc.) so
690
+ // the child receives keystrokes directly.
691
+ const saved = isTTY ? stdin.rawListeners('data').slice() : [];
692
+ for (const l of saved)
693
+ stdin.removeListener('data', l);
694
+ const restore = () => {
695
+ if (isTTY) {
696
+ try {
697
+ stdin.setRawMode(wasRaw);
698
+ }
699
+ catch { /* ignore */ }
700
+ if (process.stdout.isTTY)
701
+ process.stdout.write('\x1b[?2004h'); // re-arm bracketed paste
702
+ }
703
+ for (const l of saved)
704
+ stdin.on('data', l);
705
+ };
706
+ if (isTTY) {
707
+ try {
708
+ stdin.setRawMode(false);
709
+ }
710
+ catch { /* ignore */ }
711
+ if (process.stdout.isTTY)
712
+ process.stdout.write('\x1b[?2004l'); // disable bracketed paste for the child
713
+ }
714
+ process.stdout.write('\n');
715
+ try {
716
+ const isWindows = process.platform === 'win32';
717
+ const child = spawn(isWindows ? 'cmd.exe' : 'bash', isWindows ? ['/d', '/s', '/c', command] : ['-c', command], { cwd, stdio: 'inherit' });
718
+ child.on('error', (err) => {
719
+ restore();
720
+ resolvePromise(`Error running interactive command: ${sanitizeError(err)}`);
721
+ });
722
+ child.on('exit', (code) => {
723
+ restore();
724
+ resolvePromise(code === 0
725
+ ? '(interactive command completed — output was shown to the user; read any created/changed files to see the result)'
726
+ : `Exit ${code ?? 1} (interactive command)`);
727
+ });
728
+ }
729
+ catch (err) {
730
+ restore();
731
+ resolvePromise(`Error running interactive command: ${sanitizeError(err)}`);
732
+ }
733
+ });
734
+ }
673
735
  function listDir(input) {
674
736
  const root = resolve(input.path ?? '.');
675
737
  if (!existsSync(root))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ikie-cli",
3
- "version": "0.1.32",
3
+ "version": "0.1.33",
4
4
  "description": "Agentic coding CLI — your terminal AI pair programmer",
5
5
  "type": "module",
6
6
  "bin": {