spectoflow 0.24.0 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.md +28 -6
  2. package/bin/spectoflow.js +88 -6
  3. package/lib/dashboard/connector.js +193 -0
  4. package/lib/dashboard/handlers.js +2 -27
  5. package/lib/dashboard/hub-server.js +103 -11
  6. package/lib/dashboard/inject-design.js +41 -0
  7. package/lib/dashboard/meeting.js +116 -0
  8. package/lib/dashboard/ops.js +83 -2
  9. package/lib/dashboard/public/app.js +738 -118
  10. package/lib/dashboard/public/charts.js +3 -3
  11. package/lib/dashboard/public/commands.js +77 -0
  12. package/lib/dashboard/public/designs/console.css +7 -19
  13. package/lib/dashboard/public/designs/orbit.css +3 -4
  14. package/lib/dashboard/public/designs.js +2 -2
  15. package/lib/dashboard/public/fonts/bricolage-grotesque-400.woff2 +0 -0
  16. package/lib/dashboard/public/fonts/bricolage-grotesque-600.woff2 +0 -0
  17. package/lib/dashboard/public/fonts/bricolage-grotesque-700.woff2 +0 -0
  18. package/lib/dashboard/public/hub.html +1 -1
  19. package/lib/dashboard/public/hub.js +27 -4
  20. package/lib/dashboard/public/i18n.js +60 -18
  21. package/lib/dashboard/public/icons.js +2 -0
  22. package/lib/dashboard/public/index.html +106 -13
  23. package/lib/dashboard/public/styles.css +161 -26
  24. package/lib/dashboard/public/vendor/prism/prism-bash.min.js +1 -0
  25. package/lib/dashboard/public/vendor/prism/prism-c.min.js +1 -0
  26. package/lib/dashboard/public/vendor/prism/prism-clike.min.js +1 -0
  27. package/lib/dashboard/public/vendor/prism/prism-core.min.js +1 -0
  28. package/lib/dashboard/public/vendor/prism/prism-cpp.min.js +1 -0
  29. package/lib/dashboard/public/vendor/prism/prism-csharp.min.js +1 -0
  30. package/lib/dashboard/public/vendor/prism/prism-css.min.js +1 -0
  31. package/lib/dashboard/public/vendor/prism/prism-docker.min.js +1 -0
  32. package/lib/dashboard/public/vendor/prism/prism-go.min.js +1 -0
  33. package/lib/dashboard/public/vendor/prism/prism-java.min.js +1 -0
  34. package/lib/dashboard/public/vendor/prism/prism-json.min.js +1 -0
  35. package/lib/dashboard/public/vendor/prism/prism-kotlin.min.js +1 -0
  36. package/lib/dashboard/public/vendor/prism/prism-markdown.min.js +1 -0
  37. package/lib/dashboard/public/vendor/prism/prism-markup-templating.min.js +1 -0
  38. package/lib/dashboard/public/vendor/prism/prism-markup.min.js +1 -0
  39. package/lib/dashboard/public/vendor/prism/prism-php.min.js +1 -0
  40. package/lib/dashboard/public/vendor/prism/prism-python.min.js +1 -0
  41. package/lib/dashboard/public/vendor/prism/prism-ruby.min.js +1 -0
  42. package/lib/dashboard/public/vendor/prism/prism-rust.min.js +1 -0
  43. package/lib/dashboard/public/vendor/prism/prism-sql.min.js +1 -0
  44. package/lib/dashboard/public/vendor/prism/prism-swift.min.js +1 -0
  45. package/lib/dashboard/public/vendor/prism/prism-yaml.min.js +1 -0
  46. package/lib/dashboard/routes.js +38 -0
  47. package/lib/dashboard/runner.js +7 -2
  48. package/lib/workspace.js +36 -1
  49. package/package.json +3 -3
  50. package/templates/config.json +23 -0
  51. package/lib/dashboard/public/fonts/space-grotesk-400.woff2 +0 -0
  52. package/lib/dashboard/public/fonts/space-grotesk-500.woff2 +0 -0
  53. package/lib/dashboard/public/fonts/space-grotesk-700.woff2 +0 -0
