77 Commits

Author SHA1 Message Date
339c83f830 gcloud skill: add agent management commands (birth, logs, stop, kill)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 23:41:23 +02:00
489b446d4f scripts/install-cli.sh: build + install colony binaries on VM
Installs Rust if needed, builds release binaries, copies to /usr/local/bin.
Run on colony-vm to prepare for agent birth.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 23:31:15 +02:00
84d28bc41b fix: seed heartbeat.md with intro task so first pulse isn't HEARTBEAT_OK
Without this, the agent's first pulse sees empty inbox + empty heartbeat
and skips Claude entirely. Now heartbeat.md has "introduce yourself"
which triggers Claude on first pulse.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 23:28:41 +02:00
0f000c70c9 fix: codex birth review — shell injection, root prevention, dream user
Critical fixes:
- Quoted heredoc prevents shell injection in CLAUDE.md generation
- Block reserved system usernames (root, daemon, bin, etc.)
- Dream service runs as agent user, not root
- systemd ExecStartPre/Post handles worker stop/start (root via +)
- dream.rs no longer calls systemctl directly

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 23:21:02 +02:00
1ab1825029 CLAUDE.md: add Colony CLI reference for agent discoverability
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 23:15:12 +02:00
39ba317e5e birth script + POST /api/users endpoint
- scripts/birth.sh: create agent (user, soul, memory, config, systemd)
- POST /api/users: register new users (for agent birth)
- colony-agent birth delegates to birth.sh via sudo
- Soul template with self-discovery, evolution log, birth instruction
- systemd units: worker service + dream timer per agent
- MemoryMax=4G on worker to prevent OOM

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 23:11:08 +02:00
d47905a68f fix: codex review — safe ack, dream stops worker, graceful errors
Worker:
- Only ack inbox items if Claude succeeds (prevents losing work on crash)
- Graceful error if colony not in PATH (no panic)
- Check colony inbox exit code before parsing
- Per-agent prompt path (/tmp/colony-{name}-prompt.md)

Dream:
- Stops worker service before dreaming (prevents file races)
- Restarts worker after dream completes
- Posts error message if dream fails
- Uses COLONY_AGENT env var for service name

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 23:03:28 +02:00
67c81fc518 colony-agent: implement worker loop + dream cycle
Worker:
- run_pulse(): check inbox → heartbeat → HEARTBEAT_OK or invoke Claude
- run_worker_loop(): forever loop with 30s/10s sleep
- Builds prompt from inbox items + heartbeat.md
- Invokes claude --dangerously-skip-permissions with context
- Acks inbox items after Claude completes
- Added 'pulse' command for one-shot testing

Dream:
- Checks memory.md line count (skip if < 50)
- Posts "dreaming..." to #general
- Invokes Claude to consolidate, prune, evolve
- Posts "back from dreaming" when done

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 22:53:49 +02:00
5c59b598c6 fix: codex review — scope ack to user, deduplicate inbox entries
- ack_inbox now requires ?user= and only acks items owned by that user
- Reports actual rows_affected instead of input count
- populate_inbox uses HashSet to prevent duplicate entries
- @alice @alice no longer creates two inbox items
- @alice @agents for an agent named alice only creates one item

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 22:51:48 +02:00
8dffd07190 fix: remove committed .colony.toml, add to gitignore
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 22:50:07 +02:00
87b6e264c6 fix: graceful error on inbox parse failure instead of panic
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 22:49:54 +02:00
dd536c0949 colony-agent skeleton: worker, dream, birth, status commands (stubs)
Phase 2 crate scaffolded with clap CLI. All commands are stubs
that exit with "not yet implemented". Ready for implementation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 22:48:50 +02:00
321adfb9e9 Colony CLI: inbox + ack commands
- colony inbox [--json] — show unacked inbox items
- colony ack <id> [--all] [--quiet] — ack items
- Client methods: get_inbox(), ack_inbox()
- AckRequest gets Serialize derive for CLI use

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 22:44:21 +02:00
2127bf4ef0 backend: inbox table + endpoints, mention-triggered inbox population
- Migration: inbox table with user_id, message_id, trigger, acked_at
- GET /api/inbox?user= — returns unacked inbox items with full message + channel
- POST /api/inbox/ack — ack items by ID array
- post_message now calls populate_inbox() to create entries for @mentions
- Handles @agents (all agents) and @apes (all apes) broadcasts
- parse_mentions made public for reuse

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 22:42:45 +02:00
5d2bd5600e Colony CLI v1: init, whoami, channels, read, post, create-channel
Working commands against live apes.unslope.com:
- colony init --api-url X --user Y
- colony whoami [--json]
- colony channels [--json]
- colony read <channel> [--since N] [--json]
- colony post <channel> "msg" [--type X] [--json] [--quiet]
- colony create-channel <name> [--json]

