ndomo 0.1.0 → 0.2.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 (65) hide show
  1. package/.env.example +4 -0
  2. package/README.es.md +29 -23
  3. package/README.md +64 -24
  4. package/bun.lock +447 -0
  5. package/docs/configuration.md +4 -4
  6. package/docs/installation.md +53 -34
  7. package/docs/installer.md +164 -0
  8. package/docs/integrations.md +1 -1
  9. package/docs/web-ui.md +124 -0
  10. package/package.json +43 -4
  11. package/scripts/install.sh +28 -0
  12. package/scripts/smoke-install.sh +47 -0
  13. package/scripts/smoke-web.sh +335 -0
  14. package/src/cli/__tests__/install.test.ts +733 -0
  15. package/src/cli/index.ts +8 -0
  16. package/src/cli/install.ts +1273 -0
  17. package/src/config/__tests__/schema.test.ts +223 -0
  18. package/src/config/schema.ts +129 -16
  19. package/src/http/__tests__/auth.test.ts +10 -10
  20. package/src/http/__tests__/spa.test.ts +296 -0
  21. package/src/http/auth.ts +8 -1
  22. package/src/http/server.ts +71 -2
  23. package/.bun-version +0 -1
  24. package/.dockerignore +0 -79
  25. package/.editorconfig +0 -18
  26. package/.github/CODEOWNERS +0 -8
  27. package/.github/ISSUE_TEMPLATE/bug_report.yml +0 -62
  28. package/.github/ISSUE_TEMPLATE/config.yml +0 -2
  29. package/.github/ISSUE_TEMPLATE/feature_request.yml +0 -34
  30. package/.github/dependabot.yml +0 -36
  31. package/.github/pull_request_template.md +0 -24
  32. package/.github/release.yml +0 -30
  33. package/.github/workflows/gitleaks.yml +0 -28
  34. package/.github/workflows/release-please.yml +0 -27
  35. package/.github/workflows/smoke.yml +0 -29
  36. package/.husky/commit-msg +0 -1
  37. package/CHANGELOG.md +0 -114
  38. package/Dockerfile +0 -32
  39. package/bin/ndomo-analyses.ts +0 -4
  40. package/bin/ndomo-status.ts +0 -4
  41. package/biome.json +0 -57
  42. package/commitlint.config.js +0 -3
  43. package/opencode.json +0 -5
  44. package/release-please-config.json +0 -11
  45. package/scripts/dev-bust-cache.sh +0 -164
  46. package/scripts/smoke-e2e.ts +0 -704
  47. package/scripts/smoke-hot.ts +0 -417
  48. package/scripts/smoke-v4.ts +0 -256
  49. package/scripts/smoke-v5.ts +0 -397
  50. package/scripts/uninstall.sh +0 -224
  51. package/src/index.ts +0 -37
  52. package/src/lib.ts +0 -65
  53. package/src/mem/scoped.ts +0 -65
  54. package/src/orchestrator/background.test.ts +0 -268
  55. package/src/orchestrator/background.ts +0 -293
  56. package/src/orchestrator/memory-hook.ts +0 -182
  57. package/src/orchestrator/reconciler.ts +0 -123
  58. package/src/orchestrator/scheduler.test.ts +0 -300
  59. package/src/orchestrator/scheduler.ts +0 -243
  60. package/src/plugin.test.ts +0 -2574
  61. package/src/plugin.ts +0 -1690
  62. package/src/worktrees/manager.ts +0 -236
  63. package/src/worktrees/state.ts +0 -87
  64. package/tests/integration/ranger-flow.test.ts +0 -257
  65. package/tsconfig.json +0 -31
@@ -63,7 +63,7 @@ All agents use `opencode-go/deepseek-v4-flash` at their respective temperatures.
63
63
 
64
64
  ## Provider Override at Install Time
65
65
 
66
- The `install.sh` script includes a provider override that modifies agent models before registration. This is not a runtime setting — it applies once during installation and is baked into each agent's frontmatter.
66
+ The installer includes a provider override that modifies agent models before registration. This is not a runtime setting — it applies once during installation and is baked into each agent's frontmatter.
67
67
 
68
68
  The preset (not the provider) defines the model ID. `--provider=ID` only changes the `provider/` prefix in each agent's `model:` field, so the literal `default` model ID is never used.
69
69
 
