ompchamber 0.4.0 → 0.6.0

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 (94) hide show
  1. package/README.md +56 -7
  2. package/dist/client/index.html +1 -1
  3. package/dist/client/static/css/{index.5291f58223.css → index.51f68210a5.css} +1 -1
  4. package/dist/client/static/js/async/{3y.ededeebde8.js → 3y.4c2596f64c.js} +3 -3
  5. package/dist/client/static/js/async/73.308dff4da8.js +1 -0
  6. package/dist/client/static/js/async/{ty.3d93cf5f5f.js → 7g.a7814350c3.js} +1 -1
  7. package/dist/client/static/js/async/a.bce4542392.js +1 -0
  8. package/dist/client/static/js/async/dc.6dc4b0a04b.js +2 -0
  9. package/dist/client/static/js/async/g.8515cbc6f7.js +2 -0
  10. package/dist/client/static/js/async/hn.b645041e00.js +1 -0
  11. package/dist/client/static/js/async/{jg.69a4beade8.js → jg.d86ebd4013.js} +1 -1
  12. package/dist/client/static/js/async/l.12dd34e1be.js +1 -0
  13. package/dist/client/static/js/async/ls.9d9a01026c.js +104 -0
  14. package/dist/client/static/js/async/mw.ca1512563c.js +10 -0
  15. package/dist/client/static/js/async/nk.fc7e58325e.js +1 -0
  16. package/dist/client/static/js/async/{q.7fb4d2f374.js → q.542c184fec.js} +3 -3
  17. package/dist/client/static/js/async/t.cda4891526.js +1 -0
  18. package/dist/client/static/js/async/tr.e878658140.js +309 -0
  19. package/dist/client/static/js/async/uf.24ca3d49c3.js +2 -0
  20. package/dist/client/static/js/{index.bf1b1fe988.js → index.47d3b04d5f.js} +7 -7
  21. package/dist/client/static/js/{uy.5f791144ce.js → uy.2e8929ed0c.js} +2 -2
  22. package/package.json +13 -6
  23. package/src/cli/lib/args.js +7 -6
  24. package/src/cli/lib/commands/logs.js +76 -34
  25. package/src/cli/lib/commands/restart.js +30 -9
  26. package/src/cli/lib/commands/serve.js +19 -4
  27. package/src/cli/lib/commands/status.js +40 -18
  28. package/src/cli/lib/commands/stop.js +12 -7
  29. package/src/cli/lib/commands/update.js +2 -5
  30. package/src/cli/lib/paths.js +8 -28
  31. package/src/cli/lib/runtime.js +118 -108
  32. package/src/client/components/common/code-editor/index.tsx +5 -1
  33. package/src/client/components/common/code-surface/index.tsx +49 -1
  34. package/src/client/components/common/code-surface/measure.ts +99 -0
  35. package/src/client/components/layout/RightActivityBar.tsx +42 -69
  36. package/src/client/components/layout/desktop-layout/WorkspacePanels.tsx +5 -6
  37. package/src/client/components/layout/desktop-layout/index.tsx +11 -9
  38. package/src/client/components/layout/desktop-layout/resizer/index.tsx +22 -29
  39. package/src/client/components/layout/desktop-layout/resizer/utils.test.ts +33 -0
  40. package/src/client/components/layout/desktop-layout/resizer/utils.ts +34 -0
  41. package/src/client/components/mobile/RightSidebar.tsx +42 -119
  42. package/src/client/components/mobile/mobile-main-view/Header.tsx +17 -1
  43. package/src/client/components/workspace/editor/index.tsx +4 -1
  44. package/src/client/components/workspace/file-explorer/TreeItem.tsx +8 -2
  45. package/src/client/components/workspace/file-explorer/index.tsx +6 -0
  46. package/src/client/data/models/catalog.ts +8 -0
  47. package/src/client/data/samples/dialogue-session.ts +1 -1
  48. package/src/client/data/samples/sample-tools/other.ts +1 -1
  49. package/src/client/hooks/chat/timeline/send.ts +1 -1
  50. package/src/client/hooks/editor/use-file-editor.test.ts +158 -0
  51. package/src/client/hooks/editor/use-file-editor.ts +35 -19
  52. package/src/server/index.ts +104 -1
  53. package/src/server/lib/lifecycle/identity.ts +108 -0
  54. package/src/server/lib/lifecycle/instance.ts +102 -0
  55. package/src/server/lib/lifecycle/occupant.ts +101 -0
  56. package/src/server/lib/lifecycle/paths.ts +50 -0
  57. package/src/server/lib/lifecycle/port-guard.ts +170 -0
  58. package/src/server/lib/lifecycle/probe.ts +121 -0
  59. package/src/server/lib/models/provider-registry.server.ts +44 -20
  60. package/src/server/lib/omp/core/cli.ts +3 -2
  61. package/src/server/lib/omp/core/startup.ts +64 -0
  62. package/src/server/lib/omp/rpc/process.ts +1 -1
  63. package/src/server/mock.server.ts +6 -12
  64. package/src/server/plugins/static.test.ts +63 -0
  65. package/src/server/plugins/static.ts +28 -4
  66. package/src/server/routes/chat/stream.ts +13 -30
  67. package/src/server/routes/health/probe.ts +8 -0
  68. package/src/server/routes/models/root.ts +5 -1
  69. package/src/shared/lib/chat/stream-service.ts +0 -76
  70. package/src/shared/lib/fs/paths.ts +19 -0
  71. package/src/shared/lib/markdown/mermaid.ts +8 -0
  72. package/src/shared/lib/workspace/panel-widths.test.ts +5 -5
  73. package/src/shared/lib/workspace/panel-widths.ts +23 -10
  74. package/src/shared/lib/workspace/right-panels.ts +10 -4
  75. package/dist/client/static/js/async/73.50280ce58d.js +0 -1
  76. package/dist/client/static/js/async/a.e05da304c8.js +0 -10
  77. package/dist/client/static/js/async/ar.1e14da5588.js +0 -1
  78. package/dist/client/static/js/async/art.62139ed479.js +0 -2
  79. package/dist/client/static/js/async/g.7a4bbd4798.js +0 -2
  80. package/dist/client/static/js/async/hn.7568bdb58b.js +0 -1
  81. package/dist/client/static/js/async/l.102a97fce6.js +0 -104
  82. package/dist/client/static/js/async/l6.c56640c205.js +0 -1
  83. package/dist/client/static/js/async/nk.6de011832e.js +0 -1
  84. package/dist/client/static/js/async/t.cb3fcf8615.js +0 -1
  85. package/dist/client/static/js/async/uf.46ad6209fa.js +0 -2
  86. package/dist/client/static/js/async/vn.e98e2f3b61.js +0 -309
  87. /package/dist/client/static/js/async/{3y.ededeebde8.js.LICENSE.txt → 3y.4c2596f64c.js.LICENSE.txt} +0 -0
  88. /package/dist/client/static/js/async/{a.e05da304c8.js.LICENSE.txt → dc.6dc4b0a04b.js.LICENSE.txt} +0 -0
  89. /package/dist/client/static/js/async/{g.7a4bbd4798.js.LICENSE.txt → g.8515cbc6f7.js.LICENSE.txt} +0 -0
  90. /package/dist/client/static/js/async/{art.62139ed479.js.LICENSE.txt → mw.ca1512563c.js.LICENSE.txt} +0 -0
  91. /package/dist/client/static/js/async/{q.7fb4d2f374.js.LICENSE.txt → q.542c184fec.js.LICENSE.txt} +0 -0
  92. /package/dist/client/static/js/async/{uf.46ad6209fa.js.LICENSE.txt → uf.24ca3d49c3.js.LICENSE.txt} +0 -0
  93. /package/dist/client/static/js/{index.bf1b1fe988.js.LICENSE.txt → index.47d3b04d5f.js.LICENSE.txt} +0 -0
  94. /package/dist/client/static/js/{uy.5f791144ce.js.LICENSE.txt → uy.2e8929ed0c.js.LICENSE.txt} +0 -0
