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:
+36
-20
@@ -8,6 +8,7 @@ export default {
|
||||
'nav.inbox': 'Boîte de réception',
|
||||
'nav.dashboard': 'Tableau de bord',
|
||||
'nav.projects': 'Projets',
|
||||
'nav.files': 'Fichiers',
|
||||
'nav.tasks': 'Gestionnaire de tâches',
|
||||
'nav.tasks.running': 'Tâches en cours',
|
||||
'nav.tasks.cron': 'Tâches Cron',
|
||||
@@ -266,26 +267,40 @@ export default {
|
||||
'projects.share.access.readwrite':'Lecture et écriture',
|
||||
'projects.tabs.files': 'Fichiers',
|
||||
'projects.tabs.sharing': 'Partage',
|
||||
'projects.files.col.name': 'Nom',
|
||||
'projects.files.col.created': 'Création',
|
||||
'projects.files.col.modified': 'Modification',
|
||||
'projects.files.col.size': 'Taille',
|
||||
'projects.files.empty': 'Ce dossier est vide.',
|
||||
'projects.files.refresh': 'Actualiser',
|
||||
'projects.files.drop': 'Déposez les fichiers ici pour les envoyer',
|
||||
'projects.files.btn.new_folder': 'Nouveau dossier',
|
||||
'projects.files.btn.upload': 'Envoyer',
|
||||
'projects.files.btn.download': 'Télécharger (ZIP)',
|
||||
'projects.files.uploading': 'Envoi…',
|
||||
'projects.files.action.download': 'Télécharger',
|
||||
'projects.files.action.rename': 'Renommer',
|
||||
'projects.files.action.delete': 'Supprimer',
|
||||
'projects.files.confirm.delete_file': 'Supprimer « {name} » ?',
|
||||
'projects.files.confirm.delete_dir': 'Supprimer le dossier « {name} » et tout son contenu ?',
|
||||
'projects.files.modal.mkdir': 'Nouveau dossier',
|
||||
'projects.files.modal.rename': 'Renommer « {name} »',
|
||||
'projects.files.modal.name': 'Nom',
|
||||
'projects.files.error.name': 'Saisissez un nom valide (sans barres obliques).',
|
||||
|
||||
// ── File explorer (shared component: projects, Files section) ───────────────
|
||||
'files.col.name': 'Nom',
|
||||
'files.col.created': 'Création',
|
||||
'files.col.modified': 'Modification',
|
||||
'files.col.size': 'Taille',
|
||||
'files.empty': 'Ce dossier est vide.',
|
||||
'files.refresh': 'Actualiser',
|
||||
'files.drop': 'Déposez les fichiers ici pour les envoyer',
|
||||
'files.btn.new_folder': 'Nouveau dossier',
|
||||
'files.btn.upload': 'Envoyer',
|
||||
'files.btn.download': 'Télécharger (ZIP)',
|
||||
'files.uploading': 'Envoi…',
|
||||
'files.action.download': 'Télécharger',
|
||||
'files.action.rename': 'Renommer',
|
||||
'files.action.delete': 'Supprimer',
|
||||
'files.confirm.delete_file': 'Supprimer « {name} » ?',
|
||||
'files.confirm.delete_dir': 'Supprimer le dossier « {name} » et tout son contenu ?',
|
||||
'files.modal.mkdir': 'Nouveau dossier',
|
||||
'files.modal.rename': 'Renommer « {name} »',
|
||||
'files.modal.name': 'Nom',
|
||||
'files.error.name': 'Saisissez un nom valide (sans barres obliques).',
|
||||
'files.title': 'Fichiers',
|
||||
'files.note.roots': 'Tout ce que vous pouvez atteindre : votre dossier personnel, vos deux mémoires et les dossiers partagés avec vous. Ce sont les chemins qu\'utilise l\'assistant.',
|
||||
'files.back': 'Tous les fichiers',
|
||||
'files.badge.readonly': 'Lecture seule',
|
||||
'files.error.unknown_path': '« {path} » ne fait pas partie de vos dossiers.',
|
||||
'files.root.home': 'Dossier personnel',
|
||||
'files.root.user_memory': 'Mémoire personnelle',
|
||||
'files.root.shared_memory': 'Mémoire partagée',
|
||||
'files.root.shared': 'Dossier partagé',
|
||||
'files.root.project': 'Projet',
|
||||
'files.root.skills': 'Compétences',
|
||||
'files.root.docs': 'Documentation',
|
||||
|
||||
// ── Détail du projet ────────────────────────────────────────────────────────
|
||||
'project_board.back': 'Projets',
|
||||
@@ -1213,6 +1228,7 @@ export default {
|
||||
'common.cancel': 'Annuler',
|
||||
'common.loading': 'Chargement…',
|
||||
'common.saved': 'Enregistré',
|
||||
'common.create': 'Créer',
|
||||
|
||||
// ── Shared Folders (blueprint §6) ────────────────────────────────────────────
|
||||
'nav.shared_folders': 'Dossiers partagés',
|
||||
|
||||
Reference in New Issue
Block a user