feat: implementacao completa do PromptForge — extensao VS Code para engenharia de prompts com IA - #1
feat: implementacao completa do PromptForge — extensao VS Code para engenharia de prompts com IA#1jonathancnn wants to merge 10 commits into
Conversation
…ngenharia de prompts com IA
Sessoes 1-6 completas:
- Scaffold com esbuild dual-context (CJS + IIFE), TypeScript strict, Tailwind CSS
- 4 providers reais (Anthropic, OpenAI, Google, OpenRouter) com streaming
- Co-escritor IA com best practices por modelo (Claude/GPT/Gemini/o-series)
- Template de variaveis dinamicas {{nome:valor_padrao}}
- Test runner com score semantico e refinamento via IA
- A/B testing lado a lado com execucao paralela
- Replay de chamadas com diff de outputs
- Cost tracking por modelo com tabela de precos completa
- Biblioteca de prompts com CRUD, versionamento (max 15 + archive)
- Export em JSON, Markdown e code snippets (9 combinacoes: TS/Python/cURL x 3 providers)
- 28 testes unitarios passando
- Webview React 18 + Zustand com comunicacao tipada via postMessage
- BasePanel com CSP, nonce e dispose pattern
- API keys via SecretStorage com onboarding banner
https://claude.ai/code/session_01KpwSAzpmuo3cMJavX9JGcM
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bef10c2096
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| case 'STREAM_CHUNK': | ||
| // Tratado pelo hook useStreaming dentro dos componentes | ||
| break | ||
| case 'STREAM_DONE': | ||
| break |
There was a problem hiding this comment.
Wire stream events to state updates
STREAM_CHUNK and STREAM_DONE are dropped here, and there is no other webview listener that forwards these payloads to useStreaming (handleChunk/handleDone are never called anywhere). In practice, co-writer/refinement requests stream from the extension but the UI never renders incoming text or final cost, so users cannot see or apply generated prompt output.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in commit 7ae35b2. STREAM_CHUNK and STREAM_DONE are now routed through the Zustand store via store.handleStreamChunk() and store.handleStreamDone(). The CoWriter component reads streamText/streamIsActive/streamCost from the store, so streaming renders correctly in the UI. REFINE_RESULT is also wired to the same pipeline.
Generated by Claude Code
| case 'PROMPT_SAVED': | ||
| break |
There was a problem hiding this comment.
Persist returned promptId after first save
Ignoring PROMPT_SAVED means new prompts never store the server-returned promptId in the client state. Subsequent saves keep sending promptId: undefined, which drives PromptStore.savePrompt down its “create new prompt” path instead of appending a new version, breaking version history and duplicating prompt files on every save.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in commit 7ae35b2. PROMPT_SAVED now calls store.setLastSavedPromptId(msg.payload.promptId), which updates the store and shows a success banner. The promptId is persisted in state so subsequent saves append versions correctly instead of creating duplicates.
Generated by Claude Code
| case 'SNIPPET_RESULT': | ||
| break |
There was a problem hiding this comment.
Handle snippet result messages
SNIPPET_RESULT is ignored in the global message dispatcher, so the generated snippet coming from LibraryPanel is never stored or propagated to ExportPanel. Users can click “Gerar Snippet”, but no snippet text is ever shown in the export UI despite the backend successfully returning it.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in commit 7ae35b2. SNIPPET_RESULT now calls store.setSnippetResult(msg.payload.code, msg.payload.language). The LibraryMode component reads snippetCode from the store (instead of local state) and passes it to ExportPanel, so generated snippets are now visible in the export UI.
Generated by Claude Code
… (16 arquivos) Bugs corrigidos: - CRITICO: import crypto ausente em EditorPanel (crash em streaming) - escapeForJSON incompleto — substituido por JSON.stringify().slice(1,-1) - PromptStore/ReplayStore: file I/O sincrono trocado por fs.promises (async) - PromptStore/ReplayStore: JSON.parse sem try-catch — tratamento de corrupcao - OpenAIProvider: temperature omitida nas requests (exceto o-series) - AnthropicProvider: response.content[0] sem null check - extension.ts activate(): sem error handling — adicionado try-catch - BasePanel dispose(): ordem invertida — disposables antes de panel.dispose() Novos testes (12 arquivos, 171 testes): - streamBridge: streaming pipeline, chunks, erros, caracteres especiais - promptStore: CRUD completo, arquivamento 15 versoes, JSON corrompido - replayStore: captura, listagem ordenada, imutabilidade, corrupcao - providers: factory routing, guidelines por modelo, parametros padrao - semanticScorer: score identico/zero/parcial, case insensitive, edge cases - configureKeys: routing de keys, fallback env vars, keysStatus - snippetGenerator.extended: escape, Unicode, 9 combinacoes, edge cases - variableParser.extended: espacos, defaults, duplicatas, performance 100+ - bestPractices.extended: todas as guidelines, co-writer system prompt - tokenCounter.extended: precisao, ranking de custos, tokens negativos - panelHtml: CSP, nonce, DOCTYPE, estrutura HTML - messageTypes: MODEL_CATALOG, DEFAULT_PARAMS, SCHEMA_VERSION https://claude.ai/code/session_01KpwSAzpmuo3cMJavX9JGcM
…testados Novos testes: - extension.test.ts: activate/deactivate, registro de 4 comandos, erro na inicializacao - editorPanel.test.ts: singleton, CSP, nonce, handlers SAVE_PROMPT/CONFIGURE_KEYS - testPanel.test.ts: RUN_TEST, LOAD_REPLAYS, CAPTURE_REPLAY, erro sem API key - libraryPanel.test.ts: LOAD_LIBRARY, DELETE_PROMPT, GENERATE_SNIPPET, SAVE_PROMPT - integration.test.ts: fluxos end-to-end (prompt->test->replay, guidelines->snippet, versionamento 16 versoes) Cobertura total dos modulos: - extension.ts, EditorPanel, TestPanel, LibraryPanel (message handlers) - PromptStore (CRUD, arquivamento, corrupcao), ReplayStore (captura, listagem, corrupcao) - streamBridge (pipeline streaming), SemanticScorer (scoring) - configureKeys (routing, fallback env vars), ProviderFactory (todos os providers) - bestPractices (todas as guidelines), tokenCounter (todos os modelos) - variableParser (edge cases), snippetGenerator (9 combinacoes + escape) - panelHtml (CSP, nonce), messageTypes (MODEL_CATALOG, DEFAULT_PARAMS) https://claude.ai/code/session_01KpwSAzpmuo3cMJavX9JGcM
Novos testes adicionais: - commands.test.ts: newPrompt, testPrompt, openLibrary (delegacao para panels) - streamBridge.extended.test.ts: postMessage falha, generator imediato, 100 chunks, excecao - configureKeys.extended.test.ts: UI flow completo (QuickPick/InputBox), todos os providers - promptStore.extended.test.ts: IDs unicos, updatedAt, versionNumber, status draft, arquivamento - providerDefaults.test.ts: getDefaultParams/estimateCost/getBestPractices para todos os providers Total: 293 testes | 26 arquivos | 0 falhas https://claude.ai/code/session_01KpwSAzpmuo3cMJavX9JGcM
Correcoes criticas no fluxo React: - STREAM_CHUNK/STREAM_DONE agora roteados via Zustand store (antes ignorados no App.tsx) - CoWriter reescrito para usar streaming do store (nao hook local isolado) - SNIPPET_RESULT e PROMPT_SAVED agora atualizam o store e exibem feedback na UI - REFINE_RESULT roteado para o pipeline de streaming - Erro global exibido como banner dismissivel Bugs React corrigidos: - ReplayPanel: removido postMessage do useEffect dependency (loop infinito) - LibraryMode: mesmo fix do useEffect - VariablePanel: preserva valores do usuario ao detectar novas variaveis (usa getState) - TestMode: substituido getState() por valor reativo do store (stale closure) - snippetCode no LibraryMode agora lido do store (antes estado local nunca atualizado) Infra: - ESLint config simplificado (sem dependencias externas quebradas) - .vscodeignore otimizado (VSIX 217KB sem maps/configs) - Icone PNG 128x128 (bigorna com </> em laranja/amber) - Publisher placeholder funcional - Removido esbuild-postcss nao usado do package.json - Teste E2E skeleton com @vscode/test-electron - Teste real OpenAI (skip sem rede/key) https://claude.ai/code/session_01KpwSAzpmuo3cMJavX9JGcM
…Runner fix Documentacao: - README.md completo para VS Code Marketplace (features, models, shortcuts, settings) - CHANGELOG.md v0.1.0 com todas as features do MVP - LICENSE MIT Qualidade de codigo: - OpenAIProvider: removido 'as any' — tipagem local para Responses API - TestRunner: corrigido disabled logic (AND -> OR), adicionado loading state - ABTestPanel: adicionado loading state e indicador durante execucao paralela https://claude.ai/code/session_01KpwSAzpmuo3cMJavX9JGcM
…otado - Campo repository adicionado (elimina warning do vsce) - VSIX gerado: promptforge-0.1.0.vsix (220KB, 11 arquivos, production build) - Para instalar: code --install-extension promptforge-0.1.0.vsix https://claude.ai/code/session_01KpwSAzpmuo3cMJavX9JGcM
promptforge-0.1.0.vsix (220KB) — production build pronto para instalacao. Instalar: code --install-extension promptforge-0.1.0.vsix https://claude.ai/code/session_01KpwSAzpmuo3cMJavX9JGcM
Sessoes 1-6 completas:
https://claude.ai/code/session_01KpwSAzpmuo3cMJavX9JGcM