Commit Graph
1657 Commits
Author SHA1 Message Date
Codeman maintainer edf3cb19e4 Merge pull request #699: fix(terminal): a mouse wheel notch pages the CLI's transcript at once
Conflict in docs/architecture-invariants.md resolved by keeping both
sides: the hollow-pane paragraph carries #681's unloaded-scrollback
sentence, #698's Codex-menu rewording and #699's notch rewording (a
word-level three-way merge; the three edits touch disjoint sentences).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-24 15:22:43 +02:00
Codeman maintainer 0160db9927 Merge pull request #698: fix(terminal): the wheel no longer moves a Codex selection menu's selection
Conflicts resolved by keeping both sides:
- src/web/public/terminal-ui.js (_maybePageCliTranscript): #698's
  Codex-menu consume check sits right after the open-dialog consume
  check (its sibling, as the docblock lists them), and #681's
  unloaded-scrollback fall-through (paneHistoryLines > 0) follows it.
- docs/architecture-invariants.md: the hollow-pane paragraph carries
  #681's unloaded-scrollback sentence and #698's menu rewording.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-24 15:21:58 +02:00
Codeman maintainer d38044e2ac Merge pull request #681: fix(terminal): load tmux history instead of paging Claude after a hollow tab switch 2026-10-24 15:19:16 +02:00
Codeman maintainer 4dfe978d3f Merge pull request #682: fix(mobile): swipe through sessions in the order the strip draws them 2026-10-24 15:16:49 +02:00
Codeman maintainer af682d77ae fix: address the release-prep review of #699
terminal-ui.js: the _maybePageCliTranscript JSDoc names PAGE_KEY_NOTCH_DEBT_MS as the stretched gap after a notch-sized opener
terminal-scroll-routing.test.ts: the notch-opener test comment uses the real numbers (36 rows, 14 rows owed)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-24 14:41:32 +02:00
Codeman maintainer 2936063ea3 fix: apply the review items for #699 at merge
pageKeysForGesture comment (terminal-ui.js:218): the gap stretches to PAGE_KEY_NOTCH_DEBT_MS after a notch-sized opener, not only PAGE_KEY_DEBT_MS
pageKeysForGesture comment (terminal-ui.js:286): a repaid debt ends either lifetime, not only the one-second one

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-24 14:14:56 +02:00
Codeman maintainer d41ad16818 fix: apply the review items for #681 at merge
_notePaneHistory JSDoc names the responses it skips (an error envelope on any path, a refresh that lost its owner, a pull whose select generation moved)
selectSession records the pane count only for a non-error envelope (capture.json?.success !== false), pinned in the static guard of test/pane-history-memory.test.ts; the two invariant paragraphs now name the tab switch beside the refresh and the pull

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-24 14:02:21 +02:00
Codeman maintainer 886bf9fa0b Merge remote-tracking branch 'origin/master' into relprep/pr-678 2026-10-24 13:55:07 +02:00
Devvyn 77eefce4f6 fix(terminal): carry leftover travel into a notch's page, document the new rule 2026-10-24 10:12:58 +08:00
Devvyn 372df864b9 fix(terminal): review of the Codex menu wheel guard 2026-10-24 10:10:38 +08:00
Devvyn 81beec7b5b fix(terminal): a mouse wheel notch pages the CLI's transcript at once 2026-10-24 08:46:38 +08:00
Devvyn 9fa6d98c7c fix(terminal): the wheel no longer moves a Codex selection menu's selection 2026-10-24 08:28:52 +08:00
JD 84adb701d7 fix(terminal): load tmux history instead of paging Claude after a hollow tab switch
After a server restart the byte recording a tab switch replays (`?tail=`) holds only the tmux client's attach repaint, so an inline Claude session came back with an empty local buffer while tmux still held its scrollback. The hollow-buffer fallback then sent PageUp/PageDown to Claude, which moved the composer cursor instead of the transcript, until a page reload. Pre-existing on an unmodified build; every restart of the server showed it.

