@hraness/direct 0.7.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +436 -0
  3. package/dist/core/index.js +162 -0
  4. package/dist/index-1csg00w4.js +1167 -0
  5. package/dist/index-6mdfd2ey.js +464 -0
  6. package/dist/index-7n1h75n6.js +616 -0
  7. package/dist/index.js +232 -0
  8. package/dist/react.js +32 -0
  9. package/dist/testing/index.js +1069 -0
  10. package/dist/tooling/bombadil.js +2117 -0
  11. package/dist/tooling/browser-verification-entry.js +1499 -0
  12. package/dist/tooling/bundle-boundary.js +119 -0
  13. package/dist/web.js +605 -0
  14. package/package.json +179 -0
  15. package/skills/direct/AGENTS.md +13 -0
  16. package/skills/direct/SKILL.md +49 -0
  17. package/skills/direct/agents/openai.yaml +4 -0
  18. package/skills/direct/references/adoption.md +131 -0
  19. package/skills/direct/references/install.md +91 -0
  20. package/skills/direct/references/verification.md +247 -0
  21. package/src/core/coverage.ts +336 -0
  22. package/src/core/definition.ts +378 -0
  23. package/src/core/effects.ts +88 -0
  24. package/src/core/fixture.ts +185 -0
  25. package/src/core/ids.ts +77 -0
  26. package/src/core/index.ts +13 -0
  27. package/src/core/json-value.ts +7 -0
  28. package/src/core/json.ts +593 -0
  29. package/src/core/query.ts +230 -0
  30. package/src/core/reason.ts +16 -0
  31. package/src/core/resource.ts +10 -0
  32. package/src/core/result.ts +19 -0
  33. package/src/core/runtime.ts +229 -0
  34. package/src/core/scenario.ts +149 -0
  35. package/src/core/store.ts +784 -0
  36. package/src/index.ts +51 -0
  37. package/src/react.ts +54 -0
  38. package/src/testing/activity.ts +228 -0
  39. package/src/testing/coverage-binding.ts +99 -0
  40. package/src/testing/evidence.ts +59 -0
  41. package/src/testing/index.ts +22 -0
  42. package/src/testing/manifest.ts +559 -0
  43. package/src/testing/probe.ts +446 -0
  44. package/src/testing/scripted-transport.ts +775 -0
  45. package/src/testing/session.ts +525 -0
  46. package/src/tooling/bombadil-campaign.ts +288 -0
  47. package/src/tooling/bombadil-internal.d.ts +46 -0
  48. package/src/tooling/bombadil-runner.ts +1424 -0
  49. package/src/tooling/bombadil.ts +27 -0
  50. package/src/tooling/browser-verification-entry.ts +32 -0
  51. package/src/tooling/browser-verification.ts +916 -0
  52. package/src/tooling/bundle-boundary.ts +159 -0
  53. package/src/web/browser-bridge.ts +296 -0
  54. package/src/web/browser.ts +277 -0
  55. package/src/web/fetch-firewall.ts +251 -0
  56. package/src/web.ts +27 -0
