brass-runtime 1.15.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 +673 -136
- package/dist/agent/cli/main.cjs +40 -35
- package/dist/agent/cli/main.js +9 -4
- package/dist/agent/cli/main.mjs +9 -4
- package/dist/agent/index.cjs +8 -4
- package/dist/agent/index.d.ts +1 -1
- package/dist/agent/index.js +7 -3
- package/dist/agent/index.mjs +7 -3
- package/dist/chunk-2HQTDLHF.mjs +683 -0
- package/dist/chunk-36I3M4UC.mjs +370 -0
- package/dist/chunk-3AYM6WPJ.js +1629 -0
- package/dist/chunk-3LOYJFRR.cjs +300 -0
- package/dist/chunk-3RG5ZIWI.js +10 -0
- package/dist/chunk-3Y2RIUMM.js +300 -0
- package/dist/{chunk-VEZNF5GZ.cjs → chunk-4ROBZFL6.cjs} +130 -126
- package/dist/{chunk-3QMOKAS5.js → chunk-52OB2ROS.js} +9 -5
- package/dist/chunk-52PPNNI4.cjs +416 -0
- package/dist/chunk-5EC274J5.cjs +2874 -0
- package/dist/chunk-5QC7LRZ3.js +229 -0
- package/dist/chunk-5VRJNBLZ.mjs +2874 -0
- 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-4NHES7VK.mjs → chunk-7JIJOVCT.js} +27 -13
- package/dist/chunk-A2OM6NEH.mjs +194 -0
- package/dist/chunk-AGR5B2BC.cjs +683 -0
- package/dist/chunk-AVNQLJ5V.js +777 -0
- package/dist/chunk-B33ICAKP.js +313 -0
- package/dist/{chunk-ELOOF35R.mjs → chunk-B5JD23U7.mjs} +1 -1
- package/dist/chunk-BABBZK4Y.js +2024 -0
- package/dist/chunk-C3MDXTRZ.js +354 -0
- package/dist/chunk-CIZFIMK5.js +2193 -0
- package/dist/chunk-CZIVE6NT.cjs +354 -0
- package/dist/chunk-DNFJLJMW.mjs +354 -0
- package/dist/chunk-DNFO2EIZ.mjs +777 -0
- package/dist/chunk-EJ6BPYVR.mjs +416 -0
- package/dist/chunk-ENKODRU3.cjs +2193 -0
- package/dist/chunk-EOC4UHBS.mjs +229 -0
- package/dist/{chunk-BMH5AV44.js → chunk-FH2X7BVP.js} +756 -440
- package/dist/{chunk-PPUXIH5R.js → chunk-FHQGHPMO.mjs} +27 -13
- package/dist/{chunk-TGIFUAK4.cjs → chunk-GLE2WY7Z.cjs} +951 -635
- package/dist/{chunk-BDF4AMWX.mjs → chunk-GYM3LLGS.mjs} +756 -440
- package/dist/chunk-HLWLMW2F.mjs +2024 -0
- package/dist/chunk-JF5WGYJJ.cjs +194 -0
- package/dist/chunk-KH4SYAOS.mjs +1629 -0
- package/dist/chunk-KN32XNTH.mjs +313 -0
- package/dist/chunk-KQLYONSE.cjs +2871 -0
- package/dist/{chunk-STVLQ3XD.cjs → chunk-KZJQ723N.cjs} +92 -78
- package/dist/chunk-L2SYFEBS.js +194 -0
- package/dist/chunk-L6VB5N7Q.cjs +104 -0
- package/dist/{chunk-K6M7MDZ4.mjs → chunk-MBEJI5HF.mjs} +9 -5
- package/dist/chunk-MIIYDLGM.js +2874 -0
- package/dist/chunk-MOO4L7F4.mjs +104 -0
- package/dist/chunk-MT3OWDPC.mjs +2193 -0
- package/dist/chunk-MVGUEJ5Z.cjs +370 -0
- package/dist/chunk-OBGZSXTJ.cjs +10 -0
- package/dist/chunk-PD4EJTQC.cjs +229 -0
- package/dist/chunk-PWC3RBQE.mjs +300 -0
- package/dist/chunk-Q2I37RP3.cjs +1629 -0
- package/dist/chunk-RKGKFN2A.js +416 -0
- package/dist/{chunk-R3R2FVLG.cjs → chunk-SA6HUJVI.cjs} +5 -5
- package/dist/chunk-TRM4JUZQ.js +104 -0
- package/dist/chunk-UB4B6OFY.js +370 -0
- package/dist/{chunk-TO7IKXYT.js → chunk-UCUBNWM2.js} +1 -1
- package/dist/chunk-VN44DYYT.cjs +2024 -0
- package/dist/chunk-Y6FXYEAI.mjs +10 -0
- package/dist/client-CZHU674n.d.ts +820 -0
- package/dist/core/index.cjs +198 -4
- package/dist/core/index.d.ts +311 -212
- package/dist/core/index.js +237 -43
- package/dist/core/index.mjs +237 -43
- package/dist/{effect-CMOQKX8y.d.ts → effect-DIUHZ9IN.d.ts} +195 -1
- package/dist/effectRunner-CFLC32IK.cjs +8 -0
- package/dist/effectRunner-L4S7IPT3.js +8 -0
- package/dist/effectRunner-NNGG75QA.mjs +8 -0
- package/dist/http/index.cjs +1227 -2971
- package/dist/http/index.d.ts +826 -280
- package/dist/http/index.js +1089 -2833
- package/dist/http/index.mjs +1089 -2833
- package/dist/http/testing.cjs +161 -0
- package/dist/http/testing.d.ts +43 -0
- package/dist/http/testing.js +161 -0
- package/dist/http/testing.mjs +161 -0
- package/dist/index.cjs +486 -250
- package/dist/index.d.ts +87 -95
- package/dist/index.js +391 -155
- package/dist/index.mjs +391 -155
- package/dist/observability/index.cjs +162 -0
- package/dist/observability/index.d.ts +152 -0
- package/dist/observability/index.js +162 -0
- package/dist/observability/index.mjs +162 -0
- 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 +29 -0
- package/dist/schema/index.d.ts +179 -0
- package/dist/schema/index.js +29 -0
- package/dist/schema/index.mjs +29 -0
- package/dist/server-GJPg8ZSG.d.ts +675 -0
- package/dist/{stream-FQm9h4Mg.d.ts → stream-B4oK9JFP.d.ts} +1 -1
- package/dist/tracer-Hwt1cl7h.d.ts +189 -0
- package/dist/tracing-DqbTKGcf.d.ts +148 -0
- 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 +48 -2
- package/dist/chunk-AR22SXML.js +0 -1043
- package/dist/chunk-BDYEENHT.js +0 -224
- package/dist/chunk-JFPU5GQI.mjs +0 -1043
- package/dist/chunk-MS34J5LY.cjs +0 -224
- package/dist/chunk-UMAZLXAB.mjs +0 -224
- package/dist/chunk-XPZNXSVN.cjs +0 -1043
- package/dist/tracing-DNT9jEbr.d.ts +0 -106
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { R as RuntimeHooks, b as RingBufferOptions, c as RuntimeEvent, a as RuntimeEmitContext, d as RuntimeEventRecord, e as RuntimeSpanLink, T as TraceContext, B as Baggage } from './effect-DIUHZ9IN.js';
|
|
2
|
+
import { R as RuntimeClock } from './schedule-CK3Ml_7p.js';
|
|
3
|
+
|
|
4
|
+
type MetricType = "counter" | "gauge" | "histogram";
|
|
5
|
+
type MetricValue = {
|
|
6
|
+
readonly name: string;
|
|
7
|
+
readonly type: MetricType;
|
|
8
|
+
readonly value: number;
|
|
9
|
+
readonly labels: Record<string, string>;
|
|
10
|
+
readonly timestamp: number;
|
|
11
|
+
};
|
|
12
|
+
type HistogramBuckets = {
|
|
13
|
+
readonly boundaries: readonly number[];
|
|
14
|
+
counts: number[];
|
|
15
|
+
sum: number;
|
|
16
|
+
count: number;
|
|
17
|
+
min: number;
|
|
18
|
+
max: number;
|
|
19
|
+
exemplars?: Array<MetricExemplar | undefined>;
|
|
20
|
+
};
|
|
21
|
+
type MetricExemplar = {
|
|
22
|
+
readonly value: number;
|
|
23
|
+
readonly timestamp: number;
|
|
24
|
+
readonly traceId?: string;
|
|
25
|
+
readonly spanId?: string;
|
|
26
|
+
readonly labels?: Record<string, string>;
|
|
27
|
+
};
|
|
28
|
+
type MetricsRegistry = {
|
|
29
|
+
/** Create or get a counter. */
|
|
30
|
+
readonly counter: (name: string, labels?: Record<string, string>) => Counter;
|
|
31
|
+
/** Create or get a gauge. */
|
|
32
|
+
readonly gauge: (name: string, labels?: Record<string, string>) => Gauge;
|
|
33
|
+
/** Create or get a histogram. */
|
|
34
|
+
readonly histogram: (name: string, boundaries?: number[], labels?: Record<string, string>) => Histogram;
|
|
35
|
+
/** Get all current metric values. */
|
|
36
|
+
readonly snapshot: () => MetricSnapshot;
|
|
37
|
+
/** Reset all metrics. */
|
|
38
|
+
readonly reset: () => void;
|
|
39
|
+
};
|
|
40
|
+
type Counter = {
|
|
41
|
+
readonly increment: (n?: number) => void;
|
|
42
|
+
readonly value: () => number;
|
|
43
|
+
};
|
|
44
|
+
type Gauge = {
|
|
45
|
+
readonly set: (value: number) => void;
|
|
46
|
+
readonly increment: (n?: number) => void;
|
|
47
|
+
readonly decrement: (n?: number) => void;
|
|
48
|
+
readonly value: () => number;
|
|
49
|
+
};
|
|
50
|
+
type Histogram = {
|
|
51
|
+
readonly observe: (value: number, exemplar?: Omit<MetricExemplar, "value"> | MetricExemplar) => void;
|
|
52
|
+
readonly buckets: () => HistogramBuckets;
|
|
53
|
+
readonly percentile: (p: number) => number;
|
|
54
|
+
};
|
|
55
|
+
type MetricSnapshot = {
|
|
56
|
+
readonly counters: Array<{
|
|
57
|
+
name: string;
|
|
58
|
+
labels: Record<string, string>;
|
|
59
|
+
value: number;
|
|
60
|
+
}>;
|
|
61
|
+
readonly gauges: Array<{
|
|
62
|
+
name: string;
|
|
63
|
+
labels: Record<string, string>;
|
|
64
|
+
value: number;
|
|
65
|
+
}>;
|
|
66
|
+
readonly histograms: Array<{
|
|
67
|
+
name: string;
|
|
68
|
+
labels: Record<string, string>;
|
|
69
|
+
buckets: HistogramBuckets;
|
|
70
|
+
}>;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Creates a metrics registry.
|
|
74
|
+
*
|
|
75
|
+
* ```ts
|
|
76
|
+
* const metrics = makeMetrics();
|
|
77
|
+
*
|
|
78
|
+
* const requestCount = metrics.counter("http_requests_total", { method: "GET" });
|
|
79
|
+
* requestCount.increment();
|
|
80
|
+
*
|
|
81
|
+
* const latency = metrics.histogram("http_request_duration_ms");
|
|
82
|
+
* latency.observe(42.5);
|
|
83
|
+
*
|
|
84
|
+
* const activeConns = metrics.gauge("active_connections");
|
|
85
|
+
* activeConns.set(10);
|
|
86
|
+
*
|
|
87
|
+
* console.log(metrics.snapshot());
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
declare function makeMetrics(): MetricsRegistry;
|
|
91
|
+
|
|
92
|
+
type EventHandler = (ev: RuntimeEventRecord) => void;
|
|
93
|
+
declare function runtimeHooksToEventHandler(hooks: RuntimeHooks): EventHandler;
|
|
94
|
+
type EventBusOptions = RingBufferOptions;
|
|
95
|
+
declare class EventBus implements RuntimeHooks {
|
|
96
|
+
private readonly options;
|
|
97
|
+
private seq;
|
|
98
|
+
private subs;
|
|
99
|
+
private flushScheduled;
|
|
100
|
+
private readonly boundFlush;
|
|
101
|
+
constructor(options?: EventBusOptions);
|
|
102
|
+
emit(ev: RuntimeEvent, ctx: RuntimeEmitContext): void;
|
|
103
|
+
subscribe(handler: EventHandler, perSubscriberCapacity?: number): () => void;
|
|
104
|
+
subscribeHooks(hooks: RuntimeHooks, perSubscriberCapacity?: number): () => void;
|
|
105
|
+
flush(budget?: number): void;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
type RuntimeSpanEvent = {
|
|
109
|
+
wallTs: number;
|
|
110
|
+
name: string;
|
|
111
|
+
attrs?: unknown;
|
|
112
|
+
};
|
|
113
|
+
type RuntimeSpan = {
|
|
114
|
+
traceId: string;
|
|
115
|
+
spanId: string;
|
|
116
|
+
parentSpanId?: string;
|
|
117
|
+
traceState?: string;
|
|
118
|
+
name: string;
|
|
119
|
+
startWallTs: number;
|
|
120
|
+
endWallTs?: number;
|
|
121
|
+
attrs: Record<string, unknown>;
|
|
122
|
+
links: RuntimeSpanLink[];
|
|
123
|
+
events: RuntimeSpanEvent[];
|
|
124
|
+
};
|
|
125
|
+
type InMemoryTracerOptions = {
|
|
126
|
+
readonly sanitizeAttributes?: (attrs: Record<string, unknown>) => Record<string, unknown>;
|
|
127
|
+
readonly sanitizeError?: (error: unknown) => unknown;
|
|
128
|
+
readonly maxFinishedSpans?: number;
|
|
129
|
+
readonly maxSpanAgeMs?: number;
|
|
130
|
+
readonly clock?: () => number;
|
|
131
|
+
};
|
|
132
|
+
type InMemoryTracerStats = {
|
|
133
|
+
readonly storedSpans: number;
|
|
134
|
+
readonly finishedSpans: number;
|
|
135
|
+
readonly prunedFinishedSpans: number;
|
|
136
|
+
};
|
|
137
|
+
declare class InMemoryTracer implements RuntimeHooks {
|
|
138
|
+
private readonly options;
|
|
139
|
+
spans: Map<string, RuntimeSpan>;
|
|
140
|
+
private readonly finishedSpanIds;
|
|
141
|
+
private readonly finishedSpanSet;
|
|
142
|
+
private finishedSpanOffset;
|
|
143
|
+
private finishedSpanCount;
|
|
144
|
+
private prunedFinishedSpans;
|
|
145
|
+
constructor(options?: InMemoryTracerOptions);
|
|
146
|
+
emit(ev: RuntimeEvent, ctx: RuntimeEmitContext): void;
|
|
147
|
+
exportFinished(): RuntimeSpan[];
|
|
148
|
+
pruneFinished(spanIds?: Iterable<string>): number;
|
|
149
|
+
stats(): InMemoryTracerStats;
|
|
150
|
+
private attrs;
|
|
151
|
+
private error;
|
|
152
|
+
private now;
|
|
153
|
+
private pruneExpiredFinished;
|
|
154
|
+
private pruneFinishedOverLimit;
|
|
155
|
+
private markFinished;
|
|
156
|
+
private deleteFinished;
|
|
157
|
+
private peekOldestFinished;
|
|
158
|
+
private deleteOldestFinished;
|
|
159
|
+
private compactFinishedIds;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
type TraceSamplingInput = {
|
|
163
|
+
readonly traceId: string;
|
|
164
|
+
readonly spanName?: string;
|
|
165
|
+
readonly parentSampled?: boolean;
|
|
166
|
+
readonly attributes?: Record<string, unknown>;
|
|
167
|
+
};
|
|
168
|
+
type TraceSampler = ((input: TraceSamplingInput) => boolean) | {
|
|
169
|
+
shouldSample(input: TraceSamplingInput): boolean;
|
|
170
|
+
};
|
|
171
|
+
interface Tracer {
|
|
172
|
+
newTraceId(): string;
|
|
173
|
+
newSpanId(): string;
|
|
174
|
+
}
|
|
175
|
+
declare const defaultTracer: Tracer;
|
|
176
|
+
type BrassEnv = {
|
|
177
|
+
brass?: {
|
|
178
|
+
tracer?: Tracer;
|
|
179
|
+
traceSeed?: TraceContext;
|
|
180
|
+
baggage?: Baggage;
|
|
181
|
+
sampler?: TraceSampler;
|
|
182
|
+
respectRemoteSampled?: boolean;
|
|
183
|
+
forceSampleOnError?: boolean;
|
|
184
|
+
childName?: (parentName?: string) => string | undefined;
|
|
185
|
+
clock?: RuntimeClock;
|
|
186
|
+
};
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
export { type BrassEnv as B, type Counter as C, EventBus as E, type Gauge as G, type Histogram as H, InMemoryTracer as I, type MetricsRegistry as M, type RuntimeSpan as R, type TraceSampler as T, type MetricExemplar as a, type MetricSnapshot as b, type TraceSamplingInput as c, type Tracer as d, type InMemoryTracerOptions as e, type EventBusOptions as f, type EventHandler as g, type HistogramBuckets as h, type InMemoryTracerStats as i, type MetricType as j, type MetricValue as k, type RuntimeSpanEvent as l, defaultTracer as m, makeMetrics as n, runtimeHooksToEventHandler as r };
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { A as Async, E as Exit } from './effect-DIUHZ9IN.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Acquires a resource, uses it, and guarantees release regardless of outcome.
|
|
5
|
+
*
|
|
6
|
+
* - `acquire` runs uninterruptibly (once started, it completes)
|
|
7
|
+
* - `use` runs with the acquired resource
|
|
8
|
+
* - `release` runs after `use` completes (success, failure, or interruption)
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* const result = bracket(
|
|
12
|
+
* openConnection(), // acquire
|
|
13
|
+
* (conn) => queryDatabase(conn), // use
|
|
14
|
+
* (conn, exit) => conn.close() // release (always runs)
|
|
15
|
+
* );
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
declare function bracket<R, E, A, B>(acquire: Async<R, E, A>, use: (resource: A) => Async<R, E, B>, release: (resource: A, exit: Exit<E, B>) => Async<R, any, void>): Async<R, E, B>;
|
|
19
|
+
/**
|
|
20
|
+
* Runs `effect` and then runs `finalizer` regardless of the outcome.
|
|
21
|
+
* The finalizer receives the exit value for inspection.
|
|
22
|
+
*
|
|
23
|
+
* ```ts
|
|
24
|
+
* const result = ensuring(
|
|
25
|
+
* doWork(),
|
|
26
|
+
* (exit) => logCompletion(exit)
|
|
27
|
+
* );
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
declare function ensuring<R, E, A>(effect: Async<R, E, A>, finalizer: (exit: Exit<E, A>) => Async<R, any, void>): Async<R, E, A>;
|
|
31
|
+
declare function resource<R, E, A>(acquire: Async<R, E, A>, release: (resource: A, exit: Exit<any, any>) => Async<R, any, void>): Resource<R, E, A>;
|
|
32
|
+
declare const makeResource: typeof resource;
|
|
33
|
+
declare function resourceSucceed<A>(value: A): Resource<unknown, never, A>;
|
|
34
|
+
declare function resourceFromManaged<R, E, A>(m: Managed<R, E, A>): Resource<R, E, A>;
|
|
35
|
+
declare function useResource<R, E, A, R2, E2, B>(res: Resource<R, E, A>, body: (resource: A) => Async<R2, E2, B>): Async<R & R2, E | E2, B>;
|
|
36
|
+
declare function resourceAll<R, E, Resources extends readonly any[]>(resources: {
|
|
37
|
+
[K in keyof Resources]: Resource<R, E, Resources[K]>;
|
|
38
|
+
}): Resource<R, E, Resources>;
|
|
39
|
+
/**
|
|
40
|
+
* A Resource describes a scoped value. It is acquired for each `use`, released
|
|
41
|
+
* in LIFO order, and can be composed with `map`, `flatMap`, and `zip`.
|
|
42
|
+
*/
|
|
43
|
+
type Resource<R, E, A> = {
|
|
44
|
+
readonly _tag: "Resource";
|
|
45
|
+
readonly use: <R2, E2, B>(body: (resource: A) => Async<R2, E2, B>) => Async<R & R2, E | E2, B>;
|
|
46
|
+
readonly map: <B>(f: (resource: A) => B) => Resource<R, E, B>;
|
|
47
|
+
readonly flatMap: <R2, E2, B>(f: (resource: A) => Resource<R2, E2, B>) => Resource<R & R2, E | E2, B>;
|
|
48
|
+
readonly zip: <R2, E2, B>(that: Resource<R2, E2, B>) => Resource<R & R2, E | E2, [A, B]>;
|
|
49
|
+
};
|
|
50
|
+
declare const Resource: Readonly<{
|
|
51
|
+
make: typeof resource;
|
|
52
|
+
succeed: typeof resourceSucceed;
|
|
53
|
+
fromManaged: typeof resourceFromManaged;
|
|
54
|
+
all: typeof resourceAll;
|
|
55
|
+
use: typeof useResource;
|
|
56
|
+
}>;
|
|
57
|
+
/**
|
|
58
|
+
* A Managed resource describes how to acquire and release a resource.
|
|
59
|
+
* It can be used multiple times — each `use` call acquires a fresh instance.
|
|
60
|
+
*
|
|
61
|
+
* ```ts
|
|
62
|
+
* const dbPool = managed(
|
|
63
|
+
* createPool({ max: 10 }),
|
|
64
|
+
* (pool) => pool.close()
|
|
65
|
+
* );
|
|
66
|
+
*
|
|
67
|
+
* // Use it:
|
|
68
|
+
* const result = useManaged(dbPool, (pool) => pool.query("SELECT 1"));
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
type Managed<R, E, A> = {
|
|
72
|
+
readonly _tag: "Managed";
|
|
73
|
+
readonly acquire: Async<R, E, A>;
|
|
74
|
+
readonly release: (resource: A, exit: Exit<any, any>) => Async<R, any, void>;
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Creates a Managed resource descriptor.
|
|
78
|
+
*/
|
|
79
|
+
declare function managed<R, E, A>(acquire: Async<R, E, A>, release: (resource: A, exit?: Exit<any, any>) => Async<R, any, void>): Managed<R, E, A>;
|
|
80
|
+
/**
|
|
81
|
+
* Uses a Managed resource: acquires, runs the body, and releases.
|
|
82
|
+
*/
|
|
83
|
+
declare function useManaged<R, E, A, B>(m: Managed<R, E, A>, body: (resource: A) => Async<R, E, B>): Async<R, E, B>;
|
|
84
|
+
/**
|
|
85
|
+
* Combines multiple Managed resources. All are acquired in order,
|
|
86
|
+
* and released in reverse order (LIFO).
|
|
87
|
+
*
|
|
88
|
+
* ```ts
|
|
89
|
+
* const resources = managedAll([dbPool, cacheConn, fileHandle]);
|
|
90
|
+
* const result = useManaged(resources, ([db, cache, file]) => ...);
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
declare function managedAll<R, E, Resources extends readonly any[]>(manageds: {
|
|
94
|
+
[K in keyof Resources]: Managed<R, E, Resources[K]>;
|
|
95
|
+
}): Managed<R, E, Resources>;
|
|
96
|
+
|
|
97
|
+
type SpanContext = {
|
|
98
|
+
readonly traceId: string;
|
|
99
|
+
readonly spanId: string;
|
|
100
|
+
readonly parentSpanId?: string;
|
|
101
|
+
};
|
|
102
|
+
type SpanStatus = "ok" | "error" | "unset";
|
|
103
|
+
type Span = {
|
|
104
|
+
readonly name: string;
|
|
105
|
+
readonly context: SpanContext;
|
|
106
|
+
readonly startTime: number;
|
|
107
|
+
endTime?: number;
|
|
108
|
+
status: SpanStatus;
|
|
109
|
+
readonly attributes: Record<string, string | number | boolean>;
|
|
110
|
+
readonly events: SpanEvent[];
|
|
111
|
+
};
|
|
112
|
+
type SpanEvent = {
|
|
113
|
+
readonly name: string;
|
|
114
|
+
readonly time: number;
|
|
115
|
+
readonly attributes?: Record<string, string | number | boolean>;
|
|
116
|
+
};
|
|
117
|
+
type TracerConfig = {
|
|
118
|
+
/** Service name for span metadata. */
|
|
119
|
+
readonly serviceName: string;
|
|
120
|
+
/** Called when a span ends (for export). */
|
|
121
|
+
readonly onSpanEnd?: (span: Span) => void;
|
|
122
|
+
/** Sampling rate (0.0 to 1.0). Default: 1.0 (sample everything). */
|
|
123
|
+
readonly sampleRate?: number;
|
|
124
|
+
};
|
|
125
|
+
type Tracer = {
|
|
126
|
+
/** Wrap an effect in a span. */
|
|
127
|
+
readonly span: <R, E, A>(name: string, effect: Async<R, E, A>, attributes?: Record<string, string | number | boolean>) => Async<R, E, A>;
|
|
128
|
+
/** Get all completed spans (for testing). */
|
|
129
|
+
readonly spans: () => readonly Span[];
|
|
130
|
+
/** Clear collected spans. */
|
|
131
|
+
readonly clear: () => void;
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* Creates a tracer that wraps effects in spans.
|
|
135
|
+
*
|
|
136
|
+
* ```ts
|
|
137
|
+
* const tracer = makeTracer({ serviceName: "my-app" });
|
|
138
|
+
*
|
|
139
|
+
* const result = await run(
|
|
140
|
+
* tracer.span("fetchUser", fetchUser(id), { userId: id })
|
|
141
|
+
* );
|
|
142
|
+
*
|
|
143
|
+
* console.log(tracer.spans()); // all completed spans
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
declare function makeTracer(config: TracerConfig): Tracer;
|
|
147
|
+
|
|
148
|
+
export { type Managed as M, Resource as R, type Span as S, type Tracer as T, type SpanContext as a, type SpanEvent as b, type SpanStatus as c, type TracerConfig as d, bracket as e, ensuring as f, makeTracer as g, managed as h, managedAll as i, resourceAll as j, resourceFromManaged as k, resourceSucceed as l, makeResource as m, useResource as n, resource as r, useManaged as u };
|
|
@@ -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)
|