@@ -97,11 +97,11 @@ The install also wires the plugin into the OpenCode config directory (`~/.config
97
97
  - `agents/*.md` — the `model:` field in each agent's frontmatter is modified during Step 5.5 of the install script.
98
98
  - `~/.cache/ndomo/models-catalog.json` — cached catalog (re-fetched weekly or on cache miss).
99
99
 
100
- The provider override is a one-time install operation. To change providers after installation, either re-run `install.sh` with a different `--provider` flag, or manually edit the `model:` fields in `agents/*.md`.
100
+ The provider override is a one-time install operation. To change providers after installation, either re-run `bunx ndomo install` with a different `--provider` flag, or manually edit the `model:` fields in `agents/*.md`.
101
101
 
102
102
  ## Hot-swap: editing models without re-running install
103
103
 
104
- `ndomo.json::presets[preset][agent].model` is the **runtime source of truth** for agent models. The plugin's `syncAgentFrontmatter()` runs at every OpenCode session startup, compares each agent's `model:` and `temperature:` in `~/.config/opencode/agent/<agent>.md` against the active preset in `ndomo.json`, and rewrites the file when the values differ. This means you can edit `ndomo.json` directly and have the changes take effect on the next session — no need to re-run `install.sh`.
104
+ `ndomo.json::presets[preset][agent].model` is the **runtime source of truth** for agent models. The plugin's `syncAgentFrontmatter()` runs at every OpenCode session startup, compares each agent's `model:` and `temperature:` in `~/.config/opencode/agent/<agent>.md` against the active preset in `ndomo.json`, and rewrites the file when the values differ. This means you can edit `ndomo.json` directly and have the changes take effect on the next session — no need to re-run the installer.
105
105
 
106
106
  **Workflow:**
107
107
 
@@ -243,7 +243,7 @@ Tools listed in `protectedTools` cannot be disabled, overridden, or pruned from
243
243
 
244
244
  The ndomo package is not in `~/.config/opencode/node_modules/ndomo/`. OpenCode's plugin loader silently skips plugins it cannot resolve, so no tools, DB, or agents will appear.
245
245
 
246
- **Fix:** Re-run `./scripts/install.sh` or symlink it manually:
246
+ **Fix:** Re-run `bunx ndomo install` or symlink it manually:
247
247
 
248
248
  ```bash
249
249
  ln -sfn $(pwd) ~/.config/opencode/node_modules/ndomo
@@ -14,28 +14,22 @@ opencode --version
14
14
  opencode config list providers # should show at least one authenticated provider
15
15
  ```
16
16
 
17
- ## Install via curl/wget
17
+ ## Install via bunx
18
18
 
19
- The install script supports being piped directly from a URL, useful for quick setups, CI/CD pipelines, and ephemeral environments. When piped, the script detects it is running from stdin, clones the repository to `/tmp`, and re-executes itself.
19
+ The TS installer is distributed as a `bunx ndomo` one-shot. It applies the active preset from `config/ndomo.config.json`, copies agents/skills/config to OpenCode's user config dir, and prompts interactively for HTTP server enablement.
20
20
 
21
21
  ```bash
22
- # Quick install (interactive, will prompt for provider)
23
- curl -fsSL https://raw.githubusercontent.com/darrenhinde/OpenAgentsControl/main/install.sh | bash
22
+ # Quick install (interactive, will prompt for HTTP)
23
+ bunx ndomo install
24
24
 
25
- # Non-interactive with provider preset
26
- curl -fsSL https://raw.githubusercontent.com/darrenhinde/OpenAgentsControl/main/install.sh | bash -s -- --provider=opencode --no-provider-prompt
25
+ # Non-interactive with provider preset + HTTP enabled
26
+ bunx ndomo install --provider=opencode --no-provider-prompt --enable-http
27
27
 
28
28
  # With budget preset + DCP
29
- curl -fsSL https://raw.githubusercontent.com/darrenhinde/OpenAgentsControl/main/install.sh | bash -s -- --preset=budget --with-dcp
30
-
31
- # Install from a fork or dev branch
32
- curl -fsSL https://raw.githubusercontent.com/darrenhinde/OpenAgentsControl/main/install.sh | bash -s -- \
33
- --repo=https://github.com/myorg/ndomo-fork \
34
- --branch=dev \
35
- --provider=opencode
29
+ bunx ndomo install --preset=budget --with-dcp
36
30
  ```
37
31
 
38
- The `--repo` and `--branch` flags are only relevant in piped mode; they are ignored when running from a local clone.
32
+ See [docs/installer.md](installer.md) for the full flag reference.
39
33
 
40
34
  ## Install from Git Clone
41
35
 
@@ -48,7 +42,7 @@ cd ndomo
48
42
  bun install
49
43
 
50
44
  # 3. Run the install script
51
- ./scripts/install.sh
45
+ bunx ndomo install
52
46
  ```
53
47
 
54
48
  The install script:
@@ -68,7 +62,7 @@ When developing ndomo (editing agents, skills, config, or source files), use the
68
62
 
69
63
  | Command | When to use | What it does |
70
64
  |---|---|---|
71
- | `./scripts/install.sh` | First install, after cloning, or after changing agents/skills/config | Copies agents, skills, and config to `~/.config/opencode/`. Installs ndomo package. Always preferred for structural changes. |
65
+ | `./scripts/install.sh` or `bunx ndomo install` | First install, after cloning, or after changing agents/skills/config | Copies agents, skills, and config to `~/.config/opencode/`. Installs ndomo package. Always preferred for structural changes. |
72
66
  | `bun run dev:bust` | After editing only `src/*.ts` source files (no agent/skill/config changes) | Quick cache bust: removes stale Bun transpiler cache entries referencing ndomo, bumps mtime on all `src/*.ts` files. Does not kill opencode. |
73
67
  | `bun run dev:reset` | Same as `dev:bust` but when opencode is running and you need a clean restart | `dev:bust` + kills running opencode processes. Run this after editing source to ensure the next `opencode` picks up fresh code. |
74
68
 
@@ -83,7 +77,7 @@ When developing ndomo (editing agents, skills, config, or source files), use the
83
77
 
84
78
  Bun caches transpiled TypeScript modules in `~/.bun/install/cache/` keyed by the **resolved path** of the module. When ndomo is installed via a symlink (e.g., `~/.config/opencode/node_modules/ndomo → /home/nico/ndomo`), the cache key uses the symlink path. Editing source files on the target filesystem does **not** change the symlink path, so Bun serves stale code from cache.
85
79
 
86
- The `file:` dep strategy in `install_ndomo_package()` avoids this by creating a real copy in `node_modules` (no symlink → no stale cache). If you ever end up with a symlink install (from an older `install.sh` version or a manual `ln -s`), re-run `./scripts/install.sh` — it detects the symlink, removes it, and reinstalls as a real copy (`scripts/install.sh` lines 247–254).
80
+ The `file:` dep strategy in `install_ndomo_package()` avoids this by creating a real copy in `node_modules` (no symlink → no stale cache). If you ever end up with a symlink install (from an older `install.sh` version or a manual `ln -s`), re-run `bunx ndomo install` — the installer detects the symlink, removes it, and reinstalls as a real copy.
87
81
 
88
82
  ### Manual cache busting (advanced)
89
83
 
@@ -116,32 +110,31 @@ It is **idempotent** — safe to run multiple times. No-op if the cache is alrea
116
110
  | `--no-provider-prompt` | Skip the interactive provider prompt. The preset is still applied; no provider prefix override is performed. |
117
111
  | `--with-dcp` | Install and configure the DCP plugin (opencode-dynamic-context-pruning) as an optional peer dependency |
118
112
  | `--preset=NAME` | Select preset from `config/ndomo.config.json::presets[NAME]`. The preset is the source of truth for agent models at install time. (default: `default`, options: `default`, `budget`) |
119
- | `--repo=URL` | Override the repository URL (for piped installs from a fork or mirror). Ignored in local clones. |
120
- | `--branch=NAME` | Override the repository branch (for piped installs from `dev`/`feature/*` branches). Ignored in local clones. |
113
+ | `--dry-run` | Print planned changes without writing files. |
114
+ | `--skip-deps` | Skip the dependency installation step (`bun install`). |
115
+ | `--enable-http` | Automatically enable the HTTP server (writes http block to `ndomo.config.json`). |
116
+ | `--disable-http` | Skip the automatic HTTP prompt entirely (default in non-TTY / CI). |
117
+ | `--port=N` | HTTP server port (default: `4097`). |
118
+ | `--cors-origins=CSV` | HTTP CORS origins, comma-separated (default: `*`). |
119
+ | `--auth-required=BOOL` | HTTP auth requirement (default: `true`). |
120
+ | `--uninstall` | Uninstall ndomo (remove config, plugin registration, skill symlinks). |
121
121
 
122
122
  **Environment variable:** `NDOMO_SKIP_PACKAGE_INSTALL=1` — skip the package installation step (`bun install` in `~/.config/opencode/`). Useful if you manage the OpenCode plugin directory manually or if the install step is causing conflicts.
123
123
 
124
124
  Example with all flags:
125
125
 
126
126
  ```bash
127
- # Local clone with all flags
128
- ./scripts/install.sh --with-dcp --preset=budget
129
-
130
- # Piped install with provider, fork, and custom branch
131
- curl -fsSL https://raw.githubusercontent.com/darrenhinde/OpenAgentsControl/main/install.sh | bash -s -- \
132
- --repo=https://github.com/myorg/ndomo-fork \
133
- --branch=dev \
134
- --provider=opencode \
135
- --no-provider-prompt
127
+ # Local clone with HTTP + DCP + budget preset
128
+ bunx ndomo install --with-dcp --preset=budget --enable-http --port=4097
136
129
  ```
137
130
 
138
131
  ## Provider Override
139
132
 
140
- When `install.sh` runs without `--provider` and without `--no-provider-prompt`, it shows the active preset and asks for confirmation. The active preset is the single source of truth for agent models; `--provider=ID` only changes the provider prefix.
133
+ When the installer runs without `--provider` and without `--no-provider-prompt`, it shows the active preset and asks for confirmation. The active preset is the single source of truth for agent models; `--provider=ID` only changes the provider prefix.
141
134
 
142
135
  TTY flow:
143
136
 
144
- 1. The script prints a table of `(agent, preset model, current provider prefix)` derived from `config/ndomo.config.json`.
137
+ 1. The installer prints a table of `(agent, preset model, current provider prefix)` derived from `config/ndomo.config.json`.
145
138
  2. It asks: `Apply preset '$PRESET' as configured? [Y/n/override]`
146
139
  3. `Y` (or Enter) applies the preset, no prefix override.
147
140
  4. `n` skips preset application (warn).
@@ -150,13 +143,13 @@ TTY flow:
150
143
  To skip the prompt and apply the preset silently:
151
144
 
152
145
  ```bash
153
- ./scripts/install.sh --no-provider-prompt
146
+ bunx ndomo install --no-provider-prompt
154
147
  ```
155
148
 
156
149
  To override the provider prefix non-interactively (e.g., use `opencode` instead of `opencode-go` for all agents):
157
150
 
158
151
  ```bash
159
- ./scripts/install.sh --provider=opencode
152
+ bunx ndomo install --provider=opencode
160
153
  ```
161
154
 
162
155
  The provider override works in piped mode:
@@ -165,6 +158,26 @@ The provider override works in piped mode:
165
158
  curl -fsSL https://raw.githubusercontent.com/darrenhinde/OpenAgentsControl/main/install.sh | bash -s -- --provider=opencode --no-provider-prompt
166
159
  ```
167
160
 
161
+ > **Note:** The piped curl|bash method is deprecated. Use `bunx ndomo install --provider=opencode` instead.
162
+
163
+ ## Migration from curl|bash
164
+
165
+ If you previously installed ndomo via piped curl|bash, migrate with:
166
+
167
+ ```bash
168
+ # Old (deprecated, prints warning)
169
+ curl -fsSL https://raw.githubusercontent.com/darrenhinde/OpenAgentsControl/main/install.sh | bash
170
+
171
+ # New (recommended)
172
+ bunx ndomo install
173
+ ```
174
+
175
+ The TS installer covers all flows that the bash script did — local clone, piped install, provider override, preset selection, DCP plugin, plus new HTTP auto-prompt. See [docs/installer.md](installer.md).
176
+
177
+ ## Legacy bash installer (deprecated)
178
+
179
+ `scripts/install.sh` is preserved as a compat shim with a deprecation warning header. It still works for one major version but new installs should use `bunx ndomo install`. The shim re-execs the TS installer after printing the warning.
180
+
168
181
  ## Verify Installation
169
182
 
170
183
  1. Start OpenCode:
@@ -201,6 +214,12 @@ Should show `foreman` as the active agent.
201
214
 
202
215
  ## Uninstall
203
216
 
217
+ ```bash
218
+ bunx ndomo install --uninstall
219
+ ```
220
+
221
+ Or using the legacy bash script:
222
+
204
223
  ```bash
205
224
  ./scripts/uninstall.sh
206
225
  ```
@@ -240,7 +259,7 @@ If `ping all agents` shows no response from one or more agents:
240
259
 
241
260
  1. Verify the config file exists: `ls ~/.config/opencode/ndomo.json`
242
261
  2. Validate the config against the schema: `cat ~/.config/opencode/ndomo.json`
243
- 3. Re-run the install script: `./scripts/install.sh`
262
+ 3. Re-run the install script: `bunx ndomo install`
244
263
  4. Check OpenCode logs for model routing errors — the agent's `model` field in the config must match a model available through your authenticated provider.
245
264
 
246
265
  ### Permission denied on scripts
@@ -254,6 +273,6 @@ chmod +x scripts/install.sh scripts/uninstall.sh
254
273
  If OpenCode doesn't detect ndomo as a plugin:
255
274
 
256
275
  1. Ensure `ndomo` is listed in `config/ndomo.config.json` under `plugins`
257
- 2. Check that the package is installed: `ls ~/.config/opencode/node_modules/ndomo/` — if missing, re-run `./scripts/install.sh` or symlink manually: `ln -sfn $(pwd) ~/.config/opencode/node_modules/ndomo`
276
+ 2. Check that the package is installed: `ls ~/.config/opencode/node_modules/ndomo/` — if missing, re-run `bunx ndomo install` or symlink manually: `ln -sfn $(pwd) ~/.config/opencode/node_modules/ndomo`
258
277
  3. Verify the plugin entry point (`src/index.ts`) compiles without errors: `bun run build`
259
278
  4. Check that the local node_modules were installed: `ls node_modules/ndomo` (or the symlink target)
@@ -0,0 +1,164 @@
1
+ # ndomo Installer Reference
2
+
3
+ TypeScript installer for ndomo. Replaces the legacy `scripts/install.sh` (now deprecated).
4
+
5
+ ## Overview
6
+
7
+ `bunx ndomo install` installs agents, skills, config, and optional HTTP server support into `~/.config/opencode/`. It performs the same phases as the bash installer:
8
+
9
+ 1. Dependency installation (`bun install`)
10
+ 2. TypeScript build
11
+ 3. Agent `.md` files copy with timestamped backups
12
+ 4. Skill directories copy with timestamped backups
13
+ 5. Preset application (model, temperature, reasoningEffort per agent)
14
+ 6. Provider prefix override (optional)
15
+ 7. Config file copy (`ndomo.config.json` -> `ndomo.json`)
16
+ 8. Plugin registration in `opencode.json`
17
+ 9. Package install via 3-strategy cascade (file: dep -> bun link -> manual symlink)
18
+ 10. Tool files copy
19
+ 11. Preset injection into `ndomo.json`
20
+ 12. Optional DCP plugin install
21
+ 13. HTTP auto-prompt (interactive in TTY, skipped in CI)
22
+
23
+ **Invocation:**
24
+
25
+ ```bash
26
+ # Via npm distribution
27
+ bunx ndomo install [OPTIONS]
28
+
29
+ # From local clone
30
+ bun run src/cli/install.ts [OPTIONS]
31
+ ```
32
+
33
+ ## Flags
34
+
35
+ | Flag | Description | Default |
36
+ |------|-------------|---------|
37
+ | `--preset=NAME` | Preset from `config/ndomo.config.json::presets[NAME]` | `default` |
38
+ | `--provider=ID` | Override provider prefix on preset models (e.g., `opencode`, `anthropic`) | (none) |
39
+ | `--no-provider-prompt` | Skip interactive provider override prompt | `false` |
40
+ | `--with-dcp` | Install `@tarquinen/opencode-dcp` (AGPL-3.0 peer) | `false` |
41
+ | `--dry-run` | Print planned changes, do not write | `false` |
42
+ | `--skip-deps` | Skip `bun install` step | `false` |
43
+ | `--enable-http` | Auto-enable HTTP server (writes http block to `ndomo.config.json`) | (interactive prompt) |
44
+ | `--disable-http` | Skip HTTP auto-prompt entirely | `false` |
45
+ | `--port=N` | HTTP server port | `4097` |
46
+ | `--cors-origins=CSV` | HTTP CORS origins (comma-separated) | `*` |
47
+ | `--auth-required=BOOL` | HTTP auth requirement | `true` |
48
+ | `--uninstall` | Run uninstaller (compat shim to `scripts/uninstall.sh`) | `false` |
49
+ | `--help, -h` | Show help | `false` |
50
+
51
+ **Environment variables:**
52
+
53
+ | Variable | Description |
54
+ |----------|-------------|
55
+ | `NDOMO_SKIP_PACKAGE_INSTALL=1` | Skip ndomo package installation entirely |
56
+ | `XDG_CONFIG_HOME` | Override config directory (default: `~/.config`) |
57
+
58
+ ## HTTP Auto-Prompt
59
+
60
+ When invoked in a TTY without `--enable-http` or `--disable-http`, the installer prompts:
61
+
62
+ ```
63
+ [?] Enable ndomo HTTP server? Allows programmatic plan/task control via API.
64
+ Recommended for users integrating ndomo with other tools (port 4097, auth required).
65
+ Enable now? [Y/n]:
66
+ ```
67
+
68
+ **Behavior:**
69
+
70
+ - `Y` / Enter -> writes http block to `config/ndomo.config.json`
71
+ - `n` -> skips, no http block written
72
+ - Non-TTY (CI, scripts) -> silently skips with info log
73
+ - 30-second timeout -> auto-skips
74
+
75
+ **Block written to `config/ndomo.config.json`:**
76
+
77
+ ```json
78
+ {
79
+ "http": {
80
+ "enabled": true,
81
+ "port": 4097,
82
+ "cors": { "origins": ["*"] },
83
+ "auth": { "required": true }
84
+ }
85
+ }
86
+ ```
87
+
88
+ **Precedence:** `ndomo.config.json::http` block > env vars > defaults.
89
+
90
+ Override via flags:
91
+
92
+ ```bash
93
+ bunx ndomo install --enable-http --port=8080 --cors-origins=localhost:3000 --auth-required=false
94
+ ```
95
+
96
+ ## Package Install Strategies
97
+
98
+ The installer attempts three strategies in order to register ndomo as a package in `~/.config/opencode/`:
99
+
100
+ 1. **file: dep + bun install** -- Adds `"ndomo": "file://<project>"` to the config dir's `package.json`, runs `bun install`. Produces a real copy (no symlink). Preferred.
101
+ 2. **bun link** -- Runs `bun link` in the project root, then `bun link ndomo` in the config dir. Produces a managed symlink. May cause Bun cache stale warnings.
102
+ 3. **Manual symlink** -- Last resort. Creates a raw symlink from `node_modules/ndomo` to the project root.
103
+
104
+ Strategy 1 is preferred because it avoids symlink-related cache staleness. If you encounter stale cache warnings, run `bun run dev:bust` to clear the cache and force a real copy.
105
+
106
+ Set `NDOMO_SKIP_PACKAGE_INSTALL=1` to skip package installation entirely.
107
+
108
+ ## Migration from Bash
109
+
110
+ One-liner mapping from `scripts/install.sh` to the new TS installer:
111
+
112
+ | Old (bash) | New (TS) |
113
+ |------------|----------|
114
+ | `curl -fsSL .../install.sh \| bash` | `bunx ndomo install` |
115
+ | `./install.sh --preset=budget` | `bunx ndomo install --preset=budget` |
116
+ | `./install.sh --provider=opencode` | `bunx ndomo install --provider=opencode` |
117
+ | `./install.sh --with-dcp` | `bunx ndomo install --with-dcp` |
118
+ | `./install.sh --no-provider-prompt` | `bunx ndomo install --no-provider-prompt` |
119
+ | `./install.sh --uninstall` | `bunx ndomo install --uninstall` |
120
+
121
+ The bash version is preserved for backward-compatibility (e.g., pipe-mode from raw GitHub URL) but is deprecated and will be removed in a future major version.
122
+
123
+ ## Troubleshooting
124
+
125
+ ### "bun is not installed"
126
+
127
+ Install bun first:
128
+
129
+ ```bash
130
+ curl -fsSL https://bun.sh/install | bash
131
+ ```
132
+
133
+ ### "No agents/ directory found"
134
+
135
+ Run from a ndomo clone. The installer expects `agents/`, `skills/`, `config/`, and `tools/` directories at the project root.
136
+
137
+ ### HTTP not responding after --enable-http
138
+
139
+ 1. Check that `bun run src/cli/serve.ts` starts without errors.
140
+ 2. Ensure `OPENCODE_SERVER_PASSWORD` env var is set (HTTP auth requires it).
141
+ 3. Verify port 4097 is not in use: `lsof -i :4097`.
142
+
143
+ ### Symlink stale cache warning
144
+
145
+ Run `bun run dev:bust` to clear the Bun cache and reinstall ndomo as a real copy via the file: dep strategy (strategy 1).
146
+
147
+ ### Package install strategy 2 (bun link) fails
148
+
149
+ The installer automatically falls back to strategy 3 (manual symlink). If you want to skip package installation entirely, set:
150
+
151
+ ```bash
152
+ export NDOMO_SKIP_PACKAGE_INSTALL=1
153
+ bunx ndomo install
154
+ ```
155
+
156
+ ### Preset not found
157
+
158
+ The installer validates the preset name against `config/ndomo.config.json::presets` before proceeding. Check available presets:
159
+
160
+ ```bash
161
+ grep -o '"[a-z]*":' config/ndomo.config.json | head -20
162
+ ```
163
+
164
+ Default presets: `default`, `budget`.
@@ -48,7 +48,7 @@ DCP monitors context token usage and, on request or automatically, prunes low-va
48
48
  ### How to install
49
49
 
50
50
  ```bash
51
- ./scripts/install.sh --with-dcp
51
+ bunx ndomo install --with-dcp
52
52
  ```
53
53
 
54
54
  This installs `@tarquinen/opencode-dcp` as an optional peer dependency.
package/docs/web-ui.md ADDED
@@ -0,0 +1,124 @@
1
+ # Web UI
2
+
3
+ The ndomo HTTP server serves a Vue 3 single-page application (SPA) from the same port as the REST API. The UI provides read-only visibility into plans, tasks, and sessions.
4
+
5
+ ## Architecture (single-port topology)
6
+
7
+ ```
8
+ Browser ──HTTP──> Elysia :4097 ──/api/*──> JSON responses (auth required)
9
+ └──/*──> Vue SPA build artifacts from src/http/web/
10
+ ```
11
+
12
+ - **One process**, one port. No CORS in production.
13
+ - **SPA fallback**: any non-`/api` GET request that doesn't match a static asset returns `src/http/web/index.html` (Vue Router hash mode — routes live in the URL fragment, e.g. `/#/plans/123`).
14
+ - **Auth**: Basic Auth via `OPENCODE_SERVER_PASSWORD`. Browser prompts on first visit, password stored in `sessionStorage`.
15
+ - **Read-only MVP**: all current API endpoints are GET; no write UI yet.
16
+
17
+ ## Build pipeline
18
+
19
+ ```
20
+ web/src/ (Vue 3 SFCs, TS, CSS)
21
+
22
+ │ bun run web:build
23
+
24
+ src/http/web/ (built artifacts — gitignored, regenerated)
25
+ ├── index.html
26
+ └── assets/
27
+ ├── index-*.js (hashed JS bundles)
28
+ └── index-*.css (hashed CSS bundles)
29
+ ```
30
+
31
+ - `bun run web:dev` — Vite dev server on `:5173` with `/api` proxy to `:4097` Elysia. Use for SPA development (HMR).
32
+ - `bun run web:build` — production build to `src/http/web/`. Required before starting Elysia for production.
33
+ - `bun run web:typecheck` — vue-tsc strict mode check.
34
+ - `bun run web:test` — Vitest unit tests (api client, composables, components).
35
+
36
+ ## Running locally
37
+
38
+ 1. Build the SPA: `bun run web:build`
39
+ 2. Start the server: `NDOMO_HTTP_ENABLED=true OPENCODE_SERVER_PASSWORD=secret bun run src/cli/serve.ts`
40
+ 3. Open `http://localhost:4097/` in your browser.
41
+ 4. Enter the password when prompted.
42
+
43
+ Vite dev mode (HMR):
44
+
45
+ 1. Terminal 1: `NDOMO_HTTP_ENABLED=true OPENCODE_SERVER_PASSWORD=secret bun run src/cli/serve.ts`
46
+ 2. Terminal 2: `bun run web:dev`
47
+ 3. Open `http://localhost:5173/` — Vite proxies `/api/*` to Elysia.
48
+
49
+ ## Deployment
50
+
51
+ Single binary / single process. No reverse proxy required for MVP. For production behind nginx/Caddy:
52
+
53
+ - Proxy `/api/*` and all other paths to Elysia on `:4097`.
54
+ - The SPA serves static assets with relative paths (`base: './'` in `vite.config.ts`), so it works under any sub-path.
55
+
56
+ ## Security
57
+
58
+ - **Basic Auth** on `/api/*` (handled by Elysia middleware). `/health` and `/` are public.
59
+ - **Browser stores password in sessionStorage** (cleared on tab close). NOT localStorage. NOT cookies.
60
+ - **Same-origin only**: the SPA assumes it lives behind the same origin as the API. Cross-origin deployments require explicit CORS configuration.
61
+ - **SSE limitation**: `EventSource` cannot send custom headers in browsers. The MVP stubs the SSE composable and uses polling. A future iteration will switch to `fetch` + `ReadableStream` for SSE with auth.
62
+
63
+ ## Extension guide (adding new panels)
64
+
65
+ To add a new view (e.g., Sessions browser):
66
+
67
+ 1. Create `web/src/views/SessionsView.vue`.
68
+ 2. Register the route in `web/src/router/index.ts`:
69
+ ```ts
70
+ { path: "/sessions", name: "sessions", component: () => import("@/views/SessionsView.vue") }
71
+ ```
72
+ 3. Add a nav link in `web/src/components/AppShell.vue` sidebar.
73
+ 4. Add API client functions in `web/src/api/sessions.ts` (or new file).
74
+ 5. Add types in `web/src/types/api.ts`.
75
+ 6. Add a Vitest test in `web/__tests__/`.
76
+
77
+ No backend changes needed if the API already exists. Elysia auto-serves the new SPA build on next `bun run web:build`.
78
+
79
+ ## Tests
80
+
81
+ - **Unit (Vitest)**: `bun run web:test` — api client, composables, components.
82
+ - **Integration**: `src/http/__tests__/spa.test.ts` — boots Elysia with fake SPA dist, tests static serving, SPA fallback, 503 when unbuilt.
83
+
84
+ ## File map
85
+
86
+ ```
87
+ web/
88
+ ├── index.html
89
+ ├── vite.config.ts
90
+ ├── vitest.config.ts
91
+ ├── tsconfig.json
92
+ ├── src/
93
+ │ ├── main.ts
94
+ │ ├── App.vue
95
+ │ ├── api/ # fetch wrappers (plans, tasks, sessions, client)
96
+ │ ├── components/ # AppShell, AuthPrompt, StatusBadge, etc.
97
+ │ ├── composables/ # useApi, useAuth, useEvents (stubbed)
98
+ │ ├── router/ # vue-router config (hash mode)
99
+ │ ├── styles/ # tokens.css + globals.css
100
+ │ ├── types/ # api.ts (Plan, Task, Session, etc.)
101
+ │ └── views/ # Dashboard, PlanList, PlanDetail, TaskDetail, NotFound
102
+ └── __tests__/ # Vitest specs
103
+ ```
104
+
105
+ ## Environment variables
106
+
107
+ | var | purpose | default |
108
+ |---|---|---|
109
+ | `VITE_API_BASE` | Override API base URL (Vite build-time) | empty (same-origin) |
110
+ | `OPENCODE_SERVER_PASSWORD` | HTTP Basic Auth password | required when `http.auth.required=true` |
111
+ | `NDOMO_HTTP_ENABLED` | Enable HTTP server | `false` |
112
+ | `NDOMO_HTTP_PORT` | HTTP server port | `4097` |
113
+
114
+ ## Known limitations
115
+
116
+ - SSE deferred (auth limitation in `EventSource`). MVP polls.
117
+ - No write UI yet (all API endpoints are GET-only).
118
+ - Hash mode routing: URLs include `#` (e.g., `localhost:4097/#/plans`). Clean URLs require switching to `createWebHistory` + server-side history fallback.
119
+
120
+ ## See also
121
+
122
+ - [`docs/http-server.md`](http-server.md) — REST API reference, CLI flags, CORS, security headers
123
+ - [`.env.example`](../.env.example) — annotated env reference
124
+ - [`README.md`](../README.md) — quickstart + features
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ndomo",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "OpenCode multi-agent plugin. Taller de artesanos: foreman + 3 peer primaries (craftsman, warden, ranger) + specialists (scout, scribe, painter, smith, sage, guild, inspector, chronicler) + stack-smiths + ops (ci-smith, deploy-smith, release-smith, ops-scout). Caveman-native. opencode-mem integrated. DCP peer optional.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -10,7 +10,33 @@
10
10
  "./plugin": "./src/plugin.ts",
11
11
  "./db": "./src/db/index.ts"
12
12
  },
13
- "private": false,
13
+ "bin": {
14
+ "ndomo": "./src/cli/index.ts"
15
+ },
16
+ "files": [
17
+ ".env.example",
18
+ "agents",
19
+ "bun.lock",
20
+ "config",
21
+ "docs",
22
+ "README.md",
23
+ "scripts/install.sh",
24
+ "scripts/smoke-http.sh",
25
+ "scripts/smoke-install.sh",
26
+ "scripts/smoke-web.sh",
27
+ "scripts/smoke.sh",
28
+ "skills",
29
+ "src/cli",
30
+ "src/config",
31
+ "src/db",
32
+ "src/http",
33
+ "src/sdk",
34
+ "tools"
35
+ ],
36
+ "publishConfig": {
37
+ "access": "public",
38
+ "registry": "https://registry.npmjs.org/"
39
+ },
14
40
  "engines": {
15
41
  "bun": ">=1.1.0"
16
42
  },
@@ -22,12 +48,16 @@
22
48
  "lint:fix": "biome check --write .",
23
49
  "format": "biome format --write .",
24
50
  "test": "bun test",
51
+ "test:web": "vitest run --config web/vitest.config.ts",
25
52
  "test:smoke": "bash scripts/smoke.sh",
26
53
  "dev:bust": "bash scripts/dev-bust-cache.sh --apply",
27
54
  "dev:reset": "bash scripts/dev-bust-cache.sh --apply --kill",
28
55
  "status:plans": "bun run src/cli/status.ts --plans",
29
56
  "clean": "rm -rf dist .slim/worktrees",
30
- "prepare": "husky"
57
+ "web:dev": "vite --config web/vite.config.ts",
58
+ "web:build": "vite build --config web/vite.config.ts",
59
+ "web:typecheck": "vue-tsc --noEmit -p web/tsconfig.json",
60
+ "web:test": "vitest run --config web/vitest.config.ts"
31
61
  },
32
62
  "dependencies": {
33
63
  "@opencode-ai/sdk": "1.17.7",
@@ -47,8 +77,17 @@
47
77
  "@commitlint/cli": "^19.0.0",
48
78
  "@commitlint/config-conventional": "^19.0.0",
49
79
  "@types/bun": "latest",
80
+ "@vitejs/plugin-vue": "^5.1.0",
81
+ "@vue/test-utils": "^2.4.6",
82
+ "@vueuse/core": "^11.0.0",
83
+ "happy-dom": "^15.0.0",
50
84
  "husky": "^9.0.0",
51
- "typescript": "^6.0.0"
85
+ "typescript": "^6.0.0",
86
+ "vite": "^6.0.0",
87
+ "vitest": "^2.1.0",
88
+ "vue": "^3.5.0",
89
+ "vue-router": "^4.4.0",
90
+ "vue-tsc": "^2.1.0"
52
91
  },
53
92
  "keywords": [
54
93
  "opencode",
@@ -3,6 +3,34 @@
3
3
  # Usage: ./install.sh [OPTIONS]
4
4
  # curl -fsSL https://raw.githubusercontent.com/darrenhinde/OpenAgentsControl/main/install.sh | bash
5
5
 
6
+ # ─────────────────────────────────────────────────────────────────────────────
7
+ # ⚠️ DEPRECATED: scripts/install.sh is the legacy bash installer.
8
+ # ─────────────────────────────────────────────────────────────────────────────
9
+ # This script is preserved for backward-compat (e.g., pipe-mode installs from
10
+ # raw GitHub URL). It will be removed in a future major version.
11
+ #
12
+ # ✅ USE THE NEW TS INSTALLER INSTEAD:
13
+ #
14
+ # bunx ndomo install [OPTIONS]
15
+ #
16
+ # New features vs. this bash version:
17
+ # • Full parity with install.sh (same flags, same phases, same package install
18
+ # strategies, same preset application, same opencode.json plugin registration)
19
+ # • NEW: HTTP auto-prompt — interactively enables HTTP server (writes http
20
+ # block to ndomo.config.json) — closes the gap left by phase-1
21
+ # • NEW: --dry-run, --skip-deps, --port, --cors-origins, --auth-required flags
22
+ # • Honors XDG_CONFIG_HOME per XDG Base Directory spec
23
+ # • Cross-platform (no BSD/GNU sed differences)
24
+ # • Tested via bun:test (src/cli/__tests__/install.test.ts)
25
+ #
26
+ # Migration (one-liner):
27
+ # curl ... | bash → bunx ndomo install
28
+ # ./install.sh --preset=budget → bunx ndomo install --preset=budget
29
+ # ./install.sh --with-dcp → bunx ndomo install --with-dcp
30
+ #
31
+ # See docs/installer.md for full flag reference.
32
+ # ─────────────────────────────────────────────────────────────────────────────
33
+
6
34
  # ── Pipe detection (must be first, before set -e) ──────────────────────────────
7
35
  # When invoked via pipe/stdin, clone repo to temp dir and re-exec from disk.
8
36
  if [[ -z "${BASH_SOURCE[0]:-}" || "${BASH_SOURCE[0]}" == "bash" || "${BASH_SOURCE[0]}" == "/dev/stdin" ]]; then