hoomanjs 1.45.4 → 1.47.0

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 (227) hide show
  1. package/README.md +7 -5
  2. package/dist/acp/acp-agent.d.ts +42 -0
  3. package/dist/acp/acp-agent.js +337 -53
  4. package/dist/acp/acp-agent.js.map +1 -1
  5. package/dist/acp/prompt-invoke.d.ts +2 -1
  6. package/dist/acp/prompt-invoke.js +20 -95
  7. package/dist/acp/prompt-invoke.js.map +1 -1
  8. package/dist/acp/session-config.d.ts +2 -2
  9. package/dist/acp/session-config.js +24 -20
  10. package/dist/acp/session-config.js.map +1 -1
  11. package/dist/acp/utils/tool-kind.js +2 -0
  12. package/dist/acp/utils/tool-kind.js.map +1 -1
  13. package/dist/chat/app.js +93 -20
  14. package/dist/chat/app.js.map +1 -1
  15. package/dist/chat/components/ApprovalPrompt.js +7 -6
  16. package/dist/chat/components/ApprovalPrompt.js.map +1 -1
  17. package/dist/chat/components/BackgroundJobsPanel.d.ts +10 -0
  18. package/dist/chat/components/BackgroundJobsPanel.js +15 -0
  19. package/dist/chat/components/BackgroundJobsPanel.js.map +1 -0
  20. package/dist/chat/components/BottomChrome.d.ts +7 -2
  21. package/dist/chat/components/BottomChrome.js +3 -2
  22. package/dist/chat/components/BottomChrome.js.map +1 -1
  23. package/dist/chat/components/ChromePicker.d.ts +7 -2
  24. package/dist/chat/components/ChromePicker.js +18 -2
  25. package/dist/chat/components/ChromePicker.js.map +1 -1
  26. package/dist/chat/components/Composer.js +3 -2
  27. package/dist/chat/components/Composer.js.map +1 -1
  28. package/dist/chat/components/DownloadPanel.d.ts +1 -1
  29. package/dist/chat/components/DownloadPanel.js +3 -2
  30. package/dist/chat/components/DownloadPanel.js.map +1 -1
  31. package/dist/chat/components/EmptyChatBanner.js +2 -1
  32. package/dist/chat/components/EmptyChatBanner.js.map +1 -1
  33. package/dist/chat/components/PromptInput.js +2 -1
  34. package/dist/chat/components/PromptInput.js.map +1 -1
  35. package/dist/chat/components/QuestionPrompt.js +5 -4
  36. package/dist/chat/components/QuestionPrompt.js.map +1 -1
  37. package/dist/chat/components/QueuedPrompts.js +3 -2
  38. package/dist/chat/components/QueuedPrompts.js.map +1 -1
  39. package/dist/chat/components/ReasoningStrip.js +2 -1
  40. package/dist/chat/components/ReasoningStrip.js.map +1 -1
  41. package/dist/chat/components/RetryEvent.js +2 -1
  42. package/dist/chat/components/RetryEvent.js.map +1 -1
  43. package/dist/chat/components/SelectPicker.js +2 -1
  44. package/dist/chat/components/SelectPicker.js.map +1 -1
  45. package/dist/chat/components/ShellToolEvent.d.ts +12 -0
  46. package/dist/chat/components/ShellToolEvent.js +94 -0
  47. package/dist/chat/components/ShellToolEvent.js.map +1 -0
  48. package/dist/chat/components/SlashCommands.js +2 -1
  49. package/dist/chat/components/SlashCommands.js.map +1 -1
  50. package/dist/chat/components/Spinner.js +2 -1
  51. package/dist/chat/components/Spinner.js.map +1 -1
  52. package/dist/chat/components/StatusBar.js +17 -16
  53. package/dist/chat/components/StatusBar.js.map +1 -1
  54. package/dist/chat/components/ThinkingStatus.js +2 -1
  55. package/dist/chat/components/ThinkingStatus.js.map +1 -1
  56. package/dist/chat/components/ThoughtEvent.js +2 -1
  57. package/dist/chat/components/ThoughtEvent.js.map +1 -1
  58. package/dist/chat/components/TodoPanel.js +2 -1
  59. package/dist/chat/components/TodoPanel.js.map +1 -1
  60. package/dist/chat/components/ToolEvent.d.ts +2 -1
  61. package/dist/chat/components/ToolEvent.js +9 -2
  62. package/dist/chat/components/ToolEvent.js.map +1 -1
  63. package/dist/chat/components/ToolEventFileResult.js +8 -7
  64. package/dist/chat/components/ToolEventFileResult.js.map +1 -1
  65. package/dist/chat/components/Transcript.d.ts +4 -2
  66. package/dist/chat/components/Transcript.js +4 -4
  67. package/dist/chat/components/Transcript.js.map +1 -1
  68. package/dist/chat/components/markdown/BlockRenderer.js +3 -2
  69. package/dist/chat/components/markdown/BlockRenderer.js.map +1 -1
  70. package/dist/chat/components/markdown/CodeBlock.js +3 -2
  71. package/dist/chat/components/markdown/CodeBlock.js.map +1 -1
  72. package/dist/chat/components/markdown/InlineRenderer.js +6 -5
  73. package/dist/chat/components/markdown/InlineRenderer.js.map +1 -1
  74. package/dist/chat/components/shared.js +7 -6
  75. package/dist/chat/components/shared.js.map +1 -1
  76. package/dist/chat/types.d.ts +4 -0
  77. package/dist/cli.js +5 -2
  78. package/dist/cli.js.map +1 -1
  79. package/dist/configure/app.js +292 -0
  80. package/dist/configure/app.js.map +1 -1
  81. package/dist/configure/components/BusyScreen.js +2 -1
  82. package/dist/configure/components/BusyScreen.js.map +1 -1
  83. package/dist/configure/components/MenuScreen.js +3 -2
  84. package/dist/configure/components/MenuScreen.js.map +1 -1
  85. package/dist/configure/components/PromptForm.js +2 -1
  86. package/dist/configure/components/PromptForm.js.map +1 -1
  87. package/dist/configure/components/SelectMenuItem.js +4 -3
  88. package/dist/configure/components/SelectMenuItem.js.map +1 -1
  89. package/dist/configure/utils.js +4 -3
  90. package/dist/configure/utils.js.map +1 -1
  91. package/dist/core/agent/gitignore-guard-plugin.d.ts +2 -0
  92. package/dist/core/agent/gitignore-guard-plugin.js +79 -0
  93. package/dist/core/agent/gitignore-guard-plugin.js.map +1 -0
  94. package/dist/core/agent/index.js +5 -1
  95. package/dist/core/agent/index.js.map +1 -1
  96. package/dist/core/config.d.ts +39 -6
  97. package/dist/core/config.js +5 -2
  98. package/dist/core/config.js.map +1 -1
  99. package/dist/core/index.js +19 -1
  100. package/dist/core/index.js.map +1 -1
  101. package/dist/core/models/anthropic.js +10 -4
  102. package/dist/core/models/anthropic.js.map +1 -1
  103. package/dist/core/models/azure.js +2 -1
  104. package/dist/core/models/azure.js.map +1 -1
  105. package/dist/core/models/bedrock.js +1 -0
  106. package/dist/core/models/bedrock.js.map +1 -1
  107. package/dist/core/models/google.js +1 -0
  108. package/dist/core/models/google.js.map +1 -1
  109. package/dist/core/models/groq.js +2 -1
  110. package/dist/core/models/groq.js.map +1 -1
  111. package/dist/core/models/llama-cpp/index.js +1 -0
  112. package/dist/core/models/llama-cpp/index.js.map +1 -1
  113. package/dist/core/models/llama-cpp/resolve-model.js +1 -1
  114. package/dist/core/models/llama-cpp/resolve-model.js.map +1 -1
  115. package/dist/core/models/minimax.js +2 -1
  116. package/dist/core/models/minimax.js.map +1 -1
  117. package/dist/core/models/mlx/index.js +2 -1
  118. package/dist/core/models/mlx/index.js.map +1 -1
  119. package/dist/core/models/mlx/resolve-model.js +1 -1
  120. package/dist/core/models/mlx/resolve-model.js.map +1 -1
  121. package/dist/core/models/mlx/strands-mlx.js +1 -1
  122. package/dist/core/models/mlx/strands-mlx.js.map +1 -1
  123. package/dist/core/models/moonshot.js +2 -1
  124. package/dist/core/models/moonshot.js.map +1 -1
  125. package/dist/core/models/ollama/index.js +7 -3
  126. package/dist/core/models/ollama/index.js.map +1 -1
  127. package/dist/core/models/openai.js +2 -1
  128. package/dist/core/models/openai.js.map +1 -1
  129. package/dist/core/models/openrouter.js +2 -1
  130. package/dist/core/models/openrouter.js.map +1 -1
  131. package/dist/core/models/types.d.ts +43 -11
  132. package/dist/core/models/types.js +15 -4
  133. package/dist/core/models/types.js.map +1 -1
  134. package/dist/core/models/xai.js +2 -1
  135. package/dist/core/models/xai.js.map +1 -1
  136. package/dist/core/modes/definitions.js +4 -0
  137. package/dist/core/modes/definitions.js.map +1 -1
  138. package/dist/core/prompts/modes/agent.md +1 -1
  139. package/dist/core/prompts/modes/plan.md +11 -7
  140. package/dist/core/prompts/static/browser.md +9 -0
  141. package/dist/core/prompts/static/shell.md +21 -1
  142. package/dist/core/prompts/system.js +3 -0
  143. package/dist/core/prompts/system.js.map +1 -1
  144. package/dist/core/ripgrep/bootstrap.js +5 -19
  145. package/dist/core/ripgrep/bootstrap.js.map +1 -1
  146. package/dist/core/shell/index.d.ts +7 -0
  147. package/dist/core/shell/index.js +6 -0
  148. package/dist/core/shell/index.js.map +1 -0
  149. package/dist/core/shell/manager.d.ts +23 -0
  150. package/dist/core/shell/manager.js +604 -0
  151. package/dist/core/shell/manager.js.map +1 -0
  152. package/dist/core/shell/output-buffer.d.ts +30 -0
  153. package/dist/core/shell/output-buffer.js +116 -0
  154. package/dist/core/shell/output-buffer.js.map +1 -0
  155. package/dist/core/shell/registry.d.ts +5 -0
  156. package/dist/core/shell/registry.js +24 -0
  157. package/dist/core/shell/registry.js.map +1 -0
  158. package/dist/core/shell/shell.d.ts +41 -0
  159. package/dist/core/{tools → shell}/shell.js +188 -24
  160. package/dist/core/shell/shell.js.map +1 -0
  161. package/dist/core/{tools/shell.d.ts → shell/terminal-backend.d.ts} +20 -18
  162. package/dist/core/shell/terminal-backend.js +18 -0
  163. package/dist/core/shell/terminal-backend.js.map +1 -0
  164. package/dist/core/shell/types.d.ts +95 -0
  165. package/dist/core/shell/types.js +2 -0
  166. package/dist/core/shell/types.js.map +1 -0
  167. package/dist/core/skills/built-in/hooman-config/SKILL.md +22 -5
  168. package/dist/core/skills/built-in/hooman-config/providers.md +14 -12
  169. package/dist/core/skills/plugin.js +5 -1
  170. package/dist/core/skills/plugin.js.map +1 -1
  171. package/dist/core/state/shell-jobs.d.ts +9 -0
  172. package/dist/core/state/shell-jobs.js +20 -0
  173. package/dist/core/state/shell-jobs.js.map +1 -0
  174. package/dist/core/state/tool-approvals.js +3 -0
  175. package/dist/core/state/tool-approvals.js.map +1 -1
  176. package/dist/core/state/turn-boundaries.d.ts +33 -0
  177. package/dist/core/state/turn-boundaries.js +49 -0
  178. package/dist/core/state/turn-boundaries.js.map +1 -0
  179. package/dist/core/theme.d.ts +14 -0
  180. package/dist/core/theme.js +14 -0
  181. package/dist/core/theme.js.map +1 -0
  182. package/dist/core/tools/filesystem.js +9 -0
  183. package/dist/core/tools/filesystem.js.map +1 -1
  184. package/dist/core/tools/index.d.ts +0 -1
  185. package/dist/core/tools/index.js +0 -1
  186. package/dist/core/tools/index.js.map +1 -1
  187. package/dist/core/utils/attachments.d.ts +4 -2
  188. package/dist/core/utils/attachments.js +10 -32
  189. package/dist/core/utils/attachments.js.map +1 -1
  190. package/dist/core/utils/command-path.d.ts +1 -0
  191. package/dist/core/utils/command-path.js +17 -0
  192. package/dist/core/utils/command-path.js.map +1 -0
  193. package/dist/core/utils/download-progress.js.map +1 -0
  194. package/dist/core/utils/gitignore.d.ts +11 -0
  195. package/dist/core/utils/gitignore.js +141 -0
  196. package/dist/core/utils/gitignore.js.map +1 -0
  197. package/dist/core/utils/hub-download.js.map +1 -0
  198. package/dist/core/utils/metadata.d.ts +65 -0
  199. package/dist/core/utils/{billing.js → metadata.js} +56 -73
  200. package/dist/core/utils/metadata.js.map +1 -0
  201. package/dist/core/utils/model-metadata.d.ts +39 -0
  202. package/dist/core/utils/model-metadata.js +222 -0
  203. package/dist/core/utils/model-metadata.js.map +1 -0
  204. package/dist/core/utils/paths.d.ts +1 -0
  205. package/dist/core/utils/paths.js +2 -0
  206. package/dist/core/utils/paths.js.map +1 -1
  207. package/dist/core/utils/reasoning-effort.d.ts +9 -1
  208. package/dist/core/{models → utils}/usage.js +1 -1
  209. package/dist/core/utils/usage.js.map +1 -0
  210. package/dist/daemon/index.d.ts +2 -0
  211. package/dist/daemon/index.js +6 -3
  212. package/dist/daemon/index.js.map +1 -1
  213. package/dist/index.d.ts +5 -5
  214. package/dist/index.js +4 -4
  215. package/dist/index.js.map +1 -1
  216. package/package.json +2 -1
  217. package/dist/core/models/download-progress.js.map +0 -1
  218. package/dist/core/models/hub-download.js.map +0 -1
  219. package/dist/core/models/usage.js.map +0 -1
  220. package/dist/core/tools/shell.js.map +0 -1
  221. package/dist/core/utils/billing.d.ts +0 -76
  222. package/dist/core/utils/billing.js.map +0 -1
  223. /package/dist/core/{models → utils}/download-progress.d.ts +0 -0
  224. /package/dist/core/{models → utils}/download-progress.js +0 -0
  225. /package/dist/core/{models → utils}/hub-download.d.ts +0 -0
  226. /package/dist/core/{models → utils}/hub-download.js +0 -0
  227. /package/dist/core/{models → utils}/usage.d.ts +0 -0
