catence 0.2.0-beta.3 → 0.2.0-beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -22,7 +22,7 @@ Catence helps explore recovery, training load, trends, activity detail, swimming
22
22
 
23
23
  ## Quick start
24
24
 
25
- Install Catence and create the first athlete. The default catalog home is `~/.catence`; set `CATENCE_HOME` or pass `--home` to use a different location.
25
+ Install Catence and create the first athlete. The default catalog home is `~/.catence`; set `CATENCE_HOME` or pass `--home` to use a different location. For the full local or Docker deployment walkthrough, see [deployment notes](docs/deployment.md).
26
26
 
27
27
  ```sh
28
28
  npm install --global catence@0.2.0
@@ -3,7 +3,7 @@
3
3
  * Keep these values synchronized with release/manifest.json; release checks
4
4
  * deliberately reject drift before a package can be published.
5
5
  */
6
- export declare const CATENCE_RUNTIME_VERSION = "0.2.0-beta.3";
6
+ export declare const CATENCE_RUNTIME_VERSION = "0.2.0-beta.5";
7
7
  export declare const CATENCE_PROTOCOL_VERSION = 1;
8
8
  export type CatenceRuntimeCapabilities = {
9
9
  mcp: true;
@@ -3,7 +3,7 @@
3
3
  * Keep these values synchronized with release/manifest.json; release checks
4
4
  * deliberately reject drift before a package can be published.
5
5
  */
6
- export const CATENCE_RUNTIME_VERSION = '0.2.0-beta.3';
6
+ export const CATENCE_RUNTIME_VERSION = '0.2.0-beta.5';
7
7
  export const CATENCE_PROTOCOL_VERSION = 1;
8
8
  export function catenceRuntimeHealth() {
9
9
  return {
@@ -0,0 +1,258 @@
1
+ # Deploying Catence Console
2
+
3
+ Catence Console is a password-protected local web chat that starts a matching
4
+ Catence runtime on loopback. There are two supported ways to run it: **locally**
5
+ (npm package + Python Console on your machine) or **in Docker** (one container
6
+ built from the public registries). Both paths end with the same Console, data
7
+ directory layout, model configuration, and credentials model.
8
+
9
+ Everything below assumes a recent beta or stable release; channels are
10
+ explained in the [beta release notes](../README.md#beta-releases).
11
+
12
+ ## Prerequisites
13
+
14
+ - Node.js 22+ and Python 3.12+ with [uv](https://docs.astral.sh/uv/)
15
+ (local path), or Docker Engine with the `docker compose` plugin (Docker path).
16
+ - Provider credentials for the athletes you choose to sync (Garmin,
17
+ Intervals.icu, Strava).
18
+ - One model-provider key (OpenAI, Anthropic, OpenCode Go, Azure, or any
19
+ OpenAI-compatible endpoint).
20
+
21
+ ## What gets stored where
22
+
23
+ | What | Where | Example |
24
+ | --- | --- | --- |
25
+ | Catalog + athlete stores | data home | `~/.catence/` or `/data` in Docker |
26
+ | Model profiles (no secrets) | `config.json` in the data home | `console.profiles` |
27
+ | Provider credentials | per-athlete secret file, mode 0600 | `catence-data secret set` |
28
+ | API keys | process environment only | `.env` in Docker, shell exports locally |
29
+ | Chat history + preferences | data home | `console/chat-history.sqlite3` |
30
+
31
+ Credentials never land in `config.json`; profiles reference environment
32
+ variable *names* (`apiKeyEnv`, `apiBaseEnv`, `apiVersionEnv`). See
33
+ [`llm-providers.md`](llm-providers.md) for the profile reference and
34
+ [`config.example.json`](../config.example.json) for a complete example.
35
+
36
+ ---
37
+
38
+ ## Path A — Local deployment
39
+
40
+ ### 1. Install the runtime and the Console
41
+
42
+ ```sh
43
+ npm install --global catence@beta # or catence@latest for stable
44
+ uv tool install catence-console # persistent `catence-console` command
45
+ # alternative to the last line: uvx catence-console@<version> serve (ephemeral)
46
+ ```
47
+
48
+ `catence-console serve` launches a matching Catence runtime automatically: it
49
+ uses a globally installed `catence` if present, otherwise `npx catence@<pinned>`.
50
+
51
+ ### 2. Create the catalog and first athlete
52
+
53
+ ```sh
54
+ catence-data setup --athlete alex --label "Alex"
55
+ ```
56
+
57
+ This creates `~/.catence/` (or `$CATENCE_HOME`). It also tolerates a directory
58
+ that already holds only Console artifacts (`config.json`, `console/`).
59
+
60
+ ### 3. Store provider credentials (stdin only, never shell history)
61
+
62
+ ```sh
63
+ printf %s 'alex@example.com' | catence-data --athlete alex secret set --provider garmin --field email --value-stdin
64
+ printf %s 'your-garmin-password' | catence-data --athlete alex secret set --provider garmin --field password --value-stdin
65
+ printf %s 'intervals-api-key' | catence-data --athlete alex secret set --provider intervals --field apiKey --value-stdin
66
+ printf %s '12345' | catence-data --athlete alex secret set --provider intervals --field athleteId --value-stdin
67
+ ```
68
+
69
+ ### 4. Sync data and build retrieval context
70
+
71
+ ```sh
72
+ catence-data --athlete alex sync --provider all
73
+ catence-data --athlete alex build-retrieval-index
74
+ ```
75
+
76
+ ### 5. Configure the model
77
+
78
+ On the first chat, the Console wizard asks for a provider and model and writes
79
+ a starter profile. To start from the documented profiles instead, copy the
80
+ `console` section from [`config.example.json`](../config.example.json) into
81
+ `~/.catence/config.json`. To add OpenCode Go models, run the
82
+ [model discovery script](#model-discovery-opencode-go) below.
83
+
84
+ ### 6. Set the model credentials and Console login
85
+
86
+ ```sh
87
+ export OPENAI_API_KEY='…' # or ANTHROPIC_API_KEY / OPENCODE_GO_API_KEY …
88
+ export CATENCE_CONSOLE_USERNAME='coach'
89
+ export CATENCE_CONSOLE_PASSWORD_HASH="$(catence-console auth hash-password)"
90
+ export CHAINLIT_AUTH_SECRET="$(openssl rand -hex 32)"
91
+ ```
92
+
93
+ ### 7. Start the Console
94
+
95
+ ```sh
96
+ catence-console serve
97
+ # open http://127.0.0.1:8000
98
+ ```
99
+
100
+ The Model dropdown in the settings panel lists every profile's deployments.
101
+ Preflight with:
102
+
103
+ ```sh
104
+ catence-console doctor
105
+ ```
106
+
107
+ ---
108
+
109
+ ## Path B — Docker deployment
110
+
111
+ ### 1. Deploy with the script
112
+
113
+ ```sh
114
+ curl -fsSL https://raw.githubusercontent.com/rifusaki/catence/beta/scripts/deploy-console.sh | bash -s beta
115
+ # or from a checkout: ./scripts/deploy-console.sh beta
116
+ # use `stable` instead of `beta` for the stable channel
117
+ ```
118
+
119
+ The script resolves the newest matching versions from npm and PyPI, writes a
120
+ self-contained `catence-deploy/` project (Dockerfile, docker-compose.yml, and
121
+ `.env` with placeholders), builds the image, **seeds a starter
122
+ `/data/config.json`** into the data volume, and starts the stack — or, when
123
+ secrets are missing, prints the remaining steps and exits.
124
+
125
+ ### 2. Fill in `catence-deploy/.env`
126
+
127
+ ```sh
128
+ CATENCE_CONSOLE_USERNAME=coach
129
+ CATENCE_CONSOLE_PASSWORD_HASH='…' # generate: ./catence-deploy/hash-password.sh
130
+ CHAINLIT_AUTH_SECRET='…' # generate: openssl rand -hex 32
131
+ OPENAI_API_KEY='…' # or ANTHROPIC_API_KEY / OPENCODE_GO_API_KEY …
132
+ OPENAI_API_BASE='' # only for OpenAI-compatible endpoints
133
+ OPENCODE_GO_API_KEY='…' # the OpenCode Go base URLs are pre-filled below
134
+ OPENCODE_GO_API_BASE='https://opencode.ai/zen/go/v1'
135
+ OPENCODE_GO_MESSAGES_API_BASE='https://opencode.ai/zen/go'
136
+ ```
137
+
138
+ Then start the stack (or re-run the script, which re-reads the saved `.env`):
139
+
140
+ ```sh
141
+ docker compose -f catence-deploy/docker-compose.yml --env-file catence-deploy/.env up -d
142
+ ```
143
+
144
+ ### 3. Initialize an athlete store
145
+
146
+ The data volume already contains a seeded `config.json`, so `setup` accepts
147
+ it. Run through the container:
148
+
149
+ ```sh
150
+ docker compose -f catence-deploy/docker-compose.yml --env-file catence-deploy/.env run --rm \
151
+ --entrypoint catence-data console setup --athlete alex --label "Alex"
152
+ ```
153
+
154
+ ### 4. Store provider credentials
155
+
156
+ ```sh
157
+ printf %s 'value' | docker compose -f catence-deploy/docker-compose.yml --env-file catence-deploy/.env run --rm -T \
158
+ --entrypoint catence-data console --athlete alex secret set \
159
+ --provider intervals --field apiKey --value-stdin
160
+ ```
161
+
162
+ Use the same `--entrypoint catence-data` pattern for `sync`, `backfill`, and
163
+ `auth strava`.
164
+
165
+ ### 5. Configure the model
166
+
167
+ The seeded `config.json` already offers OpenAI, OpenAI-compatible, and
168
+ Anthropic starter profiles, so the settings panel works before the first chat.
169
+ Edit `/data/config.json` inside the volume:
170
+
171
+ ```sh
172
+ docker compose -f catence-deploy/docker-compose.yml --env-file catence-deploy/.env run --rm \
173
+ --entrypoint sh console -c 'cat > /data/config.json' # paste JSON, then Ctrl-D
174
+ ```
175
+
176
+ With `--home <dir>` (bind mount), edit `<dir>/config.json` on the host
177
+ instead. To add OpenCode Go models, see [model discovery](#model-discovery-opencode-go).
178
+
179
+ ### 6. Expose the Console safely
180
+
181
+ Keep the Console port bound to `127.0.0.1` (the default) and front it with a
182
+ Cloudflare Tunnel or reverse proxy at HTTPS. Never expose Catence's MCP port
183
+ 8787 — it stays loopback-only inside the container. For remote MCP checks use
184
+ SSH port forwarding (`ssh -L 8787:127.0.0.1:8787 server`).
185
+
186
+ ---
187
+
188
+ ## Model discovery (OpenCode Go)
189
+
190
+ OpenCode Go publishes an OpenAI-compatible API at
191
+ `https://opencode.ai/zen/go/v1`; its model list is public. The discovery
192
+ script fetches it and merges two ready-made profiles into `config.json`:
193
+ `opencode-go` (chat + responses models, base `…/zen/go/v1`) and
194
+ `opencode-go-messages` (messages models, base `…/zen/go`). Existing profiles,
195
+ limits, and `defaultProfile` are preserved unless `--set-default` is passed.
196
+
197
+ ```sh
198
+ # Local (from a checkout)
199
+ npm run discover:opencode-go -- --write ~/.catence/config.json
200
+
201
+ # Docker (the script ships inside the npm package in the image)
202
+ docker compose -f catence-deploy/docker-compose.yml --env-file catence-deploy/.env run --rm \
203
+ --entrypoint node console \
204
+ /usr/local/lib/node_modules/catence/scripts/discover-opencode-go.mjs --write /data/config.json
205
+ ```
206
+
207
+ Then set the credentials and verify. The generated `.env` already contains
208
+ `OPENCODE_GO_API_BASE` and `OPENCODE_GO_MESSAGES_API_BASE`, so on Docker only
209
+ the key is missing:
210
+
211
+ ```sh
212
+ export OPENCODE_GO_API_KEY='…' # any non-empty value passes the key check
213
+ catence-console doctor
214
+ ```
215
+
216
+ The `openai/responses/…` models (for example `grok-4.5`) go through LiteLLM's
217
+ responses bridge and are the least battle-tested path; smoke-test one chat turn
218
+ before relying on them.
219
+
220
+ ---
221
+
222
+ ## Updating
223
+
224
+ From `catence-data update`-capable releases (0.2.0-beta.3 and later), the
225
+ runtime updates both components on the tracked channel — beta installs follow
226
+ the npm `beta` tag and matching PyPI prereleases:
227
+
228
+ ```sh
229
+ catence-data update --check # report only; exit 1 when updates are pending
230
+ catence-data update # npm runtime + uv tool catence-console upgrade
231
+ catence-data update --channel stable # move off a beta onto the stable channel
232
+ ```
233
+
234
+ Older betas (for example a beta 2 install) predate the command; upgrade them
235
+ manually once:
236
+
237
+ ```sh
238
+ npm install --global catence@beta
239
+ uv tool install --upgrade catence-console
240
+ ```
241
+
242
+ Docker deployments: re-run `deploy-console.sh beta` (or `stable`); it
243
+ re-resolves the newest versions from the registries and rebuilds. The data
244
+ volume and your `config.json` are preserved.
245
+
246
+ ## Troubleshooting
247
+
248
+ - **"No Catence config exists"** — should not happen after a seeded deploy or
249
+ wizard run; ensure `/data/config.json` (Docker) or `~/.catence/config.json`
250
+ exists and contains a `console` section.
251
+ - **"Refusing to initialize"** — the data home contains unrelated files;
252
+ `config.json` and `console/` are allowed, anything else blocks `setup`.
253
+ - **Settings panel has no Model dropdown** — the Console loads profiles from
254
+ `config.json`; write one via the wizard, a manual copy, or the discovery
255
+ script.
256
+ - **Profile not ready** — `catence-console doctor` lists the missing
257
+ environment variables; set them in `.env` (Docker) or the shell (local) and
258
+ restart the Console.
@@ -305,3 +305,26 @@ prints credential values.
305
305
  ```sh
306
306
  catence-console doctor --home "$HOME/.catence" --mcp-url http://127.0.0.1:8787/mcp
307
307
  ```
