collossal 0.1.0__tar.gz

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.
@@ -0,0 +1,218 @@
1
+ Metadata-Version: 2.3
2
+ Name: collossal
3
+ Version: 0.1.0
4
+ Summary: Collossal CLI: connects your coding agent to your team's sessions, memory and rooms.
5
+ Author: Vipul
6
+ Author-email: Vipul <vilulgupta2802@gmail.com>
7
+ Requires-Dist: mcp[cli]>=2.2.0
8
+ Requires-Dist: httpx2>=2.12.0
9
+ Requires-Dist: websockets>=13.0
10
+ Requires-Python: >=3.14
11
+ Description-Content-Type: text/markdown
12
+
13
+ # Collossal MCP
14
+
15
+ Shared memory for coding agents. Runs on a developer's machine and talks to the
16
+ Collossal API over HTTPS — it holds an API key and never database credentials.
17
+
18
+ ## Setup
19
+
20
+ One command per machine — the dashboard's Setup page shows it with your
21
+ addresses filled in:
22
+
23
+ ```bash
24
+ curl -fsSL https://<your-collossal>/install.sh | sh -s -- --api-url https://<your-collossal>/api/v1
25
+ ```
26
+
27
+ That installs the `collossal` command (with uv, which brings its own Python) and
28
+ runs `collossal install`, which:
29
+
30
+ 1. **Signs the machine in through the browser.** It shows a code and opens the
31
+ dashboard; you check the code and approve. The machine receives an API key
32
+ of your own — nothing to copy — saved to `~/.collossal/config.json` (0600).
33
+ 2. **Sets up Claude Code for every project:** the hooks below go into
34
+ `~/.claude/settings.json` (your other settings are kept, and the original is
35
+ backed up once), and the MCP server is registered with
36
+ `claude mcp add --scope user`.
37
+ 3. **Uploads your past sessions** from `~/.claude/projects` — every one,
38
+ whatever it ran in — with their real timestamps, titles and redaction, so
39
+ your history appears on the dashboard, not just what happens from now on.
40
+
41
+ From then on every Claude Code session on the machine streams to your team's
42
+ Sessions tab as it happens, and every teammate can open it. Nothing has to be
43
+ connected first: a session is labelled by the repository it ran in (or, begun
44
+ in a folder holding several, the one it works in most), or by its folder. A
45
+ repository connected to a project additionally gets memory — decisions
46
+ anchored to its files.
47
+
48
+ Each person chooses which of their sessions the team sees, under **Sessions →
49
+ Configure**: all of them (the default), or only those in the repositories and
50
+ folders they pick. The choice applies at once to past sessions as well as new
51
+ ones. A session outside it is still recorded, and its owner still sees it under
52
+ My sessions — nobody else does: not teammates, not workspace admins, not an
53
+ agent's `team_sessions` or a handoff. Setting it before running the installer
54
+ keeps the upload of past sessions within it from the start.
55
+
56
+ Until the CLI is published, install it from this checkout instead:
57
+
58
+ ```bash
59
+ uv tool install --editable /path/to/main-mcp && collossal install --api-url http://localhost:3000/api/v1
60
+ ```
61
+
62
+ | Command | Does |
63
+ |---|---|
64
+ | `collossal install` | All of the above; safe to run again |
65
+ | `collossal import` | Upload past sessions again — e.g. after connecting another repo |
66
+ | `collossal status` | Who this machine is signed in as, and what is set up |
67
+ | `collossal doctor` | The same, plus what is wrong and how to fix it |
68
+ | `collossal login` | Sign in again without changing anything else |
69
+ | `collossal uninstall` | Remove the hooks, the MCP server and the sign-in |
70
+
71
+ `COLLOSSAL_API_KEY` and `COLLOSSAL_API_URL` still work and take precedence over
72
+ the saved sign-in — for CI, or to pin one project to a different workspace.
73
+
74
+ ## Tools
75
+
76
+ **`memory_write`** — records a decision and anchors it to the files it governs.
77
+
78
+ **`memory_search`** — natural-language search across the project. Results can
79
+ come from a *different repository* than the one being edited; that is the point.
80
+
81
+ **`memory_for_files`** — decisions attached to specific files. Needs no query,
82
+ so it surfaces context an agent would not have known to search for. Anchors
83
+ belong to a repo, so this looks within the current one; `memory_search` is the
84
+ cross-repo path.
85
+
86
+ **`team_sessions`** — teammates' recent agent sessions, to inherit from. Lists
87
+ the whole workspace's, whatever repository or folder they ran in; excludes your
88
+ own and any a teammate keeps private, and omits sessions that recorded nothing
89
+ — an empty run is noise in a list an agent acts on.
90
+
91
+ **`session_handoff`** — takes a teammate's session over: where the work is, the
92
+ end of their conversation, and the decisions already anchored to the files
93
+ involved, written for the receiving agent to read on its first turn. Accepts a
94
+ session id or a pasted dashboard link. No agent will adopt a foreign session id,
95
+ so what transfers is the context, not the process.
96
+
97
+ The agent supplies the claim, rationale, and files. Everything identifying —
98
+ repo, branch, commit, project — is read from the git checkout, because asking an
99
+ agent for a project id invites it to guess.
100
+
101
+ File paths are normalised to repo-relative before storage: an absolute path
102
+ would anchor the memory to one machine's directory layout and never match for a
103
+ teammate.
104
+
105
+ A decision replaced by a newer one is still returned, labelled `[SUPERSEDED]`
106
+ with the claim that replaced it, stated *before* its rationale — an agent must
107
+ not be able to read stale reasoning without first seeing that it no longer
108
+ holds.
109
+
110
+ ## Automatic capture
111
+
112
+ Two hooks, because the transcript on disk already holds every tool call and
113
+ message — there is nothing to gain from hooking each tool.
114
+
115
+ | Hook | Does |
116
+ |---|---|
117
+ | `SessionStart` | Injects this project's decisions into the new session, and starts streaming it to the dashboard |
118
+ | `Stop` | Captures what the turn taught, and delivers any instruction a teammate sent |
119
+ | `SessionEnd` | Ships the rest of the transcript, and uploads the whole session if it was never streamed — one that began before Collossal was installed |
120
+
121
+ `collossal install` puts them in `~/.claude/settings.json` for every project. To
122
+ set them up by hand instead, merge `hooks.example.json` there, or into one
123
+ project's `.claude/settings.json` to scope them to that repo — but not both, or
124
+ that project's sessions are streamed twice.
125
+
126
+ ### How a session becomes memory
127
+
128
+ The worker reads from the last cursor, then looks for four mechanically
129
+ detectable moments — nothing here calls a model:
130
+
131
+ - **`FAILURE_FIX`** — a command failed, edits followed, the same command passed.
132
+ Matched on command *shape* rather than exact text, because an agent re-runs
133
+ the same tool against a different file rather than retyping the failure.
134
+ - **`REVERSAL`** — one file rewritten six or more times, with the reasoning
135
+ stated nearest the final edit. Fewer than six is ordinary iteration.
136
+ - **`USER_CORRECTION`** — the user pushed back right after an assistant action.
137
+ - **`STATED_CONSTRAINT`** — the user stated a rule.
138
+
139
+ A session reaching none of these is dropped having cost one file read. Measured
140
+ across 78 real transcripts (296 MB), that gate discards 39% for free and the
141
+ rest yield about 6 windows each.
142
+
143
+ Windows are stored separately from decisions, so the store of durable claims
144
+ never fills with unprocessed transcript fragments. A stub promotes `FAILURE_FIX`
145
+ windows to decisions at confidence 0.4; injection ignores anything below 0.5, so
146
+ raw machine guesses never reach an agent's context before distillation exists.
147
+
148
+ ### Redaction
149
+
150
+ Credentials are stripped in the worker, immediately before the push — not on
151
+ the server, because scanning there would still mean the secret crossed the
152
+ network and landed in a request log.
153
+
154
+ Three layers: known vendor formats (Anthropic, OpenAI, GitHub, AWS, Slack,
155
+ Google, Stripe, JWTs, private keys, connection strings), assignments whose
156
+ *name* claims to hold a credential (`API_KEY=`, `SECRET=`), and a Shannon
157
+ entropy fallback for credentials with no recognisable shape.
158
+
159
+ The trade is deliberately asymmetric: a false positive costs a slightly less
160
+ readable memory, a false negative puts a live credential in a database forever.
161
+
162
+ Measured against 564 fields from real transcripts: **zero false positives**,
163
+ and zero secrets missed across a suite of 15 credential formats. Absolute paths
164
+ are rewritten repo-relative in the same pass, so memory does not carry one
165
+ machine's directory layout to everyone else.
166
+
167
+ ### Safety properties
168
+
169
+ The hook always exits 0 and swallows every error to `~/.collossal/hook.log`. It
170
+ cannot fail a session, and with the API unreachable a session starts normally
171
+ with no memory rather than an error.
172
+
173
+ ## Live sessions
174
+
175
+ A workspace admin can watch a session as it happens and step into it.
176
+
177
+ | Piece | Does |
178
+ |---|---|
179
+ | `tailer.py` | Spawned at SessionStart, detached. Follows the transcript, redacts, and pushes render-ready events plus snapshots of uncommitted work — `git diff`, and files not yet added — which a session's Changes tab and the workspace owner's Code diff view show. An empty snapshot means the tree is clean again. |
180
+ | `Stop` hook | Collects instructions queued from the dashboard and hands them to the agent as its next input. |
181
+
182
+ Two properties worth knowing.
183
+
184
+ **It tails, it does not replay.** The tailer starts from the current end of the
185
+ transcript. A hook firing on a resumed session would otherwise push its entire
186
+ history — megabytes — as though it had all just happened.
187
+
188
+ **Instructions arrive at a turn boundary, not instantly.** There is no way to
189
+ interrupt a turn already running, so anything sent is queued and delivered the
190
+ moment the agent would otherwise have stopped. Delivered exactly once: a
191
+ repeated instruction would have the agent redo work.
192
+
193
+ Everything streamed is redacted on the machine first, and absolute paths are
194
+ rewritten repo-relative — a watcher sees the repository, not someone's home
195
+ directory. Events are kept for `SESSION_RETENTION_DAYS` (90 days by default),
196
+ so a session can be read back after it ends; the durable record of a session
197
+ remains the decisions distilled from it.
198
+
199
+ Sending an instruction also writes a `NOTICE` into the stream the watched
200
+ person can see. Being observed and redirected with no indication of it is not
201
+ something to ship.
202
+
203
+ ## Layout
204
+
205
+ ```
206
+ config.py env, validated once at startup
207
+ git_context.py repo/branch/commit discovery and path normalisation
208
+ client.py Collossal API client
209
+ format.py renders decisions for a context window
210
+ server.py MCPServer and the tools
211
+ capture/
212
+ hook.py lifecycle hook: injection, and spawning the worker
213
+ worker.py detached — reads transcript, gates, ships
214
+ transcript.py streaming JSONL reader
215
+ windows.py the four detectors
216
+ redact.py strips credentials before anything leaves the machine
217
+ ship.py API calls for capture and injection
218
+ ```
@@ -0,0 +1,206 @@
1
+ # Collossal MCP
2
+
3
+ Shared memory for coding agents. Runs on a developer's machine and talks to the
4
+ Collossal API over HTTPS — it holds an API key and never database credentials.
5
+
6
+ ## Setup
7
+
8
+ One command per machine — the dashboard's Setup page shows it with your
9
+ addresses filled in:
10
+
11
+ ```bash
12
+ curl -fsSL https://<your-collossal>/install.sh | sh -s -- --api-url https://<your-collossal>/api/v1
13
+ ```
14
+
15
+ That installs the `collossal` command (with uv, which brings its own Python) and
16
+ runs `collossal install`, which:
17
+
18
+ 1. **Signs the machine in through the browser.** It shows a code and opens the
19
+ dashboard; you check the code and approve. The machine receives an API key
20
+ of your own — nothing to copy — saved to `~/.collossal/config.json` (0600).
21
+ 2. **Sets up Claude Code for every project:** the hooks below go into
22
+ `~/.claude/settings.json` (your other settings are kept, and the original is
23
+ backed up once), and the MCP server is registered with
24
+ `claude mcp add --scope user`.
25
+ 3. **Uploads your past sessions** from `~/.claude/projects` — every one,
26
+ whatever it ran in — with their real timestamps, titles and redaction, so
27
+ your history appears on the dashboard, not just what happens from now on.
28
+
29
+ From then on every Claude Code session on the machine streams to your team's
30
+ Sessions tab as it happens, and every teammate can open it. Nothing has to be
31
+ connected first: a session is labelled by the repository it ran in (or, begun
32
+ in a folder holding several, the one it works in most), or by its folder. A
33
+ repository connected to a project additionally gets memory — decisions
34
+ anchored to its files.
35
+
36
+ Each person chooses which of their sessions the team sees, under **Sessions →
37
+ Configure**: all of them (the default), or only those in the repositories and
38
+ folders they pick. The choice applies at once to past sessions as well as new
39
+ ones. A session outside it is still recorded, and its owner still sees it under
40
+ My sessions — nobody else does: not teammates, not workspace admins, not an
41
+ agent's `team_sessions` or a handoff. Setting it before running the installer
42
+ keeps the upload of past sessions within it from the start.
43
+
44
+ Until the CLI is published, install it from this checkout instead:
45
+
46
+ ```bash
47
+ uv tool install --editable /path/to/main-mcp && collossal install --api-url http://localhost:3000/api/v1
48
+ ```
49
+
50
+ | Command | Does |
51
+ |---|---|
52
+ | `collossal install` | All of the above; safe to run again |
53
+ | `collossal import` | Upload past sessions again — e.g. after connecting another repo |
54
+ | `collossal status` | Who this machine is signed in as, and what is set up |
55
+ | `collossal doctor` | The same, plus what is wrong and how to fix it |
56
+ | `collossal login` | Sign in again without changing anything else |
57
+ | `collossal uninstall` | Remove the hooks, the MCP server and the sign-in |
58
+
59
+ `COLLOSSAL_API_KEY` and `COLLOSSAL_API_URL` still work and take precedence over
60
+ the saved sign-in — for CI, or to pin one project to a different workspace.
61
+
62
+ ## Tools
63
+
64
+ **`memory_write`** — records a decision and anchors it to the files it governs.
65
+
66
+ **`memory_search`** — natural-language search across the project. Results can
67
+ come from a *different repository* than the one being edited; that is the point.
68
+
69
+ **`memory_for_files`** — decisions attached to specific files. Needs no query,
70
+ so it surfaces context an agent would not have known to search for. Anchors
71
+ belong to a repo, so this looks within the current one; `memory_search` is the
72
+ cross-repo path.
73
+
74
+ **`team_sessions`** — teammates' recent agent sessions, to inherit from. Lists
75
+ the whole workspace's, whatever repository or folder they ran in; excludes your
76
+ own and any a teammate keeps private, and omits sessions that recorded nothing
77
+ — an empty run is noise in a list an agent acts on.
78
+
79
+ **`session_handoff`** — takes a teammate's session over: where the work is, the
80
+ end of their conversation, and the decisions already anchored to the files
81
+ involved, written for the receiving agent to read on its first turn. Accepts a
82
+ session id or a pasted dashboard link. No agent will adopt a foreign session id,
83
+ so what transfers is the context, not the process.
84
+
85
+ The agent supplies the claim, rationale, and files. Everything identifying —
86
+ repo, branch, commit, project — is read from the git checkout, because asking an
87
+ agent for a project id invites it to guess.
88
+
89
+ File paths are normalised to repo-relative before storage: an absolute path
90
+ would anchor the memory to one machine's directory layout and never match for a
91
+ teammate.
92
+
93
+ A decision replaced by a newer one is still returned, labelled `[SUPERSEDED]`
94
+ with the claim that replaced it, stated *before* its rationale — an agent must
95
+ not be able to read stale reasoning without first seeing that it no longer
96
+ holds.
97
+
98
+ ## Automatic capture
99
+
100
+ Two hooks, because the transcript on disk already holds every tool call and
101
+ message — there is nothing to gain from hooking each tool.
102
+
103
+ | Hook | Does |
104
+ |---|---|
105
+ | `SessionStart` | Injects this project's decisions into the new session, and starts streaming it to the dashboard |
106
+ | `Stop` | Captures what the turn taught, and delivers any instruction a teammate sent |
107
+ | `SessionEnd` | Ships the rest of the transcript, and uploads the whole session if it was never streamed — one that began before Collossal was installed |
108
+
109
+ `collossal install` puts them in `~/.claude/settings.json` for every project. To
110
+ set them up by hand instead, merge `hooks.example.json` there, or into one
111
+ project's `.claude/settings.json` to scope them to that repo — but not both, or
112
+ that project's sessions are streamed twice.
113
+
114
+ ### How a session becomes memory
115
+
116
+ The worker reads from the last cursor, then looks for four mechanically
117
+ detectable moments — nothing here calls a model:
118
+
119
+ - **`FAILURE_FIX`** — a command failed, edits followed, the same command passed.
120
+ Matched on command *shape* rather than exact text, because an agent re-runs
121
+ the same tool against a different file rather than retyping the failure.
122
+ - **`REVERSAL`** — one file rewritten six or more times, with the reasoning
123
+ stated nearest the final edit. Fewer than six is ordinary iteration.
124
+ - **`USER_CORRECTION`** — the user pushed back right after an assistant action.
125
+ - **`STATED_CONSTRAINT`** — the user stated a rule.
126
+
127
+ A session reaching none of these is dropped having cost one file read. Measured
128
+ across 78 real transcripts (296 MB), that gate discards 39% for free and the
129
+ rest yield about 6 windows each.
130
+
131
+ Windows are stored separately from decisions, so the store of durable claims
132
+ never fills with unprocessed transcript fragments. A stub promotes `FAILURE_FIX`
133
+ windows to decisions at confidence 0.4; injection ignores anything below 0.5, so
134
+ raw machine guesses never reach an agent's context before distillation exists.
135
+
136
+ ### Redaction
137
+
138
+ Credentials are stripped in the worker, immediately before the push — not on
139
+ the server, because scanning there would still mean the secret crossed the
140
+ network and landed in a request log.
141
+
142
+ Three layers: known vendor formats (Anthropic, OpenAI, GitHub, AWS, Slack,
143
+ Google, Stripe, JWTs, private keys, connection strings), assignments whose
144
+ *name* claims to hold a credential (`API_KEY=`, `SECRET=`), and a Shannon
145
+ entropy fallback for credentials with no recognisable shape.
146
+
147
+ The trade is deliberately asymmetric: a false positive costs a slightly less
148
+ readable memory, a false negative puts a live credential in a database forever.
149
+
150
+ Measured against 564 fields from real transcripts: **zero false positives**,
151
+ and zero secrets missed across a suite of 15 credential formats. Absolute paths
152
+ are rewritten repo-relative in the same pass, so memory does not carry one
153
+ machine's directory layout to everyone else.
154
+
155
+ ### Safety properties
156
+
157
+ The hook always exits 0 and swallows every error to `~/.collossal/hook.log`. It
158
+ cannot fail a session, and with the API unreachable a session starts normally
159
+ with no memory rather than an error.
160
+
161
+ ## Live sessions
162
+
163
+ A workspace admin can watch a session as it happens and step into it.
164
+
165
+ | Piece | Does |
166
+ |---|---|
167
+ | `tailer.py` | Spawned at SessionStart, detached. Follows the transcript, redacts, and pushes render-ready events plus snapshots of uncommitted work — `git diff`, and files not yet added — which a session's Changes tab and the workspace owner's Code diff view show. An empty snapshot means the tree is clean again. |
168
+ | `Stop` hook | Collects instructions queued from the dashboard and hands them to the agent as its next input. |
169
+
170
+ Two properties worth knowing.
171
+
172
+ **It tails, it does not replay.** The tailer starts from the current end of the
173
+ transcript. A hook firing on a resumed session would otherwise push its entire
174
+ history — megabytes — as though it had all just happened.
175
+
176
+ **Instructions arrive at a turn boundary, not instantly.** There is no way to
177
+ interrupt a turn already running, so anything sent is queued and delivered the
178
+ moment the agent would otherwise have stopped. Delivered exactly once: a
179
+ repeated instruction would have the agent redo work.
180
+
181
+ Everything streamed is redacted on the machine first, and absolute paths are
182
+ rewritten repo-relative — a watcher sees the repository, not someone's home
183
+ directory. Events are kept for `SESSION_RETENTION_DAYS` (90 days by default),
184
+ so a session can be read back after it ends; the durable record of a session
185
+ remains the decisions distilled from it.
186
+
187
+ Sending an instruction also writes a `NOTICE` into the stream the watched
188
+ person can see. Being observed and redirected with no indication of it is not
189
+ something to ship.
190
+
191
+ ## Layout
192
+
193
+ ```
194
+ config.py env, validated once at startup
195
+ git_context.py repo/branch/commit discovery and path normalisation
196
+ client.py Collossal API client
197
+ format.py renders decisions for a context window
198
+ server.py MCPServer and the tools
199
+ capture/
200
+ hook.py lifecycle hook: injection, and spawning the worker
201
+ worker.py detached — reads transcript, gates, ships
202
+ transcript.py streaming JSONL reader
203
+ windows.py the four detectors
204
+ redact.py strips credentials before anything leaves the machine
205
+ ship.py API calls for capture and injection
206
+ ```
@@ -0,0 +1,27 @@
1
+ [project]
2
+ name = "collossal"
3
+ version = "0.1.0"
4
+ description = "Collossal CLI: connects your coding agent to your team's sessions, memory and rooms."
5
+ readme = "README.md"
6
+ requires-python = ">=3.14"
7
+ dependencies = [
8
+ "mcp[cli]>=2.2.0",
9
+ "httpx2>=2.12.0",
10
+ "websockets>=13.0",
11
+ ]
12
+
13
+ [[project.authors]]
14
+ name = "Vipul"
15
+ email = "vilulgupta2802@gmail.com"
16
+
17
+ [project.scripts]
18
+ collossal = "main_mcp.cli:main"
19
+ collossal-mcp = "main_mcp.server:main"
20
+ collossal-hook = "main_mcp.capture.hook:main"
21
+
22
+ [build-system]
23
+ requires = ["uv_build>=0.12.12,<0.13.0"]
24
+ build-backend = "uv_build"
25
+
26
+ [tool.uv.build-backend]
27
+ module-name = "main_mcp"
@@ -0,0 +1,31 @@
1
+ [project]
2
+ name = "collossal"
3
+ version = "0.1.0"
4
+ description = "Collossal CLI: connects your coding agent to your team's sessions, memory and rooms."
5
+ readme = "README.md"
6
+ authors = [
7
+ { name = "Vipul", email = "vilulgupta2802@gmail.com" }
8
+ ]
9
+ requires-python = ">=3.14"
10
+ dependencies = [
11
+ "mcp[cli]>=2.2.0",
12
+ # Used directly by the API client. It arrives transitively via mcp, but a
13
+ # direct import needs a direct declaration.
14
+ "httpx2>=2.12.0",
15
+ # `collossal room` streams its terminal to the room and takes keystrokes
16
+ # back; polling would make every keypress a round trip of a second or more.
17
+ "websockets>=13.0",
18
+ ]
19
+
20
+ [project.scripts]
21
+ collossal = "main_mcp.cli:main"
22
+ collossal-mcp = "main_mcp.server:main"
23
+ collossal-hook = "main_mcp.capture.hook:main"
24
+
25
+ [build-system]
26
+ requires = ["uv_build>=0.12.12,<0.13.0"]
27
+ build-backend = "uv_build"
28
+
29
+ [tool.uv.build-backend]
30
+ # The package is published as `collossal`; its code lives in `main_mcp`.
31
+ module-name = "main_mcp"
@@ -0,0 +1,16 @@
1
+ """Collossal MCP server."""
2
+
3
+
4
+ def main() -> None:
5
+ """Entry point.
6
+
7
+ The import is deferred so that `python -m main_mcp.server` does not load the
8
+ server module twice — which would run its startup config load and client
9
+ construction a second time.
10
+ """
11
+ from .server import main as run
12
+
13
+ run()
14
+
15
+
16
+ __all__ = ["main"]