catence 0.2.0-beta.4 → 0.2.0-beta.6

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.
@@ -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.4";
6
+ export declare const CATENCE_RUNTIME_VERSION = "0.2.0-beta.6";
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.4';
6
+ export const CATENCE_RUNTIME_VERSION = '0.2.0-beta.6';
7
7
  export const CATENCE_PROTOCOL_VERSION = 1;
8
8
  export function catenceRuntimeHealth() {
9
9
  return {
@@ -41,7 +41,7 @@ function legacyStoreMessage(paths) {
41
41
  return `Catence 0.2 uses a catalog at ${paths.root}. The existing directory looks like a 0.1 data store and cannot be migrated automatically. Create a fresh catalog and re-sync each athlete.`;
42
42
  }
43
43
  /** Home-directory entries the Console creates on its own and must not block catalog initialization. */
44
- const CONSOLE_ARTIFACTS = new Set(['config.json', 'console']);
44
+ const CONSOLE_ARTIFACTS = new Set(['config.json', 'console', '.files', '.chainlit', 'public']);
45
45
  export async function loadCatalog(paths = resolveCatalogPaths()) {
46
46
  const contents = await readFile(paths.catalog, 'utf8').catch((error) => {
47
47
  if (error.code !== 'ENOENT')
@@ -79,8 +79,9 @@ export async function initializeCatalog(paths = resolveCatalogPaths(), athlete)
79
79
  }
80
80
  if (entries.includes('catence.duckdb'))
81
81
  throw new Error(legacyStoreMessage(paths));
82
- if (entries.some((entry) => !CONSOLE_ARTIFACTS.has(entry))) {
83
- throw new Error(`Refusing to initialize ${paths.root}: choose an empty --home directory or remove its unrelated contents.`);
82
+ const unrelated = entries.filter((entry) => !CONSOLE_ARTIFACTS.has(entry));
83
+ if (unrelated.length > 0) {
84
+ throw new Error(`Refusing to initialize ${paths.root}: found ${unrelated.join(', ')}. Remove these or choose an empty --home directory.`);
84
85
  }
85
86
  const id = athleteIdSchema.parse(athlete.id);
86
87
  const record = { id, label: athlete.label.trim(), createdAt: new Date().toISOString() };
@@ -126,7 +126,7 @@ secrets are missing, prints the remaining steps and exits.
126
126
 
127
127
  ```sh
128
128
  CATENCE_CONSOLE_USERNAME=coach
129
- CATENCE_CONSOLE_PASSWORD_HASH='…' # generate: docker compose ... run --rm --entrypoint /opt/catence-console/bin/catence-console console auth hash-password
129
+ CATENCE_CONSOLE_PASSWORD_HASH='…' # generate: ./catence-deploy/hash-password.sh
130
130
  CHAINLIT_AUTH_SECRET='…' # generate: openssl rand -hex 32
131
131
  OPENAI_API_KEY='…' # or ANTHROPIC_API_KEY / OPENCODE_GO_API_KEY …
132
132
  OPENAI_API_BASE='' # only for OpenAI-compatible endpoints
@@ -248,8 +248,9 @@ volume and your `config.json` are preserved.
248
248
  - **"No Catence config exists"** — should not happen after a seeded deploy or
249
249
  wizard run; ensure `/data/config.json` (Docker) or `~/.catence/config.json`
250
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`.
251
+ - **"Refusing to initialize"** — the data home contains unrelated files; the
252
+ error lists them. Console artifacts (`config.json`, `console/`, and Chainlit's
253
+ `.files/`, `.chainlit/`, `public/`) are allowed; anything else blocks `setup`.
253
254
  - **Settings panel has no Model dropdown** — the Console loads profiles from
254
255
  `config.json`; write one via the wizard, a manual copy, or the discovery
255
256
  script.
@@ -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.4",
3
+ "version": "0.2.0-beta.6",
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": {