indusagi-coding-agent 0.1.28 → 0.1.30

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 (147) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/LICENSE.md +22 -0
  3. package/README.md +2 -0
  4. package/dist/core/messages.d.ts +1 -76
  5. package/dist/core/messages.d.ts.map +1 -1
  6. package/dist/core/messages.js +1 -122
  7. package/dist/core/messages.js.map +1 -1
  8. package/dist/core/session-manager.d.ts +1 -447
  9. package/dist/core/session-manager.d.ts.map +1 -1
  10. package/dist/core/session-manager.js +1 -1203
  11. package/dist/core/session-manager.js.map +1 -1
  12. package/package.json +2 -2
  13. package/docs/COMPLETE-GUIDE.md +0 -300
  14. package/docs/COMPREHENSIVE-CLI-SUMMARY.md +0 -900
  15. package/docs/MODES-ARCHITECTURE.md +0 -565
  16. package/docs/PRINT-MODE-GUIDE.md +0 -456
  17. package/docs/README.md +0 -78
  18. package/docs/RPC-GUIDE.md +0 -705
  19. package/docs/UTILS-IMPLEMENTATION-SUMMARY.md +0 -647
  20. package/docs/UTILS-MODULE-OVERVIEW.md +0 -1480
  21. package/docs/UTILS-QA-CHECKLIST.md +0 -1061
  22. package/docs/UTILS-USAGE-GUIDE.md +0 -1419
  23. package/docs/compaction.md +0 -390
  24. package/docs/custom-provider.md +0 -538
  25. package/docs/development.md +0 -69
  26. package/docs/extensions.md +0 -1733
  27. package/docs/hooks.md +0 -378
  28. package/docs/images/doom-extension.png +0 -0
  29. package/docs/images/interactive-mode.png +0 -0
  30. package/docs/images/tree-view.png +0 -0
  31. package/docs/json.md +0 -79
  32. package/docs/keybindings.md +0 -162
  33. package/docs/models.md +0 -193
  34. package/docs/packages.md +0 -163
  35. package/docs/prompt-templates.md +0 -67
  36. package/docs/providers.md +0 -147
  37. package/docs/rpc.md +0 -1048
  38. package/docs/sdk.md +0 -969
  39. package/docs/session.md +0 -412
  40. package/docs/settings.md +0 -219
  41. package/docs/shell-aliases.md +0 -13
  42. package/docs/skills.md +0 -226
  43. package/docs/subagents.md +0 -225
  44. package/docs/terminal-setup.md +0 -65
  45. package/docs/themes.md +0 -295
  46. package/docs/tree.md +0 -219
  47. package/docs/tui.md +0 -887
  48. package/docs/web-tools.md +0 -304
  49. package/docs/windows.md +0 -17
  50. package/examples/README.md +0 -25
  51. package/examples/extensions/README.md +0 -192
  52. package/examples/extensions/antigravity-image-gen.ts +0 -414
  53. package/examples/extensions/auto-commit-on-exit.ts +0 -49
  54. package/examples/extensions/bookmark.ts +0 -50
  55. package/examples/extensions/claude-rules.ts +0 -86
  56. package/examples/extensions/confirm-destructive.ts +0 -59
  57. package/examples/extensions/custom-compaction.ts +0 -115
  58. package/examples/extensions/custom-footer.ts +0 -65
  59. package/examples/extensions/custom-header.ts +0 -73
  60. package/examples/extensions/custom-provider-anthropic/index.ts +0 -605
  61. package/examples/extensions/custom-provider-anthropic/package-lock.json +0 -24
  62. package/examples/extensions/custom-provider-anthropic/package.json +0 -19
  63. package/examples/extensions/custom-provider-gitlab-duo/index.ts +0 -350
  64. package/examples/extensions/custom-provider-gitlab-duo/package.json +0 -16
  65. package/examples/extensions/custom-provider-gitlab-duo/test.ts +0 -83
  66. package/examples/extensions/dirty-repo-guard.ts +0 -56
  67. package/examples/extensions/doom-overlay/README.md +0 -46
  68. package/examples/extensions/doom-overlay/doom/build/doom.js +0 -21
  69. package/examples/extensions/doom-overlay/doom/build/doom.wasm +0 -0
  70. package/examples/extensions/doom-overlay/doom/build.sh +0 -152
  71. package/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +0 -72
  72. package/examples/extensions/doom-overlay/doom-component.ts +0 -133
  73. package/examples/extensions/doom-overlay/doom-engine.ts +0 -173
  74. package/examples/extensions/doom-overlay/doom-keys.ts +0 -105
  75. package/examples/extensions/doom-overlay/index.ts +0 -74
  76. package/examples/extensions/doom-overlay/wad-finder.ts +0 -51
  77. package/examples/extensions/event-bus.ts +0 -43
  78. package/examples/extensions/file-trigger.ts +0 -41
  79. package/examples/extensions/git-checkpoint.ts +0 -53
  80. package/examples/extensions/handoff.ts +0 -151
  81. package/examples/extensions/hello.ts +0 -25
  82. package/examples/extensions/inline-bash.ts +0 -94
  83. package/examples/extensions/input-transform.ts +0 -43
  84. package/examples/extensions/interactive-shell.ts +0 -196
  85. package/examples/extensions/mac-system-theme.ts +0 -47
  86. package/examples/extensions/message-renderer.ts +0 -60
  87. package/examples/extensions/modal-editor.ts +0 -86
  88. package/examples/extensions/model-status.ts +0 -31
  89. package/examples/extensions/notify.ts +0 -25
  90. package/examples/extensions/overlay-qa-tests.ts +0 -882
  91. package/examples/extensions/overlay-test.ts +0 -151
  92. package/examples/extensions/permission-gate.ts +0 -34
  93. package/examples/extensions/pirate.ts +0 -47
  94. package/examples/extensions/plan-mode/README.md +0 -65
  95. package/examples/extensions/plan-mode/index.ts +0 -341
  96. package/examples/extensions/plan-mode/utils.ts +0 -168
  97. package/examples/extensions/preset.ts +0 -399
  98. package/examples/extensions/protected-paths.ts +0 -30
  99. package/examples/extensions/qna.ts +0 -120
  100. package/examples/extensions/question.ts +0 -265
  101. package/examples/extensions/questionnaire.ts +0 -428
  102. package/examples/extensions/rainbow-editor.ts +0 -88
  103. package/examples/extensions/sandbox/index.ts +0 -318
  104. package/examples/extensions/sandbox/package-lock.json +0 -92
  105. package/examples/extensions/sandbox/package.json +0 -19
  106. package/examples/extensions/send-user-message.ts +0 -97
  107. package/examples/extensions/session-name.ts +0 -27
  108. package/examples/extensions/shutdown-command.ts +0 -63
  109. package/examples/extensions/snake.ts +0 -344
  110. package/examples/extensions/space-invaders.ts +0 -561
  111. package/examples/extensions/ssh.ts +0 -220
  112. package/examples/extensions/status-line.ts +0 -40
  113. package/examples/extensions/subagent/README.md +0 -172
  114. package/examples/extensions/subagent/agents/planner.md +0 -37
  115. package/examples/extensions/subagent/agents/reviewer.md +0 -35
  116. package/examples/extensions/subagent/agents/scout.md +0 -50
  117. package/examples/extensions/subagent/agents/worker.md +0 -24
  118. package/examples/extensions/subagent/agents.ts +0 -127
  119. package/examples/extensions/subagent/index.ts +0 -964
  120. package/examples/extensions/subagent/prompts/implement-and-review.md +0 -10
  121. package/examples/extensions/subagent/prompts/implement.md +0 -10
  122. package/examples/extensions/subagent/prompts/scout-and-plan.md +0 -9
  123. package/examples/extensions/summarize.ts +0 -196
  124. package/examples/extensions/timed-confirm.ts +0 -70
  125. package/examples/extensions/todo.ts +0 -300
  126. package/examples/extensions/tool-override.ts +0 -144
  127. package/examples/extensions/tools.ts +0 -147
  128. package/examples/extensions/trigger-compact.ts +0 -40
  129. package/examples/extensions/truncated-tool.ts +0 -193
  130. package/examples/extensions/widget-placement.ts +0 -17
  131. package/examples/extensions/with-deps/index.ts +0 -36
  132. package/examples/extensions/with-deps/package-lock.json +0 -31
  133. package/examples/extensions/with-deps/package.json +0 -22
  134. package/examples/sdk/01-minimal.ts +0 -22
  135. package/examples/sdk/02-custom-model.ts +0 -50
  136. package/examples/sdk/03-custom-prompt.ts +0 -55
  137. package/examples/sdk/04-skills.ts +0 -46
  138. package/examples/sdk/05-tools.ts +0 -56
  139. package/examples/sdk/06-extensions.ts +0 -88
  140. package/examples/sdk/07-context-files.ts +0 -40
  141. package/examples/sdk/08-prompt-templates.ts +0 -47
  142. package/examples/sdk/09-api-keys-and-oauth.ts +0 -48
  143. package/examples/sdk/10-settings.ts +0 -38
  144. package/examples/sdk/11-sessions.ts +0 -48
  145. package/examples/sdk/12-full-control.ts +0 -82
  146. package/examples/sdk/13-codex-oauth.ts +0 -37
  147. package/examples/sdk/README.md +0 -144