308
+
309
+ ## Docker: generating the Console login hash
310
+
311
+ `deploy-console.sh` writes a small helper into the deployment directory. Run it
312
+ once after the script to generate the bcrypt hash for
313
+ `CATENCE_CONSOLE_PASSWORD_HASH` — it prompts for the password on the terminal,
314
+ never echoes it, and uses the compose project so it works no matter what image
315
+ tag the script built:
316
+
317
+ ```sh
318
+ ./catence-deploy/hash-password.sh
319
+ ```
320
+
321
+ Paste the output into `CATENCE_CONSOLE_PASSWORD_HASH` in `catence-deploy/.env`,
322
+ then start the stack (`./deploy-console.sh beta` again, or
323
+ `docker compose -f catence-deploy/docker-compose.yml --env-file catence-deploy/.env up -d`).
324
+
325
+ If you prefer, re-run the deploy script with `--generate-secrets` instead and
326
+ answer the interactive password prompt; it saves the hash to `.env` for you.
327
+ Without the helper (for example an older deployment), the equivalent command
328
+ is `docker run --rm -it --entrypoint /opt/catence-console/bin/catence-console
329
+ <image-tag> auth hash-password`, where `<image-tag>` is the tag printed by the
330
+ script.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "catence",
3
- "version": "0.2.0-beta.3",
3
+ "version": "0.2.0-beta.5",
4
4
  "description": "Local MCP access to normalized Garmin, Intervals.icu, and targeted Strava fitness data.",
5
5
  "license": "AGPL-3.0-or-later",
6
6
  "repository": {