Commit Graph
316 Commits
Author SHA1 Message Date
codingetandClaude d88680c217 fix(smb2): reject state transfer while a disconnect is pending
CI / lint (pull_request) Successful in 46s
CI / format (pull_request) Successful in 45s
CI / install (pull_request) Successful in 3m39s
CI / typetest (pull_request) Successful in 45s
CI / node-tests (pull_request) Successful in 59s
CI / typecheck (pull_request) Successful in 59s
CI / browser-tests (pull_request) Successful in 2m2s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 23:21:16 +00:00
codingetandClaude 8ade10c020 feat(smb2): implement cross-tab state transfer on SMB2Client
Implements StateTransferable<SMB2TransferState> and SMB2Client.adopt()
per issue #99. An idle client detaches and exports the parked-transport
token plus the protocol state needed to continue the authenticated
session: dialect, negotiated sizes, message-id/credit counters, session
and tree ids, preauth hash, and the derived signing key. Credentials are
never serialized; the adopter supplies them and may opt into reconnect
fallback, which never reuses transferred signing state on a new dial.
Transfer rejects unless quiescent (no request in flight, no pending
connect, no stream owning a file handle).

Closes #99

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 23:21:16 +00:00
codingetandCodex fb8290e29b fix(ftp): detach control state atomically
CI / format (pull_request) Successful in 43s
CI / lint (pull_request) Successful in 44s
CI / install (pull_request) Successful in 3m45s
CI / typetest (pull_request) Successful in 46s
CI / node-tests (pull_request) Successful in 56s
CI / typecheck (pull_request) Successful in 1m0s
CI / browser-tests (pull_request) Successful in 2m4s
Co-Authored-By: GPT-5.6 Terra <noreply@openai.com>

Co-Authored-By: GPT-5.6 Sol <noreply@openai.com>
2026-07-19 23:14:16 +00:00
codingetandCodex f8cf4c9bf3 feat(ftp): transfer client control state
Co-Authored-By: GPT-5.6 Terra <noreply@openai.com>
2026-07-19 23:13:00 +00:00
codingetandCodex a1eca114ce fix(http-static): use HTTP paths in listings
CI / lint (pull_request) Successful in 1m45s
CI / format (pull_request) Successful in 2m27s
CI / install (pull_request) Successful in 5m53s
CI / typetest (pull_request) Successful in 2m3s
CI / node-tests (pull_request) Successful in 2m23s
CI / typecheck (pull_request) Successful in 2m29s
CI / browser-tests (pull_request) Successful in 4m3s
Co-Authored-By: GPT-5.6 Luna <noreply@openai.com>
2026-07-14 00:47:56 +00:00
codingetandCodex d1803a37de test(http-static): cover precedence vectors
Co-Authored-By: GPT-5.6 Luna <noreply@openai.com>
2026-07-14 00:47:56 +00:00
codingetandCodex a5c0a66d9a fix(http-static): address review findings
Co-Authored-By: GPT-5.6 Luna <noreply@openai.com>
2026-07-14 00:47:56 +00:00
codingetandCodex 99cdd9322b feat(http-static): add VFS static handler
Co-Authored-By: GPT-5.6 Luna <noreply@openai.com>
2026-07-14 00:47:56 +00:00
codingetandCodex 6f54110fe5 feat(vfs): centralize canonical path helpers
CI / format (pull_request) Successful in 1m50s
CI / lint (pull_request) Successful in 1m53s
CI / install (pull_request) Successful in 5m15s
CI / typetest (pull_request) Successful in 2m1s
CI / node-tests (pull_request) Successful in 2m23s
CI / typecheck (pull_request) Successful in 2m25s
CI / browser-tests (pull_request) Successful in 3m57s
Co-Authored-By: GPT-5.6 Luna <noreply@openai.com>
2026-07-13 23:42:16 +00:00
codingetandCodex b2d04de758 fix(sftp): stabilize keyless server host key
CI / lint (pull_request) Successful in 1m47s
CI / format (pull_request) Successful in 2m13s
CI / install (pull_request) Successful in 6m12s
CI / typetest (pull_request) Successful in 2m4s
CI / node-tests (pull_request) Successful in 2m27s
CI / typecheck (pull_request) Successful in 2m32s
CI / browser-tests (pull_request) Successful in 4m12s
Co-Authored-By: GPT-5.6 Luna <noreply@openai.com>
2026-07-13 00:20:18 +00:00
codinget b35a533164 feat(test-app): add ssh to test-app
CI / format (pull_request) Successful in 1m41s
CI / lint (pull_request) Successful in 1m53s
CI / install (pull_request) Successful in 6m7s
CI / typetest (pull_request) Successful in 2m13s
CI / node-tests (pull_request) Successful in 2m35s
CI / typecheck (pull_request) Successful in 2m36s
CI / browser-tests (pull_request) Successful in 4m2s
2026-07-12 23:41:20 +00:00
codingetandClaude 2d954c1bfb fix(ssh): address second-round review (send deadlock, pipe DoS, connect leaks)
CI / lint (pull_request) Successful in 2m1s
CI / format (pull_request) Successful in 2m25s
CI / install (pull_request) Successful in 6m57s
CI / typetest (pull_request) Successful in 1m22s
CI / node-tests (pull_request) Successful in 1m50s
CI / typecheck (pull_request) Successful in 1m57s
CI / browser-tests (pull_request) Successful in 3m18s
- Channel.send() no longer deadlocks when the peer closes while the
  sender is window-blocked: _deliverClose wakes #windowWaiters and send()
  aborts on a remotely-closed channel.