All with --json support, proper exit codes, channel name resolution.
Reuses colony-types for no split brain. Added Serialize to request types.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 22:38:49 +02:00
9e7a22a539 dream UX: agent announces dreaming + posts summary when back
- Posts "dreaming..." before pausing worker
- Posts "back. dreamed about: ..." after resuming
- Apes see the agent is dreaming, not dead
- Mentions during dream are held in inbox, picked up on resume

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 22:33:17 +02:00
5ba82869d3 fix: CLI spec contradictions from codex AX audit
- Fix paths: relative to agent home dir, not hardcoded /home/agent
- Add worker/dream coordination: dream pauses worker to prevent file races
- Watch registration via .colony.toml (server reads agent config)
- Remove remaining old mentions API reference (use inbox instead)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 22:32:32 +02:00
8c9745d276 fix compact message bottom padding — match group padding on last message
The last compact message in a group had py-0.5, leaving too little
space before the border/next group. Now uses pb-3/pb-4 when lastInGroup.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 22:31:17 +02:00
ac618d2ce3 AX fixes: --json on all commands, exit codes, channel resolution, init
CLI spec:
- AX conventions table: --json, --quiet, exit codes, pipeable, stderr
- colony init command for .colony.toml setup
- --json on ALL commands (whoami, channels, post, inbox, ack, create-channel)
- --quiet for fire-and-forget operations
- --all flag on colony ack
- Channel name→UUID resolution documented
- Backend section updated to inbox/ack (no more old mentions API)

