add alias to avoid explicit python commands, scheduled runs and bug fixes

This commit is contained in:
JesseMarkowitz
2026-08-18 09:59:15 -04:00
parent fe5ed341ad
commit 999429f61e
9 changed files with 737 additions and 8 deletions
+108 -8
View File
@@ -32,10 +32,31 @@ This tool is designed for a single user backing up their own conversations. Do n
```bash
git clone <repo-url>
cd ai-chat-exporter
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
cd AIChatExporter
./ai-chat-exporter doctor
```
That's the whole install. The `ai-chat-exporter` wrapper creates `.venv` and
installs dependencies on first run, and reinstalls whenever `pyproject.toml`
changes — so there is no `python3 -m venv` / `source .venv/bin/activate` to
remember, on this machine or the next one you clone onto. Every command in this
README works the same way:
```bash
./ai-chat-exporter export --provider all
./ai-chat-exporter sync
```
The wrapper does **not** change directory: `.env`, `cache/` and `exports/` all
resolve against your current directory, which is what lets one checkout archive
different machines into different places. Run it from the repo. (It warns if you
don't, because a different working directory means a different `cache/manifest.json`
— which would re-export everything and orphan your existing Joplin notes.)
Prefer the traditional route, or want the test dependencies? That still works:
```bash
python3 -m venv .venv && source .venv/bin/activate && pip install -e ".[dev]"
```
### Windows
@@ -44,12 +65,28 @@ No admin access required. Run these in **Command Prompt** (`cmd.exe`) — it's t
```bat
git clone <repo-url>
cd ai-chat-exporter
python -m venv .venv
.venv\Scripts\activate
pip install -e ".[dev]"
cd AIChatExporter
ai-chat-exporter doctor
```
`ai-chat-exporter.cmd` does the same bootstrap as the POSIX wrapper — it creates
`.venv` and installs dependencies on first run. No `python -m venv`, no
`.venv\Scripts\activate`.
**How you invoke it differs between the two Windows shells:**
| Shell | Command |
|---|---|
| Command Prompt (`cmd.exe`) | `ai-chat-exporter export --provider all` |
| PowerShell | `.\ai-chat-exporter.cmd export --provider all` |
`cmd.exe` searches the current directory before `PATH` and resolves the bare name
through `PATHEXT`, so it finds `ai-chat-exporter.cmd` with no prefix and no
extension. PowerShell deliberately does *not* search the current directory, and
`.\ai-chat-exporter` there would resolve to the extensionless POSIX script, which
PowerShell cannot execute — so name the `.cmd` explicitly. Command Prompt is the
simpler of the two here.
All `ai-chat-exporter` commands work identically in Command Prompt.
**Using PowerShell instead?** If you prefer PowerShell, you may need to allow script execution first (one-time, current user only):
@@ -284,6 +321,69 @@ Three things differ from Claude Code, all forced by how Codex stores its data:
---
## Scheduling a Daily Run
`sync` chains `export` then `joplin` in one invocation, which is what a scheduler
wants — one command, and a meaningful exit code so a failed run is visible
instead of silent.
```bash
./ai-chat-exporter sync # every configured provider
./ai-chat-exporter sync --provider codex # just one
```
### Linux (systemd user timer)
```bash
./scheduling/install-systemd-timer.sh --provider claude-code --provider codex
./scheduling/install-systemd-timer.sh --uninstall
```
Defaults to 09:00 daily (`--time 21:30` to change). `Persistent=true` means a
machine that was off at the scheduled time runs the archive at next boot rather
than skipping the day. To archive while logged out, `loginctl enable-linger $USER`.
Check on it with `systemctl --user list-timers aichat-sync.timer` and
`journalctl --user -u aichat-sync.service -n 50`.
### Windows (Task Scheduler)
```powershell
.\scheduling\Register-AiChatSyncTask.ps1 -Provider chatgpt,claude
.\scheduling\Register-AiChatSyncTask.ps1 -Unregister
```
Per-user task, no admin rights needed. `-StartWhenAvailable` is the counterpart
of systemd's `Persistent=true`.
### What to know before you rely on it
**List only the providers that work unattended on that machine.** The local
providers (`claude-code`, `codex`) need no credentials and always work. The web
providers depend on a session token that expires and can only be refreshed by
hand via DevTools — so on a machine where that token is stale, scheduling them
means a failed run every single day, which is a good way to learn to ignore
failures you actually want to see. That is why `--provider` is repeatable in both
installers: schedule the coding machine for `claude-code` + `codex`, the browser
machine for `chatgpt` + `claude`.
**Both installers pass `--joplin-optional`.** If Joplin desktop isn't running,
the sync warns instead of failing: the export has already captured the local
transcripts (the part that can disappear), and the notes are rebuilt from the
cache on the next run that finds Joplin up.
**One provider failing does not skip the rest.** Both installers loop over the
providers in a single action rather than one action each, because systemd
`oneshot` stops at the first failing `ExecStart` and Task Scheduler reports only
the last action's result. Every provider is attempted; the run still exits
non-zero if any failed.
**Acknowledge the ToS notice once, interactively.** It's stored in the cache
manifest per machine. Until then a scheduled run exits 1 with an explanation
rather than hanging on a prompt no one can answer.
---
## Output Structure
All exported files go under `EXPORT_DIR`. The folder structure maps directly to Joplin notebooks.