iron-edge 2.2.0 → 2.3.1

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 (158) hide show
  1. package/README.md +14 -10
  2. package/agents/iron-3d.md +7 -1
  3. package/agents/iron-animations.md +14 -7
  4. package/agents/iron-auditor.md +1 -1
  5. package/agents/iron-brand.md +16 -7
  6. package/agents/iron-ceo.md +2 -1
  7. package/agents/iron-claude.md +16 -9
  8. package/agents/iron-clone.md +5 -2
  9. package/agents/iron-cloning.md +14 -7
  10. package/agents/iron-commercial.md +16 -7
  11. package/agents/iron-community.md +7 -1
  12. package/agents/iron-content.md +14 -7
  13. package/agents/iron-copy.md +16 -7
  14. package/agents/iron-council.md +16 -7
  15. package/agents/iron-courses.md +14 -7
  16. package/agents/iron-cyber.md +14 -7
  17. package/agents/iron-design.md +16 -7
  18. package/agents/iron-eng.md +1 -1
  19. package/agents/iron-finance.md +14 -7
  20. package/agents/iron-forge.md +1 -1
  21. package/agents/iron-growth.md +16 -7
  22. package/agents/iron-install.md +1 -1
  23. package/agents/iron-paidmedia.md +16 -7
  24. package/agents/iron-premium.md +1 -1
  25. package/agents/iron-product.md +16 -7
  26. package/agents/iron-research.md +14 -7
  27. package/agents/iron-search.md +1 -1
  28. package/agents/iron-shopify.md +2 -2
  29. package/agents/iron-spy.md +21 -9
  30. package/agents/iron-storytelling.md +16 -7
  31. package/agents/iron-video.md +7 -1
  32. package/agents/lp-cinematico.md +1 -1
  33. package/agents/xq-advisory.md +20 -3
  34. package/agents/xq-brand.md +19 -2
  35. package/agents/xq-clevel.md +14 -2
  36. package/agents/xq-codecore.md +25 -11
  37. package/agents/xq-copy.md +18 -2
  38. package/agents/xq-copymaster.md +108 -91
  39. package/agents/xq-cyber.md +26 -12
  40. package/agents/xq-data.md +16 -2
  41. package/agents/xq-design.md +24 -8
  42. package/agents/xq-hormozi.md +16 -2
  43. package/agents/xq-movement.md +14 -2
  44. package/agents/xq-storytelling.md +18 -2
  45. package/agents/xq-traffic.md +25 -8
  46. package/bin/iron-edge.js +75 -8
  47. package/installer/gerados.js +38 -2
  48. package/installer/install.js +21 -3
  49. package/installer/update.js +201 -20
  50. package/iron-routing-map.md +19 -2
  51. package/package.json +3 -2
  52. package/skills/blindar-sistema/SKILL.md +123 -0
  53. package/skills/blindar-sistema/advanced/frieren-opcional.md +61 -0
  54. package/skills/blindar-sistema/kb/idor.md +94 -0
  55. package/skills/blindar-sistema/kb/llm-injection.md +86 -0
  56. package/skills/blindar-sistema/kb/secrets.md +89 -0
  57. package/skills/blindar-sistema/kb/sqli.md +77 -0
  58. package/skills/blindar-sistema/procedures/llm-endpoint-hardening.md +80 -0
  59. package/skills/blindar-sistema/procedures/sandbox-dado-falso.md +63 -0
  60. package/skills/blindar-sistema/procedures/secret-hygiene.md +72 -0
  61. package/skills/gate/SKILL.md +6 -0
  62. package/skills/salvar/SKILL.md +21 -1
  63. package/squads/squad-brand/agents/al-ries.md +1 -2
  64. package/squads/squad-brand/agents/alina-wheeler.md +1 -2
  65. package/squads/squad-brand/agents/brand-orqx.md +2 -0
  66. package/squads/squad-brand/agents/byron-sharp.md +1 -2
  67. package/squads/squad-brand/agents/david-aaker.md +1 -2
  68. package/squads/squad-brand/agents/denise-yohn.md +1 -2
  69. package/squads/squad-brand/agents/donald-miller.md +1 -2
  70. package/squads/squad-brand/agents/emily-heyward.md +1 -2
  71. package/squads/squad-brand/agents/jean-noel-kapferer.md +1 -2
  72. package/squads/squad-brand/agents/kevin-keller.md +1 -2
  73. package/squads/squad-brand/agents/marty-neumeier.md +1 -2
  74. package/squads/squad-cloning/agents/mind-synthesizer.md +1 -0
  75. package/squads/squad-cloning/agents/source-hunter.md +1 -0
  76. package/squads/squad-commercial/agents/commercial-orqx.md +2 -0
  77. package/squads/squad-content/agents/signal-intelligence.md +1 -0
  78. package/squads/squad-copy/agents/ad-copywriter.md +1 -0
  79. package/squads/squad-copy/agents/andre-chaperon.md +1 -2
  80. package/squads/squad-copy/agents/ben-settle.md +1 -2
  81. package/squads/squad-copy/agents/claude-hopkins.md +1 -2
  82. package/squads/squad-copy/agents/clayton-makepeace.md +1 -2
  83. package/squads/squad-copy/agents/copy-orqx.md +2 -0
  84. package/squads/squad-copy/agents/dan-kennedy.md +1 -2
  85. package/squads/squad-copy/agents/dan-koe.md +1 -2
  86. package/squads/squad-copy/agents/david-deutsch.md +1 -2
  87. package/squads/squad-copy/agents/david-ogilvy.md +1 -2
  88. package/squads/squad-copy/agents/eugene-schwartz.md +1 -2
  89. package/squads/squad-copy/agents/frank-kern.md +1 -2
  90. package/squads/squad-copy/agents/funnel-copywriter.md +1 -0
  91. package/squads/squad-copy/agents/gary-bencivenga.md +1 -2
  92. package/squads/squad-copy/agents/gary-halbert.md +1 -2
  93. package/squads/squad-copy/agents/jim-rutz.md +1 -2
  94. package/squads/squad-copy/agents/joe-sugarman.md +1 -2
  95. package/squads/squad-copy/agents/john-carlton.md +1 -2
  96. package/squads/squad-copy/agents/jon-benson.md +1 -2
  97. package/squads/squad-copy/agents/parris-lampropoulos.md +1 -2
  98. package/squads/squad-copy/agents/persuasion-psychologist.md +1 -0
  99. package/squads/squad-copy/agents/robert-collier.md +1 -2
  100. package/squads/squad-copy/agents/russell-brunson.md +1 -2
  101. package/squads/squad-copy/agents/ry-schwartz.md +1 -2
  102. package/squads/squad-copy/agents/stefan-georgi.md +1 -2
  103. package/squads/squad-copy/agents/todd-brown.md +1 -2
  104. package/squads/squad-council/agents/brene-brown.md +1 -2
  105. package/squads/squad-council/agents/charlie-munger.md +1 -2
  106. package/squads/squad-council/agents/council-orqx.md +3 -1
  107. package/squads/squad-council/agents/derek-sivers.md +1 -2
  108. package/squads/squad-council/agents/naval-ravikant.md +1 -2
  109. package/squads/squad-council/agents/patrick-lencioni.md +1 -2
  110. package/squads/squad-council/agents/peter-thiel.md +1 -2
  111. package/squads/squad-council/agents/ray-dalio.md +1 -2
  112. package/squads/squad-council/agents/reid-hoffman.md +1 -2
  113. package/squads/squad-council/agents/simon-sinek.md +1 -2
  114. package/squads/squad-council/agents/yvon-chouinard.md +1 -2
  115. package/squads/squad-courses/agents/assessment-creator.md +1 -0
  116. package/squads/squad-cybersecurity/agents/cloud-security-engineer.md +1 -0
  117. package/squads/squad-cybersecurity/agents/compliance-officer.md +1 -0
  118. package/squads/squad-cybersecurity/agents/cyber-orqx.md +1 -0
  119. package/squads/squad-cybersecurity/agents/incident-responder.md +1 -0
  120. package/squads/squad-cybersecurity/agents/network-security-engineer.md +1 -0
  121. package/squads/squad-cybersecurity/agents/penetration-tester.md +1 -0
  122. package/squads/squad-cybersecurity/agents/soc-analyst.md +1 -0
  123. package/squads/squad-cybersecurity/agents/threat-analyst.md +1 -0
  124. package/squads/squad-design/agents/brad-frost.md +4 -3
  125. package/squads/squad-design/agents/dan-mall.md +4 -3
  126. package/squads/squad-design/agents/dave-malouf.md +4 -3
  127. package/squads/squad-design/agents/design-chief.md +2 -0
  128. package/squads/squad-design/agents/design-orqx.md +2 -0
  129. package/squads/squad-design/agents/nano-banana-generator.md +1 -0
  130. package/squads/squad-engineering/agents/eng-devops.md +1 -0
  131. package/squads/squad-engineering/agents/eng-product.md +1 -0
  132. package/squads/squad-engineering/agents/eng-sprint.md +1 -0
  133. package/squads/squad-finance/agents/budget-controller.md +1 -0
  134. package/squads/squad-growth/agents/growth-orqx.md +2 -0
  135. package/squads/squad-paidmedia/agents/depesh-mandalia.md +1 -2
  136. package/squads/squad-paidmedia/agents/kasim-aslam.md +1 -2
  137. package/squads/squad-paidmedia/agents/molly-pittman.md +1 -2
  138. package/squads/squad-paidmedia/agents/nicholas-kusmich.md +1 -2
  139. package/squads/squad-paidmedia/agents/paidmedia-orqx.md +2 -0
  140. package/squads/squad-paidmedia/agents/pedro-sobral.md +1 -2
  141. package/squads/squad-paidmedia/agents/ralph-burns.md +1 -2
  142. package/squads/squad-paidmedia/agents/tom-breeze.md +1 -2
  143. package/squads/squad-product/agents/product-orqx.md +2 -0
  144. package/squads/squad-research/agents/audience-intelligence.md +1 -0
  145. package/squads/squad-research/agents/competitive-intelligence.md +1 -0
  146. package/squads/squad-research/agents/trend-forecaster.md +1 -0
  147. package/squads/squad-storytelling/agents/blake-snyder.md +1 -2
  148. package/squads/squad-storytelling/agents/dan-harmon.md +1 -2
  149. package/squads/squad-storytelling/agents/joseph-campbell.md +1 -2
  150. package/squads/squad-storytelling/agents/keith-johnstone.md +1 -2
  151. package/squads/squad-storytelling/agents/kindra-hall.md +1 -2
  152. package/squads/squad-storytelling/agents/marshall-ganz.md +1 -2
  153. package/squads/squad-storytelling/agents/matthew-dicks.md +1 -2
  154. package/squads/squad-storytelling/agents/nancy-duarte.md +1 -2
  155. package/squads/squad-storytelling/agents/oren-klaff.md +1 -2
  156. package/squads/squad-storytelling/agents/park-howell.md +1 -2
  157. package/squads/squad-storytelling/agents/shawn-coyne.md +1 -2
  158. package/squads/squad-storytelling/agents/storytelling-orqx.md +2 -0
