# How Sponge imports Ghostget captures offline

Sponge's Ghostget importer reads a text-only capture you already saved and never starts Ghostget, a browser, or a network request.

By Hraness · Published 2026-09-24

Drafted with AI from the source code and reviewed by Claude Opus 5.5 (claude-opus-5-5) editorial review.

Say a source you are allowed to read sits behind an account you hold, or only renders in a real browser. You can open it. Your research tool, running on someone else's server, cannot. The usual fix is to give that tool your login and let it browse for you, which puts a second copy of your access somewhere you do not watch.

With Sponge, you capture the page yourself on your own machine with Ghostget, and Sponge imports the saved text from a file. The importer never launches Ghostget, never opens a browser, and never makes a network request. It only reads what you already have.

## Keeping a source you can already read

You have read a source, a few passages matter, and you want those passages in Sponge as evidence your agent can cite, with a trail back to where they came from. You do not want Sponge to hold your passwords, and you do not want an agent to go browsing under your name to fetch something you have already fetched.

Sponge's hosted saving covers public pages, PDFs with extractable text, and supported text files. It does not sign in to websites or render pages in a browser. For anything else, you capture the page locally.

## What Ghostget does

[Ghostget](https://ghostget.com) is a local tool that captures web pages as Markdown on your own computer. It keeps its own accounts, permissions, and provider plugins. Signed-in capture works only for services Ghostget supports, and only after you connect that account in Ghostget; installing Ghostget does not grant access to anything. If Ghostget cannot reach a source, record it as a gap in your research and do not try to work around it. A capture produces a small folder: the page's text as a Markdown file, plus a short description file recording where the text came from, when it was captured, how long it is, a fingerprint of its exact bytes, and whether the capture was complete or partial.

Sponge uses the text-only capture, which leaves out images, media, screenshots, and page source:

```sh
ghostget capture https://example.org/study study \
  --media none --evidence none --output /absolute/private/captures --json
```

That writes a folder named after the slug, holding the description file and `study.md`. Ghostget's `read` command shows a page without saving it, and its JSON output is a summary without the saved text, so Sponge cannot import it.

## How Sponge reads a capture

Sponge's own rules split the work: Ghostget owns getting the source, the accounts, and the credentials; Sponge accepts explicit evidence you hand it in a versioned file format. Those rules forbid adding browser credentials, signed-in web requests, or an agent loop at that seam, and the importer accepts no cookies, passwords, or Ghostget grants.

The importer is a command you run from a Sponge repository checkout. It takes three things you control:

1. The capture folder Ghostget wrote.
2. A short selection file you write after reading the text: an ID, your own label for the source, and one to ten exact passages with their positions.
3. A private output folder and a new file name.

A selection file looks like this, with a passage you actually read in place of the placeholder:

```json
{"v":1,"id":"study","title":"Reef survey methods","excerpts":[{"start":0,"end":3,"exact":"..."}]}
```

Then the import:

```sh
bun run scripts/research-ghostget.ts import \
  /absolute/private/captures/study /absolute/private/selection.json \
  /absolute/private/output study.json
```

Before it writes anything, the importer checks these rules, paraphrased here from the code:

```text
byte length(saved text)        == the byte length the capture recorded
SHA-256(saved text)            == the SHA-256 the capture recorded
saved text                     ends with a newline
text[start, end) for a passage == the passage you typed, exactly
the output file                does not exist yet
```

If the text was edited after capture, the length or fingerprint no longer matches and the import stops. If a passage is off by one character, it stops. It also refuses captures that include images or media, captures in a format version it does not know, files that are too large, and files reached through symbolic links or hard links or that change while being read. On macOS and Linux the folders must be private to you, and so must the selection file. It refuses a capture that is too large and never cuts it short. It will not overwrite an existing output file.

The importer's reading code has no way to start a process, reach the network, or look up Ghostget's own state or credentials. It opens the files you named and writes one new file.

## What you get out of it

The output is a single private file holding one evidence entry and a record of where it came from: the source address, the capture date, whether the capture was complete or partial, any warnings Ghostget recorded, the text's byte length and fingerprint, and a fingerprint of the capture's description file. The full saved text is kept unchanged alongside your chosen passages. Ghostget's diagnostic attempts and your local folder paths are left out.

You add that evidence entry to your local research files, then validate and export them with Sponge's local research commands. From there your agent can cite the passages you chose, and the exact text you captured stays with the evidence, so each cited passage can be checked against it. When the evidence needs to go into a Sponge document, you use Sponge's ordinary library import and passage-copy tools; the importer is not a new upload route.

## What the import does not prove

A matching fingerprint shows that the text you imported is the text the capture recorded. It does not show that the capture is authentic, that the original page was complete, or that the passages support any particular claim. A capture marked partial stays marked partial, and its warnings travel with the evidence so a later reader can see them. The import works only with Ghostget's text-only captures, only from a repository checkout, and only one capture at a time. Selected text may itself be private, so review what you move into Sponge or share.

[Status and limits](https://sponge.computer/docs/status) lists which Sponge features work today and which are still being checked. For the wider picture of what Sponge is for, read [Introducing Sponge](https://sponge.computer/docs/introducing-sponge); other products that build on Ghostget are listed on [Built on Ghostget](https://ghostget.com/blog/built-on-ghostget).

## Sources

- [Ghostget README](https://github.com/hraness/ghostget/blob/76a79fc/README.md), checked 2026-09-24
- [Sponge research skill](https://sponge.computer/skills/sponge-research/SKILL.md), checked 2026-09-24
- [Status and limits](https://sponge.computer/docs/status), checked 2026-09-24
