lody: an image staged on the landing attaches on a box — seam patch 12 closes seam patch 8's declared gap - #163
Merged
Merged
Conversation
…llback Seam patch 8 named the one attachment entry point it could not fix by moving the guard: `use-chat-landing-image-draft.ts` had no local handoff and no degrade-to-file fallback to move in front of it. So on a box a file attaches from the landing, an image attaches from inside a session, and an image on the LANDING is the single combination that still fails. The behaviour that closes it is upstream's own, one surface away: `session-chat-input-area.tsx` turns an image it cannot upload into a pending file attachment over the local transport. Declare that mirror before making it, and record the upstream PR sketch that lets us drop the patch again. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UhdxNAYjV97JTv2pddcJiN
…token Seam patch 12, five hunks in three files. With no cloud token there is no image upload to attempt, but the landing's sibling FILE draft can still hand the bytes to the machine over its local transport. So the image hook drops the pending image and stages the raw `File` on that draft — the same degrade `session-chat-input-area.tsx` performs when both state machines live in one component, with the same toast. The move re-uses the file draft's own entry point rather than restating `sendSessionFileToLocalRuntime`, so the bytes take seam patch 8's fix, the file draft's limits, its chip and its Retry. Availability is asked of that draft (it already computes `canSendFileLocally`) instead of derived a third time. The inserted block leads with `!authToken`, so with a token set it is skipped and `startUpload` runs the same statements in the same order as before. The cloud-credential guard's text is unchanged and still owns the case where there is no local transport either. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UhdxNAYjV97JTv2pddcJiN
Extends the seam patch 8 suite with the landing-image half, over the same three cases and the same stub `window.ipc`: no token with the bridge (the fix), no token without it (the same refusal, from the unchanged guard), and a token WITH the bridge (the cloud path, untouched). It mounts BOTH real vendored hooks the way `chat-landing.tsx` does, because the mechanism IS the move across them — a harness that mounted the image hook over a hand-written callback would prove nothing about where the bytes go. Verified: the first case fails against the pre-fix vendor tree, and the other two pass there unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UhdxNAYjV97JTv2pddcJiN
The hunk tables list five; the opening line said four. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UhdxNAYjV97JTv2pddcJiN
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.
The defect
Seam patch 8 (#156) fixed attachments on a box by putting the local transport in
front of the cloud-token guard. It named the one entry point it could not fix
that way:
hooks/use-chat-landing-image-draft.tshad no local handoff and nodegrade-to-file fallback, so there was nothing to move.
So on a box today:
An image on the landing is the one remaining combination.
The mechanism, and why this one
The behaviour that closes it is upstream's own, one surface away.
session-chat-input-area.tsx:1004-1066turns an image it cannot upload into apending FILE attachment over the local transport, with the toast
sessions.imageStoredAsLocalFile. In-session that is one component holding bothstate machines, so the image moves from
pendingImagestopendingFilesinplace.
On the landing the same two state machines are two sibling hooks that
chat-landing.tsxmounts side by side and that already share one reservedsession id. So the degrade is the same move across that seam: the image hook
hands the raw
Fileto the file hook's ownaddFiles.That choice does three things a copied transport would not:
about
sendSessionFileToLocalRuntimeis restated in the image hook.status, and its Retry.
canSendFileLocally; it now returns it. The alternative was a third copy oflocalMachineId === machineId && canUseElectronLocalFileSend().The change
Seam patch 12, declared in
vendor/lody/BLITZ-PATCHES.md. Five hunks in threefiles, of which two files were already diverged by seam patches 7 and 8.
hooks/use-chat-landing-image-draft.tsdegradeToFileAttachments, a hoisted label, and the degrade inserted ABOVE the unchanged guardhooks/use-chat-landing-file-draft.tscanSendFileLocallyit already computescomponents/chat/chat-landing.tsxplans/evidence/lody-landing-image-degrade-pr.mdholds the upstream PR sketch.Drop the seam patch when upstream merges the fix.
Safety when a cloud token IS present
The same argument seam patch 8 made, and by construction rather than by
inspection.
The inserted block's condition leads with
!authToken. With a token set it isfalse, sostartUploadruns the same statements in the same order as before —the cloud upload, its telemetry and its
catchare untouched. The guard below itkeeps its exact text and still owns the case where there is no token and no local
transport, which still fails with the same message.
The other three hunks add a parameter, a label and a returned field, and change
no existing expression. The reordered hook calls are independent: the file draft
has never read anything from the image draft.
The degrade is also deliberately NOT extended to a genuine upload failure,
although the in-session path degrades on any failure. Widening it that far would
change what a token holder sees, so this patch keeps to the tokenless case.
Tests
packages/webapp/test/lody-attachment-guard.test.tsxgains the landing-imagehalf, over the same three cases and the same stub
window.ipcseam patch 8 used:transport:'local'FILEblock reaches the outgoing message (this is the fix)
It mounts BOTH real vendored hooks the way
chat-landing.tsxdoes, because themechanism IS the move across them: a harness that mounted the image hook over a
hand-written callback would prove nothing about where the bytes go.
Verified against the pre-fix vendor tree with the new test in place: case 1
fails (
expected [] to deeply equal [ { workspaceId: 'lw_guard', … } ]), cases 2and 3 pass there unchanged.
Gates
npm run typecheck— clean.npm run lint:gate— passed; 74 anti-slop findings, all at baseline.BLITZDEV_MANAGED=1 npm test— 0 assertion failures.The full run reported 8 failed tests in 5 daemon-backed webapp files, every one
of them
lody_daemon_unavailableor a boot timeout: the known port-17789environment issue. Re-run alone, that workspace reports 828 passed, 12 skipped,
0 failed tests. One file still fails at the SUITE level —
test/lody-sharing-relay.test.ts, abeforeAllthat times out waiting for ajoined frame from a real relay, with its 6 tests skipped. No assertion in the
tree fails, and nothing this change touches is reachable from either suite.
A note for the merge queue
Seam patch 12 was free at this branch's base. Another change may claim the same
number for the archive page; whichever lands second renumbers to 13. Nothing
else in the patch depends on the number.
🤖 Generated with Claude Code
https://claude.ai/code/session_01UhdxNAYjV97JTv2pddcJiN