@@ -1,10 +1,22 @@
1
1
  ---
2
2
  name: xq-movement
3
- description: Movement Chief — especialistas em comunidades, movimentos de marca e mobilização de audiência
3
+ description: "Conselho profundo de movimento de marca: comunidade, arquétipo, manifesto e mobilização. Use quando o usuário disser: 'quero criar um movimento', 'as pessoas não vestem a camisa', 'qual a bandeira da marca', 'vai fundo na comunidade'. Mais lento e mais caro que o iron-community."
4
4
  model: sonnet
5
5
  tools: [Read, Write, Edit, Bash, WebSearch, WebFetch, Glob, Grep]
6
+ squad_files: none
6
7
  ---
7
8
 
9
+ > **Especialistas sem arquivo próprio.** Os especialistas listados abaixo não têm arquivo próprio nesta instalação. Ao rotear pra um deles, VOCÊ assume o método dele, com o framework descrito na entrada dele aqui, e entrega o resultado. Não procure o arquivo, não diga que ele não existe.
10
+
11
+
12
+ ## Como você é acionado
13
+
14
+ **Como subagente** (o Claude Code te acionou com um pedido já escrito, que é o caso normal): não se apresente, não mostre saudação e não pare pra esperar. Escolha o especialista pela matriz abaixo, **assuma você mesmo o método dele** com o framework descrito na entrada dele aqui (os especialistas deste conselho não têm arquivo próprio nesta instalação, e isso está declarado no frontmatter), execute e devolva o ENTREGÁVEL pronto, com uma linha dizendo qual método usou. Nunca devolva só uma saudação nem uma lista de comandos.
15
+
16
+ **Na conversa principal** (o usuário te chamou pelo nome, sem pedido): apresente-se em três linhas e pergunte qual é o pedido. Só aqui você espera.
17
+
18
+ Este é o caminho PROFUNDO: é mais lento e mais caro que o agente `iron-*` equivalente. Se o pedido for simples, diga isso e sugira o `iron-*`.
19
+
8
20
  # Movement Chief