@@ -0,0 +1,95 @@
1
+ export type ShellJobStatus = "starting" | "running" | "ready" | "completed" | "stopped" | "failed";
2
+ export type NotifyOnOutput = {
3
+ /** JavaScript regex matched against accumulated output. */
4
+ pattern: string;
5
+ /** Milliseconds that must elapse between match checks. */
6
+ debounce_ms?: number;
7
+ };
8
+ export type ReadyProbe = {
9
+ /** Regex matched against accumulated output to mark the job ready. */
10
+ pattern?: string;
11
+ /** Local TCP port to probe until it accepts connections. */
12
+ port?: number;
13
+ /** Milliseconds to wait for readiness before returning as still running. */
14
+ timeout_ms?: number;
15
+ };
16
+ export type ShellJobStartOptions = {
17
+ command: string;
18
+ args: string[];
19
+ cwd: string;
20
+ description: string;
21
+ /** Soft timeout for the whole job (ms). Undefined = no auto-kill. */
22
+ timeoutMs?: number;
23
+ outputByteLimit?: number;
24
+ toolUseId?: string;
25
+ notifyOnOutput?: NotifyOnOutput;
26
+ ready?: ReadyProbe;
27
+ /**
28
+ * Max ms to wait before returning a background handle.
29
+ * `0` = return immediately. Undefined with no notify/ready = wait for exit
30
+ * (foreground). With notify/ready, wait until match or this deadline.
31
+ */
32
+ blockUntilMs?: number;
33
+ cancelSignal?: AbortSignal;
34
+ };
35
+ export type ShellJobInfo = {
36
+ id: string;
37
+ description: string;
38
+ command: string;
39
+ cwd: string;
40
+ status: ShellJobStatus;
41
+ ready: boolean;
42
+ pid?: number;
43
+ terminalId?: string;
44
+ toolUseId?: string;
45
+ exitCode: number | null;
46
+ signal: string | null;
47
+ startedAt: number;
48
+ endedAt?: number;
49
+ outputTruncated: boolean;
50
+ };
51
+ export type ShellJobOutputSnapshot = {
52
+ jobId: string;
53
+ output: string;
54
+ truncated: boolean;
55
+ status: ShellJobStatus;
56
+ ready: boolean;
57
+ exitCode: number | null;
58
+ signal: string | null;
59
+ matched?: boolean;
60
+ };
61
+ export type ShellJobWaitOptions = {
62
+ /** Wait for process exit (default true when no pattern). */
63
+ block?: boolean;
64
+ timeoutMs?: number;
65
+ /** Wait for a NEW regex match since the last read offset. */
66
+ pattern?: string;
67
+ tailLines?: number;
68
+ cancelSignal?: AbortSignal;
69
+ };
70
+ export type ShellJobEvent = {
71
+ type: "started";
72
+ job: ShellJobInfo;
73
+ } | {
74
+ type: "output";
75
+ job: ShellJobInfo;
76
+ chunk: string;
77
+ } | {
78
+ type: "ready";
79
+ job: ShellJobInfo;
80
+ } | {
81
+ type: "completed";
82
+ job: ShellJobInfo;
83
+ } | {
84
+ type: "stopped";
85
+ job: ShellJobInfo;
86
+ } | {
87
+ type: "failed";
88
+ job: ShellJobInfo;
89
+ error: string;
90
+ };
91
+ export type ShellJobListener = (event: ShellJobEvent) => void;
92
+ /** Host-side terminal handle returned by TerminalBackend.spawn. */
93
+ export type HostTerminalHandle = {
94
+ terminalId: string;
95
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/shell/types.ts"],"names":[],"mappings":""}
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: hooman-config
3
- description: Read and update Hooman's own ~/.hooman/config.json and instructions.md. Use when the user asks about Hooman's config, custom instructions, agent name, model providers, LLMs/models, API keys, reasoning options, web search settings, tool or prompt toggles, or compaction. Not for MCP servers (use hooman-mcp), channel integrations (hooman-channels), or installed skills (hooman-skills).
3
+ description: Read and update Hooman's own ~/.hooman/config.json and instructions.md. Use when the user asks about Hooman's config, custom instructions, agent name, model providers, LLMs/models, API keys, reasoning options, global reasoning display, web search settings, tool or prompt toggles, or compaction. Not for MCP servers (use hooman-mcp), channel integrations (hooman-channels), or installed skills (hooman-skills).
4
4
  ---
5
5
 
6
6
  # Hooman Config
@@ -32,7 +32,7 @@ overlays walked from git root to the current directory). The command prints full
32
32
 
