Skip to content

feat(cloud): team project memories#3

Closed
pippenz wants to merge 155 commits intocodingagentsystem:mainfrom
pippenz:epic/team-project-memories-cas-9ba3
Closed

feat(cloud): team project memories#3
pippenz wants to merge 155 commits intocodingagentsystem:mainfrom
pippenz:epic/team-project-memories-cas-9ba3

Conversation

@pippenz
Copy link
Copy Markdown

@pippenz pippenz commented Apr 2, 2026

Summary

  • Add cas cloud projects command — lists all team projects with contributor/memory counts
  • Add cas cloud team-memories command — pulls team memories for current project, merges into local stores via LWW
  • Add per-project sync timestamps (team_memory_sync_timestamps) to CloudConfig
  • Add response types for new cloud endpoints (shipped in petra-stella-cloud 92d69e8)
  • Handle 401/403/404 error codes per cloud API contract

Details

When a dev joins a project teammates have worked on, cas cloud team-memories pulls the team's collective learnings (entries, rules, skills) — with personal preferences filtered server-side. Uses existing LWW merge from pull.rs. Supports --dry-run, --full, and --json flags.

Test plan

  • cargo check passes
  • All 7 cloud config tests pass (including new test_team_memory_sync_timestamps)
  • Manual test: cas cloud projects with active team
  • Manual test: cas cloud team-memories --dry-run on a team-pushed project
  • Manual test: cas cloud team-memories full merge flow
  • Edge cases: no team configured, no git remote, project not on server

🤖 Generated with Claude Code

pippenz and others added 30 commits March 17, 2026 09:08
- Add custom option_i32/option_u8 serde deserializers so MCP count
  fields accept numbers sent as floats (e.g. 3.0) from Claude Code
- Fix notify_rx ref mut in factory lifecycle to allow mutable drain/recv
- Refactor DaemonNotifier socket to lazy tokio conversion (std socket
  bound before Tokio runtime, converted on first async use)
- Use gcc linker instead of clang for local build
….json

Workers were only getting Bash(cas :*) permissions in their generated
settings.json, leaving mcp__cas__* tools unallowed. This required
unreliable fallback to the global ~/.claude/settings.json.

Add get_cas_mcp_permissions() alongside get_cas_bash_permissions() and
merge both into the permissions.allow array in get_cas_hooks_config().

The 10 MCP tools added: task, coordination, memory, search, rule, skill,
spec, verification, system, pattern.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When workers use isolated git worktrees, .mcp.json must be committed to git
or it won't appear in their checkout — leaving them with no MCP tools and
silently idle.

Changes:
- preflight_factory_launch(): add git ls-files check for .mcp.json.
  Hard failure when workers > 0; advisory notice when supervisor-only.
  Quick-start steps show 'git add .mcp.json && git commit' when only
  .mcp.json is missing (not duplicated if .claude/ is also missing).
- queue_codex_worker_intro_prompt(): inject MCP fallback instructions for
  Claude workers at startup. Tells workers to check .mcp.json, run
  'cas init -y' to regenerate it, and notify supervisor via
  'cas factory message' if MCP tools are unavailable — preventing
  silent idle loops.

