teamshare-bridge 0.22.7 → 0.22.8

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 (82) hide show
  1. package/README.md +383 -383
  2. package/dist/bridge/daemon.js +43 -20
  3. package/dist/bridge/daemon.js.map +1 -1
  4. package/dist/bridge/install-verify.js +8 -8
  5. package/dist/bridge/spawn.d.ts +14 -0
  6. package/dist/bridge/spawn.js +7 -1
  7. package/dist/bridge/spawn.js.map +1 -1
  8. package/dist/bridge/wake-handler.d.ts +8 -15
  9. package/dist/bridge/wake-handler.js +109 -14
  10. package/dist/bridge/wake-handler.js.map +1 -1
  11. package/dist/bridge/wake-outbox.js +7 -0
  12. package/dist/bridge/wake-outbox.js.map +1 -1
  13. package/dist/cli/commands/plan.js +4 -0
  14. package/dist/cli/commands/plan.js.map +1 -1
  15. package/dist/lib/browser/human-input-guard.js +98 -98
  16. package/dist/lib/browser/screen-change.js +60 -60
  17. package/dist/lib/llm/usage-reader.js +4 -4
  18. package/dist/lib/workspace/classify.d.ts +29 -0
  19. package/dist/lib/workspace/classify.js +62 -0
  20. package/dist/lib/workspace/classify.js.map +1 -1
  21. package/dist/lib/workspace/presence.d.ts +31 -0
  22. package/dist/lib/workspace/presence.js +35 -1
  23. package/dist/lib/workspace/presence.js.map +1 -1
  24. package/dist/lib/workspace/shim-runner.js +23 -0
  25. package/dist/lib/workspace/shim-runner.js.map +1 -1
  26. package/package.json +70 -70
  27. package/skills/THIRD_PARTY_NOTICES.md +26 -26
  28. package/skills/architect/LICENSE +21 -21
  29. package/skills/codebase-design/LICENSE +21 -21
  30. package/skills/diagnosing-bugs/LICENSE +21 -21
  31. package/skills/domain-modeling/LICENSE +21 -21
  32. package/skills/improve-codebase-architecture/LICENSE +21 -21
  33. package/skills/recover/LICENSE +21 -21
  34. package/skills/review/LICENSE +21 -21
  35. package/skills/tdd/LICENSE +21 -21
  36. package/skills/teamshare-auth-rbac/SKILL.md +78 -78
  37. package/skills/teamshare-cdd/SKILL.md +205 -205
  38. package/skills/teamshare-modularity/SKILL.md +146 -146
  39. package/skills/teamshare-orchestrator-ask/SKILL.md +77 -77
  40. package/skills/teamshare-scaffold/SKILL.md +116 -116
  41. package/templates/backend/.env.example.tpl +13 -13
  42. package/templates/backend/nest-cli.json.tpl +8 -8
  43. package/templates/backend/package.json.tpl +41 -41
  44. package/templates/backend/prisma/schema.prisma.tpl +39 -39
  45. package/templates/backend/src/app.module.ts.tpl +24 -24
  46. package/templates/backend/src/common/filters/all-exceptions.filter.ts.tpl +59 -59
  47. package/templates/backend/src/common/guards/jwt-auth.guard.ts.tpl +27 -27
  48. package/templates/backend/src/common/guards/rbac.guard.ts.tpl +48 -48
  49. package/templates/backend/src/common/interceptors/transform.interceptor.ts.tpl +44 -44
  50. package/templates/backend/src/common/pipes/zod-validation.pipe.ts.tpl +29 -29
  51. package/templates/backend/src/common/swagger/envelope.schemas.ts.tpl +53 -53
  52. package/templates/backend/src/common/swagger/error.schemas.ts.tpl +62 -62
  53. package/templates/backend/src/main.ts.tpl +27 -27
  54. package/templates/backend/src/modules/example/example.controller.ts.tpl +102 -102
  55. package/templates/backend/src/modules/example/example.dto.ts.tpl +14 -14
  56. package/templates/backend/src/modules/example/example.module.ts.tpl +10 -10
  57. package/templates/backend/src/modules/example/example.service.ts.tpl +45 -45
  58. package/templates/backend/tsconfig.json.tpl +26 -26
  59. package/templates/common/.gitignore.tpl +42 -42
  60. package/templates/common/AGENTS.md.tpl +58 -58
  61. package/templates/common/docs/adr/README.md +25 -25
  62. package/templates/common/docs/api-contract.md.tpl +72 -72
  63. package/templates/web/next.config.ts.tpl +7 -7
  64. package/templates/web/package.json.tpl +37 -37
  65. package/templates/web/src/app/globals.css.tpl +48 -48
  66. package/templates/web/src/app/layout.tsx.tpl +25 -25
  67. package/templates/web/src/components/shared/app-button.tsx.tpl +59 -59
  68. package/templates/web/src/components/shared/app-empty-state.tsx.tpl +39 -39
  69. package/templates/web/src/components/shared/app-list-toolbar.tsx.tpl +63 -63
  70. package/templates/web/src/components/shared/app-skeleton.tsx.tpl +14 -14
  71. package/templates/web/src/components/shared/app-table.tsx.tpl +128 -128
  72. package/templates/web/src/components/shared/index.ts.tpl +5 -5
  73. package/templates/web/src/hooks/use-list-state.ts.tpl +72 -72
  74. package/templates/web/src/hooks/use-url-tab.ts.tpl +25 -25
  75. package/templates/web/src/lib/api/client.ts.tpl +123 -123
  76. package/templates/web/src/lib/providers.tsx.tpl +35 -35
  77. package/templates/web/src/lib/query-keys.ts.tpl +21 -21
  78. package/templates/web/src/lib/utils.ts.tpl +7 -7
  79. package/templates/web/src/lib/validation/schemas.ts.tpl +15 -15
  80. package/templates/web/src/modules/example/views/example-list-view.tsx.tpl +97 -97
  81. package/templates/web/tsconfig.json.tpl +23 -23
  82. package/tools/workspace-arbitration-check.mjs +389 -389
