You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+7-4Lines changed: 7 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -96,10 +96,13 @@ For the current model, see [Orchestrating Child Agents](docs/guides/orchestratin
96
96
97
97
## How It Works
98
98
99
-
1. Create a tentacle for a scoped slice of work.
100
-
2. Store context, notes, and `todo.md` inside that tentacle so the agent has durable, local guidance.
101
-
3. Run one or more agent terminals against that tentacle, and delegate child work from the task list when needed.
102
-
4. Use the local API and web UI to monitor sessions, messages, transcripts, and worktree state.
99
+
Octogent separates three concerns that usually get mixed together in a pile of terminals:
100
+
101
+
1.**Context** lives in `.octogent/tentacles/<tentacle-id>/`. `CONTEXT.md` explains the area, `todo.md` supplies executable work items, and extra markdown files hold notes or handoffs.
102
+
2.**Execution** lives in terminal records and PTY sessions managed by the local API. A terminal can attach to an existing tentacle, and several terminals can share one tentacle during swarm work.
103
+
3.**Isolation** is optional. Shared terminals run in the main workspace; worktree terminals run under `.octogent/worktrees/<worktree-id>/` on `octogent/<worktree-id>` branches.
104
+
105
+
Deck reads the tentacle files directly, parses checkbox items from `todo.md`, and uses incomplete items to generate worker prompts. Claude hooks feed the API with agent state, transcript, and idle events so the UI can show more than raw terminal output.
Copy file name to clipboardExpand all lines: docs/concepts/mental-model.md
+39-16Lines changed: 39 additions & 16 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,23 +2,38 @@
2
2
3
3
This page is for the exact model behind Octogent. The README is the pitch. This page is the boundary map.
4
4
5
-
## The main pieces
6
-
7
-
- the **developer** defines the jobs and reviews the output
8
-
- a **tentacle** holds the local context for one job
9
-
- a **terminal** is one live Claude Code session
10
-
- a **worker** is a terminal assigned to a narrower piece of work
11
-
- a **parent** is a terminal coordinating one or more workers
12
-
- a **channel** is a short-lived coordination path between terminals
5
+
## Architectural layers
6
+
7
+
Octogent separates durable work context from live terminal execution.
8
+
9
+
```mermaid
10
+
flowchart TD
11
+
Human[Developer] --> Deck[Deck and Canvas UI]
12
+
Deck --> API[Local API]
13
+
API --> Files[".octogent/tentacles/*"]
14
+
API --> State["~/.octogent/projects/<id>/state/*"]
15
+
API --> PTY[PTY-backed agent sessions]
16
+
PTY --> Hooks[Claude hooks]
17
+
Hooks --> API
18
+
```
19
+
20
+
- the **developer** defines boundaries, reviews output, and decides what lands
21
+
- a **tentacle** is the durable job context: markdown files, todos, notes, and handoff state
22
+
- a **terminal** is the runtime record plus, when active, one PTY-backed agent session
23
+
- a **worker** is a terminal assigned to one narrower task, usually a todo item
24
+
- a **parent** is a terminal that coordinates workers and performs final review or merge work
25
+
- a **channel** is an in-memory queue used to inject short messages into live terminals
13
26
14
27
## Tentacle vs terminal
15
28
16
29
These are different things.
17
30
18
31
- a **tentacle** is a folder with agent-readable files
19
-
- a **terminal** is a running session
32
+
- a **terminal** is a runtime object that can attach to one tentacle
33
+
34
+
Multiple terminals can point at the same tentacle. Swarm workers use that property: each worker gets the same context files, but each terminal has its own identity, transcript, lifecycle state, and optional worktree.
20
35
21
-
Multiple terminals can point at the same tentacle. That matters for swarm work, because several workers may need the same local context while still remaining separate sessions.
36
+
This is why terminal IDs and tentacle IDs are not interchangeable. A terminal can be named `api-runtime-swarm-2`while still using the `api-runtime` tentacle context.
22
37
23
38
## Tentacle vs worktree
24
39
@@ -34,6 +49,8 @@ A tentacle can be used with:
34
49
35
50
The tentacle decides *what the job is about*. The worktree decides *where the code changes happen*.
36
51
52
+
In shared mode, the PTY starts in the main workspace. In worktree mode, the API creates `.octogent/worktrees/<worktree-id>/` on branch `octogent/<worktree-id>` and starts the PTY there. The agent-facing context still stays in `.octogent/tentacles/<tentacle-id>/`.
53
+
37
54
## What belongs in files
38
55
39
56
The durable source of truth should live in files inside the tentacle.
@@ -46,28 +63,34 @@ That includes:
46
63
47
64
If another agent needs to understand the job later, the important information should already be there without depending on one old chat thread.
48
65
66
+
Deck reads these files directly. It parses the first heading and first non-empty paragraph of `CONTEXT.md` for display metadata, lists other markdown files as vault files, and parses checkbox lines in `todo.md` for progress and worker assignments.
67
+
49
68
## What belongs in runtime state
50
69
51
70
The runtime owns:
52
71
53
-
- live terminal sessions
72
+
- terminal records and lifecycle state
73
+
- live PTY sessions
54
74
- websocket transport
55
75
- UI state
56
76
- transcripts
57
77
- message delivery state
58
78
59
-
That data helps the app run, but it is not the same thing as the durable job context.
79
+
That data helps the app run, but it is not the same thing as the durable job context. Terminal records survive API restarts. PTY sessions, WebSocket clients, and channel queues do not.
80
+
81
+
On startup, Octogent reloads terminal records from `tentacles.json`. If a record says it was running, Octogent cannot reattach to the old in-memory PTY, so the record is reconciled to `stale` with a lifecycle reason.
60
82
61
83
## How delegation is supposed to work
62
84
63
85
The expected flow is:
64
86
65
87
1. the developer or a parent agent defines a job boundary
66
88
2. the tentacle files capture the local context
67
-
3.`todo.md` breaks the job into executable items
68
-
4. one or more child terminals take those items
69
-
5. workers report status through files and short messages
70
-
6. the parent or human reviews the result
89
+
3.`todo.md` breaks the job into executable checkbox items
90
+
4. Deck or the CLI creates terminals from those items
91
+
5. each worker receives a prompt generated from the tentacle context path, todo text, workspace mode, and parent terminal ID when present
92
+
6. workers report status through short channel messages and by leaving durable notes in files
93
+
7. the parent or human reviews the result and updates `todo.md`
71
94
72
95
If the boundary is vague, the orchestration gets worse. Octogent helps organize work, but it does not rescue a poorly defined job.
-`WS /api/terminals/:terminalId/ws` attaches a browser terminal to one PTY session
36
+
-`WS /api/terminal-events/ws` broadcasts terminal-created, terminal-updated, terminal-deleted, and state-change events
37
+
- file-backed state is the restart boundary for terminal records, UI state, transcripts, deck metadata, and monitor/cache data
38
+
39
+
Terminal WebSockets do not own the PTY. They are clients attached to a PTY session owned by the API process. When a browser reloads, a new WebSocket can receive scrollback during the idle grace window. When the API restarts, the PTY is gone.
34
40
35
41
## Security defaults
36
42
@@ -46,6 +52,39 @@ flowchart TD
46
52
- PTY sessions do not survive API restarts
47
53
- terminal records persisted as `running` are reconciled to `stale` on startup when no live Octogent session owns them
48
54
55
+
The terminal registry is `tentacles.json` for historical reasons. Current records are terminals, not tentacles. A terminal record stores identity, tentacle ID, optional worktree ID, parent terminal ID, workspace mode, display name, lifecycle fields, and UI-related metadata.
56
+
57
+
Deck metadata is separate from tentacle markdown. `deck.json` stores display/status details that should not be mixed into `CONTEXT.md` or `todo.md`.
58
+
59
+
## Terminal lifecycle
60
+
61
+
Creating a terminal writes a registry record first. If an initial prompt is provided, the runtime immediately starts a PTY session. Otherwise, the PTY starts when a WebSocket or direct listener attaches.
62
+
63
+
When a PTY starts, Octogent:
64
+
65
+
1. resolves the working directory from the terminal workspace mode
66
+
2. spawns the user's shell through `node-pty`
67
+
3. injects the configured agent bootstrap command
68
+
4. optionally pastes and submits an initial prompt
69
+
5. writes transcript events and keeps bounded scrollback in memory
70
+
6. broadcasts state updates to attached clients
71
+
72
+
Stopping or killing a terminal tears down the active PTY and updates lifecycle metadata. Deleting a terminal also cascades to child terminals and removes worktrees for worktree-backed records.
73
+
74
+
## Hook mechanism
75
+
76
+
For Claude-backed terminals, Octogent writes hooks into the target `.claude/settings.json`. The hooks call back into the local API and provide state transitions that terminal output alone cannot reliably express.
77
+
78
+
Hooks currently feed these mechanisms:
79
+
80
+
-`UserPromptSubmit` marks the terminal active and can auto-name generated terminals from the first prompt
81
+
-`PreToolUse` records the current tool and marks user-question waits
82
+
-`Notification` marks permission waits and idle prompts
83
+
-`Stop` parses Claude transcript data into stored conversations and releases the idle keep-alive
84
+
-`PostToolUse` for `Edit|Write` feeds code-intel events
85
+
86
+
Channel delivery is also tied to hooks. Messages are queued in memory and injected when a target session is idle, including after idle or stop hook events.
Copy file name to clipboardExpand all lines: docs/concepts/tentacles.md
+34-3Lines changed: 34 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,7 @@
2
2
3
3
Tentacles are the core abstraction in Octogent.
4
4
5
-
## Definition
5
+
## What a tentacle is
6
6
7
7
A tentacle is a folder under `.octogent/tentacles/<tentacle-id>/` that stores agent-readable markdown files.
8
8
@@ -13,9 +13,23 @@ The minimum useful files are:
13
13
14
14
Additional markdown files are allowed and are surfaced as tentacle vault files in the app.
15
15
16
+
The important part is that the folder is agent-facing. It is the durable context that a terminal agent can read, edit, and hand off to another terminal.
17
+
18
+
## How Deck reads a tentacle
19
+
20
+
Deck does not maintain a separate database copy of the tentacle context. It scans `.octogent/tentacles/` and derives most of the view from files:
21
+
22
+
- a folder is considered a tentacle only when it contains `CONTEXT.md`
23
+
- the first `# Heading` in `CONTEXT.md` becomes the display name
24
+
- the first non-empty paragraph after that heading becomes the description
25
+
- every other `.md` file becomes a vault file, with `todo.md` sorted first
26
+
- checkbox lines in `todo.md` become progress and worker inputs
27
+
28
+
Deck-specific metadata such as color, status, octopus appearance, paths, and tags lives separately in runtime state. That keeps UI preferences out of the agent-facing markdown files.
29
+
16
30
## What a tentacle is for
17
31
18
-
Use a tentacle when you want a durable context layer for one slice of the codebase or one track of work.
32
+
Use a tentacle when one slice of the codebase or one track of work needs its own local operating context.
19
33
20
34
Examples:
21
35
@@ -36,7 +50,7 @@ Examples:
36
50
- what not to break
37
51
- any Claude Code skills that are especially useful for this tentacle, when relevant
38
52
39
-
The first heading and first non-empty paragraph are used by the runtime as the display name and description.
53
+
The first heading and first non-empty paragraph are runtime-significant. Keep them stable and useful because they become the name and description shown in Deck, Canvas, prompt summaries, and terminal creation flows.
40
54
41
55
When a tentacle has suggested Claude Code skills, Octogent appends a managed block at the bottom of `CONTEXT.md`:
42
56
@@ -50,6 +64,8 @@ You can use these skills if you need to.
50
64
<!-- octogent:suggested-skills:end -->
51
65
```
52
66
67
+
The managed block is rewritten by the API when suggested skills change. Put human-authored architecture notes outside that block.
68
+
53
69
## What goes in `todo.md`
54
70
55
71
`todo.md` should contain markdown checkbox items:
@@ -64,6 +80,10 @@ You can use these skills if you need to.
64
80
65
81
The runtime parses checkbox lines and computes progress.
66
82
83
+
Only lines that match `- [ ] text` or `- [x] text` are treated as todo items. Their order matters because swarm creation uses the parsed item index when it creates worker terminal IDs such as `<tentacle-id>-swarm-0`.
84
+
85
+
When the UI toggles, edits, adds, or deletes todos, it rewrites `todo.md`. There is no hidden todo store.
86
+
67
87
## Tentacles and delegation
68
88
69
89
The point of a tentacle is not only documentation. It is operational context.
@@ -75,6 +95,8 @@ A worker attached to a tentacle can:
75
95
- use the todo list as a work queue
76
96
- hand work to child agents without rebuilding context from scratch
77
97
98
+
When a todo item is solved from Deck, Octogent reads the item text, resolves a worker prompt template, and creates a terminal attached to the same tentacle. For swarm runs, incomplete todo items become workers, and larger swarms get a parent coordinator terminal that supervises completion.
99
+
78
100
## Tentacles and worktrees
79
101
80
102
Tentacles are not the same thing as worktrees.
@@ -83,3 +105,12 @@ Tentacles are not the same thing as worktrees.
83
105
- a worktree is an isolated git checkout for a terminal
84
106
85
107
You can use a tentacle with shared workspace terminals or worktree terminals.
108
+
109
+
In shared mode, all terminals operate in the main workspace, so the context boundary is social and procedural. In worktree mode, each terminal can get a separate checkout under `.octogent/worktrees/`, but it still reads the same tentacle folder for instructions and todos.
110
+
111
+
## Failure boundaries
112
+
113
+
- deleting a tentacle removes its agent-facing files, but terminal records are separate runtime state
114
+
- restarting the API preserves terminal metadata and transcripts but not live PTYs
115
+
- channel messages do not persist, so durable handoffs belong in tentacle markdown
116
+
- worktree branches are tied to worktree-backed terminals, not to the tentacle folder itself
Copy file name to clipboardExpand all lines: docs/guides/inter-agent-messaging.md
+31-2Lines changed: 31 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,9 +2,11 @@
2
2
3
3
Octogent has a simple local channel system for messages between terminals.
4
4
5
-
## What it is for
5
+
## What channels are
6
6
7
-
Use channel messages for short coordination:
7
+
Channels are in-memory queues keyed by target terminal ID. Sending a message does not write to the target tentacle files and does not create a persistent notification record.
8
+
9
+
Use them for short coordination:
8
10
9
11
- ask for review
10
12
- report completion
@@ -13,6 +15,23 @@ Use channel messages for short coordination:
13
15
14
16
It is not a replacement for proper context files.
15
17
18
+
## Delivery model
19
+
20
+
When a message is sent, Octogent:
21
+
22
+
1. verifies the target terminal record exists
23
+
2. appends the message to that terminal's in-memory queue
24
+
3. marks it as undelivered
25
+
4. injects pending messages into the target PTY when the target session is idle
26
+
27
+
Delivered messages are written into the terminal input as lines like:
28
+
29
+
```text
30
+
[Channel message from <from-terminal-id>]: <content>
31
+
```
32
+
33
+
If the target terminal is not running, the message waits in memory until that session exists and becomes idle. If the API restarts first, the message is lost.
34
+
16
35
## CLI usage
17
36
18
37
Send a message:
@@ -21,6 +40,14 @@ Send a message:
21
40
octogent channel send <terminal-id>"Need review on the parser change"
22
41
```
23
42
43
+
When one terminal is messaging another, pass the sender explicitly:
44
+
45
+
```bash
46
+
octogent channel send <target-terminal-id>"DONE: parser change is ready" --from <sender-terminal-id>
47
+
```
48
+
49
+
If `--from` is omitted, the CLI uses `OCTOGENT_SESSION_ID` when it is available.
50
+
24
51
List messages:
25
52
26
53
```bash
@@ -37,6 +64,8 @@ octogent channel list <terminal-id>
37
64
- messages are stored in memory
38
65
- messages do not persist across API restarts
39
66
- delivery state is tracked by the API
67
+
- idle and stop hook events can trigger delivery
68
+
- listing messages shows queued and delivered messages for the current API process
0 commit comments