9
21
 
10
22
  > ACTIVATION-NOTICE: You are now the Movement Chief — master orchestrator of the Movement Squad. You command 6 specialist agents spanning phenomenological analysis, identity architecture, growth strategy, manifesto writing, and impact measurement. Your role: assess the movement opportunity, route to the right specialist(s), and coordinate the full movement lifecycle from spark to systemic impact. You don't build movements — you architect the process that builds them. Every revolution needs an operations room. You are it.
@@ -18,7 +30,7 @@ agent:
18
30
  title: "Movement Building Operations Orchestrator"
19
31
  icon: "✊"
20
32
  tier: 0
21
- squad: movement
33
+ squad: interno
22
34
  sub_group: "Orchestration"
23
35
  whenToUse: "When a user wants to build, analyze, or scale a movement. When multiple movement-building disciplines need coordination. When routing movement requests across strategy and execution. When assessing whether an idea has movement potential."
24
36
 
@@ -1,10 +1,26 @@
1
1
  ---
2
2
  name: xq-storytelling
3
- description: Storytelling Chief — Joseph Campbell, Dan Harmon, Oren Klaff, Nancy Duarte para narrativa estratégica
3
+ description: "Conselho profundo de narrativa com os métodos publicados (Campbell, Harmon, Klaff, Duarte). Use quando o usuário disser: 'narrativa no nível dos mestres', 'estrutura de história', 'monta o pitch', 'vai fundo na narrativa', ou quando o iron-storytelling não bastou. Mais lento e mais caro que o iron-storytelling."
4
4
  model: sonnet
5
5
  tools: [Read, Write, Edit, Bash, WebSearch, WebFetch, Glob, Grep]
6
6
  ---
7
7
 
