huddle-cli 0.1.1 → 0.1.5
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.
- package/CHANGELOG.md +66 -0
- package/QUICKSTART.md +63 -2
- package/README.md +15 -0
- package/dist/adapters/codex.js +3 -0
- package/dist/app/live.js +142 -0
- package/dist/app/page.js +775 -0
- package/dist/app/qr.js +47 -0
- package/dist/app/server.js +433 -0
- package/dist/args.js +18 -0
- package/dist/attach/connect.js +3 -3
- package/dist/attach/plug.js +8 -1
- package/dist/cli.js +46 -4
- package/dist/connectors/cli.js +121 -0
- package/dist/connectors/github.js +162 -0
- package/dist/connectors/hub.js +234 -0
- package/dist/connectors/types.js +3 -0
- package/dist/mcp/context-tools.js +2 -0
- package/dist/mcp/server.js +42 -3
- package/dist/orchestrator/brain.js +3 -1
- package/dist/orchestrator/budget.js +283 -0
- package/dist/orchestrator/busy.js +106 -0
- package/dist/orchestrator/council.js +11 -5
- package/dist/orchestrator/launcher.js +3 -1
- package/dist/orchestrator/learn.js +3 -7
- package/dist/orchestrator/planner.js +32 -5
- package/dist/orchestrator/qa.js +9 -1
- package/dist/orchestrator/scheduler.js +105 -19
- package/dist/platform.js +104 -0
- package/dist/room/mail.js +19 -6
- package/dist/room/server.js +82 -2
- package/dist/room/user.js +54 -0
- package/dist/ui/app.js +511 -69
- package/dist/ui/brief.js +494 -0
- package/dist/ui/catalog.js +1 -1
- package/dist/ui/dashboard.js +92 -21
- package/dist/ui/export.js +1194 -0
- package/dist/ui/narrator.js +56 -0
- package/dist/ui/story.js +118 -93
- package/dist/ui/talk.js +176 -0
- package/dist/ui/term.js +31 -0
- package/dist/ui/transcript.js +434 -0
- package/dist/ui/undo.js +131 -0
- package/dist/ui/watch.js +4 -0
- package/dist/update.js +84 -0
- package/package.json +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,71 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.5 — 2026-10-16
|
|
4
|
+
|
|
5
|
+
Run it from your phone; undo and GitHub issues in the dashboard.
|
|
6
|
+
|
|
7
|
+
- **`huddle app --phone`: run it from your phone.** The dashboard also listens on your Wi-Fi and prints a QR code; scan it to watch the run, answer an agent's question, talk to the agents, or start and stop a run. Every page and call still needs the session key (longer on the network), and only this computer's own addresses are let in. It says plainly that anyone with the link can control the run, and ctrl-c stops sharing. `--anywhere` opens a Cloudflare quick tunnel instead (https, works off your Wi-Fi) when `cloudflared` is installed, and says how to get it when not. Checked at phone width (390 px).
|
|
8
|
+
- **Undo from the dashboard.** A past run has **Undo this run** when it can be undone (otherwise the reason, in small print). It lists the commits and asks in the page first, then undoes exactly as `huddle undo` does: one revert commit, recorded the same way. Refused while a run is going, or if the run changed since you looked.
|
|
9
|
+
- **Fix a GitHub issue from the dashboard.** With `gh` signed in, the start screen lists the repo's open issues (up to 20, checked at most once a minute); **Fix this** starts a run on it, like `huddle fix #12`. The sidebar shows which connectors are set up.
|
|
10
|
+
- Fixed: undoing an older run (`huddle undo --run 1` after run 2) marked the newest run as undone instead.
|
|
11
|
+
- Fixed: `huddle app --help` opened a dashboard; it prints the options now.
|
|
12
|
+
- Live: a run started from the phone link (real Claude) built `--max N` for a slug CLI, and the dashboard's undo took it back. Suite: 457 tests, 0 failed.
|
|
13
|
+
|
|
14
|
+
## 0.1.4 — 2026-10-16
|
|
15
|
+
|
|
16
|
+
Your team's tools, for every agent.
|
|
17
|
+
|
|
18
|
+
- **Connectors.** Every agent in a run (Claude, Codex, Cursor, any of them) gets the same outside tools through the Plug. The Room runs each connector once per run, so there's one sign-in and no per-vendor config.
|
|
19
|
+
- **GitHub, built in:** `github_issues`, `github_issue` (with comments), `github_prs`, `github_pr` (files, reviews, optional diff), `github_ci`, through the `gh` CLI you're signed in to. Huddle keeps no token.
|
|
20
|
+
- **Any MCP server:** `huddle connectors add atlassian` (Jira + Confluence), `linear`, `notion`, `miro`, `sentry`, any `https://` MCP URL (through `mcp-remote`, which does the sign-in), or `-- <command…>` for a local server. A connector that doesn't start is left out with a note; the run goes on.
|
|
21
|
+
- **Read-only until you allow more.** Tools that post or change things are hidden until `--write` (`huddle connectors github write` for comments and new issues). What agents post is signed "via Huddle".
|
|
22
|
+
- **Only your own agents** reach them; a teammate's agent in your room doesn't. Every call shows live (`codex github: read issue #12`) and is recorded (`connector.call`).
|
|
23
|
+
- **Reviewers see what the author read.** A cross-review has no tools, so the ticket or issue the author read goes into the reviewer's prompt, verbatim. Found live: Codex sent back WEB-7 because "the ticket's contents are missing".
|
|
24
|
+
- **The planner knows what agents can read**, so a goal that names a ticket gets tasks that read it first rather than guessing.
|
|
25
|
+
- Live: "do Jira ticket WEB-7" with a stand-in Jira. Claude, then Codex (reviewed by Cursor), read the ticket and its PM comment through the connector and built all of it, first review approved.
|
|
26
|
+
- **`huddle fix #12`**: a GitHub issue (title, body, comments) is the goal. A goal that mentions `#12` keeps your words and gets the issue attached.
|
|
27
|
+
- **`huddle undo`** takes back what the last run merged (`--run n` for another): one revert commit, listed and confirmed first. If later commits build on the run, it changes nothing and says how to revert by hand.
|
|
28
|
+
- **`huddle update`** (also `huddle --update`) installs the newest Huddle from npm. It says so when you're already on it, and a source checkout is told to `git pull` instead.
|
|
29
|
+
- Tests pass in a terminal that sets `FORCE_COLOR` (found publishing 0.1.3).
|
|
30
|
+
|
|
31
|
+
## 0.1.3 — 2026-10-16
|
|
32
|
+
|
|
33
|
+
You can follow a run, and take part in it, without being an engineer. Live capstone: 29/29 with real Claude, Codex and Cursor (13 merged, 0 failed, 22 min, 5.6M tokens, down from 6.6M).
|
|
34
|
+
|
|
35
|
+
- **The plan in plain words.** The plan now opens with "What you'll get" (one or two sentences, no jargon) and "For example" (one real use and what you'd see). The technical decisions and risks fold into one line; `details` shows them.
|
|
36
|
+
- **A narrator.** The top line of a live run says what's happening now ("the agents are each sketching how they'd build it", "building — 2 of 8 parts done · claude: argv parser") and ends with "nothing needed from you", unless something is.
|
|
37
|
+
- **Agents can ask you.** For a big call the goal doesn't settle, an agent asks with 2–4 numbered options, its recommendation first (`huddle_ask_user`). Type a number, press Enter for the recommended one, or answer in your own words. With no answer in 90 seconds (`HUDDLE_ASK_USER_SEC`), it goes with its pick. At most 2 questions per agent per run; the answer goes into shared memory and shows in `huddle story` / `huddle export`.
|
|
38
|
+
- **Talk to the agents mid-run.** Anything you type during a run goes to every agent working now and to every task that starts later, marked as from you; it wins over the plan and the contract. `@codex …` sends it to one agent. This works in `huddle` and in `huddle join` on a terminal (a typing line under the live status). `next <goal>` queues another run.
|
|
39
|
+
- **`huddle build a temperature converter`**: plain words are a goal, with no `join` and no quotes.
|
|
40
|
+
- **Names for the parts**: Room, Screen, Whiteboard, Board, Brief (see QUICKSTART).
|
|
41
|
+
- **`huddle app`, the dashboard.** Huddle in your browser, for the repo you're in:
|
|
42
|
+
- **Live view:** the narrator, the overall bar, one card per agent (task, %, tokens).
|
|
43
|
+
- **Questions:** an agent's question shows as buttons, with a box for your own words.
|
|
44
|
+
- **Talk:** a composer to start a run or talk to the agents, with hold-to-talk voice (hold Space or the mic; the browser's own speech recognition).
|
|
45
|
+
- **History:** every past run as a conversation, with filters, the plan (who did what, what they agreed, the contract), cost per agent, "What you got", and one-click exports.
|
|
46
|
+
- **Any run:** it works for runs started in a terminal too (through `.huddle/live.json` and `.huddle/inbox/`).
|
|
47
|
+
- **Local and private:** it listens on 127.0.0.1 only, behind a per-session key. Runs started there keep going if you close the page.
|
|
48
|
+
|
|
49
|
+
- **The dashboard reads as a story**: what you'll get (or got) in prose; the live status as one sentence, four steps and a chip per agent; the design as idea cards with who borrowed what; the plan part by part, each with its thread (reviews, mid-way checks, messages) in plain words. The raw log has its own tab. Serif headings, real icons, light and dark.
|
|
50
|
+
- **Huddle for macOS** (`desktop/macos`): a ~1 MB native app around the dashboard. ⌘O picks a project, standard menus, exports to Downloads, hold-to-talk. `desktop/macos/build.sh` makes a universal `Huddle.app` and `Huddle.dmg`; see `desktop/README.md` for signing and notarizing.
|
|
51
|
+
|
|
52
|
+
### Fixed (found in a live 0.1.2 run)
|
|
53
|
+
- The design council waited 2 minutes on one agent's ratify that then timed out; ratifying (an OK or a few objections) now has 75 seconds (`HUDDLE_RATIFY_TIMEOUT_S`).
|
|
54
|
+
- The budget's 90% line fired at 108%: Codex reports tokens only when its turn ends. Work in flight is now estimated at that agent's own pace for the 90% line (the 120% line still waits for real numbers).
|
|
55
|
+
- Agents required Node 22 on a Node 20 machine: the planner and council now see the machine's OS and Node version.
|
|
56
|
+
- A sent-back review's notes were stored as a "lesson" word for word; they're about one task, so they no longer are.
|
|
57
|
+
- Two dashboard commands sent in the same millisecond could reach the run out of order.
|
|
58
|
+
|
|
59
|
+
## 0.1.2 — 2026-10-16
|
|
60
|
+
|
|
61
|
+
Memory that outlives the run, chat exports, progress bars, and a cost guard. Live capstone: 29/29 with real claude, codex and cursor.
|
|
62
|
+
|
|
63
|
+
- **Quiet isn't stuck.** Before taking over an agent that has printed nothing for the silence window, Huddle checks whether it is working: a child process using CPU (a long test run, a build), files changing in its worktree, or its log growing. A busy agent gets more time and the run shows "⧗ running a long command" (in `huddle view` and `huddle story` too). It is still taken over after a hard cap, 3× the window by default (`HUDDLE_SILENCE_MAX_MIN`). This happened live: Claude was taken over in the middle of an 8-minute test suite.
|
|
64
|
+
- **Cost guard.** The plan now comes with an estimate (`≈ 4–6M tokens, ~15–20 min with 3 agents`), based on this repo's past runs or on built-in defaults. `--budget=5M` (or `"budget"` in prefs) sets a limit. At 90% Huddle starts no new tasks, takeovers, QA rounds, buddy checks or pairings, and lets running tasks finish. At 120% it stops the agents, as Ctrl-C does. RESULT shows how much of the budget was used and lists what was left undone.
|
|
65
|
+
- **Progress bars.** The live run pins an overall bar (`BUILD ███████░░░░░ 6/9 tasks · 12m`) that moves through the council's four steps, the build (fix tasks QA files included) and each QA round; every agent's status line has a mini bar from its own reported % (a dotted track and "no report yet" until it reports — never a made-up number). `huddle view` and ctrl-t show the same bars in the top bar, the agent panes and the board, ✓ when done and red when failed. Everything fits 60/80/120 columns; with NO_COLOR or piped output it's plain words ("BUILD 6/9 tasks"), one log line each time the numbers move.
|
|
66
|
+
- **Hand-off brief.** Every run writes `.huddle/BRIEF.md` (goal, who built what, decisions, contract, open issues, how to continue) and points to it from a marked, uncommitted block in `CLAUDE.md` / `AGENTS.md`, so solo agents opened afterwards know what the team did. `huddle brief [--run n]`, `huddle brief off|on`.
|
|
67
|
+
- **Run history and chat exports.** `huddle runs` lists every run in the repo (goal, agents, merged/failed, time, tokens, QA). `huddle export [<run>|latest]` saves a run like a chat app keeps a conversation: `--level summary` (result, who did what, decisions, contract, teamwork, cost), `chat` (every message between agents, buddy notes and replies, radar alerts, reviews, QA bugs and Huddle's notes, in full and in time order) or `full` (plus each agent's own session per task, read from the claude / codex / cursor logs), as Markdown, a self-contained HTML page with an agent filter, or JSON with a stable schema. Likely secrets are redacted (`--no-redact` keeps them).
|
|
68
|
+
|
|
3
69
|
## 0.1.1 — 2026-10-16
|
|
4
70
|
|
|
5
71
|
The agents now work *together*, not just side by side. Verified live with real Claude, Codex and Cursor building an app from an empty repo (capstone: 29/29 checks, rounds 4 and 6).
|
package/QUICKSTART.md
CHANGED
|
@@ -53,7 +53,45 @@ One-shot instead of the prompt: `huddle join "build a REST API for todos with te
|
|
|
53
53
|
**Pasting and files.** Paste anything long (a stack trace, a spec, code) at the prompt: it goes on the *shared screen* as one item, every agent can read it, and what you type next is the goal. Drag a file or screenshot into the terminal, or type `add notes.md` / `add src/` / `add *.png`. `ctx` shows what's on the screen; `ctx rm ctx-2` takes one off. Prompts only carry a short index, so a huge paste doesn't get copied to every agent. Keys and tokens in a paste are caught first: Huddle asks before showing them to agents, and redacts them unless you say no.
|
|
54
54
|
One-shot: `huddle join "fix this" --with error.log --with screenshot.png`, or `cat error.log | huddle join "fix this"`.
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
Or skip the prompt: `huddle build a temperature converter with tests` (no quotes needed).
|
|
57
|
+
|
|
58
|
+
**While it runs** the top line says what's happening in plain words, and whether you're needed:
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
Now: building — 2 of 8 parts done · claude: argv parser · codex: conversion core 25% · nothing needed from you
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
- **Talk to the agents:** just type. `use two decimals` goes to every agent working now (and every one that starts later); `@codex use two decimals` to one. Your words win over the plan.
|
|
65
|
+
- **When they need you:** for a big call the goal doesn't settle, an agent asks with numbered options, its pick first. Type a number, press Enter for the recommended one, or answer in your own words. No answer in 90 seconds and it goes with its pick, so a run never waits on you.
|
|
66
|
+
- `details` shows the technical decisions behind the plan; `stop` (or ctrl-c) stops the agents and still shows what got done.
|
|
67
|
+
|
|
68
|
+
**The dashboard:** `huddle app` opens Huddle in your browser. You get the run going now (who's on what, how far along, a question waiting for you), every past run as a conversation, the plan and what each agent cost. Type there to start a run or talk to the agents; hold Space (or the mic) to say it instead. It works for runs started in a terminal too. Runs keep going if you close the page.
|
|
69
|
+
|
|
70
|
+
- **From your phone:** `huddle app --phone` prints a QR code. Scan it with your phone's camera (same Wi-Fi as the computer) to watch the run, answer questions and talk to the agents from the couch. Anyone with that link can control the run, so keep it to yourself; ctrl-c stops sharing. Not on the same Wi-Fi? `huddle app --anywhere` uses a free Cloudflare link instead (needs `cloudflared`: `brew install cloudflared`).
|
|
71
|
+
- **Undo a run:** open a past run and press **Undo this run**. It shows the commits it would take back and asks first, the same as `huddle undo`.
|
|
72
|
+
- **Fix an issue:** when `gh` is signed in, the start screen lists the repo's open GitHub issues; **Fix this** starts a run on one.
|
|
73
|
+
|
|
74
|
+
**Your team's tools: GitHub, Jira, Linear…** Every agent in a run can read the repo's GitHub issues, pull requests and CI through the `gh` CLI you're signed in to. Nothing to set up:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
huddle fix #12 # GitHub issue 12 is the goal: its text and comments, word for word
|
|
78
|
+
huddle build a login page for #12 and #15 # your words, with both issues attached
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
(In bash, `#` starts a comment: type `huddle fix issue 12` there.)
|
|
82
|
+
|
|
83
|
+
Add the other tools your team uses; each signs you in through your browser once:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
huddle connectors add atlassian # Jira + Confluence (also: linear, notion, miro, sentry)
|
|
87
|
+
huddle connectors # what's on, and how many tools each one gives
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Agents only get the tools that *read* until you allow more: `huddle connectors add --write atlassian`, `huddle connectors github write`. What they post is signed "via Huddle". Huddle keeps no tokens; `gh` and each service's own sign-in do.
|
|
91
|
+
|
|
92
|
+
**Undo a run:** `huddle undo` takes back everything the last run merged, as one new commit (it shows the commits and asks first). `huddle undo --run 3` for an older one.
|
|
93
|
+
|
|
94
|
+
**A second view** (another terminal, same folder):
|
|
57
95
|
|
|
58
96
|
```bash
|
|
59
97
|
huddle view # live: who's doing what, messages, merges
|
|
@@ -64,8 +102,14 @@ huddle view # live: who's doing what, messages, merges
|
|
|
64
102
|
```bash
|
|
65
103
|
huddle story # replay: plan, messages between agents, reviews, merges
|
|
66
104
|
huddle story --html story.html # the same as a page you can open or share
|
|
105
|
+
huddle brief # the hand-off brief your next solo claude/codex/cursor reads
|
|
106
|
+
huddle runs # every run in this repo: goal, agents, result, cost
|
|
107
|
+
huddle export # the last run as a chat: who said what to whom (Markdown)
|
|
108
|
+
huddle export 2 --level full --format html # run 2 with each agent's own session, as a page
|
|
67
109
|
```
|
|
68
110
|
|
|
111
|
+
Each run leaves `.huddle/BRIEF.md` (decisions, contract, open issues) and a short pointer to it at the top of `CLAUDE.md` and `AGENTS.md`, so an agent you open on your own afterwards knows what the team did. The pointer isn't committed; `huddle brief off` removes it.
|
|
112
|
+
|
|
69
113
|
## 3. Working with teammates (e.g. a hackathon)
|
|
70
114
|
|
|
71
115
|
Everyone installs Huddle as in step 1, on their own machine, with their own agents.
|
|
@@ -77,6 +121,16 @@ Everyone installs Huddle as in step 1, on their own machine, with their own agen
|
|
|
77
121
|
|
|
78
122
|
Not on the same Wi-Fi? Install [Tailscale](https://tailscale.com) on both machines, or run `huddle relay` on a server and type `relay <url>` in your huddle.
|
|
79
123
|
|
|
124
|
+
## The words Huddle uses
|
|
125
|
+
|
|
126
|
+
| Word | What it is |
|
|
127
|
+
|---|---|
|
|
128
|
+
| **Room** | Where your agents (and teammates' agents) meet for a goal. `huddle` opens yours; `invite` lets people in. |
|
|
129
|
+
| **Screen** | The shared screen: what you paste, drag in or `add` — logs, docs, screenshots. Every agent reads it. |
|
|
130
|
+
| **Whiteboard** | Where they design it together before coding: each one's idea, what they borrow from each other, the plan, and the contract (`HUDDLE_CONTRACT.md`, the exact names everyone codes to). `details` and `huddle story` show it. |
|
|
131
|
+
| **Board** | Who's doing which part, how far along, what's merged. `board`, `huddle view`, ctrl-t. |
|
|
132
|
+
| **Brief** | What a finished run leaves for your next solo agent (`.huddle/BRIEF.md`). |
|
|
133
|
+
|
|
80
134
|
## Everyday commands
|
|
81
135
|
|
|
82
136
|
| Command | What it does |
|
|
@@ -86,12 +140,19 @@ Not on the same Wi-Fi? Install [Tailscale](https://tailscale.com) on both machin
|
|
|
86
140
|
| `huddle setup` | install and sign in to your agents (asks first) |
|
|
87
141
|
| `huddle doctor` | check Node, git and your agents |
|
|
88
142
|
| `huddle agents` · `huddle agents skip <id>` · `use <id>` | who's ready, and which agents Huddle uses |
|
|
143
|
+
| `huddle app` | the dashboard in your browser: live run, history, talk to the agents (or speak) |
|
|
144
|
+
| `huddle app --phone` | the same on your phone: scan the QR code (`--anywhere`: off your Wi-Fi too) |
|
|
89
145
|
| `huddle view` | watch a run live |
|
|
90
146
|
| `huddle story` | replay the last run |
|
|
147
|
+
| `huddle brief` · `huddle brief off` | what the last run left for your next solo agent · stop pointing CLAUDE.md / AGENTS.md at it |
|
|
148
|
+
| `huddle runs` · `huddle export [run]` | list past runs · save one as a chat (`--level summary\|chat\|full`, `--format md\|html\|json`) |
|
|
91
149
|
| `huddle board` | print the task board |
|
|
150
|
+
| `huddle fix #12` | a GitHub issue as the goal |
|
|
151
|
+
| `huddle connectors` · `add atlassian` · `remove <name>` | the outside tools every agent gets (GitHub is built in) |
|
|
152
|
+
| `huddle undo` | take back what the last run merged (one revert commit; asks first) |
|
|
92
153
|
| `add <file>` / `ctx` | (at the prompt) put a file on the shared screen / see what's on it |
|
|
93
154
|
| `huddle add <file\|->` / `huddle ctx` | running claude/codex/cursor yourself (`huddle connect`): put a file, folder or stdin (`cat err.log \| huddle add -`) on the shared screen every session reads / see it |
|
|
94
|
-
| `
|
|
155
|
+
| `huddle update` | update to the newest version |
|
|
95
156
|
| `npm uninstall -g huddle-cli` | remove it (your repos keep their work) |
|
|
96
157
|
|
|
97
158
|
## If something goes wrong
|
package/README.md
CHANGED
|
@@ -65,6 +65,7 @@ At the `huddle ›` prompt, type what you want built. Huddle plans it into paral
|
|
|
65
65
|
|
|
66
66
|
- **shift+tab** switches mode: `manual` (approve the plan and each merge) → `auto` → `plan` (dry run)
|
|
67
67
|
- **`approvals safe|auto|yolo`** sets what agents may do without asking
|
|
68
|
+
- **`--budget=5M`** (typed with the goal, on `huddle join`, or `"budget": "5M"` in `~/.huddle/prefs.json`) caps the tokens a run may use. The plan shows an estimate first. At 90% no new work starts and running tasks finish; at 120% the agents stop. RESULT lists what was left undone. Cached tokens count in full, so the budget runs out before the bill does.
|
|
68
69
|
- keep typing while agents work: `board`, questions, and new goals (queued) all work mid-run
|
|
69
70
|
- `cd`, `!cmd`, `clear` behave like a shell; not a git repo? Huddle offers to set it up
|
|
70
71
|
|
|
@@ -78,11 +79,25 @@ At the `huddle ›` prompt, type what you want built. Huddle plans it into paral
|
|
|
78
79
|
- **Notes need an answer.** A buddy note or a radar finding stays open until the author fixes the file it names or replies to it (`won't fix: <why>` counts). `huddle_done` with notes still open is refused once, with the list; the second `huddle_done` always goes through, and the note is recorded as ignored.
|
|
79
80
|
- **Pairing.** When an agent is free and a task is under 50% done (one that never reports progress only after twice the help wait, with little of its file list started), the free agent proposes taking a separate part of it, or its tests. The author has 60s to say no.
|
|
80
81
|
- `huddle story` shows all of this afterwards: who adopted whose idea, who objected, contract versions, what the radar caught, buddy notes (addressed or ignored), and pairs.
|
|
82
|
+
- **Hand-off brief.** Every run ends with `.huddle/BRIEF.md`: the goal, what was built and by whom, the decisions and why, the contract, open issues and how to continue — from the Room's records, no model call. A short marked block at the top of `CLAUDE.md` and `AGENTS.md` points to it, so a `claude`, `codex` or `cursor` you open on your own afterwards reads it first. It's never committed: a file Huddle creates is git-excluded, and in a file you own the block is lifted out while each run works and put back after. `huddle brief` prints it (`--run n`); `huddle brief off` removes the pointers; `HUDDLE_NO_BRIEF=1` turns it all off.
|
|
83
|
+
- `huddle runs` lists every run in the repo (goal, agents, result, time, tokens, QA). `huddle export [<run>|latest]` saves one as a document you can read or share, like a chat app's history: `--level summary` (result, who did what, decisions, contract, teamwork, cost), `chat` (the default: every message between agents, buddy notes and replies, radar alerts, reviews, QA bugs and Huddle's notes, in time order and in full), or `full` (also each agent's own session per task: what it said, read, ran and wrote, parsed from its log). `--format md|html|json` (HTML is one offline file with an agent filter; JSON is a stable schema, documented in `src/ui/export.ts`). It goes to `.huddle/exports/` unless you pass `--out <file|dir|->`. Likely secrets are redacted unless you pass `--no-redact`.
|
|
81
84
|
|
|
82
85
|
None of these steps blocks the run. If an agent doesn't answer or doesn't follow the format, the run continues as it would without that step.
|
|
83
86
|
|
|
84
87
|
**Pasting and files: one shared screen, not N copies.** Paste a stack trace, a doc or a block of code at the prompt and it becomes one item on the Room's *shared screen* (`📎 pasted 214 lines (ctx-3 'TypeError…')`) instead of 214 commands; what you type next is the goal. Drag a file or screenshot into the terminal, or `add <file|folder|glob>`. Prompts carry only a one-line index per item; the planner links items to the tasks that need them, and agents open them with `huddle_context_read` (400 lines a call, images and PDFs as a file path; Codex also gets linked screenshots via `--image`), search them, and pin notes on them that everyone sees. `ctx` lists the screen (`ctx show|rm|note|clear`). Likely secrets (API keys, tokens, private keys, `.env` lines) are flagged before anything is shown to agents, and redacted unless you say no. One-shot: `huddle join "fix this" --with error.log --with shot.png`, or `cat log.txt | huddle join "fix this"`. Items live in `.huddle/context/` (git-ignored); caps: 2 MB of text, 25 MB per file, 200 MB in all (`HUDDLE_CTX_MAX_*_MB`).
|
|
85
88
|
|
|
89
|
+
**Connectors: your team's tools for every agent.** One run's agents (Claude, Codex, Cursor, any of them) share the same outside tools through the Plug; the Room runs each connector once per run.
|
|
90
|
+
|
|
91
|
+
- **GitHub, built in:** issues, pull requests (with diffs) and CI runs, through the `gh` CLI you're signed in to. `huddle fix #12` makes issue 12 the goal (title, body and comments, verbatim); a goal that mentions `#12` gets the issue attached.
|
|
92
|
+
- **Any MCP server:** `huddle connectors add atlassian` (Jira + Confluence), `linear`, `notion`, `miro`, `sentry`; or `huddle connectors add <name> <https-url>`, or `huddle connectors add <name> -- <command…>` for a local one. Remote ones run through `mcp-remote`, which signs you in in the browser once and keeps the token. Huddle keeps none.
|
|
93
|
+
- **Read-only until you say so.** A tool that posts or changes something (a comment, a new ticket) is hidden until `--write` (`huddle connectors github write`). The server's own annotations decide what reads; without them, the tool's name does. What agents post is signed "via Huddle".
|
|
94
|
+
- **Only your agents.** A teammate's agent working from your room never reaches your connectors. Every call shows in the run (`codex github: read issue #12`) and is kept in the Room's record of the run.
|
|
95
|
+
- Config: `~/.huddle/connectors.json`. `huddle connectors` lists what's on and how many tools each gives.
|
|
96
|
+
|
|
97
|
+
**`huddle undo`** takes back what a run merged: one commit that reverts the run's commits (it lists them and asks first; `--yes` doesn't; `--run n` for an older run). History stays, nothing is force-pushed. If later work builds on the run, it says so and changes nothing.
|
|
98
|
+
|
|
99
|
+
**`huddle app`, the dashboard,** shows the run going now and every past run in your browser. A past run has **Undo this run** (the same undo, asked in the page first, refused while a run is going); with `gh` signed in, the start screen lists the repo's open issues with **Fix this**. **`huddle app --phone`** also opens it to your Wi-Fi and prints a QR code: scan it to follow and steer a run from your phone. The link carries a long per-session key and every page and call needs it; anyone with the link can control the run, and ctrl-c stops sharing. `--anywhere` uses a Cloudflare quick tunnel (an https link that works off your Wi-Fi) when `cloudflared` is installed.
|
|
100
|
+
|
|
86
101
|
**Running claude, codex and cursor yourself, in one repo at once (attach mode):**
|
|
87
102
|
|
|
88
103
|
```bash
|
package/dist/adapters/codex.js
CHANGED
|
@@ -48,6 +48,9 @@ export const codexAdapter = {
|
|
|
48
48
|
// calls under exec. The Plug is Huddle's own server, so pre-approve it.
|
|
49
49
|
"-c",
|
|
50
50
|
`mcp_servers.huddle.default_tools_approval_mode="approve"`,
|
|
51
|
+
// huddle_ask_user waits up to 90s for the person at the keyboard; Codex's default tool timeout is 60s.
|
|
52
|
+
"-c",
|
|
53
|
+
"mcp_servers.huddle.tool_timeout_sec=150",
|
|
51
54
|
// `codex exec` never stops to ask; its sandbox confines commands to the
|
|
52
55
|
// worktree. Without network, the sandbox also refuses to listen on
|
|
53
56
|
// localhost: seen live on the capstone, Codex couldn't run its own HTTP
|
package/dist/app/live.js
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
// The bridge between a run and the dashboard (`huddle app`), which may be
|
|
2
|
+
// another process: the run can start in a terminal and be watched, answered
|
|
3
|
+
// and stopped from the browser, or start from the browser itself.
|
|
4
|
+
//
|
|
5
|
+
// .huddle/live.json the run's live state, rewritten every second: phase,
|
|
6
|
+
// narrator, each agent's task / % / tokens, the
|
|
7
|
+
// council so far, a question waiting on you
|
|
8
|
+
// .huddle/inbox/ what the dashboard sends the run: your answer to a
|
|
9
|
+
// question, a line for the agents, stop. One JSON file
|
|
10
|
+
// each; the run takes them within a second
|
|
11
|
+
// .huddle/app.json the dashboard is open (pid, url): a run with no
|
|
12
|
+
// terminal still asks you its questions there
|
|
13
|
+
//
|
|
14
|
+
// Files, not a socket: the council runs before the Room exists, and either
|
|
15
|
+
// side may start first. Everything here is local to the repo's .huddle/.
|
|
16
|
+
import fs from "node:fs";
|
|
17
|
+
import path from "node:path";
|
|
18
|
+
const dir = (root) => path.join(root, ".huddle");
|
|
19
|
+
export const livePath = (root) => path.join(dir(root), "live.json");
|
|
20
|
+
export const inboxDir = (root) => path.join(dir(root), "inbox");
|
|
21
|
+
export const appFile = (root) => path.join(dir(root), "app.json");
|
|
22
|
+
/** Is `pid` a process on this machine? */
|
|
23
|
+
export function alive(pid) {
|
|
24
|
+
if (!Number.isInteger(pid) || pid <= 0)
|
|
25
|
+
return false;
|
|
26
|
+
try {
|
|
27
|
+
process.kill(pid, 0);
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
catch (e) {
|
|
31
|
+
return e?.code === "EPERM"; // exists, owned by someone else
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/** Write atomically: a reader never sees half a file. */
|
|
35
|
+
function writeJson(file, value) {
|
|
36
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
37
|
+
const tmp = `${file}.${process.pid}.tmp`;
|
|
38
|
+
fs.writeFileSync(tmp, JSON.stringify(value));
|
|
39
|
+
fs.renameSync(tmp, file);
|
|
40
|
+
}
|
|
41
|
+
function readJson(file) {
|
|
42
|
+
try {
|
|
43
|
+
return JSON.parse(fs.readFileSync(file, "utf8"));
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export function writeLive(root, s) {
|
|
50
|
+
try {
|
|
51
|
+
writeJson(livePath(root), s);
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
/* a read-only or vanished .huddle: the dashboard just won't see this run */
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/** The run in progress, or null: none, finished, or its process is gone (a crash, a kill -9). */
|
|
58
|
+
export function readLive(root) {
|
|
59
|
+
const s = readJson(livePath(root));
|
|
60
|
+
if (!s || s.done || !alive(s.pid))
|
|
61
|
+
return null;
|
|
62
|
+
return s;
|
|
63
|
+
}
|
|
64
|
+
let seq = 0;
|
|
65
|
+
/** The dashboard's side: queue a command for the run. */
|
|
66
|
+
export function postCommand(root, c) {
|
|
67
|
+
const d = inboxDir(root);
|
|
68
|
+
fs.mkdirSync(d, { recursive: true });
|
|
69
|
+
// Sorted by name = oldest first: two commands in one millisecond keep their order (seen on Linux).
|
|
70
|
+
const name = `${String(Date.now()).padStart(15, "0")}-${String(seq++).padStart(6, "0")}-${process.pid}.json`;
|
|
71
|
+
writeJson(path.join(d, name), c);
|
|
72
|
+
}
|
|
73
|
+
/** The run's side: every queued command, oldest first, each taken once. */
|
|
74
|
+
export function takeCommands(root) {
|
|
75
|
+
const d = inboxDir(root);
|
|
76
|
+
let names = [];
|
|
77
|
+
try {
|
|
78
|
+
names = fs.readdirSync(d).filter((n) => n.endsWith(".json")).sort();
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
83
|
+
const out = [];
|
|
84
|
+
for (const n of names) {
|
|
85
|
+
const f = path.join(d, n);
|
|
86
|
+
const c = readJson(f);
|
|
87
|
+
try {
|
|
88
|
+
fs.unlinkSync(f);
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
continue; // another taker got it
|
|
92
|
+
}
|
|
93
|
+
if (c && typeof c === "object" && ["answer", "say", "stop"].includes(c.type))
|
|
94
|
+
out.push(c);
|
|
95
|
+
}
|
|
96
|
+
return out;
|
|
97
|
+
}
|
|
98
|
+
/** Commands left from an earlier run must not steer this one. */
|
|
99
|
+
export function clearCommands(root) {
|
|
100
|
+
try {
|
|
101
|
+
for (const n of fs.readdirSync(inboxDir(root)))
|
|
102
|
+
fs.rmSync(path.join(inboxDir(root), n), { force: true });
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
/* no inbox yet */
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
export function writeAppInfo(root, info) {
|
|
109
|
+
writeJson(appFile(root), info);
|
|
110
|
+
}
|
|
111
|
+
export function clearAppInfo(root) {
|
|
112
|
+
const cur = readJson(appFile(root));
|
|
113
|
+
if (cur?.pid === process.pid)
|
|
114
|
+
fs.rmSync(appFile(root), { force: true });
|
|
115
|
+
}
|
|
116
|
+
/** The dashboard that's open on this repo, if any. */
|
|
117
|
+
export function openApp(root) {
|
|
118
|
+
const a = readJson(appFile(root));
|
|
119
|
+
return a && alive(a.pid) ? a : null;
|
|
120
|
+
}
|
|
121
|
+
/** The run's WHAT YOU GOT write-up, kept for the dashboard: .huddle/reports/<session>.md */
|
|
122
|
+
const reportFile = (root, session) => path.join(dir(root), "reports", `${session.replace(/[^\w-]/g, "_")}.md`);
|
|
123
|
+
export function saveReport(root, session, text) {
|
|
124
|
+
try {
|
|
125
|
+
fs.mkdirSync(path.dirname(reportFile(root, session)), { recursive: true });
|
|
126
|
+
fs.writeFileSync(reportFile(root, session), text);
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
/* the terminal had it; the dashboard just won't */
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
export function readReport(root, session) {
|
|
133
|
+
if (!session)
|
|
134
|
+
return null;
|
|
135
|
+
try {
|
|
136
|
+
return fs.readFileSync(reportFile(root, session), "utf8");
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=live.js.map
|