- pipe()'s copy loop guards writes (not just reads) and both call sites
  swallow, so a write failure on a forwarded socket can't become an
  unhandledRejection that crashes the process.
- Connect-phase failures close the transport/connection instead of
  leaking the socket (SSHClientConnection.connect on auth failure;
  SFTPClient.#doConnect on openSubsystem/init failure).
- authenticateServer accepts a falsy auth context; #matchForward fails
  closed on an ambiguous port; acceptSession() rejects once the accept
  loop dies; duplicate tcpip-forward closes the superseded listener;
  RemoteForward teardown closes queued transports.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 23:31:57 +00:00
codingetandClaude f456e4977a fix(ssh): harden remote-forward routing and accept-loop teardown
Key remote forwards by bind host and port (not port alone) so two
forwards sharing a port stay distinct; guard the accept loops against a
failing CHANNEL_OPEN_CONFIRMATION send (close the upstream, keep the loop
alive); reject pending RemoteForward.accept() waiters when the connection
closes or its mux fails.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 23:31:57 +00:00
codingetandClaude 2de0529c4e docs: record @webnet/ssh split and TCP forwarding in AI_CHANGES
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 23:31:57 +00:00
codingetandClaude 6a67b1810a test(ssh): add opt-in OpenSSH forwarding interop suite
Env-gated (SSH_TEST_*) suite exercising direct-tcpip and a remote-forward
loop against a real sshd; verified against a local OpenSSH server.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 23:31:57 +00:00
codingetandClaude fa99bbbbbc refactor(sftp): build on the @webnet/ssh connection API
SFTPClient and the server Session now use SSHClientConnection/
SSHServerConnection instead of driving the transport, auth, and mux
directly; behaviour is unchanged and the full suite passes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 23:31:57 +00:00
codingetandClaude cbfa524c36 feat(ssh): add client and server connections with TCP forwarding
SSHClientConnection/SSHServerConnection wrap the transport, auth, and
channel mux; expose direct-tcpip local forwarding (dialer()) and
tcpip-forward remote forwarding (RemoteForward as a RawListener).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 23:31:57 +00:00
codingetandClaude 0649e0939b feat(ssh): add a RawTransport adapter for channels
channelTransport() wraps a Channel as a @webnet/transport RawTransport
(EOF as throw + readEnded, halfClose as CHANNEL_EOF); pipe() bridges two
transports for onward forwarding.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 23:31:57 +00:00
codingetandClaude 5937f3aae2 feat(ssh): generic channel opens and global requests
ConnectionMux gains configurable accept types and a global-request
handler; adds direct-tcpip/forwarded-tcpip channel opens, tcpip-forward
global requests, and closed/readEnded/whenClosed on Channel.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 23:31:57 +00:00
codingetandClaude 70c2c714d5 refactor(ssh): decouple server auth from VFS
authenticateServer is now generic over an authentication context and
auth failures throw SSHAuthError; @webnet/sftp maps those back to
VFSError("forbidden") at its boundary.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 23:31:57 +00:00
codingetandClaude 3837e0aeb4 feat(ssh): extract SSH-2 layer into @webnet/ssh
Pure file moves of the transport, kex, cipher, auth, and channel
modules out of @webnet/sftp into a standalone package; @webnet/sftp
now consumes them via @webnet/ssh and @webnet/ssh/_internals.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 23:31:57 +00:00
codinget 4ea36eb05b feat(test-app): add sftp to test-app
CI / lint (pull_request) Successful in 1m48s
CI / format (pull_request) Successful in 2m9s
CI / install (pull_request) Successful in 6m18s
CI / typetest (pull_request) Successful in 2m8s
CI / typecheck (pull_request) Successful in 2m24s
CI / node-tests (pull_request) Successful in 2m23s
CI / browser-tests (pull_request) Successful in 4m9s
2026-07-12 22:59:01 +00:00
codingetandClaude 548c71ab3e docs(sftp): note the short-read fix and intentional limitations
CI / lint (pull_request) Successful in 1m54s
CI / format (pull_request) Successful in 2m7s
CI / install (pull_request) Successful in 6m27s
CI / typetest (pull_request) Successful in 2m13s
CI / typecheck (pull_request) Successful in 2m32s
CI / node-tests (pull_request) Successful in 2m33s
CI / browser-tests (pull_request) Successful in 4m15s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F3bV2ANs8WMHxefD5pF9LN
2026-07-12 22:33:52 +00:00
codingetandClaude 645be18912 fix(sftp): handle short reads in the client read pipeline
From the neutral review: the pipelined reader advanced offsets by the
requested length, so a spec-legal short mid-file READ (pipes, special files,
some non-OpenSSH servers) left an un-requested gap and silently delivered a
corrupt, short file. Track each requests offset and requested size, and on a
short non-EOF read reset to just past the returned bytes and re-issue,
discarding the now-misaligned in-flight requests (with a catch so they never
become unhandled rejections). Also cancel the source stream with the write
error on the writeFile error path so the producer is signalled to stop.
Regression test drives a server that short-reads mid-file (verified failing
without the fix). 203 tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F3bV2ANs8WMHxefD5pF9LN
2026-07-12 22:32:11 +00:00
codingetandClaude 680d25f5d3 docs(sftp): note the code-review hardening in the AI disclosure
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F3bV2ANs8WMHxefD5pF9LN
2026-07-12 22:32:11 +00:00
codingetandClaude 7535225514 fix(sftp): address code-review findings in the server and channel layers
From the autonomous review of the package:
- server/session: wrap the whole session (auth, channel accept, subsystem
  request) in try/finally so a malformed post-handshake packet closes the
  transport instead of leaking it and its read loop.
- server/handles: WriteQueue.fail() releases a writer blocked on backpressure,
  and a failed vfs.writeFile now fails the queue, so a WRITE stuck behind a
  broken VFS consumer rejects instead of orphaning the request and its handle
  mutex forever.
- ssh/channel: enforce the advertised receive window, failing the channel if a
  peer sends more CHANNEL_DATA than the credit granted (bounded buffering).
- sftp/packets: reject a zero-length SFTP packet instead of reading a byte past
  the validated length.
Adds regression tests for each. 202 tests; interop with the OpenSSH sftp CLI
re-verified.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F3bV2ANs8WMHxefD5pF9LN
2026-07-12 22:32:11 +00:00
codingetandClaude 9ffa25f402 docs(sftp): add AI disclosure entry for the @webnet/sftp package
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F3bV2ANs8WMHxefD5pF9LN
2026-07-12 22:32:11 +00:00
codingetandClaude d00c66fb8c feat(sftp): wire package exports and add end-to-end integration suite
Export SFTPClient/SFTPServer and their option types from the package root
and subpath barrels. Add the real client-against-real-server loopback suite
(18 tests over encrypted transport: round-trips incl. a 4 MiB transfer,
ranged reads, recursive delete, posix-rename overwrite, utf8 names,
pipelined concurrency, cancel-then-continue, password/publickey/per-user
auth, and host-key verification) plus an env-gated suite against a real
OpenSSH sshd. Interop-tested against the OpenSSH sftp CLI driving our server,
which surfaced one fix: acceptSubsystem now denies benign pre-subsystem
channel requests (the CLI env request) with CHANNEL_FAILURE and keeps waiting
for the subsystem request instead of tearing the session down.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F3bV2ANs8WMHxefD5pF9LN
2026-07-12 22:32:11 +00:00
codingetandClaude 6f8b159f65 feat(sftp): add SFTP v3 server serving any AsyncVFS
SFTPServer.listen runs an accept loop mirroring the FTP server; each
connection runs the SSH server transport, authenticates via the pluggable
callback (per-user AsyncVFS), accepts the sftp subsystem channel, and serves
an FXP dispatch loop. Handlers map OPEN/READ/WRITE/CLOSE, OPENDIR/READDIR
(100 entries per batch with ls-style longnames), STAT/LSTAT/FSTAT,
REMOVE/RMDIR/MKDIR, RENAME (v3 fail-on-exists) and posix-rename@openssh.com
overwrite, and REALPATH onto the VFS; SETSTAT/FSETSTAT are accepted as no-ops
so OpenSSH put succeeds. Reads stream from the VFS with per-handle
serialization; writes stream sequentially into vfs.writeFile with a
backpressured queue and reject non-sequential offsets. Responses are
serialized on one send chain so split DATA frames never interleave, and a
handler error replies a status without tearing down the session. 17 tests
against an in-suite mock client.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F3bV2ANs8WMHxefD5pF9LN
2026-07-12 22:32:11 +00:00
codingetandClaude 5e2d1798c7 feat(sftp): add SFTP v3 client implementing AsyncVFS
SFTPClient dials through a RawDialer, runs the SSH transport/auth/channel
stack, opens the sftp subsystem, and maps AsyncVFS verbs onto SFTP v3
operations. SftpSession pipelines requests over one channel with a
request-id dispatch map, serializing only the wire writes so a WRITE packet
that splits across channel frames stays contiguous. readFile/readFileRange
return pull-driven ReadableStreams keeping up to 8 outstanding 32 KiB READs
at sequential offsets; writeFile pumps with the same in-flight bound and
fails fast. delete recurses client-side; move uses posix-rename@openssh.com
for overwrite when advertised. 12 tests against an in-suite mock server incl.
a 4 MiB round-trip, ranged reads, concurrent ops, and cancel-then-continue.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F3bV2ANs8WMHxefD5pF9LN
2026-07-12 22:32:11 +00:00
codingetandClaude 502e3cabb6 feat(sftp): add SSH userauth and connection channel layer
Client and server halves of ssh-userauth: client tries a direct signed
Ed25519 publickey request then falls back to password; server drives the
none/publickey(PK_OK)/password flow through a pluggable authenticate
callback returning a per-user AsyncVFS, capping failed attempts. ConnectionMux
runs the post-auth dispatch loop and Channel implements the session channel
with the sftp subsystem request and bidirectional window flow control:
outbound sends block on WINDOW_ADJUST, inbound window is replenished only as
the consumer reads, giving end-to-end backpressure bounded at the 1 MiB
window. 15 tests incl. a 4 MiB windowed transfer and stalled-reader
backpressure.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F3bV2ANs8WMHxefD5pF9LN
2026-07-12 22:32:11 +00:00
codingetandClaude 7a75e59bc3 feat(sftp): add SSH transport layer with kex, ciphers, and rekey
Role-shared SSHTransport over RawTransport: version-banner exchange with
pre-banner-line tolerance, binary packet framing with per-direction sequence
numbers, curve25519-sha256 key exchange with Ed25519/RSA host-key
verification, RFC 4253 key derivation, and transparent peer- or
self-initiated rekey via a send gate. Data-driven PacketCipher covers
aes128/256-gcm@openssh.com, aes128/256-ctr with hmac-sha2-256 and
hmac-sha2-256-etm@openssh.com; continuous CTR counter and GCM invocation
nonce tracked across packets. 39 tests incl. a 1000-packet encrypted echo
and mid-stream rekey over loopback.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F3bV2ANs8WMHxefD5pF9LN
2026-07-12 22:32:11 +00:00
codingetandClaude d895ec7eec feat(sftp): package scaffold, SSH codecs, keys, and SFTP wire helpers
New @webnet/sftp package skeleton: big-endian SSH cursor (string/nameList/
mpint), SSH message constants, openssh-key-v1 Ed25519 key parse/serialize
with PKCS#8 seed wrapping and generateHostKey(), host-key/signature blob
codecs with Ed25519/RSA verification and SHA256 fingerprints, SFTP v3
packet/ATTRS codecs with Stat mapping and packet reassembly, SSH_FX status
to VFSError mapping, unix ls longname formatter, and lexical path helpers.
95 unit tests.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F3bV2ANs8WMHxefD5pF9LN
2026-07-12 22:32:11 +00:00
codinget bbda6e6688 docs(smb2): note response-signature verification in AI disclosure
CI / format (pull_request) Successful in 2m4s
CI / lint (pull_request) Successful in 2m4s
CI / install (pull_request) Successful in 6m26s
CI / typetest (pull_request) Successful in 2m7s
CI / node-tests (pull_request) Successful in 2m24s
CI / typecheck (pull_request) Successful in 2m45s
CI / browser-tests (pull_request) Successful in 6m50s
Reflect the final state in AI_CHANGES.md: the client verifies inbound
response signatures (not just signs requests), advertises no cipher, and
the mock server does a real signed round-trip with tamper/unsigned
rejection tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Claude-Session: https://claude.ai/code/session_014AcGBx7EjVaByiHcBcsSfP
2026-07-12 20:17:03 +00:00
codingetandClaude ba9579aa09 fix(smb2): verify response signatures; fix connect caching and mapping
CI / format (pull_request) Successful in 1m36s
CI / lint (pull_request) Successful in 1m46s
CI / install (pull_request) Successful in 5m43s
CI / typetest (pull_request) Successful in 1m55s
CI / node-tests (pull_request) Successful in 2m13s
CI / typecheck (pull_request) Successful in 2m13s
CI / browser-tests (pull_request) Successful in 3m44s
Address the second-pass review of PR #60:

- Verify inbound signatures. Once a signed session is established, the
  client now requires every response to carry the SIGNED flag and a valid
  signature (recomputed over the message with the signature field zeroed,
  compared constant-time), rejecting otherwise, per [MS-SMB2] 3.2.5.1.3 —
  signing requests without verifying responses left signed sessions open
  to response tampering/injection. Also sanity-check the response
  message id. The mock server now derives the real session/signing key and
  signs its responses, so the end-to-end tests exercise the signed
  round-trip, with new tests asserting tampered and unsigned responses are
  rejected.
- Don't cache a rejected connect: a transient dial/auth failure no longer
  wedges every later operation until disconnect().
- Map connect-time Smb2Error to VFSError in #doConnect, so LOGON_FAILURE /
  BAD_NETWORK_NAME / ACCOUNT_DISABLED surface as proper VFSErrors.
- writeFile cancels the source stream on a mid-stream error.
- parseFileIdBothDirInfo returns [] on an empty buffer instead of throwing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014AcGBx7EjVaByiHcBcsSfP
2026-07-12 19:28:12 +00:00
codingetandClaude 353fd71c2e fix(smb2): don't advertise unsupported SMB3 encryption
Address autonomous review of PR #60:
- NEGOTIATE no longer advertises the ENCRYPTION capability or any cipher,
  so a server never selects encryption. A share that mandates encryption
  now fails cleanly at TREE_CONNECT (ACCESS_DENIED -> forbidden) instead of
  sending a transform header the client cannot decrypt. The encryption
  negotiate context is omitted entirely when no cipher is offered.
- Guard against a received SMB2 TRANSFORM (encrypted) message with a clear
  error rather than an opaque "bad SMB2 magic" parse failure.
- deriveSigningKey now handles only the dialects actually offered
  (SMB 3.1.1 via SP800-108, <=2.1 via the session key) and throws for any
  other 3.x dialect instead of silently using the 3.1.1 label.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014AcGBx7EjVaByiHcBcsSfP
2026-07-12 19:28:12 +00:00
codingetandClaude ac7a7ab464 feat(smb2): add SMB2/3 client with async VFS interface
Add @webnet/smb2, an SMB2/3 client that runs over the existing transport
abstraction and exposes a remote Windows/Samba share as an AsyncVFS, the
same way @webnet/drive exposes WebDAV. Targets default Windows 10/11
(including 24H2 mandatory signing) and supported Samba, negotiating
dialects {2.0.2, 2.1, 3.1.1}.

Runs unchanged in browser and Node with no Node APIs and no new
dependencies: MD4/MD5/HMAC-MD5 are hand-written (NTLM only), AES-CMAC is
built on Web Crypto AES-CBC, SP800-108 KDF on HMAC-SHA256, and SHA-512
preauth and HMAC-SHA256 signing use Web Crypto. NTLMv2 over NTLMSSP/SPNEGO
with MIC; SMB signing implemented, SMB3 encryption deferred.

Includes crypto/auth vector tests, protocol codec round-trips, an in-repo
mock SMB2 server for end-to-end coverage over the loopback transport, and
an env-gated integration test. Wired into test-app as window.smb2.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014AcGBx7EjVaByiHcBcsSfP
2026-07-12 19:28:12 +00:00
codingetandCodex 50db8b7707 fix(ftp): enforce protected data negotiation
CI / lint (pull_request) Successful in 1m43s
CI / format (pull_request) Successful in 1m56s
CI / install (pull_request) Successful in 5m57s
CI / typetest (pull_request) Successful in 2m5s
CI / node-tests (pull_request) Successful in 2m16s
CI / typecheck (pull_request) Successful in 2m24s
CI / browser-tests (pull_request) Successful in 3m59s
Co-Authored-By: GPT-5.6-Sol <noreply@openai.com>
2026-07-12 19:00:21 +00:00
codingetandCodex 3a6ed85c69 feat(ftp): support explicit TLS upgrades
Co-Authored-By: GPT-5.6-Sol <noreply@openai.com>
2026-07-12 19:00:21 +00:00
codingetandClaude 5bcf7fb0a7 docs: record TLS-upgrade integration in AI_CHANGES.md
CI / format (pull_request) Successful in 1m33s
CI / lint (pull_request) Successful in 1m48s
CI / install (pull_request) Successful in 5m45s
CI / typetest (pull_request) Successful in 1m57s
CI / node-tests (pull_request) Successful in 2m10s
CI / typecheck (pull_request) Successful in 2m13s
CI / browser-tests (pull_request) Successful in 3m39s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 17:15:12 +00:00
codingetandClaude f2f2293f13 feat(tsconnect-worker): integrate TLS upgrades with state transfer
Transferred conns keep their TLS state: claim replies and conn
ResourceMeta carry isTls, upgradeTls is serialized through the resource
chan lock (never overlapping an in-flight read, reply dropped on detach
mid-upgrade), and transferState refuses while an upgrade is in progress.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 17:15:09 +00:00
codingetandClaude 33b9ff5c65 docs: record state transfer review round in AI_CHANGES.md
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 17:09:12 +00:00
codingetandClaude 3a7c711484 fix(http): prune emptied pool slots on exportIdle
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 17:09:12 +00:00
codingetandClaude b0a641a68d fix(drive): close remaining exports when transferState fails mid-loop
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 17:09:12 +00:00
codingetandClaude 82396fffc0 fix(tsconnect-worker): collect nested transfer tokens and fix replay order
transfer() only recognized a bare TransferToken, so composite states like
DavTransferState were sent with an empty tokens list, skipping worker-side
validation and queue-expiry cleanup. Handshake-buffered envelopes are now
replayed before awaiting the client lock so channel ordering is preserved,
and the main-thread promise-returning stubs reject instead of throwing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 17:09:12 +00:00
codingetandClaude 8944a8a8fc fix(tsconnect-worker): preserve in-flight results across ownership transfer
Results of reads/accepts that were in flight when a resource was detached
were delivered to the old owner's dead port, and accepted conns were
registered on (and leaked with) the old client entry. Each resource now
carries a generation-tagged channel; stale completions are deposited into
a backlog the next owner's bridge drains first, serialized so stream order
is preserved. TTL expiry and cancel close backlogged conns.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 17:09:12 +00:00
codingetandClaude b7f3bd46c3 docs: record state transfer work in AI_CHANGES.md
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 17:08:12 +00:00
codingetandClaude a228434d11 test(tsconnect-worker): two-tab state transfer browser tests
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 17:08:12 +00:00
codingetandClaude 007f1695bb fix(tsconnect-worker): buffer transfer envelopes during connect handshake
Envelopes flushed by the worker when a client key registers arrive before
ready and were dropped by the temporary handshake handler.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 17:08:12 +00:00
codingetandClaude c2a4414b0d feat(drive): state transfer support via pool export and adopt
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-07-12 17:08:12 +00:00