package/README.md CHANGED
@@ -1,383 +1,383 @@
1
- # teamshare-bridge
2
-
3
- The local bridge that lets AI agents work TeamShare tasks from your machine.
4
-
5
- TeamShare is the **coordination hub**: agents are registered in the app
6
- (identity, capabilities, task assignments, run history). The AI itself runs
7
- here — on your computer — connected to TeamShare through three methods, all
8
- provided by this package:
9
-
10
- | Method | Binary | Trigger | Requirements |
11
- |---|---|---|---|
12
- | **Terminal session** | `teamshare-agent` | You paste a command (or click "Copy run command" in the app) | Node 18+, no daemon |
13
- | **Auto-wake daemon** | `teamshare-bridge start` | A task is assigned to your agent (or it is @mentioned) → the daemon spawns a session automatically | The daemon must be running (`autostart on` keeps it alive across reboots) |
14
- | **Run button (deep link)** | `teamshare-bridge register` + `serve` | The TeamShare website's "Run agent" button hands off via `teamshare://` | One-time registration; OS cold-launches the bridge |
15
-
16
- All three share the same core: fetch a task brief (task, comments, project
17
- files), drive a working session (opencode / Claude / built-in headless LLM
18
- loop), and report back through the TeamShare API.
19
-
20
- ---
21
-
22
- ## Install
23
-
24
- Requires **Node.js 18+**. One shot (Windows):
25
-
26
- ```powershell
27
- irm https://raw.githubusercontent.com/dominionbanjo/teamshare-bridge/main/scripts/install.ps1 | iex
28
- ```
29
-
30
- One shot (macOS/Linux):
31
-
32
- ```sh
33
- curl -fsSL https://raw.githubusercontent.com/dominionbanjo/teamshare-bridge/main/scripts/install.sh | bash
34
- ```
35
-
36
- Or install directly from npm (global):
37
-
38
- ```sh
39
- npm i -g teamshare-bridge # published package
40
- npm i -g . # from this repo
41
- ```
42
-
43
- You now have two commands:
44
-
45
- ```sh
46
- teamshare-agent # CLI session runner (methods 1)
47
- teamshare-bridge # daemon + protocol handler (methods 2 and 3)
48
- ```
49
-
50
- ## Run
51
-
52
- ```sh
53
- teamshare-bridge start # daemon in the background (pid file + ~/.teamshare/daemon.log)
54
- teamshare-bridge stop # stop it
55
- teamshare-bridge restart # stop + start
56
- teamshare-bridge status # pid/log/autostart + per-agent busy/idle
57
- teamshare-bridge daemon # foreground (debugging)
58
- teamshare-bridge autostart on # start at login: Task Scheduler (admin) or Startup-folder launcher (no admin)
59
- teamshare-bridge autostart off # remove it
60
- ```
61
-
62
- ## Quick start
63
-
64
- ```sh
65
- # 1. Save your agent's key (from the app: Agents → your agent → Launch Console)
66
- teamshare-agent connect --agent <agent-id> --key ts_...
67
-
68
- # 2a. Work one task explicitly
69
- teamshare-agent run --task <task-id> --agent <agent-id> --key ts_...
70
-
71
- # 2b. Or let the agent pick up its next assigned task (priority first, then oldest)
72
- teamshare-agent run --agent <agent-id> --key ts_...
73
-
74
- # 2c. Auto-wake: keep the daemon running, sessions spawn on assignment
75
- teamshare-bridge start
76
- teamshare-bridge autostart on # ...and it comes back after a reboot
77
-
78
- # 3. Run button on the website (registers the teamshare:// scheme)
79
- teamshare-bridge register
80
- ```
81
-
82
- ### Headless mode (no harness, no opencode/Claude — just an LLM API key)
83
-
84
- ```sh
85
- LLM_BASE_URL=https://openrouter.ai/api/v1 \
86
- LLM_API_KEY=sk-... \
87
- LLM_MODEL=deepseek/deepseek-chat \
88
- teamshare-agent run --task <task-id> --agent <agent-id> --key ts_... --self
89
- ```
90
-
91
- The headless loop is an OpenAI-compatible **function-calling** loop: the model
92
- gets the task brief plus tools (`get_task`, `list_tasks`, `create_task`,
93
- `update_task`, `add_comment`, `list_documents`, `read_document`, `search`,
94
- `ask_human`, `wait_for_answer`, `list_subtasks`, `create_subtask`,
95
- `update_subtask`). It is instructed to break the task into 3-8 real
96
- subtasks (`create_subtask`) and check each off (`update_subtask done: true`)
97
- as work progresses — the human sees the live breakdown in the app. It posts
98
- milestone comments and finishes by moving the task to `in_review` /
99
- `resolved`. Any OpenAI-compatible endpoint works (OpenAI, DeepSeek, OpenRouter,
100
- Together, local vLLM/Ollama…).
101
-
102
- **One session per agent:** `run`/`chat`/`doc` acquire a per-agent lock
103
- (`~/.teamshare/locks/<agentId>.lock`, auto-released on exit, stale locks
104
- reclaimed) and wait for a busy agent instead of starting a second session.
105
- The daemon queues wakes for a busy agent and spawns them when it frees up;
106
- `teamshare-bridge status` shows `BUSY` per agent.
107
-
108
- ---
109
-
110
- ## How a session works
111
-
112
- 1. **Heartbeat** — the agent's status flips to `working` in the app.
113
- 2. **Brief** — the CLI fetches the task (description, comment thread, project
114
- name) and downloads project files (text files truncated to ~20k chars;
115
- links return their URL). The brief is written to
116
- `<temp>/teamshare-task-<taskId>.md` and printed as a preview.
117
- 3. **Work** — either a harness is spawned (`opencode run "…"`, `claude -p "…"`,
118
- auto-detected in that order) or the `--self` LLM loop runs.
119
- 4. **Report** — a closing summary comment is posted (skip with `--no-report`).
120
- 5. **Watch** — the CLI polls the task status every 15s (up to 20 min) until it
121
- leaves `open`/`in_progress`, then heartbeats back to `online`.
122
-
123
- ## Command reference
124
-
125
- ### `teamshare-agent`
126
-
127
- ```
128
- teamshare-agent connect --agent <id> --key <ts_...>
129
- Test the connection and save the agent key in ~/.teamshare/config.json.
130
-
131
- teamshare-agent run --task <taskId> --agent <id> --key <ts_...> [options]
132
- Work a specific task. Without --task, picks the agent's next assigned task
133
- from its inbox (urgent > high > medium > low, then oldest; skips
134
- in_review/resolved/closed).
135
-
136
- teamshare-agent chat --project <projectId> --agent <id> --key <ts_...> [--mention <token>]
137
- Reply to every project-chat message that @mentions the agent. Replies
138
- stream token-by-token into the channel when the provider supports it
139
- (Phase C); the final message is still posted via the API.
140
-
141
- teamshare-agent doc --document <documentId> --agent <id> --key <ts_...> [--mention <token>]
142
- Document assistant (Phase F): read the document (Word/PPT/Excel/PDF text
143
- via GET /documents/:id/extract) and reply to every comment that @mentions
144
- the agent in its thread.
145
-
146
- teamshare-agent continue --task <taskId> --agent <id> --key <ts_...> [--self]
147
- Resume a previous --self session for a task (Phase E continuation).
148
-
149
- teamshare-agent build --project <id> --agent <id> --key <ts_...> [options]
150
- Run the build loop: work readyForDev tasks strictly in order (sortOrder
151
- asc, createdAt asc), one at a time, fully completing each before moving on.
152
-
153
- teamshare-agent build --project <id> --agent <id> --key <ts_...>
154
- Full loop: work all pending tasks until the queue is empty.
155
-
156
- teamshare-agent build ... --draft "<goal>"
157
- Plan a build queue from a goal string. The LLM reads the project
158
- documents, creates tasks via MCP, and orders them — then pauses
159
- for you to review before executing.
160
-
161
- teamshare-agent build ... --draft "<goal>" --go
162
- Plan and execute immediately (skip the review prompt).
163
-
164
- --once Work one task then exit
165
- --dry-run Print the queue plan without executing
166
- --on-fail ask|stop What to do on task failure (default: ask)
167
- --blocked-wait <min> Wait N minutes for an answer before quitting
168
-
169
- Prerequisites: a provider API key (LLM_API_KEY or agent settings),
170
- a linked project folder (teamshare-agent link --project <id> --path <dir>),
171
- and the bridge daemon running (teamshare-bridge start).
172
-
173
- teamshare-agent skills install [--force] | list | uninstall
174
- Install the 14 bundled opencode skills into ~/.agents/skills (override with
175
- TEAMSHARE_SKILLS_DIR). TeamShare-owned skills are always refreshed; vendored
176
- engineering skills are only copied when absent (or with --force). A manifest
177
- (~/.agents/skills/.teamshare-bundled.json) tracks what this bridge installed,
178
- so uninstall never removes independently-installed skills.
179
-
180
- teamshare-agent --help
181
- ```
182
-
183
- Model precedence: **CLI flag > agent settings (set in the app, delivered via
184
- deep link or auto-wake) > env (`LLM_MODEL`/`LLM_TEMPERATURE`/`LLM_MAX_TOKENS`)
185
- > defaults**. Model ids use the curated `<provider>:<model>` catalog
186
- (`docs/agent-models.md`) — the provider's OpenAI-compatible base URL is
187
- resolved automatically; `LLM_BASE_URL` always wins when set.
188
-
189
- ### `teamshare-bridge`
190
-
191
- ```
192
- teamshare-bridge daemon [--port N]
193
- Auto-wake listener: keeps a WebSocket to TeamShare per configured agent
194
- and spawns a session on wake events (task assigned, @mention in a comment
195
- or chat). Also serves the localhost probe the website detects.
196
-
197
- teamshare-bridge register
198
- Registers the teamshare:// URI scheme (per-user; Windows registry /
199
- macOS app bundle / Linux .desktop). No admin rights needed.
200
-
201
- teamshare-bridge serve "<teamshare://agent/run?runToken=...&task=...>"
202
- OS-invoked: redeems the run token and spawns the session.
203
-
204
- teamshare-bridge add-agent --agent <id> --key <ts_...>
205
- Saves an agent key without testing the connection.
206
-
207
- teamshare-bridge status [--port N]
208
- Shows config path, port, per-agent BUSY/idle (stale locks flagged),
209
- harness, quiet hours, scheme.
210
-
211
- teamshare-bridge clear-lock --agent <id>
212
- Force-removes a stale session lock. Crashed sessions (dead PID) and
213
- locks older than 8h are auto-reclaimed; this is the manual override.
214
-
215
- teamshare-bridge probe [--port N]
216
- Starts just the localhost probe server (for testing).
217
- ```
218
-
219
- ## Build mode quick start
220
-
221
- ```sh
222
- # 1. Link your project folder
223
- teamshare-agent link --project <project-id> --path ./my-project
224
-
225
- # 2. Plan a build queue from a goal (pauses for review)
226
- teamshare-agent build --project <project-id> --agent <agent-id> --key ts_... \
227
- --draft "Set up user auth: login, signup, JWT middleware, password reset"
228
-
229
- # 3. Review the plan, then execute
230
- # (or skip review with --draft "..." --go)
231
-
232
- # 4. Start the build loop
233
- teamshare-agent build --project <project-id> --agent <agent-id> --key ts_...
234
- ```
235
-
236
- ## Configuration
237
-
238
- `~/.teamshare/config.json` — created on first run with defaults:
239
-
240
- ```json
241
- {
242
- "agents": [{ "agentId": "...", "apiKey": "ts_..." }],
243
- "port": 48242,
244
- "harness": "auto",
245
- "quietHours": null,
246
- "wakeRules": null
247
- }
248
- ```
249
-
250
- | Key | Meaning |
251
- |---|---|
252
- | `agents` | Agent id + API key pairs the daemon listens for (`teamshare-agent connect` / `teamshare-bridge add-agent` populate this) |
253
- | `port` | Localhost probe port. Picked at **random** from `[48231, 48242, 48253, 48264, 48275, 48286, 48297]` on first run; the website probes all candidates, so any pick is discoverable. Override with `--port`. |
254
- | `harness` | Preferred session driver: `auto`, `opencode`, `claude`, `none` |
255
- | `quietHours` | `{ "start": "22:00", "end": "07:00" }` — wake events are ignored during this window |
256
- | `wakeRules` | `{ "priorities": ["high", "urgent"] }` — only wake for tasks matching these priorities |
257
-
258
- ## Environment variables
259
-
260
- | Variable | Default | Used by |
261
- |---|---|---|
262
- | `TEAMSHARE_API_URL` | `https://api.teamshare.name.ng` | all commands |
263
- | `TEAMSHARE_WS_URL` | `wss://api.teamshare.name.ng` | daemon + live console + streaming |
264
- | `LLM_BASE_URL` | (catalog per model) | `--self`, chat/doc replies |
265
- | `LLM_API_KEY` | — (required for `--self`) | `--self`, chat/doc replies |
266
- | `LLM_MODEL` | `deepseek-chat` | `--self` (catalog ids resolve the base URL) |
267
- | `LLM_TEMPERATURE` | `0.2` | `--self`, chat/doc replies |
268
- | `LLM_MAX_TOKENS` | — (provider default) | `--self`, chat/doc replies |
269
- | `TEAMSHARE_ASK_TIMEOUT` | `900` (seconds) | `ask_human` wait limit |
270
- | `TS_CHAT_ECHO` | — | Debug: post canned acknowledgments (deterministic E2E) |
271
-
272
- ## Live console & streaming
273
-
274
- - Every session (`run`/`chat`/`doc`) opens its own `/agents` socket and emits
275
- `session:start` / `session:output` (batched ~200ms) / `session:end` — the
276
- app's **Live console** on the agent detail page shows the output in real
277
- time, and a capped transcript is persisted server-side at the end.
278
- - Local mirror + continuation history: `~/.teamshare/sessions/`
279
- (`<sessionId>.json` transcripts, `task-<taskId>.json` for `--continue`).
280
- - Chat replies additionally stream into the project channel as
281
- `message:partial` frames over a `/chat` socket (apiKey auth) — the web UI
282
- renders a live draft bubble that is swapped for the persisted message.
283
-
284
- ## The localhost probe
285
-
286
- The website detects the bridge by calling `GET http://localhost:<port>/ping`
287
- with permissive CORS (the browser can reach it from the web app):
288
-
289
- ```json
290
- { "ok": true, "version": "0.1.0", "agents": ["<agent-id>"] }
291
- ```
292
-
293
- When the probe answers, the app shows "Bridge detected on this computer" and
294
- enables the **Run agent** button; otherwise it degrades gracefully to the
295
- copy-paste command.
296
-
297
- ## Security model
298
-
299
- - **Agent API keys** (`ts_...`) are minted by TeamShare with scopes derived
300
- from the agent's capabilities and can never exceed them; the raw key is
301
- shown only once in the app. Store it via `connect` — it lives in
302
- `~/.teamshare/config.json` (chmod 600 on unix).
303
- - **Run tokens** in `teamshare://` deep links are short-lived (10 min),
304
- single-use, and exchanged server-side for a session credential — the
305
- long-lived key never appears in a URL.
306
- - The bridge never sees environment-variable values; TeamShare's viewer-denied
307
- rule extends to agents automatically.
308
- - The probe server binds to `127.0.0.1` only.
309
-
310
- ## Platform notes
311
-
312
- | Platform | Terminal spawn | Protocol registration |
313
- |---|---|---|
314
- | Windows | `cmd /c start cmd /k …` (detached window, stays open) | `HKCU\Software\Classes\teamshare` via `reg.exe`, per-user |
315
- | macOS | Terminal.app via `osascript` (always present, no installs) | `~/Applications/TeamShareBridge.app` (CFBundleURLTypes); open the bundle once |
316
- | Linux (desktop) | `xdg-terminal-exec` → `gnome-terminal` → `konsole` → `xterm` (first found on PATH) | `~/.local/share/applications/teamshare-bridge.desktop` (`x-scheme-handler/teamshare`) |
317
- | Linux (server/SSH) | Headless fallback — no window; watch via the web live console | n/a |
318
-
319
- ## Troubleshooting
320
-
321
- | Symptom | Fix |
322
- |---|---|
323
- | `EADDRINUSE` on probe | `--port <candidate>` or delete the `port` key from config; the website probes all candidates |
324
- | "Agent not configured locally" on a deep link | Run `teamshare-agent connect --agent <id> --key ts_...` |
325
- | Run button disabled with a connect hint | The agent's key isn't saved on this PC - run `connect`; keys are shown once (lost key = delete + recreate the agent) |
326
- | Deep-link window flashes shut | The `serve` handler failed (usually a missing local key) - the error is now kept on screen via a 30s pause |
327
- | No harness found on `run` | Install opencode or Claude, or use `--self` |
328
- | Wake events never arrive | `teamshare-bridge status`; the daemon must be running and the key saved in config |
329
- | Wakes queued but never spawn | Stale lock from a crashed session - `teamshare-bridge status` flags it, `clear-lock --agent <id>` removes it (dead locks auto-reclaim within seconds) |
330
- | Session opens but exits instantly | Run `teamshare-agent run …` manually to see the error; check the API URL and key scopes; output is captured in `~/.teamshare/sessions/spawn-*.log` |
331
-
332
- ## Development
333
-
334
- ```sh
335
- npm install
336
- npm run build # tsc -> dist/
337
- npm run typecheck # tsc --noEmit
338
- npm run dev # watch mode
339
- ```
340
-
341
- Runtime dependency: `socket.io-client` only — everything else is Node
342
- built-ins (fetch, http, crypto, child_process). Tests for the full loop run
343
- against a live TeamShare API (see `docs/agent-setup.md`).
344
-
345
- ## Project layout
346
-
347
- ```
348
- src/
349
- ├── lib/
350
- │ ├── config.ts # ~/.teamshare/config.json (port candidates, wake rules)
351
- │ ├── api.ts # typed REST client (envelope-aware, retries, timeouts)
352
- │ ├── brief.ts # task brief fetcher + heartbeat/report helpers
353
- │ ├── llm.ts # --self headless function-calling loop (+ SSE streaming)
354
- │ ├── models.ts # curated <provider>:<model> catalog -> base URL resolution
355
- │ ├── chat-reply.ts # chat reply loop (mention-driven, streaming)
356
- │ ├── doc-reply.ts # Phase F document assistant reply loop
357
- │ ├── session-stream.ts # live-console streaming over /agents + local transcripts
358
- │ ├── partial-stream.ts # Phase C message:partial draft streaming over /chat
359
- │ ├── skills.ts # bundled skill install/list/uninstall + manifest
360
- │ └── lock.ts # per-agent session lock (~/.teamshare/locks/<agentId>.lock)
361
- ├── cli/
362
- │ └── index.ts # teamshare-agent (connect / run / chat / doc / continue)
363
- ├── skills/ # 14 bundled opencode skills (+ THIRD_PARTY_NOTICES.md)
364
- └── bridge/
365
- ├── index.ts # teamshare-bridge CLI (daemon/register/serve/status/probe)
366
- ├── daemon.ts # WS auto-wake listener + wake rules + busy-queueing
367
- ├── local-server.ts# 127.0.0.1 probe server (/ping, /status)
368
- ├── spawn.ts # detached terminal session spawner (+ output capture)
369
- └── protocol.ts # teamshare:// registration + deep-link dispatch
370
- ```
371
-
372
- ## Related docs
373
-
374
- - `docs/agent-setup.md` — plain-language setup guide (mirrors the app's
375
- Launch Console)
376
- - `docs/agent-guides/bundled-skills.md` (repo root) — bundled skill set,
377
- install/skip/manifest semantics, licensing, verification recipe
378
- - `docs/agent-tasks/agent-hub-connection.md` (repo root) — the full agent
379
- contract: REST endpoints, MCP tools, WS events, capabilities
380
- - `docs/agent-models.md` (repo root) — curated model catalog + update process
381
- - `docs/agent-capabilities.md` (repo root) — provider matrix + feature menu
382
- - `docs/agent-roadmap-verification.md` (repo root) — step-by-step E2E playbook
383
- - `AGENTS.md` (repo root) — project conventions
1
+ # teamshare-bridge
2
+
3
+ The local bridge that lets AI agents work TeamShare tasks from your machine.
4
+
5
+ TeamShare is the **coordination hub**: agents are registered in the app
6
+ (identity, capabilities, task assignments, run history). The AI itself runs
7
+ here — on your computer — connected to TeamShare through three methods, all
8
+ provided by this package:
9
+
10
+ | Method | Binary | Trigger | Requirements |
11
+ |---|---|---|---|
12
+ | **Terminal session** | `teamshare-agent` | You paste a command (or click "Copy run command" in the app) | Node 18+, no daemon |
13
+ | **Auto-wake daemon** | `teamshare-bridge start` | A task is assigned to your agent (or it is @mentioned) → the daemon spawns a session automatically | The daemon must be running (`autostart on` keeps it alive across reboots) |
14
+ | **Run button (deep link)** | `teamshare-bridge register` + `serve` | The TeamShare website's "Run agent" button hands off via `teamshare://` | One-time registration; OS cold-launches the bridge |
15
+
16
+ All three share the same core: fetch a task brief (task, comments, project
17
+ files), drive a working session (opencode / Claude / built-in headless LLM
18
+ loop), and report back through the TeamShare API.
19
+
20
+ ---
21
+
22
+ ## Install
23
+
24
+ Requires **Node.js 18+**. One shot (Windows):
25
+
26
+ ```powershell
27
+ irm https://raw.githubusercontent.com/dominionbanjo/teamshare-bridge/main/scripts/install.ps1 | iex
28
+ ```
29
+
30
+ One shot (macOS/Linux):
31
+
32
+ ```sh
33
+ curl -fsSL https://raw.githubusercontent.com/dominionbanjo/teamshare-bridge/main/scripts/install.sh | bash
34
+ ```
35
+
36
+ Or install directly from npm (global):
37
+
38
+ ```sh
39
+ npm i -g teamshare-bridge # published package
40
+ npm i -g . # from this repo
41
+ ```
42
+
43
+ You now have two commands:
44
+
45
+ ```sh
46
+ teamshare-agent # CLI session runner (methods 1)
47
+ teamshare-bridge # daemon + protocol handler (methods 2 and 3)
48
+ ```
49
+
50
+ ## Run
51
+
52
+ ```sh
53
+ teamshare-bridge start # daemon in the background (pid file + ~/.teamshare/daemon.log)
54
+ teamshare-bridge stop # stop it
55
+ teamshare-bridge restart # stop + start
56
+ teamshare-bridge status # pid/log/autostart + per-agent busy/idle
57
+ teamshare-bridge daemon # foreground (debugging)
58
+ teamshare-bridge autostart on # start at login: Task Scheduler (admin) or Startup-folder launcher (no admin)
59
+ teamshare-bridge autostart off # remove it
60
+ ```
61
+
62
+ ## Quick start
63
+
64
+ ```sh
65
+ # 1. Save your agent's key (from the app: Agents → your agent → Launch Console)
66
+ teamshare-agent connect --agent <agent-id> --key ts_...
67
+
68
+ # 2a. Work one task explicitly
69
+ teamshare-agent run --task <task-id> --agent <agent-id> --key ts_...
70
+
71
+ # 2b. Or let the agent pick up its next assigned task (priority first, then oldest)
72
+ teamshare-agent run --agent <agent-id> --key ts_...
73
+
74
+ # 2c. Auto-wake: keep the daemon running, sessions spawn on assignment
75
+ teamshare-bridge start
76
+ teamshare-bridge autostart on # ...and it comes back after a reboot
77
+
78
+ # 3. Run button on the website (registers the teamshare:// scheme)
79
+ teamshare-bridge register
80
+ ```
81
+
82
+ ### Headless mode (no harness, no opencode/Claude — just an LLM API key)
83
+
84
+ ```sh
85
+ LLM_BASE_URL=https://openrouter.ai/api/v1 \
86
+ LLM_API_KEY=sk-... \
87
+ LLM_MODEL=deepseek/deepseek-chat \
88
+ teamshare-agent run --task <task-id> --agent <agent-id> --key ts_... --self
89
+ ```
90
+
91
+ The headless loop is an OpenAI-compatible **function-calling** loop: the model
92
+ gets the task brief plus tools (`get_task`, `list_tasks`, `create_task`,
93
+ `update_task`, `add_comment`, `list_documents`, `read_document`, `search`,
94
+ `ask_human`, `wait_for_answer`, `list_subtasks`, `create_subtask`,
95
+ `update_subtask`). It is instructed to break the task into 3-8 real
96
+ subtasks (`create_subtask`) and check each off (`update_subtask done: true`)
97
+ as work progresses — the human sees the live breakdown in the app. It posts
98
+ milestone comments and finishes by moving the task to `in_review` /
99
+ `resolved`. Any OpenAI-compatible endpoint works (OpenAI, DeepSeek, OpenRouter,
100
+ Together, local vLLM/Ollama…).
101
+
102
+ **One session per agent:** `run`/`chat`/`doc` acquire a per-agent lock
103
+ (`~/.teamshare/locks/<agentId>.lock`, auto-released on exit, stale locks
104
+ reclaimed) and wait for a busy agent instead of starting a second session.
105
+ The daemon queues wakes for a busy agent and spawns them when it frees up;
106
+ `teamshare-bridge status` shows `BUSY` per agent.
107
+
108
+ ---
109
+
110
+ ## How a session works
111
+
112
+ 1. **Heartbeat** — the agent's status flips to `working` in the app.
113
+ 2. **Brief** — the CLI fetches the task (description, comment thread, project
114
+ name) and downloads project files (text files truncated to ~20k chars;
115
+ links return their URL). The brief is written to
116
+ `<temp>/teamshare-task-<taskId>.md` and printed as a preview.
117
+ 3. **Work** — either a harness is spawned (`opencode run "…"`, `claude -p "…"`,
118
+ auto-detected in that order) or the `--self` LLM loop runs.
119
+ 4. **Report** — a closing summary comment is posted (skip with `--no-report`).
120
+ 5. **Watch** — the CLI polls the task status every 15s (up to 20 min) until it
121
+ leaves `open`/`in_progress`, then heartbeats back to `online`.
122
+
123
+ ## Command reference
124
+
125
+ ### `teamshare-agent`
126
+
127
+ ```
128
+ teamshare-agent connect --agent <id> --key <ts_...>
129
+ Test the connection and save the agent key in ~/.teamshare/config.json.
130
+
131
+ teamshare-agent run --task <taskId> --agent <id> --key <ts_...> [options]
132
+ Work a specific task. Without --task, picks the agent's next assigned task
133
+ from its inbox (urgent > high > medium > low, then oldest; skips
134
+ in_review/resolved/closed).
135
+
136
+ teamshare-agent chat --project <projectId> --agent <id> --key <ts_...> [--mention <token>]
137
+ Reply to every project-chat message that @mentions the agent. Replies
138
+ stream token-by-token into the channel when the provider supports it
139
+ (Phase C); the final message is still posted via the API.
140
+
141
+ teamshare-agent doc --document <documentId> --agent <id> --key <ts_...> [--mention <token>]
142
+ Document assistant (Phase F): read the document (Word/PPT/Excel/PDF text
143
+ via GET /documents/:id/extract) and reply to every comment that @mentions
144
+ the agent in its thread.
145
+
146
+ teamshare-agent continue --task <taskId> --agent <id> --key <ts_...> [--self]
147
+ Resume a previous --self session for a task (Phase E continuation).
148
+
149
+ teamshare-agent build --project <id> --agent <id> --key <ts_...> [options]
150
+ Run the build loop: work readyForDev tasks strictly in order (sortOrder
151
+ asc, createdAt asc), one at a time, fully completing each before moving on.
152
+
153
+ teamshare-agent build --project <id> --agent <id> --key <ts_...>
154
+ Full loop: work all pending tasks until the queue is empty.
155
+
156
+ teamshare-agent build ... --draft "<goal>"
157
+ Plan a build queue from a goal string. The LLM reads the project
158
+ documents, creates tasks via MCP, and orders them — then pauses
159
+ for you to review before executing.
160
+
161
+ teamshare-agent build ... --draft "<goal>" --go
162
+ Plan and execute immediately (skip the review prompt).
163
+
164
+ --once Work one task then exit
165
+ --dry-run Print the queue plan without executing
166
+ --on-fail ask|stop What to do on task failure (default: ask)
167
+ --blocked-wait <min> Wait N minutes for an answer before quitting
168
+
169
+ Prerequisites: a provider API key (LLM_API_KEY or agent settings),
170
+ a linked project folder (teamshare-agent link --project <id> --path <dir>),
171
+ and the bridge daemon running (teamshare-bridge start).
172
+
173
+ teamshare-agent skills install [--force] | list | uninstall
174
+ Install the 14 bundled opencode skills into ~/.agents/skills (override with
175
+ TEAMSHARE_SKILLS_DIR). TeamShare-owned skills are always refreshed; vendored
176
+ engineering skills are only copied when absent (or with --force). A manifest
177
+ (~/.agents/skills/.teamshare-bundled.json) tracks what this bridge installed,
178
+ so uninstall never removes independently-installed skills.
179
+
180
+ teamshare-agent --help
181
+ ```
182
+
183
+ Model precedence: **CLI flag > agent settings (set in the app, delivered via
184
+ deep link or auto-wake) > env (`LLM_MODEL`/`LLM_TEMPERATURE`/`LLM_MAX_TOKENS`)
185
+ > defaults**. Model ids use the curated `<provider>:<model>` catalog
186
+ (`docs/agent-models.md`) — the provider's OpenAI-compatible base URL is
187
+ resolved automatically; `LLM_BASE_URL` always wins when set.
188
+
189
+ ### `teamshare-bridge`
190
+
191
+ ```
192
+ teamshare-bridge daemon [--port N]
193
+ Auto-wake listener: keeps a WebSocket to TeamShare per configured agent
194
+ and spawns a session on wake events (task assigned, @mention in a comment
195
+ or chat). Also serves the localhost probe the website detects.
196
+
197
+ teamshare-bridge register
198
+ Registers the teamshare:// URI scheme (per-user; Windows registry /
199
+ macOS app bundle / Linux .desktop). No admin rights needed.
200
+
201
+ teamshare-bridge serve "<teamshare://agent/run?runToken=...&task=...>"
202
+ OS-invoked: redeems the run token and spawns the session.
203
+
204
+ teamshare-bridge add-agent --agent <id> --key <ts_...>
205
+ Saves an agent key without testing the connection.
206
+
207
+ teamshare-bridge status [--port N]
208
+ Shows config path, port, per-agent BUSY/idle (stale locks flagged),
209
+ harness, quiet hours, scheme.
210
+
211
+ teamshare-bridge clear-lock --agent <id>
212
+ Force-removes a stale session lock. Crashed sessions (dead PID) and
213
+ locks older than 8h are auto-reclaimed; this is the manual override.
214
+
215
+ teamshare-bridge probe [--port N]
216
+ Starts just the localhost probe server (for testing).
217
+ ```
218
+
219
+ ## Build mode quick start
220
+
221
+ ```sh
222
+ # 1. Link your project folder
223
+ teamshare-agent link --project <project-id> --path ./my-project
224
+
225
+ # 2. Plan a build queue from a goal (pauses for review)
226
+ teamshare-agent build --project <project-id> --agent <agent-id> --key ts_... \
227
+ --draft "Set up user auth: login, signup, JWT middleware, password reset"
228
+
229
+ # 3. Review the plan, then execute
230
+ # (or skip review with --draft "..." --go)
231
+
232
+ # 4. Start the build loop
233
+ teamshare-agent build --project <project-id> --agent <agent-id> --key ts_...
234
+ ```
235
+
236
+ ## Configuration
237
+
238
+ `~/.teamshare/config.json` — created on first run with defaults:
239
+
240
+ ```json
241
+ {
242
+ "agents": [{ "agentId": "...", "apiKey": "ts_..." }],
243
+ "port": 48242,
244
+ "harness": "auto",
245
+ "quietHours": null,
246
+ "wakeRules": null
247
+ }
248
+ ```
249
+
250
+ | Key | Meaning |
251
+ |---|---|
252
+ | `agents` | Agent id + API key pairs the daemon listens for (`teamshare-agent connect` / `teamshare-bridge add-agent` populate this) |
253
+ | `port` | Localhost probe port. Picked at **random** from `[48231, 48242, 48253, 48264, 48275, 48286, 48297]` on first run; the website probes all candidates, so any pick is discoverable. Override with `--port`. |
254
+ | `harness` | Preferred session driver: `auto`, `opencode`, `claude`, `none` |
255
+ | `quietHours` | `{ "start": "22:00", "end": "07:00" }` — wake events are ignored during this window |
256
+ | `wakeRules` | `{ "priorities": ["high", "urgent"] }` — only wake for tasks matching these priorities |
257
+
258
+ ## Environment variables
259
+
260
+ | Variable | Default | Used by |
261
+ |---|---|---|
262
+ | `TEAMSHARE_API_URL` | `https://api.teamshare.name.ng` | all commands |
263
+ | `TEAMSHARE_WS_URL` | `wss://api.teamshare.name.ng` | daemon + live console + streaming |
264
+ | `LLM_BASE_URL` | (catalog per model) | `--self`, chat/doc replies |
265
+ | `LLM_API_KEY` | — (required for `--self`) | `--self`, chat/doc replies |
266
+ | `LLM_MODEL` | `deepseek-chat` | `--self` (catalog ids resolve the base URL) |
267
+ | `LLM_TEMPERATURE` | `0.2` | `--self`, chat/doc replies |
268
+ | `LLM_MAX_TOKENS` | — (provider default) | `--self`, chat/doc replies |
269
+ | `TEAMSHARE_ASK_TIMEOUT` | `900` (seconds) | `ask_human` wait limit |
270
+ | `TS_CHAT_ECHO` | — | Debug: post canned acknowledgments (deterministic E2E) |
271
+
272
+ ## Live console & streaming
273
+
274
+ - Every session (`run`/`chat`/`doc`) opens its own `/agents` socket and emits
275
+ `session:start` / `session:output` (batched ~200ms) / `session:end` — the
276
+ app's **Live console** on the agent detail page shows the output in real
277
+ time, and a capped transcript is persisted server-side at the end.
278
+ - Local mirror + continuation history: `~/.teamshare/sessions/`
279
+ (`<sessionId>.json` transcripts, `task-<taskId>.json` for `--continue`).
280
+ - Chat replies additionally stream into the project channel as
281
+ `message:partial` frames over a `/chat` socket (apiKey auth) — the web UI
282
+ renders a live draft bubble that is swapped for the persisted message.
283
+
284
+ ## The localhost probe
285
+
286
+ The website detects the bridge by calling `GET http://localhost:<port>/ping`
287
+ with permissive CORS (the browser can reach it from the web app):
288
+
289
+ ```json
290
+ { "ok": true, "version": "0.1.0", "agents": ["<agent-id>"] }
291
+ ```
292
+
293
+ When the probe answers, the app shows "Bridge detected on this computer" and
294
+ enables the **Run agent** button; otherwise it degrades gracefully to the
295
+ copy-paste command.
296
+
297
+ ## Security model
298
+
299
+ - **Agent API keys** (`ts_...`) are minted by TeamShare with scopes derived
300
+ from the agent's capabilities and can never exceed them; the raw key is
301
+ shown only once in the app. Store it via `connect` — it lives in
302
+ `~/.teamshare/config.json` (chmod 600 on unix).
303
+ - **Run tokens** in `teamshare://` deep links are short-lived (10 min),
304
+ single-use, and exchanged server-side for a session credential — the
305
+ long-lived key never appears in a URL.
306
+ - The bridge never sees environment-variable values; TeamShare's viewer-denied
307
+ rule extends to agents automatically.
308
+ - The probe server binds to `127.0.0.1` only.
309
+
310
+ ## Platform notes
311
+
312
+ | Platform | Terminal spawn | Protocol registration |
313
+ |---|---|---|
314
+ | Windows | `cmd /c start cmd /k …` (detached window, stays open) | `HKCU\Software\Classes\teamshare` via `reg.exe`, per-user |
315
+ | macOS | Terminal.app via `osascript` (always present, no installs) | `~/Applications/TeamShareBridge.app` (CFBundleURLTypes); open the bundle once |
316
+ | Linux (desktop) | `xdg-terminal-exec` → `gnome-terminal` → `konsole` → `xterm` (first found on PATH) | `~/.local/share/applications/teamshare-bridge.desktop` (`x-scheme-handler/teamshare`) |
317
+ | Linux (server/SSH) | Headless fallback — no window; watch via the web live console | n/a |
318
+
319
+ ## Troubleshooting
320
+
321
+ | Symptom | Fix |
322
+ |---|---|
323
+ | `EADDRINUSE` on probe | `--port <candidate>` or delete the `port` key from config; the website probes all candidates |
324
+ | "Agent not configured locally" on a deep link | Run `teamshare-agent connect --agent <id> --key ts_...` |
325
+ | Run button disabled with a connect hint | The agent's key isn't saved on this PC - run `connect`; keys are shown once (lost key = delete + recreate the agent) |
326
+ | Deep-link window flashes shut | The `serve` handler failed (usually a missing local key) - the error is now kept on screen via a 30s pause |
327
+ | No harness found on `run` | Install opencode or Claude, or use `--self` |
328
+ | Wake events never arrive | `teamshare-bridge status`; the daemon must be running and the key saved in config |
329
+ | Wakes queued but never spawn | Stale lock from a crashed session - `teamshare-bridge status` flags it, `clear-lock --agent <id>` removes it (dead locks auto-reclaim within seconds) |
330
+ | Session opens but exits instantly | Run `teamshare-agent run …` manually to see the error; check the API URL and key scopes; output is captured in `~/.teamshare/sessions/spawn-*.log` |
331
+
332
+ ## Development
333
+
334
+ ```sh
335
+ npm install
336
+ npm run build # tsc -> dist/
337
+ npm run typecheck # tsc --noEmit
338
+ npm run dev # watch mode
339
+ ```
340
+
341
+ Runtime dependency: `socket.io-client` only — everything else is Node
342
+ built-ins (fetch, http, crypto, child_process). Tests for the full loop run
343
+ against a live TeamShare API (see `docs/agent-setup.md`).
344
+
345
+ ## Project layout
346
+
347
+ ```
348
+ src/
349
+ ├── lib/
350
+ │ ├── config.ts # ~/.teamshare/config.json (port candidates, wake rules)
351
+ │ ├── api.ts # typed REST client (envelope-aware, retries, timeouts)
352
+ │ ├── brief.ts # task brief fetcher + heartbeat/report helpers
353
+ │ ├── llm.ts # --self headless function-calling loop (+ SSE streaming)
354
+ │ ├── models.ts # curated <provider>:<model> catalog -> base URL resolution
355
+ │ ├── chat-reply.ts # chat reply loop (mention-driven, streaming)
356
+ │ ├── doc-reply.ts # Phase F document assistant reply loop
357
+ │ ├── session-stream.ts # live-console streaming over /agents + local transcripts
358
+ │ ├── partial-stream.ts # Phase C message:partial draft streaming over /chat
359
+ │ ├── skills.ts # bundled skill install/list/uninstall + manifest
360
+ │ └── lock.ts # per-agent session lock (~/.teamshare/locks/<agentId>.lock)
361
+ ├── cli/
362
+ │ └── index.ts # teamshare-agent (connect / run / chat / doc / continue)
363
+ ├── skills/ # 14 bundled opencode skills (+ THIRD_PARTY_NOTICES.md)
364
+ └── bridge/
365
+ ├── index.ts # teamshare-bridge CLI (daemon/register/serve/status/probe)
366
+ ├── daemon.ts # WS auto-wake listener + wake rules + busy-queueing
367
+ ├── local-server.ts# 127.0.0.1 probe server (/ping, /status)
368
+ ├── spawn.ts # detached terminal session spawner (+ output capture)
369
+ └── protocol.ts # teamshare:// registration + deep-link dispatch
370
+ ```
371
+
372
+ ## Related docs
373
+
374
+ - `docs/agent-setup.md` — plain-language setup guide (mirrors the app's
375
+ Launch Console)
376
+ - `docs/agent-guides/bundled-skills.md` (repo root) — bundled skill set,
377
+ install/skip/manifest semantics, licensing, verification recipe
378
+ - `docs/agent-tasks/agent-hub-connection.md` (repo root) — the full agent
379
+ contract: REST endpoints, MCP tools, WS events, capabilities
380
+ - `docs/agent-models.md` (repo root) — curated model catalog + update process
381
+ - `docs/agent-capabilities.md` (repo root) — provider matrix + feature menu
382
+ - `docs/agent-roadmap-verification.md` (repo root) — step-by-step E2E playbook
383
+ - `AGENTS.md` (repo root) — project conventions