8
+ > **Pessoa real.** Especialistas marcados com `real_person: true` seguem a seção "Especialistas com nome de pessoa real" do `~/.iron/iron-routing-map.md`: aplicam o método, não personificam, não atribuem fala nova, não assinam. Leia a seção antes de assumir um deles.
9
+
10
+
11
+ ## Como você é acionado
12
+
13
+ **Como subagente** (o Claude Code te acionou com um pedido já escrito, que é o caso normal): não se apresente, não mostre saudação e não pare pra esperar. Faça, nesta ordem:
14
+
15
+ 1. Leia a matriz de roteamento abaixo e escolha o especialista certo para o pedido.
16
+ 2. **Leia o arquivo do especialista** em `~/.iron/squad-storytelling/agents/<id>.md` antes de assumir o papel dele. O método está lá, escrito; não improvise de memória.
17
+ 3. Execute o pedido e devolva o ENTREGÁVEL pronto, com uma linha dizendo qual especialista ou método usou.
18
+ 4. Nunca devolva só uma saudação, uma lista de comandos ou uma pergunta que o prompt já responde.
19
+
20
+ **Na conversa principal** (o usuário te chamou pelo nome, sem pedido): apresente-se em três linhas e pergunte qual é o pedido. Só aqui você espera.
21
+
22
+ Este é o caminho PROFUNDO: é mais lento e mais caro que o agente `iron-*` equivalente. Se o pedido for simples, diga isso e sugira o `iron-*`.
23
+
8
24
  # Story Chief
9
25
 
10
26
  > ACTIVATION-NOTICE: You are now the Story Chief — master orchestrator of the Storytelling Squad. You command 11 world-class narrative specialists spanning mythology, screenwriting, personal storytelling, business narrative, improvisation, pitching, and movement building. Your role: diagnose the narrative challenge, route to the right specialist(s), and synthesize their wisdom into actionable storytelling strategy. You don't tell stories — you architect the storytelling process.
@@ -18,7 +34,7 @@ agent:
18
34
  title: "Storytelling Squad Orchestrator — Narrative Intelligence Router"
19
35
  icon: "📖"
20
36
  tier: 0
21
- squad: storytelling
37
+ squad: squad-storytelling
22
38
  sub_group: "Orchestration"
23
39
  whenToUse: "When a user needs storytelling help but isn't sure which specialist to consult. When multiple narrative frameworks need integration. When routing storytelling requests across domains."
24
40
 
@@ -1,10 +1,27 @@
1
1
  ---
2
2
  name: xq-traffic
3
- description: Traffic Masters Chief — Kasim Aslam, Pedro Sobral, Molly Pittman, Tom Breeze para tráfego pago
3
+ description: "Conselho profundo de tráfego com os métodos publicados (Kasim, Sobral, Pittman, Breeze). Use quando o usuário disser: 'tráfego no nível dos mestres', 'diagnostica a conta inteira', 'vai fundo na campanha', ou quando o iron-paidmedia não bastou. Mais lento e mais caro que o iron-paidmedia."
4
4
  model: sonnet
5
5
  tools: [Read, Write, Edit, Bash, WebSearch, WebFetch, Glob, Grep]
6
+ known_non_agents: [traffic-chief]
6
7
  ---
7
8
 
9
+ > **Pessoa real.** Especialistas marcados com `real_person: true` seguem a seção "Especialistas com nome de pessoa real" do `~/.iron/iron-routing-map.md`: aplicam o método, não personificam, não atribuem fala nova, não assinam. Leia a seção antes de assumir um deles.
10
+
11
+
12
+ ## Como você é acionado
13
+
14
+ **Como subagente** (o Claude Code te acionou com um pedido já escrito, que é o caso normal): não se apresente, não mostre saudação e não pare pra esperar. Faça, nesta ordem:
15
+
16
+ 1. Leia a matriz de roteamento abaixo e escolha o especialista certo para o pedido.
17
+ 2. **Leia o arquivo do especialista** em `~/.iron/squad-paidmedia/agents/<id>.md` antes de assumir o papel dele. O método está lá, escrito; não improvise de memória.
18
+ 3. Execute o pedido e devolva o ENTREGÁVEL pronto, com uma linha dizendo qual especialista ou método usou.
19
+ 4. Nunca devolva só uma saudação, uma lista de comandos ou uma pergunta que o prompt já responde.
20
+
21
+ **Na conversa principal** (o usuário te chamou pelo nome, sem pedido): apresente-se em três linhas e pergunte qual é o pedido. Só aqui você espera.
22
+
23
+ Este é o caminho PROFUNDO: é mais lento e mais caro que o agente `iron-*` equivalente. Se o pedido for simples, diga isso e sugira o `iron-*`.
24
+
8
25
  # Traffic Chief
9
26
 
10
27
  > ACTIVATION-NOTICE: You are the Traffic Chief — orchestrator of the Traffic Masters Squad. You do NOT buy media or write ads. You DIAGNOSE traffic problems, ROUTE them to the correct specialist, and REVIEW their output. You think in platforms, funnels, metrics, and creative. Every traffic problem maps to a platform expert or functional specialist.
@@ -18,7 +35,7 @@ agent:
18
35
  title: "Traffic Masters Orchestrator"
19
36
  icon: "🎯"
20
37
  tier: 0
21
- squad: traffic-masters
38
+ squad: squad-paidmedia
22
39
  role: orchestrator
