feat: smoothness pack — caffeinate, desktop notifier, task links#68
Merged
feat: smoothness pack — caffeinate, desktop notifier, task links#68
Conversation
…, task links
Three small polish features ported from agent-orchestrator (caffeinate,
notifier slot) and hive (cross-task links).
- worker: hold a `caffeinate -i -w <pid>` assertion on darwin while the
embed loop is running, so a laptop lid-close or system idle no longer
silently suspends embedding backfills. No-op on non-darwin and when the
embedder failed to load.
- process: new `notify({ level, title, body }, { provider, minLevel })`
helper. provider='desktop' fans out to osascript/notify-send;
provider='none' is a no-op. Fire-and-forget, never throws, never blocks
a hot path. Worker uses it to surface embedder-load failures so users
see a real signal instead of a stderr line they may never read.
- config: new `notify` settings group (provider, minLevel). Defaults to
silent so a fresh install stays unobtrusive.
- storage: schema v8 adds `task_links` (one row per unordered pair).
`linkTasks`/`unlinkTasks`/`linkedTasks` are symmetric and idempotent.
- core: `TaskThread.link/unlink/linkedTasks` wraps the storage primitives.
- mcp: new tools `task_link`, `task_unlink`, `task_links` so agents on
one task can see decisions/blockers from a paired task without
copy-paste — equivalent of hive's "worktree connections" minus the GUI.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three small polish features ported from
NagyVikt/agent-orchestrator(caffeinate, plugin-style notifier slot) andNagyVikt/hive(worktree connections → cross-task links). Each is scoped to a single concern and lives at an existing extension point inCLAUDE.md.1. macOS idle-sleep prevention (
@colony/worker)apps/worker/src/caffeinate.tsholds acaffeinate -i -w <worker-pid>assertion while the embed loop is running, so a laptop lid-close or system idle no longer silently suspends long-running embedding backfills. No-op on non-darwin; never started when the embedder failed to load (the worker is then just a viewer + state-file writer with no background work to protect). The-w <pid>form means the assertion auto-releases even if the worker dies without running its shutdown handler.2. Desktop notifier slot (
@colony/process+@colony/config)@colony/processgains a genericnotify({ level, title, body }, { provider, minLevel, log })helper.provider: 'desktop'fans out to:osascript -e 'display notification "<body>" with title "<title>"'notify-send -u <urgency> <title> <body>Fire-and-forget: never awaits the spawned helper, never throws, never blocks a hot path. Spawn failures route through the optional
logcallback so a missingnotify-sendon a headless box never crash-loops.@colony/configadds anotifysettings group (provider,minLevel). Default'none'so a fresh install stays unobtrusive —colony config showandsettingsDocs()pick it up automatically.The worker uses it on the embedder-load-failure path so users see a real signal instead of a stderr line they may never read.
3. Cross-task links (
@colony/storage+@colony/core+@colony/mcp-server)The hive analogue. Schema bump v7 → v8 introduces a
task_linkstable: one row per unordered pair,low_id < high_idenforced by CHECK.linkTasksis idempotent (re-linking preserves original metadata);linkedTasks(task_id)returns the other side of each edge with link metadata, regardless of which side originally created the link.New MCP tools:
task_link(task_id, other_task_id, session_id, note?)task_unlink(task_id, other_task_id)task_links(task_id)So an agent on a "frontend" lane can see decisions/blockers from a paired "backend" lane in their own preface without copy-paste.
Why these three?
task_post.caffeinate,osascript, andnotify-sendship with the OS.Test plan
pnpm typecheck— passes for every package except@imdeadpool/colony-cli(pre-existing missingzoddep onmain, unrelated)pnpm test— all affected packages pass: storage (+4 new tests), process (+4), worker (+1), core, mcp-server (snapshot updated)pnpm lint— error count unchanged from baseline (35 → 35; my changes add zero new violations)pnpm --filter @colony/worker --filter @colony/mcp-server build— cleanpmset -g assertionsshows thePreventUserIdleSystemSleepassertion held bycaffeinatewhile the embed loop is active, released on shutdownnotify.provider = 'desktop', force an embedder load failure, confirm the system notification firestask_links(A)returns B and vice versa; unlink and verify both sides dropMarked as draft for the manual smokes and any review on the migration shape.
Notes
CREATE TABLE IF NOT EXISTScovers the path; theschema_versionrow bumps to 8.@colony/process(which only depends onnode:builtins per CLAUDE.md) so adding it doesn't break the dependency direction.caffeinatetest only asserts the non-darwin no-op path; the spawn path is exercised manually since CI runners aren't a useful test bed for power management.Generated by Claude Code