opencode-thrum-pro 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/commands/thrum-_deviations-protocol.md +87 -0
- package/assets/commands/thrum-_generator-idempotency-protocol.md +15 -0
- package/assets/commands/thrum-_project-rules-protocol.md +18 -0
- package/assets/commands/thrum-_snapshot-protocol.md +265 -0
- package/assets/commands/thrum-_stamp-protocol.md +112 -0
- package/assets/commands/thrum-_verify-before-write-protocol.md +27 -0
- package/assets/commands/thrum-inbox.md +22 -0
- package/assets/commands/thrum-load-context.md +17 -0
- package/assets/commands/thrum-overview.md +17 -0
- package/assets/commands/thrum-prime.md +30 -0
- package/assets/commands/thrum-quickstart.md +14 -0
- package/assets/commands/thrum-reply.md +28 -0
- package/assets/commands/thrum-restart-extended.md +195 -0
- package/assets/commands/thrum-restart.md +293 -0
- package/assets/commands/thrum-send.md +31 -0
- package/assets/commands/thrum-sleep-extended.md +186 -0
- package/assets/commands/thrum-sleep.md +212 -0
- package/assets/commands/thrum-team.md +12 -0
- package/assets/commands/thrum-update-project.md +259 -0
- package/assets/commands/thrum-wait.md +14 -0
- package/assets/skills/adversarial-critique/SKILL.md +242 -0
- package/assets/skills/brainstorm-queue-aware/SKILL.md +167 -0
- package/assets/skills/brainstorm-steward/SKILL.md +181 -0
- package/assets/skills/choosing-subagent-models/SKILL.md +244 -0
- package/assets/skills/closing-findings-while-warm/SKILL.md +104 -0
- package/assets/skills/configure-roles/SKILL.md +229 -0
- package/assets/skills/coordinator-assessing-agent-completion/SKILL.md +205 -0
- package/assets/skills/coordinator-assessing-agent-completion/scan.py +117 -0
- package/assets/skills/coordinator-branch-split-on-block/SKILL.md +168 -0
- package/assets/skills/coordinator-context-monitoring/SKILL.md +674 -0
- package/assets/skills/coordinator-dispatching-work/SKILL.md +288 -0
- package/assets/skills/coordinator-hotpath-merge-gate/SKILL.md +522 -0
- package/assets/skills/coordinator-interacting-with-the-owner/SKILL.md +171 -0
- package/assets/skills/coordinator-maintaining-memory/SKILL.md +89 -0
- package/assets/skills/coordinator-managing-state-and-lifecycle/SKILL.md +192 -0
- package/assets/skills/coordinator-merging-code/SKILL.md +331 -0
- package/assets/skills/coordinator-philosophy-merge-gate/SKILL.md +442 -0
- package/assets/skills/coordinator-plan-reconcile-gate/SKILL.md +198 -0
- package/assets/skills/coordinator-post-restart-sweep/SKILL.md +135 -0
- package/assets/skills/coordinator-running-autonomous-feature-development/SKILL.md +199 -0
- package/assets/skills/coordinator-running-brainstorm-cycles/SKILL.md +654 -0
- package/assets/skills/coordinator-running-review-cycles/SKILL.md +153 -0
- package/assets/skills/coordinator-single-responsibility-merge-gate/SKILL.md +14 -0
- package/assets/skills/diagnosing-fleet-and-daemon/SKILL.md +255 -0
- package/assets/skills/efficient-multi-agent-research/SKILL.md +177 -0
- package/assets/skills/fixing-documentation-errors/SKILL.md +258 -0
- package/assets/skills/implementer-maintaining-memory/SKILL.md +84 -0
- package/assets/skills/implementer-orchestrating-execution/SKILL.md +125 -0
- package/assets/skills/implementer-receiving-dispatch/SKILL.md +127 -0
- package/assets/skills/implementer-receiving-review-feedback/SKILL.md +125 -0
- package/assets/skills/implementer-status-and-handoff/SKILL.md +150 -0
- package/assets/skills/implementer-tdd-and-quality/SKILL.md +99 -0
- package/assets/skills/memory-audit-recover/SKILL.md +153 -0
- package/assets/skills/memory-curate/SKILL.md +139 -0
- package/assets/skills/memory-maintenance/SKILL.md +87 -0
- package/assets/skills/memory-read-discipline/SKILL.md +164 -0
- package/assets/skills/memory-search-advanced/SKILL.md +217 -0
- package/assets/skills/memory-write-discipline/SKILL.md +135 -0
- package/assets/skills/orchestrate/SKILL.md +795 -0
- package/assets/skills/persistent-watcher-archetype/SKILL.md +225 -0
- package/assets/skills/prime-agent/SKILL.md +92 -0
- package/assets/skills/project-hotpath-gate/SKILL.md +255 -0
- package/assets/skills/project-philosophy/SKILL.md +418 -0
- package/assets/skills/project-philosophy/resources/philosophy-template.md +155 -0
- package/assets/skills/project-philosophy/resources/reliability-class-library.md +653 -0
- package/assets/skills/project-setup/SKILL.md +1007 -0
- package/assets/skills/project-setup/resources/implementation-agent.md +826 -0
- package/assets/skills/researcher-answering-queries/SKILL.md +100 -0
- package/assets/skills/researcher-investigating/SKILL.md +152 -0
- package/assets/skills/researcher-maintaining-memory/SKILL.md +176 -0
- package/assets/skills/state-migration/SKILL.md +54 -0
- package/assets/skills/thrum/SKILL.md +161 -0
- package/assets/skills/thrum/resources/ANTI_PATTERNS.md +132 -0
- package/assets/skills/thrum/resources/BOUNDARIES.md +56 -0
- package/assets/skills/thrum/resources/CLI_REFERENCE.md +1066 -0
- package/assets/skills/thrum/resources/IDENTITY.md +49 -0
- package/assets/skills/thrum/resources/LISTENER_PATTERN.md +64 -0
- package/assets/skills/thrum/resources/MESSAGING.md +163 -0
- package/assets/skills/thrum/resources/TMUX_SESSIONS.md +118 -0
- package/assets/skills/thrum/resources/WORKTREES.md +117 -0
- package/assets/skills/thrum-memory/SKILL.md +138 -0
- package/assets/skills/trace-spec-to-plan/SKILL.md +104 -0
- package/assets/skills/trace-spec-to-plan/resources/sweep-agent-prompt.md +57 -0
- package/assets/skills/update-queue/SKILL.md +149 -0
- package/assets/skills/using-the-queue/SKILL.md +172 -0
- package/assets/skills/using-thrum-state/SKILL.md +104 -0
- package/assets/skills/verify-against-plan/SKILL.md +323 -0
- package/assets/skills/verify-against-source/SKILL.md +237 -0
- package/assets/skills/watcher-archetype/SKILL.md +84 -0
- package/assets/skills/writing-durable-markdown/SKILL.md +66 -0
- package/dist/hooks/block-sync-cd.d.ts +9 -0
- package/dist/hooks/block-sync-cd.js +71 -0
- package/dist/hooks/block-sync-cd.test.d.ts +1 -0
- package/dist/hooks/block-sync-cd.test.js +61 -0
- package/dist/hooks/shell-env.d.ts +8 -0
- package/dist/hooks/shell-env.js +22 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +25 -0
- package/dist/installer.d.ts +2 -0
- package/dist/installer.js +86 -0
- package/package.json +49 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Agent Identity
|
|
2
|
+
|
|
3
|
+
## Registration
|
|
4
|
+
|
|
5
|
+
Every agent must register before sending or receiving messages.
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
thrum quickstart --name <agent-name> --role <role> --module <module> --intent "<description>"
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
This registers the agent, starts a session, and sets the work intent.
|
|
12
|
+
|
|
13
|
+
## Identity Components
|
|
14
|
+
|
|
15
|
+
- **Name** — Human-readable identifier (auto-generated or via `--name`)
|
|
16
|
+
- **Role** — Function category: `implementer`, `planner`, `reviewer`, `tester`,
|
|
17
|
+
`coordinator`
|
|
18
|
+
- **Module** — Work area: `auth`, `website`, `api`, `testing`, etc.
|
|
19
|
+
- **Agent ID** — Format: `<name>:<role>:<module>` (e.g.,
|
|
20
|
+
`claude_impl:implementer:auth`)
|
|
21
|
+
|
|
22
|
+
## Identity Storage
|
|
23
|
+
|
|
24
|
+
Identities persist in `.thrum/identities/<name>.json`. Registration is
|
|
25
|
+
idempotent — re-registering with the same name updates the existing identity.
|
|
26
|
+
|
|
27
|
+
## Multi-Worktree Identity
|
|
28
|
+
|
|
29
|
+
See [WORKTREES.md](WORKTREES.md) for multi-worktree identity setup.
|
|
30
|
+
|
|
31
|
+
## Checking Identity
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
thrum whoami # Current identity
|
|
35
|
+
thrum overview # Identity + session + team + inbox + sync
|
|
36
|
+
thrum prime # Full context including identity
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Session Lifecycle
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
thrum session start # Begin session
|
|
43
|
+
thrum session set-intent "new intent" # Update intent
|
|
44
|
+
thrum session heartbeat # Keep alive
|
|
45
|
+
thrum session end # End session (do this when done)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Sessions make your agent visible in `thrum team`. Forgetting to end sessions
|
|
49
|
+
creates stale entries.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Listener Pattern: Background Message Monitoring
|
|
2
|
+
|
|
3
|
+
> **Prefer tmux-managed sessions when tmux is available.** They deliver messages
|
|
4
|
+
> at zero token cost with no background listener needed. See
|
|
5
|
+
> [TMUX_SESSIONS.md](TMUX_SESSIONS.md). Use the listener pattern below when tmux
|
|
6
|
+
> is not available or not practical for your setup.
|
|
7
|
+
|
|
8
|
+
The message-listener is a background sub-agent that blocks on `thrum wait` and
|
|
9
|
+
returns when messages arrive. A PID file (`.thrum/var/<agent_id>-listener.pid`)
|
|
10
|
+
prevents duplicate listeners — spawning when one is already running is safe.
|
|
11
|
+
|
|
12
|
+
## Quick Start
|
|
13
|
+
|
|
14
|
+
```text
|
|
15
|
+
Task(
|
|
16
|
+
subagent_type="message-listener",
|
|
17
|
+
model="sonnet", # low effort
|
|
18
|
+
prompt="Listen for Thrum messages.\nSTEP_1: /path/to/repo/scripts/thrum-startup.sh --listener-heartbeat\nSTEP_2: thrum wait --timeout 8m --after -15s --agent-name <agent_id>"
|
|
19
|
+
)
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Replace `/path/to/repo` with the actual repo path and `<agent_id>` with your
|
|
23
|
+
agent name. `thrum prime` outputs a ready-to-use spawn instruction with both
|
|
24
|
+
pre-filled.
|
|
25
|
+
|
|
26
|
+
## How It Works
|
|
27
|
+
|
|
28
|
+
1. **Spawn** — Launch as background Task (`background: true` in frontmatter)
|
|
29
|
+
2. **PID file** — `thrum wait --agent-name` writes a PID file on start, updates
|
|
30
|
+
it each cycle, and removes it on exit (or signal). All spawn paths check this
|
|
31
|
+
file with `kill -0` before spawning.
|
|
32
|
+
3. **Block** — `thrum wait --timeout 8m` blocks until message or timeout
|
|
33
|
+
4. **Return or loop** — Message received → stop. Timeout → back to step 2.
|
|
34
|
+
|
|
35
|
+
The listener loops internally (up to ~30 cycles of 8 min = ~4 hours max).
|
|
36
|
+
|
|
37
|
+
## Wait Command Flags
|
|
38
|
+
|
|
39
|
+
| Flag | Purpose |
|
|
40
|
+
| ----------------- | ------------------------------------------------------- |
|
|
41
|
+
| `--timeout 8m` | Block up to 8 min per cycle (under Bash 600s limit) |
|
|
42
|
+
| `--after -15s` | Include messages sent up to 15s ago (covers re-arm gap) |
|
|
43
|
+
| `--agent-name ID` | Write PID file for spawn coordination |
|
|
44
|
+
|
|
45
|
+
## Cron Watchdog (Recommended)
|
|
46
|
+
|
|
47
|
+
Automatically respawn the listener if it dies or is lost after compaction.
|
|
48
|
+
|
|
49
|
+
```text
|
|
50
|
+
CronCreate(
|
|
51
|
+
cron="*/30 * * * *",
|
|
52
|
+
prompt="Check the listener PID file at .thrum/var/<agent_id>-listener.pid.\nIf the file does not exist, or if kill -0 <pid> fails (process not running),\nspawn a new listener:\n\nAgent(subagent_type=\"message-listener\", model=\"sonnet\", prompt=\"Listen for Thrum messages.\\nSTEP_1: /path/to/repo/scripts/thrum-startup.sh --listener-heartbeat\\nSTEP_2: thrum wait --timeout 8m --after -15s --agent-name <agent_id>\")"
|
|
53
|
+
)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Spawn the initial listener on session start, then create the cron watchdog.
|
|
57
|
+
|
|
58
|
+
## Key Rules
|
|
59
|
+
|
|
60
|
+
- **Spawn freely** — PID file prevents duplicates
|
|
61
|
+
- **Return immediately** when messages arrive (don't wait for more)
|
|
62
|
+
- **Read-only** — the listener never sends messages
|
|
63
|
+
- **Cost-efficient** — runs on sonnet-low, blocks instead of polling
|
|
64
|
+
- Listener uses CLI only (`Bash` tool), not MCP tools
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# Messaging Protocol
|
|
2
|
+
|
|
3
|
+
## Message Lifecycle
|
|
4
|
+
|
|
5
|
+
1. **Send** — `thrum send --to @name --body-file msg.md` (direct; see
|
|
6
|
+
§Shell-Safe below for heredoc form)
|
|
7
|
+
2. **Deliver** — Daemon writes to recipient's inbox (JSONL in
|
|
8
|
+
`.git/thrum-sync/`)
|
|
9
|
+
3. **Receive** — `thrum inbox` or `thrum wait` (blocking)
|
|
10
|
+
4. **Verify sent state** — `thrum sent` or `thrum message get <msg-id>`
|
|
11
|
+
5. **Read** — Auto-marked read when displayed via `thrum inbox`; use
|
|
12
|
+
`thrum inbox --unread` to peek without marking. Explicit:
|
|
13
|
+
`thrum message read --all`
|
|
14
|
+
6. **Search — do not page through the inbox to find old messages.** The
|
|
15
|
+
default page is 10, newest-first, so stale unread sorts LAST exactly when
|
|
16
|
+
it has waited longest. Use `thrum message search "<term>"` (full-text,
|
|
17
|
+
positional query, no `--limit`) or `thrum inbox -q "<term>"` (same search
|
|
18
|
+
scoped to your inbox). `thrum message reindex` rebuilds the FTS index if
|
|
19
|
+
search looks wrong.
|
|
20
|
+
7. **Reply** — `thrum reply <msg-id> --body-file reply.md` (see Addressing for
|
|
21
|
+
the no-`--to` rule)
|
|
22
|
+
|
|
23
|
+
## Addressing
|
|
24
|
+
|
|
25
|
+
| Target | Routing | When to use |
|
|
26
|
+
| ------------------- | ------------------------------------------------------------- | ------------------------------------ |
|
|
27
|
+
| `--to @lead_agent` | **Direct** — routes to the named agent | Default for all task messages |
|
|
28
|
+
| `--to @coordinator` | **Role fanout** — ALL agents with that role (warning emitted) | Only when you want every coordinator |
|
|
29
|
+
| `--to @everyone` | **Broadcast** — all registered agents | Critical alerts |
|
|
30
|
+
|
|
31
|
+
**Critical:** `@coordinator` is a role, not an agent name. Sending
|
|
32
|
+
`--to @coordinator` fans out to every agent registered with that role. Use
|
|
33
|
+
`thrum team` to find agent names, then send `--to @<name>` for direct messages.
|
|
34
|
+
|
|
35
|
+
- **Reply:** `thrum reply <msg-id>` — same audience as original; takes **no
|
|
36
|
+
`--to`** (recipient derived from the message)
|
|
37
|
+
- **Unknown recipient** — hard error; verify names with `thrum team`
|
|
38
|
+
|
|
39
|
+
## Shell-Safe Message Bodies (backticks, `$(...)`, `$VAR`, quotes)
|
|
40
|
+
|
|
41
|
+
**The trap:** a double-quoted body is processed by your shell _before_ thrum
|
|
42
|
+
runs. Backticks and `$(...)` are command-substituted, `$VAR` is expanded, and
|
|
43
|
+
the original text never reaches thrum — it cannot detect or repair the
|
|
44
|
+
corruption. Single-quoting is only a stopgap — it breaks on apostrophes in
|
|
45
|
+
prose.
|
|
46
|
+
|
|
47
|
+
**The safe default:** read the body from stdin or a file instead of passing it
|
|
48
|
+
as a quoted argument. A **quoted** heredoc (`<<'EOF'` — note the quotes around
|
|
49
|
+
`EOF`) disables _all_ shell interpretation, so backticks, `$`, apostrophes, and
|
|
50
|
+
quotes all pass through literally. Available on `send`, `reply`, and
|
|
51
|
+
`message edit`:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# Preferred: quoted heredoc via --stdin (safe for backticks, $, apostrophes)
|
|
55
|
+
thrum send --to @agent_name --stdin <<'EOF'
|
|
56
|
+
Run `make build` then check $(git rev-parse HEAD). It's done.
|
|
57
|
+
EOF
|
|
58
|
+
|
|
59
|
+
# Reply the same way (no --to — recipient comes from the parent message)
|
|
60
|
+
thrum reply msg_01HXE... --stdin <<'EOF'
|
|
61
|
+
Done — see `internal/foo.go`. Cost was $(estimate).
|
|
62
|
+
EOF
|
|
63
|
+
|
|
64
|
+
# From a file
|
|
65
|
+
thrum send --to @agent_name --body-file ./body.md
|
|
66
|
+
|
|
67
|
+
# '-' as the body argument is a --stdin alias (good for pipes)
|
|
68
|
+
some-generator | thrum send --to @agent_name -
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Rules:
|
|
72
|
+
|
|
73
|
+
- `--stdin` and `--body-file` are mutually exclusive, and neither may be
|
|
74
|
+
combined with a positional body (the command errors on ambiguity).
|
|
75
|
+
- A single trailing newline (the one the heredoc adds) is stripped; additional
|
|
76
|
+
blank lines are preserved.
|
|
77
|
+
- All bodies must be supplied via `--stdin` (or `-`), or `--body-file` —
|
|
78
|
+
positional body arguments are refused to prevent silent shell substitution.
|
|
79
|
+
|
|
80
|
+
## Permission-Prompt Routing
|
|
81
|
+
|
|
82
|
+
Runtime permission prompts (e.g. "Allow this tool?") route to recipients listed
|
|
83
|
+
in `permission_supervisors` in `.thrum/config.json`. **The array is
|
|
84
|
+
authoritative** — the daemon sends the nudge to each entry in order, with no
|
|
85
|
+
auto-detect or broadcast fallback behind it.
|
|
86
|
+
|
|
87
|
+
```jsonc
|
|
88
|
+
{
|
|
89
|
+
"permission_supervisors": [
|
|
90
|
+
"coordinator", // role → fans out to every active coordinator
|
|
91
|
+
"@your_coordinator", // specific agent (name-based)
|
|
92
|
+
"@user:jane-doe", // user → auto-bridges to Telegram if configured
|
|
93
|
+
],
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Invariant:** the list must include at least one coordinator-role recipient —
|
|
98
|
+
either the bare role `"coordinator"` or an `@coordinator_*` agent name. When
|
|
99
|
+
absent or empty, the resolver defaults to `["coordinator"]`. If the list is
|
|
100
|
+
non-empty but has no coordinator entry, the daemon warns at start and continues
|
|
101
|
+
(prompts may still go undelivered if the listed agents are offline).
|
|
102
|
+
|
|
103
|
+
## Threading
|
|
104
|
+
|
|
105
|
+
Replies auto-create implicit threads. When you `thrum reply`, the daemon assigns
|
|
106
|
+
a shared `thread_id` to both parent and reply. No explicit thread creation
|
|
107
|
+
needed. The UI groups conversations by `thread_id`.
|
|
108
|
+
|
|
109
|
+
## Context Management
|
|
110
|
+
|
|
111
|
+
### Session Initialization
|
|
112
|
+
|
|
113
|
+
`thrum prime` gathers all context in one call:
|
|
114
|
+
|
|
115
|
+
- Agent identity (name, role, module)
|
|
116
|
+
- Team (active agents and their intents)
|
|
117
|
+
- Inbox (unread messages with summaries)
|
|
118
|
+
- Git context (branch, uncommitted files)
|
|
119
|
+
- Daemon health and sync state
|
|
120
|
+
|
|
121
|
+
The **SessionStart** hook prompts you to run `/thrum:prime`. The **PreCompact**
|
|
122
|
+
hook auto-saves context to a backup file.
|
|
123
|
+
|
|
124
|
+
### After Compaction
|
|
125
|
+
|
|
126
|
+
Context auto-recovers via the PreCompact hook. The agent sees:
|
|
127
|
+
|
|
128
|
+
1. Their identity and session state
|
|
129
|
+
2. Any unread messages accumulated during compaction
|
|
130
|
+
3. Current team state
|
|
131
|
+
4. Quick command reference
|
|
132
|
+
|
|
133
|
+
### Identity Persistence
|
|
134
|
+
|
|
135
|
+
Agent identities are stored in `.thrum/identities/<name>.json` and persist
|
|
136
|
+
across sessions. Registration via `thrum quickstart` is idempotent —
|
|
137
|
+
re-registering with the same name updates the existing identity.
|
|
138
|
+
|
|
139
|
+
For multi-worktree setups, see [WORKTREES.md](WORKTREES.md) for identity setup.
|
|
140
|
+
|
|
141
|
+
## Unified Workflow: Thrum + Beads
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
# Find work
|
|
145
|
+
thrum issue ready
|
|
146
|
+
|
|
147
|
+
# Claim and announce → Beads + Thrum
|
|
148
|
+
bd update bd-123 --status in_progress
|
|
149
|
+
thrum send --to @lead_agent --stdin <<'EOF'
|
|
150
|
+
Starting bd-123
|
|
151
|
+
EOF
|
|
152
|
+
|
|
153
|
+
# Work, update → Thrum
|
|
154
|
+
thrum send --to @lead_agent --stdin <<'EOF'
|
|
155
|
+
Progress: auth module complete
|
|
156
|
+
EOF
|
|
157
|
+
|
|
158
|
+
# Complete → Beads + Thrum
|
|
159
|
+
bd close bd-123 --reason "Done with tests"
|
|
160
|
+
thrum send --to @reviewer1 --stdin <<'EOF'
|
|
161
|
+
bd-123 done, ready for review
|
|
162
|
+
EOF
|
|
163
|
+
```
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Tmux-Managed Sessions
|
|
2
|
+
|
|
3
|
+
Tmux-managed sessions are the recommended way to run Thrum agents. The daemon
|
|
4
|
+
detects the tmux pane and delivers message notifications directly — zero token
|
|
5
|
+
cost, no background listener needed.
|
|
6
|
+
|
|
7
|
+
## Why Tmux Sessions
|
|
8
|
+
|
|
9
|
+
- **Zero-cost message delivery** — daemon nudges the tmux pane directly
|
|
10
|
+
- **No background listener** — eliminates the message-listener sub-agent
|
|
11
|
+
- **Session lifecycle** — create, launch, status, connect, restart, kill
|
|
12
|
+
- **Runtime detection** — reads configured runtime from `.thrum/config.json`
|
|
13
|
+
|
|
14
|
+
## Quick Start
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
thrum tmux start # One-command: create + launch + prime + attach
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
This creates a tmux session named after the current directory, launches the
|
|
21
|
+
configured runtime (from `config.Runtime.Primary`, default `claude`), runs
|
|
22
|
+
`/thrum:prime` for registration, and attaches.
|
|
23
|
+
|
|
24
|
+
## Setting Up a New Agent Worktree
|
|
25
|
+
|
|
26
|
+
Full sequence for a coordinator setting up an agent in a new worktree:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# 1. Initialize thrum + beads redirects in the worktree
|
|
30
|
+
cd <worktree-path>
|
|
31
|
+
thrum init # Sets up .thrum redirect to main repo
|
|
32
|
+
# Beads: bd init doesn't auto-detect worktrees, so set up the redirect manually:
|
|
33
|
+
mkdir -p .beads && echo /path/to/main/repo/.beads > .beads/redirect
|
|
34
|
+
|
|
35
|
+
# 2. Create tmux session + register agent identity in one step
|
|
36
|
+
thrum tmux create <name> --cwd <path> \
|
|
37
|
+
--name <agent> --role <role> --module <mod> --intent '...'
|
|
38
|
+
# alias: thrum tmux quickstart <name> --cwd <path> --name <agent> --role <role> --module <mod>
|
|
39
|
+
|
|
40
|
+
# 3. Launch the runtime (reads configured runtime from .thrum/config.json)
|
|
41
|
+
thrum tmux launch <name>
|
|
42
|
+
|
|
43
|
+
# 4. Agent runs /thrum:prime on startup — loads identity + full context
|
|
44
|
+
# 5. Communicate via: thrum send --to @<agent> --body-file msg.md (or --stdin <<'EOF' heredoc)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`thrum tmux create` requires either quickstart flags (`--name`, `--role`,
|
|
48
|
+
`--module`) or `--no-agent`. Bare `thrum tmux create <name> --cwd <path>` errors
|
|
49
|
+
out.
|
|
50
|
+
|
|
51
|
+
**Single identity per worktree:** quickstart cleans up any old identity files in
|
|
52
|
+
the worktree. Each worktree has exactly one identity.
|
|
53
|
+
|
|
54
|
+
**`--no-agent`** skips identity registration — for bare sessions, debugging, or
|
|
55
|
+
non-agent processes:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
thrum tmux create debug-session --cwd /path --no-agent
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Note: `thrum tmux launch` will hard-error on `--no-agent` sessions because
|
|
62
|
+
there's no agent identity to determine the runtime. Either register an agent
|
|
63
|
+
first with `thrum quickstart` inside the pane, or use `tmux create` without
|
|
64
|
+
`--no-agent`.
|
|
65
|
+
|
|
66
|
+
## Manual Setup (Quick Reference)
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
thrum tmux create <name> --cwd <path> --name <agent> --role <role> --module <mod>
|
|
70
|
+
thrum tmux launch <name> # Start runtime in session
|
|
71
|
+
thrum tmux connect <name> # Attach to session
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Session Management
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
thrum tmux status # Show all managed sessions with state
|
|
78
|
+
thrum tmux connect # Interactive picker for alive sessions
|
|
79
|
+
thrum tmux connect <name> # Attach directly by name
|
|
80
|
+
thrum tmux kill <name> # Tear down a session
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Message Delivery
|
|
84
|
+
|
|
85
|
+
When a message arrives for your agent, the daemon sends a nudge directly to your
|
|
86
|
+
tmux pane. You'll see a notification appear — check your inbox:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
thrum inbox --unread
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
For anything older, see [MESSAGING.md](MESSAGING.md) Lifecycle step 6 (search
|
|
93
|
+
instead of paging).
|
|
94
|
+
|
|
95
|
+
No listener sub-agent, no polling, no CronCreate watchdog. Messages just arrive.
|
|
96
|
+
|
|
97
|
+
## Session Restart
|
|
98
|
+
|
|
99
|
+
When the context window is running low, restart with a conversation snapshot
|
|
100
|
+
preserved:
|
|
101
|
+
|
|
102
|
+
- **Self-initiated:** Run `/thrum:restart` — saves snapshot, notifies
|
|
103
|
+
coordinator
|
|
104
|
+
- **Coordinator-initiated:** `thrum tmux restart <name>` — **PLAIN, not `--force`.**
|
|
105
|
+
`--force` **drops the `--model` pin**; a plain restart re-applies it at the
|
|
106
|
+
readiness probe. Only use `--force` if a plain restart does not take, and then
|
|
107
|
+
re-pin and verify the model **off the pane** (`runtime-config get` reports what
|
|
108
|
+
was requested, not what is running).
|
|
109
|
+
- **Automatic:** Configure `restart.auto_threshold` in `.thrum/config.json`
|
|
110
|
+
|
|
111
|
+
The snapshot is automatically included in `thrum prime` on the next session
|
|
112
|
+
start.
|
|
113
|
+
|
|
114
|
+
## When Tmux Isn't Available
|
|
115
|
+
|
|
116
|
+
If tmux is not installed or not practical for your setup, use the background
|
|
117
|
+
message listener pattern instead. See
|
|
118
|
+
[LISTENER_PATTERN.md](LISTENER_PATTERN.md).
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Multi-Worktree Coordination
|
|
2
|
+
|
|
3
|
+
Thrum enables agents in different git worktrees to communicate via a shared
|
|
4
|
+
daemon and git-backed message storage.
|
|
5
|
+
|
|
6
|
+
## Setup
|
|
7
|
+
|
|
8
|
+
Use `thrum worktree create` to create a worktree and register an agent in one
|
|
9
|
+
step. This handles git, redirects, identity, and tmux session setup.
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Two-step pattern (create + launch)
|
|
13
|
+
thrum worktree create my-feature \
|
|
14
|
+
--name impl_my_feature --role implementer --module my-feature \
|
|
15
|
+
--intent "Feature implementation"
|
|
16
|
+
# → creates worktree, registers agent, creates tmux session
|
|
17
|
+
# → output tells you to run: thrum tmux launch my-feature
|
|
18
|
+
|
|
19
|
+
thrum tmux launch my-feature
|
|
20
|
+
# → starts the runtime (claude/codex/cursor) in the tmux pane
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The worktree is created at `<base_path>/<name>` (default
|
|
24
|
+
`~/.workspaces/<repo-name>/<name>`). Branch defaults to `feature/<name>`,
|
|
25
|
+
override with `-b <branch>`.
|
|
26
|
+
|
|
27
|
+
`worktree create` automatically:
|
|
28
|
+
|
|
29
|
+
- Creates the git worktree
|
|
30
|
+
- Sets up the `.thrum/` redirect to the main repo
|
|
31
|
+
- Creates a tmux session with the worktree as cwd
|
|
32
|
+
- Runs quickstart inside the pane (PID-isolated, retries if shell init swallows
|
|
33
|
+
the command)
|
|
34
|
+
- Reports the next-step `tmux launch` command
|
|
35
|
+
|
|
36
|
+
The agent is **NOT running** until `thrum tmux launch <name>` is called. The
|
|
37
|
+
launch step is what actually starts the AI runtime (claude/codex/etc).
|
|
38
|
+
|
|
39
|
+
### Worktree without an agent
|
|
40
|
+
|
|
41
|
+
To set up the worktree without registering an agent, omit the agent
|
|
42
|
+
flags:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
thrum worktree create my-feature
|
|
46
|
+
# → creates worktree + redirect only
|
|
47
|
+
# → output tells you: thrum tmux create my-feature --cwd <path> --name <agent> --role <r> --module <m>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Existing worktree
|
|
51
|
+
|
|
52
|
+
For a worktree that already exists without thrum setup, use `tmux create`
|
|
53
|
+
directly:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
thrum tmux create existing-feature --cwd /path/to/worktree \
|
|
57
|
+
--name impl_existing --role implementer --module existing
|
|
58
|
+
thrum tmux launch existing-feature
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Shared Daemon
|
|
62
|
+
|
|
63
|
+
All worktrees share one daemon instance. The daemon auto-discovers worktrees via
|
|
64
|
+
the shared `.thrum/` directory at the git root.
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# Start daemon once (from any worktree)
|
|
68
|
+
# Note: thrum init also starts the daemon automatically if not already running
|
|
69
|
+
thrum daemon start
|
|
70
|
+
|
|
71
|
+
# All worktrees connect to the same daemon
|
|
72
|
+
thrum daemon status # Shows shared daemon health from any worktree
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Cross-Worktree Messaging
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# From main worktree
|
|
79
|
+
thrum send --to @feature_impl --stdin <<'EOF'
|
|
80
|
+
Feature branch ready for integration
|
|
81
|
+
EOF
|
|
82
|
+
|
|
83
|
+
# From feature worktree
|
|
84
|
+
thrum inbox # Sees message from @main_coordinator
|
|
85
|
+
thrum sent # Verifies what this worktree sent and who read it
|
|
86
|
+
thrum reply <msg-id> --stdin <<'EOF'
|
|
87
|
+
Integration tests passing, ready to merge
|
|
88
|
+
EOF
|
|
89
|
+
thrum message read --all # Mark all messages as read
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## File Coordination
|
|
93
|
+
|
|
94
|
+
Check which agent is editing a file before making changes:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
thrum who-has src/auth/login.ts
|
|
98
|
+
# Output: @feature_impl (active)
|
|
99
|
+
|
|
100
|
+
# Coordinate via message
|
|
101
|
+
thrum send --to @feature_impl --stdin <<'EOF'
|
|
102
|
+
Need to edit login.ts, are you done?
|
|
103
|
+
EOF
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Sync
|
|
107
|
+
|
|
108
|
+
Messages sync via git. The daemon handles push/pull automatically. Force sync if
|
|
109
|
+
needed:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
thrum sync force
|
|
113
|
+
thrum sync status
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
For multi-machine setups, ensure all machines can push/pull to the same git
|
|
117
|
+
remote.
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: thrum-memory
|
|
3
|
+
description: "Use when capturing or querying structured memories (session summaries, architectural decisions, restart snapshots, agent rules) via the thrum memory CLI. Loads decision flowchart, kind taxonomy, default-safe behaviors, and pointers to advanced sub-skills."
|
|
4
|
+
allowed-tools: "Bash(thrum memory:*)"
|
|
5
|
+
version: "0.11.0"
|
|
6
|
+
license: "Apache-2.0"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# thrum memory — capture and query structured memories
|
|
10
|
+
|
|
11
|
+
## When to use thrum memory vs. other stores
|
|
12
|
+
|
|
13
|
+
Just learned something that future work should respect? → `thrum memory create`
|
|
14
|
+
(decide kind below).
|
|
15
|
+
|
|
16
|
+
Transient task state (in-progress work, current session context)? → `bd update`
|
|
17
|
+
/ `bd comments` (per-task notes).
|
|
18
|
+
|
|
19
|
+
Long-form project narrative (architecture decisions, release status)? → memory
|
|
20
|
+
of kind `arch_decision` or `session_summary` (the integration brainstorm will
|
|
21
|
+
wire these into prime-assembly later).
|
|
22
|
+
|
|
23
|
+
Code documentation (CLAUDE.md, READMEs, in-file comments)? → edit the file
|
|
24
|
+
directly; memory is for structured records, not docs.
|
|
25
|
+
|
|
26
|
+
## Kind taxonomy at a glance
|
|
27
|
+
|
|
28
|
+
- `session_summary` — what shipped in a session (replaces ad-hoc session notes)
|
|
29
|
+
- `arch_decision` — long-lived architectural decision; can be superseded later
|
|
30
|
+
- `current_state` — point-in-time state snapshot; expires fast
|
|
31
|
+
- `epic_status` — one row of "Open Epics / Active Work"
|
|
32
|
+
- `worktree_status` — one worktree-table row; expires per session
|
|
33
|
+
- `stable_infra` — long-lived infrastructure entry
|
|
34
|
+
- `resume_snapshot` — per-agent restart blob (scope=agent)
|
|
35
|
+
- `agent_rule` — rule/preference for future sessions (scope=role or
|
|
36
|
+
scope=project)
|
|
37
|
+
- `comment` — comment on a parent memory (`child_of: <parent-id>`)
|
|
38
|
+
|
|
39
|
+
## Top operations (the 80% case)
|
|
40
|
+
|
|
41
|
+
Create with all three zoom levels (recommended; warns via MEM-010 otherwise):
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
thrum memory create --kind arch_decision \
|
|
45
|
+
--title "Tailscale-only sync" \
|
|
46
|
+
--oneline "Removed git a-sync; Tailscale peering is sole sync mechanism" \
|
|
47
|
+
--short @short.md --full @full.md \
|
|
48
|
+
--tag substrate,sync
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
See `memory-write-discipline` for prose-into-a-command conventions.
|
|
52
|
+
|
|
53
|
+
Search by tag + kind, default limit 10:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
thrum memory search --tag substrate --kind arch_decision
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Show a single memory by ID:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
thrum memory show thrum-mem-01HQXZP3V8K2N7M0YJWQ8R5T6F
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Edit a single field (other zoom levels stay intact; only changed-zoom embeddings
|
|
66
|
+
re-queue):
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
thrum memory edit <id> --short @newshort.md
|
|
70
|
+
thrum memory edit <id> --add-tag v0.11 --rm-tag draft
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Link an edge:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
thrum memory link <new-id> supersedes <old-id>
|
|
77
|
+
thrum memory link <child-id> child_of <parent-id>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Default-safe behaviors
|
|
81
|
+
|
|
82
|
+
- `--limit 10` by default for search (memory body_full is 5-50× larger than
|
|
83
|
+
typical messages; bounded context pollution). `--limit 25` or higher is a
|
|
84
|
+
one-flag opt-in for deeper exploration.
|
|
85
|
+
- `status=active` default filter (use `--status all` to include
|
|
86
|
+
superseded/purged).
|
|
87
|
+
- **Scope is an ASSEMBLY filter** (NOT visibility/access control) —
|
|
88
|
+
`memory.search` returns everything matching your predicates regardless of
|
|
89
|
+
scope unless `--scope` is explicitly passed. Scope only affects which memories
|
|
90
|
+
the (deferred) default assembler folds into an agent's prime context.
|
|
91
|
+
|
|
92
|
+
## Feature-scoped queries — use tags, not scope
|
|
93
|
+
|
|
94
|
+
Scope is closed (`project / agent / role`). For "feature-scoped" filtering
|
|
95
|
+
(e.g., "show me memories about the watcher-substrate feature"), use the
|
|
96
|
+
`feature-<name>` tag-naming convention:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
thrum memory create --kind session_summary --tag feature-watcher-substrate,substrate ...
|
|
100
|
+
thrum memory search --tag feature-watcher-substrate --limit 10
|
|
101
|
+
thrum memory search --tag substrate --kind arch_decision # one tag per query; for OR, run one search per tag
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Convention only — no code enforces the `feature-` prefix, but discoverability
|
|
105
|
+
across agents/sessions depends on consistency.
|
|
106
|
+
|
|
107
|
+
## When you need more
|
|
108
|
+
|
|
109
|
+
- For RAG / `--near` queries / complex predicates / hint code interpretation:
|
|
110
|
+
load the `memory-search-advanced` skill
|
|
111
|
+
- For edges, hierarchy, supersede semantics, comments-as-memories: load the
|
|
112
|
+
`memory-curate` skill
|
|
113
|
+
- For audit history, undelete, hard-delete confirmation flow: load the
|
|
114
|
+
`memory-audit-recover` skill
|
|
115
|
+
|
|
116
|
+
## First-time setup (configuration)
|
|
117
|
+
|
|
118
|
+
Embedding adapter is opt-in. Default config disables RAG; full-text search
|
|
119
|
+
(`--grep`) works without it. To enable RAG:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
thrum config set llm.embedding.enabled true
|
|
123
|
+
thrum config set llm.embedding.provider ollama
|
|
124
|
+
thrum config set llm.embedding.base_url http://localhost:11434
|
|
125
|
+
thrum config set llm.embedding.model "granite-embedding:30m-english"
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
For non-English projects use `granite-embedding-multilingual-97m` instead.
|
|
129
|
+
|
|
130
|
+
`id_prefix` for memory IDs is auto-derived from your repo (git remote URL →
|
|
131
|
+
main-worktree basename → CWD basename, with normalization). To override:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
thrum config set id_prefix "my-repo"
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Rate limit and backfill knobs live under `embedding.max_per_minute` (default 60)
|
|
138
|
+
and `embedding.backfill_on_boot` (default true).
|