feat(knowledge): rebuild the project notes panel as Project knowledge (#2973)
The panel stored notes, todos and plans inside one shared JSON file that six unrelated domains also wrote to, synchronised itself through window CustomEvents, and could only read plans. It is now Project knowledge: server-owned storage with explicit routes, a store with rollback, a section sidebar, plans that open and edit in place, and search across all of it. Notes and plans the user pins travel with every message sent in that project. Pinning is project state, not an attachment to one message, so it holds until unpinned and the work status panel names what is riding along and can detach it. Agent memory is added alongside, in two scopes: what is true about the user, and what is true about this codebase. The split is not cosmetic — a wrong project fact costs one project and is noticed, while a wrong global fact quietly shapes every session everywhere and the user has no code to check it against. It stays separate from notes so an agent mistake cannot land in what the user wrote. Sessions receive an index of titles only; bodies are read on demand, because an index carrying full text grows until it crowds out the conversation. Deciding what a session must be told, and whether it has been told, now lives on the server. The client owned it before, which meant sessions started without a UI — scheduled tasks, sessions the agent dispatches — received nothing at all, and a tab's record of what it had sent outlived the conversation: after compaction the agent no longer held the block while the tab went on believing it did. What was delivered is recorded in the session's own metadata, and compaction restores it through the runtime that already restores pinned messages, in the same turn. Agent memory ships dark behind OPENCHAMBER_MEMORY_ENABLE: unset, there is no tool, no routes, no session index, no settings row and no panel tab. Absent rather than switched off, so nothing invites turning on a feature that has not been announced. Pinned notes and plans are unaffected and ship as normal.
This commit is contained in:
committed by
GitHub
parent
7611076436
commit
34e8a24b20
@@ -1189,12 +1189,12 @@ export const dict: Record<I18nKey, string> = {
|
||||
"walkthrough.blocked.structuredOutput.descriptionUnknownModel": "O modelo pequeno não suporta as respostas estruturadas que um percurso exige.",
|
||||
"contextRail.surface.plan.description": "Ver o plano atual",
|
||||
"contextRail.surface.pr.description": "Crie, revise e faça merge do pull request do branch atual",
|
||||
"contextRail.surface.notes.description": "Notas, tarefas e planos do projeto",
|
||||
"contextRail.surface.notes.description": "Notas, tarefas, planos e memória do agente do projeto",
|
||||
"contextRail.surface.context.description": "Contexto da sessão e uso de tokens",
|
||||
"contextRail.surface.browser.description": "Navegador web integrado",
|
||||
"contextRail.surface.preview.description": "Pré-visualização do servidor de desenvolvimento",
|
||||
"contextRail.surface.chat.description": "Sessão aberta lado a lado",
|
||||
"contextRail.surface.notes": "Notas do projeto",
|
||||
"contextRail.surface.notes": "Conhecimento do projeto",
|
||||
"contextRail.editorTree.toggle": "Alternar árvore de arquivos",
|
||||
"contextPanel.browser.open": "Abrir painel do navegador",
|
||||
"contextPanel.browser.addressAria": "Endereço do navegador",
|
||||
@@ -1425,6 +1425,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
"planView.file.defaultName": "plano",
|
||||
"planView.title.default": "Plano",
|
||||
"planView.error.saveFailed": "Não foi possível salvar",
|
||||
"planView.error.loadFailed": "Não foi possível carregar este plano",
|
||||
"planView.error.previewUnavailable": "Pré-visualização indisponível",
|
||||
"planView.error.switchToEditMode": "Alterne para o modo de edição para resolver o problema.",
|
||||
"planView.error.writeFailed": "Não foi possível gravar",
|
||||
@@ -1519,11 +1520,46 @@ export const dict: Record<I18nKey, string> = {
|
||||
"diffView.hunk.unsupported": "A preparação de trechos individuais não é suportada neste ambiente.",
|
||||
"rightSidebar.contextNotesTodo.plan.defaultTitle": "Plano",
|
||||
"rightSidebar.contextNotesTodo.empty.selectProject": "Selecione um projeto para adicionar notas e tarefas pendentes.",
|
||||
"rightSidebar.contextNotesTodo.notes.title": "Notas rápidas — {project}",
|
||||
"rightSidebar.contextNotesTodo.notes.placeholder": "Capture contexto, lembretes ou links",
|
||||
"rightSidebar.contextNotesTodo.todo.title": "Tarefas pendentes",
|
||||
"rightSidebar.contextNotesTodo.todo.itemsSingle": "{count} elemento",
|
||||
"rightSidebar.contextNotesTodo.todo.itemsPlural": "{count} elementos",
|
||||
"rightSidebar.contextNotesTodo.notes.addAria": "Adicionar nota",
|
||||
"rightSidebar.contextNotesTodo.notes.empty": "Ainda não há notas. Registre contexto, lembretes ou links.",
|
||||
"rightSidebar.contextNotesTodo.notes.actions.expand": "Expandir nota",
|
||||
"rightSidebar.contextNotesTodo.notes.actions.collapse": "Recolher nota",
|
||||
"rightSidebar.contextNotesTodo.notes.actions.delete": "Excluir nota",
|
||||
"rightSidebar.contextNotesTodo.notes.actions.pin": "Fixar no contexto do agente",
|
||||
"rightSidebar.contextNotesTodo.notes.actions.unpin": "Desafixar do contexto do agente",
|
||||
"rightSidebar.contextNotesTodo.notes.source.selection": "Do chat",
|
||||
"rightSidebar.contextNotesTodo.notes.source.agent": "Do agente",
|
||||
"rightSidebar.contextNotesTodo.search.placeholder": "Buscar",
|
||||
"rightSidebar.contextNotesTodo.search.clear": "Limpar busca",
|
||||
"rightSidebar.contextNotesTodo.search.noResults": "Nada corresponde a \"{query}\".",
|
||||
"rightSidebar.contextNotesTodo.toast.deleteNoteFailed": "Falha ao excluir a nota",
|
||||
"rightSidebar.contextNotesTodo.toast.createNoteFailed": "Falha ao criar a nota",
|
||||
"rightSidebar.contextNotesTodo.tabs.notes": "Notas",
|
||||
"rightSidebar.contextNotesTodo.tabs.todos": "Tarefas",
|
||||
"rightSidebar.contextNotesTodo.tabs.plans": "Planos",
|
||||
"rightSidebar.contextNotesTodo.plans.actions.back": "Voltar aos planos",
|
||||
"rightSidebar.contextNotesTodo.tabs.memory": "Memória",
|
||||
"rightSidebar.contextNotesTodo.sections.label": "Seções do contexto do projeto",
|
||||
"rightSidebar.contextNotesTodo.sections.resize": "Redimensionar a barra de seções",
|
||||
"rightSidebar.contextNotesTodo.memory.scope.project": "Projeto",
|
||||
"rightSidebar.contextNotesTodo.memory.scope.label": "Escopo da memória",
|
||||
"rightSidebar.contextNotesTodo.memory.scope.global": "Sobre você",
|
||||
"rightSidebar.contextNotesTodo.memory.type.fact": "fato",
|
||||
"rightSidebar.contextNotesTodo.memory.badge.new": "novo",
|
||||
"rightSidebar.contextNotesTodo.memory.flagged": "Retido do agente — parece uma instrução",
|
||||
"rightSidebar.contextNotesTodo.memory.badge.changed": "alterado",
|
||||
"rightSidebar.contextNotesTodo.memory.type.preference": "preferência",
|
||||
"rightSidebar.contextNotesTodo.memory.type.reference": "referência",
|
||||
"rightSidebar.contextNotesTodo.memory.actions.delete": "Esquecer esta memória",
|
||||
"rightSidebar.contextNotesTodo.memory.actions.editTitle": "Título da memória",
|
||||
"rightSidebar.contextNotesTodo.memory.actions.editBody": "Texto da memória",
|
||||
"rightSidebar.contextNotesTodo.memory.toast.saveFailed": "Não foi possível salvar a memória",
|
||||
"rightSidebar.contextNotesTodo.memory.toast.deleteFailed": "Não foi possível esquecer a memória",
|
||||
"rightSidebar.contextNotesTodo.memory.empty.nothing": "O agente ainda não guardou nada aqui.",
|
||||
"rightSidebar.contextNotesTodo.memory.empty.noMatches": "Nenhuma memória guardada corresponde à sua busca.",
|
||||
"rightSidebar.contextNotesTodo.memory.empty.noProject": "Abra um projeto para ver o que o agente lembra sobre ele.",
|
||||
"rightSidebar.contextNotesTodo.memory.empty.unavailable": "Não foi possível carregar a memória guardada. Nada foi perdido — tente novamente.",
|
||||
"rightSidebar.contextNotesTodo.todo.clearCompleted": "Limpar completadas",
|
||||
"rightSidebar.contextNotesTodo.todo.inputPlaceholder": "Adicione uma tarefa pendente",
|
||||
"rightSidebar.contextNotesTodo.todo.addAria": "Adicionar tarefa pendente",
|
||||
@@ -1534,13 +1570,9 @@ export const dict: Record<I18nKey, string> = {
|
||||
"rightSidebar.contextNotesTodo.todo.actions.delete": "Excluir \"{text}\"",
|
||||
"rightSidebar.contextNotesTodo.todo.actions.send": "Enviar \"{text}\"",
|
||||
"rightSidebar.contextNotesTodo.todo.actions.reorder": "Reordenar \"{text}\"",
|
||||
"rightSidebar.contextNotesTodo.todo.resizeAria": "Redimensionar lista de tarefas",
|
||||
"rightSidebar.contextNotesTodo.todo.sendMenu.currentSession": "Enviar à sessão atual",
|
||||
"rightSidebar.contextNotesTodo.todo.sendMenu.newSession": "Enviar a uma nova sessão",
|
||||
"rightSidebar.contextNotesTodo.todo.sendMenu.newWorktreeSession": "Enviar a uma nova sessão de worktree",
|
||||
"rightSidebar.contextNotesTodo.plans.title": "Planos",
|
||||
"rightSidebar.contextNotesTodo.plans.filesSingle": "{count} arquivo",
|
||||
"rightSidebar.contextNotesTodo.plans.filesPlural": "{count} arquivos",
|
||||
"rightSidebar.contextNotesTodo.plans.importFromFile": "Importar plano de arquivo",
|
||||
"rightSidebar.contextNotesTodo.plans.empty": "Ainda não há planos salvos.",
|
||||
"rightSidebar.contextNotesTodo.plans.deletePlan": "Excluir plano",
|
||||
@@ -1560,6 +1592,7 @@ export const dict: Record<I18nKey, string> = {
|
||||
"rightSidebar.contextNotesTodo.toast.sentToNewSession": "Tarefa enviada para uma nova sessão",
|
||||
"rightSidebar.contextNotesTodo.toast.sentToNewWorktreeSession": "Tarefa enviada para uma nova sessão de worktree",
|
||||
"rightSidebar.contextNotesTodo.toast.sendTodoFailed": "Não foi possível enviar a tarefa",
|
||||
"rightSidebar.contextNotesTodo.toast.updatePlanFailed": "Falha ao atualizar o plano",
|
||||
"rightSidebar.contextNotesTodo.toast.deletePlanFailed": "Não foi possível excluir o plano",
|
||||
"rightSidebar.contextNotesTodo.toast.planFileEmpty": "O arquivo do plano está vazio",
|
||||
"rightSidebar.contextNotesTodo.toast.importPlanFailed": "Não foi possível importar o plano",
|
||||
@@ -3033,6 +3066,12 @@ export const dict: Record<I18nKey, string> = {
|
||||
'chat.workStatus.subagent.askedQuestion': 'fez uma pergunta',
|
||||
'chat.workStatus.section.contextBreakdown': 'Fontes de contexto',
|
||||
'chat.workStatus.breakdown.skills': 'Habilidades',
|
||||
'chat.workStatus.breakdown.pinnedNote': 'nota',
|
||||
'chat.workStatus.breakdown.unpin': 'Desafixar do contexto',
|
||||
'chat.workStatus.breakdown.pinnedPlan': 'plano',
|
||||
'chat.workStatus.breakdown.memory': 'Memória do agente',
|
||||
'chat.workStatus.breakdown.pinnedKnowledgeSingle': '{count} fixado',
|
||||
'chat.workStatus.breakdown.pinnedKnowledgePlural': '{count} fixados',
|
||||
'chat.workStatus.breakdown.mcp': 'Servidores MCP',
|
||||
'chat.workStatus.action.openChanges': 'Abrir alterações',
|
||||
'chat.workStatus.action.openGit': 'Abrir painel do Git',
|
||||
|
||||
Reference in New Issue
Block a user