diff --git a/.changeset/colony-package-namespace.md b/.changeset/colony-package-namespace.md
new file mode 100644
index 0000000..d6cfa44
--- /dev/null
+++ b/.changeset/colony-package-namespace.md
@@ -0,0 +1,12 @@
+---
+"colony": patch
+"@colony/compress": patch
+"@colony/config": patch
+"@colony/core": patch
+"@colony/embedding": patch
+"@colony/hooks": patch
+"@colony/installers": patch
+"@colony/storage": patch
+---
+
+Rename the public CLI package and workspace package/import namespace from cavemem to Colony. The CLI binary is now `colony`, workspace imports use `@colony/*`, release scripts pack `colony`, and installed hook scripts call `colony`.
diff --git a/.changeset/colony-session-cwd-binding.md b/.changeset/colony-session-cwd-binding.md
index 0482952..151a066 100644
--- a/.changeset/colony-session-cwd-binding.md
+++ b/.changeset/colony-session-cwd-binding.md
@@ -1,7 +1,7 @@
---
-"@cavemem/hooks": patch
-"@cavemem/storage": patch
-"cavemem": patch
+"@colony/hooks": patch
+"@colony/storage": patch
+"colony": patch
---
Bind hook-created sessions back to their repository cwd so colony views can see live Codex/Claude work instead of orphan `cwd: null` sessions.
diff --git a/.changeset/config.json b/.changeset/config.json
index 18792b6..5c0b1b1 100644
--- a/.changeset/config.json
+++ b/.changeset/config.json
@@ -3,7 +3,7 @@
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [],
- "linked": [["@cavemem/*", "cavemem"]],
+ "linked": [["@colony/*", "colony"]],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
diff --git a/.changeset/hivemind-mcp-tool.md b/.changeset/hivemind-mcp-tool.md
index 6777ae3..db86d31 100644
--- a/.changeset/hivemind-mcp-tool.md
+++ b/.changeset/hivemind-mcp-tool.md
@@ -1,5 +1,5 @@
---
-"@cavemem/mcp-server": minor
+"@colony/mcp-server": minor
---
Add a compact `hivemind` MCP tool that maps active proxy-runtime agent sessions to their current tasks.
diff --git a/.changeset/pheromone-trails.md b/.changeset/pheromone-trails.md
index bbd90b3..9f70c2a 100644
--- a/.changeset/pheromone-trails.md
+++ b/.changeset/pheromone-trails.md
@@ -1,7 +1,7 @@
---
-'@cavemem/storage': minor
-'@cavemem/core': minor
-'@cavemem/hooks': minor
+'@colony/storage': minor
+'@colony/core': minor
+'@colony/hooks': minor
---
Add pheromone trails: ambient decaying activity signal per (task, file, session). `PostToolUse` deposits pheromone on every write-tool invocation; strength decays exponentially (10-minute half-life, cap 10.0). The new `UserPromptSubmit` preface warns when another session has a strong trail on a file the current session has also touched, complementing the existing claim-based preface with a graded intensity signal that doesn't fire for stale collisions. Schema bumped to version 4 — adds `pheromones` table with FK cascade on sessions and tasks.
diff --git a/.changeset/proposal-system.md b/.changeset/proposal-system.md
index 60a2312..eaf38dc 100644
--- a/.changeset/proposal-system.md
+++ b/.changeset/proposal-system.md
@@ -1,8 +1,8 @@
---
-'@cavemem/storage': minor
-'@cavemem/core': minor
-'@cavemem/hooks': minor
-'@cavemem/mcp-server': minor
+'@colony/storage': minor
+'@colony/core': minor
+'@colony/hooks': minor
+'@colony/mcp-server': minor
---
Add proposal system: pre-tasks that auto-promote via collective reinforcement. Agents call `task_propose` to surface a candidate improvement; other agents call `task_reinforce` (kind `explicit` or `rediscovered`), and PostToolUse adds weak `adjacent` reinforcement whenever an edit touches a file listed in a pending proposal's `touches_files`. Total decayed strength (1-hour half-life, weights 1.0 / 0.7 / 0.3 by kind) is recomputed on every read; when it crosses `PROMOTION_THRESHOLD` (2.5), the proposal is auto-promoted to a real `TaskThread` on a synthetic branch `{branch}/proposal-{id}`. The new `task_foraging_report` MCP tool lists pending (above the 0.3 noise floor) and promoted proposals; `SessionStart` surfaces the same report in-preface. Schema bumped 4 → 5: adds `proposals` and `proposal_reinforcements`.
diff --git a/.changeset/response-thresholds.md b/.changeset/response-thresholds.md
index 4b6ebc9..788d063 100644
--- a/.changeset/response-thresholds.md
+++ b/.changeset/response-thresholds.md
@@ -1,8 +1,8 @@
---
-'@cavemem/storage': minor
-'@cavemem/core': minor
-'@cavemem/hooks': minor
-'@cavemem/mcp-server': minor
+'@colony/storage': minor
+'@colony/core': minor
+'@colony/hooks': minor
+'@colony/mcp-server': minor
---
Add response-threshold routing for broadcast (`to_agent: 'any'`) handoffs. Each agent identity (Claude, Codex, …) can register a capability profile (`ui_work`, `api_work`, `test_work`, `infra_work`, `doc_work`, each `0..1`) via the new `agent_upsert_profile` MCP tool; unknown agents default to `0.5` across all dimensions. When `TaskThread.handOff` runs with `to_agent: 'any'`, it snapshots a keyword-weighted ranking of every non-sender participant into `HandoffMetadata.suggested_candidates`. `SessionStart` preface surfaces the top match and the viewing agent's own score inline with each pending broadcast handoff, so receivers can see at a glance whether they are the best fit. New `agent_get_profile` MCP tool exposes read-only inspection. Schema bumped 5 → 6: adds `agent_profiles` table.
diff --git a/CLAUDE.md b/CLAUDE.md
index 2838f7a..c6d9cbb 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -1,18 +1,18 @@
-# cavemem — Agent Playbook
+# colony — Agent Playbook
This file is the source of truth for AI coding assistants working on this repository. Follow it before generating code, tests, or documentation. If a request conflicts with this file, pause and ask.
## Project identity
-cavemem is a cross-agent persistent memory system for coding assistants. It captures observations from editor sessions, compresses prose using the project's deterministic caveman grammar, stores entries in a local SQLite + vector index, and exposes them to agents through a Model Context Protocol (MCP) server and a local web viewer.
+colony is a cross-agent persistent memory system for coding assistants. It captures observations from editor sessions, compresses prose using the project's deterministic caveman grammar, stores entries in a local SQLite + vector index, and exposes them to agents through a Model Context Protocol (MCP) server and a local web viewer.
-The signature property of the project is that **memory is stored compressed**. Every write path runs text through `@cavemem/compress`. Every human-facing read path runs it back through `@cavemem/compress#expand`. Model-facing reads may keep content compressed when the caller requests it.
+The signature property of the project is that **memory is stored compressed**. Every write path runs text through `@colony/compress`. Every human-facing read path runs it back through `@colony/compress#expand`. Model-facing reads may keep content compressed when the caller requests it.
## Non-negotiable rules
1. **All persisted prose must pass through `packages/compress` before hitting storage.** Writing raw prose to SQLite is a defect. If you add a new write path, it must use `MemoryStore`, which enforces this.
2. **Never compress technical tokens.** Code blocks, inline code, URLs, file paths, shell commands, version numbers, dates, numeric literals, and quoted identifiers are preserved byte-for-byte. The tokenizer in `packages/compress/src/tokenize.ts` is the single authority.
-3. **Round-trip tests must pass.** Any change to the compressor, the lexicon, or the tokenizer requires `pnpm --filter @cavemem/compress test` green, including the technical-token preservation suite.
+3. **Round-trip tests must pass.** Any change to the compressor, the lexicon, or the tokenizer requires `pnpm --filter @colony/compress test` green, including the technical-token preservation suite.
4. **Progressive disclosure in MCP.** `search` and `timeline` return compact results (IDs + snippets). Full observation bodies are only returned by `get_observations(ids[])`. Do not bloat the compact shapes.
5. **Hot-path hooks are fast.** Hook handlers in `packages/hooks` must complete under 150 ms p95. Summarization, embedding, and indexing are handed off to the worker. No network calls in hooks.
6. **Privacy is enforced at the write boundary.** Content inside `… ` tags is stripped. Paths matching `settings.excludePatterns` are never read. Neither appears in logs.
@@ -23,8 +23,8 @@ The signature property of the project is that **memory is stored compressed**. E
## Architectural rules
- Monorepo with pnpm workspaces. Dependency direction is strictly downward: `apps/*` may depend on `packages/*`; `packages/*` may depend on each other only in the order `config → compress → storage → { core, embedding } → hooks → installers`. (`core` and `embedding` are siblings — both consume `config` and `storage`, neither depends on the other.) No upward or sideways imports that break this order.
-- All database I/O goes through `@cavemem/storage`. No other package opens the DB directly.
-- Settings access goes through `@cavemem/config`. No direct reads from `~/.cavemem/settings.json` elsewhere.
+- All database I/O goes through `@colony/storage`. No other package opens the DB directly.
+- Settings access goes through `@colony/config`. No direct reads from `~/.colony/settings.json` elsewhere.
- All user-visible strings default to the caveman intensity from settings (default `full`).
- Public package exports are listed in each package's `package.json#exports`. Internal files are not imported across package boundaries.
@@ -50,7 +50,7 @@ evals token-savings and round-trip harness
## Development workflow
- `pnpm install` once. Node ≥ 20.
-- `pnpm dev` runs the CLI and worker in watch mode against `.cavemem-dev/` in the repo root (isolated data dir).
+- `pnpm dev` runs the CLI and worker in watch mode against `.colony-dev/` in the repo root (isolated data dir).
- The four required gates before merging:
- `pnpm typecheck`
- `pnpm lint`
@@ -75,7 +75,7 @@ Unit tests cover handlers, storage, and protocol contracts in isolation. They ca
- **New compression rule**: update `packages/compress/src/lexicon.json`, add at least one round-trip fixture under `packages/compress/test/fixtures/`, and re-run the benchmark in `evals/`.
- **New embedding provider**: add a module in `packages/embedding/src/providers/`, wire it into the `createEmbedder` switch in `packages/embedding/src/index.ts`, and extend the `EmbeddingProvider` enum in `packages/config/src/schema.ts`. Each provider must expose `{ model, dim, embed(text) }` — `dim` must be correct before the first `embed()` call completes (warm-up probe).
- **New storage migration**: add a numbered SQL file in `packages/storage/src/migrations/`. Migrations are forward-only.
-- **New CLI setting**: add the field to `SettingsSchema` with a `.describe(…)` string. `cavemem config show` and `settingsDocs()` pick it up automatically — no parallel docs to maintain.
+- **New CLI setting**: add the field to `SettingsSchema` with a `.describe(…)` string. `colony config show` and `settingsDocs()` pick it up automatically — no parallel docs to maintain.
## Performance budgets
diff --git a/LICENSE b/LICENSE
index d8c0ee8..94da2ca 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2026 Julius Brussee
+Copyright (c) 2026 Imdeadpool
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index 4545072..522f8b1 100644
--- a/README.md
+++ b/README.md
@@ -1,304 +1,154 @@
-# agents (ants) hivemind
+# Colony
-**A biologically-grounded hivemind for AI coding agents.**
+**Local-first memory and coordination for AI coding agents.**
-cavemem is a local-first memory and coordination system that lets multiple AI coding agents — Claude Code, Codex, Cursor, and friends — work on the same codebase without stepping on each other. It persists memory across sessions, surfaces what other agents are doing in real time, and coordinates their work through mechanisms borrowed directly from ant colonies: chemical-trail-style signals that strengthen with use and fade without it.
-
-The design choice worth pausing on, because it's the thing that makes cavemem different from conventional coordination tools, is the decision to borrow from biology rather than from distributed systems textbooks. Ant colonies have been stress-testing their coordination protocols for about 150 million years, which means any pattern we take from them has already been debugged against failure modes we haven't even imagined yet. What ants use is not messaging and not shared state in the usual programmer's sense — it's *stigmergy*, coordination through traces left in a shared environment. cavemem applies exactly that pattern to AI agents.
-
-Important current-state note: the published CLI and package names are still `cavemem`, so the commands below use `cavemem` even though this repository is branded as `agents-hivemind`. IDE MCP installs register the server as `colony`, so agent tool calls use the `colony` namespace.
-
-## The core idea: stigmergy
-
-The fundamental pattern underneath everything cavemem does is that agents never talk to each other directly. Instead, each agent leaves traces in a shared environment, and those traces influence what the other agents choose to do next. It's the same mechanism an ant colony uses to solve surprisingly sophisticated coordination problems — finding the shortest path to food, building a ventilated nest, allocating workers to tasks — without any individual ant knowing the colony's plan, because there *is* no colony plan. There's just the environment, the trail-laying behavior, and the rules each ant follows.
-
-
- Stigmergy: the core coordination pattern in cavemem
- Two agents interact through a shared environment containing pheromones, proposals, and task threads, rather than communicating directly.
-
-
-
-
-
-
-
- Claude
- session
-
-
-
- Codex
- session
-
-
-
- Shared environment
-
- pheromones on files
- proposals (weak trails)
- task threads
- SQLite-backed, local-first
-
-
-
-
-
- deposits
- perceives
-
-
-
-
- deposits
- perceives
-
- No direct messaging. Coordination emerges from traces in the environment.
-
-
+
+
+
+
-Notice what's *missing* from the diagram: there's no arrow between Claude and Codex. Agents never see each other directly. What Claude sees is the environment — specifically, the pheromones and proposals and task threads that Codex has left behind. And what Codex sees, when it makes a decision, is the environment as Claude has most recently shaped it. This indirection is the whole trick. Because the environment is the shared medium, there's no need for a central coordinator, no need for a messaging protocol, no need for any agent to know about any other agent's internal state. The environment is the communication channel, and the traces are the messages.
-
-The concrete instantiation of this abstract environment is a SQLite database at `~/.cavemem/data.db`, with tables for memory observations, task threads, pheromones, proposals, and so on. But the conceptual model — the thing that determines how the pieces fit together — is the ant colony.
-
-## Why ants specifically, and not some other biological metaphor?
+Colony lets Claude Code, Codex, Cursor, Gemini CLI, OpenCode, and other coding agents share memory, coordinate task ownership, and avoid stepping on each other while working in the same repository. It keeps the system local-first: observations, task threads, claims, handoffs, and search indexes live on your machine instead of requiring a hosted coordinator.
-A fair question, because nature has plenty of other coordination patterns. Beehives do something similar. Starling murmurations are collective without being hive-structured. Slime molds solve maze problems through gradient-following. So why ants, specifically, as the inspiration for cavemem?
+The design is ant-colony inspired on purpose. Agents do not need a central planner or direct messages to collaborate. They leave useful traces in a shared environment, then future agents react to those traces. That stigmergic model gives Colony a practical shape: active work leaves heat, repeated interest reinforces good follow-up tasks, and stale signals fade.
-The answer is that ants are the biological organism whose coordination problems most closely resemble what a group of AI coding agents faces. Ants deal with *persistent work over time* — a foraging expedition isn't a momentary decision, it's a sustained activity that other ants need to be able to join and leave. They deal with *partial information* — no ant sees the whole picture, each one only knows what's immediately in front of it. They deal with *asynchronous participation* — ants don't all work at the same time, they come and go, and the trail system handles that gracefully. And they deal with *graceful degradation* — a colony that loses a third of its workers doesn't collapse, it just moves a little slower. All four properties are exactly what you need in a multi-agent coding system where agents start and stop independently, know only their own context, and need the system to keep working even when one of them goes quiet.
+## What Colony Provides
-The other biological systems don't quite fit. Beehives solve similar problems but with more centralized information flow (the waggle dance announces specific coordinates, which is more like messaging than stigmergy). Starling murmurations are wonderful but don't have persistent work — each bird just reacts to neighbors in the moment. Slime molds are amazing but solve fundamentally different problems. Ants, for the specific shape of "multiple long-lived agents working on the same codebase," are just the right abstraction.
+- Persistent session memory across agent runs.
+- MCP tools under the `colony` namespace.
+- CLI commands under the `colony` binary.
+- Local SQLite storage under `~/.colony`.
+- IDE installers for Claude Code, Codex, Cursor, Gemini CLI, and OpenCode.
+- Task threads for shared work, notes, answers, blockers, and decisions.
+- File claims and handoffs so agents can coordinate without a human acting as dispatcher.
+- Foraging-style proposals that can be reinforced into real work.
+- Pheromone-style activity signals for hot files and recent focus.
-## The three mechanisms
+## Install
-cavemem takes three specific mechanisms from ant coordination and implements each one on top of its SQLite substrate. These three mechanisms compose to produce the full system, but each one also stands alone and addresses a specific coordination failure mode. Let me walk through each in turn.
+```bash
+npm install -g colony
+```
-### Mechanism one: pheromones
+Register Colony with your IDE or agent runtime:
-The first and most fundamental mechanism is the pheromone trail. When an ant walks over a surface, it deposits a small amount of pheromone. Other ants sense the pheromone and are more likely to follow paths where the trail is strong. Critically, pheromones have three properties that make the whole system robust: they have **strength** (a quantity, not just a yes/no), they **decay** exponentially over time, and they get **reinforced** by repeated use. A trail that's useful gets walked more, which means more pheromone is deposited, which means the trail stays strong. A trail that leads nowhere useful doesn't get reinforced, so the pheromone evaporates and the trail disappears.
+```bash
+colony install --ide claude-code
+colony install --ide codex
+colony install --ide cursor
+colony install --ide gemini-cli
+colony install --ide opencode
+```
-This is dramatically different from how most software systems handle "someone is working on this" state. Your typical file-locking or claim system is binary (either claimed or not), static (it stays until explicitly released), and requires an agent to remember to release when done. Pheromones fix all three of these limitations at once. They're graded, so a file that's been edited ten times in the last minute looks meaningfully different from one edited once an hour ago. They're time-sensitive, so nobody has to remember to release claims — the universe forgets them automatically. And they're reinforced by actual use, so they accurately reflect what agents are currently focused on rather than what they said they'd do.
+Check wiring:
-
-
- Pheromone strength over time with decay and reinforcement
- Exponential decay curve showing pheromone strength halving every 10 minutes. One trail is reinforced by repeated deposits and stays strong; another is not reinforced and fades below the noise threshold.
-
- Pheromone strength over time
-
-
-
-
-
-
- 1.0
- 0.75
- 0.5
- 0.25
- 0
- strength
-
-
- 0
- 10 min
- 20 min
- 30 min
- 40 min
- time since deposit
-
-
-
-
-
- half-life (10 min)
-
- noise floor (0.1)
-
- unreinforced trail — decays away
-
-
-
-
-
- reinforced trail — stays hot
-
-
-
- deposit
- reinforce
- reinforce
-
-
+```bash
+colony status
+```
-The math underneath this picture is one line: `strength(t) = deposit × exp(-λ × elapsed_ms)`, where `λ` is chosen to give a ten-minute half-life. What's beautiful about this formula, and what makes the whole system cheap to implement, is that you never actually have to run a decay process. No cron job ages rows, no cleanup task scans the table. You just store when a pheromone was deposited and how strong the deposit was, and current strength is always computed fresh when someone asks for it. Time does the decaying for free.
+Example status shape:
-In code, this lives in `packages/core/src/pheromone.ts` as a `PheromoneSystem` class with three methods. Calling `deposit()` is how an edit leaves its mark — the `PostToolUse` hook invokes this whenever Claude or Codex uses an `Edit`, `Write`, or `MultiEdit` tool. Calling `sniff()` reports the current strength on a specific file, decomposed by which session deposited what. Calling `strongestTrails()` returns the hottest files on a task right now, which is what powers both the `observe` dashboard's heat-map view and the conflict warnings in the `UserPromptSubmit` preface. The whole thing is maybe 120 lines of code and one small SQL table.
+```text
+Colony 0.2.0
+data: ~/.colony/data.db
+mcp namespace: colony
+ides: claude-code, codex
+memory: 1284 observations, 22 sessions
+tasks: 3 active, 0 pending handoffs
+embeddings: local / Xenova/all-MiniLM-L6-v2
+```
-### Mechanism two: foraging for improvements
+## Daily Commands
-The second mechanism is where cavemem starts to do something genuinely novel, and it's the one that most closely maps onto the Ant Colony Optimization algorithms that computer scientists rediscovered in the 1990s. The biological setup: when a scout ant finds a potential food source, it doesn't immediately mobilize the colony. It lays a weak trail — an announcement with low confidence. If the food turns out to be rich, returning foragers reinforce the trail and more ants come to exploit it. If the food is mediocre, the trail isn't reinforced, decays quickly, and the colony's attention goes elsewhere. Critically, the ant that made the original discovery has no power to *declare* the food source important. Importance is decided collectively, by whether other ants return to it.
+| Command | Purpose |
+| --- | --- |
+| `colony install --ide ` | Register hooks and MCP config for one IDE/runtime. |
+| `colony status` | Show storage, installed IDEs, worker state, and memory counts. |
+| `colony search ""` | Search prior observations and session memory. |
+| `colony timeline ` | Inspect one session chronologically. |
+| `colony observe` | Watch current task threads and coordination state. |
+| `colony viewer` | Open the local web viewer. |
+| `colony debrief` | Summarize recent work and surface follow-ups. |
+| `colony config show` | Print current settings and documented defaults. |
+| `colony uninstall --ide ` | Remove installed hooks and MCP config for one IDE/runtime. |
-The same mechanism works beautifully for **agents proposing improvements to a codebase**. Any agent, while working on its current task, can notice something worth doing later — "the compression layer has a performance edge case," "the MCP error handling is inconsistent," "the viewer could use a search box." Rather than either ignoring these observations or immediately pivoting to address them, an agent files a *proposal*, which is the equivalent of laying a weak trail. If the proposal is actually a good idea, other agents working in adjacent code will reinforce it — either explicitly (voting for it) or implicitly (by editing files the proposal would touch, which counts as weaker evidence of shared interest). When total reinforcement crosses a threshold, the proposal is automatically promoted to a real task, which then runs through cavemem's normal task-thread machinery. If the proposal never attracts reinforcement, it decays below the noise floor and quietly disappears.
+## MCP Namespace
-
-
- Proposal lifecycle: reinforcement leads to promotion, neglect leads to evaporation
- Two parallel timelines show a proposal being reinforced by multiple agents and crossing the promotion threshold to become a real task, versus a proposal that attracts no reinforcement and decays below the noise floor.
-
- Proposal lifecycle: foraging for improvements
-
-
- Reinforced → promoted
- Unreinforced → evaporated
-
-
-
-
-
-
-
-
-
- strong
- weak
- time →
- strong
- weak
- time →
-
-
- promotion threshold
-
-
-
-
-
-
-
- proposed
- + adjacent edit
- + explicit support
- promoted to task
-
-
-
- task thread created
-
- noise floor
-
-
- proposed
- no reinforcement arrives
-
-
-
- quietly evaporates
-
-
+IDE installs register the server as `colony`, so tool calls appear as `mcp__colony__...`.
-The genius of this design, and the reason it's worth borrowing from biology rather than just adding a "suggestions" feature, is that it provides *automatic filtering*. Conventional suggestion boxes fill with noise: every idea anyone has ever had gets recorded, and nobody has the energy to triage them, so the whole system becomes untrustworthy. The foraging mechanism makes triage happen by default — a proposal nobody reinforces vanishes on its own, while a proposal that multiple agents independently find important rises naturally to attention. The database never grows unboundedly with stale ideas, and the proposals that do survive have, by definition, earned the collective attention that justifies them becoming real work.
+Common tools:
-The technical implementation lives in `packages/core/src/proposal-system.ts`, with two tables (`proposals` and `proposal_reinforcements`) and a half-life around one hour for reinforcements — longer than the ten-minute half-life for pheromones on files, because ideas deserve a longer grace period than edits. A proposal starts with the proposer's own explicit reinforcement, so it's not born at zero strength, and it crosses the promotion threshold when total reinforcement weight (decayed to the present moment) exceeds 2.5. That threshold corresponds roughly to "explicit support from one agent plus either another explicit support or repeated adjacency reinforcement," which is the minimum evidence that the proposal genuinely resonates beyond its original proposer.
+| Tool | Purpose |
+| --- | --- |
+| `mcp__colony__search` | Find compact memory hits. |
+| `mcp__colony__get_observations` | Fetch full observation bodies. |
+| `mcp__colony__list_sessions` | List recent agent sessions. |
+| `mcp__colony__timeline` | Read one session timeline. |
+| `mcp__colony__hivemind` | Summarize active sessions and ownership. |
+| `mcp__colony__task_list` | List task threads. |
+| `mcp__colony__task_timeline` | Read task-thread events. |
+| `mcp__colony__task_post` | Post a question, answer, decision, blocker, or note. |
+| `mcp__colony__task_claim_file` | Claim file ownership on a task. |
+| `mcp__colony__task_hand_off` | Transfer work and file claims to another agent. |
+| `mcp__colony__task_foraging_report` | Review proposals that may become real tasks. |
-### Mechanism three: response thresholds
+## Storage
-The third mechanism addresses a problem that shows up once you have more than two agents: how does work get routed to whichever agent is best suited to do it? The ant version of this is called *response threshold allocation*, and it's how colonies decide which castes respond to which stimuli. Soldier ants have a low threshold for "intruder" signals and a high threshold for "hungry larva" signals, so they ignore larva-feeding work unless it becomes a colony-level crisis. Nurse ants have the opposite profile. The colony therefore routes work correctly without any ant directing any other ant — each ant simply asks "is this signal strong enough for *me* personally to care?" and the answers, taken collectively, produce intelligent allocation.
+Default local state:
-For AI agents, the equivalent is that different models have different strengths. Claude might be better at UI and prose work; Codex might be better at API endpoints and systems code. When a handoff is posted with `to_agent: 'any'`, rather than being claimed by whoever reads the preface first, cavemem can score the handoff against each candidate agent's capability profile and recommend the best fit. The receiving agents still have to *choose* to accept — nothing is automatic, because the agent always has better context about its immediate situation than any routing algorithm does — but the preface each agent sees is tailored to that agent's profile, so the best-fit agent sees the handoff framed as "this is a strong match for you" while a worse-fit agent sees it framed as "this is available but Codex is probably a better fit."
-
-
-
- Response thresholds: same stimulus, different agents, different responses
- A handoff request arrives and is scored against the capability profiles of Claude and Codex. Each agent computes a different score, and the preface shown to each agent emphasizes the best match.
-
- Response-threshold routing: same handoff, different fit scores
-
-
-
- Handoff arrives
- "fix the /api/exports endpoint,"
- "add route tests"
-
-
-
-
-
-
-
-
-
- Claude profile
-
-
- ui_work 0.9
- api_work 0.4
- test_work 0.6
- doc_work 0.8
-
- score: 0.4 + 0.6 = 1.0
-
-
- Codex profile
-
-
- ui_work 0.45
- api_work 1.0
- test_work 0.9
- doc_work 0.35
-
- score: 1.0 + 0.9 = 1.9 ✓
-
-
-
-
- Preface suggests: "Codex is best fit (1.9 vs 1.0)"
-
-
-
+```text
+~/.colony/settings.json
+~/.colony/data.db
+~/.colony/models/
+~/.colony/logs/
+```
-The scoring itself is deliberately primitive — a weighted keyword match rather than anything fancier — because the right sophistication level for this layer depends on observing real handoff misrouting, not on imagining it in advance. The `rankCandidates` function in `packages/core/src/response-thresholds.ts` takes a handoff's summary and next-steps text, looks for category keywords (`api`, `endpoint`, `test`, `ui`, etc.), weights them by each candidate agent's profile score for that category, and returns a ranked list. A handoff about "fix the broken viewer component" scores high for an agent with high `ui_work` affinity; a handoff about "update the CI deploy pipeline" scores high for one with high `infra_work`. Ambiguous handoffs produce roughly-equal scores, which is the right failure mode: ambiguity in the handoff means any agent could reasonably take it, and the system correctly refuses to force a preference.
+Colony keeps memory local and uses SQLite for the coordination substrate. Embeddings are lazy: the local model downloads only when semantic search or backfill first needs it.
-## How the three mechanisms fit together
+## The Coordination Model
-Each mechanism addresses a specific coordination failure mode, and they compose without any of them needing to know about the others. Pheromones prevent file-edit conflicts by making ambient activity visible. Proposals generate a steady stream of well-filtered work that the colony can tackle between human-initiated tasks. Response thresholds route handoffs to whichever agent is best suited. Take any one away and the system is still functional; combine all three and you get coordination behavior that individual agents never had to be programmed to produce.
+Colony borrows three mechanisms from ant colonies.
-A typical working session looks like this in practice. You open Claude Code in one terminal and Codex in another, both `cd`'d into the same branch. Auto-join (keyed on `repo_root + branch`) lands both sessions on the same task thread. Each session's `SessionStart` hook injects a preface telling that agent who else is on the task and what they've recently been doing, drawing on the pheromone heat map and the task timeline. As each agent edits files, `PostToolUse` deposits pheromones, which influence the conflict warnings the other agent will see on its next turn. If either agent notices an improvement worth making later, it files a proposal — weak on its own, but if the other agent later edits a file the proposal would touch, or if a subsequent session independently proposes something similar, the reinforcement accumulates and the proposal eventually becomes its own task. When an agent finishes a chunk of work and wants to hand off, the response-threshold scoring suggests the best recipient. And underneath all of it, cavemem's memory layer is recording everything — compressed observations, embeddings for semantic search, session timelines — so that tomorrow's sessions inherit today's context.
+**Pheromones:** file activity leaves decaying traces. Recent edits, claims, and task focus make hot areas visible without requiring permanent locks.
-## Getting started
+**Foraging:** agents can leave weak proposals for future improvements. Proposals that other agents reinforce become real work; proposals nobody touches fade out.
-Install cavemem globally with a single command, which downloads the CLI, the bundled MCP server, the embedding worker, and the hook stubs: `npm install -g cavemem`. Register the hooks and MCP server with whichever IDE you use by running `cavemem install --ide claude-code` (or `--ide codex`, `--ide cursor`, etc.). The installer writes the necessary entries into the IDE's settings file and verifies the wiring. You can then confirm everything is connected by running `cavemem status`, which shows the database path, embedding backfill progress, and any currently-installed IDE integrations. If you want to see what's happening in real time while you work, run `cavemem observe` in a spare terminal — it's a live-updating dashboard showing active task threads, current pheromone heat map, pending handoffs, and recent activity from all sessions.
+**Response thresholds:** handoffs can be scored against agent profiles so the best-fit agent sees stronger routing guidance, while ambiguous work remains available to any capable agent.
-The two commands worth knowing for day-to-day use are `cavemem search ` (fast semantic search across all past sessions, useful when you remember discussing something but not which session) and `cavemem viewer` (opens a local web UI at `127.0.0.1:37777` showing session timelines, Hivemind runtime state, and eventually task-thread views). Everything else is meant to happen automatically through the hooks — you shouldn't have to call `task_post` or `task_claim_file` manually, and if you find yourself wanting to, that's feedback worth reporting, because the goal is for coordination to happen by default rather than requiring the human to orchestrate it.
+These mechanisms are intentionally simple. Colony favors observable signals, decay, and reinforcement over a central coordinator that has to know the whole plan.
-## Current status and roadmap
+## Rough Edges
-The memory layer is fully shipped and stable. Compression, FTS, semantic search, session persistence, cross-IDE hook integration, and the MCP server surface with all fourteen tools are all in place and tested. The task-thread collaboration layer is shipped through version 0.2 — auto-join, task messages, file claims, the full handoff lifecycle with atomic claim transfer, and end-to-end hook injection on both `SessionStart` and `UserPromptSubmit`. What's not yet shipped, as of this writing, is the full ant-inspired layer described above. The pheromone system is designed and partially prototyped but not yet integrated into `PostToolUse`. The proposal foraging system is designed but not yet implemented. Response-threshold routing exists as a specification rather than running code.
+- Older installs may still have the previous MCP namespace in IDE config; running `colony install --ide ` rewrites the active entry to `colony`.
+- Pheromone and proposal thresholds need tuning from real multi-agent usage, not theoretical defaults.
+- MCP transport is stdio-based, so IDE/runtime restarts can close the server process; the next tool call should reconnect through the installed config.
+- The viewer is useful for inspection, but the primary workflow is still terminal/agent-driven.
-The honest reason for the gap between design and implementation is that each of these mechanisms deserves to be tuned against real usage data rather than against imagined usage. The pheromone half-life, the proposal promotion threshold, the response-threshold scoring weights — all of these have defaults that are educated guesses, and the right way to find the correct values is to run the system on actual two-agent work for a few days and watch what happens. That observation phase is the current focus, and the code will ship in waves as each mechanism's parameters get validated against what the `cavemem debrief` command reveals at the end of each day.
+## Roadmap
-If you want to contribute, the highest-leverage thing right now is running the system seriously on a real codebase and reporting back on what you observe — particularly the places where coordination feels clumsy, where agents repeatedly step on each other, or where a handoff goes to the wrong agent. Those observations are what the next round of design decisions rest on, and no amount of theoretical work substitutes for real friction reports from real sessions.
+- Finish release hygiene for the renamed `colony` package.
+- Expand task-thread views in the local viewer.
+- Tune pheromone half-life and proposal promotion thresholds from real work.
+- Add richer routing profiles for handoffs between Claude, Codex, Cursor, and other agents.
+- Improve debrief output so useful follow-ups become proposals instead of chat-only notes.
+- Harden migration from older installs into `~/.colony` and the `colony` MCP namespace.
-## A closing thought on design philosophy
+## Contributing
-The reason cavemem is built around biological metaphors rather than around conventional distributed-systems primitives is that the problems an agent collective faces — partial information, graceful degradation, persistent work, asynchronous participation — are problems biology has already solved elegantly. Borrowing the solutions isn't just aesthetically pleasing; it's a shortcut to robustness that would take decades to derive from first principles. Ant colonies don't have deadlocks, don't have stale locks, don't have coordinator bottlenecks, and don't collapse when one ant goes quiet, because their coordination mechanism was never built around any of those failure modes in the first place.
+Use Colony on real work, then report the exact places where coordination felt wrong: stale claims, confusing handoffs, missing session context, noisy proposals, or files that should have shown up as hot but did not.
-What makes this approach work in software, and what's worth understanding if you want to extend cavemem, is that the biological metaphor is not decorative — it's functional. `strengthAt(deposit, time)` is not "inspired by" exponential decay, it *is* exponential decay, the same formula that describes real pheromone evaporation on real surfaces. The proposal foraging algorithm is not "inspired by" ant colony optimization, it *is* ant colony optimization, the same mathematical pattern computer scientists borrowed from biology in the 1990s. When you read cavemem's code, you're reading an implementation of mechanisms that evolution already proved robust. That's a load-bearing claim, not a poetic one, and it's why this particular metaphor earned its place in the architecture rather than just the documentation.
+For code changes:
-Build the system, watch how it behaves, trust what the biology has already worked out for you, and tune the parameters only where real usage insists. That's the cavemem way, and it turns out to be a surprisingly humble approach: instead of believing your design intuitions are sufficient, you lean on a few hundred million years of accumulated design wisdom, and you treat your own role as figuring out how to port those designs into a new substrate rather than inventing new designs from scratch. Ants, as it happens, make excellent engineering mentors.
+1. Keep behavior local-first.
+2. Prefer small, observable coordination primitives over central orchestration.
+3. Add regression tests when changing hooks, storage, MCP tools, or CLI output.
+4. Keep CLI, MCP namespace, package names, paths, and README examples aligned on `colony`.
----
+## License
-**License:** MIT
-**Author:** Julius Brussee
-**Repository:** [github.com/JuliusBrussee/cavemem](https://github.com/JuliusBrussee/cavemem)
+MIT © Imdeadpool
diff --git a/apps/cli/CHANGELOG.md b/apps/cli/CHANGELOG.md
index f4e9208..0788dc5 100644
--- a/apps/cli/CHANGELOG.md
+++ b/apps/cli/CHANGELOG.md
@@ -8,10 +8,10 @@
**Embeddings (previously dead code) now work out of the box**
- - New `@cavemem/embedding` package exports `createEmbedder(settings)` with three providers: `local` (Transformers.js, default — `Xenova/all-MiniLM-L6-v2`, 384 dim), `ollama`, and `openai`. `@xenova/transformers` is an optional dependency: installs automatically with `npm install -g cavemem` on supported platforms, falls back gracefully otherwise.
+ - New `@colony/embedding` package exports `createEmbedder(settings)` with three providers: `local` (Transformers.js, default — `Xenova/all-MiniLM-L6-v2`, 384 dim), `ollama`, and `openai`. `@xenova/transformers` is an optional dependency: installs automatically with `npm install -g cavemem` on supported platforms, falls back gracefully otherwise.
- The worker now runs an embedding backfill loop: polls `observationsMissingEmbeddings`, embeds the expanded (human-readable) text, persists. On startup it drops rows whose model differs from settings so switching providers never pollutes cosine ranking.
- Storage gains a model/dim filter on `allEmbeddings()` plus `dropEmbeddingsWhereModelNot`, `countObservations`, `countEmbeddings`, and a model-scoped variant of `observationsMissingEmbeddings`.
- - The `Embedder` interface in `@cavemem/core` now exposes `model` and `dim` so the store can reject mismatched rows before cosine computation.
+ - The `Embedder` interface in `@colony/core` now exposes `model` and `dim` so the store can reject mismatched rows before cosine computation.
- Both the CLI `search` command and the MCP `search` tool instantiate the embedder lazily and pass it into `MemoryStore.search`. Semantic search is on by default; `cavemem search --no-semantic` bypasses it.
- Worker writes a `worker.state.json` snapshot after every batch so `cavemem status` can show "embedded 124 / 200 (62%)" without hitting HTTP.
@@ -25,7 +25,7 @@
- New `cavemem status` top-level command: single-pane dashboard showing settings path, data dir, DB counts, installed IDEs, embedding provider/model, backfill progress, worker pid and uptime.
- New `cavemem config show|get|set|open|path|reset` command backed by zod `.describe()` — the schema is self-documenting; no parallel docs to maintain.
- - New `settingsDocs()` export from `@cavemem/config` returns `[{path, type, default, description}]` for every field.
+ - New `settingsDocs()` export from `@colony/config` returns `[{path, type, default, description}]` for every field.
- `cavemem install` now prints a multi-line "what to try next" block explaining that there is no daemon to start, and surfaces the embedding model + weight-download cost.
- Settings schema gains `embedding.batchSize`, `embedding.autoStart`, and `embedding.idleShutdownMs` — every field now has a `.describe(...)` string.
@@ -51,7 +51,7 @@
**Publishable artifact**
- - `cavemem` no longer lists the private `@cavemem/mcp-server` and `@cavemem/worker` packages as runtime dependencies. Tsup already bundles every `@cavemem/*` module via `noExternal`, so the workspace deps moved to `devDependencies` and `npm install cavemem` resolves cleanly.
+ - `cavemem` no longer lists the private `@colony/mcp-server` and `@colony/worker` packages as runtime dependencies. Tsup already bundles every `@colony/*` module via `noExternal`, so the workspace deps moved to `devDependencies` and `npm install cavemem` resolves cleanly.
- The bin entrypoint guard (`isMainEntry()`) now compares realpaths via `pathToFileURL(realpathSync(...))`, so the binary works when invoked through npm's symlinked `bin/` shim — previously `--version` and every other command silently exited 0 with no output.
- Tsup's `banner` option was producing two `#!/usr/bin/env node` lines in every dynamic-import chunk (one from the source file, one from the banner), which broke `cavemem mcp` with `SyntaxError: Invalid or unexpected token`. The banner is gone; the shebang lives in the source files that need it.
- A new `prepublishOnly` script (`apps/cli/scripts/prepack.mjs`) stages `README.md`, `LICENSE`, and `hooks-scripts/` into `apps/cli/` so `changeset publish` produces a complete tarball. The script no-ops outside the source repo so installing the tarball never re-runs it.
@@ -65,7 +65,7 @@
**Root cause**
- The CLI's `process.argv[1]` (and everything `resolveCliPath()` derives from it) is the `.js` entry file, not a native executable. Node's `child_process.spawn` cannot exec a raw `.js` on Windows — it has no associated binfmt handler, so the launcher bubbles up `EFTYPE`. Every background code path that self-spawned the CLI — `cavemem start`, `cavemem restart`, `cavemem viewer`, and the hook auto-spawn in `@cavemem/hooks` — hit this, so the worker never started and hooks stayed degraded with no embeddings. The installers then wrote the same bad shape into IDE configs (`command: ` for MCP servers; `" hook run …"` as a shell string for Claude Code hooks), so even opening Claude Code / Cursor / Codex / Gemini / OpenCode could not launch the CLI.
+ The CLI's `process.argv[1]` (and everything `resolveCliPath()` derives from it) is the `.js` entry file, not a native executable. Node's `child_process.spawn` cannot exec a raw `.js` on Windows — it has no associated binfmt handler, so the launcher bubbles up `EFTYPE`. Every background code path that self-spawned the CLI — `cavemem start`, `cavemem restart`, `cavemem viewer`, and the hook auto-spawn in `@colony/hooks` — hit this, so the worker never started and hooks stayed degraded with no embeddings. The installers then wrote the same bad shape into IDE configs (`command: ` for MCP servers; `" hook run …"` as a shell string for Claude Code hooks), so even opening Claude Code / Cursor / Codex / Gemini / OpenCode could not launch the CLI.
**Fix**
@@ -85,8 +85,8 @@
- Fix a compression bug where `collapseWhitespace` would eat the single space between prose and preserved tokens (paths, inline code, URLs), producing unreadable output like `at/tmp/foo.txt`. Boundary spacing is now preserved on compress and round-tripped through expand.
- Fix `Storage.timeline(sessionId, aroundId, limit)` — the previous single-UNION query let the "after" half swallow the whole window. Replaced with two bounded queries merged in JS so both halves are respected.
- Remove a double `expand()` call in the MCP `get_observations` tool; expansion now happens exactly once inside `MemoryStore`.
- - `runHook()` now accepts an injected `MemoryStore` so tests (and other integrations) can avoid touching the user's real `~/.cavemem` data directory.
+ - `runHook()` now accepts an injected `MemoryStore` so tests (and other integrations) can avoid touching the user's real `~/.colony` data directory.
- Test ecosystem: brand-new suites for `@cavemem/hooks` (runner + all 5 handlers + hot-path budget check), `@cavemem/installers` (claude-code idempotency, settings preservation, cursor install/uninstall, registry, deepMerge), `@cavemem/mcp-server` (InMemory MCP client hitting every tool and asserting the progressive-disclosure shape), `@cavemem/worker` (Hono `app.request()` integration tests for every HTTP route), and the `cavemem` CLI (command registration smoke test). Total tests: 22 → 54.
+ Test ecosystem: brand-new suites for `@colony/hooks` (runner + all 5 handlers + hot-path budget check), `@colony/installers` (claude-code idempotency, settings preservation, cursor install/uninstall, registry, deepMerge), `@colony/mcp-server` (InMemory MCP client hitting every tool and asserting the progressive-disclosure shape), `@colony/worker` (Hono `app.request()` integration tests for every HTTP route), and the `cavemem` CLI (command registration smoke test). Total tests: 22 → 54.
None of the new test directories are shipped — every published package keeps its `files` allowlist pointed at `dist` only.
diff --git a/apps/cli/package.json b/apps/cli/package.json
index e3a743b..d204144 100644
--- a/apps/cli/package.json
+++ b/apps/cli/package.json
@@ -1,8 +1,8 @@
{
- "name": "cavemem",
+ "name": "colony",
"version": "0.2.0",
"license": "MIT",
- "description": "Cross-agent persistent memory with compressed storage. Plug-and-play memory for Claude Code, Gemini CLI, OpenCode, Codex, and Cursor.",
+ "description": "Local-first memory and coordination for Claude Code, Gemini CLI, OpenCode, Codex, and Cursor.",
"keywords": [
"memory",
"mcp",
@@ -15,21 +15,21 @@
"compression",
"llm"
],
- "author": "Julius Brussee",
- "homepage": "https://github.com/JuliusBrussee/cavemem",
+ "author": "Imdeadpool",
+ "homepage": "https://github.com/recodeee/colony",
"repository": {
"type": "git",
- "url": "https://github.com/JuliusBrussee/cavemem.git"
+ "url": "https://github.com/recodeee/colony.git"
},
"bugs": {
- "url": "https://github.com/JuliusBrussee/cavemem/issues"
+ "url": "https://github.com/recodeee/colony/issues"
},
"engines": {
"node": ">=20.0.0"
},
"type": "module",
"bin": {
- "cavemem": "./dist/index.js"
+ "colony": "./dist/index.js"
},
"main": "./dist/index.js",
"files": ["dist", "hooks-scripts", "README.md", "LICENSE"],
@@ -55,15 +55,15 @@
"@xenova/transformers": "^2.17.2"
},
"devDependencies": {
- "@cavemem/compress": "workspace:*",
- "@cavemem/config": "workspace:*",
- "@cavemem/core": "workspace:*",
- "@cavemem/embedding": "workspace:*",
- "@cavemem/hooks": "workspace:*",
- "@cavemem/installers": "workspace:*",
- "@cavemem/mcp-server": "workspace:*",
- "@cavemem/storage": "workspace:*",
- "@cavemem/worker": "workspace:*",
+ "@colony/compress": "workspace:*",
+ "@colony/config": "workspace:*",
+ "@colony/core": "workspace:*",
+ "@colony/embedding": "workspace:*",
+ "@colony/hooks": "workspace:*",
+ "@colony/installers": "workspace:*",
+ "@colony/mcp-server": "workspace:*",
+ "@colony/storage": "workspace:*",
+ "@colony/worker": "workspace:*",
"tsup": "^8.3.5",
"typescript": "^5.6.3",
"vitest": "^2.1.5"
diff --git a/apps/cli/scripts/pack-release.mjs b/apps/cli/scripts/pack-release.mjs
index ccdbca4..c59a9e3 100644
--- a/apps/cli/scripts/pack-release.mjs
+++ b/apps/cli/scripts/pack-release.mjs
@@ -1,6 +1,6 @@
#!/usr/bin/env node
-// Prepares a self-contained publish directory for the `cavemem` npm package.
-// tsup already bundles all @cavemem/* workspace code into dist/index.js, so
+// Prepares a self-contained publish directory for the `colony` npm package.
+// tsup already bundles all @colony/* workspace code into dist/index.js, so
// the shipped package only needs the real third-party runtime deps.
import { cpSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
import { dirname, join, resolve } from 'node:path';
diff --git a/apps/cli/src/commands/compress.ts b/apps/cli/src/commands/compress.ts
index 760218f..ac4d477 100644
--- a/apps/cli/src/commands/compress.ts
+++ b/apps/cli/src/commands/compress.ts
@@ -1,6 +1,6 @@
import { copyFileSync, readFileSync, writeFileSync } from 'node:fs';
-import { compress, countTokens, expand } from '@cavemem/compress';
-import { loadSettings } from '@cavemem/config';
+import { compress, countTokens, expand } from '@colony/compress';
+import { loadSettings } from '@colony/config';
import type { Command } from 'commander';
import kleur from 'kleur';
diff --git a/apps/cli/src/commands/config.ts b/apps/cli/src/commands/config.ts
index 268ef28..05b4c2f 100644
--- a/apps/cli/src/commands/config.ts
+++ b/apps/cli/src/commands/config.ts
@@ -8,7 +8,7 @@ import {
saveSettings,
settingsDocs,
settingsPath,
-} from '@cavemem/config';
+} from '@colony/config';
import type { Command } from 'commander';
import kleur from 'kleur';
@@ -78,7 +78,7 @@ function printDocs(docs: SettingDoc[]): void {
}
export function registerConfigCommand(program: Command): void {
- const cfg = program.command('config').description('View or edit cavemem settings');
+ const cfg = program.command('config').description('View or edit colony settings');
cfg
.command('show')
diff --git a/apps/cli/src/commands/debrief.ts b/apps/cli/src/commands/debrief.ts
index 042b854..f4495be 100644
--- a/apps/cli/src/commands/debrief.ts
+++ b/apps/cli/src/commands/debrief.ts
@@ -1,6 +1,6 @@
import { join } from 'node:path';
-import { loadSettings, resolveDataDir } from '@cavemem/config';
-import { Storage } from '@cavemem/storage';
+import { loadSettings, resolveDataDir } from '@colony/config';
+import { Storage } from '@colony/storage';
import type { Command } from 'commander';
import kleur from 'kleur';
diff --git a/apps/cli/src/commands/doctor.ts b/apps/cli/src/commands/doctor.ts
index d54071c..a3cbd21 100644
--- a/apps/cli/src/commands/doctor.ts
+++ b/apps/cli/src/commands/doctor.ts
@@ -1,7 +1,7 @@
import { existsSync } from 'node:fs';
import { join } from 'node:path';
-import { loadSettings, resolveDataDir, settingsPath } from '@cavemem/config';
-import { Storage } from '@cavemem/storage';
+import { loadSettings, resolveDataDir, settingsPath } from '@colony/config';
+import { Storage } from '@colony/storage';
import type { Command } from 'commander';
import kleur from 'kleur';
diff --git a/apps/cli/src/commands/export.ts b/apps/cli/src/commands/export.ts
index 04ffb22..5873927 100644
--- a/apps/cli/src/commands/export.ts
+++ b/apps/cli/src/commands/export.ts
@@ -1,7 +1,7 @@
import { readFileSync, writeFileSync } from 'node:fs';
import { join } from 'node:path';
-import { loadSettings, resolveDataDir } from '@cavemem/config';
-import { Storage } from '@cavemem/storage';
+import { loadSettings, resolveDataDir } from '@colony/config';
+import { Storage } from '@colony/storage';
import type { Command } from 'commander';
export function registerExportCommand(program: Command): void {
diff --git a/apps/cli/src/commands/hook.ts b/apps/cli/src/commands/hook.ts
index 3cd62b1..2038b78 100644
--- a/apps/cli/src/commands/hook.ts
+++ b/apps/cli/src/commands/hook.ts
@@ -1,4 +1,4 @@
-import { type HookName, type HookResult, runHook } from '@cavemem/hooks';
+import { type HookName, type HookResult, runHook } from '@colony/hooks';
import type { Command } from 'commander';
const VALID: HookName[] = [
diff --git a/apps/cli/src/commands/install.ts b/apps/cli/src/commands/install.ts
index 28649f5..d98f982 100644
--- a/apps/cli/src/commands/install.ts
+++ b/apps/cli/src/commands/install.ts
@@ -6,8 +6,8 @@ import {
resolveDataDir,
saveSettings,
settingsPath,
-} from '@cavemem/config';
-import { type IdeName, getInstaller, installers } from '@cavemem/installers';
+} from '@colony/config';
+import { type IdeName, getInstaller, installers } from '@colony/installers';
import type { Command } from 'commander';
import kleur from 'kleur';
import { resolveCliPath } from '../util/resolve.js';
@@ -45,19 +45,19 @@ export function registerInstallCommand(program: Command): void {
const model = settings.embedding.model;
const provider = settings.embedding.provider;
- process.stdout.write(`\n${kleur.bold('cavemem is wired into')} ${kleur.cyan(name)}\n`);
+ process.stdout.write(`\n${kleur.bold('colony is wired into')} ${kleur.cyan(name)}\n`);
process.stdout.write(
`${kleur.dim('memory writes happen in hooks — no daemon required on the hot path.')}\n\n`,
);
process.stdout.write(`${kleur.bold('what to try next:')}\n`);
process.stdout.write(
- ` ${kleur.cyan('cavemem status')} show wiring + embedding backfill\n`,
+ ` ${kleur.cyan('colony status')} show wiring + embedding backfill\n`,
);
- process.stdout.write(` ${kleur.cyan('cavemem viewer')} open the memory viewer\n`);
+ process.stdout.write(` ${kleur.cyan('colony viewer')} open the memory viewer\n`);
process.stdout.write(
- ` ${kleur.cyan('cavemem search "…"')} query your memory from the terminal\n`,
+ ` ${kleur.cyan('colony search "…"')} query your memory from the terminal\n`,
);
- process.stdout.write(` ${kleur.cyan('cavemem config show')} see settings + docs\n\n`);
+ process.stdout.write(` ${kleur.cyan('colony config show')} see settings + docs\n\n`);
if (provider === 'local') {
process.stdout.write(
@@ -67,11 +67,11 @@ export function registerInstallCommand(program: Command): void {
);
} else if (provider === 'none') {
process.stdout.write(
- `${kleur.yellow('embeddings: disabled')} (provider=none). enable with \`cavemem config set embedding.provider local\`.\n`,
+ `${kleur.yellow('embeddings: disabled')} (provider=none). enable with \`colony config set embedding.provider local\`.\n`,
);
} else {
process.stdout.write(
- `${kleur.dim(`embeddings: ${provider} / ${model} — configure endpoint/apiKey via \`cavemem config\`.`)}\n`,
+ `${kleur.dim(`embeddings: ${provider} / ${model} — configure endpoint/apiKey via \`colony config\`.`)}\n`,
);
}
});
diff --git a/apps/cli/src/commands/lifecycle.ts b/apps/cli/src/commands/lifecycle.ts
index 551c9d8..5adf861 100644
--- a/apps/cli/src/commands/lifecycle.ts
+++ b/apps/cli/src/commands/lifecycle.ts
@@ -1,13 +1,13 @@
import { spawn } from 'node:child_process';
import { existsSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';
import { join } from 'node:path';
-import { loadSettings, resolveDataDir } from '@cavemem/config';
+import { loadSettings, resolveDataDir } from '@colony/config';
import type { Command } from 'commander';
import kleur from 'kleur';
import { resolveCliPath } from '../util/resolve.js';
/**
- * Top-level `cavemem start|stop|restart|viewer` commands — matches the
+ * Top-level `colony start|stop|restart|viewer` commands — matches the
* ergonomic surface users expect from tools like ollama and tailscale.
* Thin wrappers around the existing `worker start/stop` subcommands so
* there's still a single pid-managing implementation.
@@ -94,7 +94,7 @@ export function registerLifecycleCommands(program: Command): void {
process.stdout.write(`${kleur.green('started')} (pid ${pid}) http://127.0.0.1:${port}\n`);
} else {
process.stdout.write(
- `${kleur.yellow('spawned')} (pid ${pid}) — check \`cavemem status\`\n`,
+ `${kleur.yellow('spawned')} (pid ${pid}) — check \`colony status\`\n`,
);
}
}
@@ -125,7 +125,7 @@ export function registerLifecycleCommands(program: Command): void {
process.stdout.write(`${kleur.green('restarted')} (pid ${pid}) http://127.0.0.1:${port}\n`);
} else {
process.stdout.write(
- `${kleur.yellow('restart: unclear state')} — check \`cavemem status\`\n`,
+ `${kleur.yellow('restart: unclear state')} — check \`colony status\`\n`,
);
}
});
diff --git a/apps/cli/src/commands/mcp.ts b/apps/cli/src/commands/mcp.ts
index 8cbbbd2..a4ccc18 100644
--- a/apps/cli/src/commands/mcp.ts
+++ b/apps/cli/src/commands/mcp.ts
@@ -6,6 +6,6 @@ export function registerMcpCommand(program: Command): void {
.description('Run the MCP stdio server (typically invoked by the IDE)')
.action(async () => {
// Delegate: importing runs main() via the server module.
- await import('@cavemem/mcp-server');
+ await import('@colony/mcp-server');
});
}
diff --git a/apps/cli/src/commands/note.ts b/apps/cli/src/commands/note.ts
index 3d2d195..b78e244 100644
--- a/apps/cli/src/commands/note.ts
+++ b/apps/cli/src/commands/note.ts
@@ -1,6 +1,6 @@
import { join } from 'node:path';
-import { loadSettings, resolveDataDir } from '@cavemem/config';
-import { MemoryStore } from '@cavemem/core';
+import { loadSettings, resolveDataDir } from '@colony/config';
+import { MemoryStore } from '@colony/core';
import type { Command } from 'commander';
import kleur from 'kleur';
@@ -27,7 +27,7 @@ function ensureObserverSession(store: MemoryStore): void {
export function registerNoteCommand(program: Command): void {
program
- // Variadic so `cavemem note codex stepped on claude` works without
+ // Variadic so `colony note codex stepped on claude` works without
// quoting. The quoting-every-note friction kills adoption otherwise.
.command('note ')
.description('Record a timestamped scratch note into the memory timeline')
diff --git a/apps/cli/src/commands/observe.ts b/apps/cli/src/commands/observe.ts
index ae5345d..081efbd 100644
--- a/apps/cli/src/commands/observe.ts
+++ b/apps/cli/src/commands/observe.ts
@@ -1,6 +1,6 @@
import { join } from 'node:path';
-import { loadSettings, resolveDataDir } from '@cavemem/config';
-import { Storage } from '@cavemem/storage';
+import { loadSettings, resolveDataDir } from '@colony/config';
+import { Storage } from '@colony/storage';
import type { Command } from 'commander';
import kleur from 'kleur';
@@ -32,7 +32,7 @@ function fmtAgo(ts: number): string {
function renderFrame(storage: Storage): string {
const lines: string[] = [];
const now = new Date().toISOString().slice(11, 19);
- lines.push(`${kleur.bold('cavemem observe')} ${kleur.dim(now)}`);
+ lines.push(`${kleur.bold('colony observe')} ${kleur.dim(now)}`);
lines.push(kleur.dim('─'.repeat(60)));
const tasks = storage.listTasks(5);
diff --git a/apps/cli/src/commands/reindex.ts b/apps/cli/src/commands/reindex.ts
index e24f1d5..43919b9 100644
--- a/apps/cli/src/commands/reindex.ts
+++ b/apps/cli/src/commands/reindex.ts
@@ -1,6 +1,6 @@
import { join } from 'node:path';
-import { loadSettings, resolveDataDir } from '@cavemem/config';
-import { Storage } from '@cavemem/storage';
+import { loadSettings, resolveDataDir } from '@colony/config';
+import { Storage } from '@colony/storage';
import type { Command } from 'commander';
export function registerReindexCommand(program: Command): void {
diff --git a/apps/cli/src/commands/search.ts b/apps/cli/src/commands/search.ts
index 8e4d2a6..b892d3c 100644
--- a/apps/cli/src/commands/search.ts
+++ b/apps/cli/src/commands/search.ts
@@ -1,7 +1,7 @@
import { join } from 'node:path';
-import { loadSettings, resolveDataDir } from '@cavemem/config';
-import { MemoryStore } from '@cavemem/core';
-import { createEmbedder } from '@cavemem/embedding';
+import { loadSettings, resolveDataDir } from '@colony/config';
+import { MemoryStore } from '@colony/core';
+import { createEmbedder } from '@colony/embedding';
import type { Command } from 'commander';
import kleur from 'kleur';
diff --git a/apps/cli/src/commands/status.ts b/apps/cli/src/commands/status.ts
index f7ef6ba..0effa85 100644
--- a/apps/cli/src/commands/status.ts
+++ b/apps/cli/src/commands/status.ts
@@ -1,7 +1,7 @@
import { existsSync, readFileSync } from 'node:fs';
import { join } from 'node:path';
-import { loadSettings, resolveDataDir, settingsPath } from '@cavemem/config';
-import { Storage } from '@cavemem/storage';
+import { loadSettings, resolveDataDir, settingsPath } from '@colony/config';
+import { Storage } from '@colony/storage';
import type { Command } from 'commander';
import kleur from 'kleur';
@@ -55,14 +55,14 @@ function fmtAgo(ts: number | null | undefined): string {
export function registerStatusCommand(program: Command): void {
program
.command('status')
- .description('Show cavemem wiring, data, and worker state')
+ .description('Show colony wiring, data, and worker state')
.action(() => {
const sp = settingsPath();
const settings = loadSettings();
const dir = resolveDataDir(settings.dataDir);
const dbPath = join(dir, 'data.db');
- process.stdout.write(`${kleur.bold('cavemem status')}\n\n`);
+ process.stdout.write(`${kleur.bold('colony status')}\n\n`);
process.stdout.write(
`settings: ${sp} ${existsSync(sp) ? kleur.green('✓') : kleur.yellow('default')}\n`,
);
@@ -89,7 +89,7 @@ export function registerStatusCommand(program: Command): void {
.filter(([, v]) => v)
.map(([k]) => k);
process.stdout.write(
- `ides: ${enabled.length ? enabled.join(', ') : kleur.dim('none installed — try `cavemem install`')}\n`,
+ `ides: ${enabled.length ? enabled.join(', ') : kleur.dim('none installed — try `colony install`')}\n`,
);
// Embedding
@@ -112,7 +112,7 @@ export function registerStatusCommand(program: Command): void {
}
} else {
process.stdout.write(
- `backfill: ${kleur.dim('no worker state yet — run `cavemem start`')}\n`,
+ `backfill: ${kleur.dim('no worker state yet — run `colony start`')}\n`,
);
}
diff --git a/apps/cli/src/commands/uninstall.ts b/apps/cli/src/commands/uninstall.ts
index a867835..1cc5551 100644
--- a/apps/cli/src/commands/uninstall.ts
+++ b/apps/cli/src/commands/uninstall.ts
@@ -1,6 +1,6 @@
import { homedir } from 'node:os';
-import { loadSettings, resolveDataDir, saveSettings } from '@cavemem/config';
-import { type IdeName, getInstaller, installers } from '@cavemem/installers';
+import { loadSettings, resolveDataDir, saveSettings } from '@colony/config';
+import { type IdeName, getInstaller, installers } from '@colony/installers';
import type { Command } from 'commander';
import kleur from 'kleur';
import { resolveCliPath } from '../util/resolve.js';
diff --git a/apps/cli/src/commands/worker.ts b/apps/cli/src/commands/worker.ts
index 0d30299..f6374f7 100644
--- a/apps/cli/src/commands/worker.ts
+++ b/apps/cli/src/commands/worker.ts
@@ -1,7 +1,7 @@
import { spawn } from 'node:child_process';
import { existsSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';
import { join } from 'node:path';
-import { loadSettings, resolveDataDir } from '@cavemem/config';
+import { loadSettings, resolveDataDir } from '@colony/config';
import type { Command } from 'commander';
import kleur from 'kleur';
import { resolveCliPath } from '../util/resolve.js';
@@ -50,7 +50,7 @@ export function registerWorkerCommand(program: Command): void {
w.command('run')
.description('Run the worker in the foreground (internal)')
.action(async () => {
- const mod = await import('@cavemem/worker');
+ const mod = await import('@colony/worker');
await mod.start();
});
diff --git a/apps/cli/src/env.d.ts b/apps/cli/src/env.d.ts
index fa9bd5f..2fde0f7 100644
--- a/apps/cli/src/env.d.ts
+++ b/apps/cli/src/env.d.ts
@@ -1 +1 @@
-declare const __CAVEMEM_VERSION__: string;
+declare const __COLONY_VERSION__: string;
diff --git a/apps/cli/src/index.ts b/apps/cli/src/index.ts
index 0753aec..ba4731a 100644
--- a/apps/cli/src/index.ts
+++ b/apps/cli/src/index.ts
@@ -23,9 +23,9 @@ export function createProgram(): Command {
const program = new Command();
program
- .name('cavemem')
+ .name('colony')
.description('Cross-agent persistent memory with compressed storage.')
- .version(__CAVEMEM_VERSION__);
+ .version(__COLONY_VERSION__);
registerInstallCommand(program);
registerUninstallCommand(program);
@@ -58,7 +58,7 @@ if (isMainEntry()) {
createProgram()
.parseAsync(process.argv)
.catch((err) => {
- process.stderr.write(`cavemem error: ${err instanceof Error ? err.message : String(err)}\n`);
+ process.stderr.write(`colony error: ${err instanceof Error ? err.message : String(err)}\n`);
process.exit(1);
});
}
diff --git a/apps/cli/src/util/resolve.ts b/apps/cli/src/util/resolve.ts
index e9c99dd..b4e8ce3 100644
--- a/apps/cli/src/util/resolve.ts
+++ b/apps/cli/src/util/resolve.ts
@@ -1,12 +1,12 @@
import { realpathSync } from 'node:fs';
/**
- * Absolute path to the cavemem CLI binary. The installer writes this into
+ * Absolute path to the colony CLI binary. The installer writes this into
* IDE config files, so it must resolve correctly in both dev and installed modes.
*/
export function resolveCliPath(): string {
const argv1 = process.argv[1];
- if (!argv1) return 'cavemem';
+ if (!argv1) return 'colony';
try {
return realpathSync(argv1);
} catch {
diff --git a/apps/cli/tsup.config.ts b/apps/cli/tsup.config.ts
index b74f362..ef0adaf 100644
--- a/apps/cli/tsup.config.ts
+++ b/apps/cli/tsup.config.ts
@@ -17,10 +17,10 @@ export default defineConfig({
// shebang two lines down is invalid ESM and breaks dynamic imports with
// "Invalid or unexpected token". The shebang we need on the main entry is
// in src/index.ts itself.
- noExternal: [/^@cavemem\//],
- // @xenova/transformers is an optional peer of @cavemem/embedding — bundling
+ noExternal: [/^@colony\//],
+ // @xenova/transformers is an optional peer of @colony/embedding — bundling
// it drags 1.5 MB of ONNX runtime + sharp native binaries into the CLI dist.
// Keep it external so the CLI loads fast and installs without heavy native deps.
external: ['@xenova/transformers'],
- define: { __CAVEMEM_VERSION__: JSON.stringify(version) },
+ define: { __COLONY_VERSION__: JSON.stringify(version) },
});
diff --git a/apps/cli/vitest.config.ts b/apps/cli/vitest.config.ts
index 3c1de7d..d7fc372 100644
--- a/apps/cli/vitest.config.ts
+++ b/apps/cli/vitest.config.ts
@@ -7,6 +7,6 @@ const { version } = JSON.parse(readFileSync('./package.json', 'utf8')) as { vers
export default mergeConfig(
rootConfig,
defineConfig({
- define: { __CAVEMEM_VERSION__: JSON.stringify(version) },
+ define: { __COLONY_VERSION__: JSON.stringify(version) },
}),
);
diff --git a/apps/hivemind-demo/package.json b/apps/hivemind-demo/package.json
index f69f064..5f7e77a 100644
--- a/apps/hivemind-demo/package.json
+++ b/apps/hivemind-demo/package.json
@@ -1,12 +1,12 @@
{
- "name": "@cavemem/hivemind-demo",
+ "name": "@colony/hivemind-demo",
"version": "0.0.0",
"private": true,
"license": "MIT",
"type": "module",
"main": "./dist/index.js",
"bin": {
- "cavemem-hivemind-demo": "./dist/cli/index.js"
+ "colony-hivemind-demo": "./dist/cli/index.js"
},
"scripts": {
"build": "tsup src/index.ts src/cli/index.ts --format esm --dts --clean",
diff --git a/apps/hivemind-demo/src/agents/builder.ts b/apps/hivemind-demo/src/agents/builder.ts
index ac80c12..e3f285b 100644
--- a/apps/hivemind-demo/src/agents/builder.ts
+++ b/apps/hivemind-demo/src/agents/builder.ts
@@ -36,7 +36,9 @@ export class BuilderAgent implements Agent {
const research = findLatestArtifact(state, 'research')?.content;
const priorReview = findLatestArtifact(state, 'review')?.content;
const revisionNotes =
- input.attempt > 1 && priorReview ? priorReview.requiredFixes.map((issue) => `Address review feedback: ${issue}`) : [];
+ input.attempt > 1 && priorReview
+ ? priorReview.requiredFixes.map((issue) => `Address review feedback: ${issue}`)
+ : [];
const content: BuildArtifactContent = {
fileTree: [...BASE_FILE_TREE],
@@ -78,7 +80,11 @@ export class BuilderAgent implements Agent {
content,
},
markSubtasks: [
- { id: 'build', status: 'completed', note: `Builder attempt ${input.attempt} ready for review.` },
+ {
+ id: 'build',
+ status: 'completed',
+ note: `Builder attempt ${input.attempt} ready for review.`,
+ },
{ id: 'review', status: 'in_progress', note: 'Reviewing current build.' },
],
replaceBlockers: [],
diff --git a/apps/hivemind-demo/src/agents/researcher.ts b/apps/hivemind-demo/src/agents/researcher.ts
index b80d700..057643e 100644
--- a/apps/hivemind-demo/src/agents/researcher.ts
+++ b/apps/hivemind-demo/src/agents/researcher.ts
@@ -1,4 +1,10 @@
-import type { Agent, AgentInput, AgentResult, ResearchArtifactContent, RunState } from '../core/types.js';
+import type {
+ Agent,
+ AgentInput,
+ AgentResult,
+ ResearchArtifactContent,
+ RunState,
+} from '../core/types.js';
export class ResearcherAgent implements Agent {
readonly name = 'Researcher';
@@ -59,7 +65,11 @@ export class ResearcherAgent implements Agent {
content,
},
markSubtasks: [
- { id: 'research', status: 'completed', note: `Captured ${constraints.length} constraints.` },
+ {
+ id: 'research',
+ status: 'completed',
+ note: `Captured ${constraints.length} constraints.`,
+ },
{ id: 'build', status: 'in_progress', note: 'Research ready for builder.' },
],
replaceBlockers: [],
diff --git a/apps/hivemind-demo/src/agents/reviewer.ts b/apps/hivemind-demo/src/agents/reviewer.ts
index 546dc51..64cb9fe 100644
--- a/apps/hivemind-demo/src/agents/reviewer.ts
+++ b/apps/hivemind-demo/src/agents/reviewer.ts
@@ -71,7 +71,9 @@ export class ReviewerAgent implements Agent {
return {
status: approved ? 'completed' : 'blocked',
- summary: approved ? 'Reviewer approved builder output.' : `Reviewer found ${issues.length} gap(s).`,
+ summary: approved
+ ? 'Reviewer approved builder output.'
+ : `Reviewer found ${issues.length} gap(s).`,
details: approved ? strengths.slice(0, 3) : issues,
artifact: {
type: 'review',
diff --git a/apps/hivemind-demo/src/agents/verifier.ts b/apps/hivemind-demo/src/agents/verifier.ts
index bebc8da..e8375fc 100644
--- a/apps/hivemind-demo/src/agents/verifier.ts
+++ b/apps/hivemind-demo/src/agents/verifier.ts
@@ -105,7 +105,13 @@ export class VerifierAgent implements Agent {
finalResult,
runStatus: 'completed',
replaceBlockers: [],
- markSubtasks: [{ id: 'verify', status: 'completed', note: `Verified with ${state.checkpoints.length} checkpoint(s).` }],
+ markSubtasks: [
+ {
+ id: 'verify',
+ status: 'completed',
+ note: `Verified with ${state.checkpoints.length} checkpoint(s).`,
+ },
+ ],
};
}
}
diff --git a/apps/hivemind-demo/src/cli/index.ts b/apps/hivemind-demo/src/cli/index.ts
index b788a46..472354d 100644
--- a/apps/hivemind-demo/src/cli/index.ts
+++ b/apps/hivemind-demo/src/cli/index.ts
@@ -151,13 +151,15 @@ function readInteger(argv: string[], index: number, flag: string): number {
}
function printUsage(): void {
- console.log(`Usage: cavemem-hivemind-demo [options] ""`);
+ console.log(`Usage: colony-hivemind-demo [options] ""`);
console.log('');
console.log('Options:');
console.log(' --demo Run the built-in demo task');
console.log(' --data-dir Directory for persisted run state');
console.log(' --max-turns Maximum total agent turns (default: 10)');
- console.log(' --max-retries Builder retry budget after review failures (default: 1)');
+ console.log(
+ ' --max-retries Builder retry budget after review failures (default: 1)',
+ );
console.log(' --checkpoint-interval Create a checkpoint every N steps (default: 2)');
console.log(' --quiet Suppress per-step logs');
console.log(' --help, -h Show this usage text');
diff --git a/apps/hivemind-demo/src/core/orchestrator.ts b/apps/hivemind-demo/src/core/orchestrator.ts
index 2759c0a..b8d5d3d 100644
--- a/apps/hivemind-demo/src/core/orchestrator.ts
+++ b/apps/hivemind-demo/src/core/orchestrator.ts
@@ -5,7 +5,13 @@ import { ReviewerAgent } from '../agents/reviewer.js';
import { VerifierAgent } from '../agents/verifier.js';
import { createLogger } from '../utils/logger.js';
import { createCheckpoint, shouldCreateCheckpoint } from './checkpoint.js';
-import { appendCheckpoint, applyAgentResult, createInitialState, incrementRetryCount, RunStore } from './state.js';
+import {
+ RunStore,
+ appendCheckpoint,
+ applyAgentResult,
+ createInitialState,
+ incrementRetryCount,
+} from './state.js';
import type { Agent, AgentInput, AgentResult, OrchestratorOptions, RunState } from './types.js';
const DEFAULT_MAX_TURNS = 10;
@@ -43,8 +49,18 @@ export class HivemindOrchestrator {
return this.failForTurnBudget(state, store);
}
- state = this.runAgent(this.builder, { task, phase: 'build', attempt: state.retryCount + 1 }, state, store);
- state = this.runAgent(this.reviewer, { task, phase: 'review', attempt: state.retryCount + 1 }, state, store);
+ state = this.runAgent(
+ this.builder,
+ { task, phase: 'build', attempt: state.retryCount + 1 },
+ state,
+ store,
+ );
+ state = this.runAgent(
+ this.reviewer,
+ { task, phase: 'review', attempt: state.retryCount + 1 },
+ state,
+ store,
+ );
const decisionInput: AgentInput = {
task,
@@ -74,7 +90,12 @@ export class HivemindOrchestrator {
return this.failForTurnBudget(state, store);
}
- return this.runAgent(this.verifier, { task, phase: 'verify', attempt: state.retryCount + 1 }, state, store);
+ return this.runAgent(
+ this.verifier,
+ { task, phase: 'verify', attempt: state.retryCount + 1 },
+ state,
+ store,
+ );
}
private runAgent(agent: Agent, input: AgentInput, state: RunState, store: RunStore): RunState {
diff --git a/apps/hivemind-demo/src/core/state.ts b/apps/hivemind-demo/src/core/state.ts
index 642d76c..84b32f4 100644
--- a/apps/hivemind-demo/src/core/state.ts
+++ b/apps/hivemind-demo/src/core/state.ts
@@ -50,7 +50,9 @@ export function applyAgentResult(
? 'in_progress'
: state.status),
currentPlan: result.plan ? [...result.plan.steps] : [...state.currentPlan],
- subtasks: result.plan ? result.plan.subtasks.map(cloneSubtask) : state.subtasks.map(cloneSubtask),
+ subtasks: result.plan
+ ? result.plan.subtasks.map(cloneSubtask)
+ : state.subtasks.map(cloneSubtask),
completedSteps: [...state.completedSteps],
messages: [...state.messages],
artifacts: [...state.artifacts],
@@ -75,7 +77,14 @@ export function applyAgentResult(
}
if (result.artifact) {
- nextState.artifacts.push(createArtifact(result.artifact.type, result.artifact.label, result.artifact.content, nextState.artifacts.length + 1));
+ nextState.artifacts.push(
+ createArtifact(
+ result.artifact.type,
+ result.artifact.label,
+ result.artifact.content,
+ nextState.artifacts.length + 1,
+ ),
+ );
}
for (const update of result.markSubtasks ?? []) {
diff --git a/apps/hivemind-demo/test/orchestrator.test.ts b/apps/hivemind-demo/test/orchestrator.test.ts
index 49d442c..dec0b91 100644
--- a/apps/hivemind-demo/test/orchestrator.test.ts
+++ b/apps/hivemind-demo/test/orchestrator.test.ts
@@ -5,8 +5,8 @@ import { afterEach, describe, expect, it } from 'vitest';
import { ReviewerAgent } from '../src/agents/reviewer.js';
import { createCheckpoint } from '../src/core/checkpoint.js';
import { createInitialState } from '../src/core/state.js';
-import { HivemindOrchestrator } from '../src/index.js';
import type { BuildArtifactContent, OrchestratorOptions } from '../src/core/types.js';
+import { HivemindOrchestrator } from '../src/index.js';
const tempDirs: string[] = [];
const silentLogger = { info: () => {} };
@@ -69,10 +69,7 @@ describe('HivemindOrchestrator', () => {
});
const reviewer = new ReviewerAgent();
- const result = reviewer.run(
- { task: 'Ship a bounded MVP', phase: 'review', attempt: 1 },
- state,
- );
+ const result = reviewer.run({ task: 'Ship a bounded MVP', phase: 'review', attempt: 1 }, state);
expect(result.status).toBe('blocked');
expect(result.replaceBlockers).toContain('Test plan missing.');
@@ -109,7 +106,9 @@ describe('HivemindOrchestrator', () => {
expect(checkpoint.compactSummary).toContain('Goal: Tighten context handoffs');
expect(checkpoint.compactSummary).toContain('Done: Researcher captured constraints.');
expect(checkpoint.compactSummary).toContain('Current blocker: Awaiting verifier approval.');
- expect(checkpoint.compactSummary).toContain('Next batch: Review output for risks and missing edges');
+ expect(checkpoint.compactSummary).toContain(
+ 'Next batch: Review output for risks and missing edges',
+ );
});
});
diff --git a/apps/mcp-server/CHANGELOG.md b/apps/mcp-server/CHANGELOG.md
index 7581ea0..b9b24fd 100644
--- a/apps/mcp-server/CHANGELOG.md
+++ b/apps/mcp-server/CHANGELOG.md
@@ -1,4 +1,4 @@
-# @cavemem/mcp-server
+# @colony/mcp-server
## 0.2.0
@@ -8,10 +8,10 @@
**Embeddings (previously dead code) now work out of the box**
- - New `@cavemem/embedding` package exports `createEmbedder(settings)` with three providers: `local` (Transformers.js, default — `Xenova/all-MiniLM-L6-v2`, 384 dim), `ollama`, and `openai`. `@xenova/transformers` is an optional dependency: installs automatically with `npm install -g cavemem` on supported platforms, falls back gracefully otherwise.
+ - New `@colony/embedding` package exports `createEmbedder(settings)` with three providers: `local` (Transformers.js, default — `Xenova/all-MiniLM-L6-v2`, 384 dim), `ollama`, and `openai`. `@xenova/transformers` is an optional dependency: installs automatically with `npm install -g cavemem` on supported platforms, falls back gracefully otherwise.
- The worker now runs an embedding backfill loop: polls `observationsMissingEmbeddings`, embeds the expanded (human-readable) text, persists. On startup it drops rows whose model differs from settings so switching providers never pollutes cosine ranking.
- Storage gains a model/dim filter on `allEmbeddings()` plus `dropEmbeddingsWhereModelNot`, `countObservations`, `countEmbeddings`, and a model-scoped variant of `observationsMissingEmbeddings`.
- - The `Embedder` interface in `@cavemem/core` now exposes `model` and `dim` so the store can reject mismatched rows before cosine computation.
+ - The `Embedder` interface in `@colony/core` now exposes `model` and `dim` so the store can reject mismatched rows before cosine computation.
- Both the CLI `search` command and the MCP `search` tool instantiate the embedder lazily and pass it into `MemoryStore.search`. Semantic search is on by default; `cavemem search --no-semantic` bypasses it.
- Worker writes a `worker.state.json` snapshot after every batch so `cavemem status` can show "embedded 124 / 200 (62%)" without hitting HTTP.
@@ -25,7 +25,7 @@
- New `cavemem status` top-level command: single-pane dashboard showing settings path, data dir, DB counts, installed IDEs, embedding provider/model, backfill progress, worker pid and uptime.
- New `cavemem config show|get|set|open|path|reset` command backed by zod `.describe()` — the schema is self-documenting; no parallel docs to maintain.
- - New `settingsDocs()` export from `@cavemem/config` returns `[{path, type, default, description}]` for every field.
+ - New `settingsDocs()` export from `@colony/config` returns `[{path, type, default, description}]` for every field.
- `cavemem install` now prints a multi-line "what to try next" block explaining that there is no daemon to start, and surfaces the embedding model + weight-download cost.
- Settings schema gains `embedding.batchSize`, `embedding.autoStart`, and `embedding.idleShutdownMs` — every field now has a `.describe(...)` string.
@@ -42,7 +42,7 @@
- Updated dependencies [416957b]
- Updated dependencies [4af0d0d]
- - @cavemem/config@0.2.0
- - @cavemem/core@0.2.0
- - @cavemem/embedding@0.2.0
- - @cavemem/compress@0.2.0
+ - @colony/config@0.2.0
+ - @colony/core@0.2.0
+ - @colony/embedding@0.2.0
+ - @colony/compress@0.2.0
diff --git a/apps/mcp-server/package.json b/apps/mcp-server/package.json
index fa7ca65..b4a9d40 100644
--- a/apps/mcp-server/package.json
+++ b/apps/mcp-server/package.json
@@ -1,12 +1,12 @@
{
- "name": "@cavemem/mcp-server",
+ "name": "@colony/mcp-server",
"version": "0.2.0",
"license": "MIT",
"private": true,
"type": "module",
"main": "./dist/server.js",
"bin": {
- "cavemem-mcp": "./dist/server.js"
+ "colony-mcp": "./dist/server.js"
},
"scripts": {
"build": "tsup src/server.ts --format esm --dts --clean",
@@ -15,10 +15,10 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
- "@cavemem/compress": "workspace:*",
- "@cavemem/config": "workspace:*",
- "@cavemem/core": "workspace:*",
- "@cavemem/embedding": "workspace:*",
+ "@colony/compress": "workspace:*",
+ "@colony/config": "workspace:*",
+ "@colony/core": "workspace:*",
+ "@colony/embedding": "workspace:*",
"@modelcontextprotocol/sdk": "^1.0.0",
"zod": "^3.23.8"
},
diff --git a/apps/mcp-server/src/hivemind.ts b/apps/mcp-server/src/hivemind.ts
index 50e84c8..ba4d819 100644
--- a/apps/mcp-server/src/hivemind.ts
+++ b/apps/mcp-server/src/hivemind.ts
@@ -4,4 +4,4 @@ export {
type HivemindOptions,
type HivemindSession,
type HivemindSnapshot,
-} from '@cavemem/core';
+} from '@colony/core';
diff --git a/apps/mcp-server/src/server.ts b/apps/mcp-server/src/server.ts
index b61961c..0e48be5 100644
--- a/apps/mcp-server/src/server.ts
+++ b/apps/mcp-server/src/server.ts
@@ -2,7 +2,7 @@
import { realpathSync } from 'node:fs';
import { join } from 'node:path';
import { pathToFileURL } from 'node:url';
-import { type Settings, loadSettings, resolveDataDir } from '@cavemem/config';
+import { type Settings, loadSettings, resolveDataDir } from '@colony/config';
import {
type AgentCapabilities,
DEFAULT_CAPABILITIES,
@@ -17,8 +17,8 @@ import {
loadProfile,
readHivemind,
saveProfile,
-} from '@cavemem/core';
-import { createEmbedder } from '@cavemem/embedding';
+} from '@colony/core';
+import { createEmbedder } from '@colony/embedding';
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';
@@ -36,7 +36,7 @@ import { z } from 'zod';
*/
export function buildServer(store: MemoryStore, settings: Settings): McpServer {
const server = new McpServer({
- name: 'cavemem',
+ name: 'colony',
version: '0.1.0',
});
@@ -48,7 +48,7 @@ export function buildServer(store: MemoryStore, settings: Settings): McpServer {
embedder = await createEmbedder(settings, { log: () => {} });
} catch (err) {
process.stderr.write(
- `[cavemem mcp] embedder unavailable: ${err instanceof Error ? err.message : String(err)}\n`,
+ `[colony mcp] embedder unavailable: ${err instanceof Error ? err.message : String(err)}\n`,
);
embedder = null;
}
@@ -666,7 +666,7 @@ async function main(): Promise {
if (isMainEntry()) {
main().catch((err) => {
- process.stderr.write(`[cavemem mcp] fatal: ${String(err)}\n`);
+ process.stderr.write(`[colony mcp] fatal: ${String(err)}\n`);
process.exit(1);
});
}
diff --git a/apps/mcp-server/test/server.test.ts b/apps/mcp-server/test/server.test.ts
index 82c6ad6..e0fc109 100644
--- a/apps/mcp-server/test/server.test.ts
+++ b/apps/mcp-server/test/server.test.ts
@@ -1,8 +1,8 @@
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
-import { defaultSettings } from '@cavemem/config';
-import { MemoryStore } from '@cavemem/core';
+import { defaultSettings } from '@colony/config';
+import { MemoryStore } from '@colony/core';
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
@@ -43,7 +43,7 @@ afterEach(async () => {
});
describe('MCP server', () => {
- it('lists the cavemem tools', async () => {
+ it('lists the colony tools', async () => {
const { tools } = await client.listTools();
expect(tools.map((t) => t.name).sort()).toEqual([
'agent_get_profile',
diff --git a/apps/mcp-server/test/task-threads.test.ts b/apps/mcp-server/test/task-threads.test.ts
index c629f30..a434eef 100644
--- a/apps/mcp-server/test/task-threads.test.ts
+++ b/apps/mcp-server/test/task-threads.test.ts
@@ -1,8 +1,8 @@
import { mkdtempSync, rmSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
-import { defaultSettings } from '@cavemem/config';
-import { MemoryStore, TaskThread } from '@cavemem/core';
+import { defaultSettings } from '@colony/config';
+import { MemoryStore, TaskThread } from '@colony/core';
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
@@ -13,7 +13,7 @@ let store: MemoryStore;
let client: Client;
/**
- * Every cavemem tool returns `{ content: [{ type: 'text', text: JSON }] }`.
+ * Every colony tool returns `{ content: [{ type: 'text', text: JSON }] }`.
* Centralising the unwrap keeps the individual tests readable.
*/
async function call(name: string, args: Record): Promise {
diff --git a/apps/worker/CHANGELOG.md b/apps/worker/CHANGELOG.md
index 4522908..0eaa1cb 100644
--- a/apps/worker/CHANGELOG.md
+++ b/apps/worker/CHANGELOG.md
@@ -1,4 +1,4 @@
-# @cavemem/worker
+# @colony/worker
## 0.2.0
@@ -8,10 +8,10 @@
**Embeddings (previously dead code) now work out of the box**
- - New `@cavemem/embedding` package exports `createEmbedder(settings)` with three providers: `local` (Transformers.js, default — `Xenova/all-MiniLM-L6-v2`, 384 dim), `ollama`, and `openai`. `@xenova/transformers` is an optional dependency: installs automatically with `npm install -g cavemem` on supported platforms, falls back gracefully otherwise.
+ - New `@colony/embedding` package exports `createEmbedder(settings)` with three providers: `local` (Transformers.js, default — `Xenova/all-MiniLM-L6-v2`, 384 dim), `ollama`, and `openai`. `@xenova/transformers` is an optional dependency: installs automatically with `npm install -g cavemem` on supported platforms, falls back gracefully otherwise.
- The worker now runs an embedding backfill loop: polls `observationsMissingEmbeddings`, embeds the expanded (human-readable) text, persists. On startup it drops rows whose model differs from settings so switching providers never pollutes cosine ranking.
- Storage gains a model/dim filter on `allEmbeddings()` plus `dropEmbeddingsWhereModelNot`, `countObservations`, `countEmbeddings`, and a model-scoped variant of `observationsMissingEmbeddings`.
- - The `Embedder` interface in `@cavemem/core` now exposes `model` and `dim` so the store can reject mismatched rows before cosine computation.
+ - The `Embedder` interface in `@colony/core` now exposes `model` and `dim` so the store can reject mismatched rows before cosine computation.
- Both the CLI `search` command and the MCP `search` tool instantiate the embedder lazily and pass it into `MemoryStore.search`. Semantic search is on by default; `cavemem search --no-semantic` bypasses it.
- Worker writes a `worker.state.json` snapshot after every batch so `cavemem status` can show "embedded 124 / 200 (62%)" without hitting HTTP.
@@ -25,7 +25,7 @@
- New `cavemem status` top-level command: single-pane dashboard showing settings path, data dir, DB counts, installed IDEs, embedding provider/model, backfill progress, worker pid and uptime.
- New `cavemem config show|get|set|open|path|reset` command backed by zod `.describe()` — the schema is self-documenting; no parallel docs to maintain.
- - New `settingsDocs()` export from `@cavemem/config` returns `[{path, type, default, description}]` for every field.
+ - New `settingsDocs()` export from `@colony/config` returns `[{path, type, default, description}]` for every field.
- `cavemem install` now prints a multi-line "what to try next" block explaining that there is no daemon to start, and surfaces the embedding model + weight-download cost.
- Settings schema gains `embedding.batchSize`, `embedding.autoStart`, and `embedding.idleShutdownMs` — every field now has a `.describe(...)` string.
@@ -43,8 +43,8 @@
- Updated dependencies [416957b]
- Updated dependencies [99ca440]
- Updated dependencies [4af0d0d]
- - @cavemem/config@0.2.0
- - @cavemem/core@0.2.0
- - @cavemem/storage@0.2.0
- - @cavemem/embedding@0.2.0
- - @cavemem/compress@0.2.0
+ - @colony/config@0.2.0
+ - @colony/core@0.2.0
+ - @colony/storage@0.2.0
+ - @colony/embedding@0.2.0
+ - @colony/compress@0.2.0
diff --git a/apps/worker/package.json b/apps/worker/package.json
index 561965d..6306a67 100644
--- a/apps/worker/package.json
+++ b/apps/worker/package.json
@@ -1,12 +1,12 @@
{
- "name": "@cavemem/worker",
+ "name": "@colony/worker",
"version": "0.2.0",
"license": "MIT",
"private": true,
"type": "module",
"main": "./dist/server.js",
"bin": {
- "cavemem-worker": "./dist/server.js"
+ "colony-worker": "./dist/server.js"
},
"scripts": {
"build": "tsup src/server.ts --format esm --dts --clean",
@@ -15,11 +15,11 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
- "@cavemem/compress": "workspace:*",
- "@cavemem/config": "workspace:*",
- "@cavemem/core": "workspace:*",
- "@cavemem/embedding": "workspace:*",
- "@cavemem/storage": "workspace:*",
+ "@colony/compress": "workspace:*",
+ "@colony/config": "workspace:*",
+ "@colony/core": "workspace:*",
+ "@colony/embedding": "workspace:*",
+ "@colony/storage": "workspace:*",
"hono": "^4.6.10",
"@hono/node-server": "^1.13.7"
},
diff --git a/apps/worker/src/embed-loop.ts b/apps/worker/src/embed-loop.ts
index 94af358..04f0edc 100644
--- a/apps/worker/src/embed-loop.ts
+++ b/apps/worker/src/embed-loop.ts
@@ -1,9 +1,9 @@
import { writeFileSync } from 'node:fs';
import { join } from 'node:path';
-import { expand } from '@cavemem/compress';
-import type { Settings } from '@cavemem/config';
-import { resolveDataDir } from '@cavemem/config';
-import type { Embedder, MemoryStore } from '@cavemem/core';
+import { expand } from '@colony/compress';
+import type { Settings } from '@colony/config';
+import { resolveDataDir } from '@colony/config';
+import type { Embedder, MemoryStore } from '@colony/core';
export interface EmbedLoopState {
provider: string;
@@ -35,7 +35,7 @@ export function stateFilePath(settings: Settings): string {
/**
* Run the embedding backfill loop in-process. Writes a snapshot JSON after
- * every batch so `cavemem status` can read it without HTTP.
+ * every batch so `colony status` can read it without HTTP.
*
* Lifecycle:
* 1. Drop embeddings rows that don't match the current model/dim.
@@ -62,7 +62,7 @@ export function startEmbedLoop(opts: {
const dropped = store.storage.dropEmbeddingsWhereModelNot(embedder.model);
if (dropped > 0) {
process.stderr.write(
- `[cavemem worker] dropped ${dropped} stale embeddings (model switched to ${embedder.model})\n`,
+ `[colony worker] dropped ${dropped} stale embeddings (model switched to ${embedder.model})\n`,
);
}
@@ -106,7 +106,7 @@ export function startEmbedLoop(opts: {
store.storage.putEmbedding(row.id, embedder.model, vec);
} catch (err) {
state.lastError = err instanceof Error ? err.message : String(err);
- process.stderr.write(`[cavemem worker] embed error row=${row.id}: ${state.lastError}\n`);
+ process.stderr.write(`[colony worker] embed error row=${row.id}: ${state.lastError}\n`);
// Don't re-attempt forever — insert a zero vector marker? No, skip this batch
// and retry on next iteration. If the error is persistent, user will see it in status.
break;
@@ -136,7 +136,7 @@ export function startEmbedLoop(opts: {
const noTraffic = now - state.lastHttpAt;
if (noWork > idleShutdownMs && noTraffic > idleShutdownMs) {
process.stderr.write(
- `[cavemem worker] idle ${Math.round(noWork / 1000)}s + no traffic ${Math.round(
+ `[colony worker] idle ${Math.round(noWork / 1000)}s + no traffic ${Math.round(
noTraffic / 1000,
)}s — exiting\n`,
);
diff --git a/apps/worker/src/server.ts b/apps/worker/src/server.ts
index 4235898..2b2e644 100644
--- a/apps/worker/src/server.ts
+++ b/apps/worker/src/server.ts
@@ -2,10 +2,10 @@
import { existsSync, readFileSync, realpathSync, unlinkSync, writeFileSync } from 'node:fs';
import { join } from 'node:path';
import { pathToFileURL } from 'node:url';
-import { expand } from '@cavemem/compress';
-import { type Settings, loadSettings, resolveDataDir } from '@cavemem/config';
-import { type HivemindOptions, MemoryStore, readHivemind } from '@cavemem/core';
-import { createEmbedder } from '@cavemem/embedding';
+import { expand } from '@colony/compress';
+import { type Settings, loadSettings, resolveDataDir } from '@colony/config';
+import { type HivemindOptions, MemoryStore, readHivemind } from '@colony/core';
+import { createEmbedder } from '@colony/embedding';
import { serve } from '@hono/node-server';
import { Hono } from 'hono';
import { type EmbedLoopHandle, startEmbedLoop, stateFilePath } from './embed-loop.js';
@@ -130,7 +130,7 @@ export async function start(): Promise {
});
} catch (err) {
process.stderr.write(
- `[cavemem worker] embedder unavailable: ${err instanceof Error ? err.message : String(err)}\n`,
+ `[colony worker] embedder unavailable: ${err instanceof Error ? err.message : String(err)}\n`,
);
}
@@ -144,7 +144,7 @@ export async function start(): Promise {
},
});
} else {
- // Still write a minimal state file so `cavemem status` has something to show.
+ // Still write a minimal state file so `colony status` has something to show.
writeFileSync(
stateFilePath(settings),
`${JSON.stringify(
@@ -170,13 +170,13 @@ export async function start(): Promise {
const app = buildApp(store, loop);
servers.push(serve({ fetch: app.fetch, port: settings.workerPort, hostname: '127.0.0.1' }));
process.stderr.write(
- `[cavemem worker] listening on http://127.0.0.1:${settings.workerPort} (pid ${process.pid})\n`,
+ `[colony worker] listening on http://127.0.0.1:${settings.workerPort} (pid ${process.pid})\n`,
);
}
if (isMainEntry()) {
start().catch((err) => {
- process.stderr.write(`[cavemem worker] fatal: ${String(err)}\n`);
+ process.stderr.write(`[colony worker] fatal: ${String(err)}\n`);
process.exit(1);
});
}
diff --git a/apps/worker/src/viewer.ts b/apps/worker/src/viewer.ts
index a3729bd..6bc7396 100644
--- a/apps/worker/src/viewer.ts
+++ b/apps/worker/src/viewer.ts
@@ -1,5 +1,5 @@
-import type { HivemindSession, HivemindSnapshot } from '@cavemem/core';
-import type { SessionRow } from '@cavemem/storage';
+import type { HivemindSession, HivemindSnapshot } from '@colony/core';
+import type { SessionRow } from '@colony/storage';
const style = `
body { font: 14px/1.5 -apple-system, system-ui, sans-serif; margin: 0; background: #0b0d10; color: #e6e6e6; }
diff --git a/apps/worker/test/embed-loop.test.ts b/apps/worker/test/embed-loop.test.ts
index f04ab32..600e0fb 100644
--- a/apps/worker/test/embed-loop.test.ts
+++ b/apps/worker/test/embed-loop.test.ts
@@ -1,8 +1,8 @@
import { existsSync, mkdtempSync, readFileSync, rmSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
-import { SettingsSchema } from '@cavemem/config';
-import { type Embedder, MemoryStore } from '@cavemem/core';
+import { SettingsSchema } from '@colony/config';
+import { type Embedder, MemoryStore } from '@colony/core';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { startEmbedLoop, stateFilePath } from '../src/embed-loop.js';
diff --git a/apps/worker/test/server.test.ts b/apps/worker/test/server.test.ts
index 307c291..97dabc8 100644
--- a/apps/worker/test/server.test.ts
+++ b/apps/worker/test/server.test.ts
@@ -1,8 +1,8 @@
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
-import { defaultSettings } from '@cavemem/config';
-import { MemoryStore } from '@cavemem/core';
+import { defaultSettings } from '@colony/config';
+import { MemoryStore } from '@colony/core';
import type { Hono } from 'hono';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { buildApp } from '../src/server.js';
diff --git a/docs/architecture.md b/docs/architecture.md
index 292d9d6..cf231ef 100644
--- a/docs/architecture.md
+++ b/docs/architecture.md
@@ -33,6 +33,6 @@ Browser ── HTTP ──▶ worker (Hono) ─┘
## Invariants
- Only `MemoryStore` may write observations.
-- Only `@cavemem/storage` may open the database.
+- Only `@colony/storage` may open the database.
- Hooks do no I/O beyond the `MemoryStore` call.
- Worker binds to loopback only.
diff --git a/docs/compression.md b/docs/compression.md
index 6e8950f..4f8db67 100644
--- a/docs/compression.md
+++ b/docs/compression.md
@@ -1,6 +1,6 @@
# Compression spec
-cavemem compresses prose deterministically and offline. The engine never invokes a model. Its contract is:
+colony compresses prose deterministically and offline. The engine never invokes a model. Its contract is:
1. **Deterministic.** `compress(x)` always returns the same output for the same input and intensity.
2. **Technical tokens are preserved byte-for-byte.** The tokenizer identifies code, URLs, paths, commands, version numbers, dates, numeric literals, and identifier-like tokens. These segments are held out of every transformation.
@@ -55,5 +55,5 @@ input → tokenize → [preserved | prose] → transform prose → join → outp
1. Edit `packages/compress/src/lexicon.json`.
2. Add a fixture under `packages/compress/test/fixtures/` demonstrating the new rule and its round-trip.
-3. Run `pnpm --filter @cavemem/compress test`.
+3. Run `pnpm --filter @colony/compress test`.
4. Update benchmark numbers in `evals/` if the aggregate savings shifted.
diff --git a/docs/development.md b/docs/development.md
index 1eae5a9..478e64f 100644
--- a/docs/development.md
+++ b/docs/development.md
@@ -16,13 +16,13 @@ Link the CLI for local use:
```bash
cd apps/cli && pnpm link --global
-cavemem --help
+colony --help
```
## Run against a scratch data dir
```bash
-export CAVEMEM_HOME=$PWD/.cavemem-dev
+export COLONY_HOME=$PWD/.colony-dev
pnpm dev
```
diff --git a/docs/mcp.md b/docs/mcp.md
index 544559b..27d56f8 100644
--- a/docs/mcp.md
+++ b/docs/mcp.md
@@ -1,6 +1,6 @@
# MCP tools
-cavemem exposes MCP tools over a stdio server. IDE installers register that server as `colony`, so agent tool calls appear under the `colony` namespace. The design goal is **progressive disclosure**: hits are compact until the agent asks for more.
+colony exposes MCP tools over a stdio server. IDE installers register that server as `colony`, so agent tool calls appear under the `colony` namespace. The design goal is **progressive disclosure**: hits are compact until the agent asks for more.
The recommended workflow is a three-layer pattern:
@@ -107,7 +107,7 @@ Returns:
Inputs:
- `repo_root`: one workspace root to inspect. Defaults to the MCP server process cwd.
-- `repo_roots`: multiple workspace roots to inspect. Also configurable with `CAVEMEM_HIVEMIND_REPO_ROOTS` separated by the platform path delimiter.
+- `repo_roots`: multiple workspace roots to inspect. Also configurable with `COLONY_HIVEMIND_REPO_ROOTS` separated by the platform path delimiter.
- `include_stale`: include dead active-session records. Defaults to `false`.
- `limit`: maximum sessions returned, capped at 100.
diff --git a/docs/proposal-task-threads.md b/docs/proposal-task-threads.md
index 114d2f9..a630615 100644
--- a/docs/proposal-task-threads.md
+++ b/docs/proposal-task-threads.md
@@ -129,7 +129,7 @@ Over time, this produces the habit: agents start calling `claim_file` before edi
- Auto-join on `SessionStart`
- Turn-boundary new-message injection in `UserPromptSubmit`
-Impact: converts the hivemind from a passive shared notebook into an active collaboration substrate. Roughly 500 lines of code spread across `@cavemem/core`, `@cavemem/storage`, `@cavemem/hooks`, and `@cavemem/mcp-server`.
+Impact: converts the hivemind from a passive shared notebook into an active collaboration substrate. Roughly 500 lines of code spread across `@colony/core`, `@colony/storage`, `@colony/hooks`, and `@colony/mcp-server`.
### v0.4
diff --git a/evals/CHANGELOG.md b/evals/CHANGELOG.md
index 80422f6..be7bd38 100644
--- a/evals/CHANGELOG.md
+++ b/evals/CHANGELOG.md
@@ -1,8 +1,8 @@
-# @cavemem/evals
+# @colony/evals
## 0.2.0
### Patch Changes
- Updated dependencies [4af0d0d]
- - @cavemem/compress@0.2.0
+ - @colony/compress@0.2.0
diff --git a/evals/package.json b/evals/package.json
index 32533bf..9bb372b 100644
--- a/evals/package.json
+++ b/evals/package.json
@@ -1,5 +1,5 @@
{
- "name": "@cavemem/evals",
+ "name": "@colony/evals",
"version": "0.2.0",
"private": true,
"type": "module",
@@ -9,7 +9,7 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
- "@cavemem/compress": "workspace:*"
+ "@colony/compress": "workspace:*"
},
"devDependencies": {
"tsx": "^4.19.2",
diff --git a/evals/src/bench.ts b/evals/src/bench.ts
index 9f7564a..77ea081 100644
--- a/evals/src/bench.ts
+++ b/evals/src/bench.ts
@@ -1,6 +1,6 @@
import { readFileSync, readdirSync } from 'node:fs';
import { join } from 'node:path';
-import { compress, countTokens } from '@cavemem/compress';
+import { compress, countTokens } from '@colony/compress';
const corpusDir = join(import.meta.dirname, '..', 'corpus');
const files = readdirSync(corpusDir).filter((f) => f.endsWith('.md'));
diff --git a/examples/settings.example.json b/examples/settings.example.json
index c0a1ede..44c7378 100644
--- a/examples/settings.example.json
+++ b/examples/settings.example.json
@@ -1,5 +1,5 @@
{
- "dataDir": "~/.cavemem",
+ "dataDir": "~/.colony",
"workerPort": 37777,
"logLevel": "info",
"compression": {
diff --git a/hooks-scripts/post-tool-use.sh b/hooks-scripts/post-tool-use.sh
index a7d45b0..e30c33d 100755
--- a/hooks-scripts/post-tool-use.sh
+++ b/hooks-scripts/post-tool-use.sh
@@ -1,2 +1,2 @@
#!/usr/bin/env bash
-exec cavemem hook run post-tool-use
+exec colony hook run post-tool-use
diff --git a/hooks-scripts/session-end.sh b/hooks-scripts/session-end.sh
index d5cd83b..cb0f609 100755
--- a/hooks-scripts/session-end.sh
+++ b/hooks-scripts/session-end.sh
@@ -1,2 +1,2 @@
#!/usr/bin/env bash
-exec cavemem hook run session-end
+exec colony hook run session-end
diff --git a/hooks-scripts/session-start.sh b/hooks-scripts/session-start.sh
index bcf45c2..0e050fe 100755
--- a/hooks-scripts/session-start.sh
+++ b/hooks-scripts/session-start.sh
@@ -1,3 +1,3 @@
#!/usr/bin/env bash
# Portable stub for the SessionStart hook. Pipes the JSON event into the CLI.
-exec cavemem hook run session-start
+exec colony hook run session-start
diff --git a/hooks-scripts/stop.sh b/hooks-scripts/stop.sh
index d5a368a..0860c4c 100755
--- a/hooks-scripts/stop.sh
+++ b/hooks-scripts/stop.sh
@@ -1,2 +1,2 @@
#!/usr/bin/env bash
-exec cavemem hook run stop
+exec colony hook run stop
diff --git a/hooks-scripts/user-prompt-submit.sh b/hooks-scripts/user-prompt-submit.sh
index 30be38c..196742a 100755
--- a/hooks-scripts/user-prompt-submit.sh
+++ b/hooks-scripts/user-prompt-submit.sh
@@ -1,2 +1,2 @@
#!/usr/bin/env bash
-exec cavemem hook run user-prompt-submit
+exec colony hook run user-prompt-submit
diff --git a/package.json b/package.json
index 131503e..5a357c4 100644
--- a/package.json
+++ b/package.json
@@ -1,17 +1,17 @@
{
- "name": "cavemem-monorepo",
+ "name": "colony-monorepo",
"version": "0.0.0",
"private": true,
- "description": "Cross-agent persistent memory with compressed storage.",
+ "description": "Local-first memory and coordination for AI coding agents.",
"license": "MIT",
- "author": "Julius Brussee",
- "homepage": "https://github.com/JuliusBrussee/cavemem",
+ "author": "Imdeadpool",
+ "homepage": "https://github.com/recodeee/colony",
"repository": {
"type": "git",
- "url": "https://github.com/JuliusBrussee/cavemem.git"
+ "url": "https://github.com/recodeee/colony.git"
},
"bugs": {
- "url": "https://github.com/JuliusBrussee/cavemem/issues"
+ "url": "https://github.com/recodeee/colony/issues"
},
"engines": {
"node": ">=20.0.0"
@@ -19,7 +19,7 @@
"packageManager": "pnpm@9.12.0",
"scripts": {
"build": "pnpm -r --filter \"./packages/*\" --filter \"./apps/*\" build",
- "dev": "pnpm --filter cavemem dev",
+ "dev": "pnpm --filter colony dev",
"test": "pnpm -r test",
"typecheck": "pnpm -r typecheck",
"lint": "biome check .",
diff --git a/packages/compress/CHANGELOG.md b/packages/compress/CHANGELOG.md
index a70a95e..32df923 100644
--- a/packages/compress/CHANGELOG.md
+++ b/packages/compress/CHANGELOG.md
@@ -1,4 +1,4 @@
-# @cavemem/compress
+# @colony/compress
## 0.2.0
@@ -11,8 +11,8 @@
- Fix a compression bug where `collapseWhitespace` would eat the single space between prose and preserved tokens (paths, inline code, URLs), producing unreadable output like `at/tmp/foo.txt`. Boundary spacing is now preserved on compress and round-tripped through expand.
- Fix `Storage.timeline(sessionId, aroundId, limit)` — the previous single-UNION query let the "after" half swallow the whole window. Replaced with two bounded queries merged in JS so both halves are respected.
- Remove a double `expand()` call in the MCP `get_observations` tool; expansion now happens exactly once inside `MemoryStore`.
- - `runHook()` now accepts an injected `MemoryStore` so tests (and other integrations) can avoid touching the user's real `~/.cavemem` data directory.
+ - `runHook()` now accepts an injected `MemoryStore` so tests (and other integrations) can avoid touching the user's real `~/.colony` data directory.
- Test ecosystem: brand-new suites for `@cavemem/hooks` (runner + all 5 handlers + hot-path budget check), `@cavemem/installers` (claude-code idempotency, settings preservation, cursor install/uninstall, registry, deepMerge), `@cavemem/mcp-server` (InMemory MCP client hitting every tool and asserting the progressive-disclosure shape), `@cavemem/worker` (Hono `app.request()` integration tests for every HTTP route), and the `cavemem` CLI (command registration smoke test). Total tests: 22 → 54.
+ Test ecosystem: brand-new suites for `@colony/hooks` (runner + all 5 handlers + hot-path budget check), `@colony/installers` (claude-code idempotency, settings preservation, cursor install/uninstall, registry, deepMerge), `@colony/mcp-server` (InMemory MCP client hitting every tool and asserting the progressive-disclosure shape), `@colony/worker` (Hono `app.request()` integration tests for every HTTP route), and the `cavemem` CLI (command registration smoke test). Total tests: 22 → 54.
None of the new test directories are shipped — every published package keeps its `files` allowlist pointed at `dist` only.
diff --git a/packages/compress/package.json b/packages/compress/package.json
index 852518d..a6d8d09 100644
--- a/packages/compress/package.json
+++ b/packages/compress/package.json
@@ -1,5 +1,5 @@
{
- "name": "@cavemem/compress",
+ "name": "@colony/compress",
"version": "0.2.0",
"license": "MIT",
"type": "module",
diff --git a/packages/config/CHANGELOG.md b/packages/config/CHANGELOG.md
index 59ded91..4d720a7 100644
--- a/packages/config/CHANGELOG.md
+++ b/packages/config/CHANGELOG.md
@@ -1,4 +1,4 @@
-# @cavemem/config
+# @colony/config
## 0.2.0
@@ -8,10 +8,10 @@
**Embeddings (previously dead code) now work out of the box**
- - New `@cavemem/embedding` package exports `createEmbedder(settings)` with three providers: `local` (Transformers.js, default — `Xenova/all-MiniLM-L6-v2`, 384 dim), `ollama`, and `openai`. `@xenova/transformers` is an optional dependency: installs automatically with `npm install -g cavemem` on supported platforms, falls back gracefully otherwise.
+ - New `@colony/embedding` package exports `createEmbedder(settings)` with three providers: `local` (Transformers.js, default — `Xenova/all-MiniLM-L6-v2`, 384 dim), `ollama`, and `openai`. `@xenova/transformers` is an optional dependency: installs automatically with `npm install -g cavemem` on supported platforms, falls back gracefully otherwise.
- The worker now runs an embedding backfill loop: polls `observationsMissingEmbeddings`, embeds the expanded (human-readable) text, persists. On startup it drops rows whose model differs from settings so switching providers never pollutes cosine ranking.
- Storage gains a model/dim filter on `allEmbeddings()` plus `dropEmbeddingsWhereModelNot`, `countObservations`, `countEmbeddings`, and a model-scoped variant of `observationsMissingEmbeddings`.
- - The `Embedder` interface in `@cavemem/core` now exposes `model` and `dim` so the store can reject mismatched rows before cosine computation.
+ - The `Embedder` interface in `@colony/core` now exposes `model` and `dim` so the store can reject mismatched rows before cosine computation.
- Both the CLI `search` command and the MCP `search` tool instantiate the embedder lazily and pass it into `MemoryStore.search`. Semantic search is on by default; `cavemem search --no-semantic` bypasses it.
- Worker writes a `worker.state.json` snapshot after every batch so `cavemem status` can show "embedded 124 / 200 (62%)" without hitting HTTP.
@@ -25,7 +25,7 @@
- New `cavemem status` top-level command: single-pane dashboard showing settings path, data dir, DB counts, installed IDEs, embedding provider/model, backfill progress, worker pid and uptime.
- New `cavemem config show|get|set|open|path|reset` command backed by zod `.describe()` — the schema is self-documenting; no parallel docs to maintain.
- - New `settingsDocs()` export from `@cavemem/config` returns `[{path, type, default, description}]` for every field.
+ - New `settingsDocs()` export from `@colony/config` returns `[{path, type, default, description}]` for every field.
- `cavemem install` now prints a multi-line "what to try next" block explaining that there is no daemon to start, and surfaces the embedding model + weight-download cost.
- Settings schema gains `embedding.batchSize`, `embedding.autoStart`, and `embedding.idleShutdownMs` — every field now has a `.describe(...)` string.
diff --git a/packages/config/package.json b/packages/config/package.json
index 967ca49..901da1c 100644
--- a/packages/config/package.json
+++ b/packages/config/package.json
@@ -1,5 +1,5 @@
{
- "name": "@cavemem/config",
+ "name": "@colony/config",
"version": "0.2.0",
"license": "MIT",
"type": "module",
diff --git a/packages/config/src/docs.ts b/packages/config/src/docs.ts
index 26f3f43..353bb24 100644
--- a/packages/config/src/docs.ts
+++ b/packages/config/src/docs.ts
@@ -14,7 +14,7 @@ export interface SettingDoc {
/**
* Walk the settings zod schema and produce a flat list of documented fields.
- * Powers `cavemem config show` and in-terminal help so settings are
+ * Powers `colony config show` and in-terminal help so settings are
* self-documenting — one source of truth, no parallel docs to drift.
*/
export function settingsDocs(): SettingDoc[] {
diff --git a/packages/config/src/loader.ts b/packages/config/src/loader.ts
index 02c7f8d..94e61a1 100644
--- a/packages/config/src/loader.ts
+++ b/packages/config/src/loader.ts
@@ -4,21 +4,28 @@ import { dirname, join, resolve } from 'node:path';
import { defaultSettings } from './defaults.js';
import { type Settings, SettingsSchema } from './schema.js';
-const DEFAULT_DIR = '.cavemem';
+const DEFAULT_DIR = '.colony';
export function resolveDataDir(raw: string): string {
if (raw.startsWith('~')) return join(homedir(), raw.slice(1).replace(/^\/+/, ''));
return resolve(raw);
}
+function defaultDataDir(): string {
+ return process.env.COLONY_HOME ?? process.env.CAVEMEM_HOME ?? join(homedir(), DEFAULT_DIR);
+}
+
export function settingsPath(dataDir?: string): string {
- const dir = resolveDataDir(dataDir ?? join(homedir(), DEFAULT_DIR));
+ const dir = resolveDataDir(dataDir ?? defaultDataDir());
return join(dir, 'settings.json');
}
export function loadSettings(path?: string): Settings {
const target = path ?? settingsPath();
- if (!existsSync(target)) return defaultSettings;
+ if (!existsSync(target)) {
+ const envDataDir = process.env.COLONY_HOME ?? process.env.CAVEMEM_HOME;
+ return envDataDir ? { ...defaultSettings, dataDir: envDataDir } : defaultSettings;
+ }
try {
const raw = JSON.parse(readFileSync(target, 'utf8'));
return SettingsSchema.parse(raw);
diff --git a/packages/config/src/schema.ts b/packages/config/src/schema.ts
index be8e0de..e18a0ec 100644
--- a/packages/config/src/schema.ts
+++ b/packages/config/src/schema.ts
@@ -10,8 +10,8 @@ export const SettingsSchema = z
.object({
dataDir: z
.string()
- .default('~/.cavemem')
- .describe('Where cavemem stores its SQLite database, models, pidfile, and logs.'),
+ .default('~/.colony')
+ .describe('Where colony stores its SQLite database, models, pidfile, and logs.'),
workerPort: z
.number()
.int()
@@ -109,7 +109,7 @@ export const SettingsSchema = z
ides: z
.record(z.string(), z.boolean())
.default({})
- .describe('Installed IDE integrations (set by `cavemem install`).'),
+ .describe('Installed IDE integrations (set by `colony install`).'),
})
.strict();
diff --git a/packages/config/test/schema.test.ts b/packages/config/test/schema.test.ts
index 1efe9db..158d9f8 100644
--- a/packages/config/test/schema.test.ts
+++ b/packages/config/test/schema.test.ts
@@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest';
-import { SettingsSchema, defaultSettings } from '../src/index.js';
+import { SettingsSchema, defaultSettings, loadSettings, settingsPath } from '../src/index.js';
describe('SettingsSchema', () => {
it('parses empty object into defaults', () => {
@@ -16,4 +16,16 @@ describe('SettingsSchema', () => {
expect(defaultSettings.workerPort).toBe(37777);
expect(defaultSettings.embedding.provider).toBe('local');
});
+
+ it('uses COLONY_HOME for default settings location and data dir', () => {
+ const original = process.env.COLONY_HOME;
+ process.env.COLONY_HOME = '/tmp/colony-test-home';
+ try {
+ expect(settingsPath()).toBe('/tmp/colony-test-home/settings.json');
+ expect(loadSettings().dataDir).toBe('/tmp/colony-test-home');
+ } finally {
+ if (original === undefined) delete process.env.COLONY_HOME;
+ else process.env.COLONY_HOME = original;
+ }
+ });
});
diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md
index 934ec5a..225c43d 100644
--- a/packages/core/CHANGELOG.md
+++ b/packages/core/CHANGELOG.md
@@ -1,4 +1,4 @@
-# @cavemem/core
+# @colony/core
## 0.2.0
@@ -8,10 +8,10 @@
**Embeddings (previously dead code) now work out of the box**
- - New `@cavemem/embedding` package exports `createEmbedder(settings)` with three providers: `local` (Transformers.js, default — `Xenova/all-MiniLM-L6-v2`, 384 dim), `ollama`, and `openai`. `@xenova/transformers` is an optional dependency: installs automatically with `npm install -g cavemem` on supported platforms, falls back gracefully otherwise.
+ - New `@colony/embedding` package exports `createEmbedder(settings)` with three providers: `local` (Transformers.js, default — `Xenova/all-MiniLM-L6-v2`, 384 dim), `ollama`, and `openai`. `@xenova/transformers` is an optional dependency: installs automatically with `npm install -g cavemem` on supported platforms, falls back gracefully otherwise.
- The worker now runs an embedding backfill loop: polls `observationsMissingEmbeddings`, embeds the expanded (human-readable) text, persists. On startup it drops rows whose model differs from settings so switching providers never pollutes cosine ranking.
- Storage gains a model/dim filter on `allEmbeddings()` plus `dropEmbeddingsWhereModelNot`, `countObservations`, `countEmbeddings`, and a model-scoped variant of `observationsMissingEmbeddings`.
- - The `Embedder` interface in `@cavemem/core` now exposes `model` and `dim` so the store can reject mismatched rows before cosine computation.
+ - The `Embedder` interface in `@colony/core` now exposes `model` and `dim` so the store can reject mismatched rows before cosine computation.
- Both the CLI `search` command and the MCP `search` tool instantiate the embedder lazily and pass it into `MemoryStore.search`. Semantic search is on by default; `cavemem search --no-semantic` bypasses it.
- Worker writes a `worker.state.json` snapshot after every batch so `cavemem status` can show "embedded 124 / 200 (62%)" without hitting HTTP.
@@ -25,7 +25,7 @@
- New `cavemem status` top-level command: single-pane dashboard showing settings path, data dir, DB counts, installed IDEs, embedding provider/model, backfill progress, worker pid and uptime.
- New `cavemem config show|get|set|open|path|reset` command backed by zod `.describe()` — the schema is self-documenting; no parallel docs to maintain.
- - New `settingsDocs()` export from `@cavemem/config` returns `[{path, type, default, description}]` for every field.
+ - New `settingsDocs()` export from `@colony/config` returns `[{path, type, default, description}]` for every field.
- `cavemem install` now prints a multi-line "what to try next" block explaining that there is no daemon to start, and surfaces the embedding model + weight-download cost.
- Settings schema gains `embedding.batchSize`, `embedding.autoStart`, and `embedding.idleShutdownMs` — every field now has a `.describe(...)` string.
@@ -43,6 +43,6 @@
- Updated dependencies [416957b]
- Updated dependencies [99ca440]
- Updated dependencies [4af0d0d]
- - @cavemem/config@0.2.0
- - @cavemem/storage@0.2.0
- - @cavemem/compress@0.2.0
+ - @colony/config@0.2.0
+ - @colony/storage@0.2.0
+ - @colony/compress@0.2.0
diff --git a/packages/core/package.json b/packages/core/package.json
index b2027f7..c97b8b7 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -1,5 +1,5 @@
{
- "name": "@cavemem/core",
+ "name": "@colony/core",
"version": "0.2.0",
"license": "MIT",
"type": "module",
@@ -19,9 +19,9 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
- "@cavemem/compress": "workspace:*",
- "@cavemem/config": "workspace:*",
- "@cavemem/storage": "workspace:*"
+ "@colony/compress": "workspace:*",
+ "@colony/config": "workspace:*",
+ "@colony/storage": "workspace:*"
},
"devDependencies": {
"tsup": "^8.3.5",
diff --git a/packages/core/src/hivemind.ts b/packages/core/src/hivemind.ts
index 478be33..3a2971c 100644
--- a/packages/core/src/hivemind.ts
+++ b/packages/core/src/hivemind.ts
@@ -106,7 +106,7 @@ function resolveRepoRoots(options: HivemindOptions): string[] {
}
function envRepoRoots(): string[] {
- const raw = process.env.CAVEMEM_HIVEMIND_REPO_ROOTS;
+ const raw = process.env.COLONY_HIVEMIND_REPO_ROOTS ?? process.env.CAVEMEM_HIVEMIND_REPO_ROOTS;
if (!raw) return [];
return raw.split(delimiter);
}
diff --git a/packages/core/src/memory-store.ts b/packages/core/src/memory-store.ts
index de83853..2282d84 100644
--- a/packages/core/src/memory-store.ts
+++ b/packages/core/src/memory-store.ts
@@ -1,6 +1,6 @@
-import { compress, expand, redactPrivate } from '@cavemem/compress';
-import type { Settings } from '@cavemem/config';
-import { type NewObservation, type ObservationRow, Storage } from '@cavemem/storage';
+import { compress, expand, redactPrivate } from '@colony/compress';
+import type { Settings } from '@colony/config';
+import { type NewObservation, type ObservationRow, Storage } from '@colony/storage';
import { cosine, hybridRank } from './ranker.js';
import type { GetObservationsOptions, Observation, SearchResult } from './types.js';
@@ -87,7 +87,7 @@ export class MemoryStore {
/**
* Idempotently materialise a sessions row before inserting child rows.
* Claude Code does not guarantee that SessionStart fires before the first
- * UserPromptSubmit / PostToolUse — for example when cavemem is installed
+ * UserPromptSubmit / PostToolUse — for example when colony is installed
* mid-session, when a hook earlier in the chain fails, or when a user
* resumes a session whose SessionStart was lost. Without this guard,
* observations and summaries hit `FOREIGN KEY constraint failed`.
diff --git a/packages/core/src/pheromone.ts b/packages/core/src/pheromone.ts
index a79cfef..d4e314b 100644
--- a/packages/core/src/pheromone.ts
+++ b/packages/core/src/pheromone.ts
@@ -1,4 +1,4 @@
-import type { Storage } from '@cavemem/storage';
+import type { Storage } from '@colony/storage';
export interface PheromoneStrengthBySession {
session_id: string;
@@ -47,19 +47,12 @@ export class PheromoneSystem {
/** Leave pheromone on a file. Called per write-tool invocation. */
deposit(args: { task_id: number; file_path: string; session_id: string }): void {
const now = Date.now();
- const existing = this.storage.getPheromone(
- args.task_id,
- args.file_path,
- args.session_id,
- );
+ const existing = this.storage.getPheromone(args.task_id, args.file_path, args.session_id);
let newStrength: number;
if (existing) {
const decayed = PheromoneSystem.decay(existing.strength, existing.deposited_at, now);
- newStrength = Math.min(
- decayed + PheromoneSystem.DEPOSIT,
- PheromoneSystem.MAX_STRENGTH,
- );
+ newStrength = Math.min(decayed + PheromoneSystem.DEPOSIT, PheromoneSystem.MAX_STRENGTH);
} else {
newStrength = PheromoneSystem.DEPOSIT;
}
diff --git a/packages/core/src/proposal-system.ts b/packages/core/src/proposal-system.ts
index 862ce8d..7890fa2 100644
--- a/packages/core/src/proposal-system.ts
+++ b/packages/core/src/proposal-system.ts
@@ -1,4 +1,4 @@
-import type { ReinforcementKind } from '@cavemem/storage';
+import type { ReinforcementKind } from '@colony/storage';
import type { MemoryStore } from './memory-store.js';
import { TaskThread } from './task-thread.js';
diff --git a/packages/core/src/response-thresholds.ts b/packages/core/src/response-thresholds.ts
index 382923c..ea9ddab 100644
--- a/packages/core/src/response-thresholds.ts
+++ b/packages/core/src/response-thresholds.ts
@@ -1,4 +1,4 @@
-import type { Storage } from '@cavemem/storage';
+import type { Storage } from '@colony/storage';
/**
* Named capability dimensions. Intentionally small — five is the upper
diff --git a/packages/core/src/task-thread.ts b/packages/core/src/task-thread.ts
index 39853c8..3a721dc 100644
--- a/packages/core/src/task-thread.ts
+++ b/packages/core/src/task-thread.ts
@@ -1,4 +1,4 @@
-import type { ObservationRow, TaskClaimRow, TaskParticipantRow, TaskRow } from '@cavemem/storage';
+import type { ObservationRow, TaskClaimRow, TaskParticipantRow, TaskRow } from '@colony/storage';
import type { MemoryStore } from './memory-store.js';
import {
type AgentProfile,
diff --git a/packages/core/test/memory-store-search.test.ts b/packages/core/test/memory-store-search.test.ts
index fbd0079..98aa6e1 100644
--- a/packages/core/test/memory-store-search.test.ts
+++ b/packages/core/test/memory-store-search.test.ts
@@ -1,7 +1,7 @@
import { mkdtempSync, rmSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
-import { defaultSettings } from '@cavemem/config';
+import { defaultSettings } from '@colony/config';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { type Embedder, MemoryStore } from '../src/index.js';
diff --git a/packages/core/test/pheromone.test.ts b/packages/core/test/pheromone.test.ts
index 72887c2..02f82ce 100644
--- a/packages/core/test/pheromone.test.ts
+++ b/packages/core/test/pheromone.test.ts
@@ -1,7 +1,7 @@
import { mkdtempSync, rmSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
-import { defaultSettings } from '@cavemem/config';
+import { defaultSettings } from '@colony/config';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { MemoryStore } from '../src/memory-store.js';
import { PheromoneSystem } from '../src/pheromone.js';
diff --git a/packages/core/test/proposal-system.test.ts b/packages/core/test/proposal-system.test.ts
index 6846d0f..690df3b 100644
--- a/packages/core/test/proposal-system.test.ts
+++ b/packages/core/test/proposal-system.test.ts
@@ -1,7 +1,7 @@
import { mkdtempSync, rmSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
-import { defaultSettings } from '@cavemem/config';
+import { defaultSettings } from '@colony/config';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { MemoryStore } from '../src/memory-store.js';
import { ProposalSystem } from '../src/proposal-system.js';
diff --git a/packages/core/test/response-thresholds.test.ts b/packages/core/test/response-thresholds.test.ts
index e62671d..5d7e0a1 100644
--- a/packages/core/test/response-thresholds.test.ts
+++ b/packages/core/test/response-thresholds.test.ts
@@ -1,7 +1,7 @@
import { mkdtempSync, rmSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
-import { defaultSettings } from '@cavemem/config';
+import { defaultSettings } from '@colony/config';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { MemoryStore } from '../src/memory-store.js';
import {
diff --git a/packages/core/test/task-thread.test.ts b/packages/core/test/task-thread.test.ts
index 74ec95a..ae05d83 100644
--- a/packages/core/test/task-thread.test.ts
+++ b/packages/core/test/task-thread.test.ts
@@ -1,7 +1,7 @@
import { mkdtempSync, rmSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
-import { defaultSettings } from '@cavemem/config';
+import { defaultSettings } from '@colony/config';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { MemoryStore } from '../src/memory-store.js';
import { TaskThread } from '../src/task-thread.js';
diff --git a/packages/embedding/CHANGELOG.md b/packages/embedding/CHANGELOG.md
index 70d4259..50a39be 100644
--- a/packages/embedding/CHANGELOG.md
+++ b/packages/embedding/CHANGELOG.md
@@ -1,4 +1,4 @@
-# @cavemem/embedding
+# @colony/embedding
## 0.2.0
@@ -8,10 +8,10 @@
**Embeddings (previously dead code) now work out of the box**
- - New `@cavemem/embedding` package exports `createEmbedder(settings)` with three providers: `local` (Transformers.js, default — `Xenova/all-MiniLM-L6-v2`, 384 dim), `ollama`, and `openai`. `@xenova/transformers` is an optional dependency: installs automatically with `npm install -g cavemem` on supported platforms, falls back gracefully otherwise.
+ - New `@colony/embedding` package exports `createEmbedder(settings)` with three providers: `local` (Transformers.js, default — `Xenova/all-MiniLM-L6-v2`, 384 dim), `ollama`, and `openai`. `@xenova/transformers` is an optional dependency: installs automatically with `npm install -g cavemem` on supported platforms, falls back gracefully otherwise.
- The worker now runs an embedding backfill loop: polls `observationsMissingEmbeddings`, embeds the expanded (human-readable) text, persists. On startup it drops rows whose model differs from settings so switching providers never pollutes cosine ranking.
- Storage gains a model/dim filter on `allEmbeddings()` plus `dropEmbeddingsWhereModelNot`, `countObservations`, `countEmbeddings`, and a model-scoped variant of `observationsMissingEmbeddings`.
- - The `Embedder` interface in `@cavemem/core` now exposes `model` and `dim` so the store can reject mismatched rows before cosine computation.
+ - The `Embedder` interface in `@colony/core` now exposes `model` and `dim` so the store can reject mismatched rows before cosine computation.
- Both the CLI `search` command and the MCP `search` tool instantiate the embedder lazily and pass it into `MemoryStore.search`. Semantic search is on by default; `cavemem search --no-semantic` bypasses it.
- Worker writes a `worker.state.json` snapshot after every batch so `cavemem status` can show "embedded 124 / 200 (62%)" without hitting HTTP.
@@ -25,7 +25,7 @@
- New `cavemem status` top-level command: single-pane dashboard showing settings path, data dir, DB counts, installed IDEs, embedding provider/model, backfill progress, worker pid and uptime.
- New `cavemem config show|get|set|open|path|reset` command backed by zod `.describe()` — the schema is self-documenting; no parallel docs to maintain.
- - New `settingsDocs()` export from `@cavemem/config` returns `[{path, type, default, description}]` for every field.
+ - New `settingsDocs()` export from `@colony/config` returns `[{path, type, default, description}]` for every field.
- `cavemem install` now prints a multi-line "what to try next" block explaining that there is no daemon to start, and surfaces the embedding model + weight-download cost.
- Settings schema gains `embedding.batchSize`, `embedding.autoStart`, and `embedding.idleShutdownMs` — every field now has a `.describe(...)` string.
@@ -41,4 +41,4 @@
### Patch Changes
- Updated dependencies [416957b]
- - @cavemem/config@0.2.0
+ - @colony/config@0.2.0
diff --git a/packages/embedding/package.json b/packages/embedding/package.json
index 3d7d738..65633fa 100644
--- a/packages/embedding/package.json
+++ b/packages/embedding/package.json
@@ -1,5 +1,5 @@
{
- "name": "@cavemem/embedding",
+ "name": "@colony/embedding",
"version": "0.2.0",
"license": "MIT",
"type": "module",
@@ -19,7 +19,7 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
- "@cavemem/config": "workspace:*"
+ "@colony/config": "workspace:*"
},
"optionalDependencies": {
"@xenova/transformers": "^2.17.2"
diff --git a/packages/embedding/src/index.ts b/packages/embedding/src/index.ts
index 924b648..d5839be 100644
--- a/packages/embedding/src/index.ts
+++ b/packages/embedding/src/index.ts
@@ -1,5 +1,5 @@
import { join } from 'node:path';
-import { type Settings, resolveDataDir } from '@cavemem/config';
+import { type Settings, resolveDataDir } from '@colony/config';
import { createLocalEmbedder } from './providers/local.js';
import { createOllamaEmbedder } from './providers/ollama.js';
import { createOpenAIEmbedder } from './providers/openai.js';
diff --git a/packages/embedding/src/providers/local.ts b/packages/embedding/src/providers/local.ts
index ea245da..9cd2731 100644
--- a/packages/embedding/src/providers/local.ts
+++ b/packages/embedding/src/providers/local.ts
@@ -23,7 +23,7 @@ export async function createLocalEmbedder(
opts: EmbeddingFactoryOptions = {},
): Promise {
const log = opts.log ?? (() => {});
- log(`[cavemem:embed] loading local model ${model}`);
+ log(`[colony:embed] loading local model ${model}`);
const transformers = (await import('@xenova/transformers').catch((err) => {
throw new Error(
`Local embedding provider requires @xenova/transformers. Install it or set embedding.provider to 'none'. (${String(
diff --git a/packages/embedding/src/providers/ollama.ts b/packages/embedding/src/providers/ollama.ts
index d66aed1..72e6356 100644
--- a/packages/embedding/src/providers/ollama.ts
+++ b/packages/embedding/src/providers/ollama.ts
@@ -42,7 +42,7 @@ export async function createOllamaEmbedder(
};
// Warm-up probe — checks the endpoint is reachable and captures dim.
- log(`[cavemem:embed] probing ollama at ${base} with model ${model}`);
+ log(`[colony:embed] probing ollama at ${base} with model ${model}`);
const probe = await embed(' ');
dim = probe.length;
diff --git a/packages/embedding/src/providers/openai.ts b/packages/embedding/src/providers/openai.ts
index 756ba9d..e7198fb 100644
--- a/packages/embedding/src/providers/openai.ts
+++ b/packages/embedding/src/providers/openai.ts
@@ -24,7 +24,7 @@ export async function createOpenAIEmbedder(
): Promise {
if (!apiKey) {
throw new Error(
- 'OpenAI embedding provider requires an API key. Set via `cavemem config set embedding.apiKey `.',
+ 'OpenAI embedding provider requires an API key. Set via `colony config set embedding.apiKey `.',
);
}
const base = (endpoint ?? 'https://api.openai.com/v1').replace(/\/+$/, '');
@@ -55,7 +55,7 @@ export async function createOpenAIEmbedder(
};
if (dim === 0) {
- log(`[cavemem:embed] probing openai model ${model} for dim`);
+ log(`[colony:embed] probing openai model ${model} for dim`);
const probe = await embed(' ');
dim = probe.length;
}
diff --git a/packages/embedding/src/types.ts b/packages/embedding/src/types.ts
index 5f3a4b7..ecc65d9 100644
--- a/packages/embedding/src/types.ts
+++ b/packages/embedding/src/types.ts
@@ -1,7 +1,7 @@
/**
- * Embedder — matches the structural interface in @cavemem/core.
+ * Embedder — matches the structural interface in @colony/core.
*
- * Declared here too so consumers of @cavemem/embedding don't need to depend
+ * Declared here too so consumers of @colony/embedding don't need to depend
* on core for the type. The two definitions are kept in sync manually; if
* they drift, MemoryStore.search will fail to compile against this package.
*/
diff --git a/packages/embedding/test/providers.test.ts b/packages/embedding/test/providers.test.ts
index a4f6030..e433fed 100644
--- a/packages/embedding/test/providers.test.ts
+++ b/packages/embedding/test/providers.test.ts
@@ -1,4 +1,4 @@
-import { SettingsSchema } from '@cavemem/config';
+import { SettingsSchema } from '@colony/config';
import { describe, expect, it } from 'vitest';
import { createEmbedder } from '../src/index.js';
diff --git a/packages/embedding/tsup.config.ts b/packages/embedding/tsup.config.ts
index b36cdd6..3773d09 100644
--- a/packages/embedding/tsup.config.ts
+++ b/packages/embedding/tsup.config.ts
@@ -7,5 +7,5 @@ export default defineConfig({
clean: true,
// Keep @xenova/transformers external — it's an optionalDependency, and
// bundling it drags in ONNX runtime + sharp (~3 MB) into our dist.
- external: ['@xenova/transformers', '@cavemem/config'],
+ external: ['@xenova/transformers', '@colony/config'],
});
diff --git a/packages/hooks/CHANGELOG.md b/packages/hooks/CHANGELOG.md
index 7c7c720..a72db29 100644
--- a/packages/hooks/CHANGELOG.md
+++ b/packages/hooks/CHANGELOG.md
@@ -1,4 +1,4 @@
-# @cavemem/hooks
+# @colony/hooks
## 0.2.0
@@ -8,10 +8,10 @@
**Embeddings (previously dead code) now work out of the box**
- - New `@cavemem/embedding` package exports `createEmbedder(settings)` with three providers: `local` (Transformers.js, default — `Xenova/all-MiniLM-L6-v2`, 384 dim), `ollama`, and `openai`. `@xenova/transformers` is an optional dependency: installs automatically with `npm install -g cavemem` on supported platforms, falls back gracefully otherwise.
+ - New `@colony/embedding` package exports `createEmbedder(settings)` with three providers: `local` (Transformers.js, default — `Xenova/all-MiniLM-L6-v2`, 384 dim), `ollama`, and `openai`. `@xenova/transformers` is an optional dependency: installs automatically with `npm install -g cavemem` on supported platforms, falls back gracefully otherwise.
- The worker now runs an embedding backfill loop: polls `observationsMissingEmbeddings`, embeds the expanded (human-readable) text, persists. On startup it drops rows whose model differs from settings so switching providers never pollutes cosine ranking.
- Storage gains a model/dim filter on `allEmbeddings()` plus `dropEmbeddingsWhereModelNot`, `countObservations`, `countEmbeddings`, and a model-scoped variant of `observationsMissingEmbeddings`.
- - The `Embedder` interface in `@cavemem/core` now exposes `model` and `dim` so the store can reject mismatched rows before cosine computation.
+ - The `Embedder` interface in `@colony/core` now exposes `model` and `dim` so the store can reject mismatched rows before cosine computation.
- Both the CLI `search` command and the MCP `search` tool instantiate the embedder lazily and pass it into `MemoryStore.search`. Semantic search is on by default; `cavemem search --no-semantic` bypasses it.
- Worker writes a `worker.state.json` snapshot after every batch so `cavemem status` can show "embedded 124 / 200 (62%)" without hitting HTTP.
@@ -25,7 +25,7 @@
- New `cavemem status` top-level command: single-pane dashboard showing settings path, data dir, DB counts, installed IDEs, embedding provider/model, backfill progress, worker pid and uptime.
- New `cavemem config show|get|set|open|path|reset` command backed by zod `.describe()` — the schema is self-documenting; no parallel docs to maintain.
- - New `settingsDocs()` export from `@cavemem/config` returns `[{path, type, default, description}]` for every field.
+ - New `settingsDocs()` export from `@colony/config` returns `[{path, type, default, description}]` for every field.
- `cavemem install` now prints a multi-line "what to try next" block explaining that there is no daemon to start, and surfaces the embedding model + weight-download cost.
- Settings schema gains `embedding.batchSize`, `embedding.autoStart`, and `embedding.idleShutdownMs` — every field now has a `.describe(...)` string.
@@ -51,7 +51,7 @@
**Publishable artifact**
- - `cavemem` no longer lists the private `@cavemem/mcp-server` and `@cavemem/worker` packages as runtime dependencies. Tsup already bundles every `@cavemem/*` module via `noExternal`, so the workspace deps moved to `devDependencies` and `npm install cavemem` resolves cleanly.
+ - `cavemem` no longer lists the private `@colony/mcp-server` and `@colony/worker` packages as runtime dependencies. Tsup already bundles every `@colony/*` module via `noExternal`, so the workspace deps moved to `devDependencies` and `npm install cavemem` resolves cleanly.
- The bin entrypoint guard (`isMainEntry()`) now compares realpaths via `pathToFileURL(realpathSync(...))`, so the binary works when invoked through npm's symlinked `bin/` shim — previously `--version` and every other command silently exited 0 with no output.
- Tsup's `banner` option was producing two `#!/usr/bin/env node` lines in every dynamic-import chunk (one from the source file, one from the banner), which broke `cavemem mcp` with `SyntaxError: Invalid or unexpected token`. The banner is gone; the shebang lives in the source files that need it.
- A new `prepublishOnly` script (`apps/cli/scripts/prepack.mjs`) stages `README.md`, `LICENSE`, and `hooks-scripts/` into `apps/cli/` so `changeset publish` produces a complete tarball. The script no-ops outside the source repo so installing the tarball never re-runs it.
@@ -65,7 +65,7 @@
**Root cause**
- The CLI's `process.argv[1]` (and everything `resolveCliPath()` derives from it) is the `.js` entry file, not a native executable. Node's `child_process.spawn` cannot exec a raw `.js` on Windows — it has no associated binfmt handler, so the launcher bubbles up `EFTYPE`. Every background code path that self-spawned the CLI — `cavemem start`, `cavemem restart`, `cavemem viewer`, and the hook auto-spawn in `@cavemem/hooks` — hit this, so the worker never started and hooks stayed degraded with no embeddings. The installers then wrote the same bad shape into IDE configs (`command: ` for MCP servers; `" hook run …"` as a shell string for Claude Code hooks), so even opening Claude Code / Cursor / Codex / Gemini / OpenCode could not launch the CLI.
+ The CLI's `process.argv[1]` (and everything `resolveCliPath()` derives from it) is the `.js` entry file, not a native executable. Node's `child_process.spawn` cannot exec a raw `.js` on Windows — it has no associated binfmt handler, so the launcher bubbles up `EFTYPE`. Every background code path that self-spawned the CLI — `cavemem start`, `cavemem restart`, `cavemem viewer`, and the hook auto-spawn in `@colony/hooks` — hit this, so the worker never started and hooks stayed degraded with no embeddings. The installers then wrote the same bad shape into IDE configs (`command: ` for MCP servers; `" hook run …"` as a shell string for Claude Code hooks), so even opening Claude Code / Cursor / Codex / Gemini / OpenCode could not launch the CLI.
**Fix**
@@ -85,12 +85,12 @@
- Fix a compression bug where `collapseWhitespace` would eat the single space between prose and preserved tokens (paths, inline code, URLs), producing unreadable output like `at/tmp/foo.txt`. Boundary spacing is now preserved on compress and round-tripped through expand.
- Fix `Storage.timeline(sessionId, aroundId, limit)` — the previous single-UNION query let the "after" half swallow the whole window. Replaced with two bounded queries merged in JS so both halves are respected.
- Remove a double `expand()` call in the MCP `get_observations` tool; expansion now happens exactly once inside `MemoryStore`.
- - `runHook()` now accepts an injected `MemoryStore` so tests (and other integrations) can avoid touching the user's real `~/.cavemem` data directory.
+ - `runHook()` now accepts an injected `MemoryStore` so tests (and other integrations) can avoid touching the user's real `~/.colony` data directory.
- Test ecosystem: brand-new suites for `@cavemem/hooks` (runner + all 5 handlers + hot-path budget check), `@cavemem/installers` (claude-code idempotency, settings preservation, cursor install/uninstall, registry, deepMerge), `@cavemem/mcp-server` (InMemory MCP client hitting every tool and asserting the progressive-disclosure shape), `@cavemem/worker` (Hono `app.request()` integration tests for every HTTP route), and the `cavemem` CLI (command registration smoke test). Total tests: 22 → 54.
+ Test ecosystem: brand-new suites for `@colony/hooks` (runner + all 5 handlers + hot-path budget check), `@colony/installers` (claude-code idempotency, settings preservation, cursor install/uninstall, registry, deepMerge), `@colony/mcp-server` (InMemory MCP client hitting every tool and asserting the progressive-disclosure shape), `@colony/worker` (Hono `app.request()` integration tests for every HTTP route), and the `cavemem` CLI (command registration smoke test). Total tests: 22 → 54.
None of the new test directories are shipped — every published package keeps its `files` allowlist pointed at `dist` only.
- Updated dependencies [416957b]
- - @cavemem/config@0.2.0
- - @cavemem/core@0.2.0
+ - @colony/config@0.2.0
+ - @colony/core@0.2.0
diff --git a/packages/hooks/package.json b/packages/hooks/package.json
index 7f27481..816c2a0 100644
--- a/packages/hooks/package.json
+++ b/packages/hooks/package.json
@@ -1,5 +1,5 @@
{
- "name": "@cavemem/hooks",
+ "name": "@colony/hooks",
"version": "0.2.0",
"license": "MIT",
"type": "module",
@@ -19,8 +19,8 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
- "@cavemem/config": "workspace:*",
- "@cavemem/core": "workspace:*"
+ "@colony/config": "workspace:*",
+ "@colony/core": "workspace:*"
},
"devDependencies": {
"tsup": "^8.3.5",
diff --git a/packages/hooks/src/active-session.ts b/packages/hooks/src/active-session.ts
index 00b8097..98e4968 100644
--- a/packages/hooks/src/active-session.ts
+++ b/packages/hooks/src/active-session.ts
@@ -1,6 +1,6 @@
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';
import { dirname, join } from 'node:path';
-import { detectRepoBranch } from '@cavemem/core';
+import { detectRepoBranch } from '@colony/core';
import type { HookInput, HookName } from './types.js';
type ActiveSessionState = 'working' | 'thinking' | 'idle';
@@ -27,7 +27,7 @@ export function upsertActiveSession(input: HookInput, hook: HookName): void {
worktreePath: detected.repo_root,
taskMode: existing?.taskMode ?? '',
openspecTier: existing?.openspecTier ?? '',
- taskRoutingReason: 'cavemem hook cwd binding',
+ taskRoutingReason: 'colony hook cwd binding',
startedAt: existing?.startedAt ?? now,
lastHeartbeatAt: now,
state: stateForHook(hook),
diff --git a/packages/hooks/src/auto-spawn.ts b/packages/hooks/src/auto-spawn.ts
index d6b2495..d130c07 100644
--- a/packages/hooks/src/auto-spawn.ts
+++ b/packages/hooks/src/auto-spawn.ts
@@ -1,25 +1,25 @@
import { spawn } from 'node:child_process';
import { existsSync, readFileSync } from 'node:fs';
import { join } from 'node:path';
-import { type Settings, resolveDataDir } from '@cavemem/config';
+import { type Settings, resolveDataDir } from '@colony/config';
/**
* Ensure the worker daemon is running. Called from the hook runner after
* every successful hook (sessionStart, postToolUse, ...) so embeddings
- * happen without the user ever typing `cavemem start`.
+ * happen without the user ever typing `colony start`.
*
* Hard invariants:
* - Must complete in < 2 ms when the worker is already running (the hot path).
* We achieve this with one stat + one process.kill(pid, 0) probe.
* - Must never block the hook on worker start — spawn is detached + unref.
- * - Must not spawn if CAVEMEM_NO_AUTOSTART is set (e2e tests need
+ * - Must not spawn if COLONY_NO_AUTOSTART is set (e2e tests need
* deterministic lifecycle).
* - Must not spawn if autoStart is false or provider is 'none'.
* - If the CLI path cannot be resolved (e.g., we're imported from a
* library context with no argv[1]), skip — silent no-op.
*/
export function ensureWorkerRunning(settings: Settings): void {
- if (process.env.CAVEMEM_NO_AUTOSTART) return;
+ if (process.env.COLONY_NO_AUTOSTART || process.env.CAVEMEM_NO_AUTOSTART) return;
if (!settings.embedding.autoStart) return;
if (settings.embedding.provider === 'none') return;
@@ -39,7 +39,7 @@ export function ensureWorkerRunning(settings: Settings): void {
try {
// Spawn `node worker start` — Windows can't exec a raw .js path
// (EFTYPE), and `cli` is the .js entry when the hook runs through the
- // cavemem CLI.
+ // colony CLI.
const child = spawn(process.execPath, [cli, 'worker', 'start'], {
detached: true,
stdio: 'ignore',
@@ -61,7 +61,7 @@ function isAlive(pid: number): boolean {
}
function resolveCli(): string | null {
- // argv[1] is the CLI binary when the hook handler runs through `cavemem hook`.
+ // argv[1] is the CLI binary when the hook handler runs through `colony hook`.
const argv1 = process.argv[1];
if (argv1) return argv1;
return null;
diff --git a/packages/hooks/src/handlers/post-tool-use.ts b/packages/hooks/src/handlers/post-tool-use.ts
index c590c4c..b67508e 100644
--- a/packages/hooks/src/handlers/post-tool-use.ts
+++ b/packages/hooks/src/handlers/post-tool-use.ts
@@ -1,4 +1,4 @@
-import { PheromoneSystem, ProposalSystem, type MemoryStore } from '@cavemem/core';
+import { type MemoryStore, PheromoneSystem, ProposalSystem } from '@colony/core';
import type { HookInput } from '../types.js';
/**
diff --git a/packages/hooks/src/handlers/session-end.ts b/packages/hooks/src/handlers/session-end.ts
index 2cb98c7..7197b50 100644
--- a/packages/hooks/src/handlers/session-end.ts
+++ b/packages/hooks/src/handlers/session-end.ts
@@ -1,4 +1,4 @@
-import type { MemoryStore } from '@cavemem/core';
+import type { MemoryStore } from '@colony/core';
import type { HookInput } from '../types.js';
export async function sessionEnd(store: MemoryStore, input: HookInput): Promise {
diff --git a/packages/hooks/src/handlers/session-start.ts b/packages/hooks/src/handlers/session-start.ts
index f159e97..a8cee9b 100644
--- a/packages/hooks/src/handlers/session-start.ts
+++ b/packages/hooks/src/handlers/session-start.ts
@@ -1,4 +1,4 @@
-import { type MemoryStore, ProposalSystem, TaskThread, detectRepoBranch } from '@cavemem/core';
+import { type MemoryStore, ProposalSystem, TaskThread, detectRepoBranch } from '@colony/core';
import type { HookInput } from '../types.js';
export async function sessionStart(store: MemoryStore, input: HookInput): Promise {
diff --git a/packages/hooks/src/handlers/stop.ts b/packages/hooks/src/handlers/stop.ts
index ebf0b61..08a84c1 100644
--- a/packages/hooks/src/handlers/stop.ts
+++ b/packages/hooks/src/handlers/stop.ts
@@ -1,4 +1,4 @@
-import type { MemoryStore } from '@cavemem/core';
+import type { MemoryStore } from '@colony/core';
import type { HookInput } from '../types.js';
export async function stop(store: MemoryStore, input: HookInput): Promise {
diff --git a/packages/hooks/src/handlers/user-prompt-submit.ts b/packages/hooks/src/handlers/user-prompt-submit.ts
index 9ddf75f..3b302b2 100644
--- a/packages/hooks/src/handlers/user-prompt-submit.ts
+++ b/packages/hooks/src/handlers/user-prompt-submit.ts
@@ -1,4 +1,4 @@
-import { PheromoneSystem, type MemoryStore } from '@cavemem/core';
+import { type MemoryStore, PheromoneSystem } from '@colony/core';
import type { HookInput } from '../types.js';
/**
diff --git a/packages/hooks/src/runner.ts b/packages/hooks/src/runner.ts
index 6c75ba5..91e22a3 100644
--- a/packages/hooks/src/runner.ts
+++ b/packages/hooks/src/runner.ts
@@ -1,6 +1,6 @@
import { join } from 'node:path';
-import { loadSettings, resolveDataDir } from '@cavemem/config';
-import { MemoryStore } from '@cavemem/core';
+import { loadSettings, resolveDataDir } from '@colony/config';
+import { MemoryStore } from '@colony/core';
import { removeActiveSession, upsertActiveSession } from './active-session.js';
import { ensureWorkerRunning } from './auto-spawn.js';
import { postToolUse } from './handlers/post-tool-use.js';
diff --git a/packages/hooks/test/auto-claim.test.ts b/packages/hooks/test/auto-claim.test.ts
index 6825fc7..5db55a1 100644
--- a/packages/hooks/test/auto-claim.test.ts
+++ b/packages/hooks/test/auto-claim.test.ts
@@ -1,8 +1,8 @@
import { mkdtempSync, rmSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
-import { defaultSettings } from '@cavemem/config';
-import { MemoryStore, TaskThread } from '@cavemem/core';
+import { defaultSettings } from '@colony/config';
+import { MemoryStore, TaskThread } from '@colony/core';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { autoClaimFromToolUse, extractTouchedFiles } from '../src/handlers/post-tool-use.js';
import { buildConflictPreface } from '../src/handlers/user-prompt-submit.js';
diff --git a/packages/hooks/test/pheromone.test.ts b/packages/hooks/test/pheromone.test.ts
index af6308d..1e3ad18 100644
--- a/packages/hooks/test/pheromone.test.ts
+++ b/packages/hooks/test/pheromone.test.ts
@@ -1,8 +1,8 @@
import { mkdtempSync, rmSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
-import { defaultSettings } from '@cavemem/config';
-import { MemoryStore, PheromoneSystem, TaskThread } from '@cavemem/core';
+import { defaultSettings } from '@colony/config';
+import { MemoryStore, PheromoneSystem, TaskThread } from '@colony/core';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { depositPheromoneFromToolUse } from '../src/handlers/post-tool-use.js';
import { buildPheromoneConflictPreface } from '../src/handlers/user-prompt-submit.js';
diff --git a/packages/hooks/test/proposal-system.test.ts b/packages/hooks/test/proposal-system.test.ts
index 9cb909a..a3d85d5 100644
--- a/packages/hooks/test/proposal-system.test.ts
+++ b/packages/hooks/test/proposal-system.test.ts
@@ -1,8 +1,8 @@
import { mkdtempSync, rmSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
-import { defaultSettings } from '@cavemem/config';
-import { MemoryStore, ProposalSystem, TaskThread } from '@cavemem/core';
+import { defaultSettings } from '@colony/config';
+import { MemoryStore, ProposalSystem, TaskThread } from '@colony/core';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { reinforceAdjacentProposals } from '../src/handlers/post-tool-use.js';
diff --git a/packages/hooks/test/runner.test.ts b/packages/hooks/test/runner.test.ts
index 65e6738..1d04596 100644
--- a/packages/hooks/test/runner.test.ts
+++ b/packages/hooks/test/runner.test.ts
@@ -1,8 +1,8 @@
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
-import { defaultSettings } from '@cavemem/config';
-import { MemoryStore } from '@cavemem/core';
+import { defaultSettings } from '@colony/config';
+import { MemoryStore } from '@colony/core';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { runHook } from '../src/index.js';
diff --git a/packages/hooks/test/task-injection.test.ts b/packages/hooks/test/task-injection.test.ts
index 58d281d..4aeacb5 100644
--- a/packages/hooks/test/task-injection.test.ts
+++ b/packages/hooks/test/task-injection.test.ts
@@ -1,13 +1,13 @@
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
-import { defaultSettings } from '@cavemem/config';
-import { MemoryStore, TaskThread } from '@cavemem/core';
+import { defaultSettings } from '@colony/config';
+import { MemoryStore, TaskThread } from '@colony/core';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { buildTaskPreface } from '../src/handlers/session-start.js';
/**
- * End-to-end proof that the task-thread primitive (@cavemem/core), the
+ * End-to-end proof that the task-thread primitive (@colony/core), the
* storage layer, and the SessionStart hook injection are wired together
* correctly. If these are green, a fresh codex session landing on a branch
* where claude just left a handoff *will* see the handoff in its
diff --git a/packages/installers/CHANGELOG.md b/packages/installers/CHANGELOG.md
index cdef166..1892eda 100644
--- a/packages/installers/CHANGELOG.md
+++ b/packages/installers/CHANGELOG.md
@@ -1,4 +1,4 @@
-# @cavemem/installers
+# @colony/installers
## 0.2.0
@@ -15,7 +15,7 @@
**Publishable artifact**
- - `cavemem` no longer lists the private `@cavemem/mcp-server` and `@cavemem/worker` packages as runtime dependencies. Tsup already bundles every `@cavemem/*` module via `noExternal`, so the workspace deps moved to `devDependencies` and `npm install cavemem` resolves cleanly.
+ - `cavemem` no longer lists the private `@colony/mcp-server` and `@colony/worker` packages as runtime dependencies. Tsup already bundles every `@colony/*` module via `noExternal`, so the workspace deps moved to `devDependencies` and `npm install cavemem` resolves cleanly.
- The bin entrypoint guard (`isMainEntry()`) now compares realpaths via `pathToFileURL(realpathSync(...))`, so the binary works when invoked through npm's symlinked `bin/` shim — previously `--version` and every other command silently exited 0 with no output.
- Tsup's `banner` option was producing two `#!/usr/bin/env node` lines in every dynamic-import chunk (one from the source file, one from the banner), which broke `cavemem mcp` with `SyntaxError: Invalid or unexpected token`. The banner is gone; the shebang lives in the source files that need it.
- A new `prepublishOnly` script (`apps/cli/scripts/prepack.mjs`) stages `README.md`, `LICENSE`, and `hooks-scripts/` into `apps/cli/` so `changeset publish` produces a complete tarball. The script no-ops outside the source repo so installing the tarball never re-runs it.
@@ -29,7 +29,7 @@
**Root cause**
- The CLI's `process.argv[1]` (and everything `resolveCliPath()` derives from it) is the `.js` entry file, not a native executable. Node's `child_process.spawn` cannot exec a raw `.js` on Windows — it has no associated binfmt handler, so the launcher bubbles up `EFTYPE`. Every background code path that self-spawned the CLI — `cavemem start`, `cavemem restart`, `cavemem viewer`, and the hook auto-spawn in `@cavemem/hooks` — hit this, so the worker never started and hooks stayed degraded with no embeddings. The installers then wrote the same bad shape into IDE configs (`command: ` for MCP servers; `" hook run …"` as a shell string for Claude Code hooks), so even opening Claude Code / Cursor / Codex / Gemini / OpenCode could not launch the CLI.
+ The CLI's `process.argv[1]` (and everything `resolveCliPath()` derives from it) is the `.js` entry file, not a native executable. Node's `child_process.spawn` cannot exec a raw `.js` on Windows — it has no associated binfmt handler, so the launcher bubbles up `EFTYPE`. Every background code path that self-spawned the CLI — `cavemem start`, `cavemem restart`, `cavemem viewer`, and the hook auto-spawn in `@colony/hooks` — hit this, so the worker never started and hooks stayed degraded with no embeddings. The installers then wrote the same bad shape into IDE configs (`command: ` for MCP servers; `" hook run …"` as a shell string for Claude Code hooks), so even opening Claude Code / Cursor / Codex / Gemini / OpenCode could not launch the CLI.
**Fix**
@@ -49,11 +49,11 @@
- Fix a compression bug where `collapseWhitespace` would eat the single space between prose and preserved tokens (paths, inline code, URLs), producing unreadable output like `at/tmp/foo.txt`. Boundary spacing is now preserved on compress and round-tripped through expand.
- Fix `Storage.timeline(sessionId, aroundId, limit)` — the previous single-UNION query let the "after" half swallow the whole window. Replaced with two bounded queries merged in JS so both halves are respected.
- Remove a double `expand()` call in the MCP `get_observations` tool; expansion now happens exactly once inside `MemoryStore`.
- - `runHook()` now accepts an injected `MemoryStore` so tests (and other integrations) can avoid touching the user's real `~/.cavemem` data directory.
+ - `runHook()` now accepts an injected `MemoryStore` so tests (and other integrations) can avoid touching the user's real `~/.colony` data directory.
- Test ecosystem: brand-new suites for `@cavemem/hooks` (runner + all 5 handlers + hot-path budget check), `@cavemem/installers` (claude-code idempotency, settings preservation, cursor install/uninstall, registry, deepMerge), `@cavemem/mcp-server` (InMemory MCP client hitting every tool and asserting the progressive-disclosure shape), `@cavemem/worker` (Hono `app.request()` integration tests for every HTTP route), and the `cavemem` CLI (command registration smoke test). Total tests: 22 → 54.
+ Test ecosystem: brand-new suites for `@colony/hooks` (runner + all 5 handlers + hot-path budget check), `@colony/installers` (claude-code idempotency, settings preservation, cursor install/uninstall, registry, deepMerge), `@colony/mcp-server` (InMemory MCP client hitting every tool and asserting the progressive-disclosure shape), `@colony/worker` (Hono `app.request()` integration tests for every HTTP route), and the `cavemem` CLI (command registration smoke test). Total tests: 22 → 54.
None of the new test directories are shipped — every published package keeps its `files` allowlist pointed at `dist` only.
- Updated dependencies [416957b]
- - @cavemem/config@0.2.0
+ - @colony/config@0.2.0
diff --git a/packages/installers/package.json b/packages/installers/package.json
index e26c40d..13fe9fa 100644
--- a/packages/installers/package.json
+++ b/packages/installers/package.json
@@ -1,5 +1,5 @@
{
- "name": "@cavemem/installers",
+ "name": "@colony/installers",
"version": "0.2.0",
"license": "MIT",
"type": "module",
@@ -19,7 +19,7 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
- "@cavemem/config": "workspace:*"
+ "@colony/config": "workspace:*"
},
"devDependencies": {
"tsup": "^8.3.5",
diff --git a/packages/installers/src/types.ts b/packages/installers/src/types.ts
index 4f1f901..0e269c3 100644
--- a/packages/installers/src/types.ts
+++ b/packages/installers/src/types.ts
@@ -1,7 +1,7 @@
export interface InstallContext {
/** Directory where the IDE keeps its config. */
ideConfigDir: string;
- /** Absolute path to the cavemem CLI entrypoint (the .js file). */
+ /** Absolute path to the colony CLI entrypoint (the .js file). */
cliPath: string;
/**
* Absolute path to the Node binary used to launch the CLI. IDE configs
@@ -9,7 +9,7 @@ export interface InstallContext {
* a raw .js fails with EFTYPE (no associated exec handler).
*/
nodeBin: string;
- /** Absolute path to the local data dir (e.g., ~/.cavemem). */
+ /** Absolute path to the local data dir (e.g., ~/.colony). */
dataDir: string;
}
diff --git a/packages/installers/test/installers.test.ts b/packages/installers/test/installers.test.ts
index 029ff90..7d6d3f9 100644
--- a/packages/installers/test/installers.test.ts
+++ b/packages/installers/test/installers.test.ts
@@ -18,9 +18,9 @@ beforeEach(() => {
process.env.HOME = home;
ctx = {
ideConfigDir: home,
- cliPath: '/fake/bin/cavemem.js',
+ cliPath: '/fake/bin/colony.js',
nodeBin: '/fake/bin/node',
- dataDir: join(home, '.cavemem'),
+ dataDir: join(home, '.colony'),
};
});
@@ -128,9 +128,9 @@ describe('claude-code installer', () => {
it('quotes paths with spaces in hook command strings (Windows)', async () => {
const winCtx: InstallContext = {
ideConfigDir: home,
- cliPath: 'C:\\Users\\Some User\\AppData\\Roaming\\npm\\node_modules\\cavemem\\dist\\index.js',
+ cliPath: 'C:\\Users\\Some User\\AppData\\Roaming\\npm\\node_modules\\colony\\dist\\index.js',
nodeBin: 'C:\\Program Files\\nodejs\\node.exe',
- dataDir: join(home, '.cavemem'),
+ dataDir: join(home, '.colony'),
};
await claudeCode.install(winCtx);
const settingsPath = join(home, '.claude', 'settings.json');
@@ -173,7 +173,7 @@ describe('cursor installer', () => {
await cursor.uninstall(ctx);
const after = JSON.parse(readFileSync(p, 'utf8')) as typeof cfg;
expect(after.mcpServers.colony).toBeUndefined();
- expect(after.mcpServers.cavemem).toBeUndefined();
+ expect(after.mcpServers.colony).toBeUndefined();
});
});
diff --git a/packages/storage/CHANGELOG.md b/packages/storage/CHANGELOG.md
index f0da5db..1f79f63 100644
--- a/packages/storage/CHANGELOG.md
+++ b/packages/storage/CHANGELOG.md
@@ -1,4 +1,4 @@
-# @cavemem/storage
+# @colony/storage
## 0.2.0
@@ -8,10 +8,10 @@
**Embeddings (previously dead code) now work out of the box**
- - New `@cavemem/embedding` package exports `createEmbedder(settings)` with three providers: `local` (Transformers.js, default — `Xenova/all-MiniLM-L6-v2`, 384 dim), `ollama`, and `openai`. `@xenova/transformers` is an optional dependency: installs automatically with `npm install -g cavemem` on supported platforms, falls back gracefully otherwise.
+ - New `@colony/embedding` package exports `createEmbedder(settings)` with three providers: `local` (Transformers.js, default — `Xenova/all-MiniLM-L6-v2`, 384 dim), `ollama`, and `openai`. `@xenova/transformers` is an optional dependency: installs automatically with `npm install -g cavemem` on supported platforms, falls back gracefully otherwise.
- The worker now runs an embedding backfill loop: polls `observationsMissingEmbeddings`, embeds the expanded (human-readable) text, persists. On startup it drops rows whose model differs from settings so switching providers never pollutes cosine ranking.
- Storage gains a model/dim filter on `allEmbeddings()` plus `dropEmbeddingsWhereModelNot`, `countObservations`, `countEmbeddings`, and a model-scoped variant of `observationsMissingEmbeddings`.
- - The `Embedder` interface in `@cavemem/core` now exposes `model` and `dim` so the store can reject mismatched rows before cosine computation.
+ - The `Embedder` interface in `@colony/core` now exposes `model` and `dim` so the store can reject mismatched rows before cosine computation.
- Both the CLI `search` command and the MCP `search` tool instantiate the embedder lazily and pass it into `MemoryStore.search`. Semantic search is on by default; `cavemem search --no-semantic` bypasses it.
- Worker writes a `worker.state.json` snapshot after every batch so `cavemem status` can show "embedded 124 / 200 (62%)" without hitting HTTP.
@@ -25,7 +25,7 @@
- New `cavemem status` top-level command: single-pane dashboard showing settings path, data dir, DB counts, installed IDEs, embedding provider/model, backfill progress, worker pid and uptime.
- New `cavemem config show|get|set|open|path|reset` command backed by zod `.describe()` — the schema is self-documenting; no parallel docs to maintain.
- - New `settingsDocs()` export from `@cavemem/config` returns `[{path, type, default, description}]` for every field.
+ - New `settingsDocs()` export from `@colony/config` returns `[{path, type, default, description}]` for every field.
- `cavemem install` now prints a multi-line "what to try next" block explaining that there is no daemon to start, and surfaces the embedding model + weight-download cost.
- Settings schema gains `embedding.batchSize`, `embedding.autoStart`, and `embedding.idleShutdownMs` — every field now has a `.describe(...)` string.
@@ -51,7 +51,7 @@
**Publishable artifact**
- - `cavemem` no longer lists the private `@cavemem/mcp-server` and `@cavemem/worker` packages as runtime dependencies. Tsup already bundles every `@cavemem/*` module via `noExternal`, so the workspace deps moved to `devDependencies` and `npm install cavemem` resolves cleanly.
+ - `cavemem` no longer lists the private `@colony/mcp-server` and `@colony/worker` packages as runtime dependencies. Tsup already bundles every `@colony/*` module via `noExternal`, so the workspace deps moved to `devDependencies` and `npm install cavemem` resolves cleanly.
- The bin entrypoint guard (`isMainEntry()`) now compares realpaths via `pathToFileURL(realpathSync(...))`, so the binary works when invoked through npm's symlinked `bin/` shim — previously `--version` and every other command silently exited 0 with no output.
- Tsup's `banner` option was producing two `#!/usr/bin/env node` lines in every dynamic-import chunk (one from the source file, one from the banner), which broke `cavemem mcp` with `SyntaxError: Invalid or unexpected token`. The banner is gone; the shebang lives in the source files that need it.
- A new `prepublishOnly` script (`apps/cli/scripts/prepack.mjs`) stages `README.md`, `LICENSE`, and `hooks-scripts/` into `apps/cli/` so `changeset publish` produces a complete tarball. The script no-ops outside the source repo so installing the tarball never re-runs it.
@@ -68,11 +68,11 @@
- Fix a compression bug where `collapseWhitespace` would eat the single space between prose and preserved tokens (paths, inline code, URLs), producing unreadable output like `at/tmp/foo.txt`. Boundary spacing is now preserved on compress and round-tripped through expand.
- Fix `Storage.timeline(sessionId, aroundId, limit)` — the previous single-UNION query let the "after" half swallow the whole window. Replaced with two bounded queries merged in JS so both halves are respected.
- Remove a double `expand()` call in the MCP `get_observations` tool; expansion now happens exactly once inside `MemoryStore`.
- - `runHook()` now accepts an injected `MemoryStore` so tests (and other integrations) can avoid touching the user's real `~/.cavemem` data directory.
+ - `runHook()` now accepts an injected `MemoryStore` so tests (and other integrations) can avoid touching the user's real `~/.colony` data directory.
- Test ecosystem: brand-new suites for `@cavemem/hooks` (runner + all 5 handlers + hot-path budget check), `@cavemem/installers` (claude-code idempotency, settings preservation, cursor install/uninstall, registry, deepMerge), `@cavemem/mcp-server` (InMemory MCP client hitting every tool and asserting the progressive-disclosure shape), `@cavemem/worker` (Hono `app.request()` integration tests for every HTTP route), and the `cavemem` CLI (command registration smoke test). Total tests: 22 → 54.
+ Test ecosystem: brand-new suites for `@colony/hooks` (runner + all 5 handlers + hot-path budget check), `@colony/installers` (claude-code idempotency, settings preservation, cursor install/uninstall, registry, deepMerge), `@colony/mcp-server` (InMemory MCP client hitting every tool and asserting the progressive-disclosure shape), `@colony/worker` (Hono `app.request()` integration tests for every HTTP route), and the `cavemem` CLI (command registration smoke test). Total tests: 22 → 54.
None of the new test directories are shipped — every published package keeps its `files` allowlist pointed at `dist` only.
- Updated dependencies [416957b]
- - @cavemem/config@0.2.0
+ - @colony/config@0.2.0
diff --git a/packages/storage/package.json b/packages/storage/package.json
index e892757..e09e0d3 100644
--- a/packages/storage/package.json
+++ b/packages/storage/package.json
@@ -1,5 +1,5 @@
{
- "name": "@cavemem/storage",
+ "name": "@colony/storage",
"version": "0.2.0",
"license": "MIT",
"type": "module",
@@ -19,7 +19,7 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
- "@cavemem/config": "workspace:*",
+ "@colony/config": "workspace:*",
"better-sqlite3": "^11.5.0"
},
"devDependencies": {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 6a86854..539e69a 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -52,31 +52,31 @@ importers:
specifier: ^2.17.2
version: 2.17.2
devDependencies:
- '@cavemem/compress':
+ '@colony/compress':
specifier: workspace:*
version: link:../../packages/compress
- '@cavemem/config':
+ '@colony/config':
specifier: workspace:*
version: link:../../packages/config
- '@cavemem/core':
+ '@colony/core':
specifier: workspace:*
version: link:../../packages/core
- '@cavemem/embedding':
+ '@colony/embedding':
specifier: workspace:*
version: link:../../packages/embedding
- '@cavemem/hooks':
+ '@colony/hooks':
specifier: workspace:*
version: link:../../packages/hooks
- '@cavemem/installers':
+ '@colony/installers':
specifier: workspace:*
version: link:../../packages/installers
- '@cavemem/mcp-server':
+ '@colony/mcp-server':
specifier: workspace:*
version: link:../mcp-server
- '@cavemem/storage':
+ '@colony/storage':
specifier: workspace:*
version: link:../../packages/storage
- '@cavemem/worker':
+ '@colony/worker':
specifier: workspace:*
version: link:../worker
tsup:
@@ -103,16 +103,16 @@ importers:
apps/mcp-server:
dependencies:
- '@cavemem/compress':
+ '@colony/compress':
specifier: workspace:*
version: link:../../packages/compress
- '@cavemem/config':
+ '@colony/config':
specifier: workspace:*
version: link:../../packages/config
- '@cavemem/core':
+ '@colony/core':
specifier: workspace:*
version: link:../../packages/core
- '@cavemem/embedding':
+ '@colony/embedding':
specifier: workspace:*
version: link:../../packages/embedding
'@modelcontextprotocol/sdk':
@@ -134,19 +134,19 @@ importers:
apps/worker:
dependencies:
- '@cavemem/compress':
+ '@colony/compress':
specifier: workspace:*
version: link:../../packages/compress
- '@cavemem/config':
+ '@colony/config':
specifier: workspace:*
version: link:../../packages/config
- '@cavemem/core':
+ '@colony/core':
specifier: workspace:*
version: link:../../packages/core
- '@cavemem/embedding':
+ '@colony/embedding':
specifier: workspace:*
version: link:../../packages/embedding
- '@cavemem/storage':
+ '@colony/storage':
specifier: workspace:*
version: link:../../packages/storage
'@hono/node-server':
@@ -168,7 +168,7 @@ importers:
evals:
dependencies:
- '@cavemem/compress':
+ '@colony/compress':
specifier: workspace:*
version: link:../packages/compress
devDependencies:
@@ -212,13 +212,13 @@ importers:
packages/core:
dependencies:
- '@cavemem/compress':
+ '@colony/compress':
specifier: workspace:*
version: link:../compress
- '@cavemem/config':
+ '@colony/config':
specifier: workspace:*
version: link:../config
- '@cavemem/storage':
+ '@colony/storage':
specifier: workspace:*
version: link:../storage
devDependencies:
@@ -234,7 +234,7 @@ importers:
packages/embedding:
dependencies:
- '@cavemem/config':
+ '@colony/config':
specifier: workspace:*
version: link:../config
optionalDependencies:
@@ -254,10 +254,10 @@ importers:
packages/hooks:
dependencies:
- '@cavemem/config':
+ '@colony/config':
specifier: workspace:*
version: link:../config
- '@cavemem/core':
+ '@colony/core':
specifier: workspace:*
version: link:../core
devDependencies:
@@ -273,7 +273,7 @@ importers:
packages/installers:
dependencies:
- '@cavemem/config':
+ '@colony/config':
specifier: workspace:*
version: link:../config
devDependencies:
@@ -289,7 +289,7 @@ importers:
packages/storage:
dependencies:
- '@cavemem/config':
+ '@colony/config':
specifier: workspace:*
version: link:../config
better-sqlite3:
diff --git a/scripts/e2e-pack-release.sh b/scripts/e2e-pack-release.sh
index 9637604..b0349d7 100755
--- a/scripts/e2e-pack-release.sh
+++ b/scripts/e2e-pack-release.sh
@@ -27,7 +27,7 @@ cleanup
mkdir -p "$PACK" "$PREFIX" "$HOME_DIR"
echo "==> 1. pack:release (build + pack-release.mjs)"
-pnpm --filter cavemem pack:release >/dev/null
+pnpm --filter colony pack:release >/dev/null
REL="$REPO/apps/cli/release"
test -f "$REL/package.json" || { echo "release dir missing package.json"; exit 1; }
@@ -38,12 +38,12 @@ test -d "$REL/hooks-scripts" || { echo "release dir missing hooks-scripts"; exit
echo "==> 2. npm pack the release dir (mirrors what publish:release uploads)"
VERSION=$(node -e "console.log(require('$REPO/apps/cli/package.json').version)")
( cd "$REL" && npm pack --pack-destination "$PACK" >/dev/null )
-TGZ="$PACK/cavemem-$VERSION.tgz"
+TGZ="$PACK/colony-$VERSION.tgz"
test -f "$TGZ" || { echo "tarball missing at $TGZ"; ls "$PACK"; exit 1; }
echo "==> 3. install -g into isolated prefix"
npm install --prefix "$PREFIX" --global "$TGZ" >/dev/null
-BIN="$PREFIX/bin/cavemem"
+BIN="$PREFIX/bin/colony"
test -x "$BIN" || { echo "bin shim missing"; exit 1; }
export HOME="$HOME_DIR"
diff --git a/scripts/e2e-publish.sh b/scripts/e2e-publish.sh
index e741395..cd4016a 100755
--- a/scripts/e2e-publish.sh
+++ b/scripts/e2e-publish.sh
@@ -12,7 +12,7 @@
# - chunk shebangs (one shebang per ESM file, never two)
# - prepublishOnly staging (README, LICENSE, hooks-scripts in the tarball)
# - better-sqlite3 native module resolution from a global install
-# - dynamic import of bundled @cavemem/* sub-modules
+# - dynamic import of bundled @colony/* sub-modules
#
# Run from repo root: bash scripts/e2e-publish.sh
# Requires: node >= 20, npm, pnpm
@@ -35,18 +35,18 @@ cd "$REPO"
# Embedding backfill needs the worker daemon to run. We disable autoSpawn
# during hook runs so the e2e stays deterministic — the test drives the
# worker explicitly in the checks below.
-export CAVEMEM_NO_AUTOSTART=1
+export COLONY_NO_AUTOSTART=1
echo "==> 1. build everything"
pnpm build >/dev/null
echo "==> 2. stage publish files (README, LICENSE, hooks-scripts)"
-pnpm --filter cavemem stage-publish
+pnpm --filter colony stage-publish
echo "==> 3. npm pack from apps/cli"
VERSION=$(node -e "console.log(require('$REPO/apps/cli/package.json').version)")
( cd "$REPO/apps/cli" && npm pack --pack-destination "$PACK" >/dev/null )
-TGZ="$PACK/cavemem-$VERSION.tgz"
+TGZ="$PACK/colony-$VERSION.tgz"
test -f "$TGZ" || { echo "tarball missing at $TGZ"; ls "$PACK"; exit 1; }
echo "==> 4. inspect tarball contents"
@@ -54,10 +54,10 @@ tar -tzf "$TGZ" | sort
echo "==> 5. install -g into isolated prefix"
npm install --prefix "$PREFIX" --global "$TGZ" >/dev/null
-BIN="$PREFIX/bin/cavemem"
+BIN="$PREFIX/bin/colony"
test -x "$BIN" || { echo "bin shim missing"; exit 1; }
-# All subsequent commands run in an isolated $HOME so we never touch the real ~/.cavemem
+# All subsequent commands run in an isolated $HOME so we never touch the real ~/.colony
export HOME="$HOME_DIR"
echo "==> 6. version (must match apps/cli/package.json#version)"
@@ -123,7 +123,7 @@ wait $mcp_pid 2>/dev/null || true
echo "==> 15. uninstall cleans up settings"
"$BIN" uninstall --ide claude-code
-grep -q "cavemem" "$HOME/.claude/settings.json" && { echo "uninstall left cavemem entry"; exit 1; }
+grep -q "colony" "$HOME/.claude/settings.json" && { echo "uninstall left colony entry"; exit 1; }
echo
echo "ALL CHECKS PASSED"
diff --git a/tsconfig.base.json b/tsconfig.base.json
index a16f7d0..501ead5 100644
--- a/tsconfig.base.json
+++ b/tsconfig.base.json
@@ -21,15 +21,15 @@
"composite": false,
"baseUrl": ".",
"paths": {
- "@cavemem/compress": ["./packages/compress/src/index.ts"],
- "@cavemem/config": ["./packages/config/src/index.ts"],
- "@cavemem/core": ["./packages/core/src/index.ts"],
- "@cavemem/embedding": ["./packages/embedding/src/index.ts"],
- "@cavemem/storage": ["./packages/storage/src/index.ts"],
- "@cavemem/hooks": ["./packages/hooks/src/index.ts"],
- "@cavemem/installers": ["./packages/installers/src/index.ts"],
- "@cavemem/mcp-server": ["./apps/mcp-server/src/server.ts"],
- "@cavemem/worker": ["./apps/worker/src/server.ts"]
+ "@colony/compress": ["./packages/compress/src/index.ts"],
+ "@colony/config": ["./packages/config/src/index.ts"],
+ "@colony/core": ["./packages/core/src/index.ts"],
+ "@colony/embedding": ["./packages/embedding/src/index.ts"],
+ "@colony/storage": ["./packages/storage/src/index.ts"],
+ "@colony/hooks": ["./packages/hooks/src/index.ts"],
+ "@colony/installers": ["./packages/installers/src/index.ts"],
+ "@colony/mcp-server": ["./apps/mcp-server/src/server.ts"],
+ "@colony/worker": ["./apps/worker/src/server.ts"]
}
},
"exclude": ["node_modules", "dist"]
diff --git a/vitest.config.ts b/vitest.config.ts
index 1fce128..c8c12fd 100644
--- a/vitest.config.ts
+++ b/vitest.config.ts
@@ -5,15 +5,15 @@ import { defineConfig } from 'vitest/config';
const rootDir = fileURLToPath(new URL('.', import.meta.url));
export const workspaceAliases = {
- '@cavemem/compress': resolve(rootDir, 'packages/compress/src/index.ts'),
- '@cavemem/config': resolve(rootDir, 'packages/config/src/index.ts'),
- '@cavemem/core': resolve(rootDir, 'packages/core/src/index.ts'),
- '@cavemem/embedding': resolve(rootDir, 'packages/embedding/src/index.ts'),
- '@cavemem/hooks': resolve(rootDir, 'packages/hooks/src/index.ts'),
- '@cavemem/installers': resolve(rootDir, 'packages/installers/src/index.ts'),
- '@cavemem/mcp-server': resolve(rootDir, 'apps/mcp-server/src/server.ts'),
- '@cavemem/storage': resolve(rootDir, 'packages/storage/src/index.ts'),
- '@cavemem/worker': resolve(rootDir, 'apps/worker/src/server.ts'),
+ '@colony/compress': resolve(rootDir, 'packages/compress/src/index.ts'),
+ '@colony/config': resolve(rootDir, 'packages/config/src/index.ts'),
+ '@colony/core': resolve(rootDir, 'packages/core/src/index.ts'),
+ '@colony/embedding': resolve(rootDir, 'packages/embedding/src/index.ts'),
+ '@colony/hooks': resolve(rootDir, 'packages/hooks/src/index.ts'),
+ '@colony/installers': resolve(rootDir, 'packages/installers/src/index.ts'),
+ '@colony/mcp-server': resolve(rootDir, 'apps/mcp-server/src/server.ts'),
+ '@colony/storage': resolve(rootDir, 'packages/storage/src/index.ts'),
+ '@colony/worker': resolve(rootDir, 'apps/worker/src/server.ts'),
};
export default defineConfig({