@@ -20,16 +20,17 @@
20
20
  const I18N = {
21
21
  en: {
22
22
  'nav.board':'Board','nav.requests':'Requests','nav.attention':'Attention','nav.backlog':'Backlog',
23
- 'nav.workflow':'Workflow','nav.team':'Agents & Skills','nav.files':'Files','nav.chat':'Chat','nav.info':'Info','nav.docs':'Documentation','nav.settings':'Personalize',
23
+ 'nav.workflow':'Workflow','nav.team':'Agents & Skills','nav.files':'Files','nav.notes':'Notes','nav.meeting':'Daily meeting','nav.chat':'Chat','nav.info':'Info','nav.docs':'Documentation','nav.settings':'Personalize',
24
24
  'status.todo':'To do','status.in_progress':'In progress','status.to_validate':'To validate',
25
25
  'status.to_analyze':'To analyze','status.done':'Done','status.blocked':'Blocked',
26
26
  'filter.all':'All','filter.open':'Open','filter.resolved':'Resolved',
27
27
  'action.run':'Run','action.send':'Send','action.orchestrate':'Orchestrate','action.approve':'Approve','action.summarize':'Summarize','action.clear':'Clear',
28
- 'action.cancel':'Cancel','action.add':'Add','action.edit':'Edit','action.delete':'Delete',
28
+ 'action.cancel':'Cancel','action.add':'Add','action.edit':'Edit','action.delete':'Delete','action.save':'Save',
29
29
  'action.resolve':'Resolve','action.reopen':'Reopen','action.validateToTask':'Validate → task',
30
30
  'action.addToAnalyze':'Add + to analyze',
31
31
  'topbar.navToggle':'Toggle menu','topbar.run.title':'Open the run chat',
32
32
  'topbar.theme.toggle':'Toggle light / dark theme','topbar.theme.toggle.title':'Toggle light / dark',
33
+ 'offline.banner':'{name} is offline — last seen {when}. Read-only until its machine reconnects.','offline.readonly':'This project is offline (read-only).',
33
34
  'topbar.mode.title':'Autonomy mode — change from here or in Personalize',
34
35
  'topbar.lang.title':'Output language — change from here or in Personalize',
35
36
  'topbar.agent.title':'Active agent — change from here or in Personalize',
@@ -37,6 +38,8 @@ en: {
37
38
  'board.filterPlaceholder':'Filter tasks…','board.expandAll':'Expand all','board.collapseAll':'Collapse all','board.hideSidebar':'Hide sidebar','board.showSidebar':'Show sidebar',
38
39
  'board.expandAllTitle':'Expand or collapse all phases','board.viewList':'List','board.viewKanban':'Kanban',
39
40
  'board.viewList.title':'Grouped by phase','board.viewKanban.title':'Columns by status',
41
+ 'board.kanbanColumns':'Columns','board.kanbanColumnsTitle':'Choose visible columns','board.kanbanColumnsHint':'At least one column must stay visible.',
42
+ 'board.kanbanPageSizeTitle':'Tasks per column','board.kanbanShowMore':'Show more (+{n})',
40
43
  'board.noTasksMatch':'No tasks match this filter.',
41
44
  'board.noPlans':'No plans yet. Ask your agent to build something — it will run Intake and write plans/*.md.',
42
45
  'board.noAgentRunning':'no agent running','board.noneYet':'none yet',
@@ -86,12 +89,15 @@ en: {
86
89
  'team.standardsLabel':'standards','team.usesLabel':'uses','team.standardLabel':'standard',
87
90
  'drawer.agent':'Agent','drawer.skill':'Skill','drawer.file':'File · {rel}',
88
91
  'drawer.loading':'Loading…','drawer.loadError':'Could not load this file.','files.title':'Files','files.sub':'Browse the project\'s files — view Markdown & HTML, edit any text file, create new ones.','files.newFile':'+ File','files.newFolder':'+ Folder','files.pickFile':'Select a file to view it.','files.empty':'No files yet.','files.edit':'Edit','files.preview':'Preview','files.save':'Save','files.saved':'✓ saved','files.saveError':'Could not save this file.','files.loadError':'Could not load this file.','files.binary':'This file can\'t be previewed here (not text).','files.discardConfirm':'Discard unsaved changes?','files.newFilePrompt':'New file name (e.g. todo.md):','files.newFolderPrompt':'New folder name:','files.projectRoot':'project root','files.creatingIn':'Creating in: {path}','files.refresh':'Refresh','files.discard':'Discard','files.create':'Create',
92
+ 'notes.sub':'A freeform scratchpad for this project — Markdown, autosaved as you type. Only you (and whoever else opens this dashboard) can see it.','notes.saving':'Saving…',
93
+ 'meeting.sub':'One dated note per day for this project — write it yourself, or have the active agent draft it from recent tasks and chat activity.','meeting.history':'History','meeting.today':'today','meeting.generate':'Generate','meeting.generateTitle':'Generate today\'s note from recent activity','meeting.overwriteWarn':'This will overwrite today\'s note.','meeting.generateAnyway':'Generate anyway',
89
94
  'chat.widgetTitle':'Run an agent','chat.widgetSub':'Quick access · full view in the Chat tab',
90
95
  'chat.tabSub':'Full conversation with the runner — the same run as the widget, more room to read it.',
91
96
  'chat.idle':'Type a request — the agent runs headless in this project with full memory (<code>CLAUDE.md → AGENTS.md</code>) and updates the board live.',
92
97
  'chat.inputPlaceholder':'e.g. Add a login feature with email + password',
93
98
  'chat.orchestrateTitle':'Walk the enabled workflow','chat.summarizeTitle':'Condense the recent activity into a summary','chat.clearTitle':'Clear the chat log',
94
99
  'chat.warn':'⚠ Launches a real agent (<code>config.json → runners</code>) that can modify files &amp; run commands.','chat.running':'Agent running…',
100
+ 'commands.menuEmpty':'No command — add one in Personalize',
95
101
  'info.title':'Info','info.sub':'Project overview — configuration, counts, specs and active workflow.',
96
102
  'info.project':'Project','info.projectType':'Project type','info.mode':'Mode','info.language':'Language',
97
103
  'info.activeAgent':'Active agent','info.runners':'Runners','info.noRunners':'No runners configured.',
@@ -103,7 +109,8 @@ en: {
103
109
  'field.design':'Dashboard design','field.mode':'Autonomy mode','field.lang':'Output language',
104
110
  'mode.autopilot.desc':'autopilot — run freely, ask only on policy gates',
105
111
  'mode.semi.desc':'semi — autopilot + policy approvals','mode.manual.desc':'manual — approve every step',
106
- 'settings.saved':'✓ saved','settings.group.execution':'Agent & automation','settings.group.appearance':'Appearance & language','field.plansFolder':'Plans folder','field.specsFolder':'Specs folder',
112
+ 'settings.saved':'✓ saved','settings.group.execution':'Agent & automation','settings.group.appearance':'Appearance & language','settings.group.navTabs':'Navigation tabs','settings.navTabs.locked':'Always on — this is where you manage this setting','settings.navTabs.moveUp':'Move up','settings.navTabs.moveDown':'Move down','field.plansFolder':'Plans folder','field.specsFolder':'Specs folder',
113
+ 'settings.commands.title':'Commands','settings.commands.note':'Slash commands you can type in the chat. Use {{input}} in the instruction to place your text where you want it.','settings.commands.add':'+ Add command','settings.commands.restore':'Restore defaults','settings.commands.ph.trigger':'Trigger (e.g. rapport_jour)','settings.commands.ph.desc':'Short description (shown in the menu)','settings.commands.ph.instruction':'Instruction sent to the agent (use {{input}} for your text)','settings.commands.err.invalidTrigger':'Invalid trigger: lowercase letters, digits, - and _ only (max 40).','settings.commands.err.duplicateTrigger':'A command with this trigger already exists.','settings.commands.err.emptyInstruction':'The instruction cannot be empty.',
107
114
  'field.frameworkVersion':'Framework version',
108
115
  'task.status':'Status','task.tests':'Tests','task.failing':'{n} failing','task.passing':'{n} passing',
109
116
  'task.failingPassing':'{f} failing, {p} passing','task.comments':'Comments','task.noComments':'No comments.',
@@ -132,16 +139,17 @@ en: {
132
139
  },
133
140
  fr: {
134
141
  'nav.board':'Tableau','nav.requests':'Demandes','nav.attention':'Attention','nav.backlog':'Backlog',
135
- 'nav.workflow':'Workflow','nav.team':'Agents et compétences','nav.files':'Fichiers','nav.chat':'Chat','nav.info':'Infos','nav.docs':'Documentation','nav.settings':'Personnalisation',
142
+ 'nav.workflow':'Workflow','nav.team':'Agents et compétences','nav.files':'Fichiers','nav.notes':'Notes','nav.meeting':'Réunion quotidienne','nav.chat':'Chat','nav.info':'Infos','nav.docs':'Documentation','nav.settings':'Personnalisation',
136
143
  'status.todo':'À faire','status.in_progress':'En cours','status.to_validate':'À valider',
137
144
  'status.to_analyze':'À analyser','status.done':'Terminé','status.blocked':'Bloqué',
138
145
  'filter.all':'Tous','filter.open':'Ouverts','filter.resolved':'Résolus',
139
146
  'action.run':'Lancer','action.send':'Envoyer','action.orchestrate':'Orchestrer','action.approve':'Approuver','action.summarize':'Résumer','action.clear':'Effacer',
140
- 'action.cancel':'Annuler','action.add':'Ajouter','action.edit':'Modifier','action.delete':'Supprimer',
147
+ 'action.cancel':'Annuler','action.add':'Ajouter','action.edit':'Modifier','action.delete':'Supprimer','action.save':'Enregistrer',
141
148
  'action.resolve':'Résoudre','action.reopen':'Rouvrir','action.validateToTask':'Valider → tâche',
142
149
  'action.addToAnalyze':'Ajouter + à analyser',
143
150
  'topbar.navToggle':'Afficher le menu','topbar.run.title':'Ouvrir le chat d’exécution',
144
151
  'topbar.theme.toggle':'Basculer thème clair / sombre','topbar.theme.toggle.title':'Basculer clair / sombre',
152
+ 'offline.banner':'{name} est hors ligne — vu pour la dernière fois {when}. Lecture seule jusqu’au retour de sa machine.','offline.readonly':'Ce projet est hors ligne (lecture seule).',
145
153
  'topbar.mode.title':'Mode d’autonomie — modifiable ici ou dans Personnalisation',
146
154
  'topbar.lang.title':'Langue de sortie — modifiable ici ou dans Personnalisation',
147
155
  'topbar.agent.title':'Agent actif — modifiable ici ou dans Personnalisation',
@@ -149,6 +157,8 @@ fr: {
149
157
  'board.filterPlaceholder':'Filtrer les tâches…','board.expandAll':'Tout déplier','board.collapseAll':'Tout replier','board.hideSidebar':'Masquer la barre latérale','board.showSidebar':'Afficher la barre latérale',
150
158
  'board.expandAllTitle':'Déplier ou replier toutes les phases','board.viewList':'Liste','board.viewKanban':'Kanban',
151
159
  'board.viewList.title':'Regroupé par phase','board.viewKanban.title':'Colonnes par statut',
160
+ 'board.kanbanColumns':'Colonnes','board.kanbanColumnsTitle':'Choisir les colonnes visibles','board.kanbanColumnsHint':'Au moins une colonne doit rester visible.',
161
+ 'board.kanbanPageSizeTitle':'Tâches par colonne','board.kanbanShowMore':'Afficher plus (+{n})',
152
162
  'board.noTasksMatch':'Aucune tâche ne correspond à ce filtre.',
153
163
  'board.noPlans':'Aucun plan pour l’instant. Demandez à votre agent de construire quelque chose — il lancera l’Intake et écrira plans/*.md.',
154
164
  'board.noAgentRunning':'aucun agent en cours','board.noneYet':'aucun pour l’instant',
@@ -198,12 +208,15 @@ fr: {
198
208
  'team.standardsLabel':'standards','team.usesLabel':'utilise','team.standardLabel':'standard',
199
209
  'drawer.agent':'Agent','drawer.skill':'Compétence','drawer.file':'Fichier · {rel}',
200
210
  'drawer.loading':'Chargement…','drawer.loadError':'Impossible de charger ce fichier.','files.title':'Fichiers','files.sub':'Parcourez les fichiers du projet — visualisez Markdown et HTML, modifiez tout fichier texte, créez-en de nouveaux.','files.newFile':'+ Fichier','files.newFolder':'+ Dossier','files.pickFile':'Sélectionnez un fichier pour l’afficher.','files.empty':'Aucun fichier pour l’instant.','files.edit':'Modifier','files.preview':'Aperçu','files.save':'Enregistrer','files.saved':'✓ enregistré','files.saveError':'Impossible d’enregistrer ce fichier.','files.loadError':'Impossible de charger ce fichier.','files.binary':'Ce fichier ne peut pas être prévisualisé ici (non textuel).','files.discardConfirm':'Abandonner les modifications non enregistrées ?','files.newFilePrompt':'Nom du nouveau fichier (ex. todo.md) :','files.newFolderPrompt':'Nom du nouveau dossier :','files.projectRoot':'racine du projet','files.creatingIn':'Création dans : {path}','files.refresh':'Actualiser','files.discard':'Annuler','files.create':'Créer',
211
+ 'notes.sub':'Un bloc-note libre pour ce projet — Markdown, enregistré automatiquement au fil de la frappe. Visible uniquement par vous (et quiconque ouvre ce tableau de bord).','notes.saving':'Enregistrement…',
212
+ 'meeting.sub':'Une note datée par jour pour ce projet — rédigez-la vous-même, ou laissez l’agent actif la rédiger à partir des tâches récentes et du chat.','meeting.history':'Historique','meeting.today':'aujourd’hui','meeting.generate':'Générer','meeting.generateTitle':'Générer la note du jour à partir de l’activité récente','meeting.overwriteWarn':'Cela va écraser la note d’aujourd’hui.','meeting.generateAnyway':'Générer quand même',
201
213
  'chat.widgetTitle':'Lancer un agent','chat.widgetSub':'Accès rapide · vue complète dans l’onglet Chat',
202
214
  'chat.tabSub':'Conversation complète avec l’exécuteur — la même exécution que le widget, avec plus de place pour la lire.',
203
215
  'chat.idle':'Tapez une demande — l’agent s’exécute sans supervision dans ce projet avec toute sa mémoire (<code>CLAUDE.md → AGENTS.md</code>) et met le tableau à jour en direct.',
204
216
  'chat.inputPlaceholder':'ex. Ajouter une fonctionnalité de connexion par email + mot de passe',
205
217
  'chat.orchestrateTitle':'Parcourir le workflow activé','chat.summarizeTitle':'Condenser l’activité récente en un résumé','chat.clearTitle':'Effacer le journal de discussion',
206
218
  'chat.warn':'⚠ Lance un agent réel (<code>config.json → runners</code>) qui peut modifier des fichiers et exécuter des commandes.','chat.running':'Agent en cours d’exécution…',
219
+ 'commands.menuEmpty':'Aucune commande — ajoutez-en une dans Personalize',
207
220
  'info.title':'Infos','info.sub':'Vue d’ensemble du projet — configuration, comptages, specs et workflow actif.',
208
221
  'info.project':'Projet','info.projectType':'Type de projet','info.mode':'Mode','info.language':'Langue',
209
222
  'info.activeAgent':'Agent actif','info.runners':'Runners','info.noRunners':'Aucun runner configuré.',
@@ -215,7 +228,8 @@ fr: {
215
228
  'field.design':'Design du tableau de bord','field.mode':'Mode d’autonomie','field.lang':'Langue de sortie',
216
229
  'mode.autopilot.desc':'autopilot — s’exécute librement, ne demande qu’aux points de policy',
217
230
  'mode.semi.desc':'semi — autopilot + approbations de policy','mode.manual.desc':'manual — approuve chaque étape',
218
- 'settings.saved':'✓ enregistré','settings.group.execution':'Agent et automatisation','settings.group.appearance':'Apparence et langue','field.plansFolder':'Dossier des plans','field.specsFolder':'Dossier des specs',
231
+ 'settings.saved':'✓ enregistré','settings.group.execution':'Agent et automatisation','settings.group.appearance':'Apparence et langue','settings.group.navTabs':'Onglets de navigation','settings.navTabs.locked':'Toujours activé — c’est ici que vous gérez ce réglage','settings.navTabs.moveUp':'Monter','settings.navTabs.moveDown':'Descendre','field.plansFolder':'Dossier des plans','field.specsFolder':'Dossier des specs',
232
+ 'settings.commands.title':'Commandes','settings.commands.note':'Des commandes slash à taper dans le chat. Utilisez {{input}} dans l\'instruction pour placer votre texte où vous voulez.','settings.commands.add':'+ Ajouter une commande','settings.commands.restore':'Restaurer les commandes par défaut','settings.commands.ph.trigger':'Déclencheur (ex. rapport_jour)','settings.commands.ph.desc':'Courte description (affichée dans le menu)','settings.commands.ph.instruction':'Instruction envoyée à l\'agent (utilisez {{input}} pour votre texte)','settings.commands.err.invalidTrigger':'Déclencheur invalide : minuscules, chiffres, - et _ uniquement (40 max).','settings.commands.err.duplicateTrigger':'Une commande avec ce déclencheur existe déjà.','settings.commands.err.emptyInstruction':'L\'instruction ne peut pas être vide.',
219
233
  'field.frameworkVersion':'Version du framework',
220
234
  'task.status':'Statut','task.tests':'Tests','task.failing':'{n} en échec','task.passing':'{n} réussi(s)',
221
235
  'task.failingPassing':'{f} en échec, {p} réussi(s)','task.comments':'Commentaires','task.noComments':'Aucun commentaire.',
@@ -244,16 +258,17 @@ fr: {
244
258
  },
245
259
  es: {
246
260
  'nav.board':'Tablero','nav.requests':'Solicitudes','nav.attention':'Atención','nav.backlog':'Backlog',
247
- 'nav.workflow':'Workflow','nav.team':'Agentes y habilidades','nav.files':'Archivos','nav.chat':'Chat','nav.info':'Info','nav.docs':'Documentación','nav.settings':'Personalizar',
261
+ 'nav.workflow':'Workflow','nav.team':'Agentes y habilidades','nav.files':'Archivos','nav.notes':'Notas','nav.meeting':'Reunión diaria','nav.chat':'Chat','nav.info':'Info','nav.docs':'Documentación','nav.settings':'Personalizar',
248
262
  'status.todo':'Por hacer','status.in_progress':'En curso','status.to_validate':'Por validar',
249
263
  'status.to_analyze':'Por analizar','status.done':'Hecho','status.blocked':'Bloqueado',
250
264
  'filter.all':'Todos','filter.open':'Abiertos','filter.resolved':'Resueltos',
251
265
  'action.run':'Ejecutar','action.send':'Enviar','action.orchestrate':'Orquestar','action.approve':'Aprobar','action.summarize':'Resumir','action.clear':'Borrar',
252
- 'action.cancel':'Cancelar','action.add':'Añadir','action.edit':'Editar','action.delete':'Eliminar',
266
+ 'action.cancel':'Cancelar','action.add':'Añadir','action.edit':'Editar','action.delete':'Eliminar','action.save':'Guardar',
253
267
  'action.resolve':'Resolver','action.reopen':'Reabrir','action.validateToTask':'Validar → tarea',
254
268
  'action.addToAnalyze':'Añadir + por analizar',
255
269
  'topbar.navToggle':'Mostrar menú','topbar.run.title':'Abrir el chat de ejecución',
256
270
  'topbar.theme.toggle':'Cambiar tema claro / oscuro','topbar.theme.toggle.title':'Cambiar claro / oscuro',
271
+ 'offline.banner':'{name} está sin conexión — visto por última vez {when}. Solo lectura hasta que su máquina vuelva.','offline.readonly':'Este proyecto está sin conexión (solo lectura).',
257
272
  'topbar.mode.title':'Modo de autonomía — se cambia aquí o en Personalizar',
258
273
  'topbar.lang.title':'Idioma de salida — se cambia aquí o en Personalizar',
259
274
  'topbar.agent.title':'Agente activo — se cambia aquí o en Personalizar',
@@ -261,6 +276,8 @@ es: {
261
276
  'board.filterPlaceholder':'Filtrar tareas…','board.expandAll':'Expandir todo','board.collapseAll':'Colapsar todo','board.hideSidebar':'Ocultar barra lateral','board.showSidebar':'Mostrar barra lateral',
262
277
  'board.expandAllTitle':'Expandir o colapsar todas las fases','board.viewList':'Lista','board.viewKanban':'Kanban',
263
278
  'board.viewList.title':'Agrupado por fase','board.viewKanban.title':'Columnas por estado',
279
+ 'board.kanbanColumns':'Columnas','board.kanbanColumnsTitle':'Elegir columnas visibles','board.kanbanColumnsHint':'Al menos una columna debe permanecer visible.',
280
+ 'board.kanbanPageSizeTitle':'Tareas por columna','board.kanbanShowMore':'Mostrar más (+{n})',
264
281
  'board.noTasksMatch':'Ninguna tarea coincide con este filtro.',
265
282
  'board.noPlans':'Aún no hay planes. Pide a tu agente que construya algo — ejecutará Intake y escribirá plans/*.md.',
266
283
  'board.noAgentRunning':'ningún agente en ejecución','board.noneYet':'ninguno todavía',
@@ -310,12 +327,15 @@ es: {
310
327
  'team.standardsLabel':'estándares','team.usesLabel':'usa','team.standardLabel':'estándar',
311
328
  'drawer.agent':'Agente','drawer.skill':'Habilidad','drawer.file':'Archivo · {rel}',
312
329
  'drawer.loading':'Cargando…','drawer.loadError':'No se pudo cargar este archivo.','files.title':'Archivos','files.sub':'Explora los archivos del proyecto — visualiza Markdown y HTML, edita cualquier archivo de texto, crea otros nuevos.','files.newFile':'+ Archivo','files.newFolder':'+ Carpeta','files.pickFile':'Selecciona un archivo para verlo.','files.empty':'Aún no hay archivos.','files.edit':'Editar','files.preview':'Vista previa','files.save':'Guardar','files.saved':'✓ guardado','files.saveError':'No se pudo guardar este archivo.','files.loadError':'No se pudo cargar este archivo.','files.binary':'Este archivo no se puede previsualizar aquí (no es texto).','files.discardConfirm':'¿Descartar los cambios sin guardar?','files.newFilePrompt':'Nombre del nuevo archivo (p. ej. todo.md):','files.newFolderPrompt':'Nombre de la nueva carpeta:','files.projectRoot':'raíz del proyecto','files.creatingIn':'Creando en: {path}','files.refresh':'Actualizar','files.discard':'Descartar','files.create':'Crear',
330
+ 'notes.sub':'Un bloc de notas libre para este proyecto — Markdown, guardado automáticamente mientras escribes. Solo tú (y quien más abra este panel) puedes verlo.','notes.saving':'Guardando…',
331
+ 'meeting.sub':'Una nota fechada por día para este proyecto — escríbela tú mismo, o deja que el agente activo la redacte a partir de las tareas y el chat recientes.','meeting.history':'Historial','meeting.today':'hoy','meeting.generate':'Generar','meeting.generateTitle':'Generar la nota de hoy a partir de la actividad reciente','meeting.overwriteWarn':'Esto sobrescribirá la nota de hoy.','meeting.generateAnyway':'Generar de todos modos',
313
332
  'chat.widgetTitle':'Ejecutar un agente','chat.widgetSub':'Acceso rápido · vista completa en la pestaña Chat',
314
333
  'chat.tabSub':'Conversación completa con el ejecutor — la misma ejecución que el widget, con más espacio para leerla.',
315
334
  'chat.idle':'Escribe una solicitud — el agente se ejecuta sin supervisión en este proyecto con toda su memoria (<code>CLAUDE.md → AGENTS.md</code>) y actualiza el tablero en vivo.',
316
335
  'chat.inputPlaceholder':'p. ej. Añadir un inicio de sesión con email + contraseña',
317
336
  'chat.orchestrateTitle':'Recorrer el workflow activado','chat.summarizeTitle':'Condensar la actividad reciente en un resumen','chat.clearTitle':'Borrar el registro del chat',
318
337
  'chat.warn':'⚠ Lanza un agente real (<code>config.json → runners</code>) que puede modificar archivos y ejecutar comandos.','chat.running':'Agente en ejecución…',
338
+ 'commands.menuEmpty':'Ningún comando — añade uno en Personalize',
319
339
  'info.title':'Info','info.sub':'Visión general del proyecto — configuración, recuentos, specs y workflow activo.',
320
340
  'info.project':'Proyecto','info.projectType':'Tipo de proyecto','info.mode':'Modo','info.language':'Idioma',
321
341
  'info.activeAgent':'Agente activo','info.runners':'Runners','info.noRunners':'No hay runners configurados.',
@@ -327,7 +347,8 @@ es: {
327
347
  'field.design':'Diseño del panel','field.mode':'Modo de autonomía','field.lang':'Idioma de salida',
328
348
  'mode.autopilot.desc':'autopilot — actúa con libertad, solo pregunta en los puntos de policy',
329
349
  'mode.semi.desc':'semi — autopilot + aprobaciones de policy','mode.manual.desc':'manual — aprueba cada paso',
330
- 'settings.saved':'✓ guardado','settings.group.execution':'Agente y automatización','settings.group.appearance':'Apariencia e idioma','field.plansFolder':'Carpeta de planes','field.specsFolder':'Carpeta de specs',
350
+ 'settings.saved':'✓ guardado','settings.group.execution':'Agente y automatización','settings.group.appearance':'Apariencia e idioma','settings.group.navTabs':'Pestañas de navegación','settings.navTabs.locked':'Siempre activo — aquí es donde gestionas este ajuste','settings.navTabs.moveUp':'Subir','settings.navTabs.moveDown':'Bajar','field.plansFolder':'Carpeta de planes','field.specsFolder':'Carpeta de specs',
351
+ 'settings.commands.title':'Comandos','settings.commands.note':'Comandos slash que puedes escribir en el chat. Usa {{input}} en la instrucción para colocar tu texto donde quieras.','settings.commands.add':'+ Añadir comando','settings.commands.restore':'Restaurar valores predeterminados','settings.commands.ph.trigger':'Activador (p. ej. rapport_jour)','settings.commands.ph.desc':'Descripción breve (se muestra en el menú)','settings.commands.ph.instruction':'Instrucción enviada al agente (usa {{input}} para tu texto)','settings.commands.err.invalidTrigger':'Activador inválido: solo minúsculas, dígitos, - y _ (máx. 40).','settings.commands.err.duplicateTrigger':'Ya existe un comando con este activador.','settings.commands.err.emptyInstruction':'La instrucción no puede estar vacía.',
331
352
  'field.frameworkVersion':'Versión del framework',
332
353
  'task.status':'Estado','task.tests':'Pruebas','task.failing':'{n} fallando','task.passing':'{n} superadas',
333
354
  'task.failingPassing':'{f} fallando, {p} superadas','task.comments':'Comentarios','task.noComments':'Sin comentarios.',
@@ -356,16 +377,17 @@ es: {
356
377
  },
357
378
  de: {
358
379
  'nav.board':'Board','nav.requests':'Anfragen','nav.attention':'Hinweise','nav.backlog':'Backlog',
359
- 'nav.workflow':'Workflow','nav.team':'Agenten & Skills','nav.files':'Dateien','nav.chat':'Chat','nav.info':'Info','nav.docs':'Dokumentation','nav.settings':'Personalisieren',
380
+ 'nav.workflow':'Workflow','nav.team':'Agenten & Skills','nav.files':'Dateien','nav.notes':'Notizen','nav.meeting':'Tagesbesprechung','nav.chat':'Chat','nav.info':'Info','nav.docs':'Dokumentation','nav.settings':'Personalisieren',
360
381
  'status.todo':'Offen','status.in_progress':'In Arbeit','status.to_validate':'Zu prüfen',
361
382
  'status.to_analyze':'Zu analysieren','status.done':'Erledigt','status.blocked':'Blockiert',
362
383
  'filter.all':'Alle','filter.open':'Offen','filter.resolved':'Erledigt',
363
384
  'action.run':'Start','action.send':'Senden','action.orchestrate':'Orchestrieren','action.approve':'Freigeben','action.summarize':'Zusammenfassen','action.clear':'Löschen',
364
- 'action.cancel':'Abbrechen','action.add':'Hinzufügen','action.edit':'Bearbeiten','action.delete':'Löschen',
385
+ 'action.cancel':'Abbrechen','action.add':'Hinzufügen','action.edit':'Bearbeiten','action.delete':'Löschen','action.save':'Speichern',
365
386
  'action.resolve':'Erledigen','action.reopen':'Wieder öffnen','action.validateToTask':'Bestätigen → Aufgabe',
366
387
  'action.addToAnalyze':'Hinzufügen + zu analysieren',
367
388
  'topbar.navToggle':'Menü anzeigen','topbar.run.title':'Ausführungs-Chat öffnen',
368
389
  'topbar.theme.toggle':'Hell-/Dunkelmodus umschalten','topbar.theme.toggle.title':'Hell / Dunkel umschalten',
390
+ 'offline.banner':'{name} ist offline — zuletzt gesehen {when}. Nur Lesen, bis der Rechner wieder verbunden ist.','offline.readonly':'Dieses Projekt ist offline (nur Lesen).',
369
391
  'topbar.mode.title':'Autonomiemodus — hier oder in Personalisieren änderbar',
370
392
  'topbar.lang.title':'Ausgabesprache — hier oder in Personalisieren änderbar',
371
393
  'topbar.agent.title':'Aktiver Agent — hier oder in Personalisieren änderbar',
@@ -373,6 +395,8 @@ de: {
373
395
  'board.filterPlaceholder':'Aufgaben filtern…','board.expandAll':'Alle ausklappen','board.collapseAll':'Alle einklappen','board.hideSidebar':'Seitenleiste ausblenden','board.showSidebar':'Seitenleiste einblenden',
374
396
  'board.expandAllTitle':'Alle Phasen ein- oder ausklappen','board.viewList':'Liste','board.viewKanban':'Kanban',
375
397
  'board.viewList.title':'Nach Phase gruppiert','board.viewKanban.title':'Spalten nach Status',
398
+ 'board.kanbanColumns':'Spalten','board.kanbanColumnsTitle':'Sichtbare Spalten wählen','board.kanbanColumnsHint':'Mindestens eine Spalte muss sichtbar bleiben.',
399
+ 'board.kanbanPageSizeTitle':'Aufgaben pro Spalte','board.kanbanShowMore':'Mehr anzeigen (+{n})',
376
400
  'board.noTasksMatch':'Keine Aufgabe entspricht diesem Filter.',
377
401
  'board.noPlans':'Noch keine Pläne. Bitten Sie Ihren Agenten, etwas zu bauen — er startet die Aufnahme und schreibt plans/*.md.',
378
402
  'board.noAgentRunning':'kein Agent aktiv','board.noneYet':'noch keine',
@@ -422,12 +446,15 @@ de: {
422
446
  'team.standardsLabel':'Standards','team.usesLabel':'nutzt','team.standardLabel':'Standard',
423
447
  'drawer.agent':'Agent','drawer.skill':'Skill','drawer.file':'Datei · {rel}',
424
448
  'drawer.loading':'Lädt…','drawer.loadError':'Diese Datei konnte nicht geladen werden.','files.title':'Dateien','files.sub':'Durchsuche die Projektdateien — Markdown & HTML ansehen, jede Textdatei bearbeiten, neue erstellen.','files.newFile':'+ Datei','files.newFolder':'+ Ordner','files.pickFile':'Wähle eine Datei aus, um sie anzuzeigen.','files.empty':'Noch keine Dateien.','files.edit':'Bearbeiten','files.preview':'Vorschau','files.save':'Speichern','files.saved':'✓ gespeichert','files.saveError':'Diese Datei konnte nicht gespeichert werden.','files.loadError':'Diese Datei konnte nicht geladen werden.','files.binary':'Diese Datei kann hier nicht angezeigt werden (kein Text).','files.discardConfirm':'Nicht gespeicherte Änderungen verwerfen?','files.newFilePrompt':'Name der neuen Datei (z. B. todo.md):','files.newFolderPrompt':'Name des neuen Ordners:','files.projectRoot':'Projektstamm','files.creatingIn':'Erstellen in: {path}','files.refresh':'Aktualisieren','files.discard':'Verwerfen','files.create':'Erstellen',
449
+ 'notes.sub':'Ein freier Notizblock für dieses Projekt — Markdown, automatisch gespeichert während der Eingabe. Nur du (und wer sonst dieses Dashboard öffnet) siehst ihn.','notes.saving':'Speichert…',
450
+ 'meeting.sub':'Eine datierte Notiz pro Tag für dieses Projekt — schreibe sie selbst, oder lass sie vom aktiven Agenten aus den letzten Aufgaben und dem Chat entwerfen.','meeting.history':'Verlauf','meeting.today':'heute','meeting.generate':'Generieren','meeting.generateTitle':'Die heutige Notiz aus der letzten Aktivität generieren','meeting.overwriteWarn':'Dies überschreibt die heutige Notiz.','meeting.generateAnyway':'Trotzdem generieren',
425
451
  'chat.widgetTitle':'Agenten ausführen','chat.widgetSub':'Schnellzugriff · vollständige Ansicht im Chat-Tab',
426
452
  'chat.tabSub':'Vollständiges Gespräch mit dem Runner — derselbe Lauf wie im Widget, mit mehr Platz zum Lesen.',
427
453
  'chat.idle':'Geben Sie eine Anfrage ein — der Agent läuft eigenständig in diesem Projekt mit vollem Gedächtnis (<code>CLAUDE.md → AGENTS.md</code>) und aktualisiert das Board live.',
428
454
  'chat.inputPlaceholder':'z. B. Login mit E-Mail + Passwort hinzufügen',
429
455
  'chat.orchestrateTitle':'Den aktivierten Workflow durchlaufen','chat.summarizeTitle':'Die letzten Aktivitäten zu einer Zusammenfassung verdichten','chat.clearTitle':'Chat-Verlauf löschen',
430
456
  'chat.warn':'⚠ Startet einen echten Agenten (<code>config.json → runners</code>), der Dateien ändern und Befehle ausführen kann.','chat.running':'Agent läuft…',
457
+ 'commands.menuEmpty':'Kein Befehl — füge einen in Personalize hinzu',
431
458
  'info.title':'Info','info.sub':'Projektübersicht — Konfiguration, Zahlen, Specs und aktiver Workflow.',
432
459
  'info.project':'Projekt','info.projectType':'Projekttyp','info.mode':'Modus','info.language':'Sprache',
433
460
  'info.activeAgent':'Aktiver Agent','info.runners':'Runner','info.noRunners':'Keine Runner konfiguriert.',
@@ -439,7 +466,8 @@ de: {
439
466
  'field.design':'Dashboard-Design','field.mode':'Autonomiemodus','field.lang':'Ausgabesprache',
440
467
  'mode.autopilot.desc':'autopilot — läuft frei, fragt nur an Policy-Punkten',
441
468
  'mode.semi.desc':'semi — autopilot + Policy-Freigaben','mode.manual.desc':'manual — jeden Schritt bestätigen',
442
- 'settings.saved':'✓ gespeichert','settings.group.execution':'Agent & Automatisierung','settings.group.appearance':'Erscheinungsbild & Sprache','field.plansFolder':'Plan-Ordner','field.specsFolder':'Spec-Ordner',
469
+ 'settings.saved':'✓ gespeichert','settings.group.execution':'Agent & Automatisierung','settings.group.appearance':'Erscheinungsbild & Sprache','settings.group.navTabs':'Navigations-Tabs','settings.navTabs.locked':'Immer aktiv — hier verwaltest du diese Einstellung','settings.navTabs.moveUp':'Nach oben','settings.navTabs.moveDown':'Nach unten','field.plansFolder':'Plan-Ordner','field.specsFolder':'Spec-Ordner',
470
+ 'settings.commands.title':'Befehle','settings.commands.note':'Slash-Befehle, die du im Chat eingeben kannst. Verwende {{input}} in der Anweisung, um deinen Text an der gewünschten Stelle einzufügen.','settings.commands.add':'+ Befehl hinzufügen','settings.commands.restore':'Standardwerte wiederherstellen','settings.commands.ph.trigger':'Auslöser (z. B. rapport_jour)','settings.commands.ph.desc':'Kurze Beschreibung (im Menü angezeigt)','settings.commands.ph.instruction':'An den Agenten gesendete Anweisung (verwende {{input}} für deinen Text)','settings.commands.err.invalidTrigger':'Ungültiger Auslöser: nur Kleinbuchstaben, Ziffern, - und _ (max. 40).','settings.commands.err.duplicateTrigger':'Ein Befehl mit diesem Auslöser existiert bereits.','settings.commands.err.emptyInstruction':'Die Anweisung darf nicht leer sein.',
443
471
  'field.frameworkVersion':'Framework-Version',
444
472
  'task.status':'Status','task.tests':'Tests','task.failing':'{n} fehlgeschlagen','task.passing':'{n} bestanden',
445
473
  'task.failingPassing':'{f} fehlgeschlagen, {p} bestanden','task.comments':'Kommentare','task.noComments':'Keine Kommentare.',
@@ -468,16 +496,17 @@ de: {
468
496
  },
469
497
  pt: {
470
498
  'nav.board':'Painel','nav.requests':'Pedidos','nav.attention':'Atenção','nav.backlog':'Backlog',
471
- 'nav.workflow':'Workflow','nav.team':'Agentes e habilidades','nav.files':'Ficheiros','nav.chat':'Chat','nav.info':'Info','nav.docs':'Documentação','nav.settings':'Personalizar',
499
+ 'nav.workflow':'Workflow','nav.team':'Agentes e habilidades','nav.files':'Ficheiros','nav.notes':'Notas','nav.meeting':'Reunião diária','nav.chat':'Chat','nav.info':'Info','nav.docs':'Documentação','nav.settings':'Personalizar',
472
500
  'status.todo':'A fazer','status.in_progress':'Em curso','status.to_validate':'Por validar',
473
501
  'status.to_analyze':'Por analisar','status.done':'Concluído','status.blocked':'Bloqueado',
474
502
  'filter.all':'Todos','filter.open':'Abertos','filter.resolved':'Resolvidos',
475
503
  'action.run':'Executar','action.send':'Enviar','action.orchestrate':'Orquestrar','action.approve':'Aprovar','action.summarize':'Resumir','action.clear':'Limpar',
476
- 'action.cancel':'Cancelar','action.add':'Adicionar','action.edit':'Editar','action.delete':'Eliminar',
504
+ 'action.cancel':'Cancelar','action.add':'Adicionar','action.edit':'Editar','action.delete':'Eliminar','action.save':'Guardar',
477
505
  'action.resolve':'Resolver','action.reopen':'Reabrir','action.validateToTask':'Validar → tarefa',
478
506
  'action.addToAnalyze':'Adicionar + por analisar',
479
507
  'topbar.navToggle':'Mostrar menu','topbar.run.title':'Abrir o chat de execução',
480
508
  'topbar.theme.toggle':'Alternar tema claro / escuro','topbar.theme.toggle.title':'Alternar claro / escuro',
509
+ 'offline.banner':'{name} está offline — visto pela última vez {when}. Somente leitura até a máquina voltar.','offline.readonly':'Este projeto está offline (somente leitura).',
481
510
  'topbar.mode.title':'Modo de autonomia — altere aqui ou em Personalizar',
482
511
  'topbar.lang.title':'Idioma de saída — altere aqui ou em Personalizar',
483
512
  'topbar.agent.title':'Agente ativo — altere aqui ou em Personalizar',
@@ -485,6 +514,8 @@ pt: {
485
514
  'board.filterPlaceholder':'Filtrar tarefas…','board.expandAll':'Expandir tudo','board.collapseAll':'Recolher tudo','board.hideSidebar':'Ocultar barra lateral','board.showSidebar':'Mostrar barra lateral',
486
515
  'board.expandAllTitle':'Expandir ou recolher todas as fases','board.viewList':'Lista','board.viewKanban':'Kanban',
487
516
  'board.viewList.title':'Agrupado por fase','board.viewKanban.title':'Colunas por estado',
517
+ 'board.kanbanColumns':'Colunas','board.kanbanColumnsTitle':'Escolher colunas visíveis','board.kanbanColumnsHint':'Pelo menos uma coluna deve permanecer visível.',
518
+ 'board.kanbanPageSizeTitle':'Tarefas por coluna','board.kanbanShowMore':'Mostrar mais (+{n})',
488
519
  'board.noTasksMatch':'Nenhuma tarefa corresponde a este filtro.',
489
520
  'board.noPlans':'Ainda não há planos. Peça ao seu agente para construir algo — ele vai correr o Intake e escrever plans/*.md.',
490
521
  'board.noAgentRunning':'nenhum agente em execução','board.noneYet':'nenhum ainda',
@@ -534,12 +565,15 @@ pt: {
534
565
  'team.standardsLabel':'padrões','team.usesLabel':'usa','team.standardLabel':'padrão',
535
566
  'drawer.agent':'Agente','drawer.skill':'Habilidade','drawer.file':'Ficheiro · {rel}',
536
567
  'drawer.loading':'A carregar…','drawer.loadError':'Não foi possível carregar este ficheiro.','files.title':'Ficheiros','files.sub':'Percorra os ficheiros do projeto — veja Markdown e HTML, edite qualquer ficheiro de texto, crie novos.','files.newFile':'+ Ficheiro','files.newFolder':'+ Pasta','files.pickFile':'Selecione um ficheiro para o ver.','files.empty':'Ainda não há ficheiros.','files.edit':'Editar','files.preview':'Pré-visualizar','files.save':'Guardar','files.saved':'✓ guardado','files.saveError':'Não foi possível guardar este ficheiro.','files.loadError':'Não foi possível carregar este ficheiro.','files.binary':'Este ficheiro não pode ser pré-visualizado aqui (não é texto).','files.discardConfirm':'Descartar alterações não guardadas?','files.newFilePrompt':'Nome do novo ficheiro (ex. todo.md):','files.newFolderPrompt':'Nome da nova pasta:','files.projectRoot':'raiz do projeto','files.creatingIn':'A criar em: {path}','files.refresh':'Atualizar','files.discard':'Descartar','files.create':'Criar',
568
+ 'notes.sub':'Um bloco de notas livre para este projeto — Markdown, guardado automaticamente enquanto escreve. Só você (e quem mais abrir este painel) o vê.','notes.saving':'A guardar…',
569
+ 'meeting.sub':'Uma nota datada por dia para este projeto — escreva-a você mesmo, ou deixe o agente ativo redigi-la a partir das tarefas e do chat recentes.','meeting.history':'Histórico','meeting.today':'hoje','meeting.generate':'Gerar','meeting.generateTitle':'Gerar a nota de hoje a partir da atividade recente','meeting.overwriteWarn':'Isto vai substituir a nota de hoje.','meeting.generateAnyway':'Gerar mesmo assim',
537
570
  'chat.widgetTitle':'Executar um agente','chat.widgetSub':'Acesso rápido · vista completa no separador Chat',
538
571
  'chat.tabSub':'Conversa completa com o executor — a mesma execução do widget, com mais espaço para ler.',
539
572
  'chat.idle':'Escreva um pedido — o agente corre sem supervisão neste projeto com toda a sua memória (<code>CLAUDE.md → AGENTS.md</code>) e atualiza o painel em direto.',
540
573
  'chat.inputPlaceholder':'ex. Adicionar login com email + palavra-passe',
541
574
  'chat.orchestrateTitle':'Percorrer o workflow ativado','chat.summarizeTitle':'Condensar a atividade recente num resumo','chat.clearTitle':'Limpar o registo do chat',
542
575
  'chat.warn':'⚠ Inicia um agente real (<code>config.json → runners</code>) que pode alterar ficheiros e executar comandos.','chat.running':'Agente em execução…',
576
+ 'commands.menuEmpty':'Nenhum comando — adicione um em Personalize',
543
577
  'info.title':'Info','info.sub':'Visão geral do projeto — configuração, contagens, specs e workflow ativo.',
544
578
  'info.project':'Projeto','info.projectType':'Tipo de projeto','info.mode':'Modo','info.language':'Idioma',
545
579
  'info.activeAgent':'Agente ativo','info.runners':'Runners','info.noRunners':'Nenhum runner configurado.',
@@ -551,7 +585,8 @@ pt: {
551
585
  'field.design':'Design do painel','field.mode':'Modo de autonomia','field.lang':'Idioma de saída',
552
586
  'mode.autopilot.desc':'autopilot — corre livremente, só pergunta nos pontos de policy',
553
587
  'mode.semi.desc':'semi — autopilot + aprovações de policy','mode.manual.desc':'manual — aprova cada etapa',
554
- 'settings.saved':'✓ guardado','settings.group.execution':'Agente e automação','settings.group.appearance':'Aparência e idioma','field.plansFolder':'Pasta de planos','field.specsFolder':'Pasta de specs',
588
+ 'settings.saved':'✓ guardado','settings.group.execution':'Agente e automação','settings.group.appearance':'Aparência e idioma','settings.group.navTabs':'Abas de navegação','settings.navTabs.locked':'Sempre ativo — é aqui que você gerencia esta configuração','settings.navTabs.moveUp':'Mover para cima','settings.navTabs.moveDown':'Mover para baixo','field.plansFolder':'Pasta de planos','field.specsFolder':'Pasta de specs',
589
+ 'settings.commands.title':'Comandos','settings.commands.note':'Comandos slash que você pode digitar no chat. Use {{input}} na instrução para posicionar seu texto onde quiser.','settings.commands.add':'+ Adicionar comando','settings.commands.restore':'Restaurar padrões','settings.commands.ph.trigger':'Gatilho (ex.: rapport_jour)','settings.commands.ph.desc':'Descrição curta (exibida no menu)','settings.commands.ph.instruction':'Instrução enviada ao agente (use {{input}} para o seu texto)','settings.commands.err.invalidTrigger':'Gatilho inválido: apenas minúsculas, dígitos, - e _ (máx. 40).','settings.commands.err.duplicateTrigger':'Já existe um comando com este gatilho.','settings.commands.err.emptyInstruction':'A instrução não pode ficar vazia.',
555
590
  'field.frameworkVersion':'Versão do framework',
556
591
  'task.status':'Estado','task.tests':'Testes','task.failing':'{n} a falhar','task.passing':'{n} bem-sucedido(s)',
557
592
  'task.failingPassing':'{f} a falhar, {p} bem-sucedido(s)','task.comments':'Comentários','task.noComments':'Sem comentários.',
@@ -580,16 +615,17 @@ pt: {
580
615
  },
581
616
  it: {
582
617
  'nav.board':'Bacheca','nav.requests':'Richieste','nav.attention':'Attenzione','nav.backlog':'Backlog',
583
- 'nav.workflow':'Workflow','nav.team':'Agenti e competenze','nav.files':'File','nav.chat':'Chat','nav.info':'Info','nav.docs':'Documentazione','nav.settings':'Personalizza',
618
+ 'nav.workflow':'Workflow','nav.team':'Agenti e competenze','nav.files':'File','nav.notes':'Note','nav.meeting':'Riunione quotidiana','nav.chat':'Chat','nav.info':'Info','nav.docs':'Documentazione','nav.settings':'Personalizza',
584
619
  'status.todo':'Da fare','status.in_progress':'In corso','status.to_validate':'Da convalidare',
585
620
  'status.to_analyze':'Da analizzare','status.done':'Fatto','status.blocked':'Bloccato',
586
621
  'filter.all':'Tutti','filter.open':'Aperti','filter.resolved':'Risolti',
587
622
  'action.run':'Avvia','action.send':'Invia','action.orchestrate':'Orchestra','action.approve':'Approva','action.summarize':'Riassumi','action.clear':'Cancella',
588
- 'action.cancel':'Annulla','action.add':'Aggiungi','action.edit':'Modifica','action.delete':'Elimina',
623
+ 'action.cancel':'Annulla','action.add':'Aggiungi','action.edit':'Modifica','action.delete':'Elimina','action.save':'Salva',
589
624
  'action.resolve':'Risolvi','action.reopen':'Riapri','action.validateToTask':'Convalida → attività',
590
625
  'action.addToAnalyze':'Aggiungi + da analizzare',
591
626
  'topbar.navToggle':'Mostra menu','topbar.run.title':'Apri la chat di esecuzione',
592
627
  'topbar.theme.toggle':'Passa a tema chiaro / scuro','topbar.theme.toggle.title':'Chiaro / scuro',
628
+ 'offline.banner':'{name} è offline — visto l’ultima volta {when}. Sola lettura finché la macchina non torna.','offline.readonly':'Questo progetto è offline (sola lettura).',
593
629
  'topbar.mode.title':'Modalità di autonomia — modificabile qui o in Personalizza',
594
630
  'topbar.lang.title':'Lingua di output — modificabile qui o in Personalizza',
595
631
  'topbar.agent.title':'Agente attivo — modificabile qui o in Personalizza',
@@ -597,6 +633,8 @@ it: {
597
633
  'board.filterPlaceholder':'Filtra attività…','board.expandAll':'Espandi tutto','board.collapseAll':'Comprimi tutto','board.hideSidebar':'Nascondi barra laterale','board.showSidebar':'Mostra barra laterale',
598
634
  'board.expandAllTitle':'Espandi o comprimi tutte le fasi','board.viewList':'Elenco','board.viewKanban':'Kanban',
599
635
  'board.viewList.title':'Raggruppato per fase','board.viewKanban.title':'Colonne per stato',
636
+ 'board.kanbanColumns':'Colonne','board.kanbanColumnsTitle':'Scegli le colonne visibili','board.kanbanColumnsHint':'Almeno una colonna deve rimanere visibile.',
637
+ 'board.kanbanPageSizeTitle':'Attività per colonna','board.kanbanShowMore':'Mostra altro (+{n})',
600
638
  'board.noTasksMatch':'Nessuna attività corrisponde a questo filtro.',
601
639
  'board.noPlans':'Ancora nessun piano. Chiedi al tuo agente di costruire qualcosa — avvierà l’Intake e scriverà plans/*.md.',
602
640
  'board.noAgentRunning':'nessun agente in esecuzione','board.noneYet':'ancora nessuno',
@@ -646,12 +684,15 @@ it: {
646
684
  'team.standardsLabel':'standard','team.usesLabel':'usa','team.standardLabel':'standard',
647
685
  'drawer.agent':'Agente','drawer.skill':'Skill','drawer.file':'File · {rel}',
648
686
  'drawer.loading':'Caricamento…','drawer.loadError':'Impossibile caricare questo file.','files.title':'File','files.sub':'Sfoglia i file del progetto — visualizza Markdown e HTML, modifica qualsiasi file di testo, creane di nuovi.','files.newFile':'+ File','files.newFolder':'+ Cartella','files.pickFile':'Seleziona un file per visualizzarlo.','files.empty':'Nessun file ancora.','files.edit':'Modifica','files.preview':'Anteprima','files.save':'Salva','files.saved':'✓ salvato','files.saveError':'Impossibile salvare questo file.','files.loadError':'Impossibile caricare questo file.','files.binary':'Questo file non può essere visualizzato qui (non è testo).','files.discardConfirm':'Scartare le modifiche non salvate?','files.newFilePrompt':'Nome del nuovo file (es. todo.md):','files.newFolderPrompt':'Nome della nuova cartella:','files.projectRoot':'radice del progetto','files.creatingIn':'Creazione in: {path}','files.refresh':'Aggiorna','files.discard':'Scarta','files.create':'Crea',
687
+ 'notes.sub':'Un blocco note libero per questo progetto — Markdown, salvato automaticamente mentre scrivi. Solo tu (e chiunque altro apra questa dashboard) puoi vederlo.','notes.saving':'Salvataggio…',
688
+ 'meeting.sub':'Una nota datata al giorno per questo progetto — scrivila tu stesso, oppure lascia che l’agente attivo la scriva a partire dalle attività e dalla chat recenti.','meeting.history':'Cronologia','meeting.today':'oggi','meeting.generate':'Genera','meeting.generateTitle':'Genera la nota di oggi dall’attività recente','meeting.overwriteWarn':'Questo sovrascriverà la nota di oggi.','meeting.generateAnyway':'Genera comunque',
649
689
  'chat.widgetTitle':'Avvia un agente','chat.widgetSub':'Accesso rapido · vista completa nella scheda Chat',
650
690
  'chat.tabSub':'Conversazione completa con l’esecutore — la stessa esecuzione del widget, con più spazio per leggerla.',
651
691
  'chat.idle':'Digita una richiesta — l’agente viene eseguito senza supervisione in questo progetto con tutta la sua memoria (<code>CLAUDE.md → AGENTS.md</code>) e aggiorna la bacheca in diretta.',
652
692
  'chat.inputPlaceholder':'es. Aggiungi un login con email + password',
653
693
  'chat.orchestrateTitle':'Percorri il workflow attivato','chat.summarizeTitle':'Condensa l’attività recente in un riassunto','chat.clearTitle':'Cancella il registro della chat',
654
694
  'chat.warn':'⚠ Avvia un agente reale (<code>config.json → runners</code>) che può modificare file ed eseguire comandi.','chat.running':'Agente in esecuzione…',
695
+ 'commands.menuEmpty':'Nessun comando — aggiungine uno in Personalize',
655
696
  'info.title':'Info','info.sub':'Panoramica del progetto — configurazione, conteggi, specs e workflow attivo.',
656
697
  'info.project':'Progetto','info.projectType':'Tipo di progetto','info.mode':'Modalità','info.language':'Lingua',
657
698
  'info.activeAgent':'Agente attivo','info.runners':'Runner','info.noRunners':'Nessun runner configurato.',
@@ -663,7 +704,8 @@ it: {
663
704
  'field.design':'Design della dashboard','field.mode':'Modalità di autonomia','field.lang':'Lingua di output',
664
705
  'mode.autopilot.desc':'autopilot — agisce liberamente, chiede solo ai punti di policy',
665
706
  'mode.semi.desc':'semi — autopilot + approvazioni di policy','mode.manual.desc':'manual — approva ogni fase',
666
- 'settings.saved':'✓ salvato','settings.group.execution':'Agente e automazione','settings.group.appearance':'Aspetto e lingua','field.plansFolder':'Cartella dei piani','field.specsFolder':'Cartella delle specs',
707
+ 'settings.saved':'✓ salvato','settings.group.execution':'Agente e automazione','settings.group.appearance':'Aspetto e lingua','settings.group.navTabs':'Schede di navigazione','settings.navTabs.locked':'Sempre attivo — è qui che gestisci questa impostazione','settings.navTabs.moveUp':'Sposta su','settings.navTabs.moveDown':'Sposta giù','field.plansFolder':'Cartella dei piani','field.specsFolder':'Cartella delle specs',
708
+ 'settings.commands.title':'Comandi','settings.commands.note':'Comandi slash che puoi digitare in chat. Usa {{input}} nell\'istruzione per posizionare il tuo testo dove vuoi.','settings.commands.add':'+ Aggiungi comando','settings.commands.restore':'Ripristina predefiniti','settings.commands.ph.trigger':'Trigger (es. rapport_jour)','settings.commands.ph.desc':'Breve descrizione (mostrata nel menu)','settings.commands.ph.instruction':'Istruzione inviata all\'agente (usa {{input}} per il tuo testo)','settings.commands.err.invalidTrigger':'Trigger non valido: solo minuscole, cifre, - e _ (max 40).','settings.commands.err.duplicateTrigger':'Esiste già un comando con questo trigger.','settings.commands.err.emptyInstruction':'L\'istruzione non può essere vuota.',
667
709
  'field.frameworkVersion':'Versione del framework',
668
710
  'task.status':'Stato','task.tests':'Test','task.failing':'{n} falliti','task.passing':'{n} superati',
669
711
  'task.failingPassing':'{f} falliti, {p} superati','task.comments':'Commenti','task.noComments':'Nessun commento.',
@@ -31,6 +31,8 @@
31
31
  files: wrap('<path d="M2.6 5.4a1 1 0 0 1 1-1h3.1l1.2 1.6h6.5a1 1 0 0 1 1 1v6.6a1 1 0 0 1-1 1H3.6a1 1 0 0 1-1-1z"/>'),
32
32
  // crescent moon — theme toggle
33
33
  theme: wrap('<path d="M14.6 10.8A5.6 5.6 0 0 1 7.2 3.4 5.7 5.7 0 1 0 14.6 10.8z"/>'),
34
+ // calendar page — Daily meeting (a dated entry, not a generic list like backlog)
35
+ meeting: wrap('<rect x="2.6" y="4" width="12.8" height="11" rx="1.4"/><line x1="2.6" y1="7.4" x2="15.4" y2="7.4"/><line x1="5.6" y1="2.6" x2="5.6" y2="5.2"/><line x1="12.4" y1="2.6" x2="12.4" y2="5.2"/><line x1="5.4" y1="10.2" x2="7.6" y2="10.2"/>'),
34
36
  };
35
37
 
36
38
  // Representative icons for workflow pipeline steps, resolved from the step name.
@@ -61,6 +61,8 @@
61
61
  <button class="tab" data-tab="workflow" data-i18n-title="nav.workflow" title="Workflow"><span class="tab-ico" data-icon="workflow"></span><span class="tab-label" data-i18n="nav.workflow">Workflow</span></button>
62
62
  <button class="tab" data-tab="team" data-i18n-title="nav.team" title="Agents &amp; Skills"><span class="tab-ico" data-icon="agents"></span><span class="tab-label" data-i18n="nav.team">Agents &amp; Skills</span></button>
63
63
  <button class="tab" data-tab="files" data-i18n-title="nav.files" title="Files"><span class="tab-ico" data-icon="files"></span><span class="tab-label" data-i18n="nav.files">Files</span></button>
64
+ <button class="tab" data-tab="notes" data-i18n-title="nav.notes" title="Notes"><span class="tab-ico" data-icon="backlog"></span><span class="tab-label" data-i18n="nav.notes">Notes</span></button>
65
+ <button class="tab" data-tab="meeting" data-i18n-title="nav.meeting" title="Daily meeting"><span class="tab-ico" data-icon="meeting"></span><span class="tab-label" data-i18n="nav.meeting">Daily meeting</span></button>
64
66
  <button class="tab" data-tab="info" data-i18n-title="nav.info" title="Info"><span class="tab-ico" data-icon="info"></span><span class="tab-label" data-i18n="nav.info">Info</span></button>
65
67
  <button class="tab" data-tab="docs" data-i18n-title="nav.docs" title="Documentation"><span class="tab-ico" data-icon="docs"></span><span class="tab-label" data-i18n="nav.docs">Documentation</span></button>
66
68
  <button class="tab" data-tab="personalize" data-i18n-title="nav.settings" title="Personalize"><span class="tab-ico" data-icon="settings"></span><span class="tab-label" data-i18n="nav.settings">Personalize</span></button>
@@ -68,10 +70,15 @@
68
70
  <div class="top-right">
69
71
  <span class="sync" id="sync"><span class="sync-dot"></span><span id="syncLabel">live</span></span>
70
72
  <button class="btn primary run-btn" id="runQuickBtn" data-i18n-title="topbar.run.title" title="Open the run chat"><span class="tab-ico" data-icon="run"></span><span data-i18n="action.run">Run</span></button>
73
+ <button class="theme-toggle" id="sideToggle" type="button" data-i18n-title="board.hideSidebar" title="Hide sidebar">
74
+ <svg viewBox="0 0 18 18" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6"><rect x="2" y="3" width="14" height="12" rx="2"/><line x1="11.5" y1="3" x2="11.5" y2="15"/></svg>
75
+ </button>
71
76
  <button class="theme-toggle" id="themeToggle" data-i18n-aria="topbar.theme.toggle" data-i18n-title="topbar.theme.toggle.title" aria-label="Toggle light / dark theme" title="Toggle light / dark"><span class="tab-ico" data-icon="theme"></span></button>
72
77
  </div>
73
78
  </header>
74
79
 
80
+ <div class="offline-bar" id="offlineBar" hidden><span class="offline-dot"></span><span id="offlineText"></span></div>
81
+
75
82
  <main class="stage">
76
83
  <!-- BOARD -->
77
84
  <section class="panel is-active" data-panel="board">
@@ -92,14 +99,22 @@
92
99
  <button class="vt-btn" data-view="kanban" data-i18n-title="board.viewKanban.title" title="Columns by status"><span class="tab-ico" data-icon="board"></span><span data-i18n="board.viewKanban">Kanban</span></button>
93
100
  </div>
94
101
  <button class="mini-btn" id="phaseToggleAll" data-i18n-title="board.expandAllTitle" data-i18n="board.expandAll" title="Expand or collapse all phases">Expand all</button>
102
+ <div class="kanban-tools" id="kanbanTools">
103
+ <button class="mini-btn" id="kanbanColsBtn" type="button" aria-haspopup="true" aria-expanded="false" data-i18n-title="board.kanbanColumnsTitle" data-i18n="board.kanbanColumns" title="Choose visible columns">Columns</button>
104
+ <div class="view-toggle" id="kanbanPageSize" role="group" data-i18n-aria="board.kanbanPageSizeTitle" aria-label="Tasks per column">
105
+ <button class="vt-btn active" data-size="10" type="button">10</button>
106
+ <button class="vt-btn" data-size="20" type="button">20</button>
107
+ </div>
108
+ </div>
95
109
  <input type="search" id="search" class="search" data-i18n-ph="board.filterPlaceholder" placeholder="Filter tasks…" autocomplete="off" />
96
- <button class="mini-btn" id="sideToggle" type="button" data-i18n-title="board.hideSidebar" title="Hide sidebar">
97
- <svg viewBox="0 0 18 18" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6"><rect x="2" y="3" width="14" height="12" rx="2"/><line x1="11.5" y1="3" x2="11.5" y2="15"/></svg>
98
- </button>
99
110
  </div>
111
+ <div class="kanban-cols-pop" id="kanbanColsPop" hidden></div>
100
112
  <div class="board" id="board"></div>
101
113
  </div>
102
114
  <aside class="side" id="side">
115
+ <button class="mini-btn side-toggle-inline" id="sideToggleInline" type="button" data-i18n-title="board.hideSidebar" title="Hide sidebar">
116
+ <svg viewBox="0 0 18 18" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6"><rect x="2" y="3" width="14" height="12" rx="2"/><line x1="11.5" y1="3" x2="11.5" y2="15"/></svg>
117
+ </button>
103
118
  <div class="rail-block rail-block-journal">
104
119
  <h2 class="rail-title"><span data-i18n="rail.journal">Journal</span> <span class="count" id="journalCount">0</span></h2>
105
120
  <div class="journal" id="journal"></div>
@@ -248,6 +263,50 @@
248
263
  </div>
249
264
  </section>
250
265
 
266
+ <!-- NOTES (Bloc note — one freeform Markdown scratchpad per project, .spectoflow/notes.md, autosaved) -->
267
+ <section class="panel" data-panel="notes">
268
+ <div class="notes-wrap">
269
+ <h2 class="panel-title" data-i18n="nav.notes">Notes</h2>
270
+ <p class="panel-sub" data-i18n="notes.sub">A freeform scratchpad for this project — Markdown, autosaved as you type. Only you (and whoever else opens this dashboard) can see it.</p>
271
+ <div class="note-card">
272
+ <div class="note-card-bar">
273
+ <span class="note-status" id="notesStatus"></span>
274
+ </div>
275
+ <div class="note-card-body" id="notesEditor"></div>
276
+ </div>
277
+ </div>
278
+ </section>
279
+
280
+ <!-- DAILY MEETING (Sous-projet C, Task 3) — one dated Markdown note per day,
281
+ .spectoflow/meetings/<date>.md, manually editable and agent-generatable. A journal/report
282
+ panel, styled like the rest of the dashboard — deliberately NOT the Notes tab's post-it look. -->
283
+ <section class="panel" data-panel="meeting">
284
+ <div class="meeting-wrap">
285
+ <h2 class="panel-title" data-i18n="nav.meeting">Daily meeting</h2>
286
+ <p class="panel-sub" data-i18n="meeting.sub">One dated note per day for this project — write it yourself, or have the active agent draft it from recent tasks and chat activity.</p>
287
+ <div class="meeting-body">
288
+ <aside class="meeting-history-col">
289
+ <h3 class="rail-title" data-i18n="meeting.history">History</h3>
290
+ <ul class="flatlist meeting-history" id="meetingHistory"></ul>
291
+ </aside>
292
+ <div class="meeting-main">
293
+ <div class="meeting-toolbar">
294
+ <span class="meeting-date" id="meetingDate"></span>
295
+ <button id="meetingGenBtn" class="mini-btn" type="button" data-i18n-title="meeting.generateTitle" data-i18n="meeting.generate" title="Generate today's note from recent activity">Generate</button>
296
+ <span class="files-saved-tip" id="meetingStatus"></span>
297
+ </div>
298
+ <div class="meeting-confirm" id="meetingConfirm" hidden>
299
+ <span data-i18n="meeting.overwriteWarn">This will overwrite today's note.</span>
300
+ <button id="meetingConfirmBtn" class="mini-btn" type="button" data-i18n="meeting.generateAnyway">Generate anyway</button>
301
+ <button id="meetingCancelBtn" class="mini-btn" type="button" data-i18n="files.discard">Cancel</button>
302
+ </div>
303
+ <p class="chat-status" id="meetingRunStatus" hidden><span class="spinner" aria-hidden="true"></span><span data-i18n="chat.running">Agent running…</span></p>
304
+ <div class="meeting-editor" id="meetingEditor"></div>
305
+ </div>
306
+ </div>
307
+ </div>
308
+ </section>
309
+
251
310
  <!-- CHAT (full-width chat tab — shares renderChatLog + doRun/doOrchestrate/approve with the floating widget) -->
252
311
  <section class="panel" data-panel="chat">
253
312
  <div class="chat-tab-wrap">
@@ -338,6 +397,19 @@
338
397
  </select>
339
398
  </label>
340
399
  </div>
400
+ <div class="settings-card settings-card--wide">
401
+ <h3 class="settings-card-title" data-i18n="settings.group.navTabs">Navigation tabs</h3>
402
+ <div class="nav-tabs-list" id="navTabsList"></div>
403
+ </div>
404
+ <div class="settings-card settings-card--wide">
405
+ <h3 class="settings-card-title" data-i18n="settings.commands.title">Commands</h3>
406
+ <p class="settings-card-note" data-i18n="settings.commands.note">Slash commands you can type in the chat. Use {{input}} in the instruction to place your text.</p>
407
+ <div class="cmd-editor" id="commandsList"></div>
408
+ <div class="cmd-editor-actions">
409
+ <button type="button" id="cmdAddBtn" class="btn primary" data-i18n="settings.commands.add">+ Add command</button>
410
+ <button type="button" id="cmdRestoreBtn" class="btn" data-i18n="settings.commands.restore">Restore defaults</button>
411
+ </div>
412
+ </div>
341
413
  </div>
342
414
  <div class="settings-saved" id="settingsSaved" data-i18n="settings.saved" hidden>✓ saved</div>
343
415
  <div class="settings-readonly" id="settingsReadonly"></div>
@@ -399,6 +471,9 @@
399
471
  <p class="chat-status" id="widgetChatStatus" hidden><span class="spinner" aria-hidden="true"></span><span data-i18n="chat.running">Agent running…</span></p>
400
472
  </div>
401
473
 
474
+ <!-- Slash-command autocomplete popover, reused by both #runPrompt and #tabRunPrompt (app.js) -->
475
+ <div id="cmdMenu" class="cmd-menu" role="listbox" aria-label="Commands" hidden></div>
476
+
402
477
  <div class="drawer" id="drawer" aria-hidden="true">
403
478
  <div class="drawer-scrim" id="drawerScrim"></div>
404
479
  <div class="drawer-panel" role="dialog"><button class="drawer-close" id="drawerClose">×</button><div id="drawerBody"></div></div>
@@ -410,21 +485,39 @@
410
485
  <!-- workflow step popover — anchored to the clicked step, holds its details + toggle -->
411
486
  <div id="wfPop" class="wf-pop" hidden></div>
412
487
 
413
- <!-- shared gradient used by SpectoCharts.ring's foreground arc (stroke="url(#grad)") -->
414
- <svg width="0" height="0" style="position:absolute" aria-hidden="true">
415
- <defs>
416
- <linearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="100%">
417
- <stop offset="0%" stop-color="var(--cool)" />
418
- <stop offset="100%" stop-color="var(--signal)" />
419
- </linearGradient>
420
- </defs>
421
- </svg>
422
-
423
488
  <script src="/stats.js"></script>
489
+ <script src="/commands.js"></script>
424
490
  <script src="/charts.js"></script>
425
491
  <script src="/icons.js"></script>
426
492
  <script src="/designs.js"></script>
427
493
  <script src="/i18n.js"></script>
494
+ <!-- Vendored Prism.js (1.29.0, self-hosted, zero-npm-dependency — see lib/dashboard/public/vendor/prism/).
495
+ Prism.manual disables its own automatic DOMContentLoaded highlighting: app.js's Files tab calls
496
+ Prism.highlight() itself on every keystroke instead. Component load order follows real `extend()`
497
+ dependencies found in each file (clike/markup are bases; c before cpp; markup-templating before php). -->
498
+ <script>window.Prism = window.Prism || {}; Prism.manual = true;</script>
499
+ <script src="/vendor/prism/prism-core.min.js"></script>
500
+ <script src="/vendor/prism/prism-clike.min.js"></script>
501
+ <script src="/vendor/prism/prism-markup.min.js"></script>
502
+ <script src="/vendor/prism/prism-css.min.js"></script>
503
+ <script src="/vendor/prism/prism-c.min.js"></script>
504
+ <script src="/vendor/prism/prism-cpp.min.js"></script>
505
+ <script src="/vendor/prism/prism-csharp.min.js"></script>
506
+ <script src="/vendor/prism/prism-java.min.js"></script>
507
+ <script src="/vendor/prism/prism-go.min.js"></script>
508
+ <script src="/vendor/prism/prism-kotlin.min.js"></script>
509
+ <script src="/vendor/prism/prism-ruby.min.js"></script>
510
+ <script src="/vendor/prism/prism-rust.min.js"></script>
511
+ <script src="/vendor/prism/prism-swift.min.js"></script>
512
+ <script src="/vendor/prism/prism-sql.min.js"></script>
513
+ <script src="/vendor/prism/prism-bash.min.js"></script>
514
+ <script src="/vendor/prism/prism-yaml.min.js"></script>
515
+ <script src="/vendor/prism/prism-docker.min.js"></script>
516
+ <script src="/vendor/prism/prism-json.min.js"></script>
517
+ <script src="/vendor/prism/prism-markup-templating.min.js"></script>
518
+ <script src="/vendor/prism/prism-php.min.js"></script>
519
+ <script src="/vendor/prism/prism-markdown.min.js"></script>
520
+ <script src="/vendor/prism/prism-python.min.js"></script>
428
521
  <script src="/app.js"></script>
429
522
  <script src="/designs/console.js"></script>
430
523
  <script src="/designs/orbit.js"></script>