Closes cas-8397 (based on spike cas-4567).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace hand-written option_u8/option_i32 deserializers with a single
option_numeric_deser! macro generating 6 variants (u8, i32, i64, u32,
usize, u64). Apply to all ~30 Option<numeric> fields across MCP request
types so Claude Code's string-encoded numbers ("3") are accepted
alongside native JSON numbers (3).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- handle_mouse_up() returns selected text instead of calling arboard
  directly (daemon is headless, can't access system clipboard)
- Daemon relays selected text to client terminal via OSC 52 escape
  sequence for native clipboard write
- Auto-enter inject mode after image drop so user can immediately
  type context for pasted images

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…reen

Adds a "minions" theme variant selectable via `[theme] variant = "minions"`
in config.toml. When active: workers get minion names (kevin, stuart, bob),
supervisor is named gru/dru/nefario, the color palette shifts to yellow
primary with denim blue accents, and the boot screen shows a minion ASCII
art logo with "BANANA!" ready message and "Bee-do Bee-do" launch animation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… test compilation

- Replace generic box ASCII art with recognizable minion character (pill
  body, goggles with eyes, overalls, "BANANA" text)
- Wire MinionsIcons (banana/eye/sleep emoji) into agent_status_icon() and
  agent_status_icon_simple() via is_minions() theme flag
- Add missing minions_theme field to test_config() in core.rs and
  factory_integration.rs
- Fix pre-existing mut warnings in notify.rs tests (lines 132, 155)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Redesign MINION_LOGO with better pill-shaped body silhouette,
  symmetric goggle strap, arm stubs (─┤/├─), and cleaner feet
- Replace 8 non-canonical worker names (larry, tom, chris, john, paul,
  mike, ken, donny) with actual Minion film characters (jorge, otto,
  steve, herb, pete, donnie, abel, walter)
- Add otto (main character from Minions: The Rise of Gru)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The test was failing because try_recv on a Tokio UnixDatagram requires
the socket to be registered with the reactor first. Added an initial
recv().await call before the drain test sequence to ensure the Tokio
socket is properly registered.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- OSC 52: base64 encoding, empty string, unicode, multiline round-trip
- ThemeVariant: default value, Display, FromStr, serde round-trip
- ActiveTheme: minions config wiring, is_minions() check
- ColorPalette::minions(): yellow primary, denim blue info, differs
  from dark, preserves base bg
- MinionsIcons: non-empty constants, differ from default circles

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace all `mcp__cs__` prefixes with `mcp__cas__` in the hardcoded
Codex worker and supervisor instructions in pty.rs. Extract inline
instruction strings to module-level constants for maintainability.

Add tests verifying Codex worker instructions use the correct
mcp__cas__ prefix and supervisor instructions are present.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…essage

Remove the response hint ("To respond, use: coordination...") that was
appended to every agent message. This instruction is already provided at
session start via the cas-worker skill and is also enforced by the
PreToolUse hook that blocks SendMessage in factory mode. Removing the
per-message hint saves tokens on every inter-agent exchange.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Revert the prefix change per supervisor guidance: mcp__cs__ is the
correct Codex tool prefix (configured in harness.rs). Keep the
extraction of inline instruction strings to module-level constants
(CODEX_SUPERVISOR_INSTRUCTIONS, CODEX_WORKER_INSTRUCTIONS,
CODEX_WORKER_STARTUP_PREFIX) for maintainability.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The function reads CAS_AGENT_ROLE and CAS_FACTORY_WORKER_NAMES env vars
and parses CSV on every call across 6+ call sites. Since env vars don't
change during a session, cache the result per-thread using thread_local
OnceCell. Thread-local (vs process-global OnceLock) is used so that
tests which set different env vars per test thread continue to work.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… queue messages

Remove the 500-char truncation when re-queuing undelivered messages to
the supervisor. The full original message is now preserved in the
system-notice, so the supervisor can properly re-send or act on the
complete content instead of a truncated fragment.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add priority support to the prompt queue so important messages
(blockers, crashes) can jump ahead of routine status updates.

Changes:
- Add priority column to prompt_queue table (migration, DEFAULT 2)
- Add enqueue_full() method accepting optional NotificationPriority
- Change ORDER BY from created_at ASC to priority ASC, id ASC
- Wire priority param through coordination message action
- Add QueuedPrompt.priority field using existing NotificationPriority
- Add 3 tests: priority ordering, default priority, peek_for_targets

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add an ack-back mechanism so senders can verify message delivery:

- Schema: add `acked_at` column to prompt_queue table (safe migration)
- Store: add `ack()`, `unacked()`, `message_status()` to PromptQueueStore trait
- MessageStatus enum: Pending → Delivered → Confirmed lifecycle
- Coordination: add `message_ack` and `message_status` actions
- Tests: 5 new tests covering ack, idempotency, nonexistent, timeout, status

Messages now have a 3-state lifecycle:
1. Pending - queued but not yet injected
2. Delivered - injected (processed_at set) but unconfirmed
3. Confirmed - target agent acked receipt (acked_at set)

Agents can ack via: coordination action=message_ack notification_id=<id>
Senders can check via: coordination action=message_status notification_id=<id>
Unacked messages can be queried via store.unacked(timeout_secs, limit).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ool permissions

- CLAUDE.md: replace abbreviated docs with comprehensive architecture guide
  covering workspace layout, key patterns, testing, and migration details
- settings.json: add CAS MCP tool permissions to allow list

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Config::load() now detects when both config.toml and config.yaml exist
and merges any YAML-only settings (like theme.variant) into the TOML
config. This fixes minions theme never engaging — the theme was written
to config.yaml while config.toml already existed without a [theme]
section, so the YAML was silently ignored.

Changes since fork (v1.1.0):

Features:
- Minions theme for factory workers and boot screen
- Prompt queue priority levels
- Delivery confirmation for prompt queue messages
- Auto-inject mcp__cas__* permissions into worker settings.json
- Updated CLAUDE.md with detailed architecture docs

Fixes:
- Config YAML/TOML merge (minions theme never engaging)
- OSC 52 clipboard copy and auto-inject on image paste
- Numeric string-coercion for all MCP Option fields
- int32 deserialize for MCP count fields
- Preserve full message content on undeliverable prompt queue messages
- Broken mcp__cs__ tool prefixes in Codex instructions
- Per-message response hints in format_agent_message
- Minion ASCII art and canonical character names
- .mcp.json committed-file pre-flight check for workers
- drain_clears_pending_notifications test

Performance:
- Cache supervisor_owned_workers() with thread_local OnceCell

Tests:
- Coverage for OSC 52, theme variant, minions palette and icons
- Config YAML→TOML merge behavior tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…nt panic

The fork-first daemon path called try_start_cloud_client() during
run_with_progress(), which runs before the Tokio runtime is created.
This caused tokio::spawn() to panic with "there is no reactor running",
killing the daemon and producing a "session not found" error on attach.

Fix: defer cloud client initialization to daemon.run() where the Tokio
runtime is guaranteed to be active. Add a phone_home field to
FactoryDaemon to carry the flag across the boundary.

Also: make builtin agents/skills language-agnostic (TypeScript, Python,
Rust) and bump Cargo.lock version to 1.1.0.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
After dropping a file onto a pane, the TUI previously entered Inject mode
with a floating dialog. Since the file path is already pasted via bracketed
paste, the user just needs to keep typing in the PTY. Remove the inject mode
entry and instead clear sidecar focus so keystrokes go directly to the
focused PTY pane.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… feedback

The OSC 52 clipboard mechanism doesn't work reliably across all terminals.
This adds a fallback: the daemon sends a custom control sequence
(ESC]777;clipboard;<base64>BEL) alongside OSC 52, which the client
intercepts and uses to write to the clipboard via arboard/pbcopy since
the client process has display server access.

