Chat attachments, project knowledge, and the Claude-style project page - #2
Merged
Merged
Conversation
packaging/homebrew-tap/ is the canonical tap content: a brew-style-clean cask for the v0.10.0 arm64 DMG (sha256-pinned, livecheck on GitHub releases, zap for app data) plus maintainer docs for per-release bumps and first-time publishing. Verified end-to-end locally: installed through a local tap, checksum validated by brew, app landed in /Applications. README gains the brew install as the primary macOS path, with --no-quarantine documented for the unsigned app. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Attachments: a paperclip button and window-wide drag & drop join image paste. Images go to vision; text files ride along as fenced context blocks for the model while the transcript shows only "prompt 📎 name" (new label channel through session:send). Size/count caps, binary detection, and a pointer to project knowledge for oversized files. Project knowledge, like Claude's: projects/<id>/knowledge/ holds user-uploaded reference files. The system prompt lists names+sizes only; the agent reads bodies on demand via a read_knowledge tool (path-escape safe, binary-refusing, truncating). Add files via the folder-chip menu (native multi-select) or drop them in the folder (/knowledge opens it). Memory editor: /memory now opens an in-app editor over the real MEMORY.md files — project and global tabs, save, reveal in Finder — so users can curate what the agent remembers without leaving the app. Verified: 8 new knowledge assertions in test:projects; scripted renderer test round-trips the memory editor and confirms the attach affordances. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ecents Clicking a project's name in the rail (caret still collapses) opens a project page like Claude's: rename and description inline; Instructions (INSTRUCTIONS.md, injected ahead of workspace files into every session's system prompt); Memory preview with the editor a click away; Context listing the knowledge files with add/open; Scheduled recurring prompts; and Recents linking back into each session. Typing in the composer on the project page starts a fresh session in that project. Scheduled tasks live in schedule.json per project: a one-minute tick fires due prompts into new sessions (hourly/daily/weekly), and persisted lastRun means restarts never replay missed runs. Memory/knowledge IPC now accepts an explicit projectId so the page can manage non-active projects. Verified: 11 scheduler/instructions assertions plus a scripted renderer run — page opens with all five sections, instructions persist through blur→IPC→disk, schedule add/remove round-trips, recents navigate back. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adopting a running gateway has a fatal race: relaunch the app quickly and it adopts the previous instance's gateway mid-teardown, which then dies — adopted gateways were "not ours to manage", so nothing restarted it and every model call failed with a raw "fetch failed" until the next app restart. The gateway now runs a 20s health watchdog after reaching ready (spawned or adopted): if the engine vanishes, it takes ownership and boots a fresh one on the same port, so live agents recover transparently. Verified by killing the gateway process under a running app — back to HTTP 200 within 75s, hands off. Connection errors now read "Lost connection to the engine — it restarts itself within ~20s" instead of "fetch failed". Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Esc only set a flag the agent checked between steps — mid-stream fetches ran to completion, so stopping looked broken. Aborting now cancels the in-flight request via AbortController, the stream reader bails on the flag, and an aborted turn reports "aborted" (with its stats) instead of an error. Esc also works from anywhere, not just the input box, and oneShot calls carry a 60s timeout so titles/compaction can't hang a turn. The harder bug: approval_request events aren't persisted, so switching sessions destroyed the approval card and the turn hung forever — running, silent, and un-stoppable (abort never reached the parked promise). Each session now remembers its pending approval; switching back re-renders the card, and stop() denies a parked approval before aborting so Esc always lands. Verified: Esc-abort live in the renderer (generation stopped, ✕ stats line); approval lifecycle covered by 8 deterministic assertions in test/approvals.js (park, remember, emit, approve-resolves, stop-denies). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
VedSoni-dev
pushed a commit
that referenced
this pull request
Jul 27, 2026
The new watchdog restarts the engine when it disappears, which is the right behaviour while running but reintroduced the orphan bug 0.9.1 fixed. stop() had no guard against an in-flight start(): quitting while the watchdog was mid-restart let start() finish, spawn a server, and return — after teardown had already run, so nothing was left holding the handle. The gateway stranded on port 20128 and blocked the next launch. Reproduced rather than reasoned about: driving stop() 1.2s into start() against the merged code leaves a live gateway on the port, and the corrupt-storage retry path makes it worse by spawning a *second* server after stop(). With the fix, start() rejects and the port is clear. stop() now latches _stopped, which start() checks before spawning and again after the health probe. The watchdog will not resurrect an engine once shutdown has begun. Teardown moved into #killProc so the retry loop can reuse it without latching shutdown intent — calling stop() there would have aborted the corrupt-database recovery it exists to perform. Reviewed the rest of PR #2 before merging. read_knowledge resolves through path.basename, so a traversal collapses to a filename (verified). The scheduler is UI-created only, not agent-callable, so a prompt-injected model cannot install a recurring task. All eleven suites pass on macOS. Co-Authored-By: Claude <noreply@anthropic.com>
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
Builds on #1 (base branch; this PR auto-retargets to main when #1 merges). Two commits that bring Claude-in-the-browser's context features to OmniWork's coding agent.
Attachments + knowledge + memory editor (3f0c5f3)
prompt 📎 namelabel (new display-label channel throughsession:send). Caps, binary detection, oversized files pointed at project knowledge.projects/<id>/knowledge/reference files, listed (names+sizes) in the system prompt and read on demand via aread_knowledgetool — path-escape safe, binary-refusing, truncation-marked./memoryopens an in-app editor over the realMEMORY.md(project/global tabs, save, reveal in Finder).Project home page (844b120)
Clicking a project's name in the rail opens a Claude-style project page:
INSTRUCTIONS.md, injected ahead of workspace files into every session's prompt, edited inlineelectron/scheduler.js; persistedlastRunso restarts never replay missed runsTest plan
test:scheduler(11 assertions: due/not-due/no-refire/persistence, instructions & description round-trips)test:projectsextended with 8 knowledge assertions (scope safety, binary refusal, truncation)🤖 Generated with Claude Code