feat(p8): vue IDE /workspace (arbre + Monaco + diff + terminal)

- backend: garde-fou conflit d'édition par mtime (GET renvoie mtime, PUT refuse en 409 STALE_FILE si baseMtime périmé)
- lib: wt-key (base64url du chemin worktree), diff-parse (parseur pur du diff unifié → hunks)
- composables: useMonaco (import dynamique → chunk isolé), useWorkspaceLayout (largeurs/panneau persistés)
- components/workspace: GitStatusBadge, FileTree+FileTreeNode (lazy fs/list includeFiles), ChangedFilesPanel, DiffViewer (coloration +/-), MonacoEditor (Ctrl+S + bannière conflit reload/overwrite)
- views/WorkspaceView: 3 colonnes desktop redimensionnables + SegmentedControl mobile, header live (GitStatusBadge), watchWorktree → refresh diff/changements, terminal de la session corrélée
- router meta 'ide' + route /workspace/:repoId/:wt ; App.vue plein écran sans AppShell ; WorktreeCard bouton « Ouvrir l'IDE »
- deps: monaco-editor (lazy, vendor-monaco isolé, 0 impact bundle initial) ; vite manualChunks
- i18n EN+FR (workspace/editor/diff/git) ; tests diff-parse + wt-key ; acceptance-p8.mjs (mtime/409 + diff)
This commit is contained in:
2026-06-27 13:47:10 +02:00
parent c8dd539571
commit 75efecf93f
26 changed files with 1142 additions and 6 deletions

View File

@@ -202,6 +202,39 @@ export default {
create: 'Create',
creating: 'Creating…',
},
workspace: {
open: 'Open IDE',
files: 'Files',
changes: 'Changes',
noChanges: 'No changes',
changesTruncated: 'Too many changes — list truncated.',
terminal: 'Terminal',
editor: 'Editor',
diff: 'Diff',
noFileOpen: 'No file open',
noFileHint: 'Pick a file in the tree to edit it, or a changed file to view its diff.',
noSession: 'No session here',
noSessionHint: 'Start a session on this worktree from the dashboard to get a terminal.',
},
editor: {
save: 'Save',
unsaved: 'Unsaved changes',
conflict: 'This file changed on disk since you opened it.',
reload: 'Reload',
overwrite: 'Overwrite',
},
diff: {
binary: 'Binary file — no text diff.',
tooLarge: 'Diff too large to display.',
noChanges: 'No changes in this file.',
},
git: {
ahead: 'commits ahead',
behind: 'commits behind',
staged: 'staged',
unstaged: 'unstaged',
conflicts: 'conflicts',
},
terminal: {
observer: 'observer (read-only)',
sessionEnded: 'Session ended',