The paging fallback now stands down when the last capture reported tmux scrollback (`paneHistoryLines` > 0), dropping the gesture debt and any page keys already queued, so the gesture falls through to the local path, whose scroll-to-top pull fetches `full=1` and the gesture scrolls on from there. Zero and unknown counts keep paging (fullscreen Claude, codex, opencode, remote and Docker panes). The pull no longer inherits a downgrade refusal's 60 s latch for such a buffer, drops a completion that outlived a tab switch back to the same session (select generation, not only the session id), records no count from an error envelope (a JSON 5xx would otherwise forget it and hand the next gesture back to paging), and re-positions the local-echo overlay after its rewrite. The refresh path records its count only once it still owns the terminal, for the same reason. The `[scroll]` line prints `paneHistoryLines` so an unloaded buffer reads apart from a hollow one, and the invariant docs record the exception.

Measured with phone emulation after a restart: before, the second visit landed at baseY 0 and every swipe sent PageUp; after, the first swipe fetched the history once with nothing sent to Claude and the gesture scrolled 21 rows, with an unsent draft intact on the overlay.
2026-10-22 15:13:01 -04:00
JD 116961f3a8 fix(mobile): swipe through sessions in the order the strip draws them
nextSession/prevSession walk the canonical sessionOrder, but the case and state tab layouts, a sorted rail and named groups reorder the strip, so with any of them a swipe jumped to tabs that were not next to the current one on screen. The swipe now asks for the drawn order, read with the same walk the strip's arrow keys already use (factored out as _visibleTabRows); Alt+[ / Alt+], Ctrl+Tab and Alt+1..9 keep the canonical order. An active session the list does not draw steps in at the first or last row, and an empty drawn list goes nowhere instead of falling back to a hidden session.
2026-10-22 15:11:21 -04:00
Codeman maintainer 002de32a08 chore: version packages
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 20:33:07 +02:00
Codeman maintainer a85da87378 Merge pull request #674: fix(mobile): give a sideways drag on the terminal to the session swipe alone
Second merge of #674: the author pushed the thumb-arc handback from the review themselves (e8fc08be), byte-identical in code to the merge-time fix already here, so this brings their round in and keeps the browser test and docs added at merge.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

