docs: slim specs 01-03 to remaining work + add remediation specs 04/05#5
Conversation
… specs 04/05 - Slim 01/02/03 to only their unimplemented gaps (the scaffolding from prior ricky runs is already on main; do not redo it). - Add Spec 04 (cloud-agent box endpoints in ../cloud) and Spec 05 (integrations Connect via @relayfile/sdk + account-wide RelayWorkspaceManager). - Mandatory worktree → PR workflow on every spec; new runner specs/run-remaining-work.sh iterates in dependency order (05 → 04 → 01 → 02 → 03). - Remove legacy specs/run-overnight.sh (sorted order is wrong now that 05 precedes 04). - Memories: cloud credential sources, cloud-agent semantics, relayfile workspace model. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Free Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAdds memory documents and five detailed specs plus a runner script: design foundations for cloud credentials and relayfile workspaces, and specs covering Cloud Agents, Integrations, Proactive Agents, Cloud Agent Box backend, and Integrations Connect remediation. ChangesCloud Agents, Integrations & Proactive Agents Wave
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
Note 🎁 Summarized by CodeRabbit FreeYour organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/login. Comment |
| if ! "${cmd[@]}"; then | ||
| rc=$? | ||
| echo | ||
| echo "==> FAILED on $name (exit $rc)" | ||
| echo " Fix the underlying issue, then resume with:" | ||
| echo " $0 ${name%%-*}" | ||
| exit "$rc" |
There was a problem hiding this comment.
🟡 Exit code always 0 on failure due to $? after negated if condition
On line 74, rc=$? always captures 0 because it follows if ! "${cmd[@]}". In bash, when the then branch is entered, $? reflects the exit status of the negated condition (! cmd), which is 0 (true). The actual non-zero exit code of the failed command is lost. This causes exit "$rc" on line 79 to exit with 0, making the script appear to succeed to any parent process or CI system, even when ricky fails. The printed message also incorrectly shows "exit 0".
| if ! "${cmd[@]}"; then | |
| rc=$? | |
| echo | |
| echo "==> FAILED on $name (exit $rc)" | |
| echo " Fix the underlying issue, then resume with:" | |
| echo " $0 ${name%%-*}" | |
| exit "$rc" | |
| "${cmd[@]}" && true | |
| rc=$? | |
| if [[ $rc -ne 0 ]]; then | |
| echo | |
| echo "==> FAILED on $name (exit $rc)" | |
| echo " Fix the underlying issue, then resume with:" | |
| echo " $0 ${name%%-*}" | |
| exit "$rc" | |
| fi |
Was this helpful? React with 👍 or 👎 to provide feedback.
Adds resume support to specs/run-remaining-work.sh so a paused or partially completed run can continue from a given spec without re-running the ones that already landed. ./specs/run-remaining-work.sh # full run, dependency order ./specs/run-remaining-work.sh --from 01 # resume from 01 onward ./specs/run-remaining-work.sh --only 04 # run only one spec Positional NN still works for back-compat (= --only NN). On failure the script prints the exact --from command to resume from where it stopped. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Use `cmd && true; rc=$?` so the failing command's exit status is preserved. `if ! cmd; then rc=$?` always captured 0 because bash sets $? to the negated condition's result (0 = true), making FAILED on … (exit 0) and exiting 0 even when ricky failed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… dev ai-hist 0.2.0 (JSONL fallback, AgentWorkforce/relayhistory#5) isn't on npm yet. Use the local checkout so the Conversations panel picks up the fallback before publish. Switch back to `"ai-hist": "^0.2.0"` once #5 is merged + published.
… history (#20) * feat(ai-hist): Conversations panel — browse Claude/Codex/Cursor/Relay history Adds a "Conversations" view backed by the new ai-hist SDK (AgentWorkforce/relayhistory#3). Matches the conversation-history UX in the Codex and Claude apps: searchable list of recent sessions on the left, full prompt thread on the right, source-color chips, one-click "copy resume command" to re-launch the session in its native CLI. - src/main/ai-hist.ts: lazy-loading manager around `openAiHist()`. Surfaces missing-DB / load failures via getStatus() rather than crashing app startup. - src/main/ipc-handlers.ts + src/preload/index.ts: ai-hist:* IPC channels and a typed `pear.aiHist.*` namespace. - src/renderer/src/components/ai-hist/ConversationsPanel.tsx: two-pane Allotment layout with search, source filter chips, session list, and per-session prompt thread. - src/renderer/src/components/sidebar/Sidebar.tsx: "Conversations" button in the sidebar footer. - src/renderer/src/stores/ui-store.ts + src/renderer/src/App.tsx: registers `ai-hist` as a new AppTabKind / ViewMode. The SDK uses sql.js (WASM SQLite) under the hood — no electron-rebuild required. ai-hist (the Python sync tool) needs to be installed separately; the panel shows a friendly install hint when the DB isn't present. The SDK is consumed via `file:../ai-hist/sdk-ts` for now. Once ai-hist#3 lands and the SDK is published to npm, swap this to a versioned dep. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(ai-hist): switch to dynamic import() for ESM SDK The ai-hist SDK now ships as `type: module`. require() of an ESM package fails at runtime on older Node, so switch the lazy-load path in src/main/ai-hist.ts to `await import('ai-hist')`. The IPC surface is unchanged (handlers already return Promises); resumeCommand is now async too. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(ai-hist): consume published ai-hist@^0.1.1 from npm ai-hist@0.1.1 is now on npm. Swap the `file:../ai-hist/sdk-ts` link to a real versioned dep so end users of pear don't need the ai-hist repo cloned alongside. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(ai-hist): per-project Conversations + group by root + double-click resume - ProjectSidebar: adds a "Conversations" entry under the active project (replaces the global sidebar footer button). Each project gets its own tab via `{ kind: 'ai-hist', projectId }`; the ai-hist tab id now includes projectId so tabs don't collide across projects. - ConversationsPanel: reads the scoped projectId from the active tab, pulls a larger session window (limit 500), and groups sessions by which project root the session.project path matches. Without a scope, groups every pear project's roots + an "Other" bucket. - Session row UX: - single click → load the full prompt thread in the right pane - double click → spawn the session as a pear agent in the matching project (broker.spawnAgent with cli + --resume <sessionId>), open the agents tab, focus the new agent - Detail header: replaces the single "Copy resume command" button with a primary "Resume in pear" + a secondary "Copy" button. - Broker.spawnAgent: preload + renderer PearAPI now expose the `args` field that SpawnPtyInput already accepted server-side, so the renderer can pass `['--resume', sessionId]` (claude/cursor) or `['resume', sessionId]` (codex) without parsing a shell string. - Renderer ipc.ts: added the AiHist* types + the aiHist namespace (was preload-only before, which left the renderer's PearAPI untyped). Sidebar.tsx: removed the global Conversations button since the entry point now lives under each project. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(ai-hist): temporarily point at file:../ai-hist/sdk-ts for 0.2.0 dev ai-hist 0.2.0 (JSONL fallback, AgentWorkforce/relayhistory#5) isn't on npm yet. Use the local checkout so the Conversations panel picks up the fallback before publish. Switch back to `"ai-hist": "^0.2.0"` once #5 is merged + published. * fix(ai-hist): surface getSession errors + empty-state in right pane The right pane was conditionally rendering an empty <ul> when getSession returned [] or rejected, so a failed load looked identical to "loading complete with zero prompts" — i.e. invisible. Adds: - detailError state captured from the IPC promise's catch handler; rendered as a red error card in the right pane. - Explicit empty-state message including the session id so users can report which session id the SDK rejected. These are diagnostic affordances, not a fix for the underlying getSession behavior — they make any future failure visible instead of silent. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(ai-hist): bump dep to published ai-hist@^0.2.1 ai-hist 0.2.1 is now on npm with the JSONL fallback + non-blocking loads. Swap the file: link back to a real versioned dep. * fix(ai-hist): replace Allotment with plain flex — right pane was invisible Root cause of "clicking a conversation shows nothing": the Conversations panel used `Allotment` for the two-pane split, but Allotment's required CSS (allotment/dist/style.css) was never imported anywhere in the renderer. Without it, the right pane rendered at zero width and the transcript was visible to React but not to the user. Switching to plain CSS flex (`w-[380px]` left, `flex-1` right) sidesteps the missing-stylesheet bug and removes the Allotment dependency from this view. Users don't need a draggable splitter for this layout. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * perf(ai-hist): fast session-grouping + debounced search (codex-2) Lifts the conversation-loading and search freeze out of the SDK by doing the slow work in pear's main-process wrapper instead. Drafted by codex-2 via Relaycast after Khaliq reported "search freezes". Three changes: 1. `src/main/ai-hist.ts`: new `fastListSessions` + `fastSearchSessions` methods on the manager. They reach into the SDK's already-open sql.js DB handle, pull the raw rows matching the filters, and group in-memory in JS (Map keyed by source/session_id/project). Falls back to the SDK's slow methods on any error so we stay safe if the internal handle is ever unavailable. New `searchSessions` IPC handler exposed via `ai-hist:search-sessions`. 2. `src/preload/index.ts` + `src/renderer/src/lib/ipc.ts`: expose `pear.aiHist.searchSessions(query, opts)` returning `AiHistSession[]` so the renderer can avoid the previous two-call dance (`search()` followed by `listSessions(500)` to grouping by session_id intersection). 3. `src/renderer/src/components/ai-hist/ConversationsPanel.tsx`: - 150 ms debounce on the search input (was firing per keystroke). - When the query is non-empty, call `searchSessions` instead of `search + listSessions + client-side intersect`. Benchmarks against ~91 MB / 35,857-row DB: - old SDK `listSessions({ limit: 500 })`: ~17.1s - new row-scan session list: ~255ms - new search-session path (filtered): ~277ms Co-Authored-By: codex-2 (via Relaycast) <noreply@anthropic.com> Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(ai-hist): bump dep to ai-hist@^0.2.3 0.2.3 includes the listSessions window-function rewrite + auto-created session_id/timestamp indexes (~68x faster on a 35K-row DB). Pear's main-wrapper bypass (cc6a47f) still works as a safety net, but with 0.2.3 the underlying SDK is fast too — both paths agree. --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Slims specs 01–03 to only the gaps still failing their acceptance, and adds Spec 04 (cloud-agent box endpoints in
../cloud) and Spec 05 (integrations Connect via@relayfile/sdk+ account-wideRelayWorkspaceManager).Why
A check against the in-code acceptance gates showed 01–03 are scaffolded on
mainbut materially incomplete (e.g.cloudAgentManager.restoreexists but is never called on launch;ProactiveAgentsSectionis defined but never rendered; integrations Connect targets a fake random workspace id). 04 and 05 are the cross-repo remediation specs that close the gaps, and the slimmed 01–03 capture what's left after they land.What's in this PR
01-cloud-agents.md,02-integrations.md,03-proactive-agents.md— only the unimplemented bits, each with grep-based acceptance gates and the worktree+PR workflow.04-cloud-agent-box.md,05-integrations-connect.md— full remediation specs with frozen contracts, design decisions, deterministic gates, manual verification.specs/run-remaining-work.shthat iterates in dependency order (05 → 04 → 01 → 02 → 03); removes the legacyrun-overnight.sh(sorted order is wrong now that 05 must precede 04)..claude/projects/.../memory/documenting the cloud credential sources, what a "cloud agent" actually is (provider credential), and the relayfile workspace model.Docs-only — no source changes.
🤖 Generated with Claude Code