@jaimevalasek/aioson 1.5.1 → 1.6.0

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.
Files changed (131) hide show
  1. package/README.md +6 -0
  2. package/docs/design-previews/aurora-command-ui-website.html +884 -0
  3. package/docs/design-previews/aurora-command-ui.html +682 -0
  4. package/docs/design-previews/bold-editorial-ui-website.html +658 -0
  5. package/docs/design-previews/bold-editorial-ui.html +717 -0
  6. package/docs/design-previews/clean-saas-ui-website.html +1202 -0
  7. package/docs/design-previews/clean-saas-ui.html +549 -0
  8. package/docs/design-previews/cognitive-core-ui-website.html +1009 -0
  9. package/docs/design-previews/cognitive-core-ui.html +463 -0
  10. package/docs/design-previews/glassmorphism-ui-website.html +572 -0
  11. package/docs/design-previews/glassmorphism-ui.html +886 -0
  12. package/docs/design-previews/index.html +699 -0
  13. package/docs/design-previews/interface-design-website.html +1187 -0
  14. package/docs/design-previews/interface-design.html +513 -0
  15. package/docs/design-previews/neo-brutalist-ui-website.html +621 -0
  16. package/docs/design-previews/neo-brutalist-ui.html +797 -0
  17. package/docs/design-previews/premium-command-center-ui-website.html +1217 -0
  18. package/docs/design-previews/premium-command-center-ui.html +552 -0
  19. package/docs/design-previews/warm-craft-ui-website.html +684 -0
  20. package/docs/design-previews/warm-craft-ui.html +739 -0
  21. package/docs/en/cli-reference.md +20 -9
  22. package/docs/pt/README.md +7 -0
  23. package/docs/pt/agent-sharding.md +132 -0
  24. package/docs/pt/agentes.md +8 -2
  25. package/docs/pt/busca-de-contexto.md +129 -0
  26. package/docs/pt/cache-de-contexto.md +156 -0
  27. package/docs/pt/comandos-cli.md +28 -0
  28. package/docs/pt/design-hybrid-forge.md +107 -0
  29. package/docs/pt/inicio-rapido.md +54 -3
  30. package/docs/pt/inteligencia-adaptativa.md +324 -0
  31. package/docs/pt/monitor-de-contexto.md +104 -0
  32. package/docs/pt/recuperacao-de-sessao.md +125 -0
  33. package/docs/pt/sandbox.md +125 -0
  34. package/docs/pt/skills.md +98 -6
  35. package/package.json +1 -1
  36. package/src/agent-loader.js +280 -0
  37. package/src/cli.js +94 -0
  38. package/src/commands/agent-loader.js +85 -0
  39. package/src/commands/context-cache.js +90 -0
  40. package/src/commands/context-monitor.js +92 -0
  41. package/src/commands/context-search.js +66 -0
  42. package/src/commands/design-hybrid-options.js +385 -0
  43. package/src/commands/health.js +214 -0
  44. package/src/commands/init.js +54 -13
  45. package/src/commands/install.js +52 -13
  46. package/src/commands/learning-evolve.js +355 -0
  47. package/src/commands/live.js +34 -0
  48. package/src/commands/recovery.js +43 -0
  49. package/src/commands/sandbox.js +37 -0
  50. package/src/commands/setup-context.js +22 -2
  51. package/src/commands/setup.js +178 -0
  52. package/src/commands/skill.js +79 -32
  53. package/src/commands/tool-registry-cmd.js +232 -0
  54. package/src/commands/update.js +7 -0
  55. package/src/constants.js +9 -0
  56. package/src/context-cache.js +159 -0
  57. package/src/context-search.js +326 -0
  58. package/src/design-variation-catalog.js +503 -0
  59. package/src/i18n/messages/en.js +32 -2
  60. package/src/i18n/messages/es.js +30 -2
  61. package/src/i18n/messages/fr.js +30 -2
  62. package/src/i18n/messages/pt-BR.js +32 -2
  63. package/src/install-animation.js +260 -0
  64. package/src/install-profile.js +143 -0
  65. package/src/install-wizard.js +474 -0
  66. package/src/installer.js +38 -10
  67. package/src/parser.js +7 -1
  68. package/src/recovery-context-session.js +154 -0
  69. package/src/runtime-store.js +97 -1
  70. package/src/sandbox.js +177 -0
  71. package/src/tool-executor.js +94 -0
  72. package/src/updater.js +11 -3
  73. package/template/.aioson/agents/analyst.md +58 -3
  74. package/template/.aioson/agents/architect.md +38 -0
  75. package/template/.aioson/agents/design-hybrid-forge.md +127 -0
  76. package/template/.aioson/agents/dev.md +103 -0
  77. package/template/.aioson/agents/deyvin.md +57 -0
  78. package/template/.aioson/agents/pm.md +58 -0
  79. package/template/.aioson/agents/product.md +28 -0
  80. package/template/.aioson/agents/qa.md +79 -0
  81. package/template/.aioson/agents/setup.md +65 -3
  82. package/template/.aioson/agents/sheldon.md +107 -6
  83. package/template/.aioson/agents/tester.md +156 -0
  84. package/template/.aioson/config.md +15 -0
  85. package/template/.aioson/context/forensics/.gitkeep +0 -0
  86. package/template/.aioson/context/seeds/seed-example.md +27 -0
  87. package/template/.aioson/context/user-profile.md +42 -0
  88. package/template/.aioson/locales/en/agents/setup.md +33 -1
  89. package/template/.aioson/locales/es/agents/setup.md +33 -1
  90. package/template/.aioson/locales/fr/agents/setup.md +33 -1
  91. package/template/.aioson/locales/pt-BR/agents/setup.md +33 -1
  92. package/template/.aioson/skills/design/aurora-command-ui/SKILL.md +243 -0
  93. package/template/.aioson/skills/design/aurora-command-ui/references/art-direction.md +293 -0
  94. package/template/.aioson/skills/design/aurora-command-ui/references/components.md +827 -0
  95. package/template/.aioson/skills/design/aurora-command-ui/references/dashboards.md +250 -0
  96. package/template/.aioson/skills/design/aurora-command-ui/references/design-tokens.md +585 -0
  97. package/template/.aioson/skills/design/aurora-command-ui/references/motion.md +365 -0
  98. package/template/.aioson/skills/design/aurora-command-ui/references/patterns.md +482 -0
  99. package/template/.aioson/skills/design/aurora-command-ui/references/websites.md +387 -0
  100. package/template/.aioson/skills/design/glassmorphism-ui/SKILL.md +222 -0
  101. package/template/.aioson/skills/design/glassmorphism-ui/references/art-direction.md +159 -0
  102. package/template/.aioson/skills/design/glassmorphism-ui/references/components.md +498 -0
  103. package/template/.aioson/skills/design/glassmorphism-ui/references/dashboards.md +236 -0
  104. package/template/.aioson/skills/design/glassmorphism-ui/references/design-tokens.md +274 -0
  105. package/template/.aioson/skills/design/glassmorphism-ui/references/motion.md +355 -0
  106. package/template/.aioson/skills/design/glassmorphism-ui/references/patterns.md +198 -0
  107. package/template/.aioson/skills/design/glassmorphism-ui/references/websites.md +307 -0
  108. package/template/.aioson/skills/design/neo-brutalist-ui/SKILL.md +213 -0
  109. package/template/.aioson/skills/design/neo-brutalist-ui/references/art-direction.md +228 -0
  110. package/template/.aioson/skills/design/neo-brutalist-ui/references/components.md +855 -0
  111. package/template/.aioson/skills/design/neo-brutalist-ui/references/dashboards.md +334 -0
  112. package/template/.aioson/skills/design/neo-brutalist-ui/references/design-tokens.md +342 -0
  113. package/template/.aioson/skills/design/neo-brutalist-ui/references/motion.md +286 -0
  114. package/template/.aioson/skills/design/neo-brutalist-ui/references/patterns.md +458 -0
  115. package/template/.aioson/skills/design/neo-brutalist-ui/references/websites.md +723 -0
  116. package/template/.aioson/skills/process/aioson-spec-driven/SKILL.md +45 -0
  117. package/template/.aioson/skills/process/aioson-spec-driven/references/approval-gates.md +109 -0
  118. package/template/.aioson/skills/process/aioson-spec-driven/references/artifact-map.md +44 -0
  119. package/template/.aioson/skills/process/aioson-spec-driven/references/classification-map.md +37 -0
  120. package/template/.aioson/skills/process/aioson-spec-driven/references/hardening-lane.md +49 -0
  121. package/template/.aioson/skills/process/aioson-spec-driven/references/maintenance-and-state.md +66 -0
  122. package/template/.aioson/skills/process/aioson-spec-driven/references/ui-language.md +75 -0
  123. package/template/.aioson/skills/process/design-hybrid-forge/SKILL.md +144 -0
  124. package/template/.aioson/skills/process/design-hybrid-forge/references/crossover-protocol.md +221 -0
  125. package/template/.aioson/skills/process/design-hybrid-forge/references/naming-registry.md +88 -0
  126. package/template/.aioson/skills/process/design-hybrid-forge/references/output-contract.md +291 -0
  127. package/template/.aioson/skills/process/design-hybrid-forge/references/pair-compatibility.md +117 -0
  128. package/template/.aioson/skills/process/design-hybrid-forge/references/quality-gates.md +188 -0
  129. package/template/.aioson/skills/process/design-hybrid-forge/references/variation-library.md +125 -0
  130. package/template/AGENTS.md +23 -1
  131. package/template/CLAUDE.md +1 -0
