@dot-agent/cli 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/plan.md DELETED
@@ -1,665 +0,0 @@
1
- # dot-agent CLI — Spec V1
2
-
3
- ## Repositório
4
-
5
- ```
6
- https://github.com/dot-agent-spec/dot-agent
7
- ```
8
-
9
- Publicado no npm como `dot-agent` (bin: `dot-agent`).
10
-
11
- ## Referência Canônica
12
-
13
- A estrutura do arquivo `.agent` (ZIP) e o formato do `aboutme.json` seguem a especificação em [`file structure.md`](./file%20structure.md). O CLI implementa a validação, empacotamento e execução dessa especificação.
14
-
15
- ---
16
-
17
- ## Ecossistema de Dependências
18
-
19
- O CLI **não reimplementa parsing nem execução de FSM**. Consome os pacotes já existentes na org:
20
-
21
- | Pacote | Repo | Papel no CLI |
22
- |---|---|---|
23
- | `@dot-agent/tree-sitter` | `dot-agent-spec/tree-sitter` v0.3.2+ | Parse + lint sintaxe de `.description` e `.behavior` via WASM |
24
- | `@dot-agent/kernel-dsl` | `dot-agent-spec/kernel-dsl` | Carregamento de `.behavior` (usa tree-sitter internamente + valida semântica) + execução FSM ao runtime |
25
-
26
- **Tree-sitter** exporta `agentWasmPath` e `behaviorWasmPath` — caminhos absolutos para os `.wasm` pré-compilados em `dist/`:
27
- - `tree-sitter-agent.wasm` para `.description` / `.type`
28
- - `tree-sitter-behavior.wasm` para `.behavior` (sintaxe)
29
-
30
- O CLI carrega ambos via `web-tree-sitter` (já WASM, sem binding C nativo).
31
-
32
- **Kernel-dsl** (`AgentDSLKernel`) é instanciado no `pack` (para validação semântica via `load_behavior()`) e no `run` (para execução FSM). Internamente, o kernel:
33
- - Usa tree-sitter para parse robusto
34
- - Valida semântica (referências de estados, memory, etc)
35
- - Executa como FSM (intents, transitions, effects)
36
-
37
- Se `load_behavior()` retorna `parse_error` effect, o lint mapeia para E006.
38
-
39
- ---
40
-
41
- ## Visão Geral
42
-
43
- O `dot-agent` expõe dois pontos de entrada com a mesma base de código:
44
-
45
- | Ponto de entrada | Quem usa | Como | Status |
46
- |---|---|---|---|
47
- | `index.ts` (API JS) | Electron / app | `import { run, pack, unpack, init } from 'dot-agent'` | ✅ Implementado |
48
- | `cli.ts` (bin) | Terminal / npx | `npx dot-agent <comando>` | ✅ Implementado |
49
-
50
- O `cli.ts` é um wrapper fino: parse de args → chama a mesma função de `index.ts`.
51
-
52
- ---
53
-
54
- ## Estrutura do Pacote
55
-
56
- ```
57
- dot-agent/
58
- ├── src/
59
- │ ├── commands/
60
- │ │ ├── init.ts ← gera scaffold
61
- │ │ ├── pack.ts ← valida + empacota → .agent
62
- │ │ ├── unpack.ts ← extrai .agent → fontes
63
- │ │ └── run.ts ← carrega .agent, retorna AgentContext
64
- │ ├── core/
65
- │ │ ├── lint.ts ← orquestra validação (tree-sitter + kernel-dsl)
66
- │ │ ├── zip.ts ← leitura/escrita ZIP (jszip)
67
- │ │ ├── envelope.ts ← parse/geração do aboutme.json
68
- │ │ ├── id.ts ← geração e parsing de id (namespace/name:version~digest)
69
- │ │ └── types.ts ← validação e geração de types.json (tipos públicos)
70
- │ ├── index.ts ← export público da API
71
- │ └── cli.ts ← bin entry point
72
- ├── tests/
73
- ├── package.json
74
- └── tsconfig.json
75
- ```
76
-
77
- ---
78
-
79
- ## package.json (estrutura relevante)
80
-
81
- ```json
82
- {
83
- "name": "dot-agent",
84
- "type": "module",
85
- "main": "dist/index.js",
86
- "types": "dist/index.d.ts",
87
- "bin": {
88
- "dot-agent": "dist/cli.js"
89
- },
90
- "exports": {
91
- ".": {
92
- "import": "./dist/index.js",
93
- "require": "./dist/index.cjs"
94
- }
95
- },
96
- "engines": {
97
- "node": ">=18.0.0"
98
- },
99
- "dependencies": {
100
- "@dot-agent/tree-sitter": "^0.3.2",
101
- "@dot-agent/kernel-dsl": "latest",
102
- "jszip": "^3.10.1",
103
- "web-tree-sitter": "^0.25.0"
104
- }
105
- }
106
- ```
107
-
108
- **Nota:** `"type": "module"` é obrigatório pois `@dot-agent/kernel-dsl` é ESM-only. Requer Node 18+.
109
-
110
- ---
111
-
112
- ## WASM Initialization
113
-
114
- O CLI deve inicializar tree-sitter e kernel-dsl uma vez, antes de qualquer lint ou run. Ambas as bibliotecas fornecem WASM via `fetch()` nativo (Node 18+).
115
-
116
- ### Tree-sitter
117
-
118
- O pacote `@dot-agent/tree-sitter` exporta **apenas paths**, não instâncias Parser:
119
-
120
- ```typescript
121
- import Parser from 'web-tree-sitter'
122
- import { agentWasmPath, behaviorWasmPath } from '@dot-agent/tree-sitter'
123
-
124
- // Chamado uma vez, preferencialmente em core/lint.ts
125
- async function initTreeSitter() {
126
- await Parser.init()
127
- const agentLang = await Parser.Language.load(agentWasmPath)
128
- const behaviorLang = await Parser.Language.load(behaviorWasmPath)
129
- return { agentParser: new Parser(), behaviorParser: new Parser(), agentLang, behaviorLang }
130
- }
131
- ```
132
-
133
- Após `initTreeSitter()`, as instâncias são **reutilizadas** via `parser.setLanguage()`:
134
-
135
- ```typescript
136
- const { agentParser, agentLang } = await initTreeSitter()
137
- agentParser.setLanguage(agentLang)
138
- const tree = agentParser.parse(descriptionText)
139
- ```
140
-
141
- ### Kernel-dsl
142
-
143
- O pacote `@dot-agent/kernel-dsl` exporta `{ AgentDSLKernel, init }` — `init()` é async, sem parâmetros, idempotente:
144
-
145
- ```typescript
146
- import { AgentDSLKernel, init as initKernel } from '@dot-agent/kernel-dsl'
147
-
148
- await initKernel() // carrega WASM (~1.7MB via fetch)
149
- const kernel = new AgentDSLKernel()
150
- ```
151
-
152
- Se `new AgentDSLKernel()` for chamado antes de `initKernel()`, lança erro. Seguro chamar `initKernel()` múltiplas vezes — é idempotente.
153
-
154
- ### Padrão para o CLI
155
-
156
- Em `core/lint.ts`, implementar lazy singleton:
157
-
158
- ```typescript
159
- let _initialized = false
160
-
161
- async function ensureWasmInit() {
162
- if (_initialized) return
163
- await Parser.init()
164
- await initKernel()
165
- _initialized = true
166
- }
167
-
168
- // Exportado
169
- export async function createLinter() {
170
- await ensureWasmInit()
171
- // ... retorna funções de lint
172
- }
173
- ```
174
-
175
- ---
176
-
177
- ## Mapeamento de Erros (tree-sitter → lint codes)
178
-
179
- Tree-sitter retorna uma AST onde erros são nós nomeados `ERROR` ou nodes com `isMissing === true`. O CLI coleta erros via:
180
-
181
- ```typescript
182
- function collectSyntaxErrors(node: Parser.SyntaxNode): Parser.SyntaxNode[] {
183
- const errors: Parser.SyntaxNode[] = []
184
- if (node.isError || node.isMissing) errors.push(node)
185
- for (const child of node.children) errors.push(...collectSyntaxErrors(child))
186
- return errors
187
- }
188
- ```
189
-
190
- **Mapeamento para lint codes:**
191
-
192
- - Erros em `.description` (tree-sitter):
193
- - Campo obrigatório ausente (ex: `domain`, `name`, `version`) → E001
194
- - Campo obrigatório em `capability` (ex: `type`) ausente → E002
195
- - `.description` arquivo não encontrado → E003
196
-
197
- - Erros em `.behavior` (tree-sitter sintaxe):
198
- - Erro de sintaxe DSL (state, on, transition, if, etc) → E004
199
- - `.behavior` arquivo não encontrado → E007
200
-
201
- - Erros do kernel (`load_behavior()` effects):
202
- - `parse_error` effect com message → E006
203
- - Estado referenciado não existe (pode ser detectado via `get_graph()` comparado com `on intent "..."`) → E005
204
-
205
- - Erros manuais:
206
- - Arquivo referenciado em `files.json` não existe → E008
207
-
208
- ---
209
-
210
- ## Estrutura do `.agent` (ZIP)
211
-
212
- Conforme especificado em [`file structure.md`](./file%20structure.md):
213
-
214
- ```
215
- meu-agente.agent (ZIP)
216
-
217
- │ # Metadados gerados — Layer 2 🤖
218
- ├── .agent/
219
- │ ├── aboutme.json ← sempre presente
220
- │ ├── types.json ← quando há tipos públicos
221
- │ └── files.json ← quando há fontes
222
-
223
- │ # Comportamento — Layer 1 👤
224
- ├── agent.description
225
- ├── agent.behavior
226
- ├── behaviors/
227
- │ └── *.behavior
228
- ├── guides/
229
- │ └── *.md
230
- ├── knowledge/
231
- │ └── *.md
232
- └── SOUL.md
233
- ```
234
-
235
- O `aboutme.json` é o único arquivo obrigatório. Os fontes ficam na raiz do ZIP. O `files.json` referencia arquivos relativos à raiz:
236
-
237
- ```json
238
- {
239
- "description": "agent.description",
240
- "behavior": "agent.behavior",
241
- "behaviors": ["behaviors/*.behavior"],
242
- "guides": ["guides/*.md"],
243
- "knowledge": ["knowledge/*.md"]
244
- }
245
- ```
246
-
247
- ### Exemplo concreto de `aboutme.json` V1
248
-
249
- ```json
250
- {
251
- "schemaVersion": "dot-agent/1.0",
252
- "id": "entelekheia.ai/doctor:v1.0~a1b2c3d",
253
- "name": "Doctor",
254
- "description": "Agente médico para triagem inicial de pacientes.",
255
- "version": "v1.0",
256
- "domain": "entelekheia.ai",
257
- "license": "Apache-2.0",
258
- "persona": "SOUL.md",
259
- "compiler": "dot-agent/1.0.0",
260
- "commit": "a1b2c3d",
261
- "skills": [
262
- { "id": "TriagePatient", "description": "Triagem inicial de pacientes" }
263
- ],
264
- "requires": ["UserProfile"],
265
- "integrity": {
266
- "sha256": "e3b0c44298fc1c149afbaf8b2b...",
267
- "files": ".agent/files.json"
268
- }
269
- }
270
- ```
271
-
272
- **Notas:**
273
- - `purpose` omitido no V1 (mapeado futuramente por `builder.agent` + LLM)
274
- - `integrity.types` só aparece quando há tipos públicos
275
- - `compiler` é a versão do dot-agent CLI que gerou o pacote
276
- - `commit` fica ausente se o projeto não usa Git
277
-
278
- ---
279
-
280
- ## API Pública (`index.ts`)
281
-
282
- ```typescript
283
- export function init(options: InitOptions): Promise<InitResult>
284
- export function pack(options: PackOptions): Promise<PackResult>
285
- export function unpack(options: UnpackOptions): Promise<UnpackResult>
286
- export function run(options: RunOptions): Promise<AgentContext>
287
- ```
288
-
289
- ---
290
-
291
- ## Comandos
292
-
293
- ---
294
-
295
- ### ✅ `dot-agent init`
296
-
297
- Gera o scaffold completo do projeto.
298
- Não é interativo na V1 — o desenvolvedor edita os arquivos gerados.
299
-
300
- **CLI:**
301
- ```
302
- dot-agent init [--name <nome>] [--domain <domínio>] [--dir <pasta>]
303
- ```
304
-
305
- **API:**
306
- ```typescript
307
- interface InitOptions {
308
- name?: string // padrão: nome da pasta atual
309
- domain?: string // padrão: "example.com" (⚠ W003 no pack)
310
- dir?: string // padrão: process.cwd()
311
- }
312
-
313
- interface InitResult {
314
- dir: string
315
- files: string[] // lista de arquivos criados
316
- }
317
- ```
318
-
319
- **Arquivos gerados:**
320
- ```
321
- <dir>/
322
- ├── agent.description
323
- ├── agent.behavior
324
- ├── behaviors/ (.gitkeep)
325
- ├── guides/ (.gitkeep)
326
- ├── knowledge/ (.gitkeep)
327
- ├── SOUL.md
328
- ├── AGENTS.md (vazio — para documentação de dependências)
329
- ├── README.md
330
- └── LICENSE (Apache 2.0)
331
- ```
332
-
333
- **Templates:**
334
-
335
- `agent.description`:
336
- ```
337
- agent {{Name}}
338
- domain {{domain}}
339
- license Apache-2.0
340
-
341
- description
342
- {{Describe what this agent does.}}
343
-
344
- behavior agent.behavior
345
-
346
- capabilities
347
- {{ActionName}} "{{Describe this capability}}"
348
- ```
349
-
350
- `agent.behavior`:
351
- ```
352
- state init
353
- next responsive
354
-
355
- state responsive
356
- goal "{{Help the user with their task.}}"
357
- interact
358
- on intent "start" next responsive
359
- ```
360
-
361
- `SOUL.md`: Texto livre sobre persona/voz do agente. Placeholder:
362
- ```markdown
363
- # {{Name}} — Persona
364
-
365
- ## Voice and Tone
366
-
367
- {{Describe the agent's voice, personality, and communication style.}}
368
- ```
369
-
370
- `README.md`: Título + descrição + seção de uso (placeholders).
371
-
372
- **Comportamento:**
373
- - Aborta se o diretório já contiver `agent.description`
374
- - Não preenche `version` no `.description` — versão é resolvida em tempo de `pack`
375
- - Developer edita os templates antes de chamar `pack`
376
-
377
- ---
378
-
379
- ### ✅ `dot-agent pack`
380
-
381
- Valida a DSL e empacota os fontes em um arquivo `.agent` (ZIP).
382
-
383
- **CLI:**
384
- ```
385
- dot-agent pack [--dir <pasta>] [--out <arquivo.agent>] [--commit <hash>] [--version <tag>]
386
- ```
387
-
388
- **API:**
389
- ```typescript
390
- interface PackOptions {
391
- dir?: string
392
- out?: string // padrão: <name>.agent no dir
393
- commit?: string // override para git rev-parse --short HEAD
394
- version?: string // override para git describe --tags --abbrev=0
395
- }
396
-
397
- interface PackResult {
398
- path: string
399
- id: string // namespace/name:version~digest (conforme file structure.md)
400
- warnings: LintMessage[]
401
- }
402
-
403
- interface LintMessage {
404
- file: string
405
- line: number
406
- col: number
407
- severity: 'error' | 'warning'
408
- code: string
409
- message: string
410
- }
411
- ```
412
-
413
- **Resolução de `version` e `commit`:**
414
-
415
- | Campo | Prioridade |
416
- |---|---|
417
- | `version` | 1. `--version <tag>` 2. `git describe --tags --abbrev=0` 3. Interativo: `Agent version (e.g. v1.0):` |
418
- | `commit` | 1. `--commit <hash>` 2. `git rev-parse --short HEAD` 3. Ausente (não bloqueia pack) |
419
-
420
- Se Git não estiver disponível e versão não for passada, o pack pergunta interativamente.
421
-
422
- **Fluxo interno:**
423
- 1. Localiza `agent.description` e `agent.behavior` no `dir`
424
-
425
- **Lint do `.description`:**
426
- 2. Parse via `@dot-agent/tree-sitter` (WASM)
427
- 3. Valida campos obrigatórios: `domain`, `name`, `version`, `capability` com `type`
428
- 4. Valida semântica: tipos bem-formados, nomes únicos, referências válidas → mapeia erros para E001
429
-
430
- **Lint do `.behavior`:**
431
- 5. Parse via `@dot-agent/tree-sitter` (WASM)
432
- 6. Valida sintaxe DSL (if/on/state/transition/etc) → mapeia erros para E007
433
- 7. Carrega kernel: `AgentDSLKernel.load_behavior()` para validação semântica
434
- 8. Se retorna `parse_error`, mapeia para E006
435
- 9. Extrai grafo (via `kernel.get_graph()`) para detectar states sem transições → W001
436
-
437
- 10. **Se houver qualquer `error`: aborta, não gera `.agent`**
438
- 11. Warnings incluídos no `PackResult` mas não bloqueiam
439
- 12. Coleta todos os arquivos: `agent.description`, `agent.behavior`, `SOUL.md` (opt), `behaviors/`, `guides/`, `knowledge/`
440
- 13. Computa SHA-256 do conteúdo do ZIP → extrai primeiros 8 chars → `<digest>`
441
- 14. Gera `id`: `<domain>/<name>:<version>~<digest>` (ex: `entelekheia.ai/doctor:v1.0~a1b2c3d`)
442
- 15. Monta `.agent/aboutme.json` com `id`, `schemaVersion`, `compiler`, `commit`, `integrity`, etc (conforme file structure.md)
443
- 16. Monta `.agent/files.json` com mapa de fontes
444
- 17. Monta `.agent/types.json` (opcional, se agente expõe tipos públicos)
445
- 18. Cria ZIP:
446
- - Raiz: `.agent/aboutme.json`, `.agent/types.json` (opt), `.agent/files.json`
447
- - Raiz: todos os fontes
448
- 19. Salva como `<name>.agent`
449
-
450
- **Saída CLI (sucesso):**
451
- ```
452
- ✓ Lint passed (0 errors, 2 warnings)
453
- ⚠ agent.behavior:12:3 W001 state "idle" has no transitions
454
- ⚠ agent.description:2:1 W003 domain still has default value "example.com"
455
- ✓ Packed → ./doctor.agent
456
- ID: entelekheia.ai/doctor:v1.0~a1b2c3d
457
- ```
458
-
459
- **Saída CLI (erro):**
460
- ```
461
- ✗ Lint failed (2 errors)
462
- ✗ agent.description:5:1 E001 missing required field: domain
463
- ✗ agent.behavior:23:7 E006 parse error: unknown state reference "triage_v2"
464
- Pack aborted.
465
- ```
466
-
467
- ---
468
-
469
- ### ✅ `dot-agent unpack`
470
-
471
- Extrai um `.agent` e restaura os fontes.
472
-
473
- **CLI:**
474
- ```
475
- dot-agent unpack <arquivo.agent> [--out <pasta>] [--force]
476
- ```
477
-
478
- **API:**
479
- ```typescript
480
- interface UnpackOptions {
481
- file: string
482
- out?: string // padrão: ./<name>/ no cwd
483
- force?: boolean // sobrescreve se pasta já existir
484
- }
485
-
486
- interface UnpackResult {
487
- dir: string
488
- id: string // extraído do aboutme.json
489
- files: string[]
490
- aboutme: object // conteúdo do aboutme.json
491
- }
492
- ```
493
-
494
- **Fluxo interno:**
495
- 1. Valida se arquivo `.agent` é ZIP válido (magic bytes)
496
- 2. Valida ZIP bomb (soma descompactado; aborta se > 500 MB ou ratio > 100×)
497
- 3. Lê `.agent/aboutme.json` → valida e extrai `id`
498
- 4. Extrai todos os arquivos da raiz para `out/<arquivo>`
499
- 5. Aborta se `out` já existir, a menos que `--force`
500
- 6. Restaura estrutura de pastas original
501
-
502
- **Comportamento:**
503
- - Valida integridade: lê `integrity.sha256` e compara com ZIP recompactado
504
- - Se hash não bate, avisa mas continua (⚠ —verbose mostra detalhes)
505
- - Extrai apenas fontes por padrão
506
- - `--verbose` exibe também o conteúdo do `aboutme.json`
507
-
508
- ---
509
-
510
- ### ✅ `dot-agent run`
511
-
512
- Carrega um `.agent` (ou pasta de fontes) e retorna o `AgentContext`.
513
-
514
- No terminal é usado para smoke-test. O Electron usa a API.
515
-
516
- **CLI:**
517
- ```
518
- dot-agent run <arquivo.agent | pasta>
519
- ```
520
-
521
- **API:**
522
- ```typescript
523
- interface RunOptions {
524
- source: string // caminho do .agent ou pasta com fontes
525
- }
526
-
527
- interface FileEntry {
528
- path: string // caminho relativo
529
- content: string // conteúdo em memória
530
- }
531
-
532
- // AgentContext é EventEmitter + objeto com tudo parsed
533
- interface AgentContext extends EventEmitter {
534
- id: string // namespace/name:version~digest
535
- description: ParsedDescription // AST parseada pelo tree-sitter
536
- behavior: ParsedBehavior // AST parseada pelo kernel-dsl
537
- kernel: AgentDSLKernel // instância pronta para executar
538
- files: {
539
- soul?: string
540
- guides: FileEntry[]
541
- knowledge: FileEntry[]
542
- behaviors: FileEntry[]
543
- }
544
- aboutme: object // conteúdo do aboutme.json
545
-
546
- // Eventos emitidos durante o carregamento:
547
- // 'progress' → { step: string, pct: number }
548
- // 'warning' → LintMessage
549
- // 'ready' → AgentContext
550
- // 'error' → Error
551
- }
552
- ```
553
-
554
- **Fluxo interno:**
555
- 1. Emite `progress` { step: 'opening', pct: 0 }
556
- 2. Detecta se é `.agent` (ZIP) ou pasta de fontes
557
- 3. Se `.agent`: valida ZIP bomb (soma descompactado; aborta se > 500 MB ou ratio > 100×)
558
- 4. Emite `progress` { step: 'parsing', pct: 30 }
559
- 5. Lê `.agent/aboutme.json` (se ZIP) → extrai `id`
560
- 6. Lê `agent.description`; parse via `@dot-agent/tree-sitter` → `ParsedDescription`
561
- 7. Lê `agent.behavior`; parse via `@dot-agent/tree-sitter` (sintaxe)
562
- 8. Carrega kernel: `AgentDSLKernel.load_behavior()` (tree-sitter + semântica + FSM)
563
- 9. Emite warnings do lint se houver
564
- 10. Emite `progress` { step: 'loading-files', pct: 60 }
565
- 11. Carrega guides, knowledge, behaviors em memória
566
- 12. Emite `progress` { step: 'ready', pct: 100 }
567
- 13. Emite `ready` e resolve a Promise com o `AgentContext`
568
-
569
- **O runtime recebe o `AgentContext` e:**
570
- - Usa `context.kernel` (já carregado) para enviar intents via `send_intent()`
571
- - Usa `context.description` para montar system prompt do LLM
572
- - Usa `context.files.soul` e `context.files.guides` como contexto adicional
573
- - Reage aos `Effect[]` retornados pelo kernel para orquestrar estados
574
-
575
- ---
576
-
577
- ## Lint — Códigos de Erro V1
578
-
579
- | Código | Severidade | Detecção | Descrição |
580
- |---|---|---|---|
581
- | E001 | error | tree-sitter (`.description` lint) | Campo obrigatório ausente (`domain`, `name`, `version`) |
582
- | E002 | error | tree-sitter (`.description` lint) | Campo obrigatório ausente em `capability` (tipo ou descrição) |
583
- | E003 | error | manual | Arquivo `.description` ausente |
584
- | E004 | error | tree-sitter (`.behavior` lint) | Erro de sintaxe DSL (state, on, transition, if, etc) |
585
- | E005 | error | kernel-dsl (semântica) | Estado referenciado não existe (ex: `transition to unknown`) |
586
- | E006 | error | kernel-dsl (`load_behavior()`) | `parse_error` effect — erro semântico no FSM |
587
- | E007 | error | manual | Arquivo `.behavior` ausente |
588
- | E008 | error | manual | Arquivo referenciado em `files.json` não existe |
589
- | W001 | warning | kernel-dsl (`get_graph()`) | State sem transições de entrada ou saída |
590
- | W002 | warning | tree-sitter (`.behavior` lint) | Text block acima de 280 chars (goal, guide, teach) |
591
- | W003 | warning | tree-sitter (`.description` lint) | Campo `domain` ainda com valor padrão (`example.com`) |
592
-
593
- ---
594
-
595
- ## Relação com os Outros Pacotes da Org
596
-
597
- ```
598
- dot-agent (CLI / npm)
599
- ├── depende de → @dot-agent/tree-sitter (parse + lint ambos .description e .behavior, WASM)
600
- │ ├── dist/tree-sitter-agent.wasm (para .description / .type)
601
- │ └── dist/tree-sitter-behavior.wasm (para .behavior sintaxe)
602
-
603
- ├── depende de → @dot-agent/kernel-dsl (semântica + FSM + execução, WASM)
604
- │ └── usa tree-sitter internamente via Rust FFI
605
- │ para parse de .behavior com validação semântica
606
-
607
- ├── depende de → jszip (leitura/escrita ZIP)
608
-
609
- ├── produz → AgentContext
610
- │ ├── .id (namespace/name:version~digest)
611
- │ ├── .description (ParsedDescription via tree-sitter)
612
- │ ├── .behavior (ParsedBehavior, kernel carregado)
613
- │ ├── .kernel (AgentDSLKernel instância pronta)
614
- │ └── .files (guides, knowledge, behaviors em memória)
615
-
616
- ├── consumido por → Electron / Runtime (recebe AgentContext)
617
-
618
- └── não depende de → language-server (tooling de editor, LSP standalone)
619
- → vscode-dot-agent (extensão VSCode, cliente LSP)
620
- ```
621
-
622
- ---
623
-
624
- ## Estratégia de Migração para Rust (VNext)
625
-
626
- O pacote npm mantém a mesma API pública.
627
- Os binários nativos entram como `optionalDependencies`:
628
-
629
- ```json
630
- {
631
- "optionalDependencies": {
632
- "dot-agent-darwin-arm64": "1.x",
633
- "dot-agent-darwin-x64": "1.x",
634
- "dot-agent-linux-x64": "1.x",
635
- "dot-agent-win32-x64": "1.x"
636
- }
637
- }
638
- ```
639
-
640
- O `index.ts` detecta se o binário nativo está disponível e delega; caso contrário, cai no fallback JS. Zero breaking change para o Electron.
641
-
642
- ---
643
-
644
- ## Decisões V1
645
-
646
- | Decisão | Resultado |
647
- |---|---|
648
- | **Nome do pacote npm** | ✅ `dot-agent` — publicado como bin e import padrão |
649
- | **Estrutura do ZIP** | ✅ `.agent/` contém metadados; raiz contém fontes (conforme `file structure.md`) |
650
- | **Nomenclatura** | ✅ `id` no formato `namespace/name:version~digest` em vez de URN |
651
- | **Arquivo de metadados** | ✅ `aboutme.json` em `.agent/` (não `envelope.json` na raiz) |
652
- | **CLI module format** | ✅ ESM (`"type": "module"`) — obrigatório para `@dot-agent/kernel-dsl` |
653
- | **Campo `purpose`** | ✅ Omitido no V1 — mapeado futuramente por `builder.agent` + LLM |
654
- | **Resolução de `version`** | ✅ Prioridade: `--version`, git tags, interativo |
655
- | **Resolução de `commit`** | ✅ Prioridade: `--commit`, git HEAD, ausente (não bloqueia) |
656
-
657
- ---
658
-
659
- ## Questões Abertas VNext
660
-
661
- 1. **`inputModes` / `outputModes` em `skills[]`** — Runtime converte tipos estruturados para formato de transporte. A2A-compatibility completa ainda em exploração.
662
-
663
- 2. **`ui/` e `assets/` no ZIP** — Onde empacotar UI gerada? Na raiz do ZIP (fonts) ou em `.agent/` (artifacts gerados)? Exploração pendente.
664
-
665
- 3. **Tipagem de `requires[]`** — Hoje é string simples (`UserProfile`). Granularidade de ação (`Read:`, `Edit:`) e escopo (`resource.write`) em exploração para VNext.