@hachej/boring-agent 0.1.40 → 0.1.42

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 (35) hide show
  1. package/README.md +31 -252
  2. package/dist/{agentPluginEvents-CKrZLW3g.d.ts → agentPluginEvents-ZoOjcb5J.d.ts} +21 -0
  3. package/dist/front/index.d.ts +3 -1
  4. package/dist/front/index.js +9 -3
  5. package/dist/server/index.d.ts +2 -2
  6. package/dist/server/index.js +429 -257
  7. package/dist/shared/index.d.ts +2 -2
  8. package/docs/ACCESSIBILITY.md +11 -13
  9. package/docs/API.md +86 -59
  10. package/docs/CSP.md +10 -9
  11. package/docs/ERROR_CODES.md +1 -1
  12. package/docs/KNOWN_LIMITATIONS.md +3 -3
  13. package/docs/MIGRATION.md +16 -16
  14. package/docs/PERFORMANCE.md +1 -1
  15. package/docs/PLUGINS.md +42 -12
  16. package/docs/README.md +89 -12
  17. package/docs/RISKS-MULTI-TAB.md +1 -1
  18. package/docs/STYLING.md +6 -4
  19. package/docs/UI-SHADCN.md +7 -7
  20. package/docs/runtime-provisioning.md +7 -3
  21. package/docs/runtime.md +68 -13
  22. package/docs/tools.md +37 -14
  23. package/package.json +2 -2
  24. /package/docs/plans/{AGENT_EVAL_FRAMEWORK.md → archive/AGENT_EVAL_FRAMEWORK.md} +0 -0
  25. /package/docs/plans/{agent-package-spec.md → archive/agent-package-spec.md} +0 -0
  26. /package/docs/plans/{harness-followup-capabilities.md → archive/harness-followup-capabilities.md} +0 -0
  27. /package/docs/plans/{harness-tool-ui-capabilities.md → archive/harness-tool-ui-capabilities.md} +0 -0
  28. /package/docs/plans/{pi-followup-history-projection.md → archive/pi-followup-history-projection.md} +0 -0
  29. /package/docs/plans/{pi-tools-migration.md → archive/pi-tools-migration.md} +0 -0
  30. /package/docs/plans/{reviews → archive/reviews}/pi-followup-history-codex-review.md +0 -0
  31. /package/docs/plans/{reviews → archive/reviews}/pi-followup-history-gpt-review.md +0 -0
  32. /package/docs/plans/{reviews → archive/reviews}/pi-followup-history-opus-review.md +0 -0
  33. /package/docs/plans/{reviews → archive/reviews}/pi-followup-history-xai-review.md +0 -0
  34. /package/docs/plans/{vercel-base-snapshot-template-plan.md → archive/vercel-base-snapshot-template-plan.md} +0 -0
  35. /package/docs/plans/{vercel-persistent-sandbox-adapter.md → archive/vercel-persistent-sandbox-adapter.md} +0 -0
@@ -15,11 +15,15 @@ $BORING_AGENT_WORKSPACE_ROOT/.boring-agent/
15
15
  ├── skills/ # generated mirror of plugin skills
16
16
  ├── node/ # npm prefix for runtime Node CLIs
17
17
  ├── venv/ # Python virtualenv for runtime Python CLIs/SDKs
18
- ├── sdk/uv/ # optional workspace-local uv fallback
19
- ├── cache/ # adapter/package cache
20
- └── fingerprints/ # runtime skip hints
18
+ ├── sdk/ # staged local SDK/package sources (sdk/uv = workspace-local uv)
19
+ ├── cache/ # npm/uv/pip caches
20
+ └── tmp/ # staged venvs, tarballs, temp files
21
21
  ```
22
22
 
23
+ Provisioning skip state is tracked via ownership markers and fingerprints stored
24
+ alongside managed directories (see `runtimeLayout.ts`), not a separate
25
+ `fingerprints/` directory.
26
+
23
27
  `.boring-agent` is generated and disposable. Do not hand-edit it; delete it to
24
28
  force a full local reprovision. The directory writes its own `.gitignore` and
25
29
  should not be committed.
package/docs/runtime.md CHANGED
@@ -59,17 +59,23 @@ Provisioned runtime artifacts live under the workspace-local `.boring-agent/` di
59
59
 
60
60
  ```txt