package/README.md CHANGED
@@ -14,7 +14,7 @@
14
14
  <a href="https://elysiajs.com"><img alt="Server: Elysia 1.4" src="https://img.shields.io/badge/server-Elysia%201.4-6f42c1"></a>
15
15
  <a href="https://preactjs.com"><img alt="UI: Preact 10" src="https://img.shields.io/badge/UI-Preact%2010-673ab7?logo=preact&logoColor=white"></a>
16
16
  <a href="https://rsbuild.dev"><img alt="Build: Rsbuild 2" src="https://img.shields.io/badge/build-Rsbuild%202-eab308"></a>
17
- <a href="package.json"><img alt="Version: 0.4.0" src="https://img.shields.io/badge/version-0.4.0-3f3f46"></a>
17
+ <a href="package.json"><img alt="Version: 0.5.0" src="https://img.shields.io/badge/version-0.5.0-3f3f46"></a>
18
18
  </p>
19
19
 
20
20
  <p align="center">
@@ -67,8 +67,8 @@ ompchamber logs -f -n 200 # follow the server log
67
67
  - **Full omp settings surface** — OMP Engine config keys, providers, agents, behavior
68
68
  (`AGENTS.md` / `RULES.md`), slash commands, MCP servers with live connection tests, skills and
69
69
  the skills catalog, token usage and notifications.
