tracer-sh 0.2.8 → 0.3.1

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.
Files changed (23) hide show
  1. package/README.md +58 -6
  2. package/package.json +4 -3
  3. package/packages/server/dist/{chunk-WOL2ZWU7.js → chunk-5GQDB6U7.js} +4 -0
  4. package/packages/server/dist/chunk-IAWOYD5E.js +4793 -0
  5. package/packages/server/dist/{chunk-WUFQGSGW.js → chunk-YL5JSOUN.js} +1 -1
  6. package/packages/server/dist/dist-ZMUHFP5T.js +1257 -0
  7. package/packages/server/dist/{domain-knowledge-4AAER546.js → domain-knowledge-B2IREATL.js} +1 -1
  8. package/packages/server/dist/{domain-knowledge-CAD7MDFJ.js → domain-knowledge-K3OB4NDB.js} +1 -1
  9. package/packages/server/dist/{domain-knowledge-A3WXZ55R.js → domain-knowledge-U2RLSFM2.js} +1 -1
  10. package/packages/server/dist/index.js +58498 -41044
  11. package/packages/server/dist/multipart-parser-ONCUQ5VA.js +372 -0
  12. package/packages/server/dist/src-434DTNEL.js +1409 -0
  13. package/packages/server/dist/{token-QV5VOVJ4.js → token-4YFRZJYT.js} +2 -2
  14. package/packages/server/dist/{token-util-DLXYCJR4.js → token-util-CTKMWUIG.js} +2 -2
  15. package/packages/web/dist/assets/{SearchableSelect-CUhWd9KY.js → SearchableSelect-cW8CAuj_.js} +1 -1
  16. package/packages/web/dist/assets/Settings-CBO58Ysm.js +1 -0
  17. package/packages/web/dist/assets/{highlighted-body-OFNGDK62-I1fFFO4T.js → highlighted-body-OFNGDK62-C09rPU2r.js} +1 -1
  18. package/packages/web/dist/assets/{index-C2C5Z4gB.js → index-BrLT4CJt.js} +10 -10
  19. package/packages/web/dist/assets/index-CZnFdes-.css +1 -0
  20. package/packages/web/dist/assets/{mermaid-GHXKKRXX--cj8bwjs.js → mermaid-GHXKKRXX-fHfNJrVx.js} +3 -3
  21. package/packages/web/dist/index.html +2 -2
  22. package/packages/web/dist/assets/Settings-BlhaU_HT.js +0 -1
  23. package/packages/web/dist/assets/index-B4Hwftt4.css +0 -1
package/README.md CHANGED
@@ -45,25 +45,69 @@ Configure providers, LLM credentials, agent behavior, and memory. All data is st
45
45
  └─────────┘ └──────────────────┘
46
46
  ```
47
47
 
48
- Everything runs on your machine. Your data stays local in a SQLite database.
49
- Tracer talks directly to your provider and LLM APIs using your own API keys —
50
- no intermediary servers, no data leaves your machine except API calls you control.
48
+ Everything runs on your machine. Your data stays local in an encrypted SQLite
49
+ database. Tracer talks directly to your provider and LLM APIs using your own API
50
+ keys — no intermediary servers, no data leaves your machine except API calls you control.
51
+
52
+ ## Security
53
+
54
+ Tracer is built **defense-in-depth**: your secrets — provider and LLM API keys,
55
+ integration tokens, chat history, and agent memory — sit behind several independent
56
+ layers, so no single failure exposes them.
57
+
58
+ - **Local-only.** Nothing leaves your machine except the provider and LLM API calls you configure. No Tracer servers, no telemetry, no sync.
59
+ - **Encrypted at rest.** The entire SQLite database is encrypted with SQLCipher (AES-256). On disk it is ciphertext — a stolen laptop, a copied `.db` file, or a backup is useless without the key.
60
+ - **Machine-bound, user-scoped key.** A random 256-bit key is generated on first run and stored in your OS keychain (macOS Keychain, Windows Credential Manager, or Linux Secret Service). It never leaves the machine and is scoped to your OS user, so another user on the same box can't read the database either.
61
+ - **Hardened on disk.** The data directory is created owner-only (`0700`); if no keychain is available, the fallback key file is written `0600`.
62
+
63
+ **Automatic and transparent.** New installs are encrypted from the first run. An
64
+ existing plaintext database is migrated on the first launch of this version — the
65
+ encrypted copy is verified and atomically swapped in, and no plaintext is left behind.
66
+ There's nothing to enable.
67
+
68
+ **CI / headless.** Where no keychain exists, supply the key yourself with
69
+ `TRACER_DB_KEY` — a 64-character hex string (e.g. `openssl rand -hex 32`).
70
+
71
+ **What this protects — and what it doesn't.** Encryption at rest defends the file
72
+ (theft, backups, copies) and blocks other users on the same machine. It does **not**
73
+ defend against you, the logged-in user, running code as yourself: the app must hold the
74
+ key at runtime to read its own data, so anyone controlling your user session can too. No
75
+ local-first app escapes this — it's the honest boundary of on-device encryption.
76
+
77
+ **Key loss means data loss.** Because the key lives only in your keychain, losing it (an
78
+ OS reinstall or keychain reset) makes the database unrecoverable. For a safety net, back
79
+ up the `tracer-sh` / `db-key` keychain value somewhere secure.
80
+
81
+ **Verify it yourself.** The raw file should be unreadable without the key:
82
+
83
+ ```bash
84
+ sqlite3 ~/.tracer/data/tracer.db '.tables' # → "Error: file is not a database"
85
+ head -c 16 ~/.tracer/data/tracer.db | od -c # → random bytes, not "SQLite format 3"
86
+ ```
51
87
 
52
88
  ## Install
53
89
 
54
90
  Requires [Node.js 20+](https://nodejs.org/).
55
91
 
92
+ **Run the latest, no install:**
93
+
56
94
  ```bash