61
61
  .boring-agent/
62
- bin/ # command shims exposed on PATH: python, pip, app CLIs, ...
63
- node/ # npm prefix for provisioned node packages
64
- venv/ # Python virtual environment
65
- sdk/ # staged local SDK/package sources used for runtime-visible installs
66
- state/ # provisioning marker/fingerprint and managed-bin manifests
67
- cache/ # npm/pip/uv caches
62
+ bin/ # managed shims for provisioned CLIs
63
+ node/ # npm prefix for provisioned node packages (bins at node/node_modules/.bin)
64
+ venv/ # Python virtualenv (console scripts at venv/bin)
65
+ sdk/ # staged local SDK/package sources; sdk/uv holds the workspace-local uv
66
+ skills/ # mirror of plugin skills
67
+ cache/ # npm/uv/pip caches
68
68
  tmp/ # staged venvs, tarballs, temp files
69
- logs/ # runtime logs
70
69
  ```
71
70
 
72
- The provisioner writes ownership markers for managed runtime directories. Do not hand-edit managed files as an app integration mechanism; declare provisioning contributions instead.
71
+ PATH entries exposed to the harness are `node/node_modules/.bin`, `venv/bin`,
72
+ and `sdk/uv/bin` (see `getBoringAgentPathEntries` in
73
+ `src/server/workspace/runtimeLayout.ts`). `.boring-agent/bin` is a managed shim
74
+ location written by the provisioner; it is not the canonical PATH source
75
+ described by `getBoringAgentPathEntries`. The provisioner writes ownership
76
+ markers (`.boring-agent-owned.json`) for managed runtime directories. Do not
77
+ hand-edit managed files as an app integration mechanism; declare provisioning
78
+ contributions instead.
73
79
 
74
80
  ## Runtime provisioning
75
81
 
@@ -112,7 +118,7 @@ provisioning: {
112
118
  }
113
119
  ```
114
120
 
115
- The provisioner stages each project under `.boring-agent/sdk/python/<id>`, installs it into `.boring-agent/venv`, and exposes console scripts from `.boring-agent/bin`. File URL env values must point inside the Python project and are converted to runtime-visible SDK paths.
121
+ The provisioner stages each project under `.boring-agent/sdk/python/<id>`, installs it into `.boring-agent/venv`, and may write managed shims under `.boring-agent/bin`. The harness-visible executables still come from the runtime PATH entries above. File URL env values must point inside the Python project and are converted to runtime-visible SDK paths.
116
122
 
117
123
  Reserved env keys (`BORING_AGENT_WORKSPACE_ROOT`, `VIRTUAL_ENV`, `HOME`, `PYTHONHOME`) cannot be set by plugins.
118
124
 
@@ -133,7 +139,7 @@ provisioning: {
133
139
  }
134
140
  ```
135
141
 
136
- Local packages are packed/installed into `.boring-agent/node`; managed bin shims are written to `.boring-agent/bin`. Multiple node packages are installed together so later packages do not prune earlier ones.
142
+ Local packages are packed/installed into `.boring-agent/node`; managed bin shims may also be written to `.boring-agent/bin`. The harness-visible executables still come from `node/node_modules/.bin`. Multiple node packages are installed together so later packages do not prune earlier ones.
137
143
 
138
144
  ## vercel-sandbox
139
145
 
@@ -162,10 +168,12 @@ Linux only. Wraps tool execution in a `bubblewrap` sandbox. The workspace root i
162
168
 
163
169
  ```bash
164
170
  BORING_AGENT_MODE=local
165
- BORING_AGENT_WORKSPACE_ROOT=/home/ubuntu/projects/my-app
171
+ BORING_AGENT_WORKSPACE_ROOT=/home/ubuntu/projects/my-app # host config input
166
172
  ```
167
173
 
168
- The host workspace path is adapter-private. Model-facing cwd, file-tree root, and `BORING_AGENT_WORKSPACE_ROOT` should all be `/workspace`.
174
+ The host workspace path is adapter-private. Inside the runtime/model-visible
175
+ namespace, cwd, file-tree root, and `BORING_AGENT_WORKSPACE_ROOT` should all be
176
+ `/workspace`.
169
177
 
170
178
  ## direct
171
179
 
@@ -180,8 +188,55 @@ In direct mode, host paths are expected: `runtimeCwd` is the real `BORING_AGENT_
180
188
 
181
189
  ## Workspace root
182
190
 
191
+ Config input:
192
+
183
193
  ```bash
184
194
  BORING_AGENT_WORKSPACE_ROOT=/absolute/path/to/workspace
185
195
  ```
186
196
 
187
- When unset, defaults to the current working directory at server start.
197
+ When unset, it defaults to the current working directory at server start.
198
+ In `direct` mode this is also the model-visible workspace root. In isolated
199
+ modes, the adapter maps that host path into the public runtime namespace
200
+ (`/workspace`).
201
+
202
+ ## Adding a custom runtime mode
203
+
204
+ A mode is a `RuntimeModeAdapter` (defined in `src/server/runtime/mode.ts`).
205
+ There is no registry to edit: pass your adapter as the `runtimeModeAdapter`
206
+ option to `createAgentApp(opts)` or `registerAgentRoutes(app, opts)` — it takes
207
+ precedence over `mode`/auto-detection (`createAgentApp.ts`,
208
+ `registerAgentRoutes.ts`). `resolveMode()` only knows the three built-ins and
209
+ throws for unknown ids, telling you to pass `runtimeModeAdapter`.
210
+
211
+ ```ts
212
+ interface RuntimeModeAdapter {
213
+ id: string // built-ins: 'direct' | 'local' | 'vercel-sandbox'
214
+ workspaceFsCapability?: Workspace['fsCapability']
215
+ // describes how much host-side fs access exists before create();
216
+ // remote backends must not claim strong host visibility
217
+ create(ctx: ModeContext): Promise<RuntimeBundle>
218
+ createProvisioningAdapter?(runtimeLayout, ctx?): WorkspaceProvisioningAdapter
219
+ dispose?(): Promise<void>
220
+ }
221
+
222
+ interface RuntimeBundle {
223
+ runtimeContext?: WorkspaceRuntimeContext // e.g. { runtimeCwd: '/workspace' }
224
+ storageRoot?: string // host path for host-fs tools; required unless the
225
+ // workspace itself resolves a host root. NOT the
226
+ // agent-visible cwd — Workspace.root stays the public namespace
227
+ workspace: Workspace // your filesystem adapter
228
+ sandbox: Sandbox // your exec adapter — MUST share the workspace's
229
+ // filesystem substrate (invariant 5: mixed pairings = split-brain)
230
+ fileSearch: FileSearch // createServerFileSearch(workspace, sandbox) usually
231
+ }
232
+ ```
233
+
234
+ Reference implementation to copy: `src/server/runtime/modes/local.ts` (~35
235
+ lines: mkdir + template copy + `createNodeWorkspace` + `createBwrapSandbox`,
236
+ paired on the same root). Tests to extend:
237
+ `src/server/runtime/__tests__/resolveMode.test.ts`.
238
+
239
+ Rules that must hold: the adapter owns path validation (reject `../`,
240
+ absolute, symlink escapes — see `src/server/workspace/paths.ts`); Workspace +
241
+ Sandbox swap as a pair; consumers receive `Workspace` as a parameter and never
242
+ see raw paths.
package/docs/tools.md CHANGED
@@ -4,7 +4,10 @@
4
4
 
5
5
  The agent runtime ships a catalog of tools for interacting with the workspace filesystem and shell.
6
6
 
7
- ## Built-in tools
7
+ ## Filesystem + shell tools
8
+
9
+ These are adapted from `@earendil-works/pi-coding-agent` and bound to the
10
+ selected runtime mode (see [runtime.md](./runtime.md)):
8
11
 
9
12
  | tool | description |
10
13
  |---|---|
@@ -15,24 +18,42 @@ The agent runtime ships a catalog of tools for interacting with the workspace fi
15
18
  | `find` | Find files by name pattern |
16
19
  | `grep` | Search file contents |
17
20
  | `ls` | List directory contents |
18
- | `exec_ui` | Post a command to the workspace UI (open panels, navigate, etc.) |
19
- | `get_ui_state` | Read what panels are currently open |
20
21
 
21
- ## exec_ui
22
+ ## Tools added by this package
22
23
 
23
- The primary tool for interacting with the workspace frontend. See [bridge.md](../../workspace/docs/bridge.md) for the full command reference.
24
+ | tool | description |
25
+ |---|---|
26
+ | `execute_isolated_code` | Run code in an isolated sandbox capability |
27
+ | `upload_file` | Upload a workspace file to blob storage |
28
+ | `plugin_diagnostics` | Report loaded plugins and any load errors |
24
29
 
25
- ```json
26
- {
27
- "kind": "openSurface",
28
- "params": { "kind": "my-plugin.open", "target": "item-123" }
29
- }
30
- ```
30
+ ## UI-bridge tools (workspace-owned)
31
+
32
+ `exec_ui` and `get_ui_state` are **not** part of the standalone agent. They are
33
+ contributed by `@hachej/boring-workspace` when the agent is mounted via the
34
+ workspace-composed server surfaces (typically `createWorkspaceAgentServer`).
35
+ Standalone `createAgentApp` ships no UI tools. For the UI command reference see
36
+ `packages/workspace/docs/PLUGIN_SYSTEM.md`.
31
37
 
32
38
  ## Adding custom tools
33
39
 
34
- For statically composed app/server integrations, contribute tools from a
35
- workspace server plugin:
40
+ Three paths pick by who owns the tool and how it should update:
41
+
42
+ | Path | Use when | Lifecycle |
43
+ | --- | --- | --- |
44
+ | `createAgentApp({ extraTools })` | App shell owns the tool, standalone agent | Boot-time |
45
+ | `defineServerPlugin({ agentTools })` | A workspace plugin package contributes it | Boot-time |
46
+ | Pi resources (`package.json#pi`, often in runtime plugins under `.pi/extensions/<name>/`) | Tool/skill/chat behavior should hot-reload with `/reload` | Hot-reloadable |
47
+
48
+ **App-shell `extraTools`** — the simplest path for a standalone agent: pass
49
+ `extraTools: [myTool]` to `createAgentApp(...)` (or `registerAgentRoutes`).
50
+ Runnable example with a custom renderer:
51
+ [`examples/with-custom-tool`](../examples/with-custom-tool/README.md).
52
+ Collision precedence is built-in → `extraTools` → plugin tools, last wins
53
+ (see [PLUGINS.md](./PLUGINS.md)).
54
+
55
+ **Workspace server plugin** — for statically composed app/server integrations,
56
+ contribute tools from a workspace server plugin:
36
57
 
37
58
  ```ts
38
59
  import { defineServerPlugin } from "@hachej/boring-workspace/server"
@@ -63,8 +84,10 @@ export default defineServerPlugin({
63
84
  Expose that entry with `package.json#boring.server` or pass the plugin object to
64
85
  `createWorkspaceAgentServer({ plugins: [...] })`. This is static/boot-time
65
86
  server composition; restart the host process after changing routes or tools.
87
+ `execute(params, ctx)` also receives a context (`abortSignal`, `toolCallId`,
88
+ `onUpdate`) — full contract in [PLUGINS.md](./PLUGINS.md#tool-contract).
66
89
 
67
- For hot-reloadable chat behavior in user plugin packages, prefer Pi-native
90
+ **Pi-native resources** — for hot-reloadable chat behavior in user plugin packages, prefer Pi-native
68
91
  resources declared in `package.json#pi` (`extensions`, `skills`, `prompts`, and
69
92
  `systemPrompt`). Those participate in the `/reload` path and are the right
70
93
  place for tools/skills that should update without restarting the workspace
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hachej/boring-agent",
3
- "version": "0.1.40",
3
+ "version": "0.1.42",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Pane-embeddable coding agent. Ships direct/local/vercel-sandbox execution modes behind one interface.",
@@ -74,7 +74,7 @@
74
74
  "use-stick-to-bottom": "^1.1.3",
75
75
  "yaml": "^2.8.3",
76
76
  "zod": "^3.25.76",
77
- "@hachej/boring-ui-kit": "0.1.40"
77
+ "@hachej/boring-ui-kit": "0.1.42"
78
78
  },
79
79
  "devDependencies": {
80
80
  "@antithesishq/bombadil": "0.5.0",