70
- - **Two data modes** — `MOCK=true` ships demo datasets for previews; `MOCK=false` runs purely on
71
- the real SQLite database and real workspace files.
70
+ - **Two data modes** — `MOCK=false` (the default, also when unset) runs purely on the real SQLite
71
+ database and real workspace files; `MOCK=true` opts into demo datasets for previews.
72
72
  - **Self-update** — `ompchamber update` installs the latest GitHub release (bun global or git
73
73
  checkout) and restarts a running instance; **About → Updates** does the same from the console.
74
74
 
@@ -79,6 +79,10 @@ OMPChamber is published to npm. It needs a Bun runtime, not Node:
79
79
  > **Bun only** — the server imports `bun:sqlite` and `Bun.YAML`, both of which Node cannot load.
80
80
  > `bun` 1.4 or newer is required.
81
81
 
82
+ > **omp required** — every live capability (agent sessions, omp config, session state, updates)
83
+ > shells out to the `omp` binary, so `serve` refuses to start when it cannot be resolved on `PATH`
84
+ > (or via `OMPCHAMBER_OMP_BIN`). `MOCK=true` is the only mode that runs without a real omp install.
85
+
82
86
  ```bash
83
87
  bun add -g ompchamber # puts the `ompchamber` command on your PATH
84
88
  ompchamber serve --prod # start the server on :3000
@@ -151,6 +155,47 @@ same install, then asks you to restart the server, because a running server cann
151
155
  | `-f, --follow` / `-n, --lines <count>` | Tail the log, optionally from a line count |
152
156
  | `--json` / `-q, --quiet` | Machine-readable output / suppress non-essential output |
153
157
 
158
+ ### Ports and multiple instances
159
+
160
+ One port is served by exactly one process, and `bun run dev`, `ompchamber serve` and the production
161
+ server all default to `3000`. **A starting instance never stops another one** — not a CLI server
162
+ and not a dev run. If the port is taken by OMPChamber, the newcomer reports who holds it and exits
163
+ non-zero so you can pick another port and re-run:
164
+
165
+ ```bash
166
+ ompchamber serve --port 3001 # CLI flag
167
+ OMPCHAMBER_PORT=3001 ompchamber serve
168
+ PORT=3001 bun run dev # or: PORT=3001 bun run start
169
+ ```
170
+
171
+ - Nothing is ever signalled to free a port. `ompchamber stop --port 3000` is the deliberate way to
172
+ free one, and it is per port.
173
+ - A process that is **not** OMPChamber is never signalled either: the server exits with an error
174
+ naming the port and the `lsof -nP -iTCP:<port> -sTCP:LISTEN` command to identify it.
175
+ - The refusal exists because a second bind would *succeed*: Elysia's Bun adapter hardcodes
176
+ `reusePort: true`, so two servers would share a port and only the first-bound socket would receive
177
+ connections — the newcomer would look healthy while the browser kept talking to the old build.
178
+ - `bun run dev` hot reload is unaffected: `--hot` re-evaluates the server entry *inside the running
179
+ process*, and a port held by that same process is recognized as its own, so Bun swaps the handler
180
+ on the next `listen`. Saving a file neither trips the guard nor resets the reported uptime.
181
+
182
+ Running several ports at once is supported. `status`, `stop`, `restart` and `logs` act on **every**
183
+ live instance by default, and `--port <port>` narrows them to one:
184
+
185
+ ```bash
186
+ ompchamber status # every instance: port, pid, mode, launch mode, health, log
187
+ ompchamber status --port 3001 # just that one
188
+ ompchamber logs -n 200 # one header per instance, sources included
189
+ ompchamber logs --port 3001 -f # follow one instance's log
190
+ ompchamber stop # stop them all (--all is the explicit spelling)
191
+ ompchamber stop --port 3001 # stop just that one
192
+ ```
193
+
194
+ The server writes `~/.ompchamber/run/<port>.json` (`pid`, `host`, `mode`, `launchMode`,
195
+ `startedAt`) once it owns the port, which is why `status`/`stop`/`logs` also see servers started by
196
+ `bun run dev` or `--foreground` — not just daemon-spawned ones. Records left by a killed server are
197
+ pruned as soon as their PID stops answering, so a recycled PID is never reported as an instance.
198
+
154
199
  ## Configuration
155
200
 
156
201
  Environment variables, read from `.env` (see [`.env.example`](.env.example)):
@@ -159,7 +204,7 @@ Environment variables, read from `.env` (see [`.env.example`](.env.example)):
159
204
  |---|---|---|
160
205
  | `PORT` | `3000` | Server port |
161
206
  | `HOST` | `localhost` | Server bind address |
162
- | `MOCK` | `true` | `true` = demo datasets, `false` = real SQLite + workspace only |
207
+ | `MOCK` | `false` | `true` = demo datasets, `false` = real SQLite + workspace only |
163
208
  | `SYNC_WORKSPACE` | `true` | Keep the workspace index in sync with disk |
164
209
  | `OMPCHAMBER_DATA_DIR` | `~/.ompchamber` | CLI registry, logs and database root |
165
210
  | `OMPCHAMBER_PORT` / `OMPCHAMBER_HOST` | — | Defaults for the CLI when no flag is passed |
@@ -167,7 +212,7 @@ Environment variables, read from `.env` (see [`.env.example`](.env.example)):
167
212
  | `OMPCHAMBER_DEV_SERVER` | `http://localhost:3100` | Rsbuild asset origin used in dev |