package/package.json ADDED
@@ -0,0 +1,179 @@
1
+ {
2
+ "name": "@hraness/direct",
3
+ "version": "0.7.5",
4
+ "description": "A general harness for repeatable app states.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "sideEffects": [
8
+ "./src/core/index.ts",
9
+ "./src/index.ts",
10
+ "./src/react.ts",
11
+ "./src/testing/index.ts",
12
+ "./src/web.ts"
13
+ ],
14
+ "packageManager": "bun@1.3.14",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/hraness/direct.git"
18
+ },
19
+ "homepage": "https://hraness.com/direct",
20
+ "bugs": {
21
+ "url": "https://github.com/hraness/direct/issues"
22
+ },
23
+ "keywords": [
24
+ "typescript",
25
+ "frontend-testing",
26
+ "deterministic-testing",
27
+ "fixtures",
28
+ "scenario-testing",
29
+ "property-testing"
30
+ ],
31
+ "exports": {
32
+ ".": {
33
+ "types": "./src/index.ts",
34
+ "import": "./dist/index.js"
35
+ },
36
+ "./core": {
37
+ "types": "./src/core/index.ts",
38
+ "import": "./dist/core/index.js"
39
+ },
40
+ "./react": {
41
+ "types": "./src/react.ts",
42
+ "import": "./dist/react.js"
43
+ },
44
+ "./testing": {
45
+ "types": "./src/testing/index.ts",
46
+ "import": "./dist/testing/index.js"
47
+ },
48
+ "./web": {
49
+ "types": "./src/web.ts",
50
+ "import": "./dist/web.js"
51
+ },
52
+ "./tooling/browser-verification": {
53
+ "types": "./src/tooling/browser-verification-entry.ts",
54
+ "import": "./dist/tooling/browser-verification-entry.js"
55
+ },
56
+ "./tooling/bombadil": {
57
+ "types": "./src/tooling/bombadil.ts",
58
+ "import": "./dist/tooling/bombadil.js"
59
+ },
60
+ "./tooling/bombadil-campaign": "./src/tooling/bombadil-campaign.ts",
61
+ "./tooling/bundle-boundary": {
62
+ "types": "./src/tooling/bundle-boundary.ts",
63
+ "import": "./dist/tooling/bundle-boundary.js"
64
+ }
65
+ },
66
+ "main": "./dist/index.js",
67
+ "types": "./src/index.ts",
68
+ "files": [
69
+ "dist",
70
+ "src/core/coverage.ts",
71
+ "src/core/definition.ts",
72
+ "src/core/effects.ts",
73
+ "src/core/fixture.ts",
74
+ "src/core/ids.ts",
75
+ "src/core/index.ts",
76
+ "src/core/json-value.ts",
77
+ "src/core/json.ts",
78
+ "src/core/query.ts",
79
+ "src/core/reason.ts",
80
+ "src/core/resource.ts",
81
+ "src/core/result.ts",
82
+ "src/core/runtime.ts",
83
+ "src/core/scenario.ts",
84
+ "src/core/store.ts",
85
+ "src/index.ts",
86
+ "src/react.ts",
87
+ "src/testing/activity.ts",
88
+ "src/testing/coverage-binding.ts",
89
+ "src/testing/evidence.ts",
90
+ "src/testing/index.ts",
91
+ "src/testing/manifest.ts",
92
+ "src/testing/probe.ts",
93
+ "src/testing/scripted-transport.ts",
94
+ "src/testing/session.ts",
95
+ "src/tooling/browser-verification-entry.ts",
96
+ "src/tooling/browser-verification.ts",
97
+ "src/tooling/bombadil-internal.d.ts",
98
+ "src/tooling/bombadil-campaign.ts",
99
+ "src/tooling/bombadil-runner.ts",
100
+ "src/tooling/bombadil.ts",
101
+ "src/tooling/bundle-boundary.ts",
102
+ "src/web.ts",
103
+ "src/web/browser.ts",
104
+ "src/web/browser-bridge.ts",
105
+ "src/web/fetch-firewall.ts",
106
+ "skills",
107
+ "README.md",
108
+ "LICENSE"
109
+ ],
110
+ "scripts": {
111
+ "build": "bun run build:clean && bun run build:runtime && bun run build:tooling",
112
+ "build:clean": "bun -e 'await (await import(\"node:fs/promises\")).rm(\"./dist\", { recursive: true, force: true })'",
113
+ "build:runtime": "bun build ./src/index.ts ./src/core/index.ts ./src/react.ts ./src/testing/index.ts ./src/web.ts --outdir ./dist --root ./src --target browser --format esm --splitting --packages external",
114
+ "build:tooling": "bun build ./src/tooling/browser-verification-entry.ts ./src/tooling/bundle-boundary.ts --outdir ./dist/tooling --root ./src/tooling --target bun --format esm --splitting --packages external && bun build ./src/tooling/bombadil.ts --outdir ./dist/tooling --root ./src/tooling --target bun --format esm --splitting --packages external",
115
+ "typecheck": "tsc --noEmit",
116
+ "test": "bun test ./src",
117
+ "example:build": "vite build --config examples/todos/vite.config.ts",
118
+ "example:build:direct": "vite build --config examples/todos/direct/vite.config.ts",
119
+ "example:check-boundary": "bun run examples/todos/direct/check-production-boundary.ts examples/todos/dist",
120
+ "example:dev": "vite --config examples/todos/vite.config.ts",
121
+ "example:direct": "vite --config examples/todos/direct/vite.config.ts",
122
+ "example:react-native": "bun run --cwd examples/react-native start",
123
+ "example:react-native:test": "bun run --cwd examples/react-native test",
124
+ "example:react-native:typecheck": "tsc -p examples/react-native/tsconfig.json --noEmit",
125
+ "example:react-native:verify": "bun run examples/react-native/verify.ts",
126
+ "example:test": "bun test ./examples/todos",
127
+ "example:typecheck": "tsc -p examples/todos/tsconfig.json --noEmit",
128
+ "example:verify": "bun run examples/todos/verify.ts",
129
+ "lint": "eslint src examples scripts",
130
+ "test:npm-release": "bun test ./scripts/npm-stage-workflow.test.ts",
131
+ "test:package": "bun run ./scripts/package-smoke.ts",
132
+ "kb:refresh": "bunx --bun github:hraness/kb#v0.15.2 refresh --root kb",
133
+ "kb:check:lane": "bunx --bun github:hraness/kb#v0.15.2 check --root kb --no-catalog",
134
+ "kb:check": "bunx --bun github:hraness/kb#v0.15.2 check --root kb && bunx --bun github:hraness/kb#v0.15.2 agents check --root kb --repo .",
135
+ "kb:catalog": "bunx --bun github:hraness/kb#v0.15.2 catalog --root kb",
136
+ "check": "bun run typecheck && bun run test:npm-release && bun run build && bun run test:package && bun run test && bun run lint && bun run example:test && bun run example:typecheck && bun run example:verify && bun run example:react-native:test && bun run example:react-native:typecheck && bun run example:react-native:verify",
137
+ "prepack": "bun run check"
138
+ },
139
+ "peerDependencies": {
140
+ "@antithesishq/bombadil": "0.7.2",
141
+ "agent-browser": "0.32.3",
142
+ "react": ">=18 <20"
143
+ },
144
+ "peerDependenciesMeta": {
145
+ "@antithesishq/bombadil": {
146
+ "optional": true
147
+ },
148
+ "agent-browser": {
149
+ "optional": true
150
+ },
151
+ "react": {
152
+ "optional": true
153
+ }
154
+ },
155
+ "devDependencies": {
156
+ "@antithesishq/bombadil": "0.7.2",
157
+ "@eslint/js": "^9.39.2",
158
+ "@expo/metro-runtime": "~57.0.6",
159
+ "@types/bun": "^1.3.14",
160
+ "@types/node": "^24.10.0",
161
+ "@types/react": "^19.2.14",
162
+ "@types/react-dom": "^19.2.3",
163
+ "@vitejs/plugin-react": "^6.0.3",
164
+ "eslint": "^9.39.2",
165
+ "expo": "~57.0.9",
166
+ "fast-check": "^4.8.0",
167
+ "react": "19.2.3",
168
+ "react-dom": "19.2.3",
169
+ "react-native": "0.86.2",
170
+ "react-native-web": "~0.21.2",
171
+ "typescript": "^6.0.3",
172
+ "typescript-eslint": "^8.53.0",
173
+ "vite": "^8.1.5"
174
+ },
175
+ "publishConfig": {
176
+ "access": "public",
177
+ "registry": "https://registry.npmjs.org"
178
+ }
179
+ }
@@ -0,0 +1,13 @@
1
+ # Contents
2
+
3
+ - `SKILL.md` – concise routing, shared invariants, and production-exclusion rules.
4
+ - `references/install.md` – exact package installation, readiness, and optional browser-driver guidance.
5
+ - `references/adoption.md` – product-boundary and deterministic-composition workflow.
6
+ - `references/verification.md` – evidence, browser-session, cleanup, and production-boundary audit workflow.
7
+ - `agents/openai.yaml` – concise UI metadata and default `$direct` invocation.
8
+
9
+ # Guidelines
10
+
11
+ - Preserve the product-owned semantic-port boundary and keep provider protocols out of deterministic adapters.
12
+ - Require strict versioned worlds, explicit proof modes, structurally separate composition graphs, and non-vacuous emitted-output scans with paired source maps where platform resolution matters.
13
+ - Keep metadata aligned with the skill's actual trigger and workflow.
@@ -0,0 +1,49 @@
1
+ ---
2
+ name: direct
3
+ description: Use Hraness Direct to install, adopt, test, audit, or troubleshoot deterministic frontend and UI testing workbenches for web, React, React Native, and Expo. Trigger for repeatable signed-in, empty, loading, and error states; frontend fixtures and scenario URLs; strict JSON worlds; product-owned ports and adapters; logical time; fail-closed network boundaries; agent-browser, Playwright, or Bombadil verification; quiescence probes; coverage claims; property tests; and proving @hraness/direct stays out of production bundles.
4
+ ---
5
+
6
+ # Direct
7
+
8
+ Direct is a development-only harness for repeatable application states. It
9
+ runs the real interface and feature code against product-owned deterministic
10
+ ports. It does not drive the browser or prove the live systems, hosts,
11
+ platforms, or devices that those ports replace.
12
+
13
+ ## Choose the workflow
14
+
15
+ - If Direct is absent, the requested work includes installation, or package
16
+ readiness is uncertain, read [references/install.md](references/install.md).
17
+ - To add, extend, repair, or troubleshoot a Direct composition, read
18
+ [references/adoption.md](references/adoption.md).
19
+ - To test, audit, review, or report evidence from an existing composition,
20
+ read [references/verification.md](references/verification.md).
21
+ - For end-to-end adoption, read the installation and adoption references,
22
+ implement the smallest product seam, then apply the verification reference.
23
+
24
+ ## Preserve the boundary
25
+
26
+ Keep Direct in `devDependencies`. Put provider, storage, native-module, host,
27
+ or service code behind the smallest product-owned semantic port. Production
28
+ and Direct compositions must have structurally separate entry graphs.
29
+
30
+ Never import Direct, fixture worlds, scenario catalogs, workbench code, or the
31
+ browser bridge from a production entry. Build production independently and
32
+ scan its emitted executable output. A scan that inspected no executable files
33
+ is not evidence.
34
+
35
+ Parse foreign worlds and browser contracts from `unknown`. Reject malformed
36
+ explicit activation instead of falling back to another scenario. Use logical
37
+ time and activity scopes for deterministic work, and join a stable quiet probe
38
+ before making semantic assertions.
39
+
40
+ State proof limits precisely. Fixture evidence can prove the real interface
41
+ and product logic through deterministic ports; it cannot prove a substituted
42
+ adapter, service, operating system, browser host, or device.
43
+
44
+ ## Finish the task
45
+
46
+ Run narrow checks while editing, then the consumer repository's complete
47
+ in-scope gate. Report the selected product port, scenarios, proof modes,
48
+ commands, production surfaces scanned, passed evidence, and direct evidence
49
+ that remains open.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Direct"
3
+ short_description: "Build and verify deterministic UI states"
4
+ default_prompt: "Use $direct to add or verify a deterministic UI composition while keeping Direct out of production."
@@ -0,0 +1,131 @@
1
+ # Adopt Direct
2
+
3
+ ## Inspect the product boundary
4
+
5
+ 1. Read every applicable `AGENTS.md`, the package manifest, build configuration, production entry, feature state, and existing tests.
6
+ 2. Trace the external dependency that makes the target state slow or nondeterministic.
7
+ 3. Choose the lowest product-owned semantic port above that dependency and below the behavior under review.
8
+ 4. State which adapter, service, host, platform, or device behavior the deterministic composition will replace and therefore cannot prove.
9
+
10
+ Do not simulate a provider SDK or wire protocol when the product can own a smaller domain port. Do not fork product UI or reducers into fixture-only copies.
11
+
12
+ ## Separate production first
13
+
14
+ 1. Define the port in production-safe product code.
15
+ 2. Move provider, native-module, storage, or service imports into a production adapter.
16
+ 3. Compose production from a production-only graph.
17
+ 4. Add Direct as a development dependency and create a distinct Direct graph and output directory. Use a separate entry when both compositions target the same platform; a non-shipping Expo web fixture may instead sit behind an extensionless import with `.native` and `.web` implementations below a shared route tree.
18
+
19
+ Reject a design that conditionally imports fixtures from a query string, build flag, or runtime environment variable inside the production graph. Keep platform-specific navigation providers below shared routes and screens so route discovery sees one stable module while the bundler selects one composition.
20
+
21
+ ## Define the deterministic surface
22
+
23
+ 1. Define one bounded JSON world with a literal version.
24
+ 2. Parse it from `unknown`; reject unknown keys, unsupported versions, duplicate identifiers, inconsistent states, and exceeded bounds.
25
+ 3. Call `defineDirect` with a validated default, stable scenario IDs, and exact `fixture`, `mixed`, or `direct` coverage entries. Authored invalid configuration should fail during startup. Use `tryDefineDirect` for typed configuration assembled dynamically and `parseDirectDefinition` for genuinely unknown configuration.
26
+ Keep each definition within the public discovery bounds of 256 scenarios
27
+ and 256 coverage entries.
28
+ 4. Implement deterministic adapters for the same product ports. Use logical time for product delays and activity scopes for asynchronous work.
29
+ 5. Use exact scripts only when request or event order is part of the claim. Keep arbitrary valid interactive behavior stateful in the product adapter.
30
+ 6. Call `createDirectSession` to own activation, store, clock, activity,
31
+ harness construction, the world-free session manifest, probe observation,
32
+ cancellation, and reverse-order cleanup.
33
+
34
+ Treat the shared world store as a scenario seed and activity ledger. Let product adapters own mutable repositories or event streams after construction.
35
+
36
+ A scenario contains initial world, route, and optional logical-runtime state. Product-verifier actions, semantic assertions, and evidence policy do not belong in the scenario catalog.
37
+
38
+ ## Add the development entry
39
+
40
+ Render the real product interface with deterministic adapters from
41
+ `session.harness`. Call `installDirectBrowser({ session })` only in a browser
42
+ Direct entry. It atomically publishes the exact session manifest, live probe,
43
+ and reset action, installs the fail-closed application-fetch firewall by
44
+ default, tracks fetch work in the session activity scope, and registers
45
+ cleanup with the session. Configure blocked-request and activity-error
46
+ observers as named violations. Pass `firewall: false` only when another
47
+ checked boundary owns the same application-`fetch` policy. The verifier still
48
+ needs pre-navigation egress containment.
49
+
50
+ Do not create a product-specific scenario-discovery global. The manifest
51
+ already publishes the query keys, default scenario, ordered scenario metadata,
52
+ active identity, and coverage contract without exposing worlds, scripts, or
53
+ product assertions. Its catalog drift fingerprint covers the query keys,
54
+ default scenario, ordered metadata, and exact coverage snapshot. The scenario
55
+ route is the expected product route; the product still owns whether its Direct
56
+ entry lives at that route or inside one wrapper URL.
57
+
58
+ Display activation failures. Never fall back from malformed explicit activation to a nearby valid scenario.
59
+
60
+ Keep browser process and session policy in the product verifier, outside the
61
+ product composition. Direct's browser runtime remains driver-neutral. Prefer
62
+ the optional `@hraness/direct/tooling/browser-verification` Bun/Node helpers
63
+ for atomic bridge reads, bounded agent-browser commands, server leases, and
64
+ artifacts when they fit the repository. The helpers invoke the consumer's
65
+ local agent-browser installation; they do not bundle a driver, coordinate
66
+ parallel work, supervise cleanup, or own product commands and evidence.
67
+
68
+ Use one task-owned local Chromium session and process for a sequential batch of
69
+ at most eight scenarios. Call `window new` before every scenario to create a
70
+ fresh BrowserContext. Inventory its tabs and attempt to close scenario-owned
71
+ tabs, retaining each command result and the post-attempt inventory.
72
+ agent-browser 0.32.3 can ignore `Target.closeTarget` errors, so do not claim
73
+ proven per-tab closure. Keep the inert no-URL bootstrap tab until the final
74
+ whole-browser close, which is the stronger disposal boundary. Do not reuse a
75
+ context, substitute `tab new`, or launch one process per scenario. Capture
76
+ semantic and visual evidence in the same exact Chromium context.
77
+
78
+ Pass an exact `--allowed-domains` list for the target and required asset hosts
79
+ before the first navigation. Start Chromium with `open` and no URL so
80
+ agent-browser installs the allowlist while creating its inert internal
81
+ `about:blank` tab. Do not pass `about:blank` as an explicit URL; 0.32.3 rejects
82
+ that hostname-free navigation under the allowlist. Keep the Direct
83
+ application-`fetch` firewall as instrumentation; it does not contain
84
+ navigation, subresources, WebSockets, workers, service workers, beacons,
85
+ WebRTC, native traffic, or another realm.
86
+ Forbid ordinary browser-wide `--cdp` attachment because named sessions do not
87
+ isolate contexts and agent-browser 0.32.3 cannot combine that attachment with
88
+ `--allowed-domains`.
89
+
90
+ Run locally serial unless a real external coordinator enforces shared
91
+ admission. Direct does not integrate or enforce a process cap. Use one explicit
92
+ session, empty task-owned config, fresh socket directory, sanitized
93
+ environment, exact allowlist, and bounded idle timeout for every batch command.
94
+ Record the exact agent-browser version.
95
+
96
+ Require a successful final browser close. A close failure invalidates the
97
+ batch; preserve task metadata and do not claim disposal or performance.
98
+ The idle timeout is only an orphan backstop. Parallel-admission or crash-safe
99
+ cleanup claims require a real external supervisor that owns both the
100
+ agent-browser daemon and Chromium roots, or one containing job. The roots can
101
+ occupy different process groups, so daemon exit alone is not cleanup proof.
102
+
103
+ ## Prove behavior and exclusion
104
+
105
+ Add focused tests for:
106
+
107
+ - accepted and rejected worlds;
108
+ - scenario and coverage drift;
109
+ - session-manifest round trips, active identity, and catalog drift;
110
+ - deterministic adapter success, declared failure, cancellation, and cleanup;
111
+ - exact-script consumption and remaining work when scripts are used; and
112
+ - emitted production output containing a forbidden marker.
113
+
114
+ Build production and Direct separately. Scan emitted production assets for package names, wire schemas, reserved query keys, fixture and workbench markers, and browser globals. Prefer `@hraness/direct/tooling/bundle-boundary` for the shared scan mechanics while keeping included paths, product markers, and positive production identity evidence product-owned. Fail a scan that inspects no executable files.
115
+
116
+ For native bundles, emit a paired source map for each production platform. Positively require stable path suffixes for the shared screen and state, native composition, and production adapters in every map; reject the Direct package, `.web` composition, fixtures, and workbench sources. Apply the inverse positive selection to a web fixture map. An absence-only scan of an unrelated clean bundle is not proof.
117
+
118
+ Update the nearest `AGENTS.md`, package README, and command documentation. Run the narrow tests while iterating, then the repository's complete in-scope gate.
119
+
120
+ ## Report the result
121
+
122
+ Name the selected port, deterministic scenarios, proof modes, commands run, production surfaces scanned, and direct evidence that still remains. Do not describe fixture evidence as proof of a replaced external system.
123
+ When browser verification is in scope, also name the process and session
124
+ policy. Require each evidence record to carry the exact browser-driver version,
125
+ configured backend, allowed hosts, observed browser identity, batch index and
126
+ size, verifier-assigned scenario/context label, fresh `window new` command and
127
+ result, tab inventories and close-attempt results, execution mode, and final
128
+ close result. Only when a performance comparison is explicitly requested, report wall time
129
+ separately from local host CPU and peak resident memory; lower host load is not
130
+ itself a faster result. Direct provides no browser-run or performance evidence;
131
+ require external product evidence for either claim.
@@ -0,0 +1,91 @@
1
+ # Install and verify Direct
2
+
3
+ Installing this Agent Skill does not install the Direct library into a
4
+ consumer project. Direct is a development dependency and does not provide a
5
+ global `direct` CLI.
6
+
7
+ ## Check readiness
8
+
9
+ 1. Read the consumer's repository instructions and package manifest.
10
+ 2. Confirm Bun is available with `command -v bun`. If it is absent, follow the
11
+ reviewed environment setup or the official [Bun installation
12
+ guide](https://bun.sh/docs/installation); do not run an unreviewed remote
13
+ install script.
14
+ 3. Inspect `devDependencies` for `@hraness/direct`. Do not move it into
15
+ `dependencies`.
16
+ 4. Reuse the repository's existing immutable Direct pin when it is compatible.
17
+ Do not upgrade an existing pin unless the user asked for an upgrade.
18
+
19
+ ## Add the library
20
+
21
+ For a new installation, pin the reviewed public release:
22
+
23
+ ```sh
24
+ bun add --dev @hraness/direct@0.7.5
25
+ # or, in an npm project
26
+ npm install --save-dev @hraness/direct@0.7.5
27
+ ```
28
+
29
+ The equivalent manifest entry is:
30
+
31
+ ```json
32
+ {
33
+ "devDependencies": {
34
+ "@hraness/direct": "0.7.5"
35
+ }
36
+ }
37
+ ```
38
+
39
+ Then run `bun install`. Do not add another package manager or lockfile to a
40
+ repository that already defines its package manager.
41
+
42
+ If the task starts with skill installation rather than a loaded skill, install
43
+ the single repository skill with either command:
44
+
45
+ ```sh
46
+ npx skills add hraness/direct
47
+ bunx skills add hraness/direct
48
+ ```
49
+
50
+ Restart or reload the agent runner if it does not discover newly installed
51
+ skills during the current session, then invoke `$direct`.
52
+
53
+ ## Optional browser verification dependency
54
+
55
+ Direct's runtime is driver-neutral. Install `agent-browser@0.32.3` only when
56
+ the requested verification workflow uses Direct's optional agent-browser host
57
+ tooling and the consumer does not already supply the compatible peer:
58
+
59
+ ```sh
60
+ bun add --dev agent-browser@0.32.3
61
+ ```
62
+
63
+ Playwright MCP or another browser driver can instead read the same exact
64
+ `window.__direct` contract when it independently establishes the required
65
+ containment, fresh-context, and cleanup evidence. Do not install a browser
66
+ driver for an adoption-only task.
67
+
68
+ Install Bombadil only when the product requests bounded diagnostic fuzzing
69
+ through Direct's optional campaign and host-runner subpaths. The integration
70
+ supports one exact release:
71
+
72
+ ```sh
73
+ bun add --dev @antithesishq/bombadil@0.7.2
74
+ ```
75
+
76
+ Bombadil is an optional Direct peer. Keep the direct development dependency in
77
+ the consumer root because the host runner resolves and validates that root
78
+ package and its native platform binary.
79
+
80
+ ## Verify the boundary
81
+
82
+ After installation:
83
+
84
+ - ensure the lockfile resolves the intended immutable release;
85
+ - typecheck the consumer's intended Direct imports;
86
+ - build Direct and production entries separately; and
87
+ - run the product-owned emitted-bundle boundary gate against every production
88
+ surface.
89
+
90
+ Package installation alone does not activate fixtures and does not prove
91
+ production exclusion.