31 KiB
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<ExecutionResult>;
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<ValidationResult> {
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<RuleResult> {
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<RuleResult> {
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<ExecutionResult> {
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<any> {
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<string, any> {
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<CanvasProps> = ({ skill, onChange }) => {
const [nodes, setNodes] = useState<Node[]>(skill.content.nodes);
const [edges, setEdges] = useState<Edge[]>(skill.content.edges);
const [selectedNode, setSelectedNode] = useState<Node | null>(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<Node>) => {
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 (
<div className="canvas-container" ref={dropRef}>
<CanvasToolbar onCompile={onCompile} onRun={onRun} />
\<div className="canvas-workspace"\>
\<NodePalette ref={dragRef} /\>
\<ReactFlow
nodes={nodes}
edges={edges}
onNodesChange={setNodes}
onEdgesChange={setEdges}
onConnect={onConnect}
onNodeClick={(\_, node) \=\> setSelectedNode(node)}
nodeTypes={customNodeTypes}
edgeTypes={customEdgeTypes}
fitView
\>
\<Background /\>
\<Controls /\>
\<MiniMap /\>
\</ReactFlow\>
{selectedNode && (
\<PropertyPanel
node={selectedNode}
onChange={(updates) \=\> onNodeUpdate(selectedNode.id, updates)}
onClose={() \=\> setSelectedNode(null)}
/\>
)}
\</div\>
\</div\>
);
};
// 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<EditorProps> = ({ skill, onChange }) => {
const editorRef = useRef<monaco.editor.IStandaloneCodeEditor>();
const [decorations, setDecorations] = useState<string[]>([]);
// 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 (
<div className="code-editor-container">
<EditorToolbar
onRun={() => executeSkill(skill.id, editorRef.current!.getValue())}
onDebug={() => startDebugger(skill.id)}
onFormat={() => formatCode(editorRef.current!)}
/>
\<MonacoEditor
height="100%"
language="typescript"
value={skill.content.sourceCode}
onChange={onChange}
onMount={(editor) \=\> {
editorRef.current \= editor;
configureSkillEditor(editor);
}}
options={{
minimap: { enabled: true },
folding: true,
automaticLayout: true,
suggestOnTriggerCharacters: true,
quickSuggestions: true
}}
/\>
\<ValidationPanel markers={decorations} /\>
\</div\>
);
};
```
---
### 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<ResolvedReference[]> {
return Promise.all(refs.map(ref => this.resolve(ref, context)));
}
private async resolve(ref: Reference, context: ResolutionContext): Promise<ResolvedReference> {
const resolvers: Record<ReferenceType, Resolver> = {
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?