feat: v2.7.6 — edit users in one form, Settings → Account, display names, copy over plain HTTP
- Users page: one Edit user form (display name, email, role, active, a new or generated password, workspaces given or taken back, sign out everywhere), validated as a whole before anything is written (PATCH /api/users/:id, GET /api/users/:id); users.display_name/email added migration-safe. - Settings → Account for every signed-in user: profile, own password (the current one required, this login kept), sign out other devices (/api/me/account, /api/me/password, /api/me/sign-out-others; login cookie only, never a pane token). - Display names wherever a person is named (sidebar, workspace owner groups, Users page and audit log); owner_display_name / reader_display additive. - Users page: admins add and remove Claude/Codex pool accounts. - Folder browser: an admin with their own Linux account opens in their home; the "Server folder" tick opens the host's (never remembered). - AI Proxy: "Config 9router" beside Add profile when 9router is installed, opened on the dashboard's own host (GET /api/ai-proxies/9router). - Terminal: a tmux selection reaches the clipboard over plain HTTP too (writeClipboard's textarea fallback, focus handed back). - Chat: a file the session touched outside the workspace previews (GET /api/sessions/:id/file). - install-system: `!requiretty` only when visudo accepts it (sudo-rs on Ubuntu 25.10+ rejects the setting). - openapi.yaml regenerated; docs (API, SERVER-MODE, LANES) updated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -8,8 +8,9 @@
|
||||
* `GET /api/lanes/:id/git/file` (or `/git/raw` for an image), a file under
|
||||
* `~/.claude` (a memory file, a plugin's skill) through `GET /api/cc-config/file`,
|
||||
* an attached image or text file through `GET /api/run/drop/:name`, an image
|
||||
* the session read anywhere else through `GET /api/sessions/:id/image`. Anything
|
||||
* else (or an image that route refuses) shows its path only. A Windows path's `\` counts as `/` throughout.
|
||||
* the session read anywhere else through `GET /api/sessions/:id/image`, and a
|
||||
* text file it read or wrote anywhere else through `GET /api/sessions/:id/file`.
|
||||
* Anything else (or a file those routes refuse) shows its path only. A Windows path's `\` counts as `/` throughout.
|
||||
* `SkillListModal` is the same dialog over the session's skills, each one's
|
||||
* SKILL.md found by name (`plugin:name` from the plugin list, else the user's
|
||||
* or the project's); a built-in skill has no file and shows by name only.
|
||||
@@ -106,6 +107,14 @@ function useContent(path: string, scope: PreviewScope): Content {
|
||||
// An image it read elsewhere (a screenshot under ~/.cache): served
|
||||
// only because this session's own Read named it.
|
||||
setContent({ kind: "image", src: api.sessions.readImageUrl(scope.sessionId, path) });
|
||||
} else if (scope.sessionId && /^(?:\/|[A-Za-z]:\/)/.test(file)) {
|
||||
// A text file it read or wrote elsewhere (a report under ~/Documents):
|
||||
// served only because this session's own Read/Write/Edit named it.
|
||||
show(
|
||||
api.sessions
|
||||
.readFile(scope.sessionId, path)
|
||||
.then((f) => ({ kind: "text", text: f.text, truncated: f.truncated }))
|
||||
);
|
||||
} else setContent({ kind: "none" });
|
||||
return () => {
|
||||
live = false;
|
||||
|
||||
Reference in New Issue
Block a user