mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-11-15 02:49:33 +01:00
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>
This commit is contained in:
1 parent
ae0de7a1ec
commit
dbb3202161
7 files changed
+22
-14
No files matched your search
@@ -905,10 +905,10 @@ html and svg are the ones deliberately kept out.
|
||||
`POST /api/filesystem/mkdir` with `{ path, name, sessionId?, showHidden? }` makes one
|
||||
folder directly inside `path`, which must be a folder the path picker may browse, and
|
||||
answers `{ path }`. `name` is one path segment (letters, numbers, spaces and `_ - . ~`, not
|
||||
starting with a dot or `~`). `400` for a cases folder (use Add Case → New Case) or a `path`
|
||||
that is not a directory, `403` for a blocked tree or a `path` outside the browse roots,
|
||||
`404` for a `path` that does not exist, `409` when the folder already exists, and `422`
|
||||
when the mount under `path` does not answer.
|
||||
starting with a dot or `~`). `400` for a cases folder (use Add Case → Create New with no
|
||||
custom folder) or a `path` that is not a directory, `403` for a blocked tree or a `path`
|
||||
outside the browse roots, `404` for a `path` that does not exist, `409` when the folder
|
||||
already exists, and `422` when the mount under `path` does not answer.
|
||||
|
||||
## Rendered HTML files
|
||||
|
||||
|
||||
@@ -435,7 +435,7 @@ The terminal provider scans `terminalLinkLine()`, which extends `terminalPathLin
|
||||
|
||||
### Filesystem path picker
|
||||
|
||||
**Filesystem path picker** (Link Existing "Browse" button + the extended mobile keyboard's `📁 Path` key): a lazy one-directory-at-a-time browser over `GET /api/filesystem/browse`, with `GET /api/filesystem/preview` serving the tapped file. It starts at the active session's working directory (falling back to the Codeman Cases root, then `/mnt/d`, then the first root), hides dot entries, and inserts the chosen path **without** Enter so the prompt is not submitted. The companion `⌫ All` key clears only the current unsent prompt buffer and must never emit the agent's `/clear` command. **New folder** (opt-in per caller, `allowNewFolder`; Link Existing and Create New's custom folder have it): `POST /api/filesystem/mkdir` `{ path, name, sessionId? }` creates ONE folder (non-recursive) directly inside a folder the picker may browse, resolved through the same roots, ownership and blocked-tree rules as browse (`403` outside them or in a blocked tree or unwritable, `404` missing parent, `409` exists, `400` a parent that is a file, or a name outside letters, digits, space and `_ - . ~`, containing `..`, starting with a dot or a tilde or over 255 bytes, so every name it accepts is one Link Existing accepts, and `400` a parent that is a cases directory, where a folder is already a case (Add Case > New Case makes one there); `showHidden` is forwarded like browse's); the picker reloads the folder and selects the new one. A picker that browses somewhere this route cannot create in (the container-workdir picker, `fetchListing`) must not set the flag.
|
||||
**Filesystem path picker** (Link Existing "Browse" button + the extended mobile keyboard's `📁 Path` key): a lazy one-directory-at-a-time browser over `GET /api/filesystem/browse`, with `GET /api/filesystem/preview` serving the tapped file. It starts at the active session's working directory (falling back to the Codeman Cases root, then `/mnt/d`, then the first root), hides dot entries, and inserts the chosen path **without** Enter so the prompt is not submitted. The companion `⌫ All` key clears only the current unsent prompt buffer and must never emit the agent's `/clear` command. **New folder** (opt-in per caller, `allowNewFolder`; Link Existing and Create New's custom folder have it): `POST /api/filesystem/mkdir` `{ path, name, sessionId? }` creates ONE folder (non-recursive) directly inside a folder the picker may browse, resolved through the same roots, ownership and blocked-tree rules as browse (`403` outside them or in a blocked tree or unwritable, `404` missing parent, `409` exists, `400` a parent that is a file, or a name outside letters, digits, space and `_ - . ~`, containing `..`, starting with a dot or a tilde or over 255 bytes, so every name it accepts is one Link Existing accepts, and `400` a parent that is a cases directory, where a folder is already a case (Add Case > Create New with no custom folder makes one there); `showHidden` is forwarded like browse's); the picker reloads the folder and selects the new one. A picker that browses somewhere this route cannot create in (the container-workdir picker, `fetchListing`) must not set the flag.
|
||||
|
||||
⚠️ **This is a second file-serving surface, so it carries the same confinement burden as [Attachments](#attachments) and does not inherit it automatically.** Traversal is allowlisted to Home, `CASES_DIR`, `/mnt/d`, or extra roots explicitly configured via `CODEMAN_FILE_PICKER_ROOTS`; sensitive trees are blocked and symlink escapes are rejected after `realpath` resolution rather than before. Without the realpath step a symlink inside an allowed root would walk straight out of it. `preview` reuses the shared conversion cache and the **global** `document-conversion-limiter`, which is what stops N concurrent large-document previews from forking N multi-minute converter processes. Content types are pinned: images and PDF inline, DOCX/PPTX through the converters, and Markdown/TXT/JSON as inert `text/plain` (never `text/html`, which would be stored XSS on our own origin). Size caps are 2MB for text and 50MB for binary/document previews.
|
||||
|
||||
|
||||
@@ -157,9 +157,12 @@ their workspace is bind-mounted at the same path.
|
||||
|
||||
## The path picker
|
||||
|
||||
For choosing a path rather than typing one. It appears in two places:
|
||||
For choosing a path rather than typing one. It appears in these places:
|
||||
|
||||
- **Browse** in **Add Case → Link Existing**.
|
||||
- **Browse** in **Add Case → Create New**, under **Create in a custom folder**.
|
||||
- **Browse** in **Add Case → Clone Repo**, under **Clone into a custom folder**.
|
||||
- **Browse** on the folder fields of **Add Case → Docker**.
|
||||
- The **📁 Path** key on the mobile keyboard bar.
|
||||
|
||||
It browses one directory at a time and can show hidden entries on request. The current
|
||||
@@ -171,10 +174,11 @@ choice is remembered per device. The picker inserts the path into your prompt
|
||||
**without** pressing Enter, so nothing is submitted by accident. Its sibling **⌫ All**
|
||||
key clears the unsent prompt, and never sends the agent's `/clear` command.
|
||||
|
||||
In the **Link Existing** and **Create New** (custom folder) pickers, **+📁** (New folder) makes a folder inside the folder you
|
||||
are viewing and selects it. Names use letters, numbers, spaces and `_ - . ~` (not starting
|
||||
with a dot or `~`). The cases folder is refused, since every folder there is already a
|
||||
case: use **Add Case → New Case** instead.
|
||||
In the **Link Existing** and **Create New** (custom folder) pickers, **+📁** (New folder)
|
||||
makes a folder inside the folder you are viewing and selects it. Names use letters,
|
||||
numbers, spaces and `_ - . ~` (not starting with a dot or `~`). The cases folder is
|
||||
refused, since every folder there is already a case: pick a folder outside it, or make
|
||||
the case with **Add Case → Create New** (no custom folder).
|
||||
|
||||
This is a separate file-serving surface from the viewer, with its own rules: it allowlists
|
||||
your home directory, the cases directory, and anything in `CODEMAN_FILE_PICKER_ROOTS`, and
|
||||
|
||||
Reference in new issue
Block a user