Metadata-Version: 2.4
Name: wondersearch-cli
Version: 0.2.2
Summary: Command-line client for WonderSearch
License-Expression: Apache-2.0
License-File: LICENSE
Requires-Python: >=3.10
Requires-Dist: certifi>=2026.10.19
Requires-Dist: httpx<1,>=0.27
Requires-Dist: keyring<26,>=25
Requires-Dist: packaging<27,>=24
Provides-Extra: dev
Requires-Dist: build<2,>=1.2; extra == 'dev'
Requires-Dist: hatchling<2,>=1.26; extra == 'dev'
Requires-Dist: mypy<2,>=1.15; extra == 'dev'
Requires-Dist: pytest<10,>=8; extra == 'dev'
Requires-Dist: ruff<1,>=0.11; extra == 'dev'
Requires-Dist: twine<7,>=6; extra == 'dev'
Description-Content-Type: text/markdown

# WonderSearch CLI

Upload your documents and search them from the terminal.

## Install

Requires Python 3.10–3.14 on macOS, Windows, or Linux.

Before installing or upgrading packages, activate a project virtual environment
and check `python -m pip --version`. Pip must be 26.2.2 or later. Older pip
retains affected emSign roots in its own CA bundle, even after Certifi or system
certificate updates. If needed, first use the SHA-256-pinned direct-wheel
bootstrap in the [official Python security notice](https://discuss.python.org/t/information-for-python-users-regarding-emudhra-emsign-ca-certificate-security-incident/109576),
then check the pip version again. Repeat this after creating a new environment.

With patched pip, install the CLI from PyPI:

```sh
python -m pip install wondersearch-cli
```

The CLI requires Certifi 2026.10.19 or later. After patching pip, update existing
pip environments with `python -m pip install --upgrade 'certifi>=2026.10.19'`.
For an existing pipx installation, check
`pipx runpip --skip-maintenance wondersearch-cli --version`. If pip is older,
use the notice's pinned bootstrap command with
`pipx runpip --skip-maintenance wondersearch-cli` in place of `python -m pip`,
then verify pip again before running
`pipx runpip --skip-maintenance wondersearch-cli install --upgrade 'certifi>=2026.10.19'`.
Check Certifi with `python -m pip show certifi` or the same pipx prefix followed
by `show certifi`. Custom CA bundles need a separate update.

## Sign in

Set up your WonderSearch account in the Console, then run:

```sh
wondersearch login
```

Your browser will open. Check that the verification code matches the one in your
terminal, then sign in and choose **Connect CLI**. If you are already signed in,
you can connect that account directly.

If the browser does not open, run `wondersearch login --no-browser` and open the
printed link on the same computer.

## Choose where to work

List your workspaces and drives, then select the ones you want to use:

```sh
wondersearch workspace list
wondersearch workspace use WORKSPACE_ID
wondersearch drive list
wondersearch drive use DRIVE_ID
```

Replace `WORKSPACE_ID` and `DRIVE_ID` with IDs from the lists. The CLI remembers
your selections for later commands.

## Upload documents

Upload a file:

```sh
wondersearch upload ./guide.pdf --wait
```

Or upload a folder and its contents:

```sh
wondersearch upload ./docs --recursive --wait
```

Supported formats are PDF, Word (.docx), plain text, and Markdown. `--wait` keeps
the command running until your documents are ready to search.

Each drive holds at most 1,000,000 documents and 100 GB of files; a single file
can be up to 1 GB. `wondersearch limits` shows the values the service currently
enforces. Uploads of 1,000 or more files, or 1 GB or more, are checked against
them before any transfer. The service enforces the limits either way and
answers `drive_limit_exceeded` when a drive would grow past them.

An upload of more than 1,000 files, or more than 1 GB, sends its UTF-8 text and
Markdown files as one import (see below) and uploads the other files as usual.
Imported documents are not placed in folders; each one keeps its path in
`metadata.path`. The import may take up to 86,400 seconds unless you set
`--timeout`. Add `--no-import` to upload every file separately. Uploads to an
explicit `--folder`, replacements and hidden paths always upload separately.

Uploads stream up to six files concurrently. When the server supports batch
uploads, the CLI reuses transfer destinations and batches completion and status
checks. Interrupted uploads retain their run ID for safe resumption.

To preview a folder upload without sending files:

```sh
wondersearch upload ./docs --recursive --dry-run
```

WonderSearch selects the search model; there is no CLI model-selection
option, and `wondersearch search` sends no model field. The response's `model` field identifies the model actually used. The server
enforces the active model's token limit and the 16,384 UTF-8 byte limit.
Search returns at most 10 results; `search --limit` is not supported.
Use `--no-group-by-document` to allow multiple
passages per document, or `--group-by-document` to group them. `--timeout-ms`
sets a server deadline from 1 to 20,000 milliseconds; omission uses the effort
default configured by the server. This deadline is distinct from upload and
processing timeouts.

Uploading the same file again creates another document. To update an existing
document, use `wondersearch upload ./guide.pdf --replace DOCUMENT_ID --wait`.

If an upload is interrupted, use the run ID printed in the terminal to resume it:

```sh
wondersearch upload resume RUN_ID --wait
```

## Import a large text collection

`wondersearch import` sends many UTF-8 `.txt` and `.md` files to a drive in
large chunks, then waits until they are searchable:

```sh
wondersearch import ./corpus --drive DRIVE_ID --dry-run
wondersearch import ./corpus --drive DRIVE_ID
```

Directories are read recursively. Hidden paths and symbolic links are skipped,
and so are other formats; upload PDF and Word files with `wondersearch upload`.
Files of up to 31,983,616 bytes fit in one import chunk; larger files are
reported, so upload them with `wondersearch upload`. Files that are not valid
UTF-8 text are reported and left out.

`--dry-run` reads the files and reports the documents, chunks and drive limit
check without changing anything. Before an import starts, its totals are
checked against `wondersearch limits`; the service enforces the limits either
way.

The command prints its progress while it uploads, then while the documents
become searchable, and closes the import when everything is searchable. Each
document's `metadata.path` holds its path, starting with the name of the file or
directory you named, and its external ID starts with the import ID.

To reduce the number of documents in a collection of small files, combine them:

```sh
wondersearch import ./notes --drive DRIVE_ID --combine-bytes 100000
```

Consecutive files smaller than the given size (at most 1,000,000 bytes) join,
separated by a blank line, into documents of about that size.
`metadata.combined_files` is a string holding a JSON list of each file's path,
byte offset and length in the combined document.

If an import is interrupted or times out, run the same command with
`--resume`. It continues from a journal saved in the CLI configuration
directory, which holds no credentials, transfer addresses or document text.
Keep the files unchanged until the import completes. If documents fail to
become searchable and can be retried (`import_operations_failed`), run the same
command with `--resume --retry-failed`. If part of an import fails for good
(`import_failed`), the CLI closes it and lists the affected files in the error.

While an import is processing, other changes to the same drive can be refused
temporarily. Retry them after the import completes.

## Search

Ask a question about the documents in your selected drive:

```sh
wondersearch search "How do I reset my password?"
```

To search a specific folder, add `--folder FOLDER_ID`.

## Other useful commands

| Task | Command |
| --- | --- |
| Check which account is signed in | `wondersearch whoami` |
| List documents | `wondersearch document list` |
| List folders | `wondersearch folder list` |
| Create a folder | `wondersearch folder create "Research"` |
| Check account usage | `wondersearch usage` |
| Check storage | `wondersearch storage` |
| Show drive and file limits | `wondersearch limits` |
| Import many text files | `wondersearch import PATH --drive DRIVE_ID` |
| Sign out of the CLI | `wondersearch logout` |
| Update the CLI | `wondersearch update` |

Signing out of the CLI leaves you signed in to the Console.

## Stay up to date

```sh
wondersearch update --check
wondersearch update
```

`wondersearch update` upgrades the CLI with pipx or pip, whichever installed
it, to the current release the service publishes. It needs no sign-in while
the service's release information is reachable; otherwise it reads the release
from your signed-in account. On first
start and then once a day, the CLI reads the service's public release
information (never a package registry) and prints a notice when an update is
available, such as `wondersearch-cli 0.2.2 is available (installed 0.2.1). Run:
wondersearch update`. Below the minimum supported version it updates itself and
runs your command again. Set `WONDERSEARCH_AUTO_UPDATE=1` to always install new
releases automatically, or `WONDERSEARCH_NO_UPDATE_CHECK=1` to turn the check
off. If the release information cannot be reached, commands run as usual.

The CLI upgrades only the `wondersearch-cli` package. If the CLI is ever
published under another name, it prints how to install it instead of running
anything.

Deprecation and release notices from the service are printed at most once a day
and are always included in `--json` output. `--no-update-notice` hides them in
the terminal.

## Use in scripts

Add `--json` to a command for output your script can read:

```sh
wondersearch search "What is our refund policy?" --json
```

For automation, sign in with an API key using `wondersearch login --api-key`.
Paste the key at the hidden prompt. API keys can only access the workspace and
actions they have permission to use.

## Get help

Use `--help` to see the available commands and options:

```sh
wondersearch --help
wondersearch upload --help
wondersearch import --help
wondersearch search --help
```

## Contributing

To install from source, run this command from the repository root in an active
Python virtual environment:

```sh
python -m pip install .
```