# Conflicts:
#	docs/wiki/Mobile-Guide.md
#	src/web/public/terminal-ui.js
#	test/session-swipe-gesture.test.ts
2026-10-22 20:32:13 +02:00
Codeman maintainer 463a083a23 Merge pull request #676: feat(tabs): per-case default session group
Conflict in CLAUDE.md's State Files line resolved by keeping #661's new
config-backup entries and this PR's "case default groups" in state.json.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 19:54:54 +02:00
Codeman maintainer 3b6818449e Merge pull request #661: feat(config): timestamped config backups with a configurable folder and retention
Conflicts in CLAUDE.md, README.md, docs/api-reference.md and
src/web/server.ts were additions beside #662's Copilot quota read and
#666's keep-warm sections; both sides kept.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 19:54:40 +02:00
JD e8fc08beb3 fix(mobile): hand a swipe-locked drag back to the scroll past the swipe's drift limit
A scroll whose first move past the tap slop leaned sideways (a thumb arc) locked as 'swipe' for the whole contact, and SwipeHandler drops a swipe at 50 px of vertical drift, so the gesture did nothing. Past that limit the drag is now a 'y' scroll. Also brings the mobile-handlers fileoverview to the current 500 ms / 50 px limits and notes in the Mobile Guide that a selection pauses the swipe and a wide terminal pans instead.
2026-10-22 13:53:48 -04:00
DevvynandClaude Opus 5.5 33d697afe3 fix(custom-model): warn when parallel llama.cpp slots leave too little context per request (#658)
Squash of PR #658. Discovery records each llama.cpp model's parallel slot
count (from --parallel/-np, or /props total_slots when the launch command
states none), and a Claude launch warns when the context split across
those slots leaves less than 40K tokens per request. An explicit
--parallel beside a /props context records a slot count of 1, so a later
round overwrites an earlier count, and a non-2xx /props is remembered per
launch command while a network error is retried.

Merge-time fix by the maintainer: the architecture-invariants sentence on
the explicit --parallel case now says it records a slot count of 1.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 19:32:24 +02:00
DevvynandClaude Opus 5.5 34cf798b10 feat(copilot): plan-usage chip row for the monthly premium-request quota (#662)
Squash of PR #662. The header plan-usage chip gains a Copilot row: the
calendar-month premium-request quota, with the request counts and the
reset in the tooltip, read every 10 minutes from GitHub's
copilot_internal/user endpoint with the Copilot CLI's own sign-in token.
It rides showPlanUsageLimits and is on by default while the CLI is
installed and signed in; any failure leaves the chip without the row.

Merge-time fixes by the maintainer: the gates (setting, then token, then
the CLI probe) live in readCopilotPlanUsageIfEnabled() so a host with no
Copilot sign-in never runs the login-shell probe each tick, with a test
that Plan Usage Limits off means no request; the X-GitHub-Api-Version
header the Copilot CLI itself does not send is dropped; and CLAUDE.md,
architecture-invariants, README and copilot-integration describe the read.
The hooks-config import in server.ts was merged with #666's.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 19:32:17 +02:00
Codeman maintainer 9b8cb82c3b fix(tabs): leave the default-group options alone when the groups did not change
Merge-time fix for #676 (review nit 6). Once a Case settings popover had been
opened, every adopted tab layout (each create, delete and reorder) replaced
both selects' options, even with the popover hidden and the group list
unchanged, so a session created elsewhere could reset a native dropdown the
user had open. _refreshCaseDefaultGroupOptions now returns early when the ids
and names are the same. A vm case pins it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 19:32:12 +02:00
Codeman maintainer f80f107445 Merge pull request #666: feat(sessions): keep an idle session's prompt cache warm with a guarded keep-alive turn
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 19:31:08 +02:00
Codeman maintainer 3652670a7d Merge pull request #645: fix(terminal): isolate scroll batches and support tracked Codex scrolling
The remote-history PATH bootstrap that rode along in this PR was left out
at merge (it belongs in its own PR that routes every remote tmux call
through one wrapper), so 242bbfcd's title overstates what lands here.

Conflicts in CLAUDE.md and docs/architecture-invariants.md resolved by
keeping this PR's rewrite of the wheel/touch paragraphs and re-adding
#664's touch-forwarding sentence to both.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 19:29:53 +02:00
Codeman maintainer 9d30a7ff36 Merge pull request #674: fix(mobile): give a sideways drag on the terminal to the session swipe alone
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 19:28:49 +02:00
Codeman maintainer 04faa0d3f1 Merge pull request #664: fix(terminal): forward touch scrolling for native SGR mouse tracking
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 19:28:49 +02:00
Aamer Akhter 536eca8f3d fix(sse): retry an EventSource connect attempt that never opens
An EventSource whose request never gets response headers stays in
CONNECTING without firing open or error, so the backoff never runs and
the staleness watchdog (which only judges a 'connected' stream) cannot
see it. Bound each attempt with a 15s connect timeout: if open has not
fired, close the attempt and retry through the same path onerror uses.

The timer is cleared on open, on failure and at the top of every
connectSSE(), and both the timeout and the failure handler ignore an
EventSource that has since been replaced.
2026-10-22 13:28:43 -04:00
Codeman maintainer b4275e690e Merge pull request #665: fix(response-viewer): open markdown links to file paths in the preview, not as a same-origin URL
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 19:23:17 +02:00
Codeman maintainer cef64dc052 Merge pull request #659: feat(file-viewer): resize and expand the window, back/forward between previewed files
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 19:23:17 +02:00
Codeman maintainer b67018b318 Merge pull request #670: fix(input): keep the line breaks of a multi-line mux prompt, pasted as one block
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 19:23:17 +02:00
Codeman maintainer fde23e3a07 fix(response-viewer): keep a path link's label in the prose font, pin its edges
Merge-time fix for #665.

- A markdown link converted to a preview link became `a.rv-path`, so its
  label ("Our incident record") took the path style: monospace, 0.92em
  and `word-break: break-all`, which split prose mid-word on a phone. The
  anchor now also carries `rv-path-link`, and
  `.rv-text a.rv-path.rv-path-link` resets font and word-break, as the
  File Viewer does for its labelled document links.
- The first new test adds `/tmp/a.json?raw=true` (pins the `?query`
  strip) and `/tmp/` (pins the trailing-slash folder check, since
  findFilePathLinks finds no folder in a bare `/tmp/`), and checks the
  new class.
- The `_linkifyFilePaths` JSDoc and docs/architecture-invariants.md say
  the function also rewrites anchors whose href is a scheme-less,
  non-`//` path, on purpose without FILE_PATH_LINK_PATTERN's root and
  extension filter.
- Mobile Guide: "a web link" in the response viewer opens a tab.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 19:20:01 +02:00
Codeman maintainer a198b815d2 docs: update the swipe limits and note what pauses or replaces a swipe
Merge-time fix for #674: the mobile-handlers.js @fileoverview still
gave the old 300 ms and 100 px limits (now 500 ms and 50 px), and the
Mobile Guide now says a visible text selection pauses the swipe and a
terminal wider than the screen pans instead of switching.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 19:18:51 +02:00
Codeman maintainer 6fb9c4ed8a fix(mobile): hand a sideways-opening drag back to the scroll past the swipe's drift limit
Merge-time fix for #674: the first travel past the tap slop decided the
axis for the whole contact, so a scroll that opened on a thumb arc
(+9 px across, +5 px down, then straight down) locked as 'swipe'. Every
later touchmove returned before the scroll code and SwipeHandler gave
the swipe up at its 50 px drift limit, so the gesture did nothing. Past
SwipeHandler.maxVerticalDrift the drag is now handed to 'y' (and the
published axis with it), so it scrolls; a clean sideways swipe, a
vertical scroll and a long-press drag are unchanged.

The source pin in test/session-swipe-gesture.test.ts moves with the
code and also pins the drift value, and a new browser test drives the
real touch listeners: the thumb-arc drag ends as a scroll (it fails
without the fallback, axis stays 'swipe') and a clean sideways swipe
stays a swipe with nothing scrolled. The architecture note and
src/web/CLAUDE.md now say a swipe drag is consumed only up to that
limit.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 19:18:51 +02:00
Codeman maintainer 73ff2339d8 docs(file-viewer): list Alt+Left/Right in the shortcut overlay and help
Merge-time fix for #659.

- Alt+Left/Right (File Viewer back/forward) is a display-only entry in
  DEFAULT_SHORTCUTS, so the Ctrl+? overlay lists it, and a row in the
  help modal's Panels group, pinned in help-modal-shortcuts.test.ts.
  zh-CN entry for the new label; the "Restore size" entry is dropped,
  since nothing shows that string any more.
- The wiki row moves from "Sessions and tabs" to "Everything else".
- The grip comment in styles.css says only phones hide the grip;
  tablets show and use it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 19:17:05 +02:00
Codeman maintainer df521267ae fix(file-viewer): keep the Expand label fixed while it is pressed
Merge-time fix for #659.

The Expand button swapped its title and aria-label to "Restore size"
while on, so a screen reader announced "Restore size, pressed". The
label now stays "Expand" and aria-pressed alone carries the state, the
way the MD, Lines and Wrap toggles work.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 19:17:05 +02:00
Codeman maintainer 0952a2ee47 fix(config-backup): a restore that fails partway names what it restored and what failed
Merge-time fix for #661. A restore that could not write one file (a full
disk, a directory where the file should be) used to stop there and answer a
bare 500, naming neither the files it had already put back nor the
pre-restore copy, and the Settings form was not re-read, so the next Save
wrote the old settings back over a restored settings.json.

restoreConfigBackup now writes every verified file it can, then throws
ConfigBackupPartialRestoreError with restored, failed (name and error),
untouched and safetySnapshot. The route runs the same reload hooks and audit
for the files written as a full restore does, and answers 500 with the error
envelope plus those fields (and restartRequired) in data, as the tab-layout
409 carries its layout. Settings refills the form when settings.json is among
the restored files, also on that path. Tests: a unit case where a later file
is still restored, the clis.json-as-a-directory route case, and two vm cases
for the Settings handler.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 19:14:08 +02:00
Codeman maintainer 76c17e5c4e fix(terminal): log xterm's mouse encoding with each scroll routing decision
Merge-time fix for #664 (optional item): _logScrollRouting now prints
mouseEncoding (xterm's coreMouseService.activeEncoding, 'unknown' when
the private cannot be read) and counts it in the per-session signature,
since an app switching encodings changes where a touch drag goes. Adds
a unit test for that line and one asserting SGR_PIXELS fails closed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 19:12:25 +02:00
Codeman maintainer 0fcf52d38a fix(terminal): keep the touch forwarding gate's comments with their code
Merge-time fix for #664: _shouldForwardTouchToApp had landed between
_shouldForwardWheelToApp and the `target` comment that documents it, so
it now sits above that comment. Its own comment names both sessions a
local scroll fails in (a direct PTY, where the app is on xterm's
alternate screen, and a tmux-backed session, where xterm stays in the
normal buffer holding stale tmux repaints), and the touch handler's
comment no longer says touch shares the wheel's gate unchanged.
Comments only.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 19:12:16 +02:00
Codeman maintainer 0fa79b37ed fix(terminal): name any tracked CLI in the tile's wheel-forwarding comments
Merge-time fix for #645: the tile's paging gate comment (and the two
other tile comments describing the same route, the @fileoverview bullet
and the wheel listener's) still said the wheel is forwarded to Claude's
fullscreen renderer. Forwarding now covers every tracked CLI the shared
gate accepts, tracked Codex included. Comments only.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 19:04:32 +02:00
Aamer Akhter 74c980413a feat: per-case default session group
Case settings gains a "Default session group" selector (Ungrouped plus every
named tab group of the owner). A new session of the case lands in that group
in the same versioned layout write that registers it, so it is drawn in place
with no Ungrouped-to-group jump.

- Stored per owner and case in state.json (caseDefaultGroups), as the group's
  stable id or null for Ungrouped; read and written only through
  TabLayoutService under the owner lock.
- Precedence in sessionCreated: explicit tabGroupId, then the parent
  placement, then the case default, else Ungrouped. A deleted or foreign id
  never fails a spawn and is forgotten only after the creating write lands.
- POST /api/quick-start (local, linked, remote, Docker) and
  /api/ralph-loop/start pass their case; POST /api/sessions infers it
  lexically from workingDir. The create response carries tabLayout when a
  case default placed the session.
- GET/PUT /api/cases/:name/default-group; deleting a case (or an admin
  deleting a user's case folder) forgets the value.
- The selector mirrors desktop and phone, reverts on a refused save, and is
  redrawn from every adopted tab layout; zh-CN strings added.
2026-10-22 03:42:42 -04:00
JD 63cada938d fix(mobile): give a sideways drag on the terminal to the session swipe alone
The terminal's touch handler and the session swipe judged every gesture separately, so a sideways flick also ended as a tap on the session being left (a link, a CLI click, a keyboard toggle) or as a vertical scroll. The terminal now locks the dominant axis past the tap slop, hands a sideways drag it cannot pan to the swipe and publishes the axis, and the swipe stands aside for scrolls, pans, a lift the terminal consumed (its selection gesture), touch selections, a second finger and surfaces with controls of their own. A touch that starts outside the terminal resets the published axis, so swiping from the phone home screen into a session keeps working after a terminal scroll. A deliberate swipe gets 500ms instead of 300ms, and vertical drift cancels it mid-gesture instead of only at the lift.
2026-10-21 21:40:27 -04:00
JD d56b90b7c6 fix(mobile): keep the keyboard up when an accessory key is pressed
An accessory key that acts on the terminal (arrows, Tab, Esc, Ctrl, scroll, clear input) took focus on press, so every tap blurred the terminal and the click handler had to focus it again: a blur/focus pair per tap that started a keyboard dismissal and shifted the toolbar each time. Such a key now cancels the mousedown default instead, the same pattern as the Attach input, so the terminal never loses focus on the press; the click-time refocus stays as the fallback. A first tap on clear/compact only arms the confirm and is treated the same way.
2026-10-21 21:40:23 -04:00
Saqeb Akhter 242bbfcd31 fix(terminal): capture remote history and preserve isolated wheel travel (#7) 2026-10-22 02:01:17 +04:00
Claudia[bot]andClaude Opus 5.5 3392a69290 docs: tighten the comments and skill text around multi-line input
- sendInput's docstring said all text without `\r` is typed; that now holds
  for single-line text only.
- The skill's big-input section still listed "the newline stripping" among
  the hazards a workspace file avoids; it is the unconfirmed multi-line
  paste now. Rewrapped, mirrored in plugins/codeman.
- The mobile composer's hand-back comment said the prompt transport strips
  newlines. The hand-back writes to the terminal prompt, whose text reaches
  the PTY as typed input, where a newline is a key; the behaviour (a
  multi-line draft stays parked) is unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-21 04:53:57 +02:00
Claudia[bot]andClaude Opus 5.5 e3de354461 fix(input): keep the line breaks of a multi-line mux prompt, pasted as one block
TmuxManager.sendInput() removed every `\n` before the text reached tmux, so a
multi-line prompt sent with `useMux` (or a multi-line respawn prompt) arrived as
one line with its lines run together: `"echo A\necho B\r"` ran `echo Aecho B`.

The text half of a submit has gone in as one bracketed paste
(buildPasteTextCommands) since the Codex paste-burst fix, and inside the paste
markers Claude Code and Codex insert a pasted line break into the composer
instead of submitting. So the `\n` is now kept (`\r\n` loses only its `\r`) and
the existing paste carries the lines; the Enter stays a separate tmux call.
Multi-line text without an Enter is pasted too rather than typed with
`send-keys -l`, where every line break would reach the pane as a key.
Single-line input is unchanged.

The test-mode gate moves from the top of sendInput() into inputRunner(), as
readPaneRows() does, so a test subclass can record the commands sendInput()
would run instead of pinning the branch shapes on the source.

SubmitVerifier still compares the composer's last glyph line with the prompt
minus its newlines, so it does not reliably recognise a multi-line paste and
may not re-press an Enter that Claude Code ignored. `agent send` and the TUI
therefore keep refusing or joining multi-line input; the docs that described
the stripping now describe the paste and that limit.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-21 03:51:31 +02:00
Devvyn 8a4ff775fb fix(config-backup): probe a custom folder before the retention fallback reads it, test that Save omits a displayed-only retention 2026-10-20 21:47:20 +08:00
Devvyn 9c0fc30927 fix(config-backup): the retention fallback follows the folder, a clock-ahead snapshot cannot make every pass write a copy 2026-10-20 20:32:14 +08:00
Devvyn 241886d44d fix(config-backup): a restore after a reset keeps the retention, the mode probe cannot write through a planted symlink, the form shows the retention in use 2026-10-20 19:31:55 +08:00
Devvyn 71fcefbaf2 fix(config-backup): ignore a Docker case's conversation id, list every ignored key, correct the retention and restart docs 2026-10-20 18:01:43 +08:00
Devvyn a0b9570457 fix(config-backup): age a snapshot from its successor, ignore activity-only rewrites, keep at least 2
Review round 3 on #661: retention aged each snapshot by its own createdAt, so the first change after a quiet month deleted the last good copy; it now ages from when the next snapshot was made. users.json lastLoginAt, settings.json lastUsedCase and intents.json recentPrompts/updatedAt are volatile keys for the change check. The keep count has a minimum of 2. Wiki restore paragraph aligned with RESTART_REQUIRED.
2026-10-20 18:01:43 +08:00