Also adds "Copied N chars" status bar feedback and documents drag-to-copy
and Shift+drag for native terminal selection in the help overlay.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
pippenz and others added 28 commits March 30, 2026 09:31
- Replace Vec<&str> allocation with splitn iterator in
  parse_diff_numstat (cas-e48b)
- Skip TUI rendering and raise sleep to 500ms when no clients
  are connected in headless daemon mode (cas-b470)
- Make inject_prompt non-blocking by spawning the delayed carriage
  return in a background tokio task instead of sleeping
  150-500ms inline (cas-b052)
- Replace dedicated OS thread per Codex PTY CPR with tokio::spawn
  async task (cas-907f)
- Use row_style_runs() (single FFI call with pre-grouped runs)
  instead of dump_row() + row_styles() (two FFI calls + O(n)
  per-cell comparison) in row_as_line (cas-dc20)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Removes the separate write_lock: RwLock<()> and changes
index: RwLock<Index> to index: Mutex<Index>.

The cached_writer Mutex already serializes write operations (only one
IndexWriter can exist at a time via take_writer/return_writer). The
Index itself is Arc-backed in Tantivy, so clone is cheap — we briefly
lock the Mutex to clone or swap, then release immediately.

This reduces the lock hierarchy from 4 locks to 3 (index Mutex,
cached_reader RwLock, cached_writer Mutex) and eliminates the
reader-writer lock ordering complexity.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…r search

The QueryParser was previously constructed on every search_filtered call,
requiring an Index lock and parser construction overhead. Now it's cached
in a Mutex<Option<QueryParser>> field, created lazily on first use, and
invalidated during rebuild_atomic when the underlying index changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Cache QueryParser in OnceLock, rebuild only on index rebuild (cas-3c8a)
- Simplify lock hierarchy: RwLock<Index> → Mutex<Index>, remove write_lock (cas-4f95)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace Vec<&str> alloc with splitn(3) iterator in parse_diff_numstat (cas-e48b)
- Skip rendering + raise sleep to 500ms in headless mode (cas-b470)
- Make inject_prompt non-blocking via tokio::spawn (cas-b052)
- Replace OS thread with tokio::spawn for Codex CPR injection (cas-907f)
- Combine dump_row+row_styles into single row_style_runs() call (cas-dc20)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ding, compression threshold

- migration m189: add generated column + index for friction_type json_extract (cas-9335)
- Task::default(): use epoch timestamps instead of Utc::now() syscalls (cas-023f)
- director: combine 4 task iteration passes into single pass (cas-0f40)
- palette: add maintenance-trap comment to light_from_colors (cas-6f96)
- layered store: use sort_unstable_by + reserve for list(All) (cas-a19f)
- compression: raise threshold from 256→1024 for high-entropy PTY data (cas-1a8c)
- entry/task FromStr: replace to_lowercase() with eq_ignore_ascii_case (cas-4b5a)
- mux focus_next/prev: use IndexMap get_index_of instead of Vec alloc (cas-07a9)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ding, compression threshold

