Metadata-Version: 2.4
Name: tether-chat
Version: 2026.37
Summary: Local-first task and action-item assistant
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Requires-Dist: fastapi<1,>=0.115
Requires-Dist: httpx<1,>=0.27
Requires-Dist: tzdata>=2024.1
Requires-Dist: uvicorn<1,>=0.30
Requires-Dist: mcp<2,>=1.2
Requires-Dist: keyring<27,>=25
Requires-Dist: markdown-it-py<5,>=3
Requires-Dist: nh3<1,>=0.2
Requires-Dist: plyer<3,>=2.1
Requires-Dist: psutil<8,>=5.9
Requires-Dist: Pillow<13,>=10
Requires-Dist: python-multipart<1,>=0.0.18
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: httpx>=0.27; extra == "dev"
Provides-Extra: desktop
Requires-Dist: pywebview<7,>=5; extra == "desktop"
Requires-Dist: pystray<1,>=0.19; extra == "desktop"

# tether-chat

[![PyPI version](https://img.shields.io/pypi/v/tether-chat)](https://pypi.org/project/tether-chat/)

A local-first assistant for tasks, action items, and things worth remembering. Talk naturally; your work and conversation stay in a local SQLite database.

![tether-chat conversation](https://raw.githubusercontent.com/briday1/tether-chat/main/docs/screenshots/conversation.png)

## Browser app

[Open tether in your browser](https://briday1.github.io/tether-chat/) — including on your phone. On iPhone, open it in Safari and choose **Share → Add to Home Screen**.

The browser edition runs on your device, with no tether server or Python installation. Enter your own API endpoint, model, and key in Settings. Your provider must allow browser requests (CORS). Tasks, action notes, conversations, and calendars stay in this browser; saved tasks work offline after the app has loaded once. AI requests still need internet.

Keys can stay in your browser session or be saved encrypted with an unlock passphrase. Download portable backups from Settings: clearing website data removes browser tasks. Desktop and browser data are independent; they do not sync automatically. Closed-app reminders, the local MCP server, and database folder selection belong to the desktop edition.

Both editions are released from this repository. [Browser setup, backups, and development](docs/BROWSER.md).

## Install

Requires Python 3.11 or newer. No PyInstaller build or separate Windows `.exe` installer is required.

Install the desktop app from [PyPI](https://pypi.org/project/tether-chat/):

```sh
uv tool install --reinstall "tether-chat[desktop]"
tether-chat-desktop
```

The install exposes only **`tether-chat`** and **`tether-chat-desktop`**. On Windows, `tether-chat-desktop` opens a native WebView2 window and remains in the tray after the window closes. Choose **Open tether-chat** to return or **Exit tether-chat** to stop it. The Microsoft Edge WebView2 Runtime is required. macOS and Linux open the browser UI and use a tray/menu-bar entry where supported by the desktop environment.

**Browser/server mode:**

```sh
pip install tether-chat
tether-chat serve --port 9000 --mcp-port 9001
```

Without custom ports, the browser UI is at `http://127.0.0.1:8765` and the local MCP server is at `http://127.0.0.1:8766/mcp`. Use `--no-browser` to start without opening a window. Both services are local-only; Ctrl+C stops a terminal-launched server.

**Optional desktop shortcut:**

```sh
tether-chat desktop install
tether-chat desktop install --destination "/path/to/shortcuts"
```

The default destination is your operating system's Desktop folder. Windows gets an icon-branded `.lnk`, macOS a `.command` launcher, and Linux a `.desktop` entry. Keep the Python/uv environment that the shortcut references. Linux may require marking the launcher trusted. Add `tether-chat-desktop` to your OS login/startup applications to launch at sign-in; installing it does not enable startup automatically.

For desktop installation with pip, use `pip install "tether-chat[desktop]"`.

## Set up and use

Open **Settings → AI connection**, enter your provider's HTTPS API base URL, model, and API key, then save and test. The provider must support OpenAI-compatible chat-completions tool calling. Desktop keys use the operating system's credential vault; they are not stored in your task database.

**Conversation:** Describe work to track, ask for an update, or record feedback. You can switch to Tasks while a reply is running. Requests are queued on the local server, and returning to Conversation restores their progress or completed replies. Use **Stop** to end the current request, or type more context and choose **Interrupt** to stop it before continuing with your new message. Completed changes remain saved; stopping cannot undo an operation already underway. Chat provider requests have no Tether elapsed-time limit, though provider and network limits still apply. A full server shutdown interrupts in-flight requests rather than automatically repeating potentially mutating operations.

Replies use the same Note style in desktop and browser: natural update paragraphs, quiet task links, compact rows for rollups, and grouped category or activity sections. Known dates stay separate from next actions, and rows stack on phones. Local commands use this presentation without an AI call. Short confirmations stay short; older task-linked lists also receive the shared styling.

**Repeating tasks (Home and Work):** Open a task in Tasks, choose **Repeat**, set its next occurrence, and optionally choose an inclusive end date. Display and chat snapshots show scheduled occurrences throughout the visible date range, without making duplicate tasks. Completing an occurrence records it and advances the same task; after the final occurrence its next date is cleared. Monthly schedules retain their original day (January 31 → February 28 → March 31), and schedules saved with a timezone keep their local time across daylight saving changes.

**Assistant decisions:** Tasks get a suitable existing or new category, and follow-ups reuse the focused task. Open-ended reminders use saved defaults (Monday, morning 09:00, night 21:00), editable in Settings. Snapshots include task and action reminders as well as deadlines. Address lookup asks for confirmation before searching and lets you save the chosen location with a Google Maps link. See [browser behavior](docs/BROWSER.md#decisions-categories-and-reminder-defaults).

**Voice input:** Click the borderless microphone to start; it changes color while listening. Words appear in the message box as you speak. Click again to stop and keep the text, or × to discard that dictation. Both editions use open-source Vosk on your device, without a provider audio endpoint or API key. English speech files download once (about 45 MB) and are cached for offline use. In **Settings → Voice input**, optional Browser dictation uses your browser’s supported languages and may use its speech service. Review and send the draft when ready.

**Tasks:** Browse **Categories → Tasks → Action items**. Each task may have several categories and several action items. Individual action items have their own due date and **Bring to attention** time. Click an action row to open its details drawer, including its own notes. Add, edit, or remove a note there; notes stay attached to that action and are included in its check-in context.

Check off tasks and action items directly in the list. A task checkbox completes the whole ordinary task and its unfinished actions, moves it to Archive, and offers **Undo**. An action checkbox completes only that action. For a repeating task, the task checkbox completes the displayed occurrence and keeps the series. Saving failures leave the item available to retry.

**Attention:** Click an item or focus it and press Enter. This sends a contextual check-in to Conversation and asks for your update; it does not silently mark anything complete or change dates. Action-item attention stays scoped to that action, rather than its siblings or category.

The selected task and action remain visible above the composer for your reply. **“Let's do that tomorrow”** saves a deferral directly when one selected target is clear; it removes that item from Attention until tomorrow at your saved morning time. The action's notes, dates and recent activity remain available to the assistant. Clear the context chip to stop targeting that item. The assistant can also retrieve full action context, search older conversation, edit existing tasks/actions, defer, complete, reopen and restore through explicit tools.

| Field | Meaning |
| --- | --- |
| Due date | The actual deadline. Deferring attention preserves it. |
| Bring to attention | When to show a reminder. |
| Deferred until | Suppresses current attention and notifications until this time, including an overdue deadline. A task deferral also quiets its actions; an action deferral affects only that action. |
| Next occurrence | The repeating cycle. Completing one occurrence advances the series without duplicating tasks. |

Use **Tomorrow** or **Resume attention** in task/action details for the same changes without chatting. Calendars and details retain the true deadline while an item is deferred. New dates, deferrals and completion state survive backups and Home sharing.

Attention updates automatically after saves, notes, and chat changes. Completed or rescheduled items reflect their current state; other-tab and outside changes appear within a few seconds while Conversation is visible. Automatic refresh reads saved records; the ↻ button asks AI to reconsider. Completed or deferred child actions do not keep a parent in AI-selected Attention. Explicit parent reminders and deadlines remain independent. A future Bring to attention time is respected even for a recurring task; projected future occurrences stay on calendars without becoming attention now. New repeating reminders use the occurrence itself for attention, rather than leaving a duplicate one-shot reminder behind. Existing separate parent reminders are preserved unless explicitly changed to occurrence-based attention. Completing a cycle reports the completed date separately from the next occurrence, and repeating that completion does not consume the next cycle. Updating a task clears any stale AI suggestion for it while retaining reminders that are still due.

**Calendars:** Ask “give me my next week snapshot” or use `/snapshot last month`. The calendar appears inside chat with transparent cells and category colors. Week snapshots keep expanded task cards: Monday–Friday remain visible, with weekends added when they contain items. Chat month snapshots show up to three compact markers per date plus an overflow count. Click, tap or activate a date with the keyboard to read every item in the adjacent date panel; it returns to Today after 15 seconds of inactivity. Scrolling or interacting with the panel gives you another 15 seconds. Display fits its month grid to the screen and fills each date with as many readable task rows as its size allows. Wider cells show titles and available context; narrow cells use compact markers. An overflow count appears only for items that cannot fit, with space reserved so it remains visible. Calendars refresh local data automatically without calling an AI model.

**Archive:** Finished nonrecurring tasks archive automatically once no unfinished actions remain, including eligible tasks completed in older versions. Checking an individual action does not assume its whole subject is finished. Active recurring responsibilities remain active. Put inactive tasks away manually or restore completed tasks from **View archive**; restoration reopens them and keeps their notes/history. Undoing whole-task completion reopens only the actions completed with that task, preserving actions you had already completed separately.

If a previous server or another program occupies a service port, the launcher selects available local ports and opens the correct address. It remembers the successful ports for the next launch and reuses a compatible running tether. Child services load the installed package even when launched from an older source checkout. Your database and AI settings keep their existing location. The actual web and MCP addresses are printed in server mode and recorded in `~/.tend/launch-ports.json`.

## Update

Choose **Exit tether-chat** in the tray before replacing a running installation:

```sh
uv tool upgrade tether-chat
```

Run `tether-chat desktop install` again to refresh an existing shortcut. Existing data and provider settings remain in `~/.tend`; this does not install a legacy `tend` command.

## Releases

Main releases use **YYYY.sequence**: `2026.1`, `2026.2`, and so on, restarting at `2027.1` in the next year. `python scripts/bump_version.py` updates both package and runtime versions. Commit that version bump with the main update; a separate manual publish is not required.

The main release workflow validates the version, runs Windows/macOS/Linux tests and isolated installations, checks browser interactions, builds the wheel and source archive, creates the versioned GitHub release, and attempts PyPI publication using `PYPI_API_KEY`. It confirms the uploaded version before reporting PyPI success.

A separate **Browser app and GitHub Pages** workflow builds and tests the standalone browser edition and publishes it to Pages. It uses the same version, interface, AI prompt, and tool declarations as desktop. Browser publication is independent of the PyPI upload.

## More screenshots

These desktop screenshots use synthetic example data, never your personal tasks.

**Categories and tasks**

![Category buttons and task list](https://raw.githubusercontent.com/briday1/tether-chat/main/docs/screenshots/tasks.png)

**Action items in the third column**

![Categories, tasks, and clickable action items](https://raw.githubusercontent.com/briday1/tether-chat/main/docs/screenshots/task-action-columns.png)

**Details in a chat drawer**

![Action details in a themed chat drawer](https://raw.githubusercontent.com/briday1/tether-chat/main/docs/screenshots/chat-action-drawer.png)

**Week and month calendars**

![Week calendar inside chat](https://raw.githubusercontent.com/briday1/tether-chat/main/docs/screenshots/snapshot-week.png)

![Month calendar inside chat](https://raw.githubusercontent.com/briday1/tether-chat/main/docs/screenshots/snapshot-month.png)

**Task details and archive**

![Task details](https://raw.githubusercontent.com/briday1/tether-chat/main/docs/screenshots/task-details.png)

![Archived tasks](https://raw.githubusercontent.com/briday1/tether-chat/main/docs/screenshots/archive.png)

## More information

See [development and troubleshooting](https://github.com/briday1/tether-chat/blob/main/docs/DEVELOPMENT.md) for database backups, MCP configuration, and server setup. The repository also includes a [snapshot skill](https://github.com/briday1/tether-chat/blob/main/skills/tether-snapshot/SKILL.md) for compatible AI clients. Screenshots are regenerated by the screenshot workflow.

### One brand, separate applications

**tether** is the shared brand. **tether-chat** is the installed, Work-only
application. **tether-home** is the browser, Home-only application for chores,
appointments, classes and grocery lists. There is no mode switch between them.
Both have Conversation, Tasks and a persistent Display calendar.

Existing installed Work data stays in its original database. The browser keeps
Home data local. Older browser Work storage is not opened or shared, and is not
exposed through Home settings. This update does not delete that legacy storage. See
[browser details](docs/BROWSER.md) and [sharing details](docs/DRIVE_SYNC.md).

### Optional household sharing

[Google Drive Home sharing](docs/DRIVE_SYNC.md) is an experimental, safety-gated
integration: each device keeps local data and appends Home task changes to a selected shared Google Sheet
in Drive. It does not share Work data, private chats, or provider credentials.
In tether-home, Create/Join household guides sharing and conflict resolution without a Tether
backend. Google account setup, selected-file permissions and a real two-account
validation are required; automated mocks are not a claim of live Google validation.