33
33
  1. Read the existing JSON first. Preserve user values, comments are not supported, and secrets such as API keys may be present.
34
34
  2. Make the smallest JSON edit that satisfies the request. Do not rewrite unrelated sections or normalize formatting beyond valid pretty JSON.
35
- 3. `name`, `providers`, and `llms` are required. `providers` stores shared credentials/config, and `llms` must be a **non-empty array** of entries that reference provider names (see `providers.md`). `search`, `prompts`, `tools`, and `compaction` are optional in input, but Hooman expands them with defaults when loading.
35
+ 3. `name`, `providers`, and `llms` are required. `providers` stores shared credentials/config, and `llms` must be a **non-empty array** of entries that reference provider names (see `providers.md`). `search`, `prompts`, `tools`, `compaction`, and top-level `reasoning` are optional in input, but Hooman expands them with defaults when loading.
36
36
  4. Unknown keys are unsupported and may be dropped when Hooman parses and persists the config.
37
37
  5. `tools` only manages built-in runtime toggles exposed in `config.json`.
38
38
  6. Any change to `config.json` or `instructions.md` requires restarting the running Hooman agent/session before it takes effect. In an interactive `chat` session, running the `/config` command applies this automatically: it reloads config and re-bootstraps the session on exit.
@@ -117,12 +117,14 @@ This is the default shape Hooman writes when `~/.hooman/config.json` is missing:
117
117
  "filesystem": { "enabled": true },
118
118
  "shell": { "enabled": true },
119
119
  "sleep": { "enabled": true },
120
+ "browser": { "enabled": false },
120
121
  "subagents": { "enabled": true }
121
122
  },
122
123
  "compaction": {
123
124
  "ratio": 0.75,
124
125
  "keep": 5
125
- }
126
+ },
127
+ "reasoning": "collapsed"
126
128
  }
127
129
  ```
128
130
 
@@ -132,11 +134,12 @@ Hooman fills all optional sections with defaults on load and persist, so a minim
132
134
 
133
135
  - `name`: non-empty display name for the agent.
134
136
  - `providers`: required reusable provider definitions. Each entry has `name`, runtime `provider`, and provider-specific `options`. Supported runtime providers: `anthropic`, `azure`, `bedrock`, `google`, `groq`, `llama-cpp`, `minimax`, `mlx`, `moonshot`, `ollama`, `openai`, `openrouter`, `xai` — details in `providers.md`.
135
- - `llms`: required non-empty list of named LLM configs. Each entry has `name`, provider reference `provider`, model `options` (`model`, optional `temperature`, optional `maxTokens`, optional `context` — local llama-cpp/mlx providers only), and `default` (mark exactly one entry `true`). Details in `providers.md`.
137
+ - `llms`: required non-empty list of named LLM configs. Each entry has `name`, provider reference `provider`, model `options` (`model`, optional `temperature`, optional `topP`, optional `maxTokens`, optional `context` — local llama-cpp/mlx providers only), optional `metadata`, and `default` (mark exactly one entry `true`). Details in `providers.md`.
136
138
  - `search`: optional web search config; defaults to disabled Brave. Details in `search.md`.
137
139
  - `prompts`: optional built-in static prompt toggles; omitted fields default to `true`. Custom user instructions live in `~/.hooman/instructions.md`.
138
140
  - `tools`: optional tool toggles and tool-specific settings.
139
141
  - `compaction`: optional context compaction settings. `ratio` must be `0..1`; `keep` must be a non-negative integer.
142
+ - top-level `reasoning`: optional global reasoning display setting. Supported values are `"collapsed"` and `"full"`.
140
143
 
141
144
  ## Prompts
142
145
 
@@ -144,7 +147,7 @@ Each prompt toggle (`behaviour`, `communication`, `execution`, `guardrails`) is
144
147
 
145
148
  ## Tools
146
149
 
147
- Simple toggles, all enabled by default:
150
+ Simple toggles. All are enabled by default except `browser`, which defaults to `false`:
148
151
 
149
152
  ```json
150
153
  {
@@ -154,6 +157,7 @@ Simple toggles, all enabled by default:
154
157
  "filesystem": { "enabled": true },
155
158
  "shell": { "enabled": true },
156
159
  "sleep": { "enabled": true },
160
+ "browser": { "enabled": false },
157
161
  "subagents": { "enabled": true }
158
162
  }
159
163
  }
@@ -165,6 +169,19 @@ MCP servers and installed skills are not controlled by these toggles; do not ins
165
169
 
166
170
  `~/.hooman/instructions.md` contains the user's custom instructions. Read or edit it only when the user asks about Hooman instructions, custom instructions, persistent guidance, or agent behavior that belongs outside `config.json`. Keep instruction edits focused and preserve existing wording unless the user asks for a rewrite.
167
171
 