@@ -0,0 +1,125 @@
1
+ # Recuperação de Sessão
2
+
3
+ > Gera e restaura contexto entre sessões do Claude Code sem perder estado após compactação.
4
+
5
+ Quando o LLM compacta o contexto durante uma sessão longa, o histórico de tarefas, objetivo e arquivos modificados se perde. O `recovery:generate` cria um arquivo markdown estruturado em `.aioson/context/recovery-context.md` que pode ser re-injetado no início da próxima sessão para restaurar exatamente onde você parou.
6
+
7
+ ---
8
+
9
+ ## Comandos
10
+
11
+ ### `recovery:generate`
12
+
13
+ Gera o arquivo de recuperação para a sessão atual.
14
+
15
+ ```bash
16
+ aioson recovery:generate [path] [opções]
17
+ ```
18
+
19
+ **Opções:**
20
+
21
+ | Opção | Descrição |
22
+ |---|---|
23
+ | `--goal="..."` | Objetivo atual da sessão |
24
+ | `--agent="..."` | Agente ativo |
25
+ | `--json` | Retorna resultado em JSON |
26
+
27
+ **Exemplos:**
28
+
29
+ ```bash
30
+ # Gerar recovery simples
31
+ aioson recovery:generate .
32
+
33
+ # Gerar com contexto da sessão
34
+ aioson recovery:generate . --goal="implementar busca FTS5" --agent="deyvin"
35
+
36
+ # Retornar JSON para scripts
37
+ aioson recovery:generate . --json
38
+ ```
39
+
40
+ ---
41
+
42
+ ### `recovery:show`
43
+
44
+ Exibe o conteúdo do arquivo de recuperação existente.
45
+
46
+ ```bash
47
+ aioson recovery:show [path]
48
+ ```
49
+
50
+ **Exemplos:**
51
+
52
+ ```bash
53
+ # Ver o recovery atual
54
+ aioson recovery:show .
55
+
56
+ # Saída em JSON
57
+ aioson recovery:show . --json
58
+ ```
59
+
60
+ ---
61
+
62
+ ## O que o arquivo contém
63
+
64
+ O `recovery-context.md` é gerado automaticamente com:
65
+
66
+ - **Objetivo da sessão** — o que foi passado via `--goal`
67
+ - **Agente ativo** — o que foi passado via `--agent`
68
+ - **Tarefas recentes** — lista de tasks com status
69
+ - **Notas** — observações da sessão
70
+ - **Arquivos modificados** — `git diff --name-only HEAD`
71
+ - **Commits recentes** — últimos 10 commits do repositório
72
+
73
+ O arquivo é salvo em `.aioson/context/recovery-context.md`.
74
+
75
+ **Exemplo de arquivo gerado:**
76
+
77
+ ```markdown
78
+ # Recovery Context — Direct Session
79
+ > Generated: 2026-03-30T06:00:00.000Z
80
+
81
+ ## Current Goal
82
+ implementar busca FTS5 e cache de contexto
83
+
84
+ ## Active Agent
85
+ deyvin
86
+
87
+ ## Modified Files
88
+ - src/context-search.js
89
+ - src/context-cache.js
90
+ - tests/context-search.test.js
91
+
92
+ ## Recent Commits
93
+ - a1b2c3d Adicionar IndexManager com FTS5
94
+ - d4e5f6g Implementar context cache RAM
95
+ ```
96
+
97
+ ---
98
+
99
+ ## Orçamento de tokens
100
+
101
+ O arquivo é mantido abaixo de **2000 tokens** automaticamente. Se o conteúdo ultrapassar esse limite, os commits e eventos mais antigos são removidos — o objetivo, agente, arquivos modificados e tarefas são sempre preservados.
102
+
103
+ ---
104
+
105
+ ## Como usar após uma compactação
106
+
107
+ Quando o Claude compactar o contexto da sessão, basta re-injetar o arquivo:
108
+
109
+ ```
110
+ Read .aioson/context/recovery-context.md and continue from where we left off.
111
+ ```
112
+
113
+ Ou usar o `recovery:show` para copiar o conteúdo direto:
114
+
115
+ ```bash
116
+ aioson recovery:show .
117
+ ```
118
+
119
+ ---
120
+
121
+ ## Relação com squads
122
+
123
+ O `recovery:generate` é específico para **sessões diretas** (sem squad). Para squads, o AIOSON já gera recovery automaticamente via `squad:recovery` quando detecta queda de 30% no uso de contexto.
124
+
125
+ Para saber mais sobre recovery em squads, veja a documentação do [Squad Dashboard](./squad-dashboard.md).
@@ -0,0 +1,125 @@
1
+ # Sandbox de Execução
2
+
3
+ > Executa comandos shell com timeout automático, redação de secrets e summarização de output longo.
4
+
5
+ O `sandbox:exec` roda comandos em subprocesso isolado com três garantias: o comando é interrompido se passar do tempo máximo, qualquer secret reconhecido no output é redatado antes de ser exibido, e outputs maiores que 5KB são automaticamente resumidos mantendo início e fim.
6
+
7
+ ---
8
+
9
+ ## Comando
10
+
11
+ ### `sandbox:exec`
12
+
13
+ ```bash
14
+ aioson sandbox:exec "<comando>" [opções]
15
+ ```
16
+
17
+ **Opções:**
18
+
19
+ | Opção | Descrição |
20
+ |---|---|
21
+ | `--timeout=<ms>` | Interromper após N milissegundos (padrão: 30000) |
22
+ | `--cwd=<path>` | Diretório de trabalho do comando |
23
+ | `--intent="..."` | Rótulo para output truncado (aparece na marcação de omissão) |
24
+ | `--json` | Retorna stdout, stderr, exitCode e timedOut em JSON |
25
+
26
+ **Exemplos:**
27
+
28
+ ```bash
29
+ # Rodar testes com timeout de 60 segundos
30
+ aioson sandbox:exec "npm test" --timeout=60000
31
+
32
+ # Comando que pode exibir secrets (redatado automaticamente)
33
+ aioson sandbox:exec "env | grep TOKEN"
34
+
35
+ # Executar em outro diretório
36
+ aioson sandbox:exec "npm run build" --cwd=./frontend
37
+
38
+ # Capturar resultado estruturado
39
+ aioson sandbox:exec "node -e 'console.log(JSON.stringify({ok:true}))'" --json
40
+ ```
41
+
42
+ ---
43
+
44
+ ## Redação automática de secrets
45
+
46
+ O output é varrido automaticamente antes de ser exibido. Qualquer padrão reconhecido é substituído por `[REDACTED]`:
47
+
48
+ | Padrão | Exemplo |
49
+ |---|---|
50
+ | GitHub token (`ghp_*`) | `ghp_abc123...` → `ghp_[REDACTED]` |
51
+ | GitHub fine-grained (`github_pat_*`) | `github_pat_abc...` → `github_pat_[REDACTED]` |
52
+ | AWS access key (`AKIA*`) | `AKIAIOSFODNN7EXAMPLE` → `AKIA[REDACTED]` |
53
+ | Google OAuth (`ya29.*`) | `ya29.A0ARrd...` → `ya29.[REDACTED]` |
54
+ | Bearer token | `Bearer eyJhb...` → `Bearer [REDACTED]` |
55
+ | Senha em URL | `:minhasenha@host` → `:[REDACTED]@host` |
56
+ | `password=...` | `password=abc123` → `password=[REDACTED]` |
57
+ | `passwd=...` | `passwd=abc123` → `passwd=[REDACTED]` |
58
+ | `secret=...` | `secret=xyz` → `secret=[REDACTED]` |
59
+ | `api_key=...` | `api_key=sk-abc` → `api_key=[REDACTED]` |
60
+ | Bloco de chave privada | `-----BEGIN PRIVATE KEY-----...` → `[REDACTED]` |
61
+
62
+ A redação é aplicada tanto ao stdout quanto ao stderr.
63
+
64
+ ---
65
+
66
+ ## Timeout e interrupção
67
+
68
+ O comando é encerrado com `AbortController` quando o timeout é atingido. O resultado retorna `timedOut: true` e `ok: false`.
69
+
70
+ ```bash
71
+ # Vai ser interrompido após 500ms
72
+ aioson sandbox:exec "sleep 10" --timeout=500
73
+ ```
74
+
75
+ ---
76
+
77
+ ## Summarização de output longo
78
+
79
+ Se o output ultrapassar 5KB, a resposta mantém o início e o fim e indica quantos bytes foram omitidos:
80
+
81
+ ```
82
+ [início do output...]
83
+
84
+ [... 12.450 bytes omitted (npm test) ...]
85
+
86
+ [...fim do output]
87
+ ```
88
+
89
+ Use `--intent="..."` para que o rótulo apareça na marcação de omissão.
90
+
91
+ ---
92
+
93
+ ## JSON output
94
+
95
+ ```json
96
+ {
97
+ "ok": true,
98
+ "stdout": "Tests: 42 passed\n",
99
+ "stderr": "",
100
+ "exitCode": 0,
101
+ "timedOut": false,
102
+ "signal": null
103
+ }
104
+ ```
105
+
106
+ Quando há timeout:
107
+
108
+ ```json
109
+ {
110
+ "ok": false,
111
+ "stdout": "",
112
+ "stderr": "Command timed out after 500ms",
113
+ "exitCode": null,
114
+ "timedOut": true
115
+ }
116
+ ```
117
+
118
+ ---
119
+
120
+ ## Quando usar
121
+
122
+ - Rodar scripts ou testes dentro de uma sessão de agente sem expor secrets do ambiente
123
+ - Capturar output de comandos que podem conter variáveis de ambiente sensíveis
124
+ - Executar builds ou verificações com tempo máximo controlado
125
+ - Testar comandos cujo output vai ser lido de volta pelo agente (redação evita envenenamento de contexto com secrets)
package/docs/pt/skills.md CHANGED
@@ -36,19 +36,27 @@ Estrutura:
36
36
  │ ├── ethereum-docs.md
