@arnilo/prism 0.1.3 → 0.1.4

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/dist/contracts.js CHANGED
@@ -1,195 +1,10 @@
1
1
  /**
2
- * Thrown by a delegated-run host (e.g. the supervisor) when a nested run suspends on
3
- * pending decisions inside a tool execution. Core converts it into a root suspension
4
- * with attributed, root-visible approval ids; the dispatching wrapper attaches `toolCall`.
2
+ * Contracts barrel (0.1.4 god-module split): re-exports the full public
3
+ * contracts surface from the three concern-split modules
4
+ * (contracts-core / contracts-run-state / contracts-protocol) so the
5
+ * import surface of `./contracts.js` is unchanged.
5
6
  */
6
- export class AgentDelegationSuspendedError extends Error {
7
- ref;
8
- pendingDecisions;
9
- path;
10
- code = "ERR_PRISM_DELEGATION_SUSPENDED";
11
- toolCall;
12
- constructor(ref, pendingDecisions,
13
- /** Redacted delegation path (child ids) used when decisions carry no attribution. */
14
- path) {
15
- super("Delegated run suspended");
16
- this.ref = ref;
17
- this.pendingDecisions = pendingDecisions;
18
- this.path = path;
19
- this.name = "AgentDelegationSuspendedError";
20
- }
21
- }
22
- /** Shared decision-contract violations. Unknown and foreign approval ids share one non-enumerating error. */
23
- export class AgentDecisionError extends Error {
24
- code;
25
- constructor(code, message, options) {
26
- super(message, options);
27
- this.code = code;
28
- this.name = "AgentDecisionError";
29
- }
30
- }
31
- export const DEFAULT_MAX_PENDING_DECISIONS = 32;
32
- export const HARD_MAX_PENDING_DECISIONS = 128;
33
- export const DEFAULT_MAX_STICKY_DECISIONS = 64;
34
- export const HARD_MAX_STICKY_DECISIONS = 256;
35
- export const MAX_DECISION_REASON_BYTES = 2 * 1024;
36
- export const HARD_MAX_DECISION_REASON_BYTES = 8 * 1024;
37
- export const MAX_ELICITATION_BYTES = 16 * 1024;
38
- export const HARD_MAX_ELICITATION_BYTES = 64 * 1024;
39
- export const MAX_ACTION_CONSTRAINTS = 32;
40
- export const HARD_MAX_ACTION_CONSTRAINTS = 64;
41
- /** Maximum delegation attribution depth for surfaced nested pending decisions. */
42
- export const MAX_ATTRIBUTION_DEPTH = 8;
43
- export const MAX_ACTION_CONSTRAINT_BYTES = 4 * 1024;
44
- export const HARD_MAX_ACTION_CONSTRAINT_BYTES = 16 * 1024;
45
- export class AgentRunStateError extends Error {
46
- code = "ERR_PRISM_AGENT_RUN_STATE";
47
- constructor(message) {
48
- super(message);
49
- this.name = "AgentRunStateError";
50
- }
51
- }
52
- /** Durable-loop contract violations: hook-less custom strategy on a durable run, invalid snapshot, or revision drift. */
53
- export class AgentLoopStateError extends Error {
54
- code;
55
- constructor(code, message, options) {
56
- super(message, options);
57
- this.code = code;
58
- this.name = "AgentLoopStateError";
59
- }
60
- }
61
- export class AgentRunError extends Error {
62
- result;
63
- constructor(result, options) {
64
- super(result.error?.message ?? (result.status === "aborted" ? "Agent run aborted" : "Agent run failed"), options);
65
- this.name = "AgentRunError";
66
- this.result = result;
67
- }
68
- }
69
- /** Mid-run steer queue: default pending message count (fail closed at this cap). */
70
- export const DEFAULT_MAX_PENDING_STEERS = 8;
71
- /** Absolute pending steer count ceiling if hosts later expose overrides. */
72
- export const HARD_MAX_PENDING_STEERS = 32;
73
- /** Mid-run steer queue: default total UTF-8 byte budget across pending messages. */
74
- export const DEFAULT_MAX_PENDING_STEER_BYTES = 64 * 1024;
75
- /** Absolute pending steer byte ceiling if hosts later expose overrides. */
76
- export const HARD_MAX_PENDING_STEER_BYTES = 256 * 1024;
77
- export const SESSION_ENTRY_KINDS = [
78
- "message",
79
- "event",
80
- "summary",
81
- "metadata",
82
- "model_change",
83
- "label",
84
- "custom",
85
- "compaction",
86
- ];
87
- const SESSION_ENTRY_KIND_SET = new Set(SESSION_ENTRY_KINDS);
88
- export const SESSION_ENTRY_SCHEMA_VERSION = 1;
89
- export function isSessionEntryKind(value) {
90
- return typeof value === "string" && SESSION_ENTRY_KIND_SET.has(value);
91
- }
92
- /** Host-written `SessionRecord.metadata` / session metadata key for workspace filtering. */
93
- export const SESSION_SEARCH_WORKSPACE_METADATA_KEY = "workspaceRoot";
94
- export const DEFAULT_SESSION_SEARCH_LIMIT = 20;
95
- export const HARD_MAX_SESSION_SEARCH_LIMIT = 100;
96
- export const DEFAULT_MAX_SESSION_SEARCH_QUERY_BYTES = 4 * 1024;
97
- export const HARD_MAX_SESSION_SEARCH_QUERY_BYTES = 16 * 1024;
98
- export const DEFAULT_MAX_SESSION_SEARCH_SNIPPET_BYTES = 512;
99
- export const HARD_MAX_SESSION_SEARCH_SNIPPET_BYTES = 4 * 1024;
100
- export const DEFAULT_MAX_SESSION_SEARCH_CURSOR_BYTES = 1 * 1024;
101
- export const HARD_MAX_SESSION_SEARCH_CURSOR_BYTES = 4 * 1024;
102
- export const DEFAULT_MAX_SESSION_SEARCH_LINEAR_SESSIONS = 1_000;
103
- export const HARD_MAX_SESSION_SEARCH_LINEAR_SESSIONS = 5_000;
104
- export const DEFAULT_MAX_SESSION_SEARCH_LINEAR_ENTRIES = 10_000;
105
- export const HARD_MAX_SESSION_SEARCH_LINEAR_ENTRIES = 50_000;
106
- export const DEFAULT_MAX_SESSION_SEARCH_LINEAR_BYTES = 8 * 1024 * 1024;
107
- export const HARD_MAX_SESSION_SEARCH_LINEAR_BYTES = 64 * 1024 * 1024;
108
- export const DEFAULT_MAX_SESSION_SEARCH_FTS_CANDIDATES = 1_000;
109
- export const HARD_MAX_SESSION_SEARCH_FTS_CANDIDATES = 5_000;
110
- /**
111
- * O(1) validation before any scan/query. Applies default page limit; rejects NaN,
112
- * non-positive limits, oversize query/cursor/filter strings, and invalid order.
113
- */
114
- export function resolveSessionSearchQuery(query) {
115
- const limit = query.limit === undefined ? DEFAULT_SESSION_SEARCH_LIMIT : query.limit;
116
- if (!Number.isSafeInteger(limit) || limit < 1 || limit > HARD_MAX_SESSION_SEARCH_LIMIT) {
117
- throw new TypeError(`SessionSearchQuery.limit must be a safe integer from 1 to ${HARD_MAX_SESSION_SEARCH_LIMIT}`);
118
- }
119
- const order = query.order ?? "desc";
120
- if (order !== "asc" && order !== "desc") {
121
- throw new TypeError('SessionSearchQuery.order must be "asc" or "desc"');
122
- }
123
- assertSearchStringBytes(query.query, "query", HARD_MAX_SESSION_SEARCH_QUERY_BYTES);
124
- assertSearchStringBytes(query.cursor, "cursor", HARD_MAX_SESSION_SEARCH_CURSOR_BYTES);
125
- assertSearchStringBytes(query.workspaceRoot, "workspaceRoot", HARD_MAX_SESSION_SEARCH_QUERY_BYTES);
126
- assertSearchStringBytes(query.provider, "provider", HARD_MAX_SESSION_SEARCH_QUERY_BYTES);
127
- assertSearchStringBytes(query.model, "model", HARD_MAX_SESSION_SEARCH_QUERY_BYTES);
128
- assertSearchStringBytes(query.label, "label", HARD_MAX_SESSION_SEARCH_QUERY_BYTES);
129
- assertSearchStringBytes(query.summary, "summary", HARD_MAX_SESSION_SEARCH_QUERY_BYTES);
130
- assertSearchStringBytes(query.tenantId, "tenantId", HARD_MAX_SESSION_SEARCH_QUERY_BYTES);
131
- assertSearchStringBytes(query.accountId, "accountId", HARD_MAX_SESSION_SEARCH_QUERY_BYTES);
132
- assertSearchStringBytes(query.userId, "userId", HARD_MAX_SESSION_SEARCH_QUERY_BYTES);
133
- assertSearchStringBytes(query.fromUpdatedAt, "fromUpdatedAt", HARD_MAX_SESSION_SEARCH_QUERY_BYTES);
134
- assertSearchStringBytes(query.toUpdatedAt, "toUpdatedAt", HARD_MAX_SESSION_SEARCH_QUERY_BYTES);
135
- return { ...query, limit, order };
136
- }
137
- function assertSearchStringBytes(value, name, hardMax) {
138
- if (value === undefined)
139
- return;
140
- if (typeof value !== "string") {
141
- throw new TypeError(`SessionSearchQuery.${name} must be a string`);
142
- }
143
- // ponytail: UTF-8 byte length via TextEncoder; upgrade only if a non-Unicode host appears.
144
- const bytes = new TextEncoder().encode(value).byteLength;
145
- if (bytes > hardMax) {
146
- throw new TypeError(`SessionSearchQuery.${name} exceeds ${hardMax} bytes`);
147
- }
148
- }
149
- export const SESSION_SEARCH_UNSUPPORTED_CODE = "session_search_unsupported";
150
- /** Thrown when a store opts out of `searchSessions` (memory `unsupported`, JSONL). */
151
- export class SessionSearchUnsupportedError extends Error {
152
- code = SESSION_SEARCH_UNSUPPORTED_CODE;
153
- constructor(message = "session search is unsupported by this store") {
154
- super(message);
155
- this.name = "SessionSearchUnsupportedError";
156
- }
157
- }
158
- export function isSessionSearchUnsupported(error) {
159
- return error instanceof Error && error.code === SESSION_SEARCH_UNSUPPORTED_CODE;
160
- }
161
- /** Stable error code carried by `SessionAppendConflictError`. */
162
- export const SESSION_APPEND_CONFLICT_CODE = "session_append_conflict";
163
- /**
164
- * Thrown when `SessionStore.append` rejects an entry under `SessionAppendOptions`
165
- * (dangling/stale `expectedParentId`, stricter adapter CAS failure, or duplicate
166
- * idempotency key for the same parent). Recognize via the stable `code` and
167
- * `isSessionAppendConflict`, not message text.
168
- */
169
- export class SessionAppendConflictError extends Error {
170
- conflict;
171
- code = SESSION_APPEND_CONFLICT_CODE;
172
- constructor(conflict) {
173
- const detail = conflict.idempotencyDuplicate
174
- ? `idempotency key already used`
175
- : conflict.currentLeafId !== undefined
176
- ? `expected parent ${conflict.expectedParentId ?? "<none>"} does not match current leaf ${conflict.currentLeafId}`
177
- : `expected parent ${conflict.expectedParentId ?? "<none>"} is unavailable`;
178
- super(`session append conflict: ${detail}`);
179
- this.conflict = conflict;
180
- this.name = "SessionAppendConflictError";
181
- }
182
- }
183
- /** Type guard keyed off the stable `code` (works across bundles; not message text). */
184
- export function isSessionAppendConflict(error) {
185
- return error instanceof Error && error.code === SESSION_APPEND_CONFLICT_CODE;
186
- }
187
- const SESSION_METADATA_KEY_PATTERN = /^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$/;
188
- /** Validate a top-level `SessionRecord.metadata` key used by `SessionQuery.metadataKey` filters. */
189
- export function assertSessionMetadataKey(key) {
190
- if (typeof key !== "string" || !SESSION_METADATA_KEY_PATTERN.test(key)) {
191
- throw new RangeError("metadataKey must match /^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$/");
192
- }
193
- return key;
194
- }
7
+ export * from "./contracts-core.js";
8
+ export * from "./contracts-run-state.js";
9
+ export * from "./contracts-protocol.js";
195
10
  //# sourceMappingURL=contracts.js.map