172
+ ## Global reasoning display
173
+
174
+ ```json
175
+ {
176
+ "reasoning": "collapsed"
177
+ }
178
+ ```
179
+
180
+ - `collapsed`: default; show reasoning in collapsed form when available.
181
+ - `full`: show the full reasoning stream inline when available.
182
+
183
+ This top-level setting controls **display in the UI**. It is separate from provider-level `options.reasoning`, which controls **whether/how a model thinks**.
184
+
168
185
  ## Compaction
169
186
 
170
187
  ```json
@@ -10,21 +10,23 @@ Each element of `llms` has:
10
10
  - `provider`: provider reference name. It must match one of the entries in top-level `providers`.
11
11
  - `options.model`: model id passed to the resolved runtime provider.
12
12
  - `options.temperature`: optional normalized temperature override.
13
+ - `options.topP`: optional normalized nucleus-sampling override.
13
14
  - `options.maxTokens`: optional normalized output token limit.
14
- - `options.context`: optional context size in tokens; only honored by the local `llama-cpp` and `mlx` providers (overrides the provider-level `context`), other providers ignore it. For llama-cpp it sizes the actual llama.cpp context; for mlx it declares the usable window. Both feed the context-usage gauge (an explicit `billing.context` still wins).
15
+ - `options.context`: optional context size in tokens; only honored by the local `llama-cpp` and `mlx` providers (overrides the provider-level `context`), other providers ignore it. For llama-cpp it sizes the actual llama.cpp context; for mlx it declares the usable window. Both feed the context-usage gauge (an explicit `metadata.context` still wins).
15
16
  - `default`: boolean; mark one entry `"default": true` for the active model.
16
- - `billing`: optional billing metadata used for context-window utilization and session-cost display. When present, `billing.name` is required — the model identifier looked up on models.dev (defaults to `options.model` when `billing` is omitted). Optional overrides: `billing.context` (context window size in tokens) and `billing.costs` (USD per million tokens: required `"input/m"` and `"output/m"`, optional `"cache/m"` for cached-input reads). Anything not provided is resolved from the models.dev catalog; when neither source resolves, context usage and cost are simply not shown.
17
+ - `metadata`: optional model metadata used for context-window utilization, session-cost display, and input modality overrides. When present, `metadata.name` is required — the model identifier looked up on models.dev (defaults to `options.model` when `metadata` is omitted). Optional overrides: `metadata.context` (context window size in tokens), `metadata.costs` (USD per million tokens: required `"input/m"` and `"output/m"`, optional `"cache/m"` for cached-input reads), and `metadata.modality` (`text`, `image`, `pdf`, `audio`, `video`; unspecified fields default from models.dev, then to text-only). Anything not provided is resolved from the models.dev catalog; when neither source resolves prices/context, context usage and cost are simply not shown.
17
18
 
18
- Example `billing` block:
19
+ Example `metadata` block:
19
20
 
20
21
  ```json