37
37
  │ ├── solana-docs.md
38
38
  │ └── cardano-docs.md
39
- └── design/ ← design systems visuais
40
- ├── cognitive-core-ui/
41
- ├── interface-design/
42
- └── premium-command-center-ui/
39
+ ├── design/ ← design systems visuais
40
+ ├── cognitive-core-ui/
41
+ ├── interface-design/
42
+ └── premium-command-center-ui/
43
+ └── process/ ← metodologia de fluxo e contratos entre agentes
44
+ └── aioson-spec-driven/
43
45
  ```
44
46
 
45
47
  **Carregamento condicional:** O agente `@dev` carrega apenas as skills que correspondem ao valor de `framework` em `project.context.md`. Exemplo: se `framework=Laravel`, carrega `laravel-conventions.md` e opcionalmente `tall-stack-patterns.md` se o stack for TALL.
46
48
 
49
+ **Process skills** são carregadas pelos agentes de spec (`@product`, `@analyst`, `@architect`, `@sheldon`, `@dev`, `@deyvin`) no início de sessões de especificação, requirements e design — nunca todas de uma vez. Cada agente carrega o `SKILL.md` central e depois apenas o arquivo de `references/` relevante para sua fase atual.
50
+
47
51
  ### Skills instaladas (`.aioson/installed-skills/`)
48
52
 
49
- Skills de terceiros instaladas pelo usuário. São **versionadas com o projeto** (não gitignored), permitindo que toda a equipe use as mesmas skills.
53
+ Skills versionadas com o projeto. Entram aqui em dois casos:
54
+
55
+ - skills de terceiros instaladas pelo usuário via CLI
56
+ - skills locais geradas dentro do próprio projeto por agentes/process skills
50
57
 
51
58
  Cada skill instalada contém um `SKILL.md` com frontmatter YAML descrevendo quando usá-la.
59
+ Quando existir, o arquivo `.skill-meta.json` registra origem, autor e metadados do gerador/modelo.
52
60
 
53
61
  ## Instalando skills
54
62
 
@@ -61,7 +69,7 @@ aioson skill:install @tech-leads-club/agent-skills --skill coupling-analysis
61
69
  Isso:
62
70
  1. Baixa o pacote npm temporariamente
63
71
  2. Copia a skill para `.aioson/installed-skills/{nome}/`
64
- 3. Distribui para ferramentas nativas (`.claude/skills/`, `.cursor/skills/`, `.windsurf/skills/`)
72
+ 3. Distribui recursivamente para ferramentas nativas (`.claude/skills/`, `.cursor/skills/`, `.windsurf/skills/`)
65
73
  4. Registra a skill na seção "Installed skills" do `AGENTS.md`
66
74
 
67
75
  ### Via aioson.com (registry cloud)
@@ -89,6 +97,7 @@ aioson skill:list
89
97
  ```
