--- id: AGD-0010 ticket: studio-code-editor-workspace-foundations title: Iniciar foundations do Code Editor no Studio sem LSP status: open created: 2026-03-30 resolved: decision: tags: - studio - editor - workspace - multi-frontend - lsp-deferred --- ## Pain O shell do Studio ja assume `Code Editor` como parte do baseline workspace set, mas a implementacao atual do `EditorWorkspace` ainda e apenas um `CodeArea` com texto hardcoded e botoes sem modelo real de documento, tabs, arquivos, dirty state ou sessao de projeto. Ao mesmo tempo, queremos iniciar os trabalhos do editor agora, com foco em UI e infraestrutura robusta para varios frontends, mas sem cair em uma dependencia prematura de LSP. Sem fechar a boundary agora, a implementacao pode desviar para dois extremos ruins: - o Studio virar uma casca quase vazia que depende de cada frontend ate para abrir, salvar e manter buffers; - ou o Studio absorver semantica demais e virar uma segunda autoridade sobre parsing, diagnosticos e modelo de compilacao. ## Context Domain owner: `studio` Owner surface: `docs/specs/studio` Cross-domain input: `compiler` Superficies relevantes hoje: - `docs/specs/studio/1. Studio Shell and Workspace Layout Specification.md` ja define `Code Editor` como workspace baseline do shell; - `docs/specs/studio/2. Studio UI Foundations Specification.md` exige workspaces com composicao root, event bus tipado, lifecycle-managed controls e infra reutilizavel; - `prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorWorkspace.java` hoje monta um `CodeArea` simples sem modelo de arquivos do projeto; - `prometeu-studio/src/main/java/p/studio/projects/ProjectLanguageCatalogService.java` ja consome `FrontendRegistryService` e `FrontendSpec`, o que mostra que o Studio ja reconhece multiplos frontends e source roots por linguagem; - `prometeu-compiler/.../FrontendSpec.java` ja modela `languageId`, `allowedExtensions`, `sourceRoots`, `caseSensitive` e versoes de stdlib; - o compiler hoje ainda descobre e le fontes diretamente do filesystem: `LoadSourcesPipelineStage` faz `walkFileTree(...)` nos `sourceRoots`, `BuilderPipelineContext.compilerContext(...)` instancia `SourceProviderFactory.filesystem()`, e `SourceHandle` le bytes com `Files.readAllBytes(path)`; - `docs/roadmaps/lsp/` ja existe como trilha separada, mas esta wave quer editor sem depender de LSP; - o precedente do packer fixa uma boa disciplina de ownership, mas ele nao deve ser copiado mecanicamente para o editor sem discutir a diferenca entre semantica de dominio e sessao generica de edicao. O ponto mais sensivel desta agenda e justamente essa diferenca: - no packer, Studio nao deve reinventar semantica de asset, snapshots operacionais ou write lanes de dominio; - no editor, leitura/escrita de arquivos fonte, dirty tracking, buffers em memoria e snapshots documentais fazem parte da propria experiencia do workspace e nao sao, por si so, semantica de linguagem. Direcao adicional ja explicitada para a UX: - o editor deve seguir um baseline proximo ao modelo do IntelliJ; - a ala esquerda deve ser um `Project Navigator` com arquivos/pastas relevantes do projeto; - a area central deve ter tabs de arquivos abertos no topo e o editor rico no corpo principal; - a regiao inferior deve ser um helper persistente para prompts, tips e feedback contextual sobre o codigo atual, funcionando mais como `advanced editor log` do que como console cru. ## Open Questions - [ ] Qual e o seam normativo para ligar `document snapshots` do editor ao compiler: substituir `SourceProviderFactory.filesystem()` por provider de sessao, ou introduzir uma etapa explicita que materializa uma visao congelada de documentos antes do pipeline? - [ ] O primeiro wave do editor deve nascer com tabs multiplas e sessao multi-documento completa, ou tabs multiplas com uma politica mais simples de documentos ativos/carregados? - [ ] Como o `EditorWorkspace` descobre quais arquivos e source roots sao editaveis a partir de `ProjectReference.languageId` e `FrontendSpec`? - [ ] Quem detecta modificacoes externas em arquivos abertos e como o conflito entre disco e buffer em memoria deve aparecer para o usuario? - [ ] Alem do baseline ja aceito (`Project Navigator`, tabs, editor central, helper inferior), a primeira wave tambem deve incluir `outline` ou `status bar`, ou esses elementos ficam explicitamente para depois? - [ ] Como preservar uma UI consistente entre linguagens diferentes sem forcar cada frontend a carregar seu proprio mini-editor completo? - [ ] O que fica explicitamente fora desta wave por ausencia de LSP: autocomplete, go to definition, semantic diagnostics ao digitar, symbols, rename, code actions? ## Options ### Option A - Studio como casca pura; frontend/backends fazem o resto - **Approach:** O Studio hospeda a area visual do editor, mas leitura, escrita, buffers, snapshots e demais operacoes relevantes ficam delegadas a adaptadores por linguagem ou a servicos externos. - **Pro:** Mantem o Studio "leve" e minimiza responsabilidade local. - **Con:** Duplica infraestrutura generica em cada frontend, acopla UX basica a backend de linguagem e torna dificil sustentar uma experiencia coerente multi-FE sem LSP. - **Maintainability:** Fraca. A boundary fica formalmente limpa, mas o custo reaparece como fragmentacao de sessao, inconsistencias de UX e adaptadores repetidos. ### Option B - Studio possui sessao generica de documentos; frontends possuem semantica - **Approach:** O Studio passa a possuir uma camada generica de editor para descoberta de arquivos, open/save, dirty tracking, tabs, estado ativo, deteccao de mudanca externa e snapshots imutaveis de documento em memoria; frontends consomem essa camada como entrada para highlighting, parsing, diagnosticos e outras features atuais ou futuras. - **Pro:** Cria uma base robusta para varios frontends mesmo sem LSP, evita duplicacao de infra generica e mantem a semantica de linguagem fora do workspace visual. - **Con:** Exige disciplina para nao confundir `snapshot documental` com `snapshot semantico` do compiler e para nao deixar a camada generica vazar regras de linguagem. - **Maintainability:** Forte. A separacao entre sessao de edicao e semantica de linguagem fica clara e expansivel. ### Option C - Cada frontend possui seu proprio stack de editor end-to-end - **Approach:** O Studio oferece apenas um host de workspace, e cada frontend implementa seu proprio editor, file model, snapshots e event wiring do zero. - **Pro:** Maxima liberdade por linguagem. - **Con:** DestrĂ³i a chance de um framework comum de editor, duplica problema de tabs/buffers/save/conflicts e torna a shell dependente de N mini-produtos locais. - **Maintainability:** Fraca. Funciona para prototipos isolados, mas nao para um Studio que quer suportar varios FEs sob uma UX comum. ### Option D - Esperar LSP e desenhar o editor em torno dele - **Approach:** Adiar a infra editorial mais seria ate que exista um backend LSP suficientemente funcional e modelar o editor a partir desse contrato. - **Pro:** Pode reduzir retrabalho se o LSP for a unica fronteira desejada. - **Con:** Conflita com o objetivo desta wave, atrasa o editor, e ainda nao resolve ownership de file IO, buffers e dirty state, que continuam existindo mesmo com LSP. - **Maintainability:** Media para baixa. O LSP ajuda na semantica, mas nao substitui a sessao generica de edicao. ## Discussion O precedente do packer e util, mas ele nao responde sozinho a pergunta desta agenda. No packer, a semantica de dominio e forte: - identidade de asset; - validacao; - write lane; - snapshots operacionais; - causality de eventos. Nessa area, faz sentido Studio atuar mais como adaptador editorial do que como autoridade. No editor de codigo, porem, existe uma camada anterior a qualquer semantica de linguagem: - abrir arquivo; - manter buffer em memoria; - controlar dirty state; - salvar em disco; - alternar tabs; - versionar snapshots documentais; - reagir a mudancas externas; - expor um modelo de sessao que qualquer FE consiga consumir. Essas responsabilidades nao sao "semantica de compiler". Sao responsabilidades normais de um editor. Se o Studio se recusar a possui-las, cada frontend ou integracao futura precisara reinventar a mesma infraestrutura. Do ponto de vista de UX, a direcao mais solida e assumir um baseline de tres regioes dentro do `EditorWorkspace`: 1. `Project Navigator` na esquerda 2. `Editor Workarea` no centro, com tabs acima e editor no corpo 3. `Editor Helper Panel` na base, para tips, prompts, hints e feedback contextual Esse painel inferior merece cuidado de nomenclatura e ownership. Ele nao deve nascer como "console generico" nem como dumping ground de logs tecnicos. Melhor trata-lo como uma superficie editorial guiada pelo contexto do documento ativo. Sugestao de papel para esse helper: - mostrar hints sobre arquivo, linguagem e estado do documento; - receber mensagens de parse/local validation quando existirem; - explicar bloqueios de save, conflitos de disco e prompts do editor; - no futuro, acomodar saidas de LSP ou FE sem acoplar a shell global a isso. Em outras palavras: ele deve ser um `assistant/log` de workspace, nao um substituto do painel global `Activity` e nao um terminal cru. O boundary mais saudavel parece ser: 1. o Studio possui a sessao generica de documentos e a UX editorial comum; 2. os frontends recebem snapshots documentais imutaveis como entrada; 3. parsing, name resolution, diagnostics, semantic tokens, completions e afins continuam fora da camada generica do editor; 4. LSP, quando existir, entra como um consumidor/provedor de semantica sobre essa base, nao como substituto da base. O estado atual do compiler reforca essa necessidade. Hoje o build pipeline ainda assume filesystem como source of truth imediata: - os arquivos sao descobertos por crawl direto nos `sourceRoots`; - o `BuilderPipelineContext` nasce com `SourceProviderFactory.filesystem()`; - cada `SourceHandle` le bytes do `Path` canonico. Isso significa que, se quisermos uniformizar Studio, FE services e LSP futuro em torno de uma mesma visao documental, precisamos introduzir explicitamente uma camada de `document snapshot` antes do consumo pelo pipeline. O lado bom e que ja existe um seam util: `SourceProviderFactory` nao esta hardcoded em todos os callsites e ja sugere providers alternativos, inclusive `in-memory`. Isso tambem ajuda com a meta de varios FEs: - `FrontendSpec` ja informa roots e extensoes; - o `EditorWorkspace` pode montar a superficie a partir disso; - e cada linguagem fica livre para plugar servicos sem destruir o modelo editorial comum. ## Resolution Recommended direction: seguir com **Option B**. A agenda deve convergir para uma decisao com os seguintes fechamentos: 1. o Studio deve possuir uma camada generica de `document/session` para o Code Editor; 2. essa camada pode ler e escrever arquivos fonte e manter snapshots documentais em memoria; 3. essa camada nao deve possuir semantica de linguagem, parsing autoritativo ou diagnosticos como responsabilidade primaria; 4. frontends devem consumir snapshots documentais do editor por um contrato explicito, imutavel e versionado; 5. como o compiler hoje ainda le do filesystem, a decisao precisa fechar uma etapa/seam concreta para injetar `document snapshots` antes do pipeline, uniformizando a entrada de Studio, FE services e LSP futuro; 6. LSP fica explicitamente fora do primeiro wave, mas a modelagem precisa deixar caminho limpo para ele; 7. a primeira wave do editor deve normatizar explicitamente o baseline visual do workspace: `Project Navigator` na esquerda, tabs no topo da area central, editor rico no corpo e `Editor Helper Panel` inferior reservado; 8. o `Editor Helper Panel` nasce passivo na primeira wave, como espaco reservado para prompts, tips e feedback contextual, sem obrigar interatividade imediata. Next step suggestion: converter esta agenda em uma `decision` que feche o boundary entre `EditorWorkspace`, sessao documental do Studio e servicos de frontend, incluindo o escopo exato da primeira wave de UI sem LSP.