brass-runtime 1.16.0 → 1.16.1
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/CHANGELOG.md +17 -0
- package/README.md +283 -18
- package/dist/agent/cli/main.cjs +38 -38
- package/dist/agent/cli/main.js +6 -6
- package/dist/agent/cli/main.mjs +6 -6
- package/dist/agent/index.cjs +7 -7
- package/dist/agent/index.d.ts +1 -1
- package/dist/agent/index.js +6 -6
- package/dist/agent/index.mjs +6 -6
- package/dist/chunk-2HQTDLHF.mjs +683 -0
- package/dist/chunk-36I3M4UC.mjs +370 -0
- package/dist/{chunk-QY5FKYEQ.js → chunk-3AYM6WPJ.js} +570 -51
- package/dist/chunk-3LOYJFRR.cjs +300 -0
- package/dist/chunk-3Y2RIUMM.js +300 -0
- package/dist/{chunk-N6VHMOWB.cjs → chunk-4ROBZFL6.cjs} +128 -128
- package/dist/{chunk-NC5SDRYE.js → chunk-52OB2ROS.js} +4 -4
- package/dist/{chunk-JX3LZQJH.cjs → chunk-52PPNNI4.cjs} +82 -20
- package/dist/{chunk-5YOQOXEQ.cjs → chunk-5EC274J5.cjs} +676 -293
- package/dist/chunk-5QC7LRZ3.js +229 -0
- package/dist/{chunk-7TL2LHQJ.js → chunk-5VRJNBLZ.mjs} +524 -141
- package/dist/chunk-62AZW6UT.cjs +313 -0
- package/dist/chunk-6IXXWIUM.js +683 -0
- package/dist/chunk-74ZTY6CP.js +2871 -0
- package/dist/chunk-76YMRMH2.cjs +777 -0
- package/dist/chunk-7CMJS3QE.mjs +2871 -0
- package/dist/{chunk-2WC63LJK.mjs → chunk-7JIJOVCT.js} +20 -10
- package/dist/{chunk-FM4W4QPL.js → chunk-A2OM6NEH.mjs} +5 -4
- package/dist/chunk-AGR5B2BC.cjs +683 -0
- package/dist/chunk-AVNQLJ5V.js +777 -0
- package/dist/chunk-B33ICAKP.js +313 -0
- package/dist/{chunk-J3H54ZRV.mjs → chunk-B5JD23U7.mjs} +1 -1
- package/dist/chunk-BABBZK4Y.js +2024 -0
- package/dist/{chunk-U5KWK3PX.mjs → chunk-C3MDXTRZ.js} +11 -0
- package/dist/{chunk-F5EUMJL7.mjs → chunk-CIZFIMK5.js} +55 -5
- package/dist/{chunk-SPUEME2B.cjs → chunk-CZIVE6NT.cjs} +12 -1
- package/dist/{chunk-TDVMADDN.js → chunk-DNFJLJMW.mjs} +11 -0
- package/dist/chunk-DNFO2EIZ.mjs +777 -0
- package/dist/{chunk-XDZOO4L5.js → chunk-EJ6BPYVR.mjs} +79 -17
- package/dist/{chunk-JNFRRJYH.cjs → chunk-ENKODRU3.cjs} +242 -192
- package/dist/chunk-EOC4UHBS.mjs +229 -0
- package/dist/{chunk-7LVI2GIN.js → chunk-FH2X7BVP.js} +507 -72
- package/dist/{chunk-OOGJ73B6.js → chunk-FHQGHPMO.mjs} +20 -10
- package/dist/{chunk-WQ5QNU5R.cjs → chunk-GLE2WY7Z.cjs} +652 -217
- package/dist/{chunk-G6IQOE4P.mjs → chunk-GYM3LLGS.mjs} +507 -72
- package/dist/chunk-HLWLMW2F.mjs +2024 -0
- package/dist/{chunk-TVN5I4U6.cjs → chunk-JF5WGYJJ.cjs} +25 -24
- package/dist/{chunk-CY33PGEX.mjs → chunk-KH4SYAOS.mjs} +570 -51
- package/dist/chunk-KN32XNTH.mjs +313 -0
- package/dist/chunk-KQLYONSE.cjs +2871 -0
- package/dist/{chunk-7HUOJA4W.cjs → chunk-KZJQ723N.cjs} +90 -80
- package/dist/{chunk-CCKHV5BT.mjs → chunk-L2SYFEBS.js} +5 -4
- package/dist/{chunk-IJT6RRQ5.cjs → chunk-L6VB5N7Q.cjs} +20 -9
- package/dist/{chunk-ZGLD4TVZ.mjs → chunk-MBEJI5HF.mjs} +4 -4
- package/dist/{chunk-PRWCB3QL.mjs → chunk-MIIYDLGM.js} +524 -141
- package/dist/{chunk-H55LI6WY.js → chunk-MOO4L7F4.mjs} +15 -4
- package/dist/{chunk-7XOPAB5Q.js → chunk-MT3OWDPC.mjs} +55 -5
- package/dist/chunk-MVGUEJ5Z.cjs +370 -0
- package/dist/chunk-PD4EJTQC.cjs +229 -0
- package/dist/chunk-PWC3RBQE.mjs +300 -0
- package/dist/{chunk-MWXMNYJS.cjs → chunk-Q2I37RP3.cjs} +643 -124
- package/dist/{chunk-VFIUZG7J.mjs → chunk-RKGKFN2A.js} +79 -17
- package/dist/{chunk-NYL4D7SK.cjs → chunk-SA6HUJVI.cjs} +5 -5
- package/dist/{chunk-K2T3DV26.mjs → chunk-TRM4JUZQ.js} +15 -4
- package/dist/chunk-UB4B6OFY.js +370 -0
- package/dist/{chunk-G3XGCZDQ.js → chunk-UCUBNWM2.js} +1 -1
- package/dist/chunk-VN44DYYT.cjs +2024 -0
- package/dist/{client-CtFmoDvM.d.ts → client-CZHU674n.d.ts} +211 -36
- package/dist/core/index.cjs +135 -9
- package/dist/core/index.d.ts +238 -33
- package/dist/core/index.js +155 -29
- package/dist/core/index.mjs +155 -29
- package/dist/{effect-CGNl5Rqp.d.ts → effect-DIUHZ9IN.d.ts} +89 -1
- package/dist/effectRunner-CFLC32IK.cjs +8 -0
- package/dist/{effectRunner-A4CHJXJI.js → effectRunner-L4S7IPT3.js} +2 -2
- package/dist/{effectRunner-OPUF6QRN.mjs → effectRunner-NNGG75QA.mjs} +2 -2
- package/dist/http/index.cjs +324 -2986
- package/dist/http/index.d.ts +54 -68
- package/dist/http/index.js +238 -2900
- package/dist/http/index.mjs +238 -2900
- package/dist/http/testing.cjs +14 -12
- package/dist/http/testing.d.ts +5 -4
- package/dist/http/testing.js +10 -8
- package/dist/http/testing.mjs +10 -8
- package/dist/index.cjs +423 -255
- package/dist/index.d.ts +87 -69
- package/dist/index.js +301 -133
- package/dist/index.mjs +301 -133
- package/dist/observability/index.cjs +16 -531
- package/dist/observability/index.d.ts +81 -8
- package/dist/observability/index.js +23 -538
- package/dist/observability/index.mjs +23 -538
- package/dist/perf/cli.cjs +401 -0
- package/dist/perf/cli.d.ts +1 -0
- package/dist/perf/cli.js +401 -0
- package/dist/perf/cli.mjs +401 -0
- package/dist/perf/index.cjs +141 -0
- package/dist/perf/index.d.ts +483 -0
- package/dist/perf/index.js +141 -0
- package/dist/perf/index.mjs +141 -0
- package/dist/schedule-CK3Ml_7p.d.ts +259 -0
- package/dist/schema/index.cjs +6 -2
- package/dist/schema/index.d.ts +3 -1
- package/dist/schema/index.js +5 -1
- package/dist/schema/index.mjs +5 -1
- package/dist/{server-C8hDXA74.d.ts → server-GJPg8ZSG.d.ts} +4 -3
- package/dist/{stream-dvSs0QS5.d.ts → stream-B4oK9JFP.d.ts} +1 -1
- package/dist/{tracer-B5tRH9H7.d.ts → tracer-Hwt1cl7h.d.ts} +13 -54
- package/dist/{tracing-Dt9S_6V8.d.ts → tracing-DqbTKGcf.d.ts} +1 -1
- package/docs/ARCHITECTURE.md +292 -0
- package/docs/README.md +63 -0
- package/docs/adr/0001-ai-context-pack.md +32 -0
- package/docs/agent-apply-mode.md +104 -0
- package/docs/agent-approvals.md +110 -0
- package/docs/agent-batch.md +185 -0
- package/docs/agent-boundaries.md +112 -0
- package/docs/agent-chat-sessions.md +160 -0
- package/docs/agent-ci.md +17 -0
- package/docs/agent-cli.md +405 -0
- package/docs/agent-config.md +480 -0
- package/docs/agent-context-discovery.md +159 -0
- package/docs/agent-copilot-like-dx.md +126 -0
- package/docs/agent-declarative-optimized-planning.md +138 -0
- package/docs/agent-dx.md +224 -0
- package/docs/agent-env-files.md +126 -0
- package/docs/agent-follow-up-context.md +43 -0
- package/docs/agent-global-usage.md +180 -0
- package/docs/agent-init.md +109 -0
- package/docs/agent-install-and-configure.md +516 -0
- package/docs/agent-language-workspace-ux.md +99 -0
- package/docs/agent-llm-adapters.md +123 -0
- package/docs/agent-local-install.md +190 -0
- package/docs/agent-local-tests.md +51 -0
- package/docs/agent-observability.md +155 -0
- package/docs/agent-patch-quality-loop.md +162 -0
- package/docs/agent-presets.md +22 -0
- package/docs/agent-project-commands.md +237 -0
- package/docs/agent-project-intelligence.md +156 -0
- package/docs/agent-redaction.md +18 -0
- package/docs/agent-release-readiness.md +76 -0
- package/docs/agent-rollback-safety.md +162 -0
- package/docs/agent-rollback.md +23 -0
- package/docs/agent-run-artifacts.md +16 -0
- package/docs/agent-vscode-auto-discovery.md +137 -0
- package/docs/agent-vscode-batch-runner.md +100 -0
- package/docs/agent-vscode-chat-layout.md +90 -0
- package/docs/agent-vscode-clean-install.md +147 -0
- package/docs/agent-vscode-code-actions.md +70 -0
- package/docs/agent-vscode-diff-preview.md +45 -0
- package/docs/agent-vscode-inline-assist.md +56 -0
- package/docs/agent-vscode-install.md +186 -0
- package/docs/agent-vscode-model-setup.md +97 -0
- package/docs/agent-vscode-patch-preview.md +92 -0
- package/docs/agent-vscode-problems.md +79 -0
- package/docs/agent-vscode-project-dashboard.md +106 -0
- package/docs/agent-vscode-run-history.md +92 -0
- package/docs/agent-vscode-ux.md +73 -0
- package/docs/ai/INVARIANTS.md +84 -0
- package/docs/ai/PROJECT_MAP.md +338 -0
- package/docs/ai/PUBLIC_API.md +336 -0
- package/docs/ai/VALIDATION_MATRIX.md +67 -0
- package/docs/api-polish.md +37 -0
- package/docs/cancellation.md +162 -0
- package/docs/coverage.md +46 -0
- package/docs/getting-started.md +159 -0
- package/docs/guides/README.md +40 -0
- package/docs/guides/circuit-breaker.md +89 -0
- package/docs/guides/error-handling.md +91 -0
- package/docs/guides/getting-started.md +107 -0
- package/docs/guides/layers.md +189 -0
- package/docs/guides/metrics.md +101 -0
- package/docs/guides/resource-management.md +141 -0
- package/docs/guides/retry.md +215 -0
- package/docs/guides/semaphore.md +66 -0
- package/docs/guides/streams.md +117 -0
- package/docs/guides/supervisors.md +98 -0
- package/docs/guides/testing.md +162 -0
- package/docs/guides/tracing.md +71 -0
- package/docs/http-recipes.md +399 -0
- package/docs/http.md +749 -0
- package/docs/modules.md +285 -0
- package/docs/observability-collector-smoke.md +31 -0
- package/docs/observability-framework-examples.md +98 -0
- package/docs/observability.md +542 -0
- package/docs/otel-collector-smoke.yaml +27 -0
- package/docs/performance-profiler.md +199 -0
- package/docs/production-readiness.md +73 -0
- package/docs/recipes/README.md +12 -0
- package/docs/recipes/http-server.md +45 -0
- package/docs/recipes/layers.md +44 -0
- package/docs/recipes/performance.md +47 -0
- package/docs/recipes/runtime.md +41 -0
- package/docs/recipes/testing.md +41 -0
- package/docs/release.md +53 -0
- package/docs/wasm-bounded-queues.md +44 -0
- package/docs/wasm-engine-observability-benchmarks.md +85 -0
- package/docs/wasm-fiber-engine.md +117 -0
- package/docs/wasm-scheduler-state-machine.md +122 -0
- package/docs/wasm-stream-chunks.md +54 -0
- package/package.json +22 -2
- package/dist/chunk-45F7OKGT.cjs +0 -104
- package/dist/chunk-7V4KY4RL.mjs +0 -104
- package/dist/chunk-DJQ7OMMB.cjs +0 -144
- package/dist/chunk-GOV47PPB.mjs +0 -552
- package/dist/chunk-JF4XXPZ5.cjs +0 -552
- package/dist/chunk-KCPT2D6G.js +0 -552
- package/dist/chunk-NOYZIMUJ.mjs +0 -144
- package/dist/chunk-PNVFW245.js +0 -144
- package/dist/chunk-ROJC3NBJ.js +0 -104
- package/dist/effectRunner-3ZHAD3LE.cjs +0 -8
- package/dist/schedule-Fque9Abz.d.ts +0 -70
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
# 🧱 ARCHITECTURE — brass-runtime
|
|
2
|
+
|
|
3
|
+
This document explains the **architectural structure** of `brass-runtime`, how the layers relate to each other, and the design principles behind them.
|
|
4
|
+
|
|
5
|
+
The architecture is intentionally inspired by **ZIO 2**, but implemented from scratch in **TypeScript**, without relying on `Promise` as the semantic runtime primitive.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## High-level overview
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
┌────────────────────────────────────────────┐
|
|
13
|
+
│ User Programs │
|
|
14
|
+
│ (examples, apps, libraries, tests) │
|
|
15
|
+
└────────────────────────────────────────────┘
|
|
16
|
+
▲
|
|
17
|
+
│
|
|
18
|
+
┌────────────────────────────────────────────┐
|
|
19
|
+
│ High-level Modules │
|
|
20
|
+
│ (HTTP, Streams, Resources, etc.) │
|
|
21
|
+
└────────────────────────────────────────────┘
|
|
22
|
+
▲
|
|
23
|
+
│
|
|
24
|
+
┌────────────────────────────────────────────┐
|
|
25
|
+
│ Core Effect Runtime │
|
|
26
|
+
│ Async / Effect / Fiber / Scope / Scheduler │
|
|
27
|
+
└────────────────────────────────────────────┘
|
|
28
|
+
▲
|
|
29
|
+
│
|
|
30
|
+
┌────────────────────────────────────────────┐
|
|
31
|
+
│ JavaScript Host Environment │
|
|
32
|
+
│ (event loop, timers, fetch, callbacks) │
|
|
33
|
+
└────────────────────────────────────────────┘
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Key idea:
|
|
37
|
+
> **Only the core runtime knows about execution.**
|
|
38
|
+
> Everything else is *pure descriptions* interpreted by the runtime.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Core principles
|
|
43
|
+
|
|
44
|
+
### 1. No Promise-based semantics
|
|
45
|
+
- `Promise` is never the semantic primitive.
|
|
46
|
+
- Async work is represented explicitly as data (`Async`).
|
|
47
|
+
- The runtime *interprets* async effects using callbacks and schedulers.
|
|
48
|
+
|
|
49
|
+
This ensures:
|
|
50
|
+
- Deterministic scheduling
|
|
51
|
+
- Cooperative cancellation
|
|
52
|
+
- Structured concurrency
|
|
53
|
+
- Testability
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
### 2. Lazy by default
|
|
58
|
+
All effects are **lazy**:
|
|
59
|
+
- Nothing runs until interpreted by a `Fiber`
|
|
60
|
+
- Creating an effect is pure and side-effect free
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
const eff = http.getJson<Post>("/posts/1")
|
|
64
|
+
// nothing has happened yet
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Execution only begins when:
|
|
68
|
+
- Forked into a fiber
|
|
69
|
+
- Or awaited via `toPromise` (interop helper)
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
### 3. Structured concurrency
|
|
74
|
+
Fibers always belong to a **Scope**.
|
|
75
|
+
|
|
76
|
+
Rules:
|
|
77
|
+
- Child fibers cannot outlive their parent scope
|
|
78
|
+
- Closing a scope interrupts all children
|
|
79
|
+
- Finalizers run in LIFO order
|
|
80
|
+
|
|
81
|
+
This prevents:
|
|
82
|
+
- Leaked async tasks
|
|
83
|
+
- Forgotten cleanups
|
|
84
|
+
- Detached background work
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Core Runtime Layer
|
|
89
|
+
|
|
90
|
+
### Main components
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
Async
|
|
94
|
+
│
|
|
95
|
+
▼
|
|
96
|
+
Fiber ── Scheduler
|
|
97
|
+
│
|
|
98
|
+
▼
|
|
99
|
+
Scope ── Finalizers
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
#### `Async<R, E, A>`
|
|
103
|
+
- Algebraic data type representing effectful computation
|
|
104
|
+
- Variants: `Succeed | Fail | Sync | Async | FlatMap`
|
|
105
|
+
- Pure data, no execution
|
|
106
|
+
|
|
107
|
+
#### `Fiber<E, A>`
|
|
108
|
+
- Interpreter of `Async`
|
|
109
|
+
- Owns:
|
|
110
|
+
- Stack
|
|
111
|
+
- RunState
|
|
112
|
+
- Interrupt status
|
|
113
|
+
- Finalizers
|
|
114
|
+
- Can be:
|
|
115
|
+
- Joined
|
|
116
|
+
- Interrupted
|
|
117
|
+
- Forked
|
|
118
|
+
|
|
119
|
+
#### `Scheduler`
|
|
120
|
+
- Cooperative task queue
|
|
121
|
+
- Ensures fairness
|
|
122
|
+
- No preemption
|
|
123
|
+
- Explicit scheduling boundaries
|
|
124
|
+
|
|
125
|
+
#### `Scope`
|
|
126
|
+
- Lifetime manager
|
|
127
|
+
- Owns:
|
|
128
|
+
- Child fibers
|
|
129
|
+
- Sub-scopes
|
|
130
|
+
- Finalizers
|
|
131
|
+
- Deterministic cleanup
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Streams Architecture
|
|
136
|
+
|
|
137
|
+
Streams are **pull-based**, inspired by ZIO Streams.
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
ZStream
|
|
141
|
+
│
|
|
142
|
+
▼
|
|
143
|
+
Pull<R, Option<E>, A>
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Characteristics
|
|
147
|
+
- Backpressure-aware
|
|
148
|
+
- Resource-safe
|
|
149
|
+
- Scope-bound
|
|
150
|
+
- Deterministic cleanup
|
|
151
|
+
|
|
152
|
+
### Why pull-based?
|
|
153
|
+
- Simpler cancellation semantics
|
|
154
|
+
- Natural backpressure
|
|
155
|
+
- Easier reasoning about lifetimes
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## HTTP Module Architecture (brass-http)
|
|
160
|
+
|
|
161
|
+
HTTP is **not part of the core runtime**.
|
|
162
|
+
|
|
163
|
+
It is implemented as a **high-level module** built entirely on `Async`.
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
HttpRequest
|
|
167
|
+
│
|
|
168
|
+
▼
|
|
169
|
+
HttpClient (Request => Async)
|
|
170
|
+
│
|
|
171
|
+
▼
|
|
172
|
+
Middlewares
|
|
173
|
+
(withMeta, logging, retries)
|
|
174
|
+
│
|
|
175
|
+
▼
|
|
176
|
+
Content helpers
|
|
177
|
+
(getJson, getText)
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Important properties
|
|
181
|
+
- Fully lazy
|
|
182
|
+
- Cancelable via fiber interruption
|
|
183
|
+
- Composable via middleware functions
|
|
184
|
+
- Environment-aware (baseUrl, headers, auth)
|
|
185
|
+
|
|
186
|
+
HTTP execution only happens when:
|
|
187
|
+
- The returned `Async` is run by a fiber
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## Middleware model
|
|
192
|
+
|
|
193
|
+
Middlewares are pure functions:
|
|
194
|
+
|
|
195
|
+
```ts
|
|
196
|
+
type Middleware = (client: HttpClient) => HttpClient
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
They:
|
|
200
|
+
- Do not execute effects
|
|
201
|
+
- Only transform descriptions
|
|
202
|
+
- Compose left-to-right
|
|
203
|
+
|
|
204
|
+
Examples:
|
|
205
|
+
- `withMeta`
|
|
206
|
+
- logging
|
|
207
|
+
- retries
|
|
208
|
+
- tracing
|
|
209
|
+
- auth injection
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## Interop Layer
|
|
214
|
+
|
|
215
|
+
### `toPromise`
|
|
216
|
+
- Thin boundary for examples and DX
|
|
217
|
+
- Not part of core semantics
|
|
218
|
+
- Converts fiber execution into a `Promise`
|
|
219
|
+
|
|
220
|
+
### `fromPromiseAbortable`
|
|
221
|
+
- Adapts Promise APIs that support `AbortSignal`
|
|
222
|
+
- Preserves cooperative cancellation
|
|
223
|
+
- Integrates cleanly with fibers
|
|
224
|
+
|
|
225
|
+
Interop is **explicit and contained**.
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## What is NOT allowed
|
|
230
|
+
|
|
231
|
+
By design:
|
|
232
|
+
- ❌ Hidden Promises inside effects
|
|
233
|
+
- ❌ Detached async work
|
|
234
|
+
- ❌ Implicit background execution
|
|
235
|
+
- ❌ Fire-and-forget APIs
|
|
236
|
+
|
|
237
|
+
If something runs:
|
|
238
|
+
> It must be owned by a fiber and a scope.
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## Extension points
|
|
243
|
+
|
|
244
|
+
Designed to grow horizontally:
|
|
245
|
+
|
|
246
|
+
- New modules (HTTP, FS, DB, etc.)
|
|
247
|
+
- New stream combinators
|
|
248
|
+
- New schedulers (priority, test)
|
|
249
|
+
- New runtimes (browser, workers)
|
|
250
|
+
|
|
251
|
+
Without changing the core semantics.
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
## Mental model (TL;DR)
|
|
256
|
+
|
|
257
|
+
- **Core** = execution + rules
|
|
258
|
+
- **Async** = description
|
|
259
|
+
- **Fiber** = interpreter
|
|
260
|
+
- **Scope** = lifetime
|
|
261
|
+
- **Modules** = pure libraries on top
|
|
262
|
+
- **Interop** = explicit escape hatch
|
|
263
|
+
|
|
264
|
+
If you understand this:
|
|
265
|
+
👉 you understand the entire system.
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## Status
|
|
270
|
+
|
|
271
|
+
This architecture is:
|
|
272
|
+
- Experimental
|
|
273
|
+
- Intentionally minimal
|
|
274
|
+
- Designed for learning, exploration, and correctness
|
|
275
|
+
|
|
276
|
+
But:
|
|
277
|
+
> It already enforces stronger guarantees than most Promise-based codebases.
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
MIT License © 2025
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## Further reading
|
|
287
|
+
|
|
288
|
+
- [Getting started](./getting-started.md)
|
|
289
|
+
- [Modules overview](./modules.md)
|
|
290
|
+
- [Cancellation & interruption](./cancellation.md)
|
|
291
|
+
- [Observability (hooks & events)](./observability.md)
|
|
292
|
+
- [HTTP client](./http.md)
|
package/docs/README.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Documentation
|
|
2
|
+
|
|
3
|
+
Start here:
|
|
4
|
+
|
|
5
|
+
- **[Getting started](./getting-started.md)** — installation, first effects, and running examples
|
|
6
|
+
- **[Architecture](./ARCHITECTURE.md)** — how the runtime is structured
|
|
7
|
+
- **[Cancellation & interruption](./cancellation.md)** — interruption semantics, scopes, and cancellable `Async`
|
|
8
|
+
- **[Observability](./observability.md)** — hooks, events, sinks, tracing, and HTTP policy context
|
|
9
|
+
- **[HTTP client](./http.md)** — ZIO-style HTTP built on brass-runtime
|
|
10
|
+
- **[HTTP recipes](./http-recipes.md)** — typed clients, custom transports, production adoption, observability, and config validation
|
|
11
|
+
- **[Recipes](./recipes/README.md)** — copyable runtime, layer, HTTP server, testing, and performance paths
|
|
12
|
+
- **[API polish notes](./api-polish.md)** — first-release DX audit and compatibility posture
|
|
13
|
+
- **[First release checklist](./release.md)** — local release gate and perf evidence workflow
|
|
14
|
+
- **[Modules overview](./modules.md)** — map of core modules and where things live
|
|
15
|
+
- **[AI context pack](./ai/PROJECT_MAP.md)** — compact project map, invariants, validation matrix, and public API notes
|
|
16
|
+
- **[Agent module boundaries](./agent-boundaries.md)** — rules for keeping `brass-agent` isolated from the core runtime
|
|
17
|
+
- **[Brass Agent install and configure](./agent-install-and-configure.md)** — end-to-end local setup for CLI, config, providers, and VS Code
|
|
18
|
+
|
|
19
|
+
- [Agent LLM adapters](./agent-llm-adapters.md)
|
|
20
|
+
- [Agent env files](./agent-env-files.md)
|
|
21
|
+
- [Agent global usage and workspace discovery](./agent-global-usage.md)
|
|
22
|
+
- [Agent apply mode](./agent-apply-mode.md)
|
|
23
|
+
- [Brass Agent CLI](./agent-cli.md)
|
|
24
|
+
- [Agent init](./agent-init.md)
|
|
25
|
+
- [Agent observability](./agent-observability.md)
|
|
26
|
+
- [Agent approvals](./agent-approvals.md)
|
|
27
|
+
- [Agent config and policy files](./agent-config.md)
|
|
28
|
+
- [Agent project command discovery](./agent-project-commands.md)
|
|
29
|
+
- [Agent project intelligence](./agent-project-intelligence.md)
|
|
30
|
+
- [Declarative optimized planning roadmap](./agent-declarative-optimized-planning.md)
|
|
31
|
+
- [Agent context discovery](./agent-context-discovery.md)
|
|
32
|
+
- [Agent patch quality loop](./agent-patch-quality-loop.md)
|
|
33
|
+
- [Agent automatic rollback safety](./agent-rollback-safety.md)
|
|
34
|
+
- [Agent DX surfaces](./agent-dx.md)
|
|
35
|
+
|
|
36
|
+
- [VS Code patch preview](./agent-vscode-patch-preview.md)
|
|
37
|
+
- [VS Code enhanced diff preview](./agent-vscode-diff-preview.md)
|
|
38
|
+
- [VS Code run history](./agent-vscode-run-history.md)
|
|
39
|
+
- [VS Code batch runner](./agent-vscode-batch-runner.md)
|
|
40
|
+
- [VS Code UX](./agent-vscode-ux.md)
|
|
41
|
+
- [VS Code Project dashboard](./agent-vscode-project-dashboard.md)
|
|
42
|
+
- [VS Code Chat layout / focus mode](./agent-vscode-chat-layout.md)
|
|
43
|
+
- [Copilot-like VS Code DX](./agent-copilot-like-dx.md)
|
|
44
|
+
- [Chat sessions and slash commands](./agent-chat-sessions.md)
|
|
45
|
+
- [Agent follow-up context](./agent-follow-up-context.md)
|
|
46
|
+
- [VS Code code actions](./agent-vscode-code-actions.md)
|
|
47
|
+
- [VS Code problems-aware chat](./agent-vscode-problems.md)
|
|
48
|
+
- [VS Code inline assist](./agent-vscode-inline-assist.md)
|
|
49
|
+
- [Agent release readiness](./agent-release-readiness.md)
|
|
50
|
+
- [VS Code local install](./agent-vscode-install.md)
|
|
51
|
+
- [VS Code auto-discovery](./agent-vscode-auto-discovery.md)
|
|
52
|
+
- [VS Code model setup](./agent-vscode-model-setup.md)
|
|
53
|
+
- [Agent local install and doctor](./agent-local-install.md)
|
|
54
|
+
- [Agent local tests](./agent-local-tests.md)
|
|
55
|
+
|
|
56
|
+
- [Agent rollback patches](./agent-rollback.md)
|
|
57
|
+
- [Agent redaction](./agent-redaction.md)
|
|
58
|
+
- [Agent run artifacts](./agent-run-artifacts.md)
|
|
59
|
+
- [Agent CI mode](./agent-ci.md)
|
|
60
|
+
- [Agent presets](./agent-presets.md)
|
|
61
|
+
- [Agent batch runs](./agent-batch.md)
|
|
62
|
+
- [VS Code full clean and reinstall](./agent-vscode-clean-install.md)
|
|
63
|
+
- [Agent language and workspace setup UX](agent-language-workspace-ux.md)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# ADR 0001: Maintain an AI Context Pack
|
|
2
|
+
|
|
3
|
+
Status: accepted
|
|
4
|
+
|
|
5
|
+
## Context
|
|
6
|
+
|
|
7
|
+
`brass-runtime` contains a core effect runtime, streams, HTTP modules, WASM
|
|
8
|
+
engine pieces, benchmarks, and Brass Agent surfaces. The codebase is still small
|
|
9
|
+
enough to navigate manually, but large enough that a contributor or coding agent
|
|
10
|
+
needs a compact map before making safe changes.
|
|
11
|
+
|
|
12
|
+
## Decision
|
|
13
|
+
|
|
14
|
+
Maintain a small context pack:
|
|
15
|
+
|
|
16
|
+
- `AGENTS.md` for root-level contributor/agent guidance.
|
|
17
|
+
- `docs/ai/PROJECT_MAP.md` for module navigation.
|
|
18
|
+
- `docs/ai/INVARIANTS.md` for semantic rules.
|
|
19
|
+
- `docs/ai/VALIDATION_MATRIX.md` for test selection.
|
|
20
|
+
- `docs/ai/PUBLIC_API.md` for exports and compatibility.
|
|
21
|
+
- `scripts/context-pack.mjs` for generated workspace summaries.
|
|
22
|
+
|
|
23
|
+
The generated context command prints to stdout and does not create tracked
|
|
24
|
+
artifacts by default.
|
|
25
|
+
|
|
26
|
+
## Consequences
|
|
27
|
+
|
|
28
|
+
- Future changes should update the context pack when they move module
|
|
29
|
+
boundaries, change public API, or add validation expectations.
|
|
30
|
+
- Agents can gather focused context without rereading the entire repository.
|
|
31
|
+
- The context pack is documentation, not a replacement for tests.
|
|
32
|
+
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Agent apply mode
|
|
2
|
+
|
|
3
|
+
P3 adds a conservative write path for the experimental agent.
|
|
4
|
+
|
|
5
|
+
## Goal
|
|
6
|
+
|
|
7
|
+
Keep the default CLI behavior safe:
|
|
8
|
+
|
|
9
|
+
- default mode remains `propose`
|
|
10
|
+
- `write` mode must be explicit
|
|
11
|
+
- patch application remains policy-gated and approval-gated
|
|
12
|
+
- patch targets must stay inside the workspace
|
|
13
|
+
- discovered validation commands still go through `PermissionService`
|
|
14
|
+
|
|
15
|
+
## New pieces
|
|
16
|
+
|
|
17
|
+
`src/agent` now includes:
|
|
18
|
+
|
|
19
|
+
- `PatchService`
|
|
20
|
+
- `patch.apply` / `patch.applied`
|
|
21
|
+
- unified-diff extraction helpers
|
|
22
|
+
- a Node patch adapter built on `git apply`
|
|
23
|
+
- CLI flags for `--mode`, `--apply`, and approval strategy
|
|
24
|
+
|
|
25
|
+
## Modes
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
brass-agent "fix the failing tests" # propose (default)
|
|
29
|
+
brass-agent --apply "fix the failing tests" # write, prompts when interactive
|
|
30
|
+
brass-agent --apply --yes "fix the failing tests" # write, auto-approve
|
|
31
|
+
brass-agent --mode write "fix the failing tests"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Safety rules
|
|
35
|
+
|
|
36
|
+
1. The agent only applies unified diffs.
|
|
37
|
+
2. All patch target paths are validated as workspace-relative before apply.
|
|
38
|
+
3. `propose` mode may emit `patch.proposed`, but never `patch.apply`.
|
|
39
|
+
4. `write` mode may apply patches only after approval.
|
|
40
|
+
5. Shell commands remain whitelisted.
|
|
41
|
+
6. After `patch.applied`, the agent re-runs the same discovered validation commands.
|
|
42
|
+
|
|
43
|
+
## Patch adapter
|
|
44
|
+
|
|
45
|
+
The Node adapter uses `git apply --check` before the actual apply step.
|
|
46
|
+
|
|
47
|
+
That gives us a conservative path with a dry-run check first, while keeping the runtime invariant intact:
|
|
48
|
+
all external work is still represented as cancellable `Async`.
|
|
49
|
+
|
|
50
|
+
## Offline smoke tests
|
|
51
|
+
|
|
52
|
+
You can drive the fake LLM with a deterministic response:
|
|
53
|
+
|
|
54
|
+
~~~bash
|
|
55
|
+
export BRASS_LLM_PROVIDER=fake
|
|
56
|
+
export BRASS_FAKE_LLM_RESPONSE='Here is a patch.
|
|
57
|
+
|
|
58
|
+
```diff
|
|
59
|
+
--- a/hello.txt
|
|
60
|
+
+++ b/hello.txt
|
|
61
|
+
@@ -1 +1 @@
|
|
62
|
+
-old
|
|
63
|
+
+new
|
|
64
|
+
```'
|
|
65
|
+
|
|
66
|
+
brass-agent --apply --yes --cwd ./tmp/repro "apply the inferred patch"
|
|
67
|
+
~~~
|
|
68
|
+
|
|
69
|
+
## Patch quality loop
|
|
70
|
+
|
|
71
|
+
P13 adds an optional repair loop for normal generated patches in `write` mode.
|
|
72
|
+
After a generated patch is applied, the agent re-runs discovered validation
|
|
73
|
+
commands. If validation fails and repair budget remains, it calls `llm.patch` to
|
|
74
|
+
request an incremental repair diff, applies that diff, and validates again.
|
|
75
|
+
|
|
76
|
+
The default repair budget is one attempt:
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"patchQuality": {
|
|
81
|
+
"enabled": true,
|
|
82
|
+
"maxRepairAttempts": 1
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Exact patch-file flows remain exact. `--apply-patch-file` does not trigger
|
|
88
|
+
repair attempts, because clients such as the VS Code extension use that path
|
|
89
|
+
after the user approved a specific previewed diff.
|
|
90
|
+
|
|
91
|
+
See [Agent patch quality loop](./agent-patch-quality-loop.md).
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
## Automatic rollback safety
|
|
95
|
+
|
|
96
|
+
P14 adds automatic rollback safety for generated patches. If generated patches
|
|
97
|
+
still fail validation after the configured repair attempts are exhausted, the
|
|
98
|
+
agent can schedule `patch.rollback` actions to reverse the generated patch stack.
|
|
99
|
+
|
|
100
|
+
Rollback is still policy-gated and approval-gated. Exact patch-file flows remain
|
|
101
|
+
protected by default so a VS Code-approved patch is not silently reversed unless
|
|
102
|
+
the project opts in with `rollback.allowForSuppliedPatches`.
|
|
103
|
+
|
|
104
|
+
See [Agent automatic rollback safety](./agent-rollback-safety.md).
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Agent approvals
|
|
2
|
+
|
|
3
|
+
P6 adds interactive approvals to `brass-agent` without moving prompt logic into
|
|
4
|
+
`src/core`.
|
|
5
|
+
|
|
6
|
+
The boundary remains:
|
|
7
|
+
|
|
8
|
+
```txt
|
|
9
|
+
src/core
|
|
10
|
+
↑
|
|
11
|
+
src/agent PermissionService / ApprovalService
|
|
12
|
+
↑
|
|
13
|
+
src/agent/cli prompt UX
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Decision flow
|
|
17
|
+
|
|
18
|
+
Every action still goes through the same policy pipeline:
|
|
19
|
+
|
|
20
|
+
```txt
|
|
21
|
+
AgentAction
|
|
22
|
+
-> PermissionService.check(...)
|
|
23
|
+
-> allow | deny | ask
|
|
24
|
+
-> ApprovalService.request(...) when ask
|
|
25
|
+
-> ToolPolicy timeout/retry
|
|
26
|
+
-> Async tool effect
|
|
27
|
+
-> Observation
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
`PermissionService` decides whether an action needs approval. `ApprovalService`
|
|
31
|
+
decides how to obtain that approval: prompt the human, auto-approve, auto-deny,
|
|
32
|
+
or integrate with another UI.
|
|
33
|
+
|
|
34
|
+
## Built-in approvals
|
|
35
|
+
|
|
36
|
+
The agent exports:
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
autoApproveApprovals
|
|
40
|
+
makeAutoDenyApprovals(reason?)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The CLI also provides an interactive implementation that prompts on stderr.
|
|
44
|
+
|
|
45
|
+
## CLI behavior
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
brass-agent --apply "fix tests" # prompts when interactive
|
|
49
|
+
brass-agent --apply --yes "fix tests" # auto-approve
|
|
50
|
+
brass-agent --apply --no-input "fix tests" # auto-deny
|
|
51
|
+
brass-agent --approval interactive --apply "fix tests"
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Environment variables:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
BRASS_AGENT_APPROVAL=approve|deny|interactive|auto
|
|
58
|
+
BRASS_AGENT_AUTO_APPROVE=true
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
`auto` is conservative:
|
|
62
|
+
|
|
63
|
+
```txt
|
|
64
|
+
human TTY session -> interactive prompts
|
|
65
|
+
json/events-json or non-TTY -> deny approval-required actions
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Use `--yes` explicitly for non-interactive smoke tests or CI flows that are
|
|
69
|
+
allowed to mutate the workspace.
|
|
70
|
+
|
|
71
|
+
## Events
|
|
72
|
+
|
|
73
|
+
Approvals emit typed events:
|
|
74
|
+
|
|
75
|
+
```txt
|
|
76
|
+
agent.approval.requested
|
|
77
|
+
agent.approval.resolved
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
These events are available in human output and `--events-json`. They are emitted
|
|
81
|
+
before and after the approval service runs.
|
|
82
|
+
|
|
83
|
+
## Safety invariants
|
|
84
|
+
|
|
85
|
+
- Approval prompts are a capability of `src/agent`, not `src/core`.
|
|
86
|
+
- An action that requires approval must not run unless approval is granted.
|
|
87
|
+
- Missing approval service means approval-required actions are rejected.
|
|
88
|
+
- Observability is best-effort and must not change approval semantics.
|
|
89
|
+
- Non-interactive runs deny by default unless explicitly configured to approve.
|
|
90
|
+
|
|
91
|
+
## Config defaults
|
|
92
|
+
|
|
93
|
+
P7 allows a project config file to set the default CLI approval strategy:
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"approval": "auto"
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
CLI flags still win over config:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
brass-agent --approval deny "inspect"
|
|
105
|
+
brass-agent --yes --apply "fix tests"
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
`permissions.patchApply` can also tune whether `patch.apply` is allowed, denied,
|
|
109
|
+
or routed through approval in `write` and `autonomous` modes. See
|
|
110
|
+
[Agent config and policy files](./agent-config.md).
|