168
213
  | `OMPCHAMBER_BUN` | — | Explicit Bun binary for the CLI to spawn |
169
214
  | `PI_CONFIG_DIR` / `PI_CODING_AGENT_DIR` | `~/.omp` | Oh-My-Pi config root overrides |
170
- | `OMP_WEB_OMP_BIN` | — | Explicit `omp` binary path |
215
+ | `OMPCHAMBER_OMP_BIN` | — | Explicit `omp` binary path |
171
216
  | `SKILLS_API_URL` | `https://skills.sh` | Skills catalog source |
172
217
  | `GITHUB_TOKEN` / `GH_TOKEN` | — | Raise the GitHub API rate limit for update checks |
173
218
 
@@ -185,7 +230,7 @@ src/
185
230
  │ └─ tailwind.css theme tokens (--theme-ink, --theme-paper, …)
186
231
  ├─ server/ Bun-only — Elysia routes, SQLite, omp RPC bridge, fs/git/terminal
187
232
  │ ├─ routes/ one plugin per domain, mounted in routes/index.ts
188
- │ ├─ lib/ omp session/subagent/config, updates, browser runtime
233
+ │ ├─ lib/ omp session/subagent/config, updates, browser runtime, port lifecycle
189
234
  │ └─ plugins/ SSR shell, static assets, compression, dev assets
190
235
  ├─ shared/ Imported by both — types, chat timeline folding, pure helpers
191
236
  └─ cli/ ompchamber command (plain ESM, runs under Bun)
@@ -215,6 +260,10 @@ There is no HMR: the server reloads on save, the client bundle rebuilds, refresh
215
260
  `dist/client/index.html` is the shell for both dev and prod, so run `dev:client` at least once
216
261
  after a clean checkout.
217
262
 
263
+ Dev and prod share the default port `3000`: a second starter on an occupied port refuses and exits
264
+ with the port options to re-run ([Ports and multiple instances](#ports-and-multiple-instances));
265
+ nothing is stopped for you.
266
+
218
267
  Verification gates, all mandatory:
219
268
 
220
269
  ```bash
@@ -230,7 +279,7 @@ Publishing is driven by **GitHub releases**, never by a push
230
279
  ([`.github/workflows/publish.yml`](.github/workflows/publish.yml)):
231
280
 
232
281
  ```bash
233
- bun pm version minor -m "chore(release): v%s" # bump + commit + tag v0.4.0
282
+ bun pm version minor -m "chore(release): v%s" # bump + commit + tag v0.5.0
234
283
  git push origin main --tags
235
284
  # then publish the release on GitHub → the workflow publishes to npm
236
285
  ```
@@ -24,7 +24,7 @@
24
24
  href="https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap"
25
25
  />
26
26
  <!--app-head-->
27
- <script defer src="/static/js/markdown-vendor.71e43278b3.js"></script><script defer src="/static/js/shiki-vendor.cb8452ddcd.js"></script><script defer src="/static/js/uy.5f791144ce.js"></script><script defer src="/static/js/index.bf1b1fe988.js"></script><link href="/static/css/index.5291f58223.css" rel="stylesheet"></head>
27
+ <script defer src="/static/js/markdown-vendor.71e43278b3.js"></script><script defer src="/static/js/shiki-vendor.cb8452ddcd.js"></script><script defer src="/static/js/uy.2e8929ed0c.js"></script><script defer src="/static/js/index.47d3b04d5f.js"></script><link href="/static/css/index.51f68210a5.css" rel="stylesheet"></head>
28
28
  <body>
29
29
  <div id="app"></div>
30
30
  <!--app-bootstrap-->