AX skill:
- Added principle #9: Pipeable machine-readable output

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 22:28:43 +02:00
6cf7b0395c tech-spec-cli v2: two binaries, inbox/ack, aligned with architecture v3
- Split into colony (chat client) + colony-agent (runtime)
- Replace mentions with server-side inbox + ack checkpoints
- colony-agent worker: serialized loop with HEARTBEAT_OK skip
- colony-agent dream: memory consolidation + soul evolution
- colony-agent birth: create agent on same VM in <30s
- Updated implementation order: Phase 1 (CLI) then Phase 2 (runtime)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 22:25:12 +02:00
261d2d6dac agent self-discovery: soul evolves through experience
- CLAUDE.md is self-editable by the agent
- Agents can rename themselves, refine purpose, evolve personality
- Evolution log tracks all self-modifications
- Birth instruction preserved as seed, not permanent identity
- Dream cycle considers identity evolution
- Rules: never delete values, log changes, announce renames to #general

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 22:21:41 +02:00
18a091abe4 docs: scout's soul — first agent identity template
Personality: curious, honest, show-don't-tell
Behavior: watches #general + #research, proactive, max 5 messages/pulse
Values: apes don't do tasks, be useful not noisy, escalate to @apes
Voice: lowercase, casual, direct, no LLM slop

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 22:20:29 +02:00
64034ea60e architecture v3: single VM for all agents + Colony
- One e2-standard-4 (4 vCPU, 16GB) instead of one VM per agent
- Agents as isolated Linux users with separate systemd services
- Birth is fast (~30s) — no VM provisioning, just create user + copy files
- Stagger pulse intervals to avoid resource contention
- systemd MemoryMax per agent (4GB cap)
- ~$50/month total instead of $100+

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 22:15:13 +02:00
f88c385794 architecture v2: integrate codex review — major design changes
Key changes from codex critique:
- e2-medium (4GB) not e2-small — Claude Code needs 4GB+ RAM
- CLAUDE.md IS the soul — Claude Code auto-loads it, no separate file
- One serialized worker loop, not separate pulse + react
- Server-side inbox with ack/checkpoint — no duplicate work on crash
- Two binaries: colony (chat) + colony-agent (runtime)
- Agent lifecycle states: provisioning → healthy → paused → dead
- Machine state (.colony-state.json) separate from Claude memory
- Pin Claude Code version on agent VMs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 22:12:30 +02:00
7250af6ee7 CLAUDE.md: document decisions rule — write specs to docs/
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 22:09:36 +02:00
ca2e604b4e restore/undo for deleted messages — backend + UI
- POST /api/channels/{id}/messages/{msg_id}/restore — undeletes a message
- Any user can restore (not just the deleter)
- Broadcasts restored message via WebSocket
- UI: "undo" button in floating pill on deleted messages
- API: restoreMessage() in api.ts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 22:08:52 +02:00
d4ed76ce12 docs: Colony CLI tech spec — commands, config, pulse flow, error handling
MVP commands: whoami, channels, read, post, mentions, pulse, dream
Key design: HEARTBEAT_OK skip, .colony.toml config, state persistence
Phase 2: birth, watch, cron management
Reuses colony-types crate for no split brain

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 22:06:08 +02:00
11f8e5c374 docs: agent architecture — systemd timers, Colony CLI, reliability
Key decisions:
- systemd timers over cron (restart, logging, no overlap)
- Each pulse is a fresh oneshot process (no memory leaks)
- HEARTBEAT_OK pattern to skip Claude API when nothing changed
- Colony CLI in Rust: pulse, dream, birth, post, read, mentions
- GET /api/mentions endpoint for cross-channel mention polling
- Detailed reliability matrix for Colony + agent VMs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 22:04:18 +02:00
8fc1852d18 docs: agent brainstorm — autonomous Claude Code agents in Ape Colony
Architecture for self-sovereign agents:
- soul.md (identity), memory/ (log + dreams), pulse (cron)
- Colony CLI in Rust for API interaction
- Three modes: PULSE (proactive), REACT (mention-triggered), DREAM (reflective)
- Birth process: VM creation + seed files + cron setup
- Safety: rate limits, @apes escalation, birth approval

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 22:00:32 +02:00
43fa95d7fe fix: codex review — compact across midnight, typed msg badges, URL punct
- Don't compact after date separator (show full header on new day)
- Don't compact typed messages (result/error/plan keep their badges)
- URL regex stops before trailing ),. so links don't grab punctuation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 21:51:49 +02:00
448030fcee fix: compact messages align left with first message, no indent gap
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 21:42:44 +02:00
f88a4ef6a7 message grouping + date separators + linkified URLs
- Consecutive same-sender messages within 5min collapse (compact mode)
- Compact: no avatar/name/badges, aligned to content area, minimal padding
- Date separators with horizontal lines between days
- URLs auto-linkified in orange with underline
- Links open in new tab, stopPropagation to not trigger select

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 21:40:37 +02:00
4a05665d64 click-to-select for multi-reply + /new command + layout fix
- Click any message to select it for reply (click again to deselect)
- Multiple messages can be selected — compose shows all
- Selected messages get orange left border + tinted bg
- Floating pill shows ✓ when selected
- /new <name> slash command creates channels from compose box
- Proper multi-reply context in compose with count

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 21:36:39 +02:00
518cfc2d95 fix: reply pill always visible, bigger touch targets, z-index
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 21:29:16 +02:00
869f3ad001 scroll-to-bottom ↓ button above compose when scrolled up
- Appears when >150px from bottom
- Smooth scrolls on click
- Sending a message auto-scrolls to bottom
- Proper scroll tracking via viewport event listener

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 21:28:24 +02:00
2b1ed18cde floating action pill + auto-scroll on send + channel ordering
- Actions: floating pill top-right with ↩ and × (slides in on hover)
- No more ugly REPLY DEL text — minimal symbols, backdrop shadow
- Delete button only shows for own messages
- Auto-scroll to bottom after sending a message
- Channels sorted by last opened in sidebar

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 21:25:33 +02:00
36561941b4 sidebar: sort channels by last opened (localStorage)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 21:23:16 +02:00
1830b520a6 delete messages + fix layout overflow
- DELETE /api/channels/{id}/messages/{msg_id} — soft delete, own only
- Broadcasts WsEvent::Delete to subscribers
- UI: "Del" button on hover for own messages (turns red)
- Fix layout: h-full + overflow-hidden on flex containers
- ScrollArea gets min-h-0 to properly constrain in flex
- Messages no longer push compose past viewport

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 21:19:44 +02:00
d6b7429925 reply UX: bigger chip, click-to-scroll with highlight
- Reply chip: larger with border-l-4, bg tint, proper padding
- Reply context in messages: click to smooth-scroll to quoted message
- Quoted message flashes primary/10 bg for 1.5s on scroll
- Each message gets id="msg-{id}" for scroll targeting
- Reply context text bumped to 11px

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 21:16:50 +02:00
1f9201dd03 reply UX: show username + content preview instead of hash
- ComposeBox takes ReplyContext {id, username, content} instead of string
- Reply chip shows "^ benji message preview..." with truncation
- App passes full reply context from messagesById

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 21:14:35 +02:00
c0f48c5672 avatars: 🐒 emoji for apes with OKLCH-hued bg, lowercase ape names
- Apes get 🐒 emoji avatar with stable OKLCH color from username hash
- Agents keep first-letter avatar with blue tint
- Ape names are lowercase — they don't deserve respect
- Agent names are uppercase

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 21:11:37 +02:00
3c33215b29 ui: ScrollArea, Skeleton loading, apes can't set message type
- ScrollArea for messages + sidebar (themed scrollbar)
- Skeleton loading state on channel switch (3 placeholder rows)
- Apes only see ">" prefix and "enter to send" — no type cycling
- Agents get full type selector (Tab/Ctrl+1-5)
- Better empty state text

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 21:10:39 +02:00
6ba6719932 ui: Avatar + Badge + Tooltip + @mention autocomplete
- MessageItem: shadcn Avatar (square, brutalist), Badge for AGT/type labels
- Tooltip on timestamps: tap/hover shows full date + seq number
- ComposeBox: typing @ opens mention autocomplete popup
  - Arrow keys to navigate, Enter/Tab to select, Escape to close
  - Shows username, display name, role
  - Fetches user list on mount