90
98
 
91
99
  Mostra todas as skills em `.aioson/installed-skills/` com nome, descrição e fonte.
100
+ Quando a metadata existir, também pode mostrar autor e modelo gerador.
92
101
 
93
102
  ### Remover uma skill
94
103
 
@@ -150,6 +159,89 @@ Skills de design disponíveis:
150
159
  - `interface-design` — Design de interfaces (dashboards, apps, ferramentas)
151
160
  - `premium-command-center-ui` — UI premium para command centers
152
161
 
162
+ ## Skills de processo
163
+
164
+ Skills de processo ensinam os agentes **como as fases do AIOSON se conectam** — não o que implementar, mas como sequenciar, quando aprofundar e como fazer handoff limpo entre agentes.
165
+
166
+ Diferente das skills de framework (que são por stack) e das skills de design (que são por sistema visual), process skills são transversais: carregadas por qualquer agente de spec conforme a fase em que ele se encontra.
167
+
168
+ ### `aioson-spec-driven`
169
+
170
+ Localização: `.aioson/skills/process/aioson-spec-driven/`
171
+
172
+ A skill central de metodologia do AIOSON. Cobre:
173
+
174
+ - **Sequência de fases** — quais fases existem, quais artefatos cada uma produz e quem é o agente responsável
175
+ - **Profundidade por classificação** — MICRO usa fluxo mínimo, SMALL usa fluxo padrão, MEDIUM usa pacote completo
176
+ - **Gates de aprovação** — Gate A (requirements), Gate B (design), Gate C (plan) — critérios do que deve estar pronto antes de avançar para a próxima fase
177
+ - **Hardening lane** — como identificar quando um input ainda está em modo "exploratório/vibe" e o que fazer para convertê-lo em spec executável
178
+ - **Manutenção e estado** — como escrever checkpoints úteis em `spec-{slug}.md` para que qualquer agente ou sessão futura possa retomar sem redescobrir o que já foi decidido
179
+
180
+ **Estrutura:**
181
+
182
+ ```
183
+ .aioson/skills/process/aioson-spec-driven/
184
+ ├── SKILL.md ← entry point curto — carregue sempre primeiro
185
+ └── references/
186
+ ├── artifact-map.md ← qual artefato fica onde e quem é o dono
187
+ ├── classification-map.md ← profundidade de fase por MICRO/SMALL/MEDIUM
188
+ ├── approval-gates.md ← critérios dos Gates A, B e C
189
+ ├── hardening-lane.md ← quando endurecer vs quando explorar
190
+ └── maintenance-and-state.md ← como escrever spec e checkpoints úteis
191
+ ```
192
+
193
+ **Carregamento:** Os agentes `@product`, `@analyst`, `@architect`, `@sheldon`, `@dev` e `@deyvin` verificam automaticamente se esta skill está disponível e carregam `SKILL.md` + apenas o arquivo de `references/` relevante para a fase atual. Nunca carregam a pasta inteira de uma vez.
194
+
195
+ ### `design-hybrid-forge`
196
+
197
+ Localização: `.aioson/skills/process/design-hybrid-forge/`
198
+
199
+ Skill first-party para criar uma nova skill de design híbrida a partir de **2 skills primárias obrigatórias** e, opcionalmente, até 2 modificadores de escopo limitado. Em modo avançado, pode liberar um 3º modificador, ainda preso a lanes secundárias.
200
+
201
+ Se você quer o fluxo completo em um só lugar, leia a página dedicada: [design-hybrid-forge](./design-hybrid-forge.md).
202
+
203
+ Fluxo padrão:
204
+
205
+ 1. O usuário ativa `@design-hybrid-forge` no Codex ou `/design-hybrid-forge` no Claude
206
+ 2. Se quiser um overlay visual mais ousado, o usuário pode rodar `aioson design-hybrid:options` para gerar `.aioson/context/design-variation-preset.md`
207
+ 3. O comando usa `conversation_language` do projeto quando existir; `--locale` funciona como override manual
208
+ 4. O agente pede as 2 skills primárias, até 2 modificadores opcionais e lê o preset visual quando ele existir
209
+ 5. Se o usuário tiver criado o preset com `--advanced`, o agente pode aceitar um 3º modificador de escopo estreito
210
+ 6. O híbrido é gerado em `.aioson/installed-skills/{slug}/`
211
+ 7. O `AGENTS.md` é atualizado para que o Codex possa usar `@{slug}`
212
+ 8. O pacote também pode ser espelhado para `.claude/skills/`, `.cursor/skills/` e `.windsurf/skills/`
213
+
214
+ Saída padrão:
215
+
216
+ ```
217
+ .aioson/installed-skills/{slug}/
218
+ SKILL.md
219
+ .skill-meta.json
220
+ references/
221
+ previews/
222
+ ```
223
+
224
+ Esse fluxo cria uma **skill local do projeto**. Se depois você quiser promover a skill para o core do AIOSON ou para um marketplace, trate isso como uma segunda etapa de curadoria, separada da geração local.
225
+
226
+ O preset criado em `.aioson/context/design-variation-preset.md` é **temporário**:
227
+ - ele serve como input para a próxima geração híbrida
228
+ - depois da geração, deve ser removido ou movido do contexto ativo
229
+ - uma cópia histórica fica em `.aioson/context/history/design-variation-presets/`
230
+ - ele não redefine o layout padrão do projeto; quem continua mandando no projeto é a `design_skill` ativa
231
+
232
+ O preset gerado por `design-hybrid:options` cobre direções como:
233
+ - clássico / editorial
234
+ - extravagante / maximalista
235
+ - cinematográfico / imersivo
236
+ - retrofuturista
237
+ - motion-driven
238
+ - CSS avançado (scroll-driven animations, View Transition API, masks, SVG filters, 3D)
239
+
240
+ Recomendação de uso:
241
+ - fluxo normal: até 2 modificadores
242
+ - fluxo avançado: `aioson design-hybrid:options --advanced` para permitir até 3 modificadores
243
+ - mesmo no modo avançado, modificadores não podem dominar substrato nem estrutura
244
+
153
245
  ## Skills de squad