package/docs/hooks.md DELETED
@@ -1,378 +0,0 @@
1
- # Hooks
2
-
3
- Hooks are TypeScript modules that intercept and modify internal operations. Unlike extensions (which use event-based APIs), hooks use a simpler input/output transformation model for specific injection points.
4
-
5
- > **Note**: Most customization should use [extensions](extensions.md) instead. Hooks are lower-level and intended for specific use cases where you need to transform data at well-defined points.
6
-
7
- ## When to Use Hooks vs Extensions
8
-
9
- | Use Hooks When | Use Extensions When |
10
- |----------------|---------------------|
11
- | Transforming chat parameters | Listening to lifecycle events |
12
- | Modifying tool arguments/results | Registering custom tools |
13
- | Adding custom headers to requests | Adding slash commands |
14
- | Transforming system prompts | Building interactive UIs |
15
- | Modifying shell environment | Stateful tool implementations |
16
-
17
- ## Hook Locations
18
-
19
- Hooks are loaded from:
20
-
21
- - Global: `~/.indusagi/agent/hooks/*.ts`
22
- - Project: `.indusagi/hooks/*.ts`
23
- - Settings: `hooks` array in `settings.json`
24
- - CLI: `--hook <path>` flag
25
-
26
- ## Hook File Format
27
-
28
- A hook file exports a factory function that receives context and returns hook handlers:
29
-
30
- ```typescript
31
- import type { HookFactory } from "indusagi-coding-agent";
32
-
33
- export default ((ctx) => {
34
- console.log(`Hooks loading in: ${ctx.cwd}`);
35
-
36
- return {
37
- // Hook handlers go here
38
- "tool.execute.before": async (input, output) => {
39
- // Modify tool arguments before execution
40
- },
41
- };
42
- }) satisfies HookFactory;
43
- ```
44
-
45
- ### HookInitContext
46
-
47
- The factory receives an initialization context:
48
-
49
- ```typescript
50
- interface HookInitContext {
51
- cwd: string; // Current working directory
52
- agentDir: string; // Agent config directory
53
- events: EventBus; // Shared event bus
54
- exec: (command: string, args: string[], options?: ExecOptions) => Promise<ExecResult>;
55
- }
56
- ```
57
-
58
- ## Available Hooks
59
-
60
- ### chat.params
61
-
62
- Modify streaming parameters before calling the LLM.
63
-
64
- ```typescript
65
- "chat.params": async (input, output) => {
66
- // input: { sessionId, model, systemPrompt }
67
- // output: { options: SimpleStreamOptions }
68
-
69
- // Add custom timeout
70
- output.options.timeout = 60000;
71
-
72
- // Enable caching
73
- output.options.caching = true;
74
- }
75
- ```
76
-
77
- ### chat.headers
78
-
79
- Add custom headers to LLM requests.
80
-
81
- ```typescript
82
- "chat.headers": async (input, output) => {
83
- // input: { sessionId, model, systemPrompt }
84
- // output: { headers: Record<string, string> }
85
-
86
- // Add custom headers
87
- output.headers["x-custom-header"] = "value";
88
- output.headers["x-request-id"] = input.sessionId;
89
- }
90
- ```
91
-
92
- ### chat.message
93
-
94
- Transform user messages before sending to LLM.
95
-
96
- ```typescript
97
- "chat.message": async (input, output) => {
98
- // input: { sessionId, model? }
99
- // output: { content: (TextContent | ImageContent)[] }
100
-
101
- // Prepend context to message
102
- output.content = [
103
- { type: "text", text: "Additional context:\n" },
104
- ...output.content,
105
- ];
106
- }
107
- ```
108
-
109
- ### tool.execute.before
110
-
111
- Modify tool arguments before execution.
112
-
113
- ```typescript
114
- "tool.execute.before": async (input, output) => {
115
- // input: { tool, sessionId, callId }
116
- // output: { args: Record<string, unknown> }
117
-
118
- if (input.tool === "bash") {
119
- // Log all bash commands
120
- console.log(`Bash: ${output.args.command}`);
121
-
122
- // Inject environment variable
123
- output.args.command = `export CUSTOM_VAR=1 && ${output.args.command}`;
124
- }
125
-
126
- if (input.tool === "write") {
127
- // Block writes to sensitive paths
128
- if (String(output.args.path).includes(".env")) {
129
- throw new Error("Cannot write to .env files");
130
- }
131
- }
132
- }
133
- ```
134
-
135
- ### tool.execute.after
136
-
137
- Transform tool results after execution.
138
-
139
- ```typescript
140
- "tool.execute.after": async (input, output) => {
141
- // input: { tool, sessionId, callId, args }
142
- // output: { content, details, isError }
143
-
144
- if (input.tool === "bash" && !output.isError) {
145
- // Truncate long output
146
- const text = output.content[0];
147
- if (text?.type === "text" && text.text.length > 10000) {
148
- output.content = [{
149
- type: "text",
150
- text: text.text.slice(0, 10000) + "\n... (truncated)",
151
- }];
152
- }
153
- }
154
- }
155
- ```
156
-
157
- ### tool.definition
158
-
159
- Modify tool descriptions and parameters.
160
-
161
- ```typescript
162
- "tool.definition": async (input, output) => {
163
- // input: { toolId }
164
- // output: { description, parameters }
165
-
166
- if (input.toolId === "bash") {
167
- // Add usage examples to description
168
- output.description += "\n\nExamples:\n- List files: `ls -la`\n- Find text: `grep -r 'pattern' .`";
169
- }
170
- }
171
- ```
172
-
173
- ### shell.env
174
-
175
- Inject environment variables into shell sessions.
176
-
177
- ```typescript
178
- "shell.env": async (input, output) => {
179
- // input: { cwd }
180
- // output: { env: Record<string, string> }
181
-
182
- // Add custom environment
183
- output.env["MY_PROJECT_ROOT"] = input.cwd;
184
- output.env["NODE_ENV"] = "development";
185
-
186
- // Load from .env file
187
- const dotenv = await import("dotenv");
188
- const config = dotenv.config({ path: `${input.cwd}/.env` });
189
- if (config.parsed) {
190
- Object.assign(output.env, config.parsed);
191
- }
192
- }
193
- ```
194
-
195
- ### command.execute.before
196
-
197
- Transform extension command arguments.
198
-
199
- ```typescript
200
- "command.execute.before": async (input, output) => {
201
- // input: { sessionId, command, args }
202
- // output: { args: string }
203
-
204
- if (input.command === "mycommand") {
205
- // Preprocess arguments
206
- output.args = output.args.toUpperCase();
207
- }
208
- }
209
- ```
210
-
211
- ## Experimental Hooks
212
-
213
- These hooks are experimental and may change:
214
-
215
- ### experimental.chat.system.transform
216
-
217
- Transform the system prompt.
218
-
219
- ```typescript
220
- "experimental.chat.system.transform": async (input, output) => {
221
- // input: { sessionId, model }
222
- // output: { system: string }
223
-
224
- // Append custom instructions
225
- output.system += "\n\nAdditional instructions:\n- Be concise\n- Focus on code quality";
226
- }
227
- ```
228
-
229
- ### experimental.chat.messages.transform
230
-
231
- Transform the message history.
232
-
233
- ```typescript
234
- "experimental.chat.messages.transform": async (input, output) => {
235
- // input: { sessionId }
236
- // output: { messages: AgentMessage[] }
237
-
238
- // Filter out old messages
239
- const cutoff = Date.now() - 3600000; // 1 hour
240
- output.messages = output.messages.filter(
241
- (m) => m.timestamp > cutoff
242
- );
243
- }
244
- ```
245
-
246
- ### experimental.session.compacting
247
-
248
- Customize session compaction.
249
-
250
- ```typescript
251
- "experimental.session.compacting": async (input, output) => {
252
- // input: { sessionId }
253
- // output: { context: string[], prompt?: string }
254
-
255
- // Custom compaction prompt
256
- output.prompt = "Summarize this conversation focusing on:\n- Decisions made\n- Files modified\n- Pending tasks";
257
- }
258
- ```
259
-
260
- ### experimental.text.complete
261
-
262
- Transform auto-complete suggestions.
263
-
264
- ```typescript
265
- "experimental.text.complete": async (input, output) => {
266
- // input: { sessionId }
267
- // output: { text: string }
268
-
269
- // Post-process completion
270
- output.text = output.text.trim();
271
- }
272
- ```
273
-
274
- ## Error Handling
275
-
276
- Hook errors are logged but don't crash the session:
277
-
278
- ```typescript
279
- "tool.execute.before": async (input, output) => {
280
- throw new Error("This error is logged, session continues");
281
- }
282
- ```
283
-
284
- To abort an operation, modify the output appropriately:
285
-
286
- ```typescript
287
- "tool.execute.before": async (input, output) => {
288
- // Block by throwing with specific message
289
- if (forbiddenOperation(output.args)) {
290
- throw new Error("Operation blocked by security policy");
291
- }
292
- }
293
- ```
294
-
295
- ## Complete Example
296
-
297
- ```typescript
298
- // ~/.indusagi/agent/hooks/audit-logger.ts
299
- import type { HookFactory } from "indusagi-coding-agent";
300
- import * as fs from "fs";
301
- import * as path from "path";
302
-
303
- export default ((ctx) => {
304
- const logFile = path.join(ctx.agentDir, "audit.log");
305
-
306
- function log(entry: object) {
307
- const line = JSON.stringify({ ...entry, timestamp: new Date().toISOString() }) + "\n";
308
- fs.appendFileSync(logFile, line);
309
- }
310
-
311
- return {
312
- "tool.execute.before": async (input, output) => {
313
- log({
314
- event: "tool_start",
315
- tool: input.tool,
316
- callId: input.callId,
317
- args: output.args,
318
- });
319
- },
320
-
321
- "tool.execute.after": async (input, output) => {
322
- log({
323
- event: "tool_end",
324
- tool: input.tool,
325
- callId: input.callId,
326
- isError: output.isError,
327
- });
328
- },
329
-
330
- "shell.env": async (input, output) => {
331
- log({
332
- event: "shell_start",
333
- cwd: input.cwd,
334
- });
335
- },
336
- };
337
- }) satisfies HookFactory;
338
- ```
339
-
340
- ## Loading Hooks
341
-
342
- ### Via Settings
343
-
344
- ```json
345
- {
346
- "hooks": [
347
- "~/.indusagi/agent/hooks/audit-logger.ts",
348
- ".indusagi/hooks/project-hooks.ts"
349
- ]
350
- }
351
- ```
352
-
353
- ### Via CLI
354
-
355
- ```bash
356
- indusagi --hook ./my-hooks.ts
357
- ```
358
-
359
- ### Programmatically
360
-
361
- ```typescript
362
- import { loadHooks, discoverHooksInDir, DefaultResourceLoader } from "indusagi-coding-agent";
363
-
364
- // Discover hooks in a directory
365
- const hookPaths = discoverHooksInDir("./hooks");
366
-
367
- // Load hooks
368
- const result = await loadHooks(hookPaths, process.cwd());
369
- if (result.errors.length > 0) {
370
- console.error("Hook errors:", result.errors);
371
- }
372
- ```
373
-
374
- ## Related
375
-
376
- - [Extensions](extensions.md) - Higher-level customization API
377
- - [SDK](sdk.md) - Programmatic usage
378
- - [Settings](settings.md) - Configuration options
Binary file
Binary file
Binary file
package/docs/json.md DELETED
@@ -1,79 +0,0 @@
1
- # JSON Event Stream Mode
2
-
3
- ```bash
4
- indusagi --mode json "Your prompt"
5
- ```
6
-
7
- Outputs all session events as JSON lines to stdout. Useful for integrating indusagi into other tools or custom UIs.
8
-
9
- ## Event Types
10
-
11
- Events are defined in [`AgentSessionEvent`](https://github.com/badlogic/indusagi-mono/blob/main/packages/coding-agent/src/core/agent-session.ts#L102):
12
-
13
- ```typescript
14
- type AgentSessionEvent =
15
- | AgentEvent
16
- | { type: "auto_compaction_start"; reason: "threshold" | "overflow" }
17
- | { type: "auto_compaction_end"; result: CompactionResult | undefined; aborted: boolean; willRetry: boolean; errorMessage?: string }
18
- | { type: "auto_retry_start"; attempt: number; maxAttempts: number; delayMs: number; errorMessage: string }
19
- | { type: "auto_retry_end"; success: boolean; attempt: number; finalError?: string };
20
- ```
21
-
22
- Base events from [`AgentEvent`](https://github.com/badlogic/indusagi-mono/blob/main/packages/agent/src/types.ts#L179):
23
-
24
- ```typescript
25
- type AgentEvent =
26
- // Agent lifecycle
27
- | { type: "agent_start" }
28
- | { type: "agent_end"; messages: AgentMessage[] }
29
- // Turn lifecycle
30
- | { type: "turn_start" }
31
- | { type: "turn_end"; message: AgentMessage; toolResults: ToolResultMessage[] }
32
- // Message lifecycle
33
- | { type: "message_start"; message: AgentMessage }
34
- | { type: "message_update"; message: AgentMessage; assistantMessageEvent: AssistantMessageEvent }
35
- | { type: "message_end"; message: AgentMessage }
36
- // Tool execution
37
- | { type: "tool_execution_start"; toolCallId: string; toolName: string; args: any }
38
- | { type: "tool_execution_update"; toolCallId: string; toolName: string; args: any; partialResult: any }
39
- | { type: "tool_execution_end"; toolCallId: string; toolName: string; result: any; isError: boolean };
40
- ```
41
-
42
- ## Message Types
43
-
44
- Base messages from [`packages/ai/src/types.ts`](https://github.com/badlogic/indusagi-mono/blob/main/packages/ai/src/types.ts#L134):
45
- - `UserMessage` (line 134)
46
- - `AssistantMessage` (line 140)
47
- - `ToolResultMessage` (line 152)
48
-
49
- Extended messages from [`packages/coding-agent/src/core/messages.ts`](https://github.com/badlogic/indusagi-mono/blob/main/packages/coding-agent/src/core/messages.ts#L29):
50
- - `BashExecutionMessage` (line 29)
51
- - `CustomMessage` (line 46)
52
- - `BranchSummaryMessage` (line 55)
53
- - `CompactionSummaryMessage` (line 62)
54
-
55
- ## Output Format
56
-
57
- Each line is a JSON object. The first line is the session header:
58
-
59
- ```json
60
- {"type":"session","version":3,"id":"uuid","timestamp":"...","cwd":"/path"}
61
- ```
62
-
63
- Followed by events as they occur:
64
-
65
- ```json
66
- {"type":"agent_start"}
67
- {"type":"turn_start"}
68
- {"type":"message_start","message":{"role":"assistant","content":[],...}}
69
- {"type":"message_update","message":{...},"assistantMessageEvent":{"type":"text_delta","delta":"Hello",...}}
70
- {"type":"message_end","message":{...}}
71
- {"type":"turn_end","message":{...},"toolResults":[]}
72
- {"type":"agent_end","messages":[...]}
73
- ```
74
-
75
- ## Example
76
-
77
- ```bash
78
- indusagi --mode json "List files" 2>/dev/null | jq -c 'select(.type == "message_end")'
79
- ```
@@ -1,162 +0,0 @@
1
- # Keybindings
2
-
3
- All keyboard shortcuts can be customized via `~/.indusagi/agent/keybindings.json`. Each action can be bound to one or more keys.
4
-
5
- ## Key Format
6
-
7
- `modifier+key` where modifiers are `ctrl`, `shift`, `alt` (combinable) and keys are:
8
-
9
- - **Letters:** `a-z`
10
- - **Special:** `escape`, `esc`, `enter`, `return`, `tab`, `space`, `backspace`, `delete`, `insert`, `clear`, `home`, `end`, `pageUp`, `pageDown`, `up`, `down`, `left`, `right`
11
- - **Function:** `f1`-`f12`
12
- - **Symbols:** `` ` ``, `-`, `=`, `[`, `]`, `\`, `;`, `'`, `,`, `.`, `/`, `!`, `@`, `#`, `$`, `%`, `^`, `&`, `*`, `(`, `)`, `_`, `+`, `|`, `~`, `{`, `}`, `:`, `<`, `>`, `?`
13
-
14
- Modifier combinations: `ctrl+shift+x`, `alt+ctrl+x`, `ctrl+shift+alt+x`, etc.
15
-
16
- ## All Actions
17
-
18
- ### Cursor Movement
19
-
20
- | Action | Default | Description |
21
- |--------|---------|-------------|
22
- | `cursorUp` | `up` | Move cursor up |
23
- | `cursorDown` | `down` | Move cursor down |
24
- | `cursorLeft` | `left` | Move cursor left |
25
- | `cursorRight` | `right` | Move cursor right |
26
- | `cursorWordLeft` | `alt+left`, `ctrl+left` | Move cursor word left |
27
- | `cursorWordRight` | `alt+right`, `ctrl+right` | Move cursor word right |
28
- | `cursorLineStart` | `home`, `ctrl+a` | Move to line start |
29
- | `cursorLineEnd` | `end`, `ctrl+e` | Move to line end |
30
- | `pageUp` | `pageUp` | Scroll up by page |
31
- | `pageDown` | `pageDown` | Scroll down by page |
32
-
33
- ### Deletion
34
-
35
- | Action | Default | Description |
36
- |--------|---------|-------------|
37
- | `deleteCharBackward` | `backspace` | Delete character backward |
38
- | `deleteCharForward` | `delete` | Delete character forward |
39
- | `deleteWordBackward` | `ctrl+w`, `alt+backspace` | Delete word backward |
40
- | `deleteWordForward` | `alt+d`, `alt+delete` | Delete word forward |
41
- | `deleteToLineStart` | `ctrl+u` | Delete to line start |
42
- | `deleteToLineEnd` | `ctrl+k` | Delete to line end |
43
-
44
- ### Text Input
45
-
46
- | Action | Default | Description |
47
- |--------|---------|-------------|
48
- | `newLine` | `shift+enter` | Insert new line |
49
- | `submit` | `enter` | Submit input |
50
- | `tab` | `tab` | Tab / autocomplete |
51
-
52
- ### Kill Ring
53
-
54
- | Action | Default | Description |
55
- |--------|---------|-------------|
56
- | `yank` | `ctrl+y` | Paste most recently deleted text |
57
- | `yankPop` | `alt+y` | Cycle through deleted text after yank |
58
- | `undo` | `ctrl+-` | Undo last edit |
59
-
60
- ### Clipboard
61
-
62
- | Action | Default | Description |
63
- |--------|---------|-------------|
64
- | `copy` | `ctrl+c` | Copy selection |
65
- | `pasteImage` | `ctrl+v` | Paste image from clipboard |
66
-
67
- ### Application
68
-
69
- | Action | Default | Description |
70
- |--------|---------|-------------|
71
- | `interrupt` | `escape` | Cancel / abort |
72
- | `clear` | `ctrl+c` | Clear editor |
73
- | `exit` | `ctrl+d` | Exit (when editor empty) |
74
- | `suspend` | `ctrl+z` | Suspend to background |
75
- | `externalEditor` | `ctrl+g` | Open in external editor (`$VISUAL` or `$EDITOR`) |
76
-
77
- ### Models & Thinking
78
-
79
- | Action | Default | Description |
80
- |--------|---------|-------------|
81
- | `selectModel` | `ctrl+l` | Open model selector |
82
- | `cycleModelForward` | `ctrl+p` | Cycle to next model |
83
- | `cycleModelBackward` | `shift+ctrl+p` | Cycle to previous model |
84
- | `cycleThinkingLevel` | `shift+tab` | Cycle thinking level |
85
-
86
- ### Display
87
-
88
- | Action | Default | Description |
89
- |--------|---------|-------------|
90
- | `expandTools` | `ctrl+o` | Collapse/expand tool output |
91
- | `toggleThinking` | `ctrl+t` | Collapse/expand thinking blocks |
92
-
93
- ### Message Queue
94
-
95
- | Action | Default | Description |
96
- |--------|---------|-------------|
97
- | `followUp` | `alt+enter` | Queue follow-up message |
98
- | `dequeue` | `alt+up` | Restore queued messages to editor |
99
-
100
- ### Selection (Lists, Pickers)
101
-
102
- | Action | Default | Description |
103
- |--------|---------|-------------|
104
- | `selectUp` | `up` | Move selection up |
105
- | `selectDown` | `down` | Move selection down |
106
- | `selectPageUp` | `pageUp` | Page up in list |
107
- | `selectPageDown` | `pageDown` | Page down in list |
108
- | `selectConfirm` | `enter` | Confirm selection |
109
- | `selectCancel` | `escape`, `ctrl+c` | Cancel selection |
110
-
111
- ### Session Picker
112
-
113
- | Action | Default | Description |
114
- |--------|---------|-------------|
115
- | `toggleSessionPath` | `ctrl+p` | Toggle path display |
116
- | `toggleSessionSort` | `ctrl+s` | Toggle sort mode |
117
- | `renameSession` | `ctrl+r` | Rename session |
118
- | `deleteSession` | `ctrl+d` | Delete session |
119
- | `deleteSessionNoninvasive` | `ctrl+backspace` | Delete session (when query empty) |
120
-
121
- ## Custom Configuration
122
-
123
- Create `~/.indusagi/agent/keybindings.json`:
124
-
125
- ```json
126
- {
127
- "cursorUp": ["up", "ctrl+p"],
128
- "cursorDown": ["down", "ctrl+n"],
129
- "deleteWordBackward": ["ctrl+w", "alt+backspace"]
130
- }
131
- ```
132
-
133
- Each action can have a single key or an array of keys. User config overrides defaults.
134
-
135
- ### Emacs Example
136
-
137
- ```json
138
- {
139
- "cursorUp": ["up", "ctrl+p"],
140
- "cursorDown": ["down", "ctrl+n"],
141
- "cursorLeft": ["left", "ctrl+b"],
142
- "cursorRight": ["right", "ctrl+f"],
143
- "cursorWordLeft": ["alt+left", "alt+b"],
144
- "cursorWordRight": ["alt+right", "alt+f"],
145
- "deleteCharForward": ["delete", "ctrl+d"],
146
- "deleteCharBackward": ["backspace", "ctrl+h"],
147
- "newLine": ["shift+enter", "ctrl+j"]
148
- }
149
- ```
150
-
151
- ### Vim Example
152
-
153
- ```json
154
- {
155
- "cursorUp": ["up", "alt+k"],
156
- "cursorDown": ["down", "alt+j"],
157
- "cursorLeft": ["left", "alt+h"],
158
- "cursorRight": ["right", "alt+l"],
159
- "cursorWordLeft": ["alt+left", "alt+b"],
160
- "cursorWordRight": ["alt+right", "alt+w"]
161
- }
162
- ```