Fix Ctrl+] attach controls on Windows - #4
Closed
JeremiahM37 wants to merge 58 commits into
Closed
JeremiahM37 wants to merge 58 commits into
JeremiahM37 wants to merge 58 commits into
Conversation
A message sent to a session is staged at /tmp/… by Go and pasted by a command line. On Windows Go wrote C:\tmp\… while Git Bash, and the lectern it runs, read the user's temp directory, where Git mounts /tmp. Local file reads and writes now map /tmp to that directory and other root paths into Git's installation, as Git Bash does. The local runtime's PATH merge treats Windows directories case-insensitively, and its test uses paths that are absolute on each OS.
Windows cannot delete a running executable, and the test's PTY host and terminal server are still exiting when t.TempDir is removed.
…ity test CI's python3 is 3.12, which words them differently from 3.13; the Go port follows 3.13, and callers only see that the document is invalid.
… standing in, own-folder commit warning and a real message, chat keeps its last line, sessions named by project and topic with inline rename, a calm Sessions page, three-item navigation
…ion, and let the demo ask once Starting an agent whose program is not on the machine now fails before a session exists (422 agent_not_installed, naming the agents that are installed and how to install this one) instead of reporting Started and then Idle over "command not found". A pending approval expires once its session has ended or its agent has exited, swept on the scheduler tick so every way a session ends is covered. A real-process test proves an agent that dies while asking reads Ended · agent exited on both the pty and tmux backends. In ask mode the demo agent asks for approval before its first write, through the same PermissionRequest hook a real agent uses, and points at Review & merge.
…s and controls readable without a terminal With no LECTERN_DB, a server (lectern serve, or bare lectern with no terminal) now uses ~/.local/state/lectern/server/lectern.db instead of the folder it was started in; an existing ./lectern.db is still used, so no install loses its data, and the startup log names the file. local status is a sentence by default and JSON with --json. controls with no terminal says to use lectern api instead of failing inside the TUI. up names an installed agent, or the demo, rather than always lectern claude.
The private runtime can now also listen on this computer's Wi-Fi address, on request, serving the same sessions and database. Settings → Connect your phone gets a "Let phones on this Wi-Fi connect" button, and lectern phone does the same from the terminal, printing a QR code for a one-time pairing link (5 minutes), a warning that the LAN connection is unencrypted, and the Tailscale and relay alternatives; lectern phone --off stops it. Only paired devices get in from the network: the app is in token mode, the LAN gate refuses other host names and origins, never accepts the runtime token, and keeps the runtime's own controls off the network. The device cookie drops Secure only for plain HTTP from the network, where a browser would otherwise discard it. The wizard no longer tells people to run lectern serve, which listens on localhost and keeps its own database.
docs/getting-started.md is three steps per OS (install, lectern up, start an agent) with the phone, doctor and update next. quickstart.md becomes "Run a shared server" (install, a token, lectern serve), local.md drops the tmux and Python requirements, the WSL-only Windows story and the macOS-experimental note, and README, guide and terminal-client link to the new page. install.ps1 and the MCP example use a neutral server address.
…screen; the plain pty attach never sends Ctrl+\
… Ctrl+] keys, needs-you note, links, panes and clipboard
… here, the chat's status; docs for attaching without tmux
…to the suite The conversation log stays at the bottom while output grows (mutation and resize observers), the header follows a rename, and More agents counts only installed ones. Choosing a grouping brings the list tools back inline, the scratch cleanup is reachable from the ⋯ menu when the page is short, a launch profile is left to the server to judge, and sessions without a project say so again. Browser tests follow controls into the card and header menus.
Revive used to close the session's terminal first and only then find the agent's program missing, leaving nothing. The check now runs first, so a refusal leaves the session as it was. The revive browser test gets an installed stand-in agent.
A fresh machine has no git identity. Commit on a new branch used to switch the person's own folder first and only then fail at the commit with "Commit step commit failed". The server now checks with git var before anything moves and answers no_git_identity; the Commit tab says nothing was changed and shows the two git config commands. Real-git API test plus a browser test at 1440 and 390 that also sweeps the round-two controls for contrast in light and dark.
# Conflicts: # web/index.html # web/static/react/assets/PaneViews-B5L5XKMF.js # web/static/react/assets/PaneViews-B6rbhOIr.js # web/static/react/assets/PaneViews-D8gj3EW6.js # web/static/react/assets/RichMarkdown-CdeDviL6.js # web/static/react/assets/RichMarkdown-CkKq-iQw.js # web/static/react/assets/RichMarkdown-Q7wKu4Uf.js # web/static/react/assets/Workbench-CdOmoDCG.js # web/static/react/assets/Workbench-D51V6bXy.js # web/static/react/assets/Workbench-DBwIuJ1J.js # web/static/react/assets/abnfDiagram-VCTEODGH-CgOqIBwZ.js # web/static/react/assets/abnfDiagram-VCTEODGH-DKY9TBy2.js # web/static/react/assets/abnfDiagram-VCTEODGH-ltFbF4bW.js # web/static/react/assets/action-C0ldWb1-.js # web/static/react/assets/action-D3z6nmti.js # web/static/react/assets/action-DgoT6u-Z.js # web/static/react/assets/app-Bmi8DgMA.js # web/static/react/assets/app-CTcV2nNz.js # web/static/react/assets/app-HJ02Pyjy.js # web/static/react/assets/architectureDiagram-5GKGNRK7-BRTty8u2.js # web/static/react/assets/architectureDiagram-5GKGNRK7-Bw87b9i6.js # web/static/react/assets/architectureDiagram-5GKGNRK7-CFEfKN02.js # web/static/react/assets/blockDiagram-I7D4REHJ-B43PE8Y2.js # web/static/react/assets/blockDiagram-I7D4REHJ-JwTq3G7e.js # web/static/react/assets/blockDiagram-I7D4REHJ-QYYDLsdu.js # web/static/react/assets/c4Diagram-7LVT6UL2-BWoAerJ6.js # web/static/react/assets/c4Diagram-7LVT6UL2-BZZhjbEk.js # web/static/react/assets/c4Diagram-7LVT6UL2-D--ne6hm.js # web/static/react/assets/chunk-4HAMMTFA-CdyC4Ca2.js # web/static/react/assets/chunk-4HAMMTFA-Dak6WsV_.js # web/static/react/assets/chunk-4HAMMTFA-mdRFDOQ4.js # web/static/react/assets/chunk-75Z2AOVW-957CGxL_.js # web/static/react/assets/chunk-75Z2AOVW-Cg5bWo8T.js # web/static/react/assets/chunk-75Z2AOVW-D3qL2gXT.js # web/static/react/assets/chunk-DU6HZSFF-BFfOPqFa.js # web/static/react/assets/chunk-DU6HZSFF-Cbm9CLOn.js # web/static/react/assets/chunk-DU6HZSFF-D1jeAJym.js # web/static/react/assets/chunk-F27PBJKO-B6p4kuxZ.js # web/static/react/assets/chunk-F27PBJKO-CmHVe2h8.js # web/static/react/assets/chunk-F27PBJKO-DR5D88Sn.js # web/static/react/assets/chunk-GMAD6QVW-BbSp6lwD.js # web/static/react/assets/chunk-GMAD6QVW-BlJGfzaZ.js # web/static/react/assets/chunk-GMAD6QVW-DJ0HFV-9.js # web/static/react/assets/chunk-GVQU2GXP-C5zDAV40.js # web/static/react/assets/chunk-GVQU2GXP-C9WxBu4F.js # web/static/react/assets/chunk-GVQU2GXP-CauUILic.js # web/static/react/assets/chunk-IMKFNOWR-BUSVbXBH.js # web/static/react/assets/chunk-IMKFNOWR-ChnfBiKh.js # web/static/react/assets/chunk-IMKFNOWR-DvqWDvr9.js # web/static/react/assets/chunk-L3NEJ4N5-BWybKPpb.js # web/static/react/assets/chunk-L3NEJ4N5-CANtKTzf.js # web/static/react/assets/chunk-L3NEJ4N5-DVIsDcNf.js # web/static/react/assets/chunk-OSK3NFVY-3uy8HQ7C.js # web/static/react/assets/chunk-OSK3NFVY-CNsef5RK.js # web/static/react/assets/chunk-OSK3NFVY-YOvPXRUq.js # web/static/react/assets/chunk-P2QGCYS3-B_X5W4pU.js # web/static/react/assets/chunk-P2QGCYS3-HOusNWqu.js # web/static/react/assets/chunk-P2QGCYS3-ZYJrOuD2.js # web/static/react/assets/chunk-POPQ4Y6H-B0DgyP_F.js # web/static/react/assets/chunk-POPQ4Y6H-BS1qkyAi.js # web/static/react/assets/chunk-POPQ4Y6H-jcI2QP6z.js # web/static/react/assets/chunk-PWAF6VOD-3-U8Cpu4.js # web/static/react/assets/chunk-PWAF6VOD-CqU5YIKz.js # web/static/react/assets/chunk-PWAF6VOD-FiDglwd7.js # web/static/react/assets/chunk-SHT3W25Y-3X5XhVEE.js # web/static/react/assets/chunk-SHT3W25Y-B99-GcGT.js # web/static/react/assets/chunk-SHT3W25Y-Cw59llsa.js # web/static/react/assets/chunk-SVP7TREG-C8nDz84A.js # web/static/react/assets/chunk-SVP7TREG-CLFgXFZw.js # web/static/react/assets/chunk-SVP7TREG-DqIbIAXI.js # web/static/react/assets/chunk-TICWLB2K-11py4ySH.js # web/static/react/assets/chunk-TICWLB2K-BcBOiewN.js # web/static/react/assets/chunk-TICWLB2K-CgD3mLAO.js # web/static/react/assets/cynefinDiagram-5FMLGOSQ-Bg8npMjQ.js # web/static/react/assets/cynefinDiagram-5FMLGOSQ-CUdy8fVG.js # web/static/react/assets/cynefinDiagram-5FMLGOSQ-DPGGFZfU.js # web/static/react/assets/dagre-GXQ25YYZ-BIRe1ppJ.js # web/static/react/assets/dagre-GXQ25YYZ-BhaXSzM7.js # web/static/react/assets/dagre-GXQ25YYZ-DW0SlLhR.js # web/static/react/assets/diagram-S7CK7UJ4-A65jJNTc.js # web/static/react/assets/diagram-S7CK7UJ4-Cfkh_bWv.js # web/static/react/assets/diagram-S7CK7UJ4-TX-CUmRL.js # web/static/react/assets/diagram-UQ7AKVKN-BZ_Yrtak.js # web/static/react/assets/diagram-UQ7AKVKN-CxWkeyO6.js # web/static/react/assets/diagram-UQ7AKVKN-DUycjvAt.js # web/static/react/assets/diagram-VSXAHHWV-BKT4N91g.js # web/static/react/assets/diagram-VSXAHHWV-BY1yhvj0.js # web/static/react/assets/diagram-VSXAHHWV-DnIO4wHH.js # web/static/react/assets/diagram-VX7I27RA-CgyAV71U.js # web/static/react/assets/diagram-VX7I27RA-D6YGjufm.js # web/static/react/assets/diagram-VX7I27RA-wfzKvUn1.js # web/static/react/assets/diagram-Z3DM3KII-6dpWLJra.js # web/static/react/assets/diagram-Z3DM3KII-BGrgvCjH.js # web/static/react/assets/diagram-Z3DM3KII-ElIQm19k.js # web/static/react/assets/ebnfDiagram-PWID7BFC-CCY2WEk6.js # web/static/react/assets/ebnfDiagram-PWID7BFC-Ccs2G2jj.js # web/static/react/assets/ebnfDiagram-PWID7BFC-gy61n7Pj.js # web/static/react/assets/erDiagram-RLTQ6QDP-BfMFG3Uk.js # web/static/react/assets/erDiagram-RLTQ6QDP-CzLrDTTx.js # web/static/react/assets/erDiagram-RLTQ6QDP-VacA07Jt.js # web/static/react/assets/es-BjvOFIqx.js # web/static/react/assets/es-CQ2xsPic.js # web/static/react/assets/es-Jd9UP7tf.js # web/static/react/assets/fr-BgU7KYtZ.js # web/static/react/assets/fr-DbwLjgwa.js # web/static/react/assets/fr-YIn9Z5ej.js # web/static/react/assets/ganttDiagram-EL5Y4UJY-Ci-nGf4e.js # web/static/react/assets/ganttDiagram-EL5Y4UJY-RoMyoJZo.js # web/static/react/assets/ganttDiagram-EL5Y4UJY-wq9CeWvh.js # web/static/react/assets/gitGraphDiagram-WWUBYQGX-Amb8k2nU.js # web/static/react/assets/gitGraphDiagram-WWUBYQGX-B5S4-kda.js # web/static/react/assets/gitGraphDiagram-WWUBYQGX-_uk_m_Ju.js # web/static/react/assets/infoDiagram-27XIBGKW-BB0h5pdC.js # web/static/react/assets/infoDiagram-27XIBGKW-DPcEo2-Q.js # web/static/react/assets/infoDiagram-27XIBGKW-t_KF5Tyy.js # web/static/react/assets/ishikawaDiagram-5VMMS53U-CdFMBx5t.js # web/static/react/assets/ishikawaDiagram-5VMMS53U-CgKrljNZ.js # web/static/react/assets/ishikawaDiagram-5VMMS53U-CwY29Ce4.js # web/static/react/assets/ja-Ct-b0xPU.js # web/static/react/assets/ja-FORQR6Ty.js # web/static/react/assets/ja-KZkHyd2O.js # web/static/react/assets/journeyDiagram-3NMN7TZE-5nXEDwSI.js # web/static/react/assets/journeyDiagram-3NMN7TZE-BMe8gNYL.js # web/static/react/assets/journeyDiagram-3NMN7TZE-QKge-W8H.js # web/static/react/assets/jsx-runtime-B_8u7U8_.js # web/static/react/assets/jsx-runtime-CTc3L-Ek.js # web/static/react/assets/jsx-runtime-DKr7__-1.js # web/static/react/assets/kanban-definition-UXKFOSKX-BY3m2yUg.js # web/static/react/assets/kanban-definition-UXKFOSKX-BcKeO5IL.js # web/static/react/assets/kanban-definition-UXKFOSKX-o0E0YNRC.js # web/static/react/assets/ko-BANBmYm_.js # web/static/react/assets/ko-DVlu-jXb.js # web/static/react/assets/ko-dZHXPESm.js # web/static/react/assets/line-CVGzKhp0.js # web/static/react/assets/line-CbwlDtMl.js # web/static/react/assets/line-DC7CO8aV.js # web/static/react/assets/mermaid.core-BGmpGPki.js # web/static/react/assets/mermaid.core-SfATCJyh.js # web/static/react/assets/mermaid.core-dnpdoiFF.js # web/static/react/assets/mindmap-definition-YA3MSWOX-B1OW5K1R.js # web/static/react/assets/mindmap-definition-YA3MSWOX-BAQTsDJp.js # web/static/react/assets/mindmap-definition-YA3MSWOX-wh3goASK.js # web/static/react/assets/pegDiagram-XKGWAZYB-BBFo6umg.js # web/static/react/assets/pegDiagram-XKGWAZYB-CRcNrAE8.js # web/static/react/assets/pegDiagram-XKGWAZYB-CfgG_gTA.js # web/static/react/assets/pieDiagram-E7YTZNPT-CWzaKJcK.js # web/static/react/assets/pieDiagram-E7YTZNPT-D-qkL8A_.js # web/static/react/assets/pieDiagram-E7YTZNPT-DmQ5x8x-.js # web/static/react/assets/quadrantDiagram-AXDQQJYC-DDGStmic.js # web/static/react/assets/quadrantDiagram-AXDQQJYC-jUfP4SSH.js # web/static/react/assets/quadrantDiagram-AXDQQJYC-zpdD6FHB.js # web/static/react/assets/railroadDiagram-O6MQD6OU-B4_T6yJ4.js # web/static/react/assets/railroadDiagram-O6MQD6OU-BEnMhdQg.js # web/static/react/assets/railroadDiagram-O6MQD6OU-BhqMYPSm.js # web/static/react/assets/requirementDiagram-BXWQKSXE-CZWXnnvi.js # web/static/react/assets/requirementDiagram-BXWQKSXE-D6FkA4AD.js # web/static/react/assets/requirementDiagram-BXWQKSXE-DGCx52gO.js # web/static/react/assets/sankeyDiagram-P5KCCOFB-BK5FpyRT.js # web/static/react/assets/sankeyDiagram-P5KCCOFB-CS1UKujk.js # web/static/react/assets/sankeyDiagram-P5KCCOFB-EwRSS07u.js # web/static/react/assets/sequenceDiagram-WJ2MYXX4-CYrcmF2P.js # web/static/react/assets/sequenceDiagram-WJ2MYXX4-DuEm_vQY.js # web/static/react/assets/sequenceDiagram-WJ2MYXX4-o4cxGATG.js # web/static/react/assets/stateDiagram-D77RDMKH-BQQpVrjB.js # web/static/react/assets/stateDiagram-D77RDMKH-Cme-Qrye.js # web/static/react/assets/stateDiagram-D77RDMKH-JMBeW-em.js # web/static/react/assets/swimlanes-42K2YHIH-D__z8anH.js # web/static/react/assets/swimlanes-42K2YHIH-dBGym0sa.js # web/static/react/assets/swimlanes-42K2YHIH-i7QtUajN.js # web/static/react/assets/terminal-B-uCaZZ-.js # web/static/react/assets/terminal-BBKSMpBk.js # web/static/react/assets/terminal-BiylDP49.js # web/static/react/assets/timeline-definition-24CTP7MA-C7hlhG_y.js # web/static/react/assets/timeline-definition-24CTP7MA-Ck_0IoYa.js # web/static/react/assets/timeline-definition-24CTP7MA-Dx47N7s_.js # web/static/react/assets/tokens-C3cMAG2N.js # web/static/react/assets/tokens-DbSIDRBH.js # web/static/react/assets/tokens-Dpc2hDHL.js # web/static/react/assets/vennDiagram-4TSXK5OY-Bn3YdQn8.js # web/static/react/assets/vennDiagram-4TSXK5OY-Ca1EfFJq.js # web/static/react/assets/vennDiagram-4TSXK5OY-Cnbex8V3.js # web/static/react/assets/viewers-CA2cj8y4.js # web/static/react/assets/viewers-Cw-ARQKe.js # web/static/react/assets/viewers-DTiiYeVX.js # web/static/react/assets/wardleyDiagram-VM6X3IG4-B9aUY15Q.js # web/static/react/assets/wardleyDiagram-VM6X3IG4-BYGpe6xM.js # web/static/react/assets/wardleyDiagram-VM6X3IG4-DbnJi7ui.js # web/static/react/assets/xychartDiagram-S5SC5T6Z-Cwo52OlL.js # web/static/react/assets/xychartDiagram-S5SC5T6Z-D2sYm3QZ.js # web/static/react/assets/xychartDiagram-S5SC5T6Z-i5cnNGF0.js # web/static/react/assets/zh-BttOdNY4.js # web/static/react/assets/zh-CeF9vD5r.js # web/static/react/assets/zh-DF7kEYYZ.js # web/static/sw.js # web/static/terminal.html
# Conflicts: # frontend/src/i18n/en/board.ts # frontend/src/i18n/es/board.ts # frontend/src/i18n/fr/board.ts # frontend/src/i18n/ja/board.ts # frontend/src/i18n/ko/board.ts # frontend/src/i18n/zh/board.ts # frontend/src/sessions/Conversation.tsx # web/index.html # web/static/react/assets/PaneViews-CGmk3RZC.js # web/static/react/assets/RichMarkdown-CdeDviL6.js # web/static/react/assets/RichMarkdown-CkKq-iQw.js # web/static/react/assets/RichMarkdown-DpZ7QT0X.js # web/static/react/assets/Workbench-BIN2kjb-.js # web/static/react/assets/Workbench-CdOmoDCG.js # web/static/react/assets/Workbench-DBwIuJ1J.js # web/static/react/assets/abnfDiagram-VCTEODGH-DYK8uF4W.js # web/static/react/assets/action-DSlPwQaw.js # web/static/react/assets/app-Bmi8DgMA.js # web/static/react/assets/architectureDiagram-5GKGNRK7-BRTty8u2.js # web/static/react/assets/architectureDiagram-5GKGNRK7-CFEfKN02.js # web/static/react/assets/architectureDiagram-5GKGNRK7-DqKWnehx.js # web/static/react/assets/blockDiagram-I7D4REHJ-7Q6t1H_c.js # web/static/react/assets/blockDiagram-I7D4REHJ-B43PE8Y2.js # web/static/react/assets/blockDiagram-I7D4REHJ-QYYDLsdu.js # web/static/react/assets/c4Diagram-7LVT6UL2-BWoAerJ6.js # web/static/react/assets/c4Diagram-7LVT6UL2-BZZhjbEk.js # web/static/react/assets/c4Diagram-7LVT6UL2-mzXM1e0G.js # web/static/react/assets/chunk-4HAMMTFA-CdyC4Ca2.js # web/static/react/assets/chunk-4HAMMTFA-DF0czc-P.js # web/static/react/assets/chunk-4HAMMTFA-mdRFDOQ4.js # web/static/react/assets/chunk-75Z2AOVW-957CGxL_.js # web/static/react/assets/chunk-75Z2AOVW-CGmBNe08.js # web/static/react/assets/chunk-75Z2AOVW-Cg5bWo8T.js # web/static/react/assets/chunk-DU6HZSFF-BFfOPqFa.js # web/static/react/assets/chunk-DU6HZSFF-C1dsg9Mw.js # web/static/react/assets/chunk-DU6HZSFF-D1jeAJym.js # web/static/react/assets/chunk-F27PBJKO-C5jXgOkd.js # web/static/react/assets/chunk-GMAD6QVW-BbSp6lwD.js # web/static/react/assets/chunk-GMAD6QVW-BlJGfzaZ.js # web/static/react/assets/chunk-GMAD6QVW-CtMfgxep.js # web/static/react/assets/chunk-GVQU2GXP-Cpv7fJ-a.js # web/static/react/assets/chunk-IMKFNOWR-BUSVbXBH.js # web/static/react/assets/chunk-IMKFNOWR-ChnfBiKh.js # web/static/react/assets/chunk-IMKFNOWR-kW9hg2lU.js # web/static/react/assets/chunk-L3NEJ4N5-B2NwHw-L.js # web/static/react/assets/chunk-OSK3NFVY-3uy8HQ7C.js # web/static/react/assets/chunk-OSK3NFVY-CLe3B2w8.js # web/static/react/assets/chunk-OSK3NFVY-CNsef5RK.js # web/static/react/assets/chunk-P2QGCYS3-RVpLW1XP.js # web/static/react/assets/chunk-POPQ4Y6H-Dq0QmBVR.js # web/static/react/assets/chunk-PWAF6VOD-Bn-6bXKJ.js # web/static/react/assets/chunk-SHT3W25Y-3X5XhVEE.js # web/static/react/assets/chunk-SHT3W25Y-B1A9q2LV.js # web/static/react/assets/chunk-SHT3W25Y-B99-GcGT.js # web/static/react/assets/chunk-SVP7TREG-C8nDz84A.js # web/static/react/assets/chunk-SVP7TREG-CLFgXFZw.js # web/static/react/assets/chunk-SVP7TREG-Ddj-QEfB.js # web/static/react/assets/chunk-TICWLB2K-11py4ySH.js # web/static/react/assets/chunk-TICWLB2K-BcBOiewN.js # web/static/react/assets/chunk-TICWLB2K-DwQJOU6r.js # web/static/react/assets/cynefinDiagram-5FMLGOSQ-Bg8npMjQ.js # web/static/react/assets/cynefinDiagram-5FMLGOSQ-DPGGFZfU.js # web/static/react/assets/cynefinDiagram-5FMLGOSQ-Ww9PRz2F.js # web/static/react/assets/dagre-GXQ25YYZ-BIRe1ppJ.js # web/static/react/assets/dagre-GXQ25YYZ-BVhsupmT.js # web/static/react/assets/dagre-GXQ25YYZ-DW0SlLhR.js # web/static/react/assets/diagram-S7CK7UJ4-A65jJNTc.js # web/static/react/assets/diagram-S7CK7UJ4-D_yMzCgn.js # web/static/react/assets/diagram-S7CK7UJ4-TX-CUmRL.js # web/static/react/assets/diagram-UQ7AKVKN-B-DJZkbx.js # web/static/react/assets/diagram-UQ7AKVKN-BZ_Yrtak.js # web/static/react/assets/diagram-UQ7AKVKN-CxWkeyO6.js # web/static/react/assets/diagram-VSXAHHWV-BKT4N91g.js # web/static/react/assets/diagram-VSXAHHWV-DnIO4wHH.js # web/static/react/assets/diagram-VSXAHHWV-hEQIKUX0.js # web/static/react/assets/diagram-VX7I27RA-B6lTtsTe.js # web/static/react/assets/diagram-Z3DM3KII-CcQnC9wy.js # web/static/react/assets/ebnfDiagram-PWID7BFC-DTzsPDgv.js # web/static/react/assets/erDiagram-RLTQ6QDP-BfMFG3Uk.js # web/static/react/assets/erDiagram-RLTQ6QDP-CzLrDTTx.js # web/static/react/assets/erDiagram-RLTQ6QDP-Tyud8vqe.js # web/static/react/assets/es-BPYU4L0D.js # web/static/react/assets/es-BjvOFIqx.js # web/static/react/assets/es-Jd9UP7tf.js # web/static/react/assets/fr-BgU7KYtZ.js # web/static/react/assets/fr-D6u_E_zV.js # web/static/react/assets/fr-YIn9Z5ej.js # web/static/react/assets/ganttDiagram-EL5Y4UJY-C7BqW9tT.js # web/static/react/assets/ganttDiagram-EL5Y4UJY-Ci-nGf4e.js # web/static/react/assets/ganttDiagram-EL5Y4UJY-RoMyoJZo.js # web/static/react/assets/gitGraphDiagram-WWUBYQGX-Amb8k2nU.js # web/static/react/assets/gitGraphDiagram-WWUBYQGX-B5S4-kda.js # web/static/react/assets/gitGraphDiagram-WWUBYQGX-wlNhr8_6.js # web/static/react/assets/infoDiagram-27XIBGKW-CuZGOhQs.js # web/static/react/assets/ishikawaDiagram-5VMMS53U-BokmpuXN.js # web/static/react/assets/ishikawaDiagram-5VMMS53U-CdFMBx5t.js # web/static/react/assets/ishikawaDiagram-5VMMS53U-CgKrljNZ.js # web/static/react/assets/ja-BjpQdtHz.js # web/static/react/assets/ja-Ct-b0xPU.js # web/static/react/assets/ja-FORQR6Ty.js # web/static/react/assets/journeyDiagram-3NMN7TZE-5nXEDwSI.js # web/static/react/assets/journeyDiagram-3NMN7TZE-B0Hb5kZr.js # web/static/react/assets/journeyDiagram-3NMN7TZE-BMe8gNYL.js # web/static/react/assets/jsx-runtime-B_8u7U8_.js # web/static/react/assets/jsx-runtime-CTc3L-Ek.js # web/static/react/assets/jsx-runtime-zL88avyV.js # web/static/react/assets/kanban-definition-UXKFOSKX-BY3m2yUg.js # web/static/react/assets/kanban-definition-UXKFOSKX-CZWtMwmJ.js # web/static/react/assets/kanban-definition-UXKFOSKX-o0E0YNRC.js # web/static/react/assets/ko-BANBmYm_.js # web/static/react/assets/ko-C_A5s4U2.js # web/static/react/assets/ko-dZHXPESm.js # web/static/react/assets/line-B2RVsozf.js # web/static/react/assets/mermaid.core-BGmpGPki.js # web/static/react/assets/mermaid.core-DepdohST.js # web/static/react/assets/mermaid.core-dnpdoiFF.js # web/static/react/assets/mindmap-definition-YA3MSWOX-B1OW5K1R.js # web/static/react/assets/mindmap-definition-YA3MSWOX-BAQTsDJp.js # web/static/react/assets/mindmap-definition-YA3MSWOX-CepnbBBo.js # web/static/react/assets/pegDiagram-XKGWAZYB-ImVa88mr.js # web/static/react/assets/pieDiagram-E7YTZNPT-CWzaKJcK.js # web/static/react/assets/pieDiagram-E7YTZNPT-D-qkL8A_.js # web/static/react/assets/pieDiagram-E7YTZNPT-DvamMSYL.js # web/static/react/assets/quadrantDiagram-AXDQQJYC-DDGStmic.js # web/static/react/assets/quadrantDiagram-AXDQQJYC-jUfP4SSH.js # web/static/react/assets/quadrantDiagram-AXDQQJYC-ry0Abme0.js # web/static/react/assets/railroadDiagram-O6MQD6OU-dmqUR8U3.js # web/static/react/assets/requirementDiagram-BXWQKSXE-CZWXnnvi.js # web/static/react/assets/requirementDiagram-BXWQKSXE-D6FkA4AD.js # web/static/react/assets/requirementDiagram-BXWQKSXE-DZFEfC-s.js # web/static/react/assets/sankeyDiagram-P5KCCOFB-BK5FpyRT.js # web/static/react/assets/sankeyDiagram-P5KCCOFB-C8DTTeUV.js # web/static/react/assets/sankeyDiagram-P5KCCOFB-CS1UKujk.js # web/static/react/assets/sequenceDiagram-WJ2MYXX4-CYrcmF2P.js # web/static/react/assets/sequenceDiagram-WJ2MYXX4-CpU5URxC.js # web/static/react/assets/sequenceDiagram-WJ2MYXX4-o4cxGATG.js # web/static/react/assets/stateDiagram-D77RDMKH-B_CTuQvB.js # web/static/react/assets/swimlanes-42K2YHIH-DhyBOtOa.js # web/static/react/assets/terminal-B-uCaZZ-.js # web/static/react/assets/terminal-BBKSMpBk.js # web/static/react/assets/terminal-DLh1C7rX.js # web/static/react/assets/timeline-definition-24CTP7MA-C7hlhG_y.js # web/static/react/assets/timeline-definition-24CTP7MA-Ck_0IoYa.js # web/static/react/assets/timeline-definition-24CTP7MA-rZBP0s8x.js # web/static/react/assets/tokens-C3cMAG2N.js # web/static/react/assets/vennDiagram-4TSXK5OY-4ioyr7r_.js # web/static/react/assets/vennDiagram-4TSXK5OY-Bn3YdQn8.js # web/static/react/assets/vennDiagram-4TSXK5OY-Ca1EfFJq.js # web/static/react/assets/viewers-CA2cj8y4.js # web/static/react/assets/viewers-DTiiYeVX.js # web/static/react/assets/viewers-DZ54SDTB.js # web/static/react/assets/wardleyDiagram-VM6X3IG4-B9aUY15Q.js # web/static/react/assets/wardleyDiagram-VM6X3IG4-BYGpe6xM.js # web/static/react/assets/wardleyDiagram-VM6X3IG4-B_7wvo9t.js # web/static/react/assets/xychartDiagram-S5SC5T6Z-Cwo52OlL.js # web/static/react/assets/xychartDiagram-S5SC5T6Z-DaqkP2u7.js # web/static/react/assets/xychartDiagram-S5SC5T6Z-i5cnNGF0.js # web/static/react/assets/zh-ACTVu6OJ.js # web/static/react/assets/zh-BttOdNY4.js # web/static/react/assets/zh-CeF9vD5r.js # web/static/sw.js # web/static/terminal.html
…al and Windows branches
On 2026-10-01 a restarted server marked eight live tmux sessions dead: auto chose the PTY backend because stray test hosts held sessions on the user's default socket, polled the tmux sessions there, and read them as missing. - Each session records the backend holding it (sessions.session_backend, set on start, relaunch and adopt) and is polled, probed, attached, typed into and stopped through it. Rows from before are recorded on first poll. - A session its backend reports missing is looked for in the target's other backends before it ends; when found, the row follows it. Scheduler runs get the same check before being called ghosts. - auto prefers tmux on Linux when tmux holds Lectern sessions, whatever a PTY host holds. - Local executors are no longer zero-sized, so two of them cannot share one TargetEnv. - Tests never use the default PTY host socket: it is refused under LECTERN_PTYHOST_TEST_GUARD (set by Go test binaries, the isolated runner and the browser suite); the local-runtime tests and e2e workers get private sockets and stop their hosts.
…ation story Both lines built the same simplicity round from 69dc2e5. Where both built the same thing, one design is kept and the other's unique safety and tests come with it: - Phone on Wi-Fi: origin's runtime listener behind POST /api/phone/wifi and `lectern phone` as a client command that prefers a tailnet or server address; connect-ui's off switch (DELETE /api/phone/wifi, --off, Stop in Settings), runtime-token stripping, /api/local/ blocking, CGNAT and link-local exclusion, loopback-port reuse, rsc.io/qr rendering and the one-click Wi-Fi row. Pairing cookies drop Secure on plain HTTP from the network or on the Wi-Fi listener. - Launch preflight: one check (agent_installed.go) with origin's shell-word parser and PATH overrides, run before any row or scratch folder, and connect-ui's "isn't installed ... Installed there" error. - Launch secrets: origin's private mktemp environment file (it reaches sandboxes too); the subshell deletes it once read, the shell's report of a killed agent is discarded, and secrets stay out of saved launch settings. - No-tmux attachment: connect-ui's bare client; origin's AttachProcess and its scrollback/direct-link plumbing are removed. Ctrl+\ handling uses origin's attachKeys. - Session names: connect-ui's project-or-folder plus topic with #2, #3. - Navigation: origin's desktop sidebar with every page; on narrow screens connect-ui's Sessions/Approvals/Settings + More, Tasks joining once used. - Sessions page, cards, Start sheet: connect-ui's. Agent-exited reads Stopped (origin). Commit drafting keeps the suggested message until the draft arrives and never lets a refresh replace the draft. - Approvals: origin's immediate expiry and late-request denial plus connect-ui's scheduler sweep. - Database default: connect-ui's (state dir, existing ./lectern.db kept), plus LOCALAPPDATA on Windows. No new migrations on origin's side. - Docs: one Getting started page with the per-OS details folded in; README keeps its version badge. Web bundle rebuilt from the merged sources.
Failures seen only on a loaded machine, each with its cause: - test_mobile_terminal::test_a_snippet_is_one_tap_and_the_list_is_the_operators: a quick command added in the terminal frame vanished. The app page's first /ui/prefs answer, arriving after the frame's write but before its storage event, rewrote the shared cache and its unsent list with the server's older copy, and the frame then put the defaults back. A load now takes other documents' unsent changes from the cache first (store test). - test_session_review::test_review_send_comments_and_commit_push_to_bare_remote: the drafted commit message arrived while the field was being typed into and was spliced into the text. Focusing the field now makes it the person's, as typing does. - test_terminal_file_links::test_links_win_over_a_program_that_tracks_the_mouse: counted a click's release as a second press when it arrived late. It now counts presses only. - test_quick_shell::test_cli_shell_picks_local_machine_and_keeps_blank_room: the attach wrapper could relay Ctrl-b d as one write, which tmux takes for a paste. The helper presses it again after clearing the line.
Audits, round-two status notes, unmerged-branch designs, dated comparison evidence, the GPU lease protocol and test investigations are history, not user documentation. Links from user docs, a frontend comment and the marketing-asset checker follow the move. first-install-validation.md no longer says Windows and macOS have no native runtime coverage: CI runs the session backend, PTY host, web terminal and server smoke tests on both.
Host names, a tailnet IP, private paths, a personal file name and a deployment log no longer appear in pages meant for users. The guide stops pointing at an eval directory this repository does not have.
The first screen now says what Lectern is in one sentence, then gives the install command for macOS/Linux and Windows (with Homebrew and Scoop), then lectern claude, lectern up and lectern phone. Machines, SSH, Proxmox, sandboxes and racing agents move under Going further. The release badge reads the latest GitHub release; its alt text keeps the version that TestVersionIsDeclaredOnce checks.
Install, first agent, approving in the browser, approving from the phone, then review and commit, with what appears at each step. The phone step says plainly that Wi-Fi pairing is local and unencrypted, and that notifications need an HTTPS address from Tailscale or a relay.
…d name the Windows startup entry
…ent switching and text size behind ⋯ in plainer words
…lback drafts plainly, tuck push, amend and PR under Options, and say when there is nothing to commit
… inline git identity and the terminal approval strip
…terminal-approval changes
…ark mode now the theme follows the device
…alog timing and the device theme
On Windows the test reads a ConPTY, which sends a rendering of the screen each frame rather than the bytes written to it. The test popup named its action and returned at once, and the client redrew over it before the next frame, so ACTION_menu was never sent even though Ctrl+] m had worked. The popup now appends what it was asked for to a file the test reads.
JeremiahM37
force-pushed
the
win-attach-fix
branch
from
October 2, 2026 06:53
8d3b0fa to
540551f
Compare
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.
CI iteration for the Windows attach test