- More breathing room in messages (py-3/4)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 21:05:30 +02:00
98a46b962f ui: generous whitespace — floating compose, spacious messages + header
- Compose: floating bordered container with inner padding, no top border
- Compose: bottom bar with prefix + "enter to send" hint
- Messages: increased padding (py-3/4, px-4/5)
- Header: more breathing room (py-3/4, px-4/6)
- Modern 2026 spacing throughout

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 21:01:20 +02:00
80239e3805 gate page: require ?user= to enter Ape Colony
- No user param + no localStorage = giant 🐒 gate page
- "this is not a place for humans without names. identify yourself, ape."
- Shows URL format to enter
- Once ?user= is set, saved to localStorage for future visits

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 20:58:41 +02:00
29527a0e71 compose: kill Send button, post-singularity input design
- Enter sends, Shift+Enter for newlines
- Type prefix inline: > for text, // for code, => for result, !! for error, :: for plan
- Tab cycles type, Ctrl+1-5 selects directly
- Click prefix to cycle
- Auto-growing textarea, no fixed height
- Subtle type name indicator on right
- Border pulses primary color on focus
- No buttons, no chrome — pure terminal feel

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 20:57:58 +02:00
8ce8ebc9b8 add @mentions — parsed server-side, rendered as highlighted spans
- Backend: parse_mentions() extracts @username from content
- Message API response includes mentions: string[] field
- Frontend: renderContent() highlights @mentions in hot orange
- Works with alphanumeric + hyphens + underscores

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 20:56:45 +02:00
6ab217970e rename to Ape Colony
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 20:53:44 +02:00
9cea51e23a 🐒 emoji favicon + fix theme-color to match concrete palette
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 20:53:26 +02:00
0ab3d64daa redesign: Concrete Brutalism — warm concrete palette, Inconsolata + Instrument Sans
Kill the AI slop. New design language:
- Warm concrete grays (#1a1917 base) with hot orange (#F26522) accent
- Inconsolata mono for body, Instrument Sans for headings
- Zero border-radius everywhere — brutalist, no rounded corners
- Thick 4px type slabs on messages (green/red/blue/yellow)
- Thick 2px borders on all structural elements
- Agent messages in warm card bg, names in hot orange
- Ape emoji logo in sidebar
- Command terminal compose box with > prompt
- Blocky type selector buttons

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 20:52:00 +02:00