iron-edge 2.3.1 → 2.4.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.
package/README.md CHANGED
@@ -213,6 +213,31 @@ npx iron-edge verify
213
213
 
214
214
  ---
215
215
 
216
+ ## Iron Office
217
+
218
+ Converse com o Iron pelo dashboard ([iron-office.vercel.app](https://iron-office.vercel.app)) e veja os agentes trabalhando no feed e no mapa 3D.
219
+
220
+ ```bash
221
+ npx iron-edge office
222
+ ```
223
+
224
+ Antes, faça o **passo 4** do onboarding do Iron Office (ele salva a sua chave em `~/.claude/iron-office-api-key`).
225
+
226
+ O que esperar:
227
+
228
+ 1. O comando instala (ou atualiza) o plugin de canal `iron-office` e abre o Claude Code com ele ligado.
229
+ 2. O Claude Code mostra um **aviso de tela cheia**: canais ainda são recurso em teste. Aceite.
230
+ 3. Abra a página **Iron** do dashboard. Em até 1 minuto aparece "Iron online". Escreva ali e o Iron responde ali.
231
+ 4. **Deixe essa aba do terminal aberta.** É ela que faz o Iron responder no site.
232
+
233
+ Por padrão a sessão do `office` roda **sem pedir licença** a cada ferramenta (é o que deixa o Iron trabalhar enquanto você está só no site). `npx iron-edge office --safe` abre pedindo licença a cada ferramenta. Qualquer outro argumento vai direto pro `claude`.
234
+
235
+ Mensagem escrita no site com o terminal fechado espera até 15 minutos; depois disso expira e o chat avisa pra mandar de novo (ordem velha não é executada sem você ver).
236
+
237
+ O plugin também manda a atividade das sessões pro seu painel: veja o que sai em "Sobre o que sai da sua máquina", mais abaixo.
238
+
239
+ ---
240
+
216
241
  ## Requisitos
217
242
 
218
243
  - **Node.js** 18 ou superior
@@ -230,12 +255,14 @@ O Iron Edge instala uma equipe de agentes especializados diretamente no Claude C
230
255
 
231
256
  Seus dados ficam locais em `~/.iron/`. Sobre o que sai da sua máquina, com precisão:
232
257
 
233
- - **Para o Iron Office** (`iron-office.vercel.app`, servidor deste projeto) vão dados de apenas **2 agentes**: `iron-auditor` e `iron-shopify`. E só se você criar a chave em `~/.claude/iron-office-api-key`. Confira você mesmo: `grep -rln "iron-office" ~/.claude/agents/`.
258
+ - **Para o Iron Office** (`iron-office.vercel.app`, servidor deste projeto), e só se você criar a chave em `~/.claude/iron-office-api-key`:
259
+ - dados de apenas **2 agentes**, `iron-auditor` e `iron-shopify`. Confira: `grep -rln "iron-office" ~/.claude/agents/`;
260
+ - **se você rodou `npx iron-edge office`**, o plugin `iron-office` fica instalado e manda a atividade de **toda sessão** do Claude Code pro seu painel (feed e mapa 3D): nome da ferramenta, caminho do arquivo (nunca o conteúdo), os primeiros 200 caracteres de cada comando de terminal e a descrição dele, buscas, o domínio dos endereços visitados, nome e descrição dos agentes, a pasta e o identificador da sessão. A resposta das ferramentas nunca sai. Padrões conhecidos de segredo nesses campos (chaves de Stripe, Shopify, Meta, GitHub, OpenAI, Supabase e AWS, `Bearer`, `ALGO_KEY=`, `--password`, `-u usuario:senha`…) são apagados antes do envio; é uma lista de padrões, não garantia. Lista completa no README do plugin (github.com/filipecoff21-code/iron-office-channel). Desligar: `claude plugin disable iron-office@iron-office-channel`. Conferir se está ligado: `claude plugin list`.
234
261
  - **Para a internet aberta**, através das ferramentas do próprio Claude Code (`WebSearch` / `WebFetch`), vão as buscas de **41 dos 44 agentes** — é como o `iron-research` pesquisa mercado e o `iron-spy` lê a biblioteca de anúncios. Isso passa pelo Claude Code, com a visibilidade e a aprovação que ele te dá; não é canal deste pacote. Confira: `grep -rln "WebSearch\|WebFetch" ~/.claude/agents/`.
235
262
  - **A skill `clone-site`** baixa a URL que você mandar clonar. É o trabalho dela.
236
263
 
237
264
 
238
- Sendo exato sobre a força dessa garantia, porque ela não é um sandbox: cada bloco que chama o Iron Office começa com uma guarda (`[ -z "$IRON_KEY" ] && exit 0`) e a regra R20 do lint impede que qualquer bloco novo entre sem ela. Mas esses arquivos são **instruções lidas por um modelo**, não um binário fechado: um agente que execute só a linha do `curl`, isolada da guarda, não é barrado por nada aqui. Se o que você quer é garantia dura, a que existe é não criar o arquivo de chave — sem ele, não há para onde enviar, e todo bloco para na guarda.
265
+ Sendo exato sobre a força dessa garantia, porque ela não é um sandbox: cada bloco que chama o Iron Office começa com uma guarda (`[ -z "$IRON_KEY" ] && exit 0`) e a regra R20 do lint impede que qualquer bloco novo entre sem ela. Mas esses arquivos são **instruções lidas por um modelo**, não um binário fechado: um agente que execute só a linha do `curl`, isolada da guarda, não é barrado por nada aqui. Se o que você quer é garantia dura, a que existe é não criar o arquivo de chave — sem ele, não há para onde enviar, e todo bloco para na guarda (o plugin `iron-office` também: sem a chave, ele não envia nada).
239
266
 
240
267
  ---
241
268
 
package/bin/iron-edge.js CHANGED
@@ -14,6 +14,9 @@
14
14
  * arquivos cujo hash bate com o manifesto — os que
15
15
  * ninguem alterou — e preserva o resto
16
16
  *
17
+ * office [--safe] liga o Iron Office: instala o plugin de canal e abre o
18
+ * Claude Code conversando com o chat do dashboard
19
+ *
17
20
  * Nao existe 'uninstall' automatico: remover continua sendo operacao conduzida, com o
18
21
  * manifesto na mao (o README descreve o procedimento).
19
22
  */
@@ -147,7 +150,12 @@ if (cmd === 'install') {
147
150
  // Reprovam so' divergencia sem registro e arquivo sumido.
148
151
  process.exit(alterados.length + sumidos.length === 0 ? 0 : 1);
149
152
 
153
+ } else if (cmd === 'office') {
154
+ // liga o chat do dashboard (iron-office.vercel.app/chat) na sessao do Claude Code
155
+ const r = spawnSync(process.execPath, [path.join(__dirname, '..', 'installer', 'office.js'), ...rest], { stdio: 'inherit' });
156
+ process.exit(r.status ?? 1);
157
+
150
158
  } else {
151
- console.log('uso: iron-edge <install|update|verify> [--dry-run] [--source <dir>]');
152
- process.exit(cmd ? 1 : 0);
159
+ console.log('uso: iron-edge <install|update|verify|office> [--dry-run] [--source <dir>] [--safe]');
160
+ process.exit(cmd && cmd !== '--help' && cmd !== '-h' ? 1 : 0);
153
161
  }
@@ -0,0 +1,123 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * office.js — `npx iron-edge office`: liga o Iron Office (chat do dashboard) no Claude Code.
4
+ *
5
+ * Passos: (1) confere a chave do Iron Office, (2) confere o Claude Code, (3) instala ou
6
+ * atualiza o plugin de canal `iron-office` pelo marketplace do GitHub, (4) abre o Claude Code
7
+ * com o canal ligado. O aluno deixa essa aba aberta: e' ela que faz o Iron responder no site.
8
+ *
9
+ * Flags: --safe tira o `--permission-mode bypassPermissions` (o Claude pede licenca a cada
10
+ * ferramenta). Qualquer outro argumento vai direto pro `claude`.
11
+ *
12
+ * Saida so' em ASCII, como o resto do instalador: console do Windows antigo mostra lixo em
13
+ * acento e simbolo. O `claude` recebe IRON_OFFICE_CHANNEL=1 no ambiente: e' o que diz ao
14
+ * servidor do plugin que ESTA sessao e' o canal (uma aba comum do Claude Code nao puxa o chat).
15
+ */
16
+ const fs = require('fs');
17
+ const path = require('path');
18
+ const os = require('os');
19
+ const { spawnSync } = require('child_process');
20
+
21
+ const MARKETPLACE_REPO = 'filipecoff21-code/iron-office-channel';
22
+ const PLUGIN = 'iron-office@iron-office-channel';
23
+ const CHANNEL = 'plugin:' + PLUGIN;
24
+ const ONBOARDING = 'https://iron-office.vercel.app/onboarding';
25
+ const IS_WIN = process.platform === 'win32';
26
+
27
+ function keyPath(home) {
28
+ return path.join(home || os.homedir(), '.claude', 'iron-office-api-key');
29
+ }
30
+
31
+ // O `echo` do passo 4 no Windows pode gravar UTF-16 com BOM: normaliza antes de decidir.
32
+ function readKey(home) {
33
+ try {
34
+ const buf = fs.readFileSync(keyPath(home));
35
+ const utf16 = buf.length >= 2 && buf[0] === 0xff && buf[1] === 0xfe;
36
+ return buf.toString(utf16 ? 'utf16le' : 'utf8').replace(/[\uFEFF\u0000]/g, '').trim();
37
+ } catch (_) { return ''; }
38
+ }
39
+
40
+ // Argumentos do `claude` que abre a sessao com o canal. Separado pra ser testado sem rede.
41
+ function buildClaudeArgs(argv) {
42
+ const safe = argv.includes('--safe');
43
+ const extra = argv.filter(a => a !== '--safe');
44
+ const args = ['--dangerously-load-development-channels', CHANNEL];
45
+ if (!safe) args.push('--permission-mode', 'bypassPermissions');
46
+ return args.concat(extra);
47
+ }
48
+
49
+ function run(bin, args, opts) {
50
+ return spawnSync(bin, args, { encoding: 'utf8', shell: IS_WIN, ...opts });
51
+ }
52
+
53
+ // No Windows o `claude` instalado pelo npm e' um `claude.cmd`; com shell ele costuma resolver,
54
+ // mas ha PATH em que so' o nome com extensao funciona.
55
+ function resolveClaude() {
56
+ const candidates = IS_WIN ? ['claude', 'claude.cmd'] : ['claude'];
57
+ for (const bin of candidates) {
58
+ const r = run(bin, ['--version']);
59
+ if (!r.error && r.status === 0) return bin;
60
+ }
61
+ return null;
62
+ }
63
+
64
+ function step(claude, label, args, okPatterns) {
65
+ const r = run(claude, args);
66
+ const out = ((r.stdout || '') + (r.stderr || '')).trim();
67
+ if (r.status === 0) { console.log(' [ok] ' + label); return true; }
68
+ if (okPatterns.some(p => p.test(out))) { console.log(' [ok] ' + label + ' (ja estava)'); return true; }
69
+ console.log(' [falhou] ' + label + ': ' + (out.split('\n').pop() || 'sem detalhe'));
70
+ return false;
71
+ }
72
+
73
+ function main(argv) {
74
+ if (!readKey()) {
75
+ console.error('Falta a chave do Iron Office. Faca o passo 4 em ' + ONBOARDING);
76
+ return 1;
77
+ }
78
+
79
+ const claude = resolveClaude();
80
+ if (!claude) {
81
+ console.error('Instale o Claude Code primeiro: https://claude.com/claude-code');
82
+ return 1;
83
+ }
84
+
85
+ console.log('Iron Office - preparando o canal');
86
+ const okMarket = step(claude, 'marketplace ' + MARKETPLACE_REPO, ['plugin', 'marketplace', 'add', MARKETPLACE_REPO], [/already/i]);
87
+ const okPlugin = okMarket && step(claude, 'plugin ' + PLUGIN, ['plugin', 'install', PLUGIN, '--scope', 'user'], [/already/i]);
88
+ if (!okMarket || !okPlugin) {
89
+ console.error('');
90
+ console.error('Nao deu pra instalar o plugin do Iron Office. Confira:');
91
+ console.error(' 1. a internet esta funcionando;');
92
+ console.error(' 2. o git esta instalado (rode: git --version);');
93
+ console.error(' 3. rode de novo: npx iron-edge office');
94
+ console.error('Se continuar, mande um print desta tela pro suporte.');
95
+ return 1;
96
+ }
97
+ // atualizar e' melhor-esforco: sem internet no meio, segue com a versao ja instalada
98
+ step(claude, 'atualizacao do plugin', ['plugin', 'update', PLUGIN], [/already|up.to.date|latest/i]);
99
+
100
+ const safe = argv.includes('--safe');
101
+ console.log('');
102
+ console.log('Abrindo o Claude Code com o Iron Office ligado.');
103
+ console.log('Vai aparecer um aviso de canal (recurso em teste): aceite.');
104
+ if (!safe) {
105
+ console.log('O Iron vai agir SEM pedir licenca a cada passo (e o que deixa ele trabalhar');
106
+ console.log('enquanto voce esta no site). Quer aprovar cada passo? Rode: npx iron-edge office --safe');
107
+ }
108
+ console.log('Deixe esta aba aberta: e ela que faz o Iron responder no site.');
109
+ console.log('');
110
+
111
+ const r = spawnSync(claude, buildClaudeArgs(argv), {
112
+ stdio: 'inherit',
113
+ shell: IS_WIN,
114
+ env: { ...process.env, IRON_OFFICE_CHANNEL: '1' },
115
+ });
116
+ return r.status ?? 1;
117
+ }
118
+
119
+ module.exports = { buildClaudeArgs, keyPath, readKey, CHANNEL, PLUGIN, MARKETPLACE_REPO };
120
+
121
+ if (require.main === module) {
122
+ process.exit(main(process.argv.slice(2)));
123
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "iron-edge",
3
- "version": "2.3.1",
4
- "description": "Ecossistema de agentes para Claude Code: 44 agentes de topo, 18 squads e 14 skills, com quality gate, memoria e instalador que nunca sobrescreve.",
3
+ "version": "2.4.0",
4
+ "description": "Ecossistema de agentes para Claude Code: 44 agentes de topo, 18 squads e 14 skills, com quality gate, memoria, instalador que nunca sobrescreve e o comando office (chat do Iron Office no dashboard).",
5
5
  "keywords": [
6
6
  "claude",
7
7
  "claude-code",
@@ -25,13 +25,14 @@
25
25
  "iron-routing-map.md",
26
26
  "docs/",
27
27
  "!docs/interno",
28
- "!docs/historico"
28
+ "!docs/historico",
29
+ "!**/_auditoria"
29
30
  ],
30
31
  "engines": {
31
32
  "node": ">=18.0.0"
32
33
  },
33
34
  "scripts": {
34
- "test": "node scripts/lint.js && node scripts/test-verify.js && node scripts/test-update.js",
35
+ "test": "node scripts/lint.js && node scripts/test-verify.js && node scripts/test-update.js && node scripts/test-office.js",
35
36
  "test:matriz": "node scripts/test-matriz-update.js"
36
37
  },
37
38
  "devDependencies": {
@@ -27,8 +27,14 @@ Nunca assuma quais modelos a conta do usuário tem — contas diferem. Conduza,
27
27
  **DIA A DIA** (feature, ajuste, bug): planejar no plan mode → executar no EXECUTOR → revisar no JULGADOR se a coisa for séria. Se `opusplan` apareceu na lista, `/model opusplan` automatiza exatamente isso — é o único caso em que `/model` é bem-vindo, porque aí mudar o padrão É a intenção.
28
28
 
29
29
  **DEMANDA ESTRUTURAL** (desenhar um sistema, arquitetura, decisão cara de errar) — o fluxo das TRÊS ABAS do terminal:
30
- - aba 1: JULGADOR planeja e **salva o plano num ARQUIVO**;
31
- - aba 2: EXECUTOR executa lendo o arquivo. Sobe um degrau em DOIS casos apenas: implementação pesada em si, ou o EXECUTOR travou 2 vezes no mesmo ponto. Regra de bolso: **sonnet até travar, degrau acima pra destravar** — e subir é FECHAR a aba e abrir outra com `claude --model "opus"`, nunca `/model` na aba aberta;
30
+ - aba 1: JULGADOR planeja e **salva o plano num ARQUIVO**, com a **data no cabeçalho** (formato AAAA-MM-DD, que é o que o git lê sem ambiguidade). O plano só merece confiança se tiver três seções: **(a) arquivos exatos** (caminho + o que muda em cada um), **(b) checklist de gates** com `[ ]`, **(c) validação de ponta a ponta** no app/tela real, com o estado esperado. Sem isso o executor vai ter que explorar tudo de novo, e a economia some;
31
+ - aba 2: EXECUTOR executa lendo o arquivo, sob o **bilhete do executor** (vai junto com o pedido "executa o plano: <caminho>"):
32
+ - **Confie no plano. Só escreva o código.** O JULGADOR já mapeou o projeto; não gastar esta aba relendo arquitetura nem redescobrindo o plano. Ler só os arquivos que o plano lista. Antes de começar, uma checagem só: o código mudou desde a data do cabeçalho do plano? Em projeto com git, `git status` (mudança não commitada) + `git log --since=<data do cabeçalho>` (commits). Sem git, ou se o comando falhar: pular a checagem e escrever isso no relatório. Pular a checagem NÃO libera explorar: a lista de arquivos do plano continua valendo. Só o arquivo que a checagem mostrou alterado pode ser aberto fora da lista, e vai registrado no relatório.
33
+ - **O plano inteiro, de uma vez.** Sem entregar um pedaço e perguntar "continuo?": cada ida e volta reenvia a conversa inteira, e é isso que gasta.
34
+ - **PRONTO só quando funcionou de verdade.** Teste de código verde não é PRONTO. PRONTO é o checklist do plano todo marcado `[x]`, incluindo a validação de ponta a ponta na tela real. Gate que só o humano fecha (cartão, celular, login) vai pro fim do relatório como passo dele.
35
+ - **O que não está no plano não vira código**: vira pendência escrita. Trecho impossível ou desatualizado: executar todo o resto e registrar o que travou, com o motivo. Nunca inventar caminho alternativo em silêncio.
36
+ - Por que isso economiza: o executor desperdiça em três lugares (reler o projeto que já foi lido, fatiar a entrega, e declarar pronto cedo demais, o que abre uma sessão de correção que relê tudo de novo). O bilhete fecha os três.
37
+ - Sobe um degrau em DOIS casos apenas: implementação pesada em si, ou o EXECUTOR travou 2 vezes no mesmo ponto. Regra de bolso: **sonnet até travar, degrau acima pra destravar** — e subir é FECHAR a aba e abrir outra com `claude --model "opus"`, nunca `/model` na aba aberta;
32
38
  - aba 3: JULGADOR dá o veredito comparando entrega × plano.
33
39
  - O canal entre as abas é sempre um arquivo, nunca copiar e colar conversa.
34
40
 
@@ -53,10 +59,11 @@ Os agentes do Iron Edge já vêm com `model:` por cargo (opus = estrategista, so
53
59
  Depois da medição, grave no `~/.claude/CLAUDE.md` do usuário (backup antes se existir; se a seção `## ESCADA DE MODELOS` já existir, ATUALIZE inteira no lugar, nunca duplique) a seção com:
54
60
  - a regra de ouro;
55
61
  - os três degraus MEDIDOS desta conta;
56
- - o fluxo das 3 abas, com a instrução de salvar o plano em arquivo;
62
+ - o fluxo das 3 abas, com a instrução de salvar o plano em arquivo (e as três seções que o plano precisa ter);
63
+ - o bilhete do executor, pra acordar sozinho quando o usuário disser "executa o plano";
57
64
  - a vacina do /model;
58
65
  - e a ordem de SUGERIR SOZINHO: quando o usuário pedir pra desenhar sistema/arquitetura/decisão grande, avisar em 1 linha que é demanda estrutural e dar o comando da aba do JULGADOR pronto pra copiar; quando um planejamento desses terminar, salvar o plano em arquivo sem pedir e dizer o caminho; quando a execução terminar, lembrar do veredito.
59
66
 
60
67
  Mostre a seção pronta ANTES de salvar. Lembre o usuário: CLAUDE.md novo só vale em sessão nova (fechar e abrir).
61
68
 
62
- **Teste de que pegou** (sessão nova): o usuário pede algo estrutural sem citar modelo nenhum. Critério duplo: (a) o Iron reconheceu sozinho e sugeriu a escada; (b) a sugestão veio com o comando pronto pra copiar. Se respondeu direto sem sugerir, a seção não carregou — conferir arquivo e sessão nova antes de qualquer outra coisa.
69
+ **Teste de que pegou** (sessão nova): o usuário pede algo estrutural sem citar modelo nenhum. Critério triplo: (a) o Iron reconheceu sozinho e sugeriu a escada; (b) a sugestão veio com o comando pronto pra copiar; (c) numa aba de execução, ao dizer "executa o plano: <caminho>", o Iron abriu só os arquivos da lista do plano, entregou de uma vez e fechou com o checklist marcado (ou com o que ficou aberto, nomeado). Se respondeu direto sem sugerir, a seção não carregou — conferir arquivo e sessão nova antes de qualquer outra coisa.
@@ -59,3 +59,8 @@ O método da casa manda avisar, em uma linha, quando a demanda é **estrutural**
59
59
 
60
60
  ## O canal entre sessões é o arquivo
61
61
  Quando o trabalho atravessa sessões — uma planeja, outra executa, outra dá o veredito — o canal é `docs/eng/`, nunca copiar e colar conversa. É por isso que o doc-first e a escada são a mesma coisa vista de dois ângulos: a pasta que este squad escreve é exatamente o canal que a escada exige.
62
+
63
+ ## O plano que o executor recebe, e o bilhete que vai junto
64
+ A skill `escada` é a fonte desta regra; aqui é o resumo pro squad não divergir dela. Um plano que vai ser executado em OUTRA aba precisa de: **data no cabeçalho** (formato AAAA-MM-DD), **(a) arquivos exatos** (caminho + o que muda em cada um), **(b) checklist de gates** com `[ ]`, **(c) validação de ponta a ponta** na tela real, com o estado esperado. O documento de arquitetura deste squad tem o formato dele; quando ele vira o plano de uma execução em aba separada, fecha com essas três seções.
65
+
66
+ Na aba de execução vale o **bilhete do executor**: confie no plano e só escreva o código (o planejador já mapeou o projeto); leia só os arquivos da lista, com uma checagem única no início de "o código mudou desde a data do plano?" (`git status` + `git log --since=<data>`; sem git, pular e registrar); entregue o plano inteiro de uma vez, sem "continuo?"; PRONTO só com o checklist marcado `[x]`, incluindo a validação na tela real; o que não está no plano vira pendência escrita, e trecho travado vira registro com motivo, nunca caminho alternativo em silêncio.
@@ -22,6 +22,9 @@ teto: duas páginas, ADRs à parte
22
22
 
23
23
  6. **Apresente e espere a aprovação** antes de qualquer story ser escrita em cima.
24
24
 
25
+ ## Se este documento vai ser executado em OUTRA aba (escada de três abas)
26
+ Feche-o com a data no cabeçalho (formato AAAA-MM-DD) e as três seções que o executor exige: arquivos exatos, checklist de gates `[ ]`, validação de ponta a ponta na tela real. A regra inteira está em `knowledge-base/escada-e-cargos.md`, seção "O plano que o executor recebe".
27
+
25
28
  ## Meça antes de entregar (não estime)
26
29
 
27
30
  Antes de apresentar o documento, **conte**. Instrução que depende de o autor achar que "ficou mais ou menos do tamanho" é instrução que falha: num teste real, um documento foi entregue como "perto do limite, mas dentro" e estava **acima** do teto quando medido.