Commit Graph
3714 Commits
Author SHA1 Message Date
Codeman maintainer aacf105cea Merge #614 fix(files): prevent large folders starving File Viewer results
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 05:04:44 +01:00
Codeman maintainer 76e40668fc Merge #766 feat: edit history panel for remote (SSH) claude sessions
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 05:04:19 +01:00
Codeman maintainer 44349395d0 Merge #753 feat(codex): let Codex sessions drive other sessions through the codeman skill
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 05:03:54 +01:00
Codeman maintainer 11208a153c Merge #768 feat(install): install without administrator rights (--no-admin)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 05:03:29 +01:00
Codeman maintainer a2c530b93c Merge #573 feat(docker): guided first run for the Compose deployment
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 05:03:04 +01:00
Codeman maintainer cddfc07550 Merge relprep/rtl fix(response-viewer): lay out Persian, Arabic and Hebrew right to left (#715)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 05:02:36 +01:00
Codeman maintainer 9ba5a89123 Merge #761 feat(picker): New folder button for Create New's custom folder picker
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 05:02:08 +01:00
Codeman maintainer f8832ec78f Merge #772 fix(files): list the git worktree an agent moved into
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 05:01:41 +01:00
Codeman maintainer 9751f51bdc Merge #767 fix(custom-model): give a session its own env values back when the selection goes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 05:01:14 +01:00
Codeman maintainer 4d20b9c898 Merge #771 fix(pi): keep the mouse wheel working after a tab switch or reload
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 05:00:46 +01:00
Codeman maintainer 9e9031214e Merge #770 fix(remote): stop the local shell expanding the remote launch (exit 127 since 1.47.0)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 05:00:18 +01:00
Codeman maintainer 78b1cb26dc Merge #764 fix(cases): serialize every write to linked-cases.json
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 04:59:52 +01:00
Codeman maintainer 39d0e6c5ab docs: describe right-to-left rendering in the manual and the invariants (release review)
The wiki gains right-to-left notes for Last Response, the phone's Compose
editor and the rendered Markdown view, plus a Troubleshooting entry for the
#715 report: the terminal is xterm.js, which has no right-to-left support
(xtermjs/xterm.js#701). src/web/CLAUDE.md and the invariants now state the dir
pins, the logical-property rule and that the direction pass runs last.

The changeset claimed every file path stays left to right. It now says only
what holds: the paths the viewer links on its own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 04:49:02 +01:00
Codeman maintainer 4413240c5f fix: set dir="auto" after the linkifier so code-only documents stay linear (release review)
`_renderMarkdown` wrote dir="auto" into its string, before the code pins and
the linkifier. An element carrying dir="auto" re-resolves its direction on
every insertion under it, and a block whose letters all sit in `dir` children
walks its whole subtree each time, so a code-only or path-only document went
quadratic, English ones included.

Measured in real Chromium through the real File Viewer, before and after:
9000 inline-code items 8.7 s to 0.35 s, 9000 bare paths 5.6 s to 0.23 s, a
209 KB out-of-workspace list 41.9 s to 1.4 s. All three now match master.

The pass is now `_applyBlockDirection()`, run last on the DOM by both
consumers. The direction results are unchanged. Tests pin that the rendered
string holds no dir="auto" and that the pass runs after the linkifier.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 04:49:02 +01:00
Codeman maintainer 0141c8954c fix: the wiki's install table says git pull too, and the pty tests skip without script (release review)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 04:34:24 +01:00
Codeman maintainer c97b592ee2 fix: bring the docs in line with the no-admin route (release review)
Name the real trigger and CODEMAN_NO_ADMIN=0 in the READMEs and the
Installation page, add the install without git to the update tables and the
updater notes, record the installer's downloads in the supply chain section,
and say that the data directory question also removes a kept runtime.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 04:34:18 +01:00
Codeman maintainer 49b2c0e9bd fix: no-admin route messages, noexec tmp, unset USER and install dir slash (release review)
An account sudoers lists by name, with a password, is routed to no-admin
because nothing can read sudoers without reporting to the administrator.
The route itself stays as chosen, but the reason no longer claims the
account may not use sudo, and every message that ends or sums up the route
names CODEMAN_NO_ADMIN=0 for that reason alone.

tmux and cloudflared are staged in the home folder, so a noexec /tmp no
longer reports a working build as one that does not run. USER gets a default
at the top of the script, which also covers the older lines this route can
reach. A trailing slash on CODEMAN_INSTALL_DIR no longer puts .new and .old
inside the install. The data directory prompt names a runtime kept one
prompt earlier.

The uninstall check reads the source and must never drive uninstall(): HOME
does not redirect systemctl --user, so a drive reaches the real service.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 04:34:18 +01:00
Codeman maintainer ba2475c84f fix: updating a Compose install takes a git pull, and the docs say what the script does (release review)
The summary and README said rerunning the script updates Codeman. It never
fetches, so that was a successful no-op. The summary, README, its zh-CN mirror
and the wiki now say git pull, then rerun, with the in-app route first.

Also corrects "printed once" (twice at a terminal, never off one), says a typed
answer beats a preset, adds the first-run setup, the 180 s wait, --no-wait and
the changeme refusal to Running-As-A-Service and Troubleshooting, and records in
architecture-invariants why docker/.env is generated FROM .env.example.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 04:31:26 +01:00
Codeman maintainer 1a5b314d33 fix: a generated password goes to a terminal only (release review)
With stdout captured (CI, provisioning, `| tee`) the log held the password twice
for a service that controls Docker on the host, while docker/.env, the stronger
copy, is 0600. Off a terminal the script now points at the file instead. The note
beside it no longer promises a second showing, which `--setup-only` never gave.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 04:30:17 +01:00
Codeman maintainer f41e0cc6d4 fix: dot segments and doubled slashes cannot spell around the data folder refusals (release review)
The refusals of $HOME, ~/.codeman and the checkout compare strings, so
`~/../me` or `<repo>/../repo/data` passed them: the first shares state with a
native install, the second lands in the build context, where `COPY . .` would
bake CLI logins into the image. Doubled slashes are collapsed and any `.` or
`..` segment is refused.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 04:29:51 +01:00
Codeman maintainer 7ada939182 fix: refuse a docker/.env that exists but is not a regular file (release review)
The first-run gate tested `! -f`, so a dangling symlink was silently replaced,
and a directory got a 0600 temp file holding a working password, a "Wrote"
message and exit 0, with setup repeating on every later run. Setup now runs only
when nothing is there. A symlink to a real file stays an existing install.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 04:29:21 +01:00
Codeman maintainer 10a53579c6 fix: Update-Codeman.sh no longer closes the settings pipe early (release review)
The CODEMAN_APPDATA_PATH read ended awk at its first match. Whatever wrote the
rest of `config --environment` then met a closed pipe, and pipefail ended the
script with exit 141 and no message. Real Compose wins that race (0 of 50 runs,
on 2.33.0 and 5.5.0), so nobody has reported it, but the test stub, once it
honoured the shell environment, lost it. Same read as the password check below.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 04:29:00 +01:00
Codeman maintainer d539a7a3a2 fix: refuse a value ending in a backslash on the first run (release review)
In a single-quoted dotenv value a backslash escapes the closing quote, so a
password or data path ending in one passed validation and produced a docker/.env
Compose cannot parse. The error named an unrelated line, printed the password,
and a rerun never asked again. The env_quote comment claimed a single quote was
the only character such a value cannot hold, and the test stub's comment said
bash reads these values the way Compose does: both corrected, and a test now
reads generated values back by Compose's rules.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 04:28:01 +01:00
Codeman maintainer af6fcb624b fix: a first run's typed answers reach the stack, not just docker/.env (release review)
Compose prefers the shell environment over the env file, so with
CODEMAN_APPDATA_PATH or CODEMAN_PORT preset, a different typed answer went into
docker/.env and the summary while the stack ran on the preset: state split
across two folders and the next plain start mounted another home. Setup now
unsets everything it wrote, so the file it just printed is what Compose reads.
The test stub honours that precedence, and the questions get their first test
through a real pty.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 04:27:24 +01:00
Codeman maintainer 666e595dfc fix: the Docker daemon preflight fires on CLI 24 through 27 (release review)
`docker info --format` exits 0 with the daemon unreachable on those clients,
so a user outside the docker group got a raw Compose error and a "network
hiccup" hint after docker/.env and the data folder had already been written.
`docker version --format` exits 1 on every release and keeps the same stderr
text, so the permission branch still matches. The test stub now answers `info`
the way those clients do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 04:26:53 +01:00
Codeman maintainer 0bc6171687 chore: merge master into the release review branch for PR 573
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 04:23:10 +01:00
Codeman maintainer aae0951d4e fix: name which picker rules skip the container picker (release review)
The New folder rule in the same paragraph does cover that picker, so "none of
the host rules" said too much.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 04:06:52 +01:00
Codeman maintainer 19a2197f84 docs: say which picker each statement covers (release review)
The picker is now reached from every Add Case Browse button, so three lines
in the manual and the opening of the CLAUDE.md and architecture-invariants
paragraphs read wrong. A Browse fills its form field, only the Path key types
into a prompt, and Docker's Container Workdir picker lists the inside of the
container through POST /api/docker-cases/browse: it always shows dot entries
and the host allowlist does not apply to it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 04:03:32 +01:00
Codeman maintainer 3ef65d7c74 fix: let the path picker's error status wrap (release review)
The cases-folder refusal grew to 143 characters, and the status line is one
line with an ellipsis and no title, so at 513px on desktop it ended at "or
make the case with Ad..." and lost the instruction. .path-picker-status.error
now wraps: 2 lines on desktop, 4 on a phone, measured clear in Chromium at
both, and it covers the picker's other refusals too.

Tests: a pin on that rule (fails without the fix), and the option check now
reads each picker's whole options object instead of a fixed 400 characters,
which stopped short of the container-workdir picker's 829. Retitled to say
what it checks: Create New has the flag too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 04:02:11 +01:00
Codeman maintainer f37f101137 Merge remote-tracking branch 'origin/master' into relprep/rtl 2026-11-06 04:01:39 +01:00
Codeman maintainer fafec35344 fix: bound what the Files panel walk reads and keep its subfolders in it (release review)
The round-robin walk capped what it listed, not what it read: every queued
folder was read whole, sorted and held until drained, so one GET could pull
millions of entries (100 folders of 50,000 files killed a 400 MB heap). A read
now keeps only the entries the listing can use, and MAX_WALK_ENTRIES_READ stops
opening folders at 250,000 entries, leaving the rest queued and flagged.

A folder also spent its whole share on its own files, leaving nothing for the
subfolders it had just found, alone in its round or beside a sibling, so search
hits inside them were lost. Its files now count as one more share beside those
subfolders. Math.max(directoriesInRound, 2) would have fixed only the sole-folder
case and cut a wide root's folder list short.

Folders below the walk root are probed before their readdir (#516), since the
walk reaches folders the depth-first one never did.

Filtering at the read also clears the false flag on a folder whose only unread
entries were hidden or excluded, and an exactly-full workspace now finishes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 03:53:08 +01:00
Codeman maintainer 962aa9b998 fix: the remote docs name the Edit history diffs as the exception (release review)
"Nothing is copied to the Codeman host" stopped being true when the Edit
history panel started keeping diffs read from a remote session's
transcripts. The README, the wiki's Remote SSH Sessions page and its
Security page now name that exception, in the wording the PR already uses
on Working With Files and in remote-sessions.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 03:49:59 +01:00
Codeman maintainer 81f8c8e894 fix: the live transcript lookup targets the exact tmux session (release review)
list-panes -t '=name' with no colon is a window target to tmux, so a
remote session that is gone resolved to a window of that name or to a
session the name is a prefix of, and the Edit history panel moved to that
session's conversation and stored its diffs. `=name:` is an exact session
match, as src/remote-pane-history.ts already uses. Measured on tmux 3.4.

The fake tmux in the test matched the name as a substring, so it passed
with or without the colon. It now needs the exact token and answers a bare
prefix the way real tmux does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 03:49:59 +01:00
Codeman maintainer dbb3202161 fix(picker): word the cases-folder refusal for both pickers, and finish the review items
With the folder field empty, Create New's Browse opens in the cases folder, and New
folder there answered "Use Add Case > New Case". There is no tab of that name (the
label is Create New), and a Create New user is already on it. The refusal now reads
right from Link Existing and from Create New's custom folder. Its test pin, the code
comment, the manual, api-reference, CLAUDE.md and architecture-invariants move with it.

The block() helper in the New folder picker test returned an empty string for a name
that is not in session-ui.js, so .not.toContain passed and a renamed picker dropped out
of the check. It now asserts the name was found.

The manual's path picker list said two places and left out Create New, which the New
folder paragraph names. It now lists every Browse that opens the picker, and that
paragraph is rewrapped to the page's width.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 03:40:58 +01:00
Codeman maintainer ae0de7a1ec Merge origin/master into relprep/pr-761
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 03:37:24 +01:00
Codeman maintainer 14716114cb fix: format the Codex changeset's frontmatter (release review)
Prettier wants single quotes on the package key, as earlier changesets in this
repository have. Valid YAML either way, so the release is unaffected.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 03:30:06 +01:00
Codeman maintainer e10b84dcdd fix: refresh comments that still say claude is the only gated CLI (release review)
Codex now declares a version gate too, so the notes in session.ts and
docker-hosts.ts were wrong, the hooks-config caveat described every local codex
when --no-daemon now covers 0.162 and later, and session-routes left network
access out of the launch defaults. architecture-invariants gains --no-daemon and
the network config in its list of Codex flags. Comments and docs only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 03:25:00 +01:00
Codeman maintainer 353fe7ebcf fix: say what Allow network access really opens (release review)
The setting told users the sandbox and approvals stay on. With it on, a
command in Codex's sandbox can call Codeman's API, which can start a session
outside the sandbox with no approval prompt. Measured on codex 0.162.0 with
`codex sandbox`: a touch the sandbox refused landed through POST /api/sessions,
and from inside a Codeman pane it landed with a password set too, because a
pane inherits CODEMAN_PASSWORD. Without that password the same call gets 401.

The settings row, the wiki, the skill and the changeset now say so, the wiki
Security page and security-architecture name it, and the docs scope the claims
to what the code does: app-wide, local launches only, not cron jobs, and
--no-daemon is a local launch's flag. Agent-CLIs gains the --no-daemon
trade-off. A test pins that no surface sells the sandbox as still in charge.

Text only: the switch, the clamp and the launch are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 03:25:00 +01:00
Codeman maintainer 08d99da5ae test(edit-history): the ssh kill test no longer races the fake's pid file
The test waited for a real 1000 ms timeout and read the pid file afterwards.
On a loaded machine the kill could land before the fake ssh wrote it. It now
waits for the pid and sends the timeout's SIGTERM itself, which is all Node's
timeout does. Without exec the fake still survives and the test goes red.

The invariants said "the reads" go through buildRemoteEditHistoryCommand; the
image probes go through remoteProbePaths, on the same limiter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 03:17:14 +01:00
Codeman maintainer b5066744be fix(edit-history): a remote read with many subagents spans several round trips
The read script carries one case line per subagent cursor, and the whole
script is one argument of the ssh line, which Linux caps at 128 KiB. From
about 1000 subagents the command failed with E2BIG. The cursors have no cap
and the stored conversation is read first, so the session stayed unavailable
and not even a /clear got past it.

A read with more than 300 subagent requests now takes several round trips.
The cut is by name range, not only by count: the script takes a file no case
line names for a new one, so plain groups would read each other's files as
new. Each round trip walks only the names between its cuts, through one awk,
so a new file lands in exactly one range. Budget and meta budget carry over,
and a later round trip still lists its files, because a requested file missing
from the result loses its cursor. A failed round trip fails the whole read and
nothing of it reaches the store. A read of up to 300 runs no awk at all.

Each round of the 60-seed fuzz is also cut at a random size and compared with
the local reader. Run outside the suite too: bash --posix, BusyBox and mawk,
and bash 3.2 in a container, which is macOS sh. That shell cannot parse a case
inside $(...), so the names come from a shell function.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 03:13:03 +01:00
Codeman maintainer 26b63aea2d fix(edit-history): remote lookup finds tmux, a timeout reaches ssh, docs follow
Applies the review of #766.

The live lookup ran tmux on the bare PATH of the ssh command. On a host
where tmux sits in ~/.local/bin or /opt/homebrew/bin it found no pane, the
2>/dev/null hid that, and the panel stayed on the launch conversation after
a /clear. It now goes through withRemoteTmuxPath(), inside the sh script and
scoped to the $(...), so the other tools keep the PATH they had. The fake
tmux of the test block moved to $HOME/.local/bin for the same reason: that
directory is first on the new PATH, so a real tmux is never asked.

The two ssh commands get exec. Node signals the local sh -c, and dash stays
the parent of a plain command, so ssh survived the timeout. A test with a
fake ssh shows the process dies now and survives without exec.

The comment at the meta budget claimed a meta past it comes with a later
read. A meta comes only with a subagent's first read, so it is never sent.

Docs: the store is named as the exception to "never copied to local disk",
remoteProbePaths and the remote transcript lookup are described, and the
line saying a remote session loads no store is gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 02:57:58 +01:00
Codeman maintainer a908be05ac fix(files): mark folders the scan limit stopped short of
The fair rounds give a directory its node before reading it, so every folder
still queued when the 5,000-node budget ends sat in the tree with empty or
partial children and read as an empty folder. Keep the node on the tree cursor
and set an additive incomplete: true on every cursor left in the queue, then
draw one dim, inert row under such a folder while it is expanded. The envelope
check ignores keys it does not know, so old and new clients stay compatible.

Stop each round at the top once the budget is spent, before the shift: the
rest stay queued unread, and flagged, rather than read and sorted for nothing.

Say what the walk is: a per-directory round-robin (breadth-first), fair per
directory and not per subtree, with search results now shallow-first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 02:57:28 +01:00
Codeman maintainer 131a12d195 docs(codex): say what Allow network access leaves alone
The owner's answer to the PR's open question: the switch does not also pass
--sandbox workspace-write. Settings, wiki, skill and release note now state
the consequence: a folder Codex runs read-only keeps the network closed and
asks per command. A golden test pins the decision by name, and the stale
launch-defaults comments now name networkAccess.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 02:52:52 +01:00
Codeman maintainer bb42f8105e Merge branch 'relprep/pr-772' into relprep/pr-614
Both sides rewrite the /files walk. Keep the fair rounds from #614 and carry
the two things #772 does to the walk onto them: both queues start at walkRoot,
and the search predicate reads a path relative to the listing while every
returned path stays relative to workingDir.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 02:51:50 +01:00
Codeman maintainer 35ff4e886c Merge origin/master into relprep/pr-753
Conflict in src/session-cli-registry-bridge.ts: kept the PR's gateVersion() (gates measured against the gated CLI's own version) and added master's Discord startup hint engine value.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 02:50:25 +01:00
Codeman maintainer 0d42fdc0cf Merge remote-tracking branch 'origin/master' into relprep/pr-614 2026-11-06 02:44:43 +01:00
Codeman maintainer a8688f14a0 fix: disclose the tcsh regression and bring the launch docs in line (release review)
A tcsh login shell worked on 1.48.0 only because the local sh rewrote
${SHELL:-/bin/sh} to this host's shell. With the launch verbatim, tcsh gets -i -l,
refuses it and every stock launch leaves a dead pane. The changeset and
docs/remote-sessions.md described that as a standing limitation; they now name it
as a change in this release, with what the override workaround costs.

Also: extraSshOptions joins the list of values now literal at launch, the stock pane
command is shown as /bin/sh -c in the docs and the builder's JSDoc, the invariants
state how the launch must reach the far end, the manual pages cover $ in an override,
and the invariants no longer say extraSshOptions refuses a bare $ (it never did).

Reworded the em-dashes on the invariants line this rewrites.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 02:39:42 +01:00
Codeman maintainer 9b73ab3dbe fix: state what a clear and a restart keep in the custom-model docs (release review)
Records the limit on a session with its own CLAUDE_CONFIG_DIR, which does not
carry its conversation across an endpoint because the isolated projects link
goes to the server's tree. Also records that an own home set before a restart
with no selection is lost on clear, that only an absolute path is persisted,
and tells the user manual what a clear gives back.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 02:39:11 +01:00
Codeman maintainer 4513ef6ebb fix: keep a disabled CLI's keys in the owner env clamp (release review)
ownerClampedEnvKeys() read enabledClis(), so disabling a CLI dropped its
privileged keys from the clamp, and a revoked owner got a saved home back on
recovery or reboot restore. getCli() still returns a disabled entry, and a
session can outlive the switch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 02:39:11 +01:00
Codeman maintainer db5222c4fa fix: keep a home value that is not a path off disk, and re-apply from the own home (release review)
getCustomModelForPersist() trusted homeEnvVar to name a path, but the registry
types it as any env name, so a clis.json override could write a session's own
credential to state.json. Only an absolute path is written now.

A re-apply resolved the CLI's real home from what the session's map held, which
under a selection is the injected directory, and recovery resolved none at all.
An entry the own home lacks (settings.yaml) was then linked from the server's
home on an endpoint switch and on recovery. The route now reads the new
Session.ownEnvValue(), and recovery reads the clamped record through the same
bounded guard, under the bulk cap since it walks every saved session. Also
corrects the comment that said only a removed directory gets its links again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 02:39:11 +01:00