feat(files): a Files section over the caller's whole space
Nightly Build / build (push) Successful in 5m36s
Nightly Build / build (push) Successful in 5m36s
Until now file browsing existed only inside a project, and the two memory
stores were reachable only by the agent's tools. `#files` is the general
surface: home, both memory stores, the shared folders and projects the
caller belongs to, plus the read-only skills and docs trees.
The root is virtual, and that is the design. Anchoring at `~` is wrong:
the explorer reads host-side, while `shared/`, `projects/`, `skills/` and
`docs/` are bind mounts inside the container — a page rooted at the home
would show less than the user has with no way to reach the rest, and on
native Linux would show Docker's empty mountpoint stubs, a door that
appears to work and leads nowhere. So level 0 is a synthetic list from the
new `GET /api/files/roots`, serialized from the caller's `UserFs` plus the
two virtual memory roots. It sends `kind`, never a label: labels are copy
and get translated.
`GET /api/files/dir` now answers `{ path, can_write, entries }`, and a
memory path is classified before `resolve_view_path` (which refuses one)
and listed from `memory_docs`: one level derived from the flat key space
by the pure `memory_docs::immediate_children`, over a single query whose
unslashed prefix also spots an exact note as "not a directory". Memory is
read-only from the page — every writer routes through `resolve_view_path`,
and `shared-memory/*` is `@fs_write require` for the agent, so a button
that walks past that rule is a decision of its own.
The explorer moves out of projects into `shared/file-explorer.js`, taking
`root` + `rootLabel` and reading `can_write` from the listing rather than
from its host: writability changes per branch and comes from the same
`UserFs::can_write_to` the server rejects writes with, so the buttons
offered and the writes accepted cannot disagree. Deep-linking needed it
steerable without a two-way binding, hence `rel` in and
`explorer-navigate` out — the event fires only for a click, never for a
`rel` the host set, so echoing it back is a no-op.
The URL carries the agent path of the open folder in one parameter, the
same vocabulary the assistant uses, so a link is shareable and pasteable
into a conversation; which root it belongs to is derived, not stored.
docs/: a new files.md, plus two pages this made false — shared-folders.md
claimed in three places that a shared folder has no explorer, and
memory.md never said a user can now read their own notes.
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
# Files
|
||||
|
||||
The **Files** page (sidebar → Files) is where a member sees their own space: everything they can reach, in one list. Before it existed, files were reachable only through you — a user could ask "what's in the recipes folder?" but could not go and look. Now they can, and this document exists so you know what they are looking at when they mention it.
|
||||
|
||||
## What they see first
|
||||
|
||||
The page opens on a list of **places**, not files. This is deliberate: the things a person can reach are not folders inside one another, they are separate roots, and the list is the only level where they all appear together.
|
||||
|
||||
| Place | Path | Notes |
|
||||
| --- | --- | --- |
|
||||
| Home | `~` | Their own workspace. Always writable. |
|
||||
| Personal memory | `user-memory/` | Their private notes — the ones you keep for them |
|
||||
| Shared memory | `shared-memory/` | The group's common notes |
|
||||
| Shared folders | `shared/{name}` | One entry per folder they are a member of |
|
||||
| Projects | `projects/{owner}/{name}` | One entry per project they can reach |
|
||||
| Skills | `skills/` | Installed skill folders. Read-only |
|
||||
| Documentation | `docs/` | This documentation. Read-only |
|
||||
|
||||
A place they have no access to simply is not in the list — there is nothing to explain away.
|
||||
|
||||
**The paths shown are the paths you use.** Under each name the page prints the real path (`shared/recipes`, `projects/anna/holiday`), which is the same string you would pass to a file tool. That is worth pointing out to a user who asks how to tell you where to look: they can read the path off the page and say "the file in `shared/recipes/dolci`", and you will find it.
|
||||
|
||||
## Inside a place
|
||||
|
||||
Clicking a place opens a file explorer: one folder at a time, folders first, with size and dates. From there:
|
||||
|
||||
- **Clicking a file opens it** in the usual file viewer — Markdown rendered, images, PDFs, colored code, plain text.
|
||||
- **Clicking a folder goes into it**; the breadcrumb at the top walks back out, and the browser's back button works too. The address bar carries the folder, so a user can bookmark or paste a link to exactly where they are.
|
||||
- **The listing is live.** A file you create from a conversation, or another member uploads, appears within a second without a refresh. If a user says "it's not there", ask them to check the folder rather than assuming the write failed — but the page updates on its own, so a truly missing file is missing.
|
||||
- **ZIP download** — the button in the toolbar downloads the whole open folder as a single archive. Useful when someone wants "all the photos" rather than one file.
|
||||
|
||||
## What they can change, and where
|
||||
|
||||
Write buttons — new folder, upload (including drag & drop), rename, delete — appear **only where that person may write**. Everywhere else the page shows a **Read-only** badge and no buttons.
|
||||
|
||||
Read-only for everyone: **Skills**, **Documentation**, and both memory stores. Read-only for some people: a shared folder or project where they were given read access only.
|
||||
|
||||
This matters when a user asks you to do something they just failed to do in the page: if the badge said read-only, you cannot do it either — the same rule applies to your file tools, and asking you is not a way around it. Tell them who to ask (an admin for a shared folder, the owner for a project).
|
||||
|
||||
## Memory in the page
|
||||
|
||||
The two memory stores appear as ordinary folders, and this is the first place a person can read their notes themselves rather than asking you. Two things to explain if it comes up:
|
||||
|
||||
- **They are read-only here.** A user can open and read a note, but cannot edit or delete it from the page. Changing memory goes through you, in conversation — which is what keeps the history in `log.md` honest and, for shared memory, what keeps the confirmation step in place.
|
||||
- **The folders are not on disk.** Notes live in the database, not as files, so they will not appear if someone goes looking in a terminal. The page shows them as folders because that is the useful way to read them, not because they are files.
|
||||
|
||||
## What is not there
|
||||
|
||||
- **Places outside their space.** Only what is in the list. A path inside the sandbox but not under any of those roots (`/tmp/…`, for example) is not browsable from the page, though you can still read it with your own tools.
|
||||
- **Search.** There is no search box yet. Finding something by content is still a question for you — you can search notes and files far better than a folder-by-folder look.
|
||||
- **The phone app.** The Files page is desktop-only for now.
|
||||
|
||||
## Related
|
||||
|
||||
- [shared-folders.md](shared-folders.md) — who may see a shared folder, and read vs write access
|
||||
- [projects.md](projects.md) — projects have their own explorer on the project page, the same one this page uses
|
||||
- [memory.md](memory.md) — what goes in each memory store, and why shared memory asks for confirmation
|
||||
- [skills.md](skills.md) — what the skill folders hold and why they can only be changed by installing
|
||||
+2
-1
@@ -4,7 +4,7 @@ This folder is written for **you, the assistant**, not for the human directly. I
|
||||
|
||||
Keep answers grounded in what's actually enabled and configured for this instance — check with the relevant tool (e.g. list installed/enabled plugins) rather than assuming everything described here is turned on. A feature documented here may not be enabled on this particular instance.
|
||||
|
||||
This index will grow over time. Right now it covers the interface, agents, memory, projects, shared folders, background tasks, system agents, access grants, connectors, skills, the sandbox, voice input and plugins; more sections (security groups…) will be added later.
|
||||
This index will grow over time. Right now it covers the interface, files, agents, memory, projects, shared folders, background tasks, system agents, access grants, connectors, skills, the sandbox, voice input and plugins; more sections (security groups…) will be added later.
|
||||
|
||||
## Features
|
||||
|
||||
@@ -12,6 +12,7 @@ This index will grow over time. Right now it covers the interface, agents, memor
|
||||
| --- | --- |
|
||||
| [memory.md](memory.md) | Private and shared memory: what goes where, the indexes and history log, why some shared facts can't be changed on request |
|
||||
| [agents.md](agents.md) | Agents: the three kinds (chat, task, system), which one you are talking to and why, the specialist agents the assistant delegates to, how the model is chosen, and adding a custom agent |
|
||||
| [files.md](files.md) | The Files page: everywhere a member can reach — home, both memory stores, shared folders, projects, skills and docs — what they can change there, and what is deliberately read-only |
|
||||
| [projects.md](projects.md) | Projects: shared folders with their own assistant chat, a live file explorer, and member sharing |
|
||||
| [shared-folders.md](shared-folders.md) | Shared folders: admin-managed folders with no chat of their own — who sees them, read vs write access, why the assistant asks before touching them, and when to choose a project instead |
|
||||
| [system-agents.md](system-agents.md) | Background agents that run on a schedule (event triage, the two memory lints, the nightly conversation review of a supervised account): what they watch, why they only ever report, why a run can be skipped, and their settings |
|
||||
|
||||
@@ -19,6 +19,8 @@ The rule that decides between them, and the one to explain when a user asks: **s
|
||||
|
||||
**Writing to shared memory asks for confirmation.** Saving to their private memory is silent; adding or changing something in shared memory shows an approval card first, because it becomes visible to everyone. Appending to the shared `log.md` is the one exception — the history must always be recorded.
|
||||
|
||||
**They can read their notes themselves.** Both stores appear as folders on the **Files** page (sidebar → Files), so a user can open and read any note without asking you — but **read-only**: editing and deleting still go through you, which is what keeps `log.md` honest and, for shared memory, keeps the confirmation step in place. See [files.md](files.md).
|
||||
|
||||
**Superseded facts stay visible.** In shared memory nothing is deleted; an outdated fact is struck through and the new one added underneath. A user asking "why is the old date still there?" is seeing this on purpose.
|
||||
|
||||
**You may decline to change a shared fact.** Every shared fact records who put it there. If someone tells you a fact is wrong and it isn't theirs, you note their claim — marked `unconfirmed` — but leave the fact alone until the person it belongs to, or an admin, confirms it. Explain it as protection, not distrust: it means nobody can quietly rewrite what the group relies on, and it means a mistake or a joke can be undone.
|
||||
|
||||
@@ -9,7 +9,7 @@ Shared folders are **managed by an admin**: an admin creates them, decides who i
|
||||
Two things shared folders are *not*, so expectations stay right:
|
||||
|
||||
- They have **no chat of their own** — the files are shared, not a conversation. (That is what Projects are for; see [Shared folders vs Projects](#shared-folders-vs-projects) below.)
|
||||
- They have **no file explorer page** in the web app. Members work with the files through the assistant, and open individual files in the file viewer when the assistant shows them (see [Working with the files](#working-with-the-files)).
|
||||
- They have **no page of their own** in the web app. Members reach the files either through the assistant or from the general **Files** page, which lists every folder they belong to (see [Working with the files](#working-with-the-files)) — but there is no place where a folder is a thing with its own tabs, the way a project is.
|
||||
|
||||
## Creating a folder (admin)
|
||||
|
||||
@@ -35,12 +35,12 @@ Two things worth knowing about membership:
|
||||
|
||||
## Working with the files
|
||||
|
||||
There is no file explorer for shared folders — no grid of files, no upload button. The files live on the server, and members reach them through the assistant:
|
||||
There are two ways in, and they work on the same files:
|
||||
|
||||
- **Ask the assistant** — "what's in the recipes folder?", "add this note to documents", "send me the manual for the boiler". The assistant knows which folders you belong to, can list their contents, open and search files, and — if you have read & write — create and edit them.
|
||||
- **Open a file** — when the assistant shows you a file from a shared folder, it opens in the usual file viewer (Markdown rendered, images, PDFs, syntax-colored code, text), exactly like any other file. You can read it there; editing in the viewer is available if you have read & write access.
|
||||
- **Open the Files page** (sidebar → Files) — every shared folder you belong to is one entry in the list. From there you can browse it, open a file in the viewer, download it, download the whole folder as a ZIP, and — only if you have read & write — upload, rename and delete. See [files.md](files.md).
|
||||
|
||||
A practical consequence: if a member wants a file *from* a shared folder, the assistant is the way to get it — there is no download button on the folder itself. (An admin can of course reach the folder directly on the server, but members should not need to.)
|
||||
Searching by content is still the assistant's job: the Files page browses, it does not search.
|
||||
|
||||
## What the assistant knows
|
||||
|
||||
@@ -75,7 +75,7 @@ The two features look similar — a shared place for files with per-member acces
|
||||
|---|---|---|
|
||||
| Who manages it | An admin (no owner; anyone can be removed) | The owner (a member) and read & write members |
|
||||
| Where it lives in the chat | No chat of its own | Its own conversation with the assistant (`project-{id}`), plus extra tabs |
|
||||
| Files | No explorer page; work through the assistant | A live file explorer with upload, rename, delete, ZIP download |
|
||||
| Files | Browsable from the general Files page | The same explorer, on the project's own page |
|
||||
| Assistant's access | Every read/write asks for confirmation | Reads and writes are frictionless (only the folder's membership limits them) |
|
||||
| Typical use | A place to *keep* shared documents | A place to *work together* on something |
|
||||
|
||||
|
||||
Reference in New Issue
Block a user