23
40
 
24
41
  persona:
@@ -51,22 +68,22 @@ routing_logic:
51
68
  function_specific:
52
69
  creative_problem:
53
70
  signals: ["ads not getting clicks", "creative fatigue", "need better ad creative", "low CTR"]
54
- route_to: [ad-midas, creative-analyst]
71
+ route_to: [nicholas-kusmich, creative-strategist]
55
72
  scaling_problem:
56
73
  signals: ["can't scale spend", "CPA increases with budget", "diminishing returns"]
57
- route_to: [scale-optimizer, depesh-mandalia]
74
+ route_to: [ralph-burns, depesh-mandalia]
58
75
  tracking_problem:
59
76
  signals: ["attribution issues", "pixel not firing", "iOS tracking", "conversion tracking broken"]
60
- route_to: pixel-specialist
77
+ route_to: performance-engineer
61
78
  analysis_problem:
62
79
  signals: ["don't know what's working", "need audit", "can't read the data"]
63
- route_to: [performance-analyst, ads-analyst]
80
+ route_to: [campaign-analyst, pm-creative-performance-analyst]
64
81
  budget_problem:
65
82
  signals: ["budget allocation", "cashflow for ads", "ROAS targets", "profitability"]
66
- route_to: fiscal
83
+ route_to: campaign-analyst
67
84
  execution_problem:
68
85
  signals: ["need someone to set up campaigns", "campaign structure", "media buying"]
69
- route_to: media-buyer
86
+ route_to: meta-ads-specialist
70
87
 
71
88
  quality_review:
72
89
  checks:
package/bin/iron-edge.js CHANGED
@@ -23,7 +23,16 @@ const os = require('os');
23
23
  const crypto = require('crypto');
24
24
  const { spawnSync } = require('child_process');
25
25
 
26
- const HOME = os.homedir();
26
+ // a versao publicada: unica fonte e o package.json do proprio pacote.
27
+ // sem isso o instalador cai no fallback sem numero e o verify nao sabe dizer a versao.
28
+ let PKG_VERSION = '';
29
+ try { PKG_VERSION = require('../package.json').version || ''; } catch (_) {}
30
+
31
+ // O install grava o `dest` no manifesto com o HOME resolvido (`fs.realpathSync.native`). Comparar
32
+ // com o HOME cru nao casa quando o perfil esta atras de symlink ou redirecionado — e o `update`
33
+ // ja' documenta esse caso como real. Sem isto, o config do usuario volta a reprovar naquela maquina.
34
+ let HOME = os.homedir();
35
+ try { HOME = fs.realpathSync.native(HOME); } catch (_) {}
27
36
  const cmd = process.argv[2];
28
37
  const rest = process.argv.slice(3);
29
38
 
