Nests: team rooms with core crows and borrowing

- Server: nests API, persistence, core-first picking, borrowed flag
  (built by the backend agent against EVENTS.md; tests pass with -race)
- UI: nests in the sidebar, one feed per nest, header shows the core
  team, New nest dialog, borrowed crows labeled, per-nest waiting count
- start.command: one-click local server in controlled mode (mock crows,
  localhost only, state in .crows/)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UQnSw4RRWp8uqpj3nsnnXF
This commit is contained in:
SmokeyandClaude Opus 5.5 committed 2026-10-27 13:45:04 -06:00
1 parent e9f20349a1
commit 2d85cab716
14 files changed
+782 -62

No files matched your search

+10 -3
View File
@@ -36,7 +36,7 @@ func main() {
func usage() {
fmt.Fprintln(os.Stderr, `So Many Crows
crows run <todo.txt> [-as name] hand the flock a todo list
crows run <todo.txt> [-as name] [-nest id] hand the flock a todo list
crows serve [-addr 127.0.0.1:8080] run the web server (API + SSE)
crows trust show trust ledger
crows log [-n 20] show recent flight log entries`)
@@ -46,6 +46,7 @@ func usage() {
func cmdRun(args []string) {
fs := flag.NewFlagSet("run", flag.ExitOnError)
as := fs.String("as", defaultRequester(), "requester id")
nestID := fs.String("nest", defaultNestID, "nest whose core crows fly first")
var pos []string
for fs.Parse(args); fs.NArg() > 0; fs.Parse(args) {
pos = append(pos, fs.Arg(0))
@@ -62,6 +63,12 @@ func cmdRun(args []string) {
flog, err := OpenFlightLog(filepath.Join(dataDir, "flight.jsonl"))
must(err)
defer flog.Close()
nests, err := LoadNests(filepath.Join(dataDir, "nests.json"))
must(err)
nest, found := nests.Get(*nestID)
if !found {
must(fmt.Errorf("there is no nest called %q", *nestID))
}
p := &Pipeline{Ledger: ledger, Log: flog, G: g, Approver: &StdinApprover{in: bufio.NewReader(os.Stdin)}}
if ok, msg, _ := ledger.Admit(*as, time.Now(), g); !ok {
@@ -86,8 +93,8 @@ func cmdRun(args []string) {
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
defer stop()
fmt.Printf("Brain: %s · requester: %s · %d items\n", brain.Name(), *as, len(items))
l := List{ID: "cli", Requester: *as, Source: todoPath, Items: items}
fmt.Printf("Brain: %s · requester: %s · nest: %s · %d items\n", brain.Name(), *as, nest.ID, len(items))
l := List{ID: "cli", Requester: *as, Source: todoPath, Items: items, Nest: nest}
results, listBudget := p.Run(ctx, l, &cliEmitter{items: items, seen: map[string]bool{}})
resultPath := strings.TrimSuffix(todoPath, filepath.Ext(todoPath)) + ".crows.md"