@hachej/boring-agent 0.1.41 → 0.1.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -252
- package/dist/{DebugDrawer-2PUDZ2RL.js → DebugDrawer-RYEBQ6CO.js} +1 -1
- package/dist/{agentPluginEvents-CKrZLW3g.d.ts → agentPluginEvents-DP-vLNCs.d.ts} +36 -3
- package/dist/{session-BRovhe0D.d.ts → chatSubmitPayload-gC61O4Ni.d.ts} +20 -1
- package/dist/{chunk-IUJ22EFB.js → chunk-BOIV2I3N.js} +2 -10
- package/dist/{chunk-VQ7VSSSX.js → chunk-YUDMSYAO.js} +6 -1
- package/dist/front/index.d.ts +22 -5
- package/dist/front/index.js +155 -103
- package/dist/front/styles.css +0 -6
- package/dist/piChatEvent-DR9a-FVz.d.ts +306 -0
- package/dist/server/index.d.ts +363 -94
- package/dist/server/index.js +1611 -414
- package/dist/shared/index.d.ts +29 -23
- package/dist/shared/index.js +1 -1
- package/docs/ACCESSIBILITY.md +11 -13
- package/docs/API.md +86 -59
- package/docs/CSP.md +10 -9
- package/docs/ERROR_CODES.md +5 -1
- package/docs/KNOWN_LIMITATIONS.md +3 -3
- package/docs/MIGRATION.md +16 -16
- package/docs/PERFORMANCE.md +1 -1
- package/docs/PLUGINS.md +42 -12
- package/docs/README.md +89 -12
- package/docs/RISKS-MULTI-TAB.md +1 -1
- package/docs/STYLING.md +6 -4
- package/docs/UI-SHADCN.md +7 -7
- package/docs/runtime-provisioning.md +7 -3
- package/docs/runtime.md +68 -13
- package/docs/tools.md +37 -14
- package/package.json +2 -2
- package/dist/piChatEvent-Ck1BAE_m.d.ts +0 -323
- /package/docs/plans/{AGENT_EVAL_FRAMEWORK.md → archive/AGENT_EVAL_FRAMEWORK.md} +0 -0
- /package/docs/plans/{agent-package-spec.md → archive/agent-package-spec.md} +0 -0
- /package/docs/plans/{harness-followup-capabilities.md → archive/harness-followup-capabilities.md} +0 -0
- /package/docs/plans/{harness-tool-ui-capabilities.md → archive/harness-tool-ui-capabilities.md} +0 -0
- /package/docs/plans/{pi-followup-history-projection.md → archive/pi-followup-history-projection.md} +0 -0
- /package/docs/plans/{pi-tools-migration.md → archive/pi-tools-migration.md} +0 -0
- /package/docs/plans/{reviews → archive/reviews}/pi-followup-history-codex-review.md +0 -0
- /package/docs/plans/{reviews → archive/reviews}/pi-followup-history-gpt-review.md +0 -0
- /package/docs/plans/{reviews → archive/reviews}/pi-followup-history-opus-review.md +0 -0
- /package/docs/plans/{reviews → archive/reviews}/pi-followup-history-xai-review.md +0 -0
- /package/docs/plans/{vercel-base-snapshot-template-plan.md → archive/vercel-base-snapshot-template-plan.md} +0 -0
- /package/docs/plans/{vercel-persistent-sandbox-adapter.md → archive/vercel-persistent-sandbox-adapter.md} +0 -0
package/docs/ERROR_CODES.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# ERROR_CODES
|
|
2
2
|
|
|
3
|
-
Canonical registry for stable `@boring
|
|
3
|
+
Canonical registry for stable `@hachej/boring-agent` error codes.
|
|
4
4
|
|
|
5
5
|
All API failures must use the response envelope:
|
|
6
6
|
|
|
@@ -21,6 +21,7 @@ All API failures must use the response envelope:
|
|
|
21
21
|
|
|
22
22
|
| Code | When it fires | HTTP status | Suggested client action | Log level | Stability |
|
|
23
23
|
| --- | --- | --- | --- | --- | --- |
|
|
24
|
+
| `UNAUTHORIZED` | Request reached a protected path (e.g. credit metering) without an authenticated user | 401 | re-auth | warn | stable (public API) |
|
|
24
25
|
| `MISSING_API_KEY` | Required provider API key missing from runtime config | 500 | report-bug | error | stable (public API) |
|
|
25
26
|
| `INVALID_API_KEY` | Provider rejects API key as malformed/invalid | 401 | re-auth | warn | stable (public API) |
|
|
26
27
|
| `OIDC_REFRESH_FAILED` | OIDC refresh token exchange fails | 401 | re-auth | warn | stable (public API) |
|
|
@@ -43,8 +44,11 @@ All API failures must use the response envelope:
|
|
|
43
44
|
| `SANDBOX_NOT_READY` | Remote sandbox cold start / provisioning | 503 | retry | warn | stable (public API) |
|
|
44
45
|
| `SANDBOX_EXPIRED` | Remote sandbox TTL elapsed | 410 | retry | warn | stable (public API) |
|
|
45
46
|
| `VERCEL_API_ERROR` | Generic upstream Vercel SDK/API failure | 502 | retry | error | stable (public API) |
|
|
47
|
+
| `REMOTE_WORKER_TIMEOUT` | Remote worker request exceeded its client-side timeout before a response arrived | 504 | retry | warn | stable (public API) |
|
|
48
|
+
| `REMOTE_WORKER_STREAM_CLOSED` | Remote worker filesystem event stream closed unexpectedly | 502 | retry | warn | stable (public API) |
|
|
46
49
|
| `CIRCUIT_OPEN` | Circuit breaker open; request fast-failed | 503 | retry | warn | stable (public API) |
|
|
47
50
|
| `ABORTED` | Request cancelled via `AbortSignal` | 499 | retry | warn | stable (public API) |
|
|
51
|
+
| `PAYMENT_REQUIRED` | Billing/metering sink rejected the run (e.g. credits exhausted) | 402 | user-fix | warn | stable (public API) |
|
|
48
52
|
| `SESSION_NOT_FOUND` | Session id does not exist | 404 | user-fix | warn | stable (public API) |
|
|
49
53
|
| `SESSION_LOCKED` | Session currently locked by concurrent writer | 409 | retry | warn | stable (public API) |
|
|
50
54
|
| `STREAM_BUFFER_EVICTED` | Resume cursor evicted from in-memory stream buffer | 410 | retry | warn | stable (public API) |
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Abandoned Vercel sandboxes (xzr)
|
|
4
4
|
|
|
5
|
-
`@boring
|
|
5
|
+
`@hachej/boring-agent` v1 intentionally does **not** implement a session-close release hook.
|
|
6
6
|
If a process crashes or a client disappears before cleanup, the sandbox may remain
|
|
7
7
|
alive until Vercel timeout/TTL.
|
|
8
8
|
|
|
@@ -68,8 +68,8 @@ v1 status: **accepted risk**, documented and monitored.
|
|
|
68
68
|
|
|
69
69
|
## GitHub Connect + `/api/v1/git/*` deferred to v1.x (nfx)
|
|
70
70
|
|
|
71
|
-
Git HTTP routes are intentionally not shipped in v1. Both `@boring
|
|
72
|
-
and `@boring
|
|
71
|
+
Git HTTP routes are intentionally not shipped in v1. Both `@hachej/boring-agent` v1
|
|
72
|
+
and `@hachej/boring-workspace` v1 dropped git UI consumers, so `/api/v1/git/*` would
|
|
73
73
|
be dead code today.
|
|
74
74
|
|
|
75
75
|
### Current v1 behavior
|
package/docs/MIGRATION.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# MIGRATION
|
|
2
2
|
|
|
3
3
|
Migration notes for moving from legacy monorepo-integrated agent flows to
|
|
4
|
-
`@boring
|
|
4
|
+
`@hachej/boring-agent` in v2.
|
|
5
5
|
|
|
6
6
|
## What Changes
|
|
7
7
|
|
|
@@ -14,37 +14,37 @@ v1-style app code typically mixed these concerns in one place:
|
|
|
14
14
|
|
|
15
15
|
In v2, split responsibilities are intentional:
|
|
16
16
|
|
|
17
|
-
- `@boring
|
|
18
|
-
|
|
17
|
+
- `@hachej/boring-agent`: agent runtime, tool catalog, harness, sandbox/workspace
|
|
18
|
+
adapters, and the chat UI (`ChatPanel`).
|
|
19
|
+
- `@hachej/boring-workspace`: IDE-style layout/panes plus the UI-bridge tools
|
|
20
|
+
(`exec_ui`, `get_ui_state`) and `/api/v1/ui/*` routes.
|
|
19
21
|
- App shell: final composition, mode selection, and product policy.
|
|
20
22
|
|
|
21
23
|
## Practical Migration Steps
|
|
22
24
|
|
|
23
|
-
1. Move chat/runtime logic into `@boring
|
|
24
|
-
2. Keep editor/file-tree/layout code in `@boring
|
|
25
|
+
1. Move chat/runtime logic into `@hachej/boring-agent` integration points.
|
|
26
|
+
2. Keep editor/file-tree/layout code in `@hachej/boring-workspace` or your own UI.
|
|
25
27
|
3. Route all filesystem and command execution through runtime mode adapters.
|
|
26
|
-
4. Replace ad-hoc shared types with imports from `@boring
|
|
28
|
+
4. Replace ad-hoc shared types with imports from `@hachej/boring-agent/shared`.
|
|
27
29
|
5. Keep server-only code in server entry points; avoid server imports in
|
|
28
30
|
frontend/shared paths.
|
|
29
31
|
|
|
30
32
|
## Runtime Mode Migration
|
|
31
33
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
If you are migrating today, target `direct` first and keep your integration
|
|
38
|
-
surface mode-agnostic so later adapter swaps are non-breaking.
|
|
34
|
+
All three modes ship: `direct`, `local` (`bwrap`), and `vercel-sandbox`. Select
|
|
35
|
+
via `mode` in `createAgentApp` or the `BORING_AGENT_MODE` env var. Keep your
|
|
36
|
+
integration surface mode-agnostic so adapter swaps are non-breaking. See
|
|
37
|
+
[runtime.md](./runtime.md).
|
|
39
38
|
|
|
40
39
|
## Contract Hygiene Checklist
|
|
41
40
|
|
|
42
41
|
- No `node:*` imports in `src/shared/**`.
|
|
43
42
|
- No `Buffer` in shared contracts (`Uint8Array` only).
|
|
44
|
-
- Keep
|
|
45
|
-
- Keep session/tool/workspace behavior aligned with `@boring/agent/shared`.
|
|
43
|
+
- Keep session/tool/workspace behavior aligned with `@hachej/boring-agent/shared`.
|
|
46
44
|
|
|
47
45
|
## References
|
|
48
46
|
|
|
49
|
-
-
|
|
47
|
+
- Runtime modes: [runtime.md](./runtime.md)
|
|
48
|
+
- API surface: [API.md](./API.md)
|
|
50
49
|
- README quickstart/context: `../README.md`
|
|
50
|
+
- Historical design notes: `docs/plans/archive/` (archival; not current truth)
|
package/docs/PERFORMANCE.md
CHANGED
package/docs/PLUGINS.md
CHANGED
|
@@ -1,22 +1,27 @@
|
|
|
1
1
|
# PLUGINS
|
|
2
2
|
|
|
3
|
-
Plugin and extension notes for `@boring
|
|
3
|
+
Plugin and extension notes for `@hachej/boring-agent`.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Two extension paths
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
There are two ways to extend the agent, depending on host integration:
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
1. **Pi-native resources** (`package.json#pi`: `extensions`, `skills`,
|
|
10
|
+
`prompts`, `systemPrompt`) — discovered by the Pi harness in `direct`/`local`
|
|
11
|
+
mode and reloadable through `/reload`. This is the right place for portable,
|
|
12
|
+
hot-reloadable tools and skills. See [tools.md](./tools.md).
|
|
13
|
+
2. **Trusted server plugins** (`@hachej/boring-workspace` `defineServerPlugin`)
|
|
14
|
+
— static/boot-time `agentTools`, routes, and provisioning declared by trusted
|
|
15
|
+
server code. See [tools.md](./tools.md) and
|
|
16
|
+
[runtime-provisioning.md](./runtime-provisioning.md).
|
|
10
17
|
|
|
11
|
-
|
|
12
|
-
|
|
18
|
+
Both paths converge on the same `AgentTool` contract
|
|
19
|
+
(`src/shared/tool.ts`). The standalone `createAgentApp` ships no UI tools;
|
|
20
|
+
`exec_ui`/`get_ui_state` and UI routes are owned by `@hachej/boring-workspace`.
|
|
13
21
|
|
|
14
|
-
##
|
|
22
|
+
## Tool contract
|
|
15
23
|
|
|
16
|
-
|
|
17
|
-
without modifying core runtime internals.
|
|
18
|
-
|
|
19
|
-
Each tool should provide:
|
|
24
|
+
Each tool provides:
|
|
20
25
|
|
|
21
26
|
- Stable `name`
|
|
22
27
|
- Clear `description`
|
|
@@ -29,6 +34,22 @@ Each tool should provide:
|
|
|
29
34
|
- `toolCallId`
|
|
30
35
|
- Optional progress callbacks (`onUpdate`)
|
|
31
36
|
|
|
37
|
+
Optional fields:
|
|
38
|
+
|
|
39
|
+
- `readinessRequirements?: ToolReadinessRequirement[]` — gates the tool on
|
|
40
|
+
runtime readiness. `mergeTools` assigns `['workspace-fs']` to plugin tools
|
|
41
|
+
that omit it (built-in/`extraTools` tools keep whatever they declare).
|
|
42
|
+
- `promptSnippet?` — extra guidance injected into the system prompt when the
|
|
43
|
+
tool is registered.
|
|
44
|
+
|
|
45
|
+
## Trust & runtime modes
|
|
46
|
+
|
|
47
|
+
Plugin tools' `execute()` run in the **host Node process** and bypass the
|
|
48
|
+
sandbox by design — treat plugin code as trusted local/workspace code. Plugin
|
|
49
|
+
auto-discovery is local-mode-only (see the `vercel-sandbox` caveat below). For
|
|
50
|
+
the full internal-vs-external plugin trust model, see
|
|
51
|
+
`packages/workspace/docs/PLUGIN_SYSTEM.md` §1.1.
|
|
52
|
+
|
|
32
53
|
## Safety + Compatibility Rules
|
|
33
54
|
|
|
34
55
|
- Validate all plugin input against schema before execution.
|
|
@@ -63,6 +84,12 @@ previous tool came from built-ins, `extraTools`, or another plugin.
|
|
|
63
84
|
|
|
64
85
|
## Discovery Sources (direct/local)
|
|
65
86
|
|
|
87
|
+
This section describes **Pi-native resource discovery** at the harness level.
|
|
88
|
+
Workspace runtime/generated plugins are a higher-level package format under
|
|
89
|
+
`.pi/extensions/<id>/package.json` documented in
|
|
90
|
+
`packages/workspace/docs/PLUGIN_SYSTEM.md`; those packages may themselves
|
|
91
|
+
declare `pi.extensions` resources.
|
|
92
|
+
|
|
66
93
|
In `direct` and `local` mode, plugin discovery can load tools from:
|
|
67
94
|
|
|
68
95
|
- `~/.pi/agent/extensions/*.js|*.mjs` (global)
|
|
@@ -104,5 +131,8 @@ When porting plugins from host modes to `vercel-sandbox`, expect differences:
|
|
|
104
131
|
|
|
105
132
|
## References
|
|
106
133
|
|
|
107
|
-
-
|
|
134
|
+
- Adding tools: [tools.md](./tools.md)
|
|
135
|
+
- Chat `/slash` commands as a plugin surface:
|
|
136
|
+
`packages/workspace/docs/PLUGIN_SYSTEM.md` §4.7
|
|
108
137
|
- Minimal integration sketch: `examples/with-custom-tool/README.md`
|
|
138
|
+
- Historical design notes: `docs/plans/archive/` (archival; not current truth)
|
package/docs/README.md
CHANGED
|
@@ -1,18 +1,95 @@
|
|
|
1
|
-
# @boring
|
|
1
|
+
# @hachej/boring-agent Docs
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`@hachej/boring-agent` is a pane-embeddable coding agent: an LLM agent loop, a
|
|
4
|
+
tool catalog, and a chat UI, with swappable execution backends. The same agent,
|
|
5
|
+
tools, and UI run in three modes — `direct` (host process), `local` (bwrap
|
|
6
|
+
sandbox), and `vercel-sandbox` (Firecracker microVM) — selected at construction.
|
|
7
|
+
It is consumed two ways: standalone via `createAgentApp` (Fastify server +
|
|
8
|
+
`ChatPanel`), or mounted into `@hachej/boring-workspace` for the full IDE shell.
|
|
4
9
|
|
|
5
|
-
##
|
|
10
|
+
## Architecture
|
|
6
11
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
```
|
|
13
|
+
Chat UI (ChatPanel / front)
|
|
14
|
+
│ pi-chat SSE stream
|
|
15
|
+
Agent HTTP routes (registerAgentRoutes / createAgentApp)
|
|
16
|
+
│
|
|
17
|
+
Agent harness (pi-coding-agent loop) ── Tool catalog (AgentTool[])
|
|
18
|
+
│ │
|
|
19
|
+
Workspace (filesystem) Sandbox (command execution)
|
|
20
|
+
```
|
|
12
21
|
|
|
13
|
-
|
|
22
|
+
- **front** (`src/front`) — `ChatPanel` (= `PiChatPanel`), primitives, slash
|
|
23
|
+
commands, tool renderers, session hooks. Browser-only.
|
|
24
|
+
- **server** (`src/server`) — `createAgentApp`, `registerAgentRoutes`, the Pi
|
|
25
|
+
harness adapter, sandbox/workspace adapters, runtime provisioning, model
|
|
26
|
+
config, HTTP routes. Node-only.
|
|
27
|
+
- **shared** (`src/shared`) — platform-agnostic contracts and zod schemas
|
|
28
|
+
(`AgentHarness`, `Workspace`, `Sandbox`, `AgentTool`, `SessionStore`, chat
|
|
29
|
+
frames, error codes).
|
|
30
|
+
- **eval** (`src/eval`) — agent-behavior evaluation toolkit.
|
|
14
31
|
|
|
15
|
-
|
|
16
|
-
|
|
32
|
+
Data flow: the browser opens a pi-chat SSE stream; the server drives the
|
|
33
|
+
pi-coding-agent harness; tools resolve filesystem ops through the `Workspace`
|
|
34
|
+
adapter and shell/exec through the `Sandbox` adapter. Workspace + Sandbox must
|
|
35
|
+
target the same filesystem substrate (the mode adapter enforces the pairing).
|
|
17
36
|
|
|
18
|
-
|
|
37
|
+
## Key abstractions
|
|
38
|
+
|
|
39
|
+
The public surfaces a consumer or extender touches (all in
|
|
40
|
+
`@hachej/boring-agent/shared` unless noted):
|
|
41
|
+
|
|
42
|
+
- `AgentHarness` — the agent loop interface; pi-coding-agent is the v1 impl.
|
|
43
|
+
- `Workspace` / `Sandbox` — filesystem and command-execution adapters, swapped
|
|
44
|
+
per mode.
|
|
45
|
+
- `AgentTool` + `CatalogDeps` — the tool contract and the deps tools bind to.
|
|
46
|
+
- `SessionStore` — session listing/lifecycle.
|
|
47
|
+
- `createAgentApp` / `registerAgentRoutes` (`/server`) — entry points to run or
|
|
48
|
+
embed the server.
|
|
49
|
+
- `ChatPanel` (`/front`) — the embeddable UI.
|
|
50
|
+
|
|
51
|
+
## Architectural decisions
|
|
52
|
+
|
|
53
|
+
Locked decisions live in the root [`docs/DECISIONS.md`](../../../docs/DECISIONS.md);
|
|
54
|
+
the agent ↔ workspace boundary is in
|
|
55
|
+
[`docs/WORKSPACE_CONTRACT.md`](../../../docs/WORKSPACE_CONTRACT.md). Highlights:
|
|
56
|
+
|
|
57
|
+
- Standalone CLI-shaped product; same code embeds into a host shell — decision 1.
|
|
58
|
+
- pi-coding-agent as the v1 harness behind a generic `AgentHarness` — decisions 4–5.
|
|
59
|
+
- `mode = direct | local | vercel-sandbox`; Workspace+Sandbox pairing invariant — decisions 7a–7f.
|
|
60
|
+
- Single Anthropic provider by default, but the model layer also supports custom
|
|
61
|
+
OpenAI-compatible and Infomaniak providers — decision 10.
|
|
62
|
+
- Plugins extend via Pi resources or trusted server plugins, not core edits — decision 8.
|
|
63
|
+
- Four export surfaces: top-level/`front`, `/server`, `/shared`, `/eval` — decision 15.
|
|
64
|
+
|
|
65
|
+
## Documentation
|
|
66
|
+
|
|
67
|
+
**Surfaces & integration**
|
|
68
|
+
|
|
69
|
+
- [API](./API.md) — the four entry points and what each exports.
|
|
70
|
+
- [STYLING](./STYLING.md) — CSS-variable theming contract and public selectors.
|
|
71
|
+
- [UI-SHADCN](./UI-SHADCN.md) — `ChatPanel` styling model and tool-renderer overrides.
|
|
72
|
+
- [tools](./tools.md) — built-in tools, package-added tools, and how to add custom tools.
|
|
73
|
+
- [PLUGINS](./PLUGINS.md) — the two extension paths and tool-collision rules.
|
|
74
|
+
- [MIGRATION](./MIGRATION.md) — moving legacy integrations to the v2 split.
|
|
75
|
+
|
|
76
|
+
**Runtime & provisioning**
|
|
77
|
+
|
|
78
|
+
- [runtime](./runtime.md) — the three modes, the cwd invariant, and `.boring-agent/` layout.
|
|
79
|
+
- [runtime-provisioning](./runtime-provisioning.md) — when provisioning runs, package-authoring shape, trusted server provisioning.
|
|
80
|
+
|
|
81
|
+
**Contracts & operations**
|
|
82
|
+
|
|
83
|
+
- [ERROR_CODES](./ERROR_CODES.md) — the stable API error-code registry.
|
|
84
|
+
- [CSP](./CSP.md) — Content-Security-Policy compatibility.
|
|
85
|
+
- [ACCESSIBILITY](./ACCESSIBILITY.md) — a11y coverage and known gaps.
|
|
86
|
+
|
|
87
|
+
**Risk & cost notes**
|
|
88
|
+
|
|
89
|
+
- [KNOWN_LIMITATIONS](./KNOWN_LIMITATIONS.md) — accepted risks (orphaned sandboxes, deferred git routes).
|
|
90
|
+
- [RISKS-MULTI-TAB](./RISKS-MULTI-TAB.md) — last-write-wins behavior for concurrent edits.
|
|
91
|
+
- [VERCEL_COSTS](./VERCEL_COSTS.md) — Vercel sandbox cost model.
|
|
92
|
+
- [PERFORMANCE](./PERFORMANCE.md) — historical Vercel cold-start benchmark.
|
|
93
|
+
|
|
94
|
+
Historical plans and specs live under `docs/plans/archive/` — archival context only, not
|
|
95
|
+
current truth; verify against code before relying on them.
|
package/docs/RISKS-MULTI-TAB.md
CHANGED
package/docs/STYLING.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# STYLING
|
|
2
2
|
|
|
3
|
-
Styling contract for `@boring
|
|
3
|
+
Styling contract for `@hachej/boring-agent` frontend surfaces. For the full
|
|
4
|
+
agent/workspace Tailwind isolation model, see
|
|
5
|
+
[`docs/TAILWIND-V4-STYLE-ISOLATION.md`](../../../docs/TAILWIND-V4-STYLE-ISOLATION.md).
|
|
4
6
|
|
|
5
7
|
## Package CSS
|
|
6
8
|
|
|
@@ -8,12 +10,12 @@ Consumers import the precompiled package stylesheet once, after host/workspace
|
|
|
8
10
|
base CSS and before app overrides:
|
|
9
11
|
|
|
10
12
|
```ts
|
|
11
|
-
import "@boring
|
|
12
|
-
import "@boring
|
|
13
|
+
import "@hachej/boring-workspace/globals.css"
|
|
14
|
+
import "@hachej/boring-agent/front/styles.css"
|
|
13
15
|
import "./app.css"
|
|
14
16
|
```
|
|
15
17
|
|
|
16
|
-
The published `@boring
|
|
18
|
+
The published `@hachej/boring-agent/front/styles.css` is consumer-safe: it contains no
|
|
17
19
|
Tailwind `@source`, no Tailwind imports, and no repo-relative source paths.
|
|
18
20
|
|
|
19
21
|
## Public selectors
|
package/docs/UI-SHADCN.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# Agent UI
|
|
2
2
|
|
|
3
|
-
`@boring
|
|
3
|
+
`@hachej/boring-agent` exports the pane-embeddable `ChatPanel` and its frontend
|
|
4
4
|
primitives. The default styled surface is packaged with precompiled CSS.
|
|
5
5
|
|
|
6
6
|
## Quickstart
|
|
7
7
|
|
|
8
8
|
```tsx
|
|
9
|
-
import "@boring
|
|
10
|
-
import "@boring
|
|
11
|
-
import { ChatPanel } from "@boring
|
|
9
|
+
import "@hachej/boring-workspace/globals.css"
|
|
10
|
+
import "@hachej/boring-agent/front/styles.css"
|
|
11
|
+
import { ChatPanel } from "@hachej/boring-agent"
|
|
12
12
|
|
|
13
13
|
function App() {
|
|
14
14
|
return <ChatPanel sessionId="my-session" />
|
|
@@ -18,8 +18,8 @@ function App() {
|
|
|
18
18
|
Import app overrides after the package CSS when customizing:
|
|
19
19
|
|
|
20
20
|
```ts
|
|
21
|
-
import "@boring
|
|
22
|
-
import "@boring
|
|
21
|
+
import "@hachej/boring-workspace/globals.css"
|
|
22
|
+
import "@hachej/boring-agent/front/styles.css"
|
|
23
23
|
import "./app.css"
|
|
24
24
|
```
|
|
25
25
|
|
|
@@ -27,7 +27,7 @@ import "./app.css"
|
|
|
27
27
|
|
|
28
28
|
| Concern | Contract |
|
|
29
29
|
|---|---|
|
|
30
|
-
| Package CSS | `@boring
|
|
30
|
+
| Package CSS | `@hachej/boring-agent/front/styles.css` |
|
|
31
31
|
| Root selector | `[data-boring-agent]` |
|
|
32
32
|
| Parts | `[data-boring-agent-part="composer"]`, `[data-boring-agent-part="tool-card"]`, etc. |
|
|
33
33
|
| Message role | `[data-boring-agent-message-role="assistant"]` |
|
|
@@ -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/
|
|
19
|
-
├── cache/ #
|
|
20
|
-
└──
|
|
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/ #
|
|
63
|
-
node/ # npm prefix for provisioned node packages
|
|
64
|
-
venv/ # Python
|
|
65
|
-
sdk/ # staged local SDK/package sources
|
|
66
|
-
|
|
67
|
-
cache/ # npm/pip
|
|
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
|
-
|
|
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
|
|
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
|
|
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.
|
|
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
|
-
##
|
|
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
|
-
##
|
|
22
|
+
## Tools added by this package
|
|
22
23
|
|
|
23
|
-
|
|
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
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
-
|
|
35
|
-
|
|
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
|
-
|
|
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.
|
|
3
|
+
"version": "0.1.43",
|
|
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.
|
|
77
|
+
"@hachej/boring-ui-kit": "0.1.43"
|
|
78
78
|
},
|
|
79
79
|
"devDependencies": {
|
|
80
80
|
"@antithesishq/bombadil": "0.5.0",
|