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.
- package/README.md +14 -10
- package/agents/iron-3d.md +7 -1
- package/agents/iron-animations.md +14 -7
- package/agents/iron-auditor.md +1 -1
- package/agents/iron-brand.md +16 -7
- package/agents/iron-ceo.md +2 -1
- package/agents/iron-claude.md +16 -9
- package/agents/iron-clone.md +5 -2
- package/agents/iron-cloning.md +14 -7
- package/agents/iron-commercial.md +16 -7
- package/agents/iron-community.md +7 -1
- package/agents/iron-content.md +14 -7
- package/agents/iron-copy.md +16 -7
- package/agents/iron-council.md +16 -7
- package/agents/iron-courses.md +14 -7
- package/agents/iron-cyber.md +14 -7
- package/agents/iron-design.md +16 -7
- package/agents/iron-eng.md +1 -1
- package/agents/iron-finance.md +14 -7
- package/agents/iron-forge.md +1 -1
- package/agents/iron-growth.md +16 -7
- package/agents/iron-install.md +1 -1
- package/agents/iron-paidmedia.md +16 -7
- package/agents/iron-premium.md +1 -1
- package/agents/iron-product.md +16 -7
- package/agents/iron-research.md +14 -7
- package/agents/iron-search.md +1 -1
- package/agents/iron-shopify.md +2 -2
- package/agents/iron-spy.md +21 -9
- package/agents/iron-storytelling.md +16 -7
- package/agents/iron-video.md +7 -1
- package/agents/lp-cinematico.md +1 -1
- package/agents/xq-advisory.md +20 -3
- package/agents/xq-brand.md +19 -2
- package/agents/xq-clevel.md +14 -2
- package/agents/xq-codecore.md +25 -11
- package/agents/xq-copy.md +18 -2
- package/agents/xq-copymaster.md +108 -91
- package/agents/xq-cyber.md +26 -12
- package/agents/xq-data.md +16 -2
- package/agents/xq-design.md +24 -8
- package/agents/xq-hormozi.md +16 -2
- package/agents/xq-movement.md +14 -2
- package/agents/xq-storytelling.md +18 -2
- package/agents/xq-traffic.md +25 -8
- package/bin/iron-edge.js +75 -8
- package/installer/gerados.js +38 -2
- package/installer/install.js +21 -3
- package/installer/update.js +201 -20
- package/iron-routing-map.md +19 -2
- package/package.json +3 -2
- package/skills/blindar-sistema/SKILL.md +123 -0
- package/skills/blindar-sistema/advanced/frieren-opcional.md +61 -0
- package/skills/blindar-sistema/kb/idor.md +94 -0
- package/skills/blindar-sistema/kb/llm-injection.md +86 -0
- package/skills/blindar-sistema/kb/secrets.md +89 -0
- package/skills/blindar-sistema/kb/sqli.md +77 -0
- package/skills/blindar-sistema/procedures/llm-endpoint-hardening.md +80 -0
- package/skills/blindar-sistema/procedures/sandbox-dado-falso.md +63 -0
- package/skills/blindar-sistema/procedures/secret-hygiene.md +72 -0
- package/skills/gate/SKILL.md +6 -0
- package/skills/salvar/SKILL.md +21 -1
- package/squads/squad-brand/agents/al-ries.md +1 -2
- package/squads/squad-brand/agents/alina-wheeler.md +1 -2
- package/squads/squad-brand/agents/brand-orqx.md +2 -0
- package/squads/squad-brand/agents/byron-sharp.md +1 -2
- package/squads/squad-brand/agents/david-aaker.md +1 -2
- package/squads/squad-brand/agents/denise-yohn.md +1 -2
- package/squads/squad-brand/agents/donald-miller.md +1 -2
- package/squads/squad-brand/agents/emily-heyward.md +1 -2
- package/squads/squad-brand/agents/jean-noel-kapferer.md +1 -2
- package/squads/squad-brand/agents/kevin-keller.md +1 -2
- package/squads/squad-brand/agents/marty-neumeier.md +1 -2
- package/squads/squad-cloning/agents/mind-synthesizer.md +1 -0
- package/squads/squad-cloning/agents/source-hunter.md +1 -0
- package/squads/squad-commercial/agents/commercial-orqx.md +2 -0
- package/squads/squad-content/agents/signal-intelligence.md +1 -0
- package/squads/squad-copy/agents/ad-copywriter.md +1 -0
- package/squads/squad-copy/agents/andre-chaperon.md +1 -2
- package/squads/squad-copy/agents/ben-settle.md +1 -2
- package/squads/squad-copy/agents/claude-hopkins.md +1 -2
- package/squads/squad-copy/agents/clayton-makepeace.md +1 -2
- package/squads/squad-copy/agents/copy-orqx.md +2 -0
- package/squads/squad-copy/agents/dan-kennedy.md +1 -2
- package/squads/squad-copy/agents/dan-koe.md +1 -2
- package/squads/squad-copy/agents/david-deutsch.md +1 -2
- package/squads/squad-copy/agents/david-ogilvy.md +1 -2
- package/squads/squad-copy/agents/eugene-schwartz.md +1 -2
- package/squads/squad-copy/agents/frank-kern.md +1 -2
- package/squads/squad-copy/agents/funnel-copywriter.md +1 -0
- package/squads/squad-copy/agents/gary-bencivenga.md +1 -2
- package/squads/squad-copy/agents/gary-halbert.md +1 -2
- package/squads/squad-copy/agents/jim-rutz.md +1 -2
- package/squads/squad-copy/agents/joe-sugarman.md +1 -2
- package/squads/squad-copy/agents/john-carlton.md +1 -2
- package/squads/squad-copy/agents/jon-benson.md +1 -2
- package/squads/squad-copy/agents/parris-lampropoulos.md +1 -2
- package/squads/squad-copy/agents/persuasion-psychologist.md +1 -0
- package/squads/squad-copy/agents/robert-collier.md +1 -2
- package/squads/squad-copy/agents/russell-brunson.md +1 -2
- package/squads/squad-copy/agents/ry-schwartz.md +1 -2
- package/squads/squad-copy/agents/stefan-georgi.md +1 -2
- package/squads/squad-copy/agents/todd-brown.md +1 -2
- package/squads/squad-council/agents/brene-brown.md +1 -2
- package/squads/squad-council/agents/charlie-munger.md +1 -2
- package/squads/squad-council/agents/council-orqx.md +3 -1
- package/squads/squad-council/agents/derek-sivers.md +1 -2
- package/squads/squad-council/agents/naval-ravikant.md +1 -2
- package/squads/squad-council/agents/patrick-lencioni.md +1 -2
- package/squads/squad-council/agents/peter-thiel.md +1 -2
- package/squads/squad-council/agents/ray-dalio.md +1 -2
- package/squads/squad-council/agents/reid-hoffman.md +1 -2
- package/squads/squad-council/agents/simon-sinek.md +1 -2
- package/squads/squad-council/agents/yvon-chouinard.md +1 -2
- package/squads/squad-courses/agents/assessment-creator.md +1 -0
- package/squads/squad-cybersecurity/agents/cloud-security-engineer.md +1 -0
- package/squads/squad-cybersecurity/agents/compliance-officer.md +1 -0
- package/squads/squad-cybersecurity/agents/cyber-orqx.md +1 -0
- package/squads/squad-cybersecurity/agents/incident-responder.md +1 -0
- package/squads/squad-cybersecurity/agents/network-security-engineer.md +1 -0
- package/squads/squad-cybersecurity/agents/penetration-tester.md +1 -0
- package/squads/squad-cybersecurity/agents/soc-analyst.md +1 -0
- package/squads/squad-cybersecurity/agents/threat-analyst.md +1 -0
- package/squads/squad-design/agents/brad-frost.md +4 -3
- package/squads/squad-design/agents/dan-mall.md +4 -3
- package/squads/squad-design/agents/dave-malouf.md +4 -3
- package/squads/squad-design/agents/design-chief.md +2 -0
- package/squads/squad-design/agents/design-orqx.md +2 -0
- package/squads/squad-design/agents/nano-banana-generator.md +1 -0
- package/squads/squad-engineering/agents/eng-devops.md +1 -0
- package/squads/squad-engineering/agents/eng-product.md +1 -0
- package/squads/squad-engineering/agents/eng-sprint.md +1 -0
- package/squads/squad-finance/agents/budget-controller.md +1 -0
- package/squads/squad-growth/agents/growth-orqx.md +2 -0
- package/squads/squad-paidmedia/agents/depesh-mandalia.md +1 -2
- package/squads/squad-paidmedia/agents/kasim-aslam.md +1 -2
- package/squads/squad-paidmedia/agents/molly-pittman.md +1 -2
- package/squads/squad-paidmedia/agents/nicholas-kusmich.md +1 -2
- package/squads/squad-paidmedia/agents/paidmedia-orqx.md +2 -0
- package/squads/squad-paidmedia/agents/pedro-sobral.md +1 -2
- package/squads/squad-paidmedia/agents/ralph-burns.md +1 -2
- package/squads/squad-paidmedia/agents/tom-breeze.md +1 -2
- package/squads/squad-product/agents/product-orqx.md +2 -0
- package/squads/squad-research/agents/audience-intelligence.md +1 -0
- package/squads/squad-research/agents/competitive-intelligence.md +1 -0
- package/squads/squad-research/agents/trend-forecaster.md +1 -0
- package/squads/squad-storytelling/agents/blake-snyder.md +1 -2
- package/squads/squad-storytelling/agents/dan-harmon.md +1 -2
- package/squads/squad-storytelling/agents/joseph-campbell.md +1 -2
- package/squads/squad-storytelling/agents/keith-johnstone.md +1 -2
- package/squads/squad-storytelling/agents/kindra-hall.md +1 -2
- package/squads/squad-storytelling/agents/marshall-ganz.md +1 -2
- package/squads/squad-storytelling/agents/matthew-dicks.md +1 -2
- package/squads/squad-storytelling/agents/nancy-duarte.md +1 -2
- package/squads/squad-storytelling/agents/oren-klaff.md +1 -2
- package/squads/squad-storytelling/agents/park-howell.md +1 -2
- package/squads/squad-storytelling/agents/shawn-coyne.md +1 -2
- package/squads/squad-storytelling/agents/storytelling-orqx.md +2 -0
package/agents/xq-movement.md
CHANGED
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: xq-movement
|
|
3
|
-
description:
|
|
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:
|
|
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:
|
|
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
|
|
package/agents/xq-traffic.md
CHANGED
|
@@ -1,10 +1,27 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: xq-traffic
|
|
3
|
-
description:
|
|
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:
|
|
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: [
|
|
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: [
|
|
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:
|
|
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: [
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(`
|
|
78
|
-
for (const
|
|
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 {
|
package/installer/gerados.js
CHANGED
|
@@ -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
|
-
'
|
|
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 };
|
package/installer/install.js
CHANGED
|
@@ -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
|
-
|
|
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 (_) {
|
|
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
|
-
|
|
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('');
|