Repository navigation
Paste clipboard images into remote and Codespace loops (#819) - #859
Conversation
Independent review of 2d25c98Verdict: no blocking issues. The transport, quoting and stale-reply handling are sound. I found one medium issue, on delete-time cost for Codespace graphs, and three low ones. Every finding below was checked against the code at this head. Findings, by severity
1. Deleting nodes starts stopped Codespaces and fans out dials.
2. A stale swallowed key release.
3. The grant is lost on resume.
4. Overlapping paste notices. Checked and fine
Minor observation, not a finding: the upload's stdin passes through I didn't rebuild or rerun the suite. This review is from reading the code at |
- Remote memory removal is batched by RemoteMemoryJanitor into one rm -rf per project, sent one project at a time. Deleting a 30-loop graph is now one dial instead of 30. - Node and graph deletion never dials a Codespace, because gh would start a stopped one. A cancelled draft that has just uploaded still cleans up. - Clear the swallowed Cmd-V release on the next keyDown, since AppKit often sends no keyUp for a Cmd chord. - Overlapping pastes keep the "Copying image" notice up until the last one finishes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: scgopi <scgopireddy@gmail.com>
|
Review follow-up, in ce09ce3:
New tests: one dial for 30 deletions plus a skipped codespace; codespace removal is refused unless explicitly included; removal of several nodes in one command. GREEN: xcodebuild test -only-testing RemoteAttachmentUploadTests, DraftAttachmentReducerTests, RemoteImagePasteKeyTests, RemoteSessionLaunchTests -> exit 0, 54 tests passed |
launchArguments returned before any --add-dir when there was no prompt, so a resumed session lost the workspace and attachments grants it was launched with. Defaults (Copilot YOLO, Codex YOLO) still emit none. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: scgopi <scgopireddy@gmail.com>
|
Finding 3 is fixed in ebb4e1f. All four review findings are now addressed in this PR.
RED: resume-grant tests with BackendCommand.swift from 2d0bbe8 -> exit 65, both copilotCLI/allowTools and codex/workspace cases failed |
An image on the Mac's pasteboard now reaches a loop running over SSH or in a GitHub Codespace. RemoteAttachmentUpload sends the raw bytes on one ssh process's stdin, through the existing sshInvocation (plain ssh, ports, multiplexing, both Codespace dials). A python3 writer on the host checks the byte count and SHA-256, writes 0600 into ~/.graphcode/memory/<slug>/<node>/ attachments, and publishes with an atomic rename. - Live terminal: an image-only Cmd-V or Ctrl-V on a remote agent surface is uploaded, and "Image available at <path> - inspect it." is typed into the composer. Nothing is submitted. Text pastes are unchanged. - New Node form: remote drafts take images again. They are staged locally and uploaded when Create is pressed. A failed upload keeps the form open and creates nothing. - Every remote launch grants and creates the node's memory directory, so Copilot and Codex can open images pasted mid-session. - Deleting a remote node or graph removes its remote memory, best effort. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: scgopi <scgopireddy@gmail.com>
- Remote memory removal is batched by RemoteMemoryJanitor into one rm -rf per project, sent one project at a time. Deleting a 30-loop graph is now one dial instead of 30. - Node and graph deletion never dials a Codespace, because gh would start a stopped one. A cancelled draft that has just uploaded still cleans up. - Clear the swallowed Cmd-V release on the next keyDown, since AppKit often sends no keyUp for a Cmd chord. - Overlapping pastes keep the "Copying image" notice up until the last one finishes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: scgopi <scgopireddy@gmail.com>
launchArguments returned before any --add-dir when there was no prompt, so a resumed session lost the workspace and attachments grants it was launched with. Defaults (Copilot YOLO, Codex YOLO) still emit none. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: scgopi <scgopireddy@gmail.com>
ebb4e1f to
76ce315
Compare
Closes #819.
What changes
You can now paste an image from the Mac's clipboard into a loop running over SSH or in a GitHub Codespace.
Image available at /home/…/attachments/paste-….png - inspect it.into the composer. Nothing is submitted. Text pastes, local loops and plain shell panes behave exactly as before. A short notice in the pane shows progress or the error.How
RemoteAttachmentUpload(GraphcodeKit/Sessions) sends the raw bytes on one ssh process's stdin, through the existingRemoteProjectLocation.sshInvocation. That covers plain ssh, custom ports, IPv6, ControlMaster, and both Codespace dials. There is no PTY, no base64 and no new transport.python3writer checks the byte count and SHA-256 and writes to a temp file in~/.graphcode/memory/<slug>/<node>/attachments. It then fsyncs, sets mode 0600 (0700 on the directory) and does an atomicos.replace. Only the count, the digest and paths GraphCode generates go into argv, each single-quoted. File names never come from the clipboard.workspacePaths) and creates itsattachments/folder before the agent starts. Copilot and Codex can therefore open images pasted mid-session.rm -rfof that node's remote memory.Evidence
RED: xcodebuild test -only-testing:graphcodeTests/RemoteAttachmentUploadTests with main's sources and this PR's tests -> exit 65, compile errors "cannot find 'RemoteAttachmentUpload' in scope" (52), 'RemoteImagePaste' (20), 'RemoteAttachmentClient' (4)
GREEN: xcodebuild test -only-testing RemoteAttachmentUploadTests, DraftAttachmentReducerTests, RemoteImagePasteKeyTests, PromptAttachmentTests, RemoteSessionLaunchTests -> exit 0, 63 tests passed
GREEN: loopback sshd with a fake HOME (TEST_RUNNER_GRAPHCODE_LOOPBACK_RIG) -> aRealSSHHopDeliversTheExactBytes passed, 300282 bytes byte-identical on the host, mode 0600
REGRESSION: xcodebuild test -scheme graphcode (private DerivedData) -> exit 0, 2321 tests in 262 suites passed
REGRESSION: xcodebuild build -scheme graphcoded and -scheme graphcode-cli -> exit 0 and exit 0; swift build --target GraphcodeKit -> exit 0; swift-portable swift test -> exit 0
REGRESSION: swiftlint lint -> 0 errors, and the new complexity warning was removed; swift format lint --strict -> exit 0
RED: resume-grant tests with BackendCommand.swift from 2d0bbe8 -> exit 65, aResumedLoopKeepsItsDirectoryGrants failed for copilotCLI/allowTools and codex/workspace
GREEN: xcodebuild test -only-testing RemoteAttachmentUploadTests, RemoteSessionResumeTests, CopilotBackendTests, ZmxSessionLauncherTests -> exit 0, 96 tests passed
REGRESSION: xcodebuild test -scheme graphcode after ebb4e1f -> exit 0, 2325 tests in 262 suites passed; swift-portable swift test -> exit 0
Tests cover binary payloads with NUL, invalid UTF-8, newlines and shell metacharacters. They also cover a wrong digest, truncated input and extra bytes: in each case nothing is published and no temp file is left behind. The rest check argv for every host kind (including a multiplexed Codespace), the 10 MB limit, extension and file-name refusal, parsing past login-shell noise, error mapping, the launch grant, mkdir happening before
zmx run, upload-then-create, a failed upload creating nothing, a stale reply for a cancelled draft creating nothing, local drafts never dialing, and a pasteboard holding text plus an image staying text.Not verified
GhosttyTerminalNSView.keyDown) is unit-tested only for key matching. No GUI automation is available on this machine.sshInvocationthat every other Codespace dial uses, but it was not tried against a live or stopped Codespace.