@@ -36,7 +45,7 @@ if (cmd === 'install') {
36
45
  const pkgRoot = path.join(__dirname, '..');
37
46
  const args = [path.join(pkgRoot, 'installer', 'install.js'), ...rest];
38
47
  if (!rest.includes('--source')) args.push('--source', pkgRoot);
39
- const r = spawnSync(process.execPath, args, { stdio: 'inherit' });
48
+ const r = spawnSync(process.execPath, args, { stdio: 'inherit', env: { ...process.env, IRON_EDGE_VERSION: PKG_VERSION } });
40
49
  process.exit(r.status ?? 1);
41
50
 
42
51
  } else if (cmd === 'update') {
@@ -44,7 +53,7 @@ if (cmd === 'install') {
44
53
  const pkgRoot = path.join(__dirname, '..');
45
54
  const args = [path.join(pkgRoot, 'installer', 'update.js'), ...rest];
46
55
  if (!rest.includes('--source')) args.push('--source', pkgRoot);
47
- const r = spawnSync(process.execPath, args, { stdio: 'inherit' });
56
+ const r = spawnSync(process.execPath, args, { stdio: 'inherit', env: { ...process.env, IRON_EDGE_VERSION: PKG_VERSION } });
48
57
  process.exit(r.status ?? 1);
49
58
 
50
59
  } else if (cmd === 'verify') {
@@ -54,15 +63,58 @@ if (cmd === 'install') {
54
63
  console.error('Se o Iron foi instalado por um metodo antigo, reinstale com: iron-edge install');
55
64
  process.exit(1);
56
65
  }
57
- const man = JSON.parse(fs.readFileSync(manPath, 'utf8'));
66
+ let man;
67
+ try { man = JSON.parse(fs.readFileSync(manPath, 'utf8')); }
68
+ catch (e) {
69
+ // o update ja tratava este caso e o verify nao: gravacao interrompida, antivirus ou disco cheio
70
+ // deixavam o aluno com um stack trace cru em ingles no lugar de uma instrucao.
71
+ console.error('verify: o manifesto existe mas nao e JSON valido (' + e.message + ').');
72
+ console.error('Reinstale com: npx iron-edge install — seus arquivos proprios nao sao tocados.');
73
+ process.exit(1);
74
+ }
58
75
  const files = man.files || [];
59
- let alterados = [], sumidos = [];
76
+
77
+ // Quais arquivos sao da PESSOA: lista explicita, declarada em gerados.js.
78
+ // A versao anterior deste bloco deduzia por regra — "gerado no install e nao declarado como
79
+ // do pacote" — e a deducao generalizou errado: metadata.json tambem nasce gerado e NUNCA e'
80
+ // reescrito por ninguem, entao divergencia nele e' corrupcao, nao personalizacao, e passou a
81
+ // sair aprovada com exit 0. Regra que deduz pertencimento erra no arquivo que ninguem lembrou.
82
+ //
83
+ // E se o require falhar (instalacao pela metade, pasta installer/ ausente), a lista fica
84
+ // VAZIA e nada e' tratado como seu: tudo que divergir cai em "alterados" e reprova. Falha
85
+ // FECHADO de proposito. A versao anterior falhava aberta — sem a lista, ate o atalho /iron
86
+ // adulterado virava "seu" e saia com exit 0.
87
+ let doUsuario = new Set();
88
+ try {
89
+ const { arquivosDoUsuario } = require('../installer/gerados');
90
+ for (const d of arquivosDoUsuario({ IRON_DIR: path.join(HOME, '.iron') })) doUsuario.add(d);
91
+ } catch (e) { /* lista vazia = ninguem e' "seu" = tudo divergente reprova */ }
92
+
93
+ // TRES baldes, e a fronteira e' "ha registro de que isto e seu?", nao "mudou?".
94
+ // seus = seu por natureza (config, integracoes) ou marcado user_modified -> NAO reprova
95
+ // alterados = difere do pacote e ninguem registrou que foi voce -> reprova
96
+ // ausentes = sumiu do disco -> reprova
97
+ //
98
+ // Arquivo do usuario entra em "seus" SEMPRE, batendo o hash ou nao. Nao se compara hash aqui
99
+ // de proposito: o `update` regrava o manifesto com o hash do disco, entao qualquer balde que
100
+ // dependa de divergencia de hash esvazia sozinho na primeira atualizacao. Foi exatamente esse
101
+ // o defeito que um relatorio de campo pegou nos arquivos do pacote — e que a primeira tentativa
102
+ // de conserto recriou nos arquivos de config, pelo mesmo caminho.
103
+ let alterados = [], sumidos = [], seus = [];
60
104
  for (const f of files) {
61
105
  const dest = f.dest || f.path || f;
62
106
  const want = f.sha256 || f.hash;
63
107
  if (!dest || !want) continue;
64
108
  if (!fs.existsSync(dest)) { sumidos.push(dest); continue; }
65
- if (sha256(dest) !== want) alterados.push(dest);
109
+ // Compara os DOIS lados resolvidos, como o update.js ja faz: o install so' passou a gravar
110
+ // o dest resolvido a partir de certa versao, entao manifesto antigo tem caminho cru. Assumir
111
+ // um formato so' faz o config do usuario voltar a reprovar na maquina com perfil redirecionado.
112
+ let real = dest;
113
+ try { real = fs.realpathSync.native(dest); } catch (_) {}
114
+ if (doUsuario.has(dest) || doUsuario.has(real)) { seus.push({ dest, motivo: 'seu: config e integracoes, o update nunca encosta' }); continue; }
115
+ const igual = sha256(dest) === want;
116
+ if (f.user_modified) { seus.push({ dest, motivo: igual ? 'voce editou este arquivo do pacote' : 'voce editou de novo depois da ultima atualizacao' }); continue; }
117
+ if (!igual) alterados.push({ dest });
66
118
  }
67
119
  console.log(`Iron Edge — verificacao da instalacao`);
68
120
  if (man.label) console.log(` edicao: ${man.label}`);
@@ -74,10 +126,25 @@ if (cmd === 'install') {
74
126
  }
75
127
  if (man.installed_at) console.log(` instalado em: ${man.installed_at}`);
76
128
  console.log(` arquivos no manifesto: ${files.length}`);
77
- console.log(` alterados pelo usuario: ${alterados.length}`);
78
- for (const a of alterados) console.log(` ~ ${a}`);
129
+ console.log(` seus, o update nao encosta: ${seus.length}`);
130
+ for (const x of seus) console.log(` * ${x.dest} (${x.motivo})`);
131
+ // Aqui havia uma instrucao de remedio ("apague o arquivo e rode update"). Ela foi REMOVIDA,
132
+ // nao reescrita: o balde reune duas classes de arquivo e a frase so' valia para uma. No
133
+ // config.yaml, apagar destroi o vault_path e o update recria em branco; no shopify.yaml o
134
+ // arquivo some de vez, porque ele nao esta em arquivosGerados() e o update nao o repoe.
135
+ // Instrucao errada e' pior que instrucao nenhuma. Como reverter continua dito no proprio
136
+ // update.js, no bloco `preservar` — aparece na tela quando a pessoa roda o update.
137
+ console.log(` alterados sem registro: ${alterados.length}`);
138
+ for (const a of alterados) console.log(` ~ ${a.dest}`);
139
+ if (alterados.length) {
140
+ console.log(` Estes diferem do pacote e ninguem registrou que a edicao foi sua. Se foi voce, rode`);
141
+ console.log(` "iron-edge update" uma vez: ele passa a reconhecer a edicao e para de acusar.`);
142
+ }
79
143
  console.log(` ausentes: ${sumidos.length}`);
80
144
  for (const s of sumidos) console.log(` x ${s}`);
145
+ // "seus" NAO reprova: e' o estado esperado de quem preencheu o config ou personalizou um
146
+ // agente. Reprovar o caminho que o produto MANDA seguir treina a pessoa a ignorar o verify.
147
+ // Reprovam so' divergencia sem registro e arquivo sumido.
81
148
  process.exit(alterados.length + sumidos.length === 0 ? 0 : 1);
82
149
 
83
150
  } else {
@@ -17,9 +17,36 @@
17
17
  'use strict';
18
18
  const path = require('path');
19
19
 
20
+ // Os arquivos que nascem na instalacao e pertencem a PESSOA: ela preenche, ela edita, e nem
21
+ // o install nem o update reescrevem. Ficam declarados aqui, um por um, e nao deduzidos por
22
+ // regra ("tudo que e gerado e nao e do pacote"), porque a deducao ja errou: metadata.json
23
+ // tambem nasce gerado, NUNCA e' reescrito por ninguem, e por isso qualquer divergencia nele e'
24
+ // corrupcao — nao personalizacao. Lista explicita nao tem como generalizar errado.
25
+ function arquivosDoUsuario({ IRON_DIR }) {
26
+ return [
27
+ path.join(IRON_DIR, 'config.yaml'),
28
+ // Medido no gate de 20/09: sem esta linha, quem LIGA a integracao (a unica razao do arquivo
29
+ // existir) passa a ter o verify reprovando para sempre, e o `update` que a mensagem receita
30
+ // nao conserta — o processo sai em "Nada a fazer" antes da fase que regravaria o hash.
31
+ // Arquivo APAGADO continua caindo em "sumidos": o verify checa existencia ANTES de checar dono.
32
+ path.join(IRON_DIR, 'integrations', 'shopify.yaml'),
33
+ ];
34
+ }
35
+
20
36
  function arquivosGerados({ IRON_DIR, CLAUDE_DIR }) {
21
37
  const COMMANDS = path.join(CLAUDE_DIR, 'commands');
22
38
  return [
39
+ {
40
+ // A integracao da Shopify entra aqui, e nao so' no install.js, porque enquanto ela viveu
41
+ // fora desta lista o `update` nao sabia recria-la: quem apagasse o arquivo ficava com o
42
+ // `verify` acusando "ausentes: 1" para sempre, sem caminho de volta. Era divida conhecida
43
+ // desde `c44a965` e virou defeito medido na matriz de estados de 20/09/2026.
44
+ // `sobrescrever: false` mantem a outra metade da promessa: se o arquivo existe, ninguem encosta.
45
+ dest: path.join(IRON_DIR, 'integrations', 'shopify.yaml'),
46
+ oQueE: 'a config da integracao com a Shopify',
47
+ sobrescrever: false,
48
+ conteudo: 'enabled: false\nendpoint: ""\napi_key_file: ""\n',
49
+ },
23
50
  {
24
51
  dest: path.join(IRON_DIR, 'config.yaml'),
25
52
  oQueE: 'a config inicial',
@@ -41,7 +68,16 @@ function arquivosGerados({ IRON_DIR, CLAUDE_DIR }) {
41
68
  '#',
42
69
  '# Ainda nao tem? Peca ao Iron: "cria meu cofre". Ele monta a estrutura no lugar que',
43
70
  '# voce escolher e preenche este campo sozinho. Leva um minuto.',
44
- 'vault_path: "" # ex: ~/Documents/Cofre',
71
+ '#',
72
+ '# WINDOWS: escreva o caminho com BARRA NORMAL, nunca com barra invertida. O Windows',
73
+ '# aceita as duas; o YAML, nao. Barra invertida dentro de aspas e escape, entao o \\U de',
74
+ '# C:\\Users pede um codigo Unicode que nao existe e o arquivo INTEIRO fica invalido —',
75
+ '# voce perde o owner junto. E nao da erro na tela: o Iron so passa a responder generico',
76
+ '# e a oferecer criar um cofre que ja existe, com o seu cheio do lado.',
77
+ '#',
78
+ '# Exemplos: mac/linux ~/Documents/Cofre',
79
+ '# windows C:/Users/<voce>/Documents/Cofre',
80
+ 'vault_path: ""',
45
81
  '',
46
82
  '# focus: dev # prioriza o iron-eng (engenharia de software) no roteamento.',
47
83
  '# # descomente se o seu uso principal for programar.',
@@ -103,4 +139,4 @@ function arquivosGerados({ IRON_DIR, CLAUDE_DIR }) {
103
139
  ];
104
140
  }
105
141
 
106
- module.exports = { arquivosGerados };
142
+ module.exports = { arquivosGerados, arquivosDoUsuario };
@@ -31,7 +31,9 @@ const crypto = require('crypto');
31
31
  let IRON_VERSION = 'iron-edge-2.x';
32
32
  let IRON_VERSION_HUMAN = 'Iron Edge';
33
33
 
34
- function log(msg) { process.stdout.write(msg + '\n'); }
34
+ // Sincrono pelo mesmo motivo do update.js: em Windows, saida em cano + process.exit() perde o
35
+ // que estava na fila, e o log do instalador e' justamente o que o aluno cola quando pede ajuda.
36
+ function log(msg) { try { fs.writeSync(1, msg + '\n'); } catch (_) { process.stdout.write(msg + '\n'); } }
35
37
  function abort(msg) {
36
38
  process.stderr.write('\n[ABORTADO] ' + msg + '\n');
37
39
  process.exit(1);
@@ -50,7 +52,11 @@ try {
50
52
  const ed = JSON.parse(fs.readFileSync(path.join(SOURCE, 'edition.json'), 'utf8'));
51
53
  if (ed.label) IRON_VERSION_HUMAN = ed.label + ' v' + (ed.version || '');
52
54
  if (ed.name) IRON_VERSION = ed.name + '-' + (ed.version || '');
53
- } catch (_) { /* payload sem edition.json: fica o fallback */ }
55
+ } catch (_) {
56
+ // payload sem edition.json (o caso do npm): a versao vem do package.json, via bin/iron-edge.js
57
+ const v = process.env.IRON_EDGE_VERSION || '';
58
+ if (v) { IRON_VERSION = 'iron-edge-' + v; IRON_VERSION_HUMAN = 'Iron Edge v' + v; }
59
+ }
54
60
 
55
61
  let HOME = os.homedir();
56
62
  try { HOME = fs.realpathSync.native(HOME); } catch (_) {}
@@ -449,6 +455,12 @@ for (const d of [path.join(IRON_DIR, 'integrations'), path.join(IRON_DIR, 'secre
449
455
  criarPasta(d, 'as pastas de estado');
450
456
  }
451
457
 
458
+ // A pasta de segredos nasce fechada. O proprio LEIA-ME dela diz "para as SUAS credenciais", e ate
459
+ // o gate de 20/09 ela nascia 755: em maquina compartilhada (laboratorio, escritorio, familia),
460
+ // qualquer outro usuario local lia o que fosse colocado ali. chmod nao existe em Windows e falha
461
+ // aberto de proposito: sem permissao POSIX, o diretorio ja herda a ACL do perfil do usuario.
462
+ try { fs.chmodSync(path.join(IRON_DIR, 'secrets'), 0o700); } catch (_) {}
463
+
452
464
  // memoria por cargo do squad-engineering: pasta vazia, FORA do manifesto de propósito.
453
465
  // O que a maquina aprendeu nao e gerenciado pelo instalador — update de pacote nunca apaga.
454
466
  // Cada arquivo <cargo>.md nasce do template na primeira vez que o cargo roda.
@@ -456,6 +468,8 @@ criarPasta(path.join(IRON_DIR, 'memory', 'squad-engineering'), 'a pasta de memor
456
468
 
457
469
  const shopifyYaml = path.join(IRON_DIR, 'integrations', 'shopify.yaml');
458
470
  escrever(shopifyYaml, 'enabled: false\nendpoint: ""\napi_key_file: ""\n', 'a config da integracao');
471
+ // o arquivo que aponta pra chave tambem nao e' de leitura publica
472
+ try { fs.chmodSync(shopifyYaml, 0o600); } catch (_) {}
459
473
 
460
474
  const installedAt = new Date().toISOString();
461
475
 
@@ -539,6 +553,8 @@ log(`Manifesto: ${manifestPath}`);
539
553
  log('\n--------------------------------');
540
554
  log(' PROXIMO PASSO');
541
555
  log('--------------------------------');
556
+ log('0. Use no terminal. Se voce usa VS Code, abra o terminal integrado (Ctrl+crase) e rode: claude');
557
+ log('');
542
558
  log('1. Reabra o Claude Code. Agente novo so aparece em sessao nova.');
543
559
  log('');
544
560
  log('2. Chame o orquestrador. Escreva so isto:');
@@ -549,7 +565,9 @@ log(' So a palavra, sem barra e sem traco. Se preferir a barra, /iron faz o me
549
565
  log(' e da pra ja mandar o pedido junto: iron preciso da copy desse anuncio');
550
566
  log('');
551
567
  log(' Os outros 43 agentes se chamam PEDINDO ("usa o iron-copy").');
552
- log(' As 14 SKILLS sao de barra: /gate /salvar /brandkit /escada ...');
568
+ // o numero sai do disco: ele ja nasceu errado uma vez (14 quando eram 15) e ninguem viu
569
+ const nSkills = (() => { try { return fs.readdirSync(path.join(SOURCE, 'skills')).filter((d) => !d.startsWith('.')).length; } catch (_) { return null; } })();
570
+ log(` As ${nSkills || ''} SKILLS sao de barra: /gate /salvar /brandkit /escada ...`.replace(' ', ' '));
553
571
  log('');
554
572
  log('3. Ligue a memoria. Diga a ele:');
555
573
  log('');