57
- npx tracer-sh
95
+ npx tracer-sh@latest
58
96
  ```
59
97
 
60
- Or install globally:
98
+ `npx` is ephemeral — it runs the newest published version on every launch and isn't a pinned version.
99
+
100
+ **Install a pinned copy:**
61
101
 
62
102
  ```bash
63
103
  npm install -g tracer-sh
64
104
  tracer-sh
65
105
  ```
66
106
 
107
+ The first run gets the latest version; it then stays on that version until you explicitly update — either with **Update now** in the app (click the version in the sidebar) or by re-running the install.
108
+
109
+ **Which should I pick?** Use the global install if you want a stable version that only changes when you choose; use `npx` to always grab the newest with zero install.
110
+
67
111
  Open `http://localhost:3579`, go to **Settings** to add your API keys and choose an LLM — done.
68
112
 
69
113
  ## Headless / CLI
@@ -94,13 +138,21 @@ To also remove your local database (settings, sessions, API keys):
94
138
  rm -rf ~/.tracer
95
139
  ```
96
140
 
141
+ The database encryption key also lives in your OS keychain (service `tracer-sh`,
142
+ account `db-key`). Remove it for a clean slate — on macOS:
143
+
144
+ ```bash
145
+ security delete-generic-password -s tracer-sh -a db-key
146
+ ```
147
+
97
148
  ## Troubleshooting
98
149
 
99
150
  | Problem | Fix |
100
151
  |---------|-----|
101
- | `better-sqlite3` build fails | macOS: `xcode-select --install` / Linux: `sudo apt install build-essential python3` |
152
+ | Native SQLite build fails | macOS: `xcode-select --install` / Linux: `sudo apt install build-essential python3` |
102
153
  | Port in use | `TRACER_PORT=3580 tracer-sh` |
103
154
  | No LLM responses | Add an API key in Settings |
155
+ | Headless / CI: no keychain available | Set `TRACER_DB_KEY` to a 64-char hex key (`openssl rand -hex 32`) |
104
156
 
105
157
  ## Contributing
106
158
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tracer-sh",
3
- "version": "0.2.8",
3
+ "version": "0.3.1",
4
4
  "type": "module",
5
5
  "description": "Local-first debugging & analysis platform",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -28,11 +28,12 @@
28
28
  "prepublishOnly": "if [ -z \"${CI:-}\" ]; then echo 'ERROR: Do not publish manually. Use: pnpm release <version>' && exit 1; fi && pnpm build"
29
29
  },
30
30
  "dependencies": {
31
- "better-sqlite3": "^12.6.2"
31
+ "@napi-rs/keyring": "^1.3.0",
32
+ "better-sqlite3-multiple-ciphers": "^12.6.2"
32
33
  },
33
34
  "pnpm": {
34
35
  "onlyBuiltDependencies": [
35
- "better-sqlite3",
36
+ "better-sqlite3-multiple-ciphers",
36
37
  "esbuild"
37
38
  ],
38
39
  "overrides": {
@@ -11,6 +11,9 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
11
11
  if (typeof require !== "undefined") return require.apply(this, arguments);
12
12
  throw Error('Dynamic require of "' + x + '" is not supported');
13
13
  });
14
+ var __esm = (fn, res) => function __init() {
15
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
16
+ };
14
17
  var __commonJS = (cb, mod) => function __require2() {
15
18
  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
16
19
  };
@@ -37,6 +40,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
37
40
 
38
41
  export {
39
42
  __require,
43
+ __esm,
40
44
  __commonJS,
41
45
  __export,
42
46
  __toESM