--- ⚠️ **AVISO: DOCUMENTAÇÃO HISTÓRICA** Este documento foi criado em **Março/2026** como planejamento estratégico. Pode conter informações desatualizadas em relação ao sistema atual. Para documentação técnica atualizada, consulte: - \_SPEC_NAVBAR.md\_ (componentes UI) - \_KERNEL_SPEC.md\_ (arquitetura do Kernel) - Código-fonte em \_server/modules/\_ --- Vou criar um plano técnico focado apenas nas funções e implementações, sem aspectos de negócio, custos ou gestão de equipe. Ideal para gerar comandos no Claude Code. \--- \`\`\`markdown \# PLANO TÉCNICO DE IMPLEMENTAÇÃO: SKILL FABRIC \#\# Gerador e Gestor de Desenvolvimento de Skills \- Arcádia Suite \*\*Versão:\*\* 1.0 \*\*Data:\*\* Março 2026 \*\*Tipo:\*\* Especificação Técnica para Implementação \--- \#\# 1\. ARQUITETURA TÉCNICA \#\#\# 1.1 Stack Tecnológico | Camada | Tecnologia | Propósito | |--------|-----------|-----------| | Frontend | React \+ TypeScript \+ Monaco Editor | IDE no browser | | Backend | Node.js \+ TypeScript | API e runtime | | Compilador | ANTLR \+ AST | Parser de skills | | Validação | ESLint \+ Custom Rules | Quality gates | | Runtime | VM2 \+ Sandboxing | Execução segura | | Storage | PostgreSQL \+ Neo4j | Dados e grafo | | Cache | Redis | Performance | \#\#\# 1.2 Estrutura de Diretórios \`\`\` server/modules/skill-fabric/ ├── src/ │ ├── api/ │ │ ├── routes/ │ │ │ ├── skills.routes.ts │ │ │ ├── compiler.routes.ts │ │ │ ├── validator.routes.ts │ │ │ └── marketplace.routes.ts │ │ └── controllers/ │ ├── core/ │ │ ├── skill/ │ │ │ ├── Skill.entity.ts │ │ │ ├── Skill.repository.ts │ │ │ └── Skill.service.ts │ │ ├── compiler/ │ │ │ ├── VisualCompiler.ts │ │ │ ├── CodeCompiler.ts │ │ │ ├── MarkdownCompiler.ts │ │ │ └── AST/ │ │ ├── validator/ │ │ │ ├── ValidationPipeline.ts │ │ │ ├── rules/ │ │ │ │ ├── SyntaxRule.ts │ │ │ │ ├── TypeRule.ts │ │ │ │ ├── SecurityRule.ts │ │ │ │ └── PerformanceRule.ts │ │ ├── executor/ │ │ │ ├── SkillExecutor.ts │ │ │ ├── Sandbox.ts │ │ │ └── ReferenceResolver.ts │ │ └── lifecycle/ │ │ ├── LifecycleManager.ts │ │ └── StateMachine.ts │ └── types/ │ └── index.ts └── tests/ client/src/modules/skill-fabric/ ├── visual-studio/ │ ├── components/ │ │ ├── Canvas.tsx │ │ ├── NodePalette.tsx │ │ ├── PropertyPanel.tsx │ │ └── ConnectionLine.tsx │ └── hooks/ │ ├── useCanvas.ts │ └── useDragDrop.ts ├── code-ide/ │ ├── components/ │ │ ├── MonacoEditor.tsx │ │ ├── IntelliSenseProvider.ts │ │ └── DebuggerPanel.tsx │ └── templates/ │ └── skill-template.ts ├── markdown-studio/ │ ├── components/ │ │ ├── MarkdownEditor.tsx │ │ ├── AIAssistant.tsx │ │ └── LivePreview.tsx │ └── parser/ │ └── MarkdownParser.ts └── shared/ ├── components/ │ ├── SkillToolbar.tsx │ ├── VersionSelector.tsx │ └── ValidationPanel.tsx └── utils/ └── referenceParser.ts \`\`\` \--- \#\# 2\. MÓDULOS DE IMPLEMENTAÇÃO \#\#\# 2.1 Módulo: Core API (skills.api) \*\*Arquivos:\*\* \- \`server/modules/skill-fabric/src/api/routes/skills.routes.ts\` \- \`server/modules/skill-fabric/src/api/controllers/skills.controller.ts\` \*\*Funções:\*\* \`\`\`typescript // CRUD Básico POST /api/skills // createSkill(dto: CreateSkillDTO) GET /api/skills // listSkills(query: ListSkillsQuery) GET /api/skills/:id // getSkill(id: string) PUT /api/skills/:id // updateSkill(id: string, dto: UpdateSkillDTO) DELETE /api/skills/:id // archiveSkill(id: string) // Compilação POST /api/skills/:id/compile // compileSkill(id: string) GET /api/skills/:id/ast // getSkillAST(id: string) // Validação POST /api/skills/:id/validate // validateSkill(id: string) GET /api/skills/:id/validation // getValidationResults(id: string) // Execução POST /api/skills/:id/execute // executeSkill(id: string, input: any) GET /api/skills/:id/executions // listExecutions(id: string) // Versionamento GET /api/skills/:id/versions // listVersions(id: string) POST /api/skills/:id/versions // createVersion(id: string, dto: VersionDTO) POST /api/skills/:id/rollback // rollbackToVersion(id: string, version: string) // Lifecycle POST /api/skills/:id/submit // submitForReview(id: string) POST /api/skills/:id/approve // approveSkill(id: string) POST /api/skills/:id/reject // rejectSkill(id: string, reason: string) POST /api/skills/:id/publish // publishSkill(id: string) POST /api/skills/:id/deprecate // deprecateSkill(id: string) // Marketplace GET /api/skills/marketplace // listMarketplaceSkills(query: MarketplaceQuery) POST /api/skills/:id/publish-marketplace // publishToMarketplace(id: string) POST /api/skills/marketplace/:id/install // installFromMarketplace(id: string) \`\`\` \*\*DTOs:\*\* \`\`\`typescript interface CreateSkillDTO { name: string; slug: string; description: string; type: 'visual' | 'code' | 'markdown'; tenantId: number; companyId?: number; initialContent?: any; } interface UpdateSkillDTO { name?: string; description?: string; content?: any; metadata?: SkillMetadata; } interface ListSkillsQuery { tenantId?: number; companyId?: number; userId?: number; type?: 'visual' | 'code' | 'markdown'; status?: 'draft' | 'dev' | 'testing' | 'staging' | 'production'; tags?: string\[\]; search?: string; limit?: number; offset?: number; } \`\`\` \--- \#\#\# 2.2 Módulo: Skill Entity (skill.entity) \*\*Arquivo:\*\* \`server/modules/skill-fabric/src/core/skill/Skill.entity.ts\` \*\*Classe:\*\* \`\`\`typescript export class Skill { constructor(props: SkillProps) { this.id \= props.id || uuid(); this.validateProps(props); Object.assign(this, props); } // Identidade id: UUID; slug: string; name: string; description: string; // Hierarquia tenantId: number; companyId?: number; userId?: number; namespace: 'system' | 'tenant' | 'company' | 'user'; // Implementação type: 'visual' | 'code' | 'markdown'; content: VisualContent | CodeContent | MarkdownContent; compiled?: CompiledSkill; // Interface inputSchema: JSONSchema; outputSchema: JSONSchema; // Runtime timeout: number \= 30000; memory: number \= 512; retries: number \= 3; // Lifecycle status: SkillStatus \= 'draft'; version: SemanticVersion \= '0.0.1'; branch: string \= 'main'; // Métodos de domínio compile(): CompiledSkill; validate(): ValidationResult; execute(context: ExecutionContext): Promise\; changeStatus(newStatus: SkillStatus, reason?: string): void; createVersion(message: string): Version; rollback(version: string): void; fork(newSlug: string): Skill; // Validação private validateProps(props: SkillProps): void; private validateSlug(slug: string): boolean; private validateContent(content: any): boolean; } \`\`\` \--- \#\#\# 2.3 Módulo: Compiladores (compiler) \*\*Arquivos:\*\* \- \`server/modules/skill-fabric/src/core/compiler/VisualCompiler.ts\` \- \`server/modules/skill-fabric/src/core/compiler/CodeCompiler.ts\` \- \`server/modules/skill-fabric/src/core/compiler/MarkdownCompiler.ts\` \*\*Interface:\*\* \`\`\`typescript interface Compiler { compile(source: any): CompiledSkill; parse(source: any): AST; generateCode(ast: AST): string; validateSyntax(source: any): SyntaxValidationResult; } // Visual Compiler export class VisualCompiler implements Compiler { compile(canvas: VisualCanvas): CompiledSkill { // 1\. Valida conexões // 2\. Ordena topologicamente // 3\. Gera AST // 4\. Compila para JavaScript } parse(canvas: VisualCanvas): VisualAST; generateCode(ast: VisualAST): string; validateSyntax(canvas: VisualCanvas): SyntaxValidationResult; } // Code Compiler export class CodeCompiler implements Compiler { compile(sourceCode: string): CompiledSkill { // 1\. Parse TypeScript // 2\. Type checking // 3\. Transform decorators // 4\. Bundle dependencies } parse(sourceCode: string): TypeScriptAST; generateCode(ast: TypeScriptAST): string; validateSyntax(sourceCode: string): SyntaxValidationResult; } // Markdown Compiler export class MarkdownCompiler implements Compiler { compile(markdown: string): CompiledSkill { // 1\. Parse frontmatter // 2\. Extrair blocos de código // 3\. Resolver referências /xxx/ // 4\. Gerar JavaScript } parse(markdown: string): MarkdownAST; generateCode(ast: MarkdownAST): string; validateSyntax(markdown: string): SyntaxValidationResult; } \`\`\` \*\*AST Types:\*\* \`\`\`typescript interface AST { type: 'skill'; version: string; metadata: SkillMetadata; imports: ImportNode\[\]; exports: ExportNode\[\]; body: StatementNode\[\]; } type StatementNode \= | VariableDeclarationNode | FunctionDeclarationNode | ClassDeclarationNode | ExpressionStatementNode | IfStatementNode | LoopStatementNode | TryCatchNode | SkillCallNode; interface SkillCallNode { type: 'skill-call'; reference: string; // /skill/xxx arguments: ArgumentNode\[\]; await: boolean; } \`\`\` \--- \#\#\# 2.4 Módulo: Validador (validator) \*\*Arquivo:\*\* \`server/modules/skill-fabric/src/core/validator/ValidationPipeline.ts\` \*\*Pipeline:\*\* \`\`\`typescript export class ValidationPipeline { private rules: ValidationRule\[\] \= \[ new SyntaxRule(), new TypeRule(), new SecurityRule(), new DependencyRule(), new PerformanceRule(), new DocumentationRule() \]; async validate(skill: Skill): Promise\ { const results: RuleResult\[\] \= \[\]; for (const rule of this.rules) { const result \= await rule.check(skill); results.push(result); // Fail fast para erros críticos if (result.severity \=== 'error' && rule.isBlocking) { break; } } return this.aggregateResults(results); } calculateScore(results: RuleResult\[\]): number { return results.reduce((score, r) \=\> { return r.passed ? score \+ r.weight : score; }, 0); } } // Regras individuais export class SyntaxRule implements ValidationRule { name \= 'syntax'; weight \= 10; isBlocking \= true; async check(skill: Skill): Promise\ { const compiler \= this.getCompiler(skill.type); const result \= compiler.validateSyntax(skill.content); return { rule: this.name, passed: result.valid, weight: this.weight, severity: result.valid ? 'info' : 'error', details: result.errors }; } } export class SecurityRule implements ValidationRule { name \= 'security'; weight \= 20; isBlocking \= true; forbiddenPatterns \= \[ /eval\\s\*\\(/, /Function\\s\*\\(/, /child\_process/, /fs\\.unlink/, /process\\.env\\s\*=/, /\_\_proto\_\_/, /constructor\\s\*\\\[\\s\*\["'\]prototype\["'\]\\s\*\\\]/ \]; async check(skill: Skill): Promise\ { const code \= skill.compiled?.code || ''; const vulnerabilities: Vulnerability\[\] \= \[\]; for (const pattern of this.forbiddenPatterns) { if (pattern.test(code)) { vulnerabilities.push({ severity: 'critical', pattern: pattern.source, line: this.findLine(code, pattern), message: \`Uso proibido de: ${pattern.source}\` }); } } // Scan de dependências const deps \= skill.compiled?.dependencies || \[\]; for (const dep of deps) { const audit \= await this.auditDependency(dep); if (audit.vulnerabilities.length \> 0\) { vulnerabilities.push(...audit.vulnerabilities); } } return { rule: this.name, passed: vulnerabilities.length \=== 0, weight: this.weight, severity: vulnerabilities.length \> 0 ? 'error' : 'info', details: vulnerabilities }; } } \`\`\` \--- \#\#\# 2.5 Módulo: Executor (executor) \*\*Arquivo:\*\* \`server/modules/skill-fabric/src/core/executor/SkillExecutor.ts\` \*\*Implementação:\*\* \`\`\`typescript export class SkillExecutor { constructor( private sandbox: Sandbox, private referenceResolver: ReferenceResolver, private cache: CacheManager, private logger: Logger ) {} async execute( skillId: string, input: any, context: ExecutionContext ): Promise\ { const skill \= await this.loadSkill(skillId); // Check cache const cacheKey \= this.generateCacheKey(skillId, input); if (\!context.skipCache) { const cached \= await this.cache.get(cacheKey); if (cached) return { ...cached, cached: true }; } // Pre-execution const validatedInput \= this.validateInput(skill, input); const executionContext \= this.buildContext(skill, context); // Execute in sandbox const startTime \= Date.now(); try { const result \= await this.sandbox.run({ code: skill.compiled.code, context: executionContext, timeout: skill.timeout, memory: skill.memory }); // Post-execution const duration \= Date.now() \- startTime; const output \= this.validateOutput(skill, result); // Cache result await this.cache.set(cacheKey, output, skill.cacheConfig); // Log execution await this.logExecution(skill, input, output, duration); return { success: true, data: output, duration, executionId: context.executionId }; } catch (error) { // Handle error if (skill.retries \> 0 && this.isRetryable(error)) { return this.retry(skillId, input, context, skill.retries); } // Fallback if (skill.fallbackSkillId) { return this.execute(skill.fallbackSkillId, input, context); } return { success: false, error: this.sanitizeError(error), duration: Date.now() \- startTime }; } } private buildContext(skill: Skill, parentContext: ExecutionContext): ExecutionContext { return { ...parentContext, skillId: skill.id, tenantId: skill.tenantId, variables: { input: parentContext.input, config: skill.config, secrets: this.loadSecrets(skill.tenantId) }, skills: { execute: (ref: string, params: any) \=\> this.executeReference(ref, params, parentContext) }, kg: { query: (cypher: string, params: any) \=\> this.kg.query(cypher, params) }, tools: { call: (toolName: string, params: any) \=\> this.callTool(toolName, params) } }; } } \`\`\` \*\*Sandbox:\*\* \`\`\`typescript export class Sandbox { private vm: NodeVM; constructor(config: SandboxConfig) { this.vm \= new NodeVM({ timeout: config.timeout, sandbox: config.context, require: { external: config.allowedModules || \[\], builtin: \['path', 'util', 'crypto'\], root: './', mock: this.buildMocks() }, compiler: (code: string) \=\> this.compile(code) }); } async run(options: RunOptions): Promise\ { const script \= new VMScript(options.code, { filename: options.filename || 'skill.js' }); const fn \= this.vm.run(script); if (typeof fn \=== 'function') { return await fn(options.context); } return fn; } private buildMocks(): Record\ { return { fs: { readFile: (path: string) \=\> { throw new Error('fs.readFile blocked'); }, writeFile: () \=\> { throw new Error('fs.writeFile blocked'); } }, child\_process: new Proxy({}, { get: () \=\> { throw new Error('child\_process blocked'); } }) }; } } \`\`\` \--- \#\#\# 2.6 Módulo: Visual Studio (Frontend) \*\*Arquivo:\*\* \`client/src/modules/skill-fabric/visual-studio/components/Canvas.tsx\` \*\*Componentes:\*\* \`\`\`typescript // Canvas principal export const Canvas: React.FC\ \= ({ skill, onChange }) \=\> { const \[nodes, setNodes\] \= useState\(skill.content.nodes); const \[edges, setEdges\] \= useState\(skill.content.edges); const \[selectedNode, setSelectedNode\] \= useState\(null); const { dragRef, dropRef, isDragging } \= useDragDrop({ onDrop: (item, position) \=\> { const newNode \= createNode(item.type, position); setNodes(\[...nodes, newNode\]); } }); const onConnect \= (connection: Connection) \=\> { const newEdge \= createEdge(connection); if (validateConnection(newEdge, nodes, edges)) { setEdges(\[...edges, newEdge\]); } }; const onNodeUpdate \= (nodeId: string, updates: Partial\) \=\> { setNodes(nodes.map(n \=\> n.id \=== nodeId ? { ...n, ...updates } : n)); }; const onCompile \= async () \=\> { const compiled \= await compileVisualSkill({ nodes, edges }); onChange({ ...skill, content: { nodes, edges }, compiled }); }; return ( \
\ \
\ \ setSelectedNode(node)} nodeTypes={customNodeTypes} edgeTypes={customEdgeTypes} fitView \> \ \ \ \ {selectedNode && ( \ onNodeUpdate(selectedNode.id, updates)} onClose={() \=\> setSelectedNode(null)} /\> )} \ \ ); }; // Tipos de nós disponíveis const nodeTypes \= { trigger: TriggerNode, action: ActionNode, condition: ConditionNode, loop: LoopNode, transform: TransformNode, output: OutputNode }; \`\`\` \--- \#\#\# 2.7 Módulo: Code IDE (Frontend) \*\*Arquivo:\*\* \`client/src/modules/skill-fabric/code-ide/components/MonacoEditor.tsx\` \*\*Implementação:\*\* \`\`\`typescript export const SkillCodeEditor: React.FC\ \= ({ skill, onChange }) \=\> { const editorRef \= useRef\(); const \[decorations, setDecorations\] \= useState\(\[\]); // Configurar IntelliSense para referências /xxx/ useEffect(() \=\> { if (\!editorRef.current) return; const disposable \= monaco.languages.registerCompletionItemProvider( 'typescript', { triggerCharacters: \['/'\], provideCompletionItems: async (model, position) \=\> { const lineContent \= model.getLineContent(position.lineNumber); const beforeCursor \= lineContent.substring(0, position.column \- 1); if (beforeCursor.match(/\\/(\\w\*)$/)) { const suggestions \= await fetchReferenceSuggestions( beforeCursor, skill.tenantId ); return { suggestions: suggestions.map(s \=\> ({ label: s.fullReference, kind: monaco.languages.CompletionItemKind.Reference, insertText: s.fullReference, detail: s.description, documentation: { value: s.documentation } })) }; } return { suggestions: \[\] }; } } ); return () \=\> disposable.dispose(); }, \[skill.tenantId\]); // Real-time validation const onValidate \= async (code: string) \=\> { const markers \= await validateCode(code); monaco.editor.setModelMarkers( editorRef.current\!.getModel()\!, 'skill-validator', markers.map(m \=\> ({ severity: monaco.MarkerSeverity\[m.severity\], message: m.message, startLineNumber: m.line, startColumn: m.column, endLineNumber: m.endLine || m.line, endColumn: m.endColumn || m.column \+ 1 })) ); }; return ( \
\ executeSkill(skill.id, editorRef.current\!.getValue())} onDebug={() \=\> startDebugger(skill.id)} onFormat={() \=\> formatCode(editorRef.current\!)} /\> \ { editorRef.current \= editor; configureSkillEditor(editor); }} options={{ minimap: { enabled: true }, folding: true, automaticLayout: true, suggestOnTriggerCharacters: true, quickSuggestions: true }} /\> \ \ ); }; \`\`\` \--- \#\#\# 2.8 Módulo: Referências (reference) \*\*Arquivo:\*\* \`client/src/shared/utils/referenceParser.ts\` \*\*Parser:\*\* \`\`\`typescript export class ReferenceParser { // Padrão: /type:namespace/path?query private static readonly PATTERN \= /\\/(skill|kg|file|data|var|tool|agent)(?::(system|tenant|company|user))?\\/(\[a-zA-Z0-9\_\\/\\.\\-:\]+)(?:\\?(\[^\\s\]+))?/g; parse(text: string): Reference\[\] { const refs: Reference\[\] \= \[\]; let match; while ((match \= ReferenceParser.PATTERN.exec(text)) \!== null) { const \[fullMatch, type, namespace, path, queryString\] \= match; refs.push({ type: type as ReferenceType, namespace: namespace as ReferenceNamespace, path, queryParams: queryString ? parseQueryString(queryString) : undefined, fullMatch, position: { start: match.index, end: match.index \+ fullMatch.length } }); } return refs; } async resolveReferences( refs: Reference\[\], context: ResolutionContext ): Promise\ { return Promise.all(refs.map(ref \=\> this.resolve(ref, context))); } private async resolve(ref: Reference, context: ResolutionContext): Promise\ { const resolvers: Record\ \= { skill: new SkillResolver(), kg: new KGResolver(), file: new FileResolver(), data: new DataResolver(), var: new VariableResolver(), tool: new ToolResolver(), agent: new AgentResolver() }; const resolver \= resolvers\[ref.type\]; const value \= await resolver.resolve(ref, context); return { ...ref, resolved: true, value, metadata: await resolver.getMetadata(ref) }; } } \`\`\` \--- \#\# 3\. COMANDOS DE IMPLEMENTAÇÃO PARA CLAUDE CODE \#\#\# 3.1 Setup Inicial \`\`\`bash \# Criar estrutura de diretórios mkdir \-p server/modules/skill-fabric/src/{api/{routes,controllers},core/{skill,compiler,validator,executor,lifecycle},types} mkdir \-p client/src/modules/skill-fabric/{visual-studio/{components,hooks},code-ide/{components,templates},markdown-studio/{components,parser},shared/{components,utils}} \# Instalar dependências backend cd server/modules/skill-fabric npm init \-y npm install typescript @types/node ts-node express zod uuid vm2 antlr4ts npm install \-D jest @types/jest supertest \# Instalar dependências frontend cd ../../../client npm install @monaco-editor/react react-flow-renderer @types/react-flow-renderer npm install antlr4ts antlr4ts-cli \# Gerar parser ANTLR npx antlr4ts \-visitor \-listener server/modules/skill-fabric/src/core/compiler/grammar/SkillLexer.g4 npx antlr4ts \-visitor \-listener server/modules/skill-fabric/src/core/compiler/grammar/SkillParser.g4 \`\`\` \#\#\# 3.2 Implementação por Fase \*\*Fase 1: Core API e Entity\*\* \`\`\`bash \# Gerar arquivos base claude generate server/modules/skill-fabric/src/core/skill/Skill.entity.ts claude generate server/modules/skill-fabric/src/core/skill/Skill.repository.ts claude generate server/modules/skill-fabric/src/api/routes/skills.routes.ts claude generate server/modules/skill-fabric/src/api/controllers/skills.controller.ts \`\`\` \*\*Fase 2: Compiladores\*\* \`\`\`bash claude generate server/modules/skill-fabric/src/core/compiler/VisualCompiler.ts claude generate server/modules/skill-fabric/src/core/compiler/CodeCompiler.ts claude generate server/modules/skill-fabric/src/core/compiler/MarkdownCompiler.ts \`\`\` \*\*Fase 3: Validador\*\* \`\`\`bash claude generate server/modules/skill-fabric/src/core/validator/ValidationPipeline.ts claude generate server/modules/skill-fabric/src/core/validator/rules/SyntaxRule.ts claude generate server/modules/skill-fabric/src/core/validator/rules/SecurityRule.ts \`\`\` \*\*Fase 4: Executor\*\* \`\`\`bash claude generate server/modules/skill-fabric/src/core/executor/SkillExecutor.ts claude generate server/modules/skill-fabric/src/core/executor/Sandbox.ts claude generate server/modules/skill-fabric/src/core/executor/ReferenceResolver.ts \`\`\` \*\*Fase 5: Frontend Visual\*\* \`\`\`bash claude generate client/src/modules/skill-fabric/visual-studio/components/Canvas.tsx claude generate client/src/modules/skill-fabric/visual-studio/components/NodePalette.tsx claude generate client/src/modules/skill-fabric/visual-studio/hooks/useDragDrop.ts \`\`\` \*\*Fase 6: Frontend Code\*\* \`\`\`bash claude generate client/src/modules/skill-fabric/code-ide/components/MonacoEditor.tsx claude generate client/src/modules/skill-fabric/code-ide/components/IntelliSenseProvider.ts claude generate client/src/modules/skill-fabric/code-ide/templates/skill-template.ts \`\`\` \--- \#\# 4\. TESTES \#\#\# 4.1 Estrutura de Testes \`\`\` tests/ ├── unit/ │ ├── skill.entity.test.ts │ ├── visual-compiler.test.ts │ ├── code-compiler.test.ts │ ├── markdown-compiler.test.ts │ ├── validation-pipeline.test.ts │ └── skill-executor.test.ts ├── integration/ │ ├── api.test.ts │ ├── compile-execute.test.ts │ └── reference-resolution.test.ts └── e2e/ ├── create-skill-flow.test.ts ├── visual-editor.test.ts └── marketplace.test.ts \`\`\` \#\#\# 4.2 Exemplo de Teste \`\`\`typescript // tests/unit/skill.entity.test.ts describe('Skill Entity', () \=\> { it('should create skill with valid props', () \=\> { const skill \= new Skill({ name: 'Test Skill', slug: 'test\_skill', type: 'code', content: { sourceCode: 'export default () \=\> {}' }, tenantId: 1 }); expect(skill.id).toBeDefined(); expect(skill.status).toBe('draft'); expect(skill.version).toBe('0.0.1'); }); it('should validate slug format', () \=\> { expect(() \=\> new Skill({ slug: 'invalid slug' })).toThrow(); expect(() \=\> new Skill({ slug: 'valid\_slug' })).not.toThrow(); }); it('should compile skill', async () \=\> { const skill \= createTestSkill('code'); const compiled \= await skill.compile(); expect(compiled.code).toBeDefined(); expect(compiled.ast).toBeDefined(); expect(compiled.dependencies).toBeInstanceOf(Array); }); }); \`\`\` \--- \#\# 5\. MIGRAÇÃO E DEPLOY \#\#\# 5.1 Migração de Dados \`\`\`typescript // scripts/migrate-skills.ts export async function migrateLegacySkills() { const legacySkills \= await db.query('SELECT \* FROM old\_automations'); for (const old of legacySkills) { const skill \= new Skill({ name: old.name, slug: generateSlug(old.name), type: inferType(old), content: convertContent(old), tenantId: old.tenant\_id, status: 'production' }); await skillRepo.save(skill); } } \`\`\` \#\#\# 5.2 Feature Flags \`\`\`typescript // Configuração gradual const featureFlags \= { 'skill-fabric.enabled': true, 'skill-fabric.visual-editor': true, 'skill-fabric.code-ide': true, 'skill-fabric.markdown-studio': false, // Beta 'skill-fabric.marketplace': false // Próxima release }; \`\`\` \--- \*\*Fim do Plano Técnico\*\* \`\`\` \--- Este plano técnico está pronto para gerar comandos no Claude Code. Ele contém: ✅ \*\*Estrutura de diretórios\*\* completa ✅ \*\*Funções e métodos\*\* detalhados para cada módulo ✅ \*\*Interfaces e tipos\*\* TypeScript ✅ \*\*Comandos de implementação\*\* por fase ✅ \*\*Testes\*\* estruturados \*\*Para usar no Claude Code:\*\* \`\`\`bash \# Exemplo de comando claude generate server/modules/skill-fabric/src/core/skill/Skill.entity.ts \--spec "Plano Técnico Skill Fabric v1.0" \`\`\` Quer que eu gere comandos específicos para algum módulo ou adicione mais detalhes de implementação?