package/dist/index.d.ts CHANGED
@@ -105,5 +105,5 @@ export { createToolParameterValidator, createToolRegistry, dispatchToolCall, fil
105
105
  export type { ResolvedUseCaseModel, ResolveUseCaseModelInput, UseCaseModelBinding, } from "./use-case-model.js";
106
106
  export { resolveUseCaseModel, resolveUseCaseModelBinding, useCaseCredentialProviderId, } from "./use-case-model.js";
107
107
  export declare const name = "prism";
108
- export declare const version = "0.1.3";
108
+ export declare const version = "0.1.4";
109
109
  export declare const description = "Agent harness for AI providers, agents, sessions, and tools.";
package/dist/index.js CHANGED
@@ -57,6 +57,6 @@ export { DEFAULT_TOOL_RESULT_FOLD_MAX_SUMMARY_BYTES, DEFAULT_TOOL_RESULT_FOLD_MI
57
57
  export { createToolParameterValidator, createToolRegistry, dispatchToolCall, filterTools } from "./tools.js";
58
58
  export { resolveUseCaseModel, resolveUseCaseModelBinding, useCaseCredentialProviderId, } from "./use-case-model.js";
59
59
  export const name = "prism";
60
- export const version = "0.1.3";
60
+ export const version = "0.1.4";
61
61
  export const description = "Agent harness for AI providers, agents, sessions, and tools.";
62
62
  //# sourceMappingURL=index.js.map
@@ -133,6 +133,8 @@ const clone = await session.clone({ id: "s2" });
133
133
 
134
134
  ## Extension and configuration notes
135
135
 
136
+ **Internal file structure (0.1.4).** Since 0.1.4 the runtime is spread across sibling modules behind the `src/agents.ts` barrel: `src/agent-session.ts` (the `RuntimeAgentSession` class, session factories, and shared session helpers), `src/agent-run-lifecycle.ts` (resume lifecycle: `resumeAgentRun`/`resumeAgentRunStream`), `src/agent-approval.ts` (pending-decision and approval helpers), `src/agent-tool-dispatch.ts` (elicitation and tool-policy helpers), `src/agent-run-state.ts` (run-state persistence + agent fingerprint), and `src/agent-loops.ts`/`src/compaction.ts`. The public import surface is unchanged — `createAgent`/`createAgentSession`/`resumeAgentRun`/`resumeAgentRunStream` still resolve from the package entry.
137
+
136
138
  The runtime calls `assembleProviderInput()` on every turn and uses only runtime-consumed values supplied on `AgentConfig`: `instructions`, `systemPrompt`, `inputBuilder`, `promptBuilder`, `inputLayout`, `context`, selected `skills`, active `tools`, `middleware`, `resourceLoader`, metadata, `compaction`, `retry`, and `RunOptions.model`/`systemPrompt`/`inputLayout`/`compaction`/`retry`. Contributions remain inert until a host passes selected values into the agent config.
137
139
 
138
140
  `AgentConfig` no longer accepts inert `extensions`, `settings`, or `credentials` fields. Load extensions with `createExtensionKernel()` before building config; read settings in the host before passing concrete runtime options; resolve credentials at the provider edge and pass exact secret values to redaction when needed.
@@ -2,11 +2,11 @@
2
2
 
3
3
  ## What it does
4
4
 
5
- `@arnilo/prism-browser` exposes exactly four exclusive model-facing tools—`browser_open`, `browser_snapshot`, `browser_act`, and `browser_close`—over a host-supplied Playwright `Browser`. Prism creates one non-persistent `BrowserContext` per run, serializes actions, returns bounded AI-mode accessibility snapshots with snapshot-scoped refs, enforces egress/side-effect/upload/download/screenshot policy, and closes context/pages/listeners/quarantined downloads on close, abort, or manager disposal.
5
+ `@arnilo/prism-browser` exposes six exclusive model-facing tools—`browser_open`, `browser_snapshot`, `browser_act`, `browser_close`, `browser_evaluate`, and `browser_observe`—over a host-supplied Playwright `Browser`. Prism creates one non-persistent `BrowserContext` per run, serializes actions, returns bounded AI-mode accessibility snapshots with snapshot-scoped refs, enforces egress/side-effect/upload/download/screenshot policy, and closes context/pages/listeners/quarantined downloads on close, abort, or manager disposal. Since 0.1.4 the package also rides playwright-core's existing CDP transport for bounded page evaluation, console/network observation, and network/emulation control on Chromium hosts — zero new dependencies, Prism still never launches or downloads browsers.
6
6
 
7
7
  ## When to use it
8
8
 
9
- Use when an agent must interact with JavaScript-heavy or authenticated pages that search/fetch cannot cover. Prefer `@arnilo/prism-web-tools` for ordinary public retrieval. Do not use this package as a browser launcher, MCP proxy, visual planner, CDP console, or persistent profile manager.
9
+ Use when an agent must interact with JavaScript-heavy or authenticated pages that search/fetch cannot cover, or needs bounded page-context evaluation and console/network observation on Chromium. Prefer `@arnilo/prism-web-tools` for ordinary public retrieval. Do not use this package as a browser launcher, MCP proxy, visual planner, general-purpose CDP console (domains are allowlisted), or persistent profile manager.
10
10
 
11
11
  ## Inputs / request
12
12
 
@@ -14,14 +14,16 @@ Use when an agent must interact with JavaScript-heavy or authenticated pages tha
14
14
  | --- | --- | --- |
15
15
  | `browser_open` | optional absolute `http(s)` `url` | host Playwright `Browser` or `BrowserManager`, limits, `ExecutionPolicy`, `networkPolicy`, uploads/downloads |
16
16
  | `browser_snapshot` | optional `pageId` | same manager/context |
17
- | `browser_act` | `action` plus action-specific fields (`target`, `snapshotId`, `url`, `text`, `values`, `paths`, `downloadId`, `dialogResponse`, `pageId`, `clip`, …) | policy checked before side effects |
17
+ | `browser_act` | `action` plus action-specific fields (`target`, `snapshotId`, `url`, `text`, `values`, `paths`, `downloadId`, `dialogResponse`, `pageId`, `clip`, `patterns`, `offline`, `latencyMs`, `downloadKbps`, `uploadKbps`, `reset`, `width`, `height`, `mobile`, `deviceScaleFactor`, `userAgent`, …) | policy checked before side effects |
18
+ | `browser_evaluate` | optional `pageId`, required `expression`, optional `awaitPromise`/`timeoutMs` | CDP `Runtime.evaluate` on a per-page session (Chromium hosts) |
19
+ | `browser_observe` | optional `pageId` | CDP Runtime/Network ring, drain-on-read |
18
20
  | `browser_close` | none | closes only the run-owned context, never the host Browser process |
19
21
 
20
- `createBrowserTools({ browser, executionPolicy?, limits?, networkPolicy?, uploads?, downloads?, beforeSideEffect? })` builds the four tools. `createBrowserManager(...)` exposes host lifecycle helpers `closeRun(runId)` / `close()` and `listDownloads(runId)`.
22
+ `createBrowserTools({ browser, executionPolicy?, limits?, networkPolicy?, uploads?, downloads?, beforeSideEffect?, cdp? })` builds the six tools. `createBrowserManager(...)` exposes host lifecycle helpers `closeRun(runId)` / `close()` and `listDownloads(runId)`.
21
23
 
22
- Targets accepted by `browser_act`: snapshot `ref`, `role`(+`name`), `label`, `testId`, or `text`. CSS, XPath, selector strings, `page.evaluate`, CDP/devtools, extensions, and persistent/local profiles are unsupported.
24
+ Targets accepted by `browser_act`: snapshot `ref`, `role`(+`name`), `label`, `testId`, `text`, and (0.1.4) raw `{ css }` / `{ xpath }`. `selector` strings and `evaluate` target keys stay denied; page-context JS goes through the policy-gated `browser_evaluate`. Extensions and persistent/local profiles are unsupported.
23
25
 
24
- `browser_act` actions: `navigate`, `click`, `type`, `fill`, `select`, `check`, `uncheck`, `scroll`, `wait`, `dialog`, `select_page`, `upload`, `screenshot`, `download_release`.
26
+ `browser_act` actions: `navigate`, `click`, `type`, `fill`, `select`, `check`, `uncheck`, `scroll`, `wait`, `dialog`, `select_page`, `upload`, `screenshot`, `download_release`, and (0.1.4, CDP) `block_urls`, `unblock_urls`, `throttle`, `emulate`.
25
27
 
26
28
  ## Outputs / response / events
27
29
 
@@ -105,16 +107,18 @@ await browser.close();
105
107
  - Uploads require absolute paths under `uploads.roots` (realpath-contained; symlink escapes rejected). Downloads stream into `downloads.quarantine` with SHA-256/MIME/name metadata; `download_release` requires host `approveRelease`. Screenshots return bounded `ImageContent`.
106
108
  - Observation (`snapshot`, `wait`, open-without-url, `close`) vs mutation/high-impact (`navigate`, click/form, dialog accept, upload, download release, popup select) is classified for `ExecutionPolicy` / `beforeSideEffect`.
107
109
  - `createSharedSandboxBrowserOptions()` aligns browser uploads/downloads with Task 1 sandbox `/workspace` and `/downloads`. `assertBrowserSandboxNetwork()` in `@arnilo/prism-coding-security` fails closed for custom Docker networks without browser egress attestation.
108
- - Raw CSS is absent from production defaults. Ref resolution uses Playwright’s built-in `aria-ref=` selector with a package-owned snapshot ref table for staleness checks.
110
+ - Raw CSS/XPath: since 0.1.4 `{ css }` / `{ xpath }` targets resolve via Playwright's selector engine (`locator(css)` / `locator("xpath=…")`); ref resolution keeps the built-in `aria-ref=` selector with a package-owned snapshot ref table for staleness checks.
111
+ - CDP capabilities (0.1.4): `browser_evaluate` (bounded `Runtime.evaluate`), `browser_observe` (Runtime console/exception + Network request/response/failed events in a bounded ring with drain-on-read), and `block_urls`/`unblock_urls` (`Network.setBlockedURLs`), `throttle` (`Network.emulateNetworkConditions`), `emulate` (`Emulation.setDeviceMetricsOverride` + optional `setUserAgentOverride`). All CDP sessions are per-page via `context.newCDPSession(page)` and are detached on run close — network/emulation changes are run-scoped and reset with `browser_close`. `BrowserCdpOptions.mode` (`auto` | `on` | `off`, default `auto`) gates the surface: non-Chromium hosts or mode `off` return `ERR_PRISM_BROWSER_CDP_UNAVAILABLE` without affecting Playwright-only tools. Domains are limited to the Runtime/Network/Emulation allowlist — cookies, tracing, performance profiles, IndexedDB, and worker debugging are not exposed. CDP is not an egress bypass: page network still routes through the run's routing/blocking and `networkPolicy`.
112
+ - CDP bounds (0.1.4): evaluate expression ≤ `maxActionInputBytes` (64 KiB default / 256 KiB hard) and result capped at `maxEvaluateResultBytes` (64 KiB / 256 KiB) with truncation marking; `browser_observe` rings capped at `maxConsoleEntries` (200/500) and `maxNetworkRequests`; `block_urls` patterns ≤ `maxBlockedUrlPatterns` (32/128); throttle latency ≤ 120 s and throughput ≤ 1 Gbps; emulate dimensions ≤ 16 384 and scale ≤ 10, user agent ≤ 2 KiB. Evaluate is classified high-impact (arbitrary page-context code execution): `ExecutionPolicy` approval and the `beforeSideEffect` hook are mandatory, it charges the action budget, and results are marked `untrusted_external`. `browser_observe` is observation-only (no side-effect hook, no action charge) and **never captures request/response bodies, cookies, or auth headers** — only bounded URL/method/status/error-text/arg previews.
109
113
  - Verified-state checkpoints (0.0.14): `createBrowserCheckpointLedger()` records navigation state — URL, a domain-state hash, and host-owned data refs — never serialized browser internals (cookies/storage/contexts), which are fragile and secret-bearing. Frozen caps: URL 8 KiB/16 KiB, domain-state hash 256 B/1 KiB, host-data ref 2 KiB/8 KiB (refs only, never bodies), 16/64 checkpoints per run (oldest evicted). After any resume/interruption `markResumed(runId)` marks state stale; `assertVerifiedBeforeSideEffect(runId)` fails closed until the host reloads + `verify()`s, so side effects never replay on stale state. Checkpoints are run-scoped: a conversation thread composes through the run it owns, reusing the manager's sandbox/egress/approval/limit policy above.
110
114
 
111
115
  Observation tools declare `kind: none`; mutations are `external_mutation`/`unsupported` and fail closed on stale checkpoint state. See [tool effects](tool-effects.md).
112
116
 
113
117
  ## Security and performance notes
114
118
 
115
- Import is inert. Construction fails clearly when neither `browser` nor `manager` is supplied. Browser installation, launch, version, and control endpoint are host-owned. Prism never exposes `page.evaluate`, init scripts, CDP, extensions, persistent profiles, or model-supplied Playwright launch options. Secrets and storage state must not appear in snapshots, tool results, logs, or checkpoints. Finite caps charge before context/page/action/queue/snapshot/network/artifact retention; snapshots retain no unbounded DOM, console, request, response, or trace history. Unreleased downloads are deleted on context close.
119
+ Import is inert. Construction fails clearly when neither `browser` nor `manager` is supplied. Browser installation, launch, version, and control endpoint are host-owned. Prism never exposes init scripts, extensions, persistent profiles, or model-supplied Playwright launch options; CDP exposure is limited to the allowlisted Runtime/Network/Emulation surface above (evaluate is policy-gated arbitrary code execution — treat results as untrusted). Secrets and storage state must not appear in snapshots, tool results, logs, or checkpoints. Finite caps charge before context/page/action/queue/snapshot/network/artifact retention; snapshots retain no unbounded DOM, console, request, response, or trace history. Unreleased downloads are deleted on context close.
116
120
 
117
- Default tests use fake Playwright APIs only. Protected live gate: `PRISM_LIVE_PLAYWRIGHT=1` (or `PRISM_TEST_PLAYWRIGHT=1`) `npm run test:live -w @arnilo/prism-browser` exercises a local loopback hostile HTML fixture for snapshot refs, stale-ref rejection, CSS denial, private/file deny, upload containment, screenshot bounds, and download quarantine/release. Missing browser binaries fail closed when the gate is enabled. Adversarial network-free fixtures live in `eval-fixtures.test.ts`; see [Evaluations](evaluations.md) and `examples/coding-browser-evaluation.ts`.
121
+ Default tests use fake Playwright APIs only. Protected live gate: `PRISM_LIVE_PLAYWRIGHT=1` (or `PRISM_TEST_PLAYWRIGHT=1`) `npm run test:live -w @arnilo/prism-browser` exercises a local loopback hostile HTML fixture for snapshot refs, stale-ref rejection, css/xpath targets, private/file deny, upload containment, screenshot bounds, download quarantine/release, and the CDP leg (real evaluate, observe, and emulate). Missing browser binaries fail closed when the gate is enabled. Adversarial network-free fixtures live in `eval-fixtures.test.ts`; see [Evaluations](evaluations.md) and `examples/coding-browser-evaluation.ts`.
118
122
 
119
123
  ## Related APIs
120
124
 
package/docs/index.md CHANGED
@@ -72,7 +72,7 @@ Prism is a TypeScript/Node.js agent harness. Host apps and extension packages ow
72
72
  - [Web search, fetch, and extraction](web-tools.md): optional host-selected Brave/Exa discovery and Firecrawl Markdown/schema tools with native fetch, stable citations, late credentials, finite limits, and explicit untrusted-content boundaries.
73
73
  - [Work tools](work-tools.md): optional `@arnilo/prism-work-tools` identity-scoped M365 + GWS connectors (hard-coded CLI argv, draft-then-approve, state-machine idempotency, shared result shapes); 0.0.14 adds a late-bound per-identity `tokenProvider` (env-only, fail-closed).
74
74
  - [Work connectors](work-connectors.md): connector principles, capability gates, scoped OAuth establishment (0.0.14), and out-of-scope boundaries (Slack/Teams channels not shipped) for Microsoft 365 / Google Workspace.
75
- - [Browser automation](browser-automation.md): optional `@arnilo/prism-browser` with host-supplied Playwright contexts, AI-mode snapshots/refs, ordered `browser_open`/`browser_snapshot`/`browser_act`/`browser_close`, egress/side-effect/upload/download/screenshot policy, finite page/action/snapshot/network/artifact caps, and 0.0.14 verified-state checkpoints with reload/verify-before-side-effect.
75
+ - [Browser automation](browser-automation.md): optional `@arnilo/prism-browser` with host-supplied Playwright contexts, AI-mode snapshots/refs, ordered `browser_open`/`browser_snapshot`/`browser_act`/`browser_close` plus (0.1.4) `browser_evaluate`/`browser_observe` and CDP `block_urls`/`unblock_urls`/`throttle`/`emulate` act actions on Chromium hosts, egress/side-effect/upload/download/screenshot policy, finite page/action/snapshot/network/artifact caps, and 0.0.14 verified-state checkpoints with reload/verify-before-side-effect.
76
76
  - [Device adapters](device-adapters.md): deny-by-default realtime voice / desktop-control contract + conformance (0.0.14); no vendor package — admission fails closed without explicit consent+sandbox+approval, stream bounds, shared `RunLimits`, redacted telemetry.
77
77
  - [Coding agent tools](coding-agent-tools.md): optional `shell`, `read`, `write`, `edit`, `repo_list`, `repo_search`, `glob`, `delete`, and `move` definitions plus opt-in `createGitTools()` / `coding_check`, opt-in `createAskUserDecisionTool` (single/multi/free-text + durable suspend glue), and `runCodingGoalVerify`; durable plan/todo Markdown helpers with workflow `state.coding` checkpoint metadata; streamed text pages, `repo_search` `outputMode`, bounded glob, optional read-before-write, optional Git-aware (`createGitAwareRepositoryOperations`) ignore-aware enumeration with native fallback, finite Git/check/plan/ask caps, bounded image/edit reads and write/edit payloads, finite shell wall/total-output limits, secure host-owned spill cleanup, pluggable bounded operation contracts, per-path mutation serialization, and optional `ExecutionPolicy`. No PDF/trash/PTY in the 0.0.21 baseline; Phase 9 adds optional language intelligence (separate page). Limits do not sandbox host access—gate with permission/trust policy and `@arnilo/prism-coding-security`.
78
78
  - [Language intelligence](language-intelligence.md): optional host-activated `createLanguageIntelligence` — bounded in-package LSP 3.17 JSON-RPC client (Content-Length framing), host-selected server command/args per language, workspace symbols/definitions/references/diagnostics/hover/rename; lazy spawn; URI root confinement; rename gated by `ExecutionPolicy` + atomic write/mutation queue; frozen message/diagnostic/pending/result/timeout/server caps. No `vscode-languageserver-protocol` dependency.
@@ -129,7 +129,7 @@ Prism is a TypeScript/Node.js agent harness. Host apps and extension packages ow
129
129
  - [Ponytail behavior integration](ponytail.md): optional `@arnilo/prism-ponytail` — upstream Ponytail skills/commands, `ponytail-mode` injector, session `ponytail-mode` persistence; resolves peer `@dietrichgebert/ponytail` or `upstreamPath`; opt-in (not in code/sdk profiles).
130
130
 
131
131
  ## Release and install
132
- - [Release and install](release-and-install.md): current **0.1.3** 49-package graph (root + 48 workspace packages; plan 015 dead-code and deprecation hygiene on the frozen 0.1.x line — parameterized benchmark runner `scripts/benchmark.mjs` absorbing the per-version runners, archived review-coverage evidence in `docs/_evidence/`, non-blocking unused-code sweep `npm run sweep:unused`, opt-in checkpoint persistence for loaded-skill names and read-path sets; plan 014 Alibaba provider enrichment — embeddings, video input, verified compatible-mode surface decision table; plan 013 post-release hardening — build single-flight, MCP SSE relay test, combined coverage summary, canonical manifest-count narrative, ACP modes/config persistence guidance; Phase 12 release-candidate hardening; plan 012 — freeze manifest, compatibility matrix, upgrade matrix, packed-install e2e journeys, restart-recovery evidence, capacity envelopes, security policy), exact-peer/install/tarball rules, deterministic resumable publication and publish dry-run, frozen 0.1.x compatibility and support matrix (Node/PostgreSQL/platform/provider/protocol pins and unsupported combinations, machine-checked against `scripts/phase12-freeze-manifest.json`), protected PostgreSQL gate, pinned supply-chain gates, offline tests, the 0.0.15 provider/AI-SDK/RAG/memory protected live-canary matrix, and sandbox-browser Docker/Playwright gates.
132
+ - [Release and install](release-and-install.md): current **0.1.4** 49-package graph (root + 48 workspace packages; plan 016 internal god-module split — `agents.ts`/`contracts.ts` reorganized behind barrel re-exports with a byte-identical public entry surface, measured tree-shaking improvement in `scripts/phase16-baseline.json`, and additive `@arnilo/prism-browser` Chrome DevTools Protocol capabilities — `browser_evaluate`/`browser_observe` and `block_urls`/`unblock_urls`/`throttle`/`emulate` act actions; plan 015 dead-code and deprecation hygiene on the frozen 0.1.x line — parameterized benchmark runner `scripts/benchmark.mjs` absorbing the per-version runners, archived review-coverage evidence in `docs/_evidence/`, non-blocking unused-code sweep `npm run sweep:unused`, opt-in checkpoint persistence for loaded-skill names and read-path sets; plan 014 Alibaba provider enrichment — embeddings, video input, verified compatible-mode surface decision table; plan 013 post-release hardening — build single-flight, MCP SSE relay test, combined coverage summary, canonical manifest-count narrative, ACP modes/config persistence guidance; Phase 12 release-candidate hardening; plan 012 — freeze manifest, compatibility matrix, upgrade matrix, packed-install e2e journeys, restart-recovery evidence, capacity envelopes, security policy), exact-peer/install/tarball rules, deterministic resumable publication and publish dry-run, frozen 0.1.x compatibility and support matrix (Node/PostgreSQL/platform/provider/protocol pins and unsupported combinations, machine-checked against `scripts/phase12-freeze-manifest.json`), protected PostgreSQL gate, pinned supply-chain gates, offline tests, the 0.0.15 provider/AI-SDK/RAG/memory protected live-canary matrix, and sandbox-browser Docker/Playwright gates.
133
133
  - [0.1.0 / 1.0 readiness gates](0.1.0-readiness.md): command-per-gate 1.0 readiness table — frozen API surface + compat gate, migration/docs tripwires, budget table, live-suite matrix, security matrix, current-line status (**0.0.23** published target), signed-publication/live-canary prerequisites for 1.0, and Phase 12 demand-evidence entry criteria.
134
134
  - [Review coverage archive](_evidence/): per-phase evidence freezes (plans 067–079, releases 0.0.4–0.0.16) — traceability matrices, provider validation, capability/primitive/limit matrices, benchmark budgets, and artifact-diet findings; tarball-excluded, kept in-repo for audit.
135
135
 
package/docs/migration.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # Migration guide
2
2
 
3
- ## 0.1.2 → 0.1.3 dead-code and deprecation hygiene (additive, no migration)
3
+ ## 0.1.3 → 0.1.4 internal reorganization behind barrel re-exports (no migration)
4
+
5
+ Release **0.1.4** (plan 016) is an **internal file reorganization behind barrel re-exports**: the root `src/agents.ts` and `src/contracts.ts` god-modules were split by concern into sibling modules (`contracts-core` / `contracts-run-state` / `contracts-protocol` behind the `contracts.ts` barrel; `agent-session` / `agent-run-lifecycle` / `agent-approval` / `agent-tool-dispatch` / `agent-run-state` / `agent-loops` / `compaction` behind the `agents.ts` barrel). **Public declaration surface unchanged** — the root entry surface is byte-identical to 0.1.3 (zero added/removed/changed on the public entry; the only union-surface additions are 14 internal cross-module helper exports that are not consumer-importable, see `scripts/compat-baseline/arnilo__prism.txt`). The optional `@arnilo/prism-browser` package extends additively with Chrome DevTools Protocol capabilities (0.1.4): `browser_evaluate`, `browser_observe`, and the `block_urls`/`unblock_urls`/`throttle`/`emulate` act actions on Chromium hosts, plus raw `{ css }`/`{ xpath }` targets — new exports and two optional structural interface members only, zero removals. **Store compatibility: compatible** — no persisted shape, event schema, or default behavior changed (no runtime path changed; the split is declaration-level). no migration step; rollback = restore the 0.1.3 manifests/tag (stores never change). The next line, **0.1.5**, is the documented **breaking cut** (deprecated-option removal); its migration section will list the removed symbols (the public-but-unused export candidates from `scripts/dead-exports.mjs`).
4
6
 
5
7
  Release **0.1.3** (plan 015) is the dead-code and deprecation hygiene patch on the frozen 0.1.x line: benchmark-runner consolidation (one parameterized `scripts/benchmark.mjs --scenario <name>` replaces the per-version runners; 16 orphaned `benchmark-0.0.{8..16}` runner/test files removed, all `benchmark-*.json` evidence kept), the 12 `docs/review-coverage-2026-07-*.md` evidence files archived to the tarball-excluded `docs/_evidence/`, a non-blocking unused-code sweep (`npm run sweep:unused`, always exits 0, report to `scripts/unused-sweep-report.txt`), and opt-in checkpoint persistence (`persistSessionState: true` on durable run/resume options persists the loaded-skill name catalog ≤64 names in the run-state checkpoint and restores it on resume — bodies re-resolve from the live registry; `createReadPathSetPersistence` in `@arnilo/prism-coding-agent` persists the read-before-write path set through the host `CheckpointStore`, ≤1024 paths, ownership-scoped). **Store compatibility: compatible** — the persisted run-state schema stays at version 1 (the optional `sessionState` field is absent by default, so 0.1.2 checkpoints parse unchanged and opt-out checkpoints are byte-identical); no upgrade or rollback step exists (rollback = restore the 0.1.2 manifests/tag; stores never change). Declaration surface is additive-only vs the frozen 0.1.x contract (`scripts/compat-baseline` regenerated at 0.1.3 with zero breaking deltas, enforced by `node scripts/release.mjs gate`). No breaking defaults.
6
8
 
@@ -28,6 +28,16 @@ node scripts/benchmark-0.1.0.mjs --out scripts/benchmark-0.1.0.json
28
28
  PRISM_TEST_POSTGRES_URL="postgresql://…" node scripts/benchmark-0.1.0.mjs --out scripts/benchmark-0.1.0.json # adds protected legs
29
29
  ```
30
30
 
31
+ ## 0.1.4 tree-shake measurement (static-reachability proxy)
32
+
33
+ The 0.1.4 god-module split (agents/contracts → per-concern modules behind barrels) is
34
+ measured by `scripts/phase16-tree-shake.mjs`: `dist/agents.js`/`dist/contracts.js` byte
35
+ sizes, `dist/*.js` module count, and a static-import reachability count from the minimal
36
+ entry proxy, recorded in `scripts/phase16-baseline.json` (task 3 of plan 016). Static
37
+ graph reachability is an upper-bound proxy, not a real bundle — a byte-accurate
38
+ tree-shake budget needs a bundler and actual consumer code, deferred behind a 0.1.7 DX
39
+ demand gate.
40
+
31
41
  **Pass/fail thresholds.** Network-free rows fail above the frozen ceiling in
32
42
  the table below; protected PostgreSQL rows fail above their per-phase
33
43
  budgets.json ceilings (50/100 ms per the approved budget contract); startup
@@ -417,6 +417,8 @@ void credentials;
417
417
 
418
418
  ## Extension and configuration notes
419
419
 
420
+ **Internal file structure (0.1.4).** Since 0.1.4 the contract declarations are spread across sibling modules behind the `src/contracts.ts` barrel: `src/contracts-core.ts` (JSON/content/core agent contracts plus the `SESSION_ENTRY_KINDS`/`session-store` values), `src/contracts-run-state.ts` (run-state and agent-session contracts including `AgentRunStatus` through `AgentSession`, decision/steer constants, and the error classes), and `src/contracts-protocol.ts` (pure protocol-payload types). The 295-name public surface is unchanged; this page groups the frozen contract by functionality rather than source file.
421
+
420
422
  - Contracts are host-owned and package-friendly. External packages can implement `AIProvider`, `ToolDefinition`, `CommandDefinition`, `AgentDefinition`, `InputBuilder`, `PromptBuilder`, `Middleware`, `ContextProvider`, `Skill`, `Extension`, config providers, data-only manifests, compaction strategies, store factories, resource loaders, settings providers, and credential resolvers.
421
423
  - `ExtensionAPI` is implemented by the extension kernel. It exposes explicit registries, ordered middleware registration, ordered event subscription/emission, and registration methods for Phase 2 contribution categories.
422
424
  - `AgentConfig.provider` can hold a direct provider instance for simple host wiring. Hosts that need config-driven selection should use `ModelConfig.provider` with explicit `createProviderRegistry()` / `createModelRegistry()` objects; Prism does not create a hidden global provider registry.
@@ -274,6 +274,38 @@ git push origin v0.1.2 # tag push triggers release.yml publish job (prove
274
274
 
275
275
  **Rollback notes.** `release:publish --version 0.1.2 --resume --report release-artifacts/publish-report.json` resumes an interrupted publication and skips only registry versions whose internal dependency fingerprint matches the local manifest. A failed package aborts the run with its status written to the report; re-run after fixing the cause. npm cannot unpublish the `0.1.2` line after 72 hours — a post-publication defect ships as a `0.1.x` patch (additive-only compat promise, `release:gate` enforced), or as a documented break in the next line with a `docs/migration.md` entry. `0.1.2` is store-compatible with `0.1.1` in **both directions** (no migration ran — same checksum-protected contract), so an operator may defer or roll back the patch without a database rollback.
276
276
 
277
+ ### 0.1.4 publish handoff (plan 016 Task 6)
278
+
279
+ **Decision: GO when the operator prerequisites below are recorded.** Release **0.1.4** (plan 016) is the internal god-module split, compat-preserving on the frozen 0.1.x line: `src/agents.ts` and `src/contracts.ts` reorganized by concern behind barrel re-exports (`contracts-core`/`contracts-run-state`/`contracts-protocol`; `agent-session`/`agent-run-lifecycle`/`agent-approval`/`agent-tool-dispatch` reusing `agent-run-state`/`agent-loops`/`compaction`) with a **byte-identical public entry surface** (0 added/0 removed/0 changed vs the 0.1.3 baseline; the 14 additive union-surface helpers are internal cross-module exports, not consumer-importable — deviation #1), measured tree-shaking improvement (111,049 → 982 B `dist/agents.js`, 9,420 → 418 B `dist/contracts.js`, module count 64 → 70; evidence in `scripts/phase16-baseline.json`), and additive **`@arnilo/prism-browser` Chrome DevTools Protocol capabilities** (Tasks 4-5): `browser_evaluate`, `browser_observe`, `block_urls`/`unblock_urls`/`throttle`/`emulate` act actions, and `{ css }`/`{ xpath }` targets on Chromium hosts — 41 added / 0 removed / 18 changed declaration texts (15 re-export-statement artifacts + 3 optional-member/signature widenings), the documented deviation #2 carve-out; root `arnilo__prism.txt` regenerated with zero breaking deltas. Publishable graph stays **49** manifests (root + 48 workspace) at exact **0.1.4**. Store compatibility with 0.1.3: **compatible, no migration**; zero new dependencies (lockfile name-set unchanged).
280
+
281
+ ```bash
282
+ # Operator prerequisites (each a named blocked gate — none may be skipped):
283
+ # 1. protected live-canary matrix green (live-canaries.yml, canary-report.json retained)
284
+ # 2. PostgreSQL + keychain protected suites green (test:postgres, keychain suite)
285
+ # 3. CodeQL SAST green on the release commit (security.yml / release.yml codeql-release)
286
+ # 4. npm OIDC trusted publishing identity authenticated (NPM_TOKEN with id-token, provenance)
287
+
288
+ git diff --check
289
+ npm ci
290
+ npm run sdk:ready # includes typecheck, lint, format, full test, coverage, pack, release:gate
291
+ npm run security:threat-suites
292
+ PRISM_TEST_POSTGRES_URL="$DATABASE_URL" npm run test:postgres # Phase 7 + Phase 12 restart-recovery
293
+ npm audit --audit-level=moderate
294
+ npm run release:check -- --version 0.1.4 --report /tmp/prism-0.1.4-preflight.json
295
+ npm run release:publish -- --version 0.1.4 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.1.4-dry-run.json
296
+ # run the dry-run twice and diff the reports: deterministic, byte-identical
297
+
298
+ # Sign the release on the clean tagged tree (operator GPG key):
299
+ git tag -s v0.1.4 -m "Prism 0.1.4"
300
+ git verify-tag v0.1.4
301
+ git push origin v0.1.4 # tag push triggers release.yml publish job (provenance, attestations)
302
+
303
+ # Real publication never bypasses the gates: release.mjs refuses
304
+ # --allow-dirty/--allow-untagged without --dry-run.
305
+ ```
306
+
307
+ **Rollback notes.** `release:publish --version 0.1.4 --resume --report release-artifacts/publish-report.json` resumes an interrupted publication and skips only registry versions whose internal dependency fingerprint matches the local manifest. A failed package aborts the run with its status written to the report; re-run after fixing the cause. npm cannot unpublish the `0.1.4` line after 72 hours — a post-publication defect ships as a `0.1.x` patch (additive-only compat promise, `release:gate` enforced), or as a documented break in the next line with a `docs/migration.md` entry. `0.1.4` is store-compatible with `0.1.3` in **both directions** (no migration ran — same checksum-protected contract), so an operator may defer or roll back the patch without a database rollback. The next line, **0.1.5**, is the documented breaking cut (deprecated-option removal) with its removed-symbols list landing in `docs/migration.md`.
308
+
277
309
  ### 0.1.3 publish handoff (plan 015 Task 5)
278
310
 
279
311
  **Decision: GO when the operator prerequisites below are recorded.** Release **0.1.3** (plan 015) is the dead-code and deprecation hygiene patch on the frozen 0.1.x line: one parameterized benchmark runner `scripts/benchmark.mjs --scenario <name>` replaces the per-version runners (16 orphaned `benchmark-0.0.{8..16}` runner/test files removed, evidence JSON kept; the CI schema leg runs `scripts/benchmark.test.mjs`), the 12 `docs/review-coverage-2026-07-*.md` evidence files moved to the tarball-excluded `docs/_evidence/` archive, a non-blocking unused-code sweep (`npm run sweep:unused` — tsc `noUnusedLocals`/`noUnusedParameters` over core + all workspace tsconfigs plus a zero-dep dead-export scan; always exits 0, report to `scripts/unused-sweep-report.txt`), and opt-in checkpoint persistence (`persistSessionState: true` on durable run/resume options — loaded-skill name catalog ≤64 names rides the run-state checkpoint and restores on resume, bodies re-resolve from the live registry; `createReadPathSetPersistence` in `@arnilo/prism-coding-agent` persists the read-before-write path set through the host `CheckpointStore`, ≤1024 paths, ownership-scoped). Publishable graph stays **49** manifests (root + 48 workspace) at exact **0.1.3**. Store compatibility with 0.1.2: **compatible, no migration**; declaration surface additive-only vs the frozen 0.1.x contract (`scripts/compat-baseline` regenerated at 0.1.3 with zero breaking deltas).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arnilo/prism",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Agent harness for AI providers, agents, sessions, and tools.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -142,7 +142,7 @@
142
142
  "build": "npm run build:core && npm run build --workspaces --if-present",
143
143
  "typecheck": "npm run build && npm run typecheck --workspaces --if-present && tsc -p examples --noEmit",
144
144
  "sweep:unused": "node scripts/sweep-unused.mjs",
145
- "test": "npm run build && node --test dist/__tests__/*.test.js && node --test scripts/release-gate.test.mjs scripts/tooling-gate.test.mjs scripts/budget-gate.test.mjs scripts/phase8-conformance.test.mjs scripts/phase9-conformance.test.mjs scripts/phase10-conformance.test.mjs scripts/phase11-conformance.test.mjs scripts/phase11-freeze.test.mjs scripts/phase12-freeze.test.mjs scripts/phase13-freeze.test.mjs scripts/phase14-freeze.test.mjs scripts/phase15-freeze.test.mjs scripts/benchmark-0.1.0.test.mjs scripts/sweep-unused.test.mjs scripts/e2e-enterprise-journey.test.mjs scripts/e2e-coding-journey.test.mjs && npm run test --workspaces --if-present",
145
+ "test": "npm run build && node --test dist/__tests__/*.test.js && node --test scripts/release-gate.test.mjs scripts/tooling-gate.test.mjs scripts/budget-gate.test.mjs scripts/phase8-conformance.test.mjs scripts/phase9-conformance.test.mjs scripts/phase10-conformance.test.mjs scripts/phase11-conformance.test.mjs scripts/phase11-freeze.test.mjs scripts/phase12-freeze.test.mjs scripts/phase13-freeze.test.mjs scripts/phase14-freeze.test.mjs scripts/phase15-freeze.test.mjs scripts/phase16-freeze.test.mjs scripts/benchmark-0.1.0.test.mjs scripts/sweep-unused.test.mjs scripts/e2e-enterprise-journey.test.mjs scripts/e2e-coding-journey.test.mjs && npm run test --workspaces --if-present",
146
146
  "test:coverage": "node --test --experimental-test-coverage --test-coverage-lines=60 --test-coverage-functions=70 --test-coverage-branches=75 --test-coverage-exclude='**/__tests__/**' --test-coverage-exclude='**/node_modules/**' --test-coverage-exclude='**/scripts/**' --test-coverage-exclude='**/packages/**' --test-coverage-exclude='**/examples/**' dist/__tests__/*.test.js && node scripts/coverage-summary.mjs",
147
147
  "coverage:summary": "node scripts/coverage-summary.mjs",
148
148
  "lint": "biome lint .",