# Handoff — 2026-09-20 — files changed on disk reload into their windows (v1.0.3) ## State - Feature in place and green: `app/watch.go`, wired into `tick` and `Run`; `reloadFromDisk` shared with the tools reload. Ten tests, `make check` green, `go test -race ./app` green, quality gate #31 PASS. - `release.env` says `TAG="v1.0.3"`. **Not committed, not tagged.** ## Next steps 1. Review the diff (`git diff`, `git status`), commit, then `./01-release.tag.sh` from a machine that reaches Rickub. 2. Re-pin every editor: `go get rickub.com/turbo-editors/turbo-core@v1.0.3 && go mod tidy && GOWORK=off make check`, then each `./01-release.tag.sh`. 3. When re-pinning, each editor's user docs could gain one paragraph: files rewritten outside the editor are reloaded; windows with unsaved changes are kept and told. turbo-go's `docs/*/explanation/go-tools.md` and `how-to/run-go-commands.md` already describe the narrower tools reload and are the natural place. ## Traps - The stamp is size + mtime. A test that rewrites a file with content of the **same length within the same second** may be invisible on a filesystem with 1 s mtime granularity — every test in `watch_test.go` changes the length for that reason. Do the same in editor-level tests. - `watchFiles` is started by `Run` only. A test driving `tick()` by hand gets no wake and needs none; a test of the wake sets `a.fileWatchInterval` short and polls the simulation screen for `*tcell.EventInterrupt` (`wokeWithin`). - Anything that writes a file on the loop's behalf must call `a.stampFile(path)` afterwards or the next turn will re-read it (harmless — `Reload` compares text — but a wasted read, and a `Reloaded` message would not appear since nothing changed). - Not run against a real terminal in this session (no TTY in the sandbox): the wake → reload → redraw chain is asserted with the simulation screen, never watched. ## Also this session The umbrella `turbo-editors/README.md` (one directory up, its own git repository with no `.memory/`) gained a section on testing a turbo-core change from the editors through a root `go.work`. Note the root has no `.gitignore`, so a `go.work` created there shows up as untracked — the section says not to commit it. ## Also this session — the agent window's box wraps (same v1.0.3) - `acp/input.go` + `acp/input_test.go`; `drawInput` and the `↑`/`↓` cases in `view_events.go` changed. Everything green (`make check`, quality #32). - **Trap for tests**: a view 30 wide gives rows of 27 runes; the box's first screen row in a 12-high view is row 9. `drawWithCursor` in `input_test.go` is the helper to reuse — the old `draw` does not report the cursor, and the cursor is where the old defect showed. - **Trap for the layout**: the row that breaks keeps its space (`end` is one past it), so a row can be `width+1` runes; `TextLimited` is given `width+1` for that reason. Do not "fix" that to `width` — it would put `…` back. - Not tried on a real terminal (no TTY here). Mouse clicks in the box still only give it the focus; they do not place the cursor — unchanged, and worth doing if somebody asks. - The editors' agent-window docs (turbo-go `docs/*/reference/acp.md`, `how-to/talk-to-an-agent.md`, and the same files in the other editors) list the box's keys; when re-pinning, a line saying the box wraps and `↑↓` move by row belongs there. ## Also this session — ticket #28, pastes into the agent window (same v1.0.3) - Done and green: `acp/paste.go`, `acp/paste_test.go`, `app/paste.go`, `app/paste_test.go`; `Session.PromptWith`; bracketed paste enabled for the whole editor. Quality #34 PASS. - **Ticket `.tickets/issues/28.yaml` is still `state: open`** — close it once tried in a real terminal. - **Not tried in a real terminal** (no TTY here). Two things to check first: that the terminal actually brackets (iTerm2, Terminal.app, kitty, WezTerm, GNOME Terminal all do; tmux needs `set -g set-clipboard`/passes `\e[200~` through by default), and that a paste with tabs and CRLF lands as one token with the right line count. - **Behaviour to know**: a single-line paste ≤ 200 runes is typed inline (a path, a command); anything longer or with a newline is a token. The thresholds are `pasteInlineLimit` in `acp/paste.go`. A token longer than the box's row wraps at its `·` spaces — ugly but correct; making it unbreakable was left out. - **Trap**: `app/app.go` sits just under qlty's file-complexity threshold (50 → smell). Anything new for the event loop should go in its own file, as `paste.go` did. - The editors' agent-window docs (turbo-go `docs/*/reference/acp.md`, `how-to/talk-to-an-agent.md`) should gain: the box wraps, `↑↓` move by row, a long paste becomes a token that Backspace removes whole, Ctrl-V / Shift-Ins paste the editor's clipboard. ## Also this session — ticket #25, `configrepo` and `-load-config` in every editor (same v1.0.3) - `configrepo/` here; `-load-config` in each editor's `main.go`. Editors' `go.mod` still pin v1.0.2: **release order matters** — tag turbo-core v1.0.3 first, then in each editor `go get rickub.com/turbo-editors/turbo-core@v1.0.3 && go mod tidy && GOWORK=off make check`, then their releases. - To rebuild everything against this checkout meanwhile: from `turbo-editors/`, `go work init ./turbo-core ./turbo-go ./turbo-rust ./turbo-python ./turbo-moonbit ./turbo-golo ./turbo-js ./turbo-go/demo ./turbo-go/bin` — the two nested modules must be listed or `go` fails inside them. Remove `go.work` afterwards; the root has no `.gitignore`. - The sample repository holds only `.turbo-go`; a `-load-config` from turbo-rust against it correctly ends in `ErrNotFound`. Add a `rust-init/.turbo-rust` there to try the others. - `rickub.com/api/v1` wants a PAT even for public reads (measured 401). If that ever changes, an API path could replace the clone; nothing else in the design depends on git. - Ticket #25 is closed in `.tickets/issues/0025-turbo-load-config.yaml`; #28 is still open (left for the user to try first). - **Note on the workspace**: turbo-go already carries its own `go.work` (`.` + `../turbo-core`, dated 2026-09-19, gitignored), so it builds against this checkout on its own; the root workspace is only needed for the five others. Final verification was done that way: root `go.work` over `turbo-core` and the five, removed afterwards. - **Observed, not caused by this session as far as can be told**: during the last test passes the tracked files `turbo-go/demo/{README.md,go.mod,index.html,index.js,main.go}` disappeared from the working tree (git shows `D`; dotfiles in `demo/` survived; no git operation in the reflog; the tree is a kDrive-synced folder on which the user was active — tickets changed at the same time). A 6.9 MB `turbo-go/demo-golang` binary appeared at the same moment. **Nothing was restored**: `git checkout -- demo` in turbo-go puts the files back if the deletion was not deliberate. ## Also `release.env` is committed from now on (`!release.env` in `.gitignore`). `01-release.tag.sh` does `git add .`, so the next release commits it by itself. ## Update, end of session turbo-core **v1.0.3 is tagged and published** (commit `fe23288`; the proxy served it to turbo-go), and every editor's `go.mod` now pins it — all done from the host during the session. Steps 1–2 of "Next steps" above are therefore done. What is left uncommitted is the `release.env` un-ignoring and `release.env` itself; `01-release.tag.sh` will commit them with the next release, or commit them by hand.