Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

- Use Bun 1.3.14 and run `bun run check` before handing off a change.
- Follow `WRITING.md` for internal prose and `STYLE.md` for public prose.
- Follow the shared [README guidelines](https://github.com/hraness/.github/blob/main/README_GUIDELINES.md) for the root README and any site copy that summarizes it.
- Apply unreasonably robust programming when agent work is cheap. Model invalid states out of existence and pair readable regression examples with property tests for general laws.
- Deliver changes to `main` through a current-head pull request. Keep the stable `Required` CI job green, resolve every review thread, and serialize merges. Human approval stays optional while one regular maintainer would otherwise self-review. Never force-push or bypass the gate.
- Pin Hraness dependencies to reviewed immutable releases or full commits. Never replace them with sibling paths, Git submodules, or coordinated `main` assumptions.
Expand Down
146 changes: 84 additions & 62 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,68 +21,8 @@ Bring the model, planner, tool loop, approval interface, and application shell
you prefer. Wrench supplies precise web capabilities with local custody and
explicit evidence.

```sh
wrench https://example.com/article
wrench capabilities
wrench plugin list
```

[Install](#install) · [npm package](https://www.npmjs.com/package/@hraness/wrench) · [Project site](https://wrench.rip) · [Privacy and data custody](https://wrench.rip/privacy/) · [Security policy](SECURITY.md) · [Plugin guide](docs/plugins.md) · [Local CLI transport guide](docs/local-cli-providers.md)

## What Wrench does

- **Capture knowledge.** Turn a public URL into durable Markdown, inspect it
without saving, and search the knowledge you keep locally.
- **Preserve media.** Archive one authorized, accessible, finite media item
with source bytes, requested derivatives, transcript, manifest, and SHA-256
integrity records.
- **Read connected services.** Store validated account-bound reads as encrypted
exact-query snapshots, then load the last verified state without reopening a
browser or contacting the provider.
- **Add one capability.** Turn a reviewed first-party exchange into a typed,
semantic operation with strict inputs, bounded outputs, and explicit trust.

## Built-in provider catalog

This v0.16.2 source tree defines actions for 19 services: Beeper, Bluesky, Facebook,
Facebook Groups, Facebook Marketplace, GitHub, Gmail, Hacker News, Instagram,
iMessage, LinkedIn, Reddit, Substack, Threads, TikTok, Twitch, WhatsApp, X, and
YouTube.
LinkedIn and X each have separate official and authenticated-web adapters. The
[release-bound provider directory](https://wrench.rip/provider-capabilities/)
lists only executable actions, grouped by the tasks each service supports and
the access method each action uses. Inspect `wrench capabilities --json` for
the exact installed contract state.

Beeper is Wrench's first pinned local-CLI provider. Its 32 supported actions
read accounts, contacts, conversations, and messages; manage reactions, drafts,
reminders, and conversation state; and preview and confirm sends, edits, group
changes, and presence. Wrench accepts only the reviewed official Beeper CLI
0.6.2 executable and one bound Desktop target. It does not expose a generic
command runner, and submission is not a claim of network delivery.

```sh
wrench messaging routes --input @/absolute/private/beeper-routes-request.json \
--private-output /absolute/private/beeper-routes.json --json
wrench messaging resolve --input @/absolute/private/beeper-resolve-request.json \
--private-output /absolute/private/beeper-route.json --json
wrench messaging context --input @/absolute/private/beeper-context-request.json \
--private-output /absolute/private/beeper-context.json --json
wrench messaging preview --input @/absolute/private/beeper-turn.json \
--private-output /absolute/private/beeper-preview.json --json
```

`routes` returns bounded discovery evidence and opaque candidate references.
Put one candidate `routeRef` in the private resolve request. Wrench loads the
checked provider target from encrypted private state and performs the exact
provider read. The caller never resupplies an account, network, conversation
ID, name, handle, title, or participant match. Preview is draft-only until the
owner reviews the exact private recipient and bubbles and makes a fresh
same-turn send request.

Read the focused [Beeper guide](https://wrench.rip/providers/beeper/) for setup,
version identities, action boundaries, export workflows, and exclusions.

## Why Wrench is different

- **Intent over mechanism.** Agents receive labeled operations, not credentials,
Expand Down Expand Up @@ -130,13 +70,24 @@ npm:
bun add --global @hraness/wrench@0.16.2
wrench adapter sync-bundled --json
wrench doctor
wrench read https://example.com/article
```

Wrench requires Bun 1.3.14. It runs on macOS and Linux. `wrench doctor`
reports capture, media, authentication, provider, plugin, and durable-recovery
readiness. Provider-specific commands remain unavailable until their exact
local dependency and auth contracts are ready.

`wrench read` returns a readable page result without saving it. Pass a URL
directly to save durable Markdown in a configured knowledge base, then inspect
the exact operations installed on the machine:

```sh
wrench https://example.com/article
wrench capabilities
wrench plugin list
```

`wrench adapter sync-bundled` atomically installs the reviewed data manifests
shipped by that exact package version. It upgrades only an exact current or
archived bundled baseline and preserves any independently modified install.
Expand All @@ -145,6 +96,77 @@ The public manifest projects each closure-attested package as an exact runtime
dependency. Standalone validation installs without the repository lock, then
verifies the resolved closure versions and reviewed entrypoint hashes.

## What Wrench does

- **Capture knowledge.** Turn a public URL into durable Markdown, inspect it
without saving, and search the knowledge you keep locally.
- **Preserve media.** Archive one authorized, accessible, finite media item
with source bytes, requested derivatives, transcript, manifest, and SHA-256
integrity records.
- **Read connected services.** Store validated account-bound reads as encrypted
exact-query snapshots, then load the last verified state without reopening a
browser or contacting the provider.
- **Add one capability.** Turn a reviewed first-party exchange into a typed,
semantic operation with strict inputs, bounded outputs, and explicit trust.

## Built-in provider catalog

This v0.16.2 source tree defines actions for 19 services: Beeper, Bluesky, Facebook,
Facebook Groups, Facebook Marketplace, GitHub, Gmail, Hacker News, Instagram,
iMessage, LinkedIn, Reddit, Substack, Threads, TikTok, Twitch, WhatsApp, X, and
YouTube.
LinkedIn and X each have separate official and authenticated-web adapters. The
[release-bound provider directory](https://wrench.rip/provider-capabilities/)
lists only executable actions, grouped by the tasks each service supports and
the access method each action uses. Inspect `wrench capabilities --json` for
the exact installed contract state.

Beeper is Wrench's first pinned local-CLI provider. Its 32 supported actions
read accounts, contacts, conversations, and messages; manage reactions, drafts,
reminders, and conversation state; and preview and confirm sends, edits, group
changes, and presence. Wrench accepts only the reviewed official Beeper CLI
0.6.2 executable and one bound Desktop target. It does not expose a generic
command runner, and submission is not a claim of network delivery.

```sh
wrench messaging routes --input @/absolute/private/beeper-routes-request.json \
--private-output /absolute/private/beeper-routes.json --json
wrench messaging resolve --input @/absolute/private/beeper-resolve-request.json \
--private-output /absolute/private/beeper-route.json --json
wrench messaging context --input @/absolute/private/beeper-context-request.json \
--private-output /absolute/private/beeper-context.json --json
wrench messaging preview --input @/absolute/private/beeper-turn.json \
--private-output /absolute/private/beeper-preview.json --json
```

`routes` returns bounded discovery evidence and opaque candidate references.
Put one candidate `routeRef` in the private resolve request. Wrench loads the
checked provider target from encrypted private state and performs the exact
provider read. The caller never resupplies an account, network, conversation
ID, name, handle, title, or participant match. Preview is draft-only until the
owner reviews the exact private recipient and bubbles and makes a fresh
same-turn send request.

Read the focused [Beeper guide](https://wrench.rip/providers/beeper/) for setup,
version identities, action boundaries, export workflows, and exclusions.

## Important limitations

- Wrench is not an AI agent, hosted API, model, planner, approval interface, or
application shell. The caller owns those layers.
- Authenticated provider operations stay unavailable until their exact local
dependency, account binding, and installed contract are ready.
- Media acquisition accepts one authorized, accessible, finite, non-DRM item.
It rejects playlists, live streams, affirmative DRM, unsupported
authentication, and access-control bypasses.
- Source plugins are trusted in-process code. Portable-plugin process
separation contains ordinary failures and is not a hostile-code sandbox.
- Consequential writes require an exact preview and durable dispatch evidence.
A partial or indeterminate dispatch remains unsettled and is not retried.

Read [SECURITY.md](SECURITY.md) for the complete trust boundary and
[`DISCLOSURE`](DISCLOSURE) for the authorization and dual-use boundary.

## SDK and code mode

For that same released coordinate, install Wrench in an agent or application
Expand Down Expand Up @@ -1151,7 +1173,7 @@ platforms while preserving per-provider attachment limits and at-most-once
dispatch evidence. Packages built from this source carry the same consolidated
skill as the skills CLI.

## Risk and confirmation
## Trust, risk, and confirmation

- R1 is a reviewed read with no intended remote mutation.
- R2 is one bounded, normally reversible change.
Expand Down Expand Up @@ -1194,7 +1216,7 @@ directs the operator to `wrench doctor`, the exact predecessor build, or manual
evidence review. Runtime loading still verifies the current exact source,
dependency, and execution closure separately.

## Develop
## Verification

```sh
git clone https://github.com/hraness/wrench.git
Expand Down
21 changes: 21 additions & 0 deletions website/site.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ describe("wrench.rip static site", () => {
readFile(join(repositoryRoot, "middleware.ts"), "utf8"),
]);
const html = pages[0]!.html;
const searchableHtml = html.replace(/\s+/gu, " ");
const cssAsset = /<link rel="stylesheet" href="([^"?]+)">/u.exec(html)?.[1];
expect(cssAsset).toMatch(/^\/assets\/styles-[a-f0-9]{12}\.css$/u);
const builtCss = await readFile(join(websiteRoot, "dist", cssAsset!.slice(1)), "utf8");
Expand Down Expand Up @@ -213,6 +214,10 @@ describe("wrench.rip static site", () => {
expect(html).toContain('href="/paypal-grapheneos-attestation/"');
expect(html).toContain('href="/providers/beeper/"');
expect(html).toContain("Give your coding agent bounded access to the web.");
expect(searchableHtml).toContain(
"An agent asks for a named outcome; Wrench binds it to one reviewed provider",
);
expect(html).toContain("Use <code>wrench read https://example.com/article</code> as the smallest first run");
expect(html).toContain("Work with the services you already use.");
expect(html).toContain('class="wordmark" href="/">Wrench</a>');
expect(html).not.toMatch(/hero-field|hero-orbit|hero-glyph/u);
Expand Down Expand Up @@ -892,6 +897,22 @@ describe("wrench.rip static site", () => {
"[built-in Beeper Desktop MCP server](https://developers.beeper.com/desktop-api/mcp/)",
);
expect(readme).not.toContain("https://github.com/beeper/desktop-api-mcp");

const readerPath = [
"## Why Wrench is different",
"## Install",
"## What Wrench does",
"## Built-in provider catalog",
"## Important limitations",
"## SDK and code mode",
"## Trust, risk, and confirmation",
"## Verification",
].map((heading) => readme.indexOf(heading));
expect(readerPath.every((position) => position >= 0)).toBe(true);
expect(readerPath).toEqual([...readerPath].sort((left, right) => left - right));
expect(readme.indexOf("wrench read https://example.com/article")).toBeLessThan(
readme.indexOf("## SDK and code mode"),
);
});

test("ships a correctly sized original social card", async () => {
Expand Down
6 changes: 4 additions & 2 deletions website/source/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ <h1 id="brand-name">Give your coding agent bounded access to the web.</h1>
<p class="hero-explainer">
Wrench is a local CLI and TypeScript SDK for capturing public pages,
preserving finite media, and using supported actions in connected
services. You bring the model and interface.
services. You bring the model and interface. An agent asks for a
named outcome; Wrench binds it to one reviewed provider, transport,
account realm, contract, implementation, and risk level.
</p>
<div class="action-row">
<a class="button button-primary" href="#start">Install Wrench</a>
Expand Down Expand Up @@ -119,7 +121,7 @@ <h1 id="brand-name">Give your coding agent bounded access to the web.</h1>
<li><span aria-hidden="true">01</span><code>{{WRENCH_INSTALL_COMMAND}}</code></li>
<li><span aria-hidden="true">02</span><code>wrench doctor</code></li>
</ol>
<p>Install the CLI and SDK from the <a href="{{WRENCH_NPM_PACKAGE}}"><code>@hraness/wrench</code> package on npm</a>, then run <code>wrench doctor</code> in the project where your agent will work.</p>
<p>Install the CLI and SDK from the <a href="{{WRENCH_NPM_PACKAGE}}"><code>@hraness/wrench</code> package on npm</a>, then run <code>wrench doctor</code> in the project where your agent will work. Use <code>wrench read https://example.com/article</code> as the smallest first run; it returns readable page content without saving it.</p>
</div>
</div>
</section>
Expand Down
Loading