21
22
  {
22
23
  "name": "Haiku 4.5",
23
24
  "provider": "LiteLLM Anthropic",
24
- "billing": {
25
+ "metadata": {
25
26
  "name": "claude-haiku-4.5",
26
27
  "context": 200000,
27
- "costs": { "input/m": 1, "cache/m": 0.1, "output/m": 5 }
28
+ "costs": { "input/m": 1, "cache/m": 0.1, "output/m": 5 },
29
+ "modality": { "text": true, "image": true, "pdf": true }
28
30
  },
29
31
  "options": { "model": "claude-haiku-4.5" },
30
32
  "default": true
@@ -77,7 +79,7 @@ Common shape:
77
79
  "name": "Claude Sonnet",
78
80
  "provider": "Anthropic",
79
81
  "options": {
80
- "model": "claude-sonnet-4-20250514",
82
+ "model": "claude-sonnet-4-6",
81
83
  "temperature": 0.2,
82
84
  "maxTokens": 4096
83
85
  },
@@ -94,14 +96,14 @@ Common shape:
94
96
  - `bedrock`: provider `options` support `region`, `accessKeyId`, `secretAccessKey`, `sessionToken`, optional `apiKey`, and optional `reasoning` (an object with optional `effort` and optional `display` — `"summarized"` or `"omitted"`). Providing `reasoning` enables extended thinking on supported models (e.g. Claude); because Bedrock's Converse API requires a budget, `effort` (default `"medium"`) maps to `budget_tokens` (`minimal`→1024, `low`→2048, `medium`→4096, `high`→8192). Ensure the LLM `maxTokens` exceeds the budget. Newer Bedrock Claude (e.g. Opus 4.7+) hide reasoning by default and reject `type: "enabled"`; set `display: "summarized"` to reveal it — this switches to `thinking: { type: "adaptive", display }` with `output_config.effort` (`minimal`→`low`, else passthrough) sent via `additionalRequestFields`. LLM `options` support `model`, `temperature`, and `maxTokens`.
95
97
  - `google`: provider `options` support `apiKey` and optional `reasoning` (an object with optional `effort`). Setting `reasoning.effort` enables Gemini thinking with a dynamic budget (`thinkingConfig: { includeThoughts: true, thinkingBudget: -1 }`). LLM `options` support `model`, `temperature`, and `maxTokens` (Hooman maps this to the Google SDK's `maxOutputTokens` internally).
96
98
  - `groq`: provider `options` support `apiKey`, optional `baseURL`, optional `headers`, and optional `reasoning` (an object with optional `effort`). `reasoning.effort` maps to Groq's `reasoning_effort` (`minimal`→`low`) and streams reasoning via `reasoning_format: "parsed"`. Only reasoning models honor it. LLM `options` support `model`, `temperature`, and `maxTokens`.
97
- - `llama-cpp`: runs GGUF models in-process via node-llama-cpp (no server needed); weights are downloaded from the Hugging Face Hub into `~/.hooman/cache/huggingface` on first use. Provider `options` support optional `hfToken` (Hugging Face access token for gated/private repos; falls back to the `HF_TOKEN` env var), optional `gpu` (`"auto"` — default when unset, `"metal"`, `"cuda"`, `"vulkan"`, or `false` for CPU-only), optional `context` (tokens; overridden by a per-LLM `options.context`; when both are absent it adapts to the model and available memory), optional `promptCache` (boolean, default `true`; reuse KV state evaluated by previous turns — set `false` to re-prefill the full conversation every turn), and optional `reasoning` (an object with optional `effort`). Providing `reasoning` enables thinking (the chat template is configured to allow thought segments — Qwen3 thinking mode, Gemma 4 reasoning turns, gpt-oss/Harmony native effort levels — with `effort` capping thought tokens via a budget: `minimal`→1024, `low`→2048, `medium`→4096, `high`→8192, default `medium`); omitting it disables thinking (templates discourage thoughts, thought budget forced to 0). LLM `options.model` accepts a Hugging Face repo (`owner/repo`, GGUF auto-detected preferring common quantizations like Q4_K_M), a repo with a quant tag (`owner/repo:Q8_0`), an exact file (`owner/repo/path/to/file.gguf`), or a local `.gguf` path; the out-of-the-box config ships three entries — `Qwen/Qwen3-1.7B-GGUF:Q8_0` (default, `context` 32768), `unsloth/Qwen3.5-0.8B-MTP-GGUF:Q8_0` (`context` 262144), and `unsloth/gemma-4-E2B-it-GGUF:Q8_0` (`context` 131072); `temperature`, `maxTokens`, and `context` are supported.
99
+ - `llama-cpp`: runs GGUF models in-process via node-llama-cpp (no server needed); weights are downloaded from the Hugging Face Hub into `~/.hooman/cache/huggingface` on first use. Provider `options` support optional `hfToken` (Hugging Face access token for gated/private repos; falls back to the `HF_TOKEN` env var), optional `gpu` (`"auto"` — default when unset, `"metal"`, `"cuda"`, `"vulkan"`, or `false` for CPU-only), optional `context` (tokens; overridden by a per-LLM `options.context`; when both are absent it adapts to the model and available memory), optional `promptCache` (boolean, default `true`; reuse KV state evaluated by previous turns — set `false` to re-prefill the full conversation every turn), and optional `reasoning` (an object with optional `effort`). Providing `reasoning` enables thinking (the chat template is configured to allow thought segments — Qwen3 thinking mode, Gemma 4 reasoning turns, gpt-oss/Harmony native effort levels — with `effort` capping thought tokens via a budget: `minimal`→1024, `low`→2048, `medium`→4096, `high`→8192, default `medium`); omitting it disables thinking (templates discourage thoughts, thought budget forced to 0). LLM `options.model` accepts a Hugging Face repo (`owner/repo`, GGUF auto-detected preferring common quantizations like Q4_K_M), a repo with a quant tag (`owner/repo:Q8_0`), an exact file (`owner/repo/path/to/file.gguf`), or a local `.gguf` path; the out-of-the-box config ships two entries — `unsloth/gemma-4-E2B-it-GGUF:Q4_K_M` (`context` 131072) and `unsloth/Qwen3.5-2B-MTP-GGUF:Q4_K_M` (`context` 262144); `temperature`, `topP`, `maxTokens`, and `context` are supported.
98
100
  - `minimax`: provider `options` support `apiKey`, optional `headers`, and optional `reasoning` (an object with optional `effort` — `"minimal"`, `"low"`, `"medium"`, `"high"` — and optional `display` — `"summarized"` or `"omitted"`). Providing `reasoning` enables thinking, normalized to MiniMax's `thinking: { type: "adaptive", budget_tokens }`; `effort` defaults to `"medium"` and maps to an explicit budget (`minimal`→1024, `low`→2048, `medium`→4096, `high`→8192). Setting `display` switches to `thinking: { type: "adaptive", display }` with `output_config.effort` instead of a budget. Omit `reasoning` to keep thinking off. Hooman routes this through the Anthropic-compatible MiniMax endpoint automatically.
99
- - `mlx`: runs MLX-format models in-process on Apple Silicon via `mlex.js` (Metal GPU; macOS 26+ for the prebuilt binaries); weights are downloaded from the Hugging Face Hub into `~/.hooman/cache/huggingface` on first use. Supported architectures: Qwen2/2.5, Qwen3, Qwen3.5/3.6 (dense and MoE), Gemma 4 (including multi-modal vision/audio variants), Nemotron 3 (hybrid Mamba2/attention), DharaAR — the repo must be MLX format (e.g. `mlx-community/...`), and every MLX quantization scheme loads (bf16/fp16, affine 2-8 bit, mxfp4/mxfp8/nvfp4, and mixed-precision OptiQ/Google-QAT exports). Provider `options` support optional `hfToken` (Hugging Face access token for gated/private repos; falls back to the `HF_TOKEN` env var), optional `context` (tokens; overridden by a per-LLM `options.context` — MLX allocates KV state dynamically, so this declares the usable window for the context-usage gauge rather than sizing an allocation), optional `promptCache` (`{ minTokens?, maxEntries?, ttl? }`, or `false`/`null`/unset; sizes and gates mlex's internal prompt-cache pool, applied once when the model loads — `undefined`, `null`, and `false` all disable caching entirely, while an object, even `{}`, enables it, with `maxEntries`/`ttl` (seconds)/`minTokens` overriding mlex's own defaults of 16/300/8 where set; the out-of-the-box `mlx` provider ships `{ "promptCache": {} }`), and optional `reasoning` (an object with optional `effort`). Providing `reasoning` enables thinking (the model thinks naturally with `effort` capping thought tokens via a budget: `minimal`→1024, `low`→2048, `medium`→4096, `high`→8192, default `medium`; when the budget runs out the runtime force-closes the reasoning span and moves on to the answer); omitting it disables thinking. Tools use standard JSON Schema natively — no grammar-subset conversion applies. LLM `options.model` accepts a Hugging Face repo (`owner/repo`) or a local MLX model directory (containing `config.json` + safetensors); the out-of-the-box config ships three entries (none the default, each with `context` 262144 the models' full training window) — `mlx-community/Qwen3.5-9B-OptiQ-4bit` ("Qwen3.5 9B (MLX)"), `mlx-community/NVIDIA-Nemotron-3-Nano-4B-OptiQ-4bit` ("Nemotron 3 Nano 4B (MLX)"), and `mlx-community/gemma-4-12B-it-qat-OptiQ-4bit` ("Gemma 4 12B (MLX)"); `temperature`, `maxTokens`, and `context` are supported.
100
- - `moonshot`: provider `options` support `apiKey`, optional `baseURL`, optional `headers`, and optional `reasoning` (an object with optional `effort`). Setting `reasoning.effort` enables Kimi thinking (`thinking: { type: "enabled" }`). Served through the reasoning-aware openai-compatible adapter, so Kimi's `reasoning_content` is surfaced as thinking. When `baseURL` is omitted, Hooman defaults it to `https://api.moonshot.ai/v1`. To reach Kimi through an OpenAI-compatible proxy (e.g. LiteLLM), use this provider with `baseURL` set to the proxy's `/v1` endpoint — the `openai` provider's Chat adapter would otherwise drop Kimi's reasoning.
101
+ - `mlx`: runs MLX-format models in-process on Apple Silicon via `mlex.js` (Metal GPU; macOS 26+ for the prebuilt binaries); weights are downloaded from the Hugging Face Hub into `~/.hooman/cache/huggingface` on first use. Supported architectures: Qwen2/2.5, Qwen3, Qwen3.5/3.6 (dense and MoE), Gemma 4 (including multi-modal vision/audio variants), Nemotron 3 (hybrid Mamba2/attention), DharaAR — the repo must be MLX format (e.g. `mlx-community/...`), and every MLX quantization scheme loads (bf16/fp16, affine 2-8 bit, mxfp4/mxfp8/nvfp4, and mixed-precision OptiQ/Google-QAT exports). Provider `options` support optional `hfToken` (Hugging Face access token for gated/private repos; falls back to the `HF_TOKEN` env var), optional `context` (tokens; overridden by a per-LLM `options.context` — MLX allocates KV state dynamically, so this declares the usable window for the context-usage gauge rather than sizing an allocation), optional `promptCache` (`{ minTokens?, maxEntries?, ttl? }`, or `false`/`null`/unset; sizes and gates mlex's internal prompt-cache pool, applied once when the model loads — `undefined`, `null`, and `false` all disable caching entirely, while an object, even `{}`, enables it, with `maxEntries`/`ttl` (seconds)/`minTokens` overriding mlex's own defaults of 16/300/8 where set; the out-of-the-box `mlx` provider ships `{ "promptCache": {} }`), and optional `reasoning` (an object with optional `effort`). Providing `reasoning` enables thinking (the model thinks naturally with `effort` capping thought tokens via a budget: `minimal`→1024, `low`→2048, `medium`→4096, `high`→8192, default `medium`; when the budget runs out the runtime force-closes the reasoning span and moves on to the answer); omitting it disables thinking. Tools use standard JSON Schema natively — no grammar-subset conversion applies. LLM `options.model` accepts a Hugging Face repo (`owner/repo`) or a local MLX model directory (containing `config.json` + safetensors); the out-of-the-box config ships two entries — `mlx-community/gemma-4-e2b-it-OptiQ-4bit` (`context` 131072) and `mlx-community/Qwen3.5-2B-OptiQ-4bit` (`context` 262144); `temperature`, `topP`, `maxTokens`, and `context` are supported.
102
+ - `moonshot`: provider `options` support `apiKey`, optional `baseURL`, optional `headers`, and optional `reasoning` (an object with optional `effort`). Setting `reasoning.effort` enables Kimi thinking (`thinking: { type: "enabled" }`). Served through the reasoning-aware openai-compatible adapter, so Kimi's `reasoning_content` is surfaced as thinking. When `baseURL` is omitted, Hooman defaults it to `https://api.moonshot.ai/v1`. To reach Kimi through an OpenAI-compatible proxy (e.g. LiteLLM), use this provider with `baseURL` set to the proxy's `/v1` endpoint — the `openai` provider's Chat adapter would otherwise drop Kimi's reasoning. The bundled default Moonshot model id is `kimi-k2.7-code`.
101
103
  - `ollama`: provider `options` support optional `baseURL` and optional `reasoning` (an object with optional `effort`). Setting `reasoning.effort` enables thinking, mapped to Ollama's `think` level (`minimal`/`low`→`"low"`, `medium`→`"medium"`, `high`→`"high"`). LLM `options` support `model`, `temperature`, and `maxTokens`.
102
104
  - `openai`: provider `options` support `apiKey`, optional `baseURL`, optional `headers`, optional `api` (`"responses"` or `"chat"`, defaults to `"responses"`), and optional `reasoning` (an object with optional `effort` — `"minimal"`, `"low"`, `"medium"`, `"high"` — and optional `summary` — `"auto"` (default), `"concise"`, `"detailed"`, `"none"`). LLM `options` support `model`, `temperature`, and `maxTokens`. Use `"responses"` (the default) to surface model reasoning/thinking; set `"chat"` for OpenAI-compatible endpoints/proxies that do not implement the Responses API. Reasoning summaries stream only on the Responses API, and some models (e.g. GPT-5) require `reasoning.effort` of `"medium"` or higher to emit them; set `reasoning.summary` to `"none"` for non-reasoning models that reject the `reasoning` parameter. Note: `"chat"` mode does NOT surface reasoning (the Chat adapter drops `reasoning_content`); for a proxy that only exposes thinking via chat `reasoning_content` (e.g. Kimi/Moonshot), use the `moonshot` or `openrouter` provider instead. Also note the Responses API may return an empty reasoning item for non-OpenAI backends behind a proxy (they won't stream summary text).
103
- - `openrouter`: provider `options` support `apiKey`, optional `baseURL`, optional `headers`, and optional `reasoning` (an object with optional `effort`). Served through the reasoning-aware openai-compatible adapter, so `reasoning`/`reasoning_content` deltas are surfaced as thinking. `reasoning.effort` maps to `reasoning_effort`, which OpenRouter normalizes for reasoning models. LLM `options` support `model`, `temperature`, and `maxTokens`. The `model` value is usually a provider-qualified OpenRouter model id such as `anthropic/claude-3.5-sonnet`.
104
- - `xai`: provider `options` support `apiKey`, optional `baseURL`, optional `headers`, and optional `reasoning` (an object with optional `effort`). `reasoning.effort` maps to xAI's `reasoning_effort` (`low`/`high`; `minimal`/`low`→`low`, `medium`/`high`→`high`). Only reasoning models (e.g. grok-3-mini) honor it. LLM `options` support `model`, `temperature`, and `maxTokens`.
105
+ - `openrouter`: provider `options` support `apiKey`, optional `baseURL`, optional `headers`, and optional `reasoning` (an object with optional `effort`). Served through the reasoning-aware openai-compatible adapter, so `reasoning`/`reasoning_content` deltas are surfaced as thinking. `reasoning.effort` maps to `reasoning_effort`, which OpenRouter normalizes for reasoning models. LLM `options` support `model`, `temperature`, `topP`, and `maxTokens`. The `model` value is usually a provider-qualified OpenRouter model id such as `google/gemma-4-26b-a4b-it:free` or `anthropic/claude-sonnet-4-5`.
106
+ - `xai`: provider `options` support `apiKey`, optional `baseURL`, optional `headers`, and optional `reasoning` (an object with optional `effort`). `reasoning.effort` maps to xAI's `reasoning_effort` (`low`/`high`; `minimal`/`low`→`low`, `medium`/`high`→`high`). Only reasoning models (e.g. grok-3-mini) honor it. LLM `options` support `model`, `temperature`, `topP`, and `maxTokens`. The bundled default xAI model id is `grok-4.3`.
105
107
 
106
108
  ## Examples
107
109
 
@@ -163,7 +165,7 @@ Common shape:
163
165
  "name": "Claude Sonnet",
164
166
  "provider": "Bedrock",
165
167
  "options": {
166
- "model": "anthropic.claude-sonnet-4-20250514-v1:0",
168
+ "model": "anthropic.claude-sonnet-4-6",
167
169
  "temperature": 0.2,
168
170
  "maxTokens": 4096
169
171
  },
@@ -2,7 +2,7 @@ import { existsSync } from "node:fs";
2
2
  import { dirname, join } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
4
  import { AgentSkills, } from "@strands-agents/sdk/vended-plugins/skills";
5
- import { skillsPath } from "../utils/paths.js";
5
+ import { localSkillsPath, skillsPath } from "../utils/paths.js";
6
6
  export const AGENT_SKILLS_STATE_KEY = "hooman.agentSkills";
7
7
  export function builtInSkillsPath() {
8
8
  return join(dirname(fileURLToPath(import.meta.url)), "./built-in");
@@ -17,6 +17,10 @@ export function createAgentSkillSources() {
17
17
  if (existsSync(installed)) {
18
18
  sources.push(installed);
19
19
  }
20
+ const local = localSkillsPath();
21
+ if (existsSync(local)) {
22
+ sources.push(local);
23
+ }
20
24
  return sources;
21
25
  }
22
26
  export function createAgentSkillsPlugin() {
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../../src/core/skills/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EACL,WAAW,GAEZ,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,MAAM,CAAC,MAAM,sBAAsB,GAAG,oBAAoB,CAAC;AAE3D,MAAM,UAAU,iBAAiB;IAC/B,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,uBAAuB;IACrC,MAAM,OAAO,GAAkB,EAAE,CAAC;IAClC,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IACpC,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC;IAED,MAAM,SAAS,GAAG,UAAU,EAAE,CAAC;IAC/B,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC1B,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,uBAAuB;IACrC,OAAO,IAAI,WAAW,CAAC;QACrB,MAAM,EAAE,uBAAuB,EAAE;QACjC,QAAQ,EAAE,sBAAsB;KACjC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,oCAAoC,CAAC,KAAiB;IACpE,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IACzD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACxE,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAG,EAAE,GAAG,KAAK,EAA+B,CAAC;IACvD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,iBAAiB,CAAC,EAAE,CAAC;QACnE,OAAO;IACT,CAAC;IAED,OAAO,IAAI,CAAC,eAAe,CAAC;IAC5B,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,sBAAsB,EAAE,IAAI,CAAC,CAAC;AACnD,CAAC"}
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../../src/core/skills/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EACL,WAAW,GAEZ,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEhE,MAAM,CAAC,MAAM,sBAAsB,GAAG,oBAAoB,CAAC;AAE3D,MAAM,UAAU,iBAAiB;IAC/B,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,uBAAuB;IACrC,MAAM,OAAO,GAAkB,EAAE,CAAC;IAClC,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IACpC,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC;IAED,MAAM,SAAS,GAAG,UAAU,EAAE,CAAC;IAC/B,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC1B,CAAC;IAED,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;IAChC,IAAI,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,uBAAuB;IACrC,OAAO,IAAI,WAAW,CAAC;QACrB,MAAM,EAAE,uBAAuB,EAAE;QACjC,QAAQ,EAAE,sBAAsB;KACjC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,oCAAoC,CAAC,KAAiB;IACpE,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IACzD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACxE,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAG,EAAE,GAAG,KAAK,EAA+B,CAAC;IACvD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,iBAAiB,CAAC,EAAE,CAAC;QACnE,OAAO;IACT,CAAC;IAED,OAAO,IAAI,CAAC,eAAe,CAAC;IAC5B,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,sBAAsB,EAAE,IAAI,CAAC,CAAC;AACnD,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { ShellJobInfo } from "../shell/types.js";
2
+ export type ShellJobViewState = {
3
+ visible: boolean;
4
+ jobs: ShellJobInfo[];
5
+ active: number;
6
+ };
7
+ type AgentLike = object;
8
+ export declare function getShellJobViewState(agent: AgentLike): ShellJobViewState;
9
+ export {};
@@ -0,0 +1,20 @@
1
+ import { peekShellJobManager } from "../shell/registry.js";
2
+ const ACTIVE = new Set([
3
+ "starting",
4
+ "running",
5
+ "ready",
6
+ ]);
7
+ export function getShellJobViewState(agent) {
8
+ const manager = peekShellJobManager(agent);
9
+ if (!manager) {
10
+ return { visible: false, jobs: [], active: 0 };
11
+ }
12
+ const jobs = manager.list();
13
+ const activeJobs = jobs.filter((j) => ACTIVE.has(j.status));
14
+ return {
15
+ visible: activeJobs.length > 0,
16
+ jobs: activeJobs,
17
+ active: activeJobs.length,
18
+ };
19
+ }
20
+ //# sourceMappingURL=shell-jobs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell-jobs.js","sourceRoot":"","sources":["../../../src/core/state/shell-jobs.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAQ3D,MAAM,MAAM,GAAgC,IAAI,GAAG,CAAC;IAClD,UAAU;IACV,SAAS;IACT,OAAO;CACR,CAAC,CAAC;AAIH,MAAM,UAAU,oBAAoB,CAAC,KAAgB;IACnD,MAAM,OAAO,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAC3C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IACjD,CAAC;IACD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAC5B,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAC5D,OAAO;QACL,OAAO,EAAE,UAAU,CAAC,MAAM,GAAG,CAAC;QAC9B,IAAI,EAAE,UAAU;QAChB,MAAM,EAAE,UAAU,CAAC,MAAM;KAC1B,CAAC;AACJ,CAAC"}
@@ -28,6 +28,9 @@ export const INTERNAL_ALWAYS_ALLOWED = new Set([
28
28
  "subagent_test_investigator",
29
29
  // Sleep
30
30
  "sleep",
31
+ // Background shell job management (safe to use in any mode once a job exists)
32
+ "shell_output",
33
+ "shell_stop",
31
34
  // Asking the user a question IS the interaction — no separate approval gate.
32
35
  ASK_USER_TOOL,
33
36
  SEARCH_TOOLS_TOOL,
@@ -1 +1 @@
1
- {"version":3,"file":"tool-approvals.js","sourceRoot":"","sources":["../../../src/core/state/tool-approvals.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tool-approvals.js","sourceRoot":"","sources":["../../../src/core/state/tool-approvals.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EACL,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAW/D,MAAM,cAAc,GAAG,WAAW,CAAC;AACnC,MAAM,wBAAwB,GAAG,qBAAqB,CAAC;AACvD,MAAM,eAAe,GAAG,YAAY,CAAC;AACrC,MAAM,cAAc,GAAG,WAAW,CAAC;AACnC,MAAM,CAAC,MAAM,oBAAoB,GAAG,iBAAiB,CAAC;AACtD,MAAM,CAAC,MAAM,mBAAmB,GAAG,gBAAgB,CAAC;AACpD,MAAM,aAAa,GAAG,UAAU,CAAC;AACjC,MAAM,iBAAiB,GAAG,cAAc,CAAC;AACzC,MAAM,mBAAmB,GAAG,gBAAgB,CAAC;AAE7C,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,GAAG,CAAC;IAC7C,oBAAoB;IACpB,QAAQ;IACR,4BAA4B;IAC5B,eAAe;IACf,2BAA2B;IAC3B,QAAQ;IACR,cAAc;IACd,WAAW;IACX,OAAO;IACP,wBAAwB;IACxB,mBAAmB;IACnB,iBAAiB;IACjB,4BAA4B;IAC5B,QAAQ;IACR,OAAO;IACP,8EAA8E;IAC9E,cAAc;IACd,YAAY;IACZ,6EAA6E;IAC7E,aAAa;IACb,iBAAiB;IACjB,mBAAmB;IACnB,OAAO;IACP,cAAc;IACd,kBAAkB;IAClB,wCAAwC;IACxC,gBAAgB;IAChB,eAAe;IACf,gBAAgB;IAChB,MAAM;IACN,6EAA6E;IAC7E,4EAA4E;IAC5E,6EAA6E;IAC7E,oBAAoB;CACrB,CAAC,CAAC;AAEH,SAAS,mBAAmB,CAAC,KAAc;IACzC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iCAAiC,CAC/C,KAAgB,EAChB,QAAgB,EAChB,SAAkB;IAElB,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACxC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,QAAQ,KAAK,eAAe,IAAI,QAAQ,KAAK,cAAc,EAAE,CAAC;QAChE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,SAAS,GAAG,SAAS,EAAE,CAAC;IAC9B,IAAI,CAAC,mBAAmB,CAAC,SAAS,CAAC,EAAE,CAAC;QACpC,OAAO,kBAAkB,QAAQ,sDAAsD,SAAS,IAAI,CAAC;IACvG,CAAC;IACD,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC;IAC3B,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;QAC3C,OAAO,kBAAkB,QAAQ,gDAAgD,SAAS,IAAI,CAAC;IACjG,CAAC;IACD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IAC/C,IAAI,uBAAuB,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAE,CAAC;QACjD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,kBAAkB,QAAQ,yEAAyE,SAAS,IAAI,CAAC;AAC1H,CAAC;AAED;;;;;GAKG;AACH,SAAS,qBAAqB,CAC5B,QAAgB,EAChB,SAAkC,EAClC,IAAkB;IAElB,MAAM,WAAW,GAAG,eAAe,EAAE,CAAC;IACtC,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;IAC1B,MAAM,SAAS,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IACvC,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACtC,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAC3B,CAAC;IAED,IAAI,QAAQ,KAAK,cAAc,EAAE,CAAC;QAChC,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC;QAC3B,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;YAC3C,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;QACxC,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,uBAAuB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;IAC3E,CAAC;IAED,IAAI,QAAQ,KAAK,wBAAwB,EAAE,CAAC;QAC1C,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC;QAC9B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChD,OAAO,KAAK,CAAC;QACf,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;gBAC7C,OAAO,KAAK,CAAC;YACf,CAAC;YACD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CACjC,uBAAuB,CAAC,QAAQ,EAAE,IAAI,CAAC,CACxC,CAAC;YACF,IAAI,CAAC,EAAE,EAAE,CAAC;gBACR,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,QAAQ,KAAK,eAAe,IAAI,QAAQ,KAAK,cAAc,EAAE,CAAC;QAChE,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC;QAC3B,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;YAC3C,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;QACxC,OAAO,uBAAuB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAClD,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,QAAgB,EAChB,SAAmB,EACnB,IAAkB;IAElB,OAAO,CACL,mBAAmB,CAAC,SAAS,CAAC;QAC9B,qBAAqB,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,CACjD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,IAAiB,EACjB,QAAgB,EAChB,OAAuC;IAEvC,MAAM,cAAc,GAAG,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;IACzD,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,YAAY,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,YAAY,EAAE,CAAC;QACjB,IAAI,cAAc,EAAE,CAAC;YACnB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Per-turn message-index bookmarks, keyed by the ACP `messageId` the agent
3
+ * generates for that turn's user message.
4
+ *
5
+ * Per the ACP MessageId RFD, only the Agent generates protocol message ids —
6
+ * a client never mints its own. Clients that support Cursor-style "revert"
7
+ * capture the `messageId`
8
+ * from the turn's `user_message_chunk` echo and pass it back via the custom
9
+ * `_hoomanjs/rewind_session` method. We record `agent.messages.length` right
10
+ * before the turn's messages are appended, so a later rewind can splice
11
+ * history back to exactly that point. Stored on `appState` (persisted with
12
+ * the snapshot) so it survives across turns within a session; entries are
13
+ * dropped once their turn (or a later one) is rewound.
14
+ */
15
+ export declare const TURN_BOUNDARIES_STATE_KEY = "hooman.turnBoundaries";
16
+ type AppStateLike = {
17
+ get<T = unknown>(key: string): T;
18
+ set(key: string, value: unknown): void;
19
+ };
20
+ type AgentLike = {
21
+ appState: AppStateLike;
22
+ };
23
+ /** Record the message-index boundary for a turn about to start. */
24
+ export declare function recordTurnBoundary(agent: AgentLike, messageId: string, messageIndex: number): void;
25
+ /** Message-index boundary for `messageId`, or `undefined` if unknown (e.g. replayed history). */
26
+ export declare function getTurnBoundary(agent: AgentLike, messageId: string): number | undefined;
27
+ /**
28
+ * Drop the boundary for `messageId` and every turn recorded after it (their
29
+ * messages are being spliced away by the rewind, so their bookmarks are no
30
+ * longer meaningful).
31
+ */
32
+ export declare function dropTurnBoundariesFrom(agent: AgentLike, messageId: string): void;
33
+ export {};
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Per-turn message-index bookmarks, keyed by the ACP `messageId` the agent
3
+ * generates for that turn's user message.
4
+ *
5
+ * Per the ACP MessageId RFD, only the Agent generates protocol message ids —
6
+ * a client never mints its own. Clients that support Cursor-style "revert"
7
+ * capture the `messageId`
8
+ * from the turn's `user_message_chunk` echo and pass it back via the custom
9
+ * `_hoomanjs/rewind_session` method. We record `agent.messages.length` right
10
+ * before the turn's messages are appended, so a later rewind can splice
11
+ * history back to exactly that point. Stored on `appState` (persisted with
12
+ * the snapshot) so it survives across turns within a session; entries are
13
+ * dropped once their turn (or a later one) is rewound.
14
+ */
15
+ export const TURN_BOUNDARIES_STATE_KEY = "hooman.turnBoundaries";
16
+ function readTurnBoundaries(agent) {
17
+ const raw = agent.appState.get(TURN_BOUNDARIES_STATE_KEY);
18
+ return raw && typeof raw === "object" ? raw : {};
19
+ }
20
+ /** Record the message-index boundary for a turn about to start. */
21
+ export function recordTurnBoundary(agent, messageId, messageIndex) {
22
+ const boundaries = readTurnBoundaries(agent);
23
+ boundaries[messageId] = messageIndex;
24
+ agent.appState.set(TURN_BOUNDARIES_STATE_KEY, boundaries);
25
+ }
26
+ /** Message-index boundary for `messageId`, or `undefined` if unknown (e.g. replayed history). */
27
+ export function getTurnBoundary(agent, messageId) {
28
+ return readTurnBoundaries(agent)[messageId];
29
+ }
30
+ /**
31
+ * Drop the boundary for `messageId` and every turn recorded after it (their
32
+ * messages are being spliced away by the rewind, so their bookmarks are no
33
+ * longer meaningful).
34
+ */
35
+ export function dropTurnBoundariesFrom(agent, messageId) {
36
+ const boundaries = readTurnBoundaries(agent);
37
+ const cutoff = boundaries[messageId];
38
+ if (cutoff === undefined) {
39
+ return;
40
+ }
41
+ const next = {};
42
+ for (const [id, index] of Object.entries(boundaries)) {
43
+ if (index < cutoff) {
44
+ next[id] = index;
45
+ }
46
+ }
47
+ agent.appState.set(TURN_BOUNDARIES_STATE_KEY, next);
48
+ }
49
+ //# sourceMappingURL=turn-boundaries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turn-boundaries.js","sourceRoot":"","sources":["../../../src/core/state/turn-boundaries.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,uBAAuB,CAAC;AAajE,SAAS,kBAAkB,CAAC,KAAgB;IAC1C,MAAM,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAC5B,yBAAyB,CAC1B,CAAC;IACF,OAAO,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;AACnD,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,kBAAkB,CAChC,KAAgB,EAChB,SAAiB,EACjB,YAAoB;IAEpB,MAAM,UAAU,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAC7C,UAAU,CAAC,SAAS,CAAC,GAAG,YAAY,CAAC;IACrC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,yBAAyB,EAAE,UAAU,CAAC,CAAC;AAC5D,CAAC;AAED,iGAAiG;AACjG,MAAM,UAAU,eAAe,CAC7B,KAAgB,EAChB,SAAiB;IAEjB,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC;AAC9C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CACpC,KAAgB,EAChB,SAAiB;IAEjB,MAAM,UAAU,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;IACrC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO;IACT,CAAC;IACD,MAAM,IAAI,GAAmB,EAAE,CAAC;IAChC,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QACrD,IAAI,KAAK,GAAG,MAAM,EAAE,CAAC;YACnB,IAAI,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC;QACnB,CAAC;IACH,CAAC;IACD,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,yBAAyB,EAAE,IAAI,CAAC,CAAC;AACtD,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Shared brand palette for CLI Ink surfaces (and any other non-webview UI).
3
+ * VS Code webviews mirror these values in `src/vscode/webview/index.css`.
4
+ */
5
+ export declare const theme: {
6
+ readonly primary: "#0091cd";
7
+ readonly secondary: "#56a0d3";
8
+ readonly warning: "#ecb731";
9
+ readonly error: "#ee4c58";
10
+ readonly success: "#8ec06c";
11
+ readonly info: "#c4dff6";
12
+ readonly muted: "#9ba5a8";
13
+ };
14
+ export type ThemeColor = (typeof theme)[keyof typeof theme];
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Shared brand palette for CLI Ink surfaces (and any other non-webview UI).
3
+ * VS Code webviews mirror these values in `src/vscode/webview/index.css`.
4
+ */
5
+ export const theme = {
6
+ primary: "#0091cd",
7
+ secondary: "#56a0d3",
8
+ warning: "#ecb731",
9
+ error: "#ee4c58",
10
+ success: "#8ec06c",
11
+ info: "#c4dff6",
12
+ muted: "#9ba5a8",
13
+ };
14
+ //# sourceMappingURL=theme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.js","sourceRoot":"","sources":["../../src/core/theme.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,OAAO,EAAE,SAAS;IAClB,SAAS,EAAE,SAAS;IACpB,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,SAAS;IAChB,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,SAAS;CACR,CAAC"}
@@ -8,6 +8,7 @@ import { setFileToolDisplay, } from "../state/file-tool-display.js";
8
8
  import { readAttachmentAsBlocksOrBase64, } from "../utils/attachments.js";
9
9
  import { findReplacementSpan, unescapeModelText, } from "../utils/edit-replace.js";
10
10
  import { z } from "zod";
11
+ import { createGitignorePredicate } from "../utils/gitignore.js";
11
12
  /** Keyed by the Strands agent instance so backends are never serialized. */
12
13
  const textFsBackends = new WeakMap();
13
14
  export function setTextFsBackend(agent, backend) {
@@ -413,6 +414,7 @@ async function walkDirectory(dirPath, options) {
413
414
  const recursive = options?.recursive ?? false;
414
415
  const maxDepth = options?.maxDepth ?? DEFAULT_TREE_DEPTH;
415
416
  const excludes = (options?.excludePatterns ?? []).map(globToRegExp);
417
+ const gitignore = await createGitignorePredicate(dirPath);
416
418
  async function visit(currentPath, depth) {
417
419
  const entries = await fs.readdir(currentPath, { withFileTypes: true });
418
420
  for (const entry of entries) {
@@ -421,6 +423,9 @@ async function walkDirectory(dirPath, options) {
421
423
  if (excludes.some((pattern) => pattern.test(relative))) {
422
424
  continue;
423
425
  }
426
+ if (gitignore.ignoresPath(fullPath, { isDirectory: entry.isDirectory() })) {
427
+ continue;
428
+ }
424
429
  if (entry.isDirectory()) {
425
430
  results.push({ path: fullPath, type: "directory" });
426
431
  if (recursive && depth < maxDepth) {
@@ -439,6 +444,7 @@ async function walkDirectory(dirPath, options) {
439
444
  async function buildTree(rootPath, options) {
440
445
  const excludes = (options?.excludePatterns ?? []).map(globToRegExp);
441
446
  const maxDepth = options?.maxDepth ?? DEFAULT_TREE_DEPTH;
447
+ const gitignore = await createGitignorePredicate(rootPath);
442
448
  async function build(currentPath, depth) {
443
449
  const stat = await fs.stat(currentPath);
444
450
  const node = {
@@ -457,6 +463,9 @@ async function buildTree(rootPath, options) {
457
463
  if (excludes.some((pattern) => pattern.test(relative))) {
458
464
  continue;
459
465
  }
466
+ if (gitignore.ignoresPath(fullPath, { isDirectory: entry.isDirectory() })) {
467
+ continue;
468
+ }
460
469
  children.push(await build(fullPath, depth + 1));
461
470
  }
462
471
  node.children = children;