154
246
 
155
247
  Squads podem ter suas próprias skills em `.aioson/squads/{squad-slug}/skills/`. Essas são carregadas automaticamente quando a tarefa pertence ao escopo do squad.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jaimevalasek/aioson",
3
- "version": "1.5.1",
3
+ "version": "1.6.0",
4
4
  "description": "AI operating framework for hyper-personalized software.",
5
5
  "keywords": [
6
6
  "ai",
@@ -0,0 +1,280 @@
1
+ 'use strict';
2
+
3
+ const fs = require('node:fs/promises');
4
+ const path = require('node:path');
5
+ const os = require('node:os');
6
+ const { IndexManager } = require('./context-search');
7
+
8
+ const SHARD_SEARCH_DIR = path.join(os.homedir(), '.aioson', 'shards');
9
+ const MAX_SHARD_TOKENS = 2000;
10
+ const DEFAULT_SHARDS = 3;
11
+
12
+ function estimateTokens(str) {
13
+ return Math.ceil(str.length / 4);
14
+ }
15
+
16
+ /**
17
+ * Split a markdown document into semantic shards by H2/H3 headings.
18
+ * Each shard = heading + its content until the next heading.
19
+ *
20
+ * @param {string} content — raw markdown
21
+ * @param {string} agentId — used to label shards
22
+ * @returns {Array<{id, heading, level, content, tokens}>}
23
+ */
24
+ function shardMarkdown(content, agentId) {
25
+ const lines = content.split('\n');
26
+ const shards = [];
27
+ let currentHeading = '(preamble)';
28
+ let currentLevel = 1;
29
+ let currentLines = [];
30
+ let shardIndex = 0;
31
+
32
+ function flushShard() {
33
+ const text = currentLines.join('\n').trim();
34
+ if (!text) return;
35
+ const tokens = estimateTokens(text);
36
+ shards.push({
37
+ id: `${agentId}:shard:${shardIndex}`,
38
+ heading: currentHeading,
39
+ level: currentLevel,
40
+ content: text,
41
+ tokens
42
+ });
43
+ shardIndex++;
44
+ }
45
+
46
+ for (const line of lines) {
47
+ const h2 = line.match(/^##\s+(.+)/);
48
+ const h3 = line.match(/^###\s+(.+)/);
49
+
50
+ if (h2 || h3) {
51
+ flushShard();
52
+ currentHeading = (h2 || h3)[1].trim();
53
+ currentLevel = h2 ? 2 : 3;
54
+ currentLines = [line];
55
+ } else {
56
+ currentLines.push(line);
57
+ }
58
+ }
59
+
60
+ flushShard();
61
+ return shards;
62
+ }
63
+
64
+ /**
65
+ * Agent shard loader — indexes agent instruction files as shards
66
+ * and loads only the relevant ones based on a goal query.
67
+ */
68
+ class AgentLoader {
69
+ constructor(opts = {}) {
70
+ this._searchDir = opts.searchDir || SHARD_SEARCH_DIR;
71
+ this._idx = null;
72
+ this._shardMap = new Map(); // id → shard content
73
+ }
74
+
75
+ async open() {
76
+ this._idx = new IndexManager(this._searchDir);
77
+ await this._idx.open();
78
+ return this;
79
+ }
80
+
81
+ close() {
82
+ if (this._idx) {
83
+ this._idx.close();
84
+ this._idx = null;
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Index a single agent instruction file as shards.
90
+ * @param {string} filePath — absolute path to agent .md file
91
+ * @param {string} agentId
92
+ * @param {object} opts — { force? }
93
+ */
94
+ async indexAgentFile(filePath, agentId, opts = {}) {
95
+ const content = await fs.readFile(filePath, 'utf8');
96
+ const shards = shardMarkdown(content, agentId);
97
+
98
+ // Write individual shard files to a temp dir for FTS5 indexing
99
+ const shardDir = path.join(this._searchDir, 'agent-shards', agentId);
100
+ await fs.mkdir(shardDir, { recursive: true });
101
+
102
+ for (const shard of shards) {
103
+ const shardFile = path.join(shardDir, `${shard.id.replace(/:/g, '_')}.md`);
104
+ const shardContent = `# ${shard.heading}\n\n${shard.content}`;
105
+ await fs.writeFile(shardFile, shardContent, 'utf8');
106
+ // Keep content in memory for fast retrieval
107
+ this._shardMap.set(shard.id, shard);
108
+ }
109
+
110
+ // Index the shard dir
111
+ await this._idx.indexDirectory(shardDir, { force: opts.force !== false });
112
+
113
+ return { agentId, shards: shards.length };
114
+ }
115
+
116
+ /**
117
+ * Index an entire agents directory.
118
+ * @param {string} agentsDir — directory containing agent .md files
119
+ * @param {object} opts — { force? }
120
+ * @returns {{ agents: number, totalShards: number }}
121
+ */
122
+ async indexAgentsDir(agentsDir, opts = {}) {
123
+ let entries;
124
+ try {
125
+ entries = await fs.readdir(agentsDir, { withFileTypes: true });
126
+ } catch {
127
+ return { agents: 0, totalShards: 0 };
128
+ }
129
+
130
+ let agents = 0;
131
+ let totalShards = 0;
132
+
133
+ for (const entry of entries) {
134
+ if (!entry.isFile()) continue;
135
+ if (!entry.name.endsWith('.md')) continue;
136
+
137
+ const agentId = entry.name.replace(/\.md$/, '');
138
+ const filePath = path.join(agentsDir, entry.name);
139
+
140
+ try {
141
+ const result = await this.indexAgentFile(filePath, agentId, opts);
142
+ agents++;
143
+ totalShards += result.shards;
144
+ } catch {
145
+ // best-effort: skip unreadable files
146
+ }
147
+ }
148
+
149
+ return { agents, totalShards };
150
+ }
151
+
152
+ /**
153
+ * Load the most relevant shards for an agent given a goal query.
154
+ *
155
+ * Strategy:
156
+ * 1. Search FTS5 index for the goal query, filtered to agent shards
157
+ * 2. Always include H1/H2 "Role" and "preamble" shards
158
+ * 3. Fill remaining budget with ranked results
159
+ *
160
+ * @param {string} agentId
161
+ * @param {string} goal
162
+ * @param {object} opts — { maxShards?, maxTokens? }
163
+ * @returns {{ shards: Array, tokens: number, agentId: string }}
164
+ */
165
+ async loadRelevantShards(agentId, goal, opts = {}) {
166
+ const maxShards = opts.maxShards || DEFAULT_SHARDS;
167
+ const maxTokens = opts.maxTokens || MAX_SHARD_TOKENS;
168
+
169
+ // If shards aren't in memory (e.g., loaded from a previous session), load from disk
170
+ if (this._shardMap.size === 0) {
171
+ await this._loadShardsFromDisk(agentId);
172
+ }
173
+
174
+ const agentShards = [...this._shardMap.values()].filter(s => s.id.startsWith(`${agentId}:`));
175
+
176
+ if (agentShards.length === 0) {
177
+ return { shards: [], tokens: 0, agentId };
178
+ }
179
+
180
+ // Always include preamble/role shards
181
+ const priority = agentShards.filter(s =>
182
+ s.heading === '(preamble)' ||
183
+ /^role$/i.test(s.heading) ||
184
+ /^your role$/i.test(s.heading)
185
+ );
186
+
187
+ let selected = [...priority];
188
+ let usedTokens = selected.reduce((sum, s) => sum + s.tokens, 0);
189
+
190
+ // Search for relevant shards
191
+ if (goal && goal.trim()) {
192
+ const searchResults = this._idx.search(`${agentId} ${goal}`, { limit: maxShards + 2 });
193
+
194
+ for (const result of searchResults) {
195
+ if (selected.length >= maxShards) break;
196
+
197
+ // Match result back to shard via heading
198
+ const matchedShard = agentShards.find(s =>
199
+ result.relPath.includes(s.id.replace(/:/g, '_')) ||
200
+ s.heading.toLowerCase().includes(result.title.toLowerCase())
201
+ );
202
+
203
+ if (!matchedShard) continue;
204
+ if (selected.some(s => s.id === matchedShard.id)) continue;
205
+
206
+ if (usedTokens + matchedShard.tokens <= maxTokens) {
207
+ selected.push(matchedShard);
208
+ usedTokens += matchedShard.tokens;
209
+ }
210
+ }
211
+ }
212
+
213
+ // Fill with remaining shards if budget allows
214
+ if (selected.length < maxShards) {
215
+ for (const shard of agentShards) {
216
+ if (selected.length >= maxShards) break;
217
+ if (selected.some(s => s.id === shard.id)) continue;
218
+ if (usedTokens + shard.tokens <= maxTokens) {
219
+ selected.push(shard);
220
+ usedTokens += shard.tokens;
221
+ }
222
+ }
223
+ }
224
+
225
+ return {
226
+ agentId,
227
+ shards: selected,
228
+ tokens: usedTokens,
229
+ totalShards: agentShards.length
230
+ };
231
+ }
232
+
233
+ /**
234
+ * Load shards from disk (for cross-session use).
235
+ * @private
236
+ */
237
+ async _loadShardsFromDisk(agentId) {
238
+ const shardDir = path.join(this._searchDir, 'agent-shards', agentId);
239
+ let files;
240
+ try {
241
+ files = await fs.readdir(shardDir);
242
+ } catch {
243
+ return;
244
+ }
245
+
246
+ for (const file of files) {
247
+ if (!file.endsWith('.md')) continue;
248
+ const filePath = path.join(shardDir, file);
249
+ try {
250
+ const content = await fs.readFile(filePath, 'utf8');
251
+ // Reconstruct shard id from filename
252
+ const id = file.replace(/\.md$/, '').replace(/_/g, ':');
253
+ const headingMatch = content.match(/^#\s+(.+)$/m);
254
+ const heading = headingMatch ? headingMatch[1] : '(unknown)';
255
+ const tokens = estimateTokens(content);
256
+ this._shardMap.set(id, { id, heading, level: 2, content, tokens });
257
+ } catch {
258
+ // skip
259
+ }
260
+ }
261
+ }
262
+
263
+ /**
264
+ * Build a merged context string from selected shards.
265
+ * @param {Array} shards
266
+ * @returns {string}
267
+ */
268
+ static buildContext(shards) {
269
+ return shards.map(s => s.content).join('\n\n---\n\n');
270
+ }
271
+
272
+ /**
273
+ * Return index statistics for all agent shards.
274
+ */
275
+ stats() {
276
+ return this._idx.stats();
277
+ }
278
+ }
279
+
280
+ module.exports = { AgentLoader, shardMarkdown };