- Replace allocating to_lowercase() with eq_ignore_ascii_case in enum FromStr (cas-4b5a)
- Task::default() uses epoch timestamps instead of Utc::now() syscalls (cas-023f)
- Add generated column + index for friction_type json_extract queries (cas-9335)
- Use sort_unstable_by + reserve in LayeredEntryStore list(All) (cas-a19f)
- Combine 4 task iteration passes into single-pass partitioning (cas-0f40)
- Raise COMPRESSION_THRESHOLD from 256 to 1024 for PTY data (cas-1a8c)
- Use IndexMap get_index_of in focus_next/prev to avoid Vec alloc (cas-07a9)
- Add maintenance-trap comment to light_from_colors (cas-6f96)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ane content

The Zig VT style run generator used 1-based run_start and col_idx+1 at
style boundaries, causing the first character of every line and one
character at each style transition to be dropped. The web client's
convert_style_runs_to_proto had a compensating saturating_sub(1)
workaround, but row_as_line (rewritten in d98954d to use style runs)
did not, making the clipping visible in the TUI.

Fix: use 0-based indices in both viewport and screen row style run
functions, and remove the workaround from the proto converter.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…-request hang

Every factory session sees the first MCP tool call hang for exactly 60s
(Claude Code's client timeout). The server receives the request but the
handler never returns. This happens on ext4 too, not just NTFS.

Changes:
- Add START log to tools/list, resources/list, and call_tool handlers
- Wrap call_tool in a 55s tokio::time::timeout — returns an error instead
  of silently hanging until the 60s client cancellation
- Log WARN with tool name + request ID when timeout fires

This will identify which tool hangs on the next factory run, and the
timeout prevents the cascade of retried-and-also-hung requests that
currently produces 100+ timeouts per session.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Every factory session logged "TLS support not compiled in" because ureq
was built with only the "json" feature. Add "tls" feature to enable
HTTPS for cloud sync, phone-home, and auth endpoints.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Workers in git worktrees now check `$PWD` for `.cas/worktrees` on their
first turn and skip MCP tools entirely if detected, instead of wasting
2-4 turns attempting mcp__cas__task, cas init, cas factory, etc.

Changes:
- Restructured "Worktree Mode" + "Tool Availability" sections into a
  single "First Turn: Detect Your Mode" section with a concrete bash
  check and clear branching (WORKTREE → Fallback, NORMAL → try MCP once)
- Updated all three sources: builtin skill, synced SKILL.md, and
  default_worker_guidance() fallback in cas-core

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Two fixes for verification deadlocks when supervisor implements tasks:

1. close_ops.rs: When supervisor is the task assignee, the verification
   gate message now instructs them to spawn task-verifier or record
   verification directly, instead of the misleading "continue with
   other tasks while waiting" message that left nobody to verify.

2. pre_tool.rs: When supervisor spawns task-verifier, write the unjail
   marker file and clear pending_verification on owned tasks. Previously
   supervisors were exempt from verification jail entirely (correct),
   but this also meant the unjail marker was never written — blocking
   the task-verifier subagent from recording verification via
   cas_verification_add when running in supervisor context.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ttempt

Restructure the worker intro prompt (queue_codex_worker_intro_prompt)
to instruct workers to check for worktree mode FIRST, before attempting
any MCP tool call. Workers in worktrees (.cas/worktrees/) now skip MCP
entirely and go straight to built-in tools, saving 2-4 wasted turns.

The prompt now has two clear branches:
- Worktree mode: use built-in tools, read supervisor's message
- Normal mode: try mcp__cas__task action=mine, fall back if it fails

References the cas-worker skill for detailed workflow guidance.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When a worker dies mid-task, the supervisor was blocked from reclaiming
the orphaned task by "Supervisors cannot claim non-epic tasks" guard.

Two changes to task_claiming.rs:
1. Supervisor role restriction now checks if the task's assignee is
   inactive (heartbeat expired >300s or not found). If so, the orphaned
   task can be claimed by the supervisor.
2. Assignee mismatch check now allows supervisor to reclaim: re-assigns
   the task, adds a reclaim note, and releases the dead worker's stale
   lease.

This mirrors the existing assignee_inactive pattern from close_ops.rs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fix #1 — Idle message dedup: Add per-worker rate limiting (5 min) for
idle-like messages in process_prompt_queue(). Detects common idle
patterns ("standing by", "ready for task", "MCP tools unavailable",
"idle", "awaiting instructions", etc.) and suppresses duplicates.

Fix #2 — Stale messages: Dead worker filtering was already in place
via is_dead_worker_source() and the dead_workers HashSet (populated on
both crash and shutdown). No additional changes needed — verified the
existing filter covers both paths.

New: is_idle_message() helper with unit tests for pattern matching.
New: last_idle_message_times HashMap on FactoryDaemon for per-worker
rate tracking.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Three improvements to find_cas_root_from() in store/detect.rs:

1. CAS worktree detection: new find_cas_root_from_cas_worktree()
   detects if the current path is inside .cas/worktrees/<name>/ and
   resolves directly to the parent .cas/ directory. This is the most
   reliable detection for factory workers since it doesn't depend on
   git state or .git file parsing.

2. Relative gitdir path handling: find_main_repo_from_worktree() now
   resolves relative paths in .git files against the worktree root
   and canonicalizes the result. This fixes Git 2.40+ which can write
   relative gitdir references.

3. Detection priority documented: CAS_ROOT env var > CAS worktree
   path detection > git worktree .git file parsing > directory walk.

Includes tests for CAS worktree detection and relative gitdir paths.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…, slim CLAUDE.md

Replace custom mouse selection/clipboard (arboard, selection.rs, clipboard.rs)
with native terminal selection by removing EnableMouseCapture. Users can now
select text and copy via right-click as expected.

Fix scroll viewport preservation in Pane::feed() — use delta-based offset
correction instead of assuming the terminal auto-scrolls to bottom, preventing
viewport drift when reading scrollback during active output.

Slim CLAUDE.md by extracting architecture and contributing docs to
cas-cli/docs/ (ARCHITECTURE.md, CONTRIBUTING.md). Add `cas claude-md`
CLI analyzer command. Add CAS deep-dive doc, issue tracker, and site.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Global ~/.claude/settings.json already provides CAS hooks. When project-level
.claude/settings.json also has them, each hook runs twice per tool call,
causing PreToolUse errors.

- Add `global_has_cas_hooks()` detection in configure
- `cas hook configure` now skips hooks when global ones exist (writes only
  permissions + statusLine)
- Add `cas hook cleanup` command to strip duplicates from all project settings
- Add `strip_cas_hooks()` and `has_cas_hook_entries()` utilities
- Tests handle both global-hooks-present and absent paths
- Ran cleanup: 96 project files stripped across all Petrastella projects

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Without mouse capture, scroll wheel events become arrow key sequences that
get forwarded to Claude Code panes (cycling command history instead of
scrolling content). Re-enable EnableMouseCapture but only handle scroll
events — click/drag are ignored so native selection still works via
Shift+click/drag.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove CAS block from project CLAUDE.md (global provides it)
- Remove 'What is CAS' description (Claude works here, doesn't need a pitch)
- Remove boilerplate line — 65→34 lines, ~820→376 tokens (54% reduction)
- build.rs: use `git diff --quiet HEAD` instead of `git status --porcelain`
  so untracked files don't mark the binary as dirty

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
tokio-tungstenite was missing a TLS feature, causing every factory
session's cloud relay to fail with "TLS support not compiled in" when
connecting to wss://petra-stella-cloud.vercel.app. Added
rustls-tls-native-roots feature.

Found in ozer factory logs — all 3 most recent sessions hit this
10-retry loop and gave up.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Schema advanced from v187→v189, adding 2 tables and 5 rows.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Pull team memories for current project and merge into local stores
using LWW conflict resolution. Adds per-project sync timestamps
to CloudConfig. Supports --dry-run and --full flags.
Lists all projects the team has pushed to cloud with contributor
and memory counts. Supports --team flag and JSON output.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Resolve merge conflicts from parallel worker branches:
- fast-raven-71: cas cloud projects command
- quiet-gopher-25: cas cloud team-memories command + CloudConfig

Remove duplicate TeamProjectsResponse/TeamProject structs that
both workers added to syncer/mod.rs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add 403 (not a team member) handling to projects and team-memories
- Add 404 (project not found) handling to memories endpoint
- Pluralize "contributor"/"memory" labels in projects list output

Aligned with shipped cloud API error contract.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 2, 2026

Thank you for your interest in CAS! We appreciate you taking the time to contribute.

CAS is source-available but does not accept pull requests at this time. Instead, please:

See CONTRIBUTING.md for more details on how to participate.

@github-actions github-actions bot closed this Apr 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant