predators-protocol 0.4.0-beta.0 → 0.5.2-beta.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.
@@ -0,0 +1,210 @@
1
+ // packages/predators-protocol/lib/gen-token-client.js
2
+ //
3
+ // CLI gen-token canon · Apex T7 gera tokens via terminal
4
+ // Owner: Borboleta-azul (Designer T3) + Polvo (cross-doc API integration)
5
+ // Lei #1 SEVERA gates:
6
+ // [ok1] PREDATORS_OWNER_KEY_BACKEND env var canon (não-confundir com OWN_ runtime)
7
+ // [ok3] header X-Owner-Key (não query string · evita leak URL logs)
8
+ //
9
+ // Uso:
10
+ // export PREDATORS_OWNER_KEY_BACKEND="<seu-secret-canon>"
11
+ // npx predators-protocol gen-token --name "José Silva" --email jose@ex.com
12
+ // npx predators-protocol gen-token -n "Maria" --notes "DevOps Q3" --no-email
13
+
14
+ "use strict";
15
+
16
+ const https = require("https");
17
+ const { URL } = require("url");
18
+
19
+ const API_ENDPOINT_DEFAULT =
20
+ process.env.PREDATORS_API_ENDPOINT ||
21
+ "https://predators-protocol.vercel.app/api/admin/access-tokens";
22
+
23
+ function parseArgs(argv) {
24
+ const args = {};
25
+ for (let i = 0; i < argv.length; i++) {
26
+ const a = argv[i];
27
+ if (a === "--name" || a === "-n") args.name = argv[++i];
28
+ else if (a === "--email" || a === "-e") args.email = argv[++i];
29
+ else if (a === "--notes") args.notes = argv[++i];
30
+ else if (a === "--prefix") args.prefix = argv[++i];
31
+ else if (a === "--expires") args.expires = argv[++i];
32
+ else if (a === "--no-email") args.send_email = false;
33
+ else if (a === "--perm") {
34
+ args.permissions = args.permissions || [];
35
+ args.permissions.push(argv[++i]);
36
+ } else if (a === "--list" || a === "-l") args.list = true;
37
+ else if (a === "--help" || a === "-h") args.help = true;
38
+ }
39
+ return args;
40
+ }
41
+
42
+ function printHelp() {
43
+ console.log(`
44
+ predators-protocol gen-token · gera tokens colaborador via CLI
45
+
46
+ USO:
47
+ npx predators-protocol gen-token --name "Nome" [opções]
48
+
49
+ OPÇÕES:
50
+ --name, -n <name> Nome do colaborador (obrigatório)
51
+ --email, -e <email> Email (opcional · auto-send email canon)
52
+ --notes <text> Notas internas (ex: "DevOps Q3-2026")
53
+ --prefix <COL|OWN> Tipo · default COL (colaborador)
54
+ --expires <YYYY-MM-DD> Data expiração (opcional · sem expiry default)
55
+ --perm <permission> Permissão (pode repetir · default 3 canon)
56
+ --no-email Não envia email automático
57
+ --list, -l Lista tokens existentes
58
+ --help, -h Esta mensagem
59
+
60
+ AUTHENTICATION:
61
+ export PREDATORS_OWNER_KEY_BACKEND="<seu-secret-canon>"
62
+ (mesmo valor que setou em Vercel env var no dashboard project)
63
+
64
+ ENDPOINT (opcional override):
65
+ export PREDATORS_API_ENDPOINT="https://meu-deploy.vercel.app/api/admin/access-tokens"
66
+
67
+ EXEMPLOS:
68
+ npx predators-protocol gen-token -n "José Silva" -e jose@email.com
69
+ npx predators-protocol gen-token -n "Maria" --notes "freelance DevOps Q3"
70
+ npx predators-protocol gen-token -l # lista todos tokens ativos
71
+ `);
72
+ }
73
+
74
+ function makeRequest(method, endpoint, ownerKey, body) {
75
+ return new Promise((resolve, reject) => {
76
+ const url = new URL(endpoint);
77
+ const reqBody = body ? JSON.stringify(body) : null;
78
+ const req = https.request(
79
+ {
80
+ hostname: url.hostname,
81
+ port: url.port || 443,
82
+ path: url.pathname,
83
+ method,
84
+ headers: {
85
+ "Content-Type": "application/json",
86
+ "x-owner-key": ownerKey,
87
+ "User-Agent": "predators-protocol-cli/gen-token",
88
+ ...(reqBody ? { "Content-Length": Buffer.byteLength(reqBody) } : {}),
89
+ },
90
+ timeout: 15_000,
91
+ },
92
+ (res) => {
93
+ let data = "";
94
+ res.on("data", (chunk) => (data += chunk));
95
+ res.on("end", () => {
96
+ try {
97
+ const parsed = JSON.parse(data);
98
+ resolve({ status: res.statusCode, body: parsed });
99
+ } catch {
100
+ resolve({ status: res.statusCode, body: { raw: data } });
101
+ }
102
+ });
103
+ },
104
+ );
105
+ req.on("error", reject);
106
+ req.on("timeout", () => {
107
+ req.destroy();
108
+ reject(new Error("timeout"));
109
+ });
110
+ if (reqBody) req.write(reqBody);
111
+ req.end();
112
+ });
113
+ }
114
+
115
+ async function runGenToken() {
116
+ const args = parseArgs(process.argv.slice(3));
117
+
118
+ if (args.help) {
119
+ printHelp();
120
+ return;
121
+ }
122
+
123
+ const ownerKey = process.env.PREDATORS_OWNER_KEY_BACKEND;
124
+ if (!ownerKey) {
125
+ console.error("ERRO: PREDATORS_OWNER_KEY_BACKEND env var não-setada.");
126
+ console.error("");
127
+ console.error("Setup canon:");
128
+ console.error(' export PREDATORS_OWNER_KEY_BACKEND="<seu-secret>"');
129
+ console.error("");
130
+ console.error("Mesmo valor deve estar em Vercel env vars do projeto dashboard.");
131
+ process.exit(1);
132
+ }
133
+
134
+ // List mode
135
+ if (args.list) {
136
+ console.log("Buscando tokens existentes...");
137
+ const result = await makeRequest("GET", API_ENDPOINT_DEFAULT, ownerKey, null);
138
+ if (result.status !== 200) {
139
+ console.error(`HTTP ${result.status} · ${JSON.stringify(result.body)}`);
140
+ process.exit(1);
141
+ }
142
+ const tokens = result.body.tokens || [];
143
+ console.log(`\n${tokens.length} token(s) registrado(s):\n`);
144
+ for (const t of tokens) {
145
+ const isRevoked = t.revoked_at !== null;
146
+ const status = isRevoked ? "REVOGADO" : "ATIVO";
147
+ const created = (t.created_at || "").slice(0, 10);
148
+ const lastUsed = t.last_used_at ? (t.last_used_at || "").slice(0, 10) : "nunca";
149
+ console.log(` [${status}] ${t.prefix} · ${t.collaborator_name}`);
150
+ console.log(` email: ${t.collaborator_email || "—"}`);
151
+ console.log(` created: ${created} · last_used: ${lastUsed}`);
152
+ if (t.notes) console.log(` notes: ${t.notes}`);
153
+ console.log("");
154
+ }
155
+ return;
156
+ }
157
+
158
+ // Create mode
159
+ if (!args.name) {
160
+ console.error("ERRO: --name é obrigatório.");
161
+ console.error("Use: npx predators-protocol gen-token --help");
162
+ process.exit(1);
163
+ }
164
+
165
+ const body = {
166
+ collaborator_name: args.name,
167
+ collaborator_email: args.email,
168
+ notes: args.notes,
169
+ prefix: args.prefix || "COL",
170
+ expires_at: args.expires,
171
+ permissions: args.permissions,
172
+ send_email: args.send_email !== false,
173
+ };
174
+
175
+ console.log("Gerando token canon...");
176
+ const result = await makeRequest("POST", API_ENDPOINT_DEFAULT, ownerKey, body);
177
+
178
+ if (result.status !== 201) {
179
+ console.error(`Falha · HTTP ${result.status}`);
180
+ console.error(JSON.stringify(result.body, null, 2));
181
+ process.exit(1);
182
+ }
183
+
184
+ const { token, plaintext, email_sent, email_error, warning_canon } = result.body;
185
+ console.log("");
186
+ console.log("==========================================");
187
+ console.log(" TOKEN GERADO · copie AGORA (uma única vez)");
188
+ console.log("==========================================");
189
+ console.log("");
190
+ console.log(` Token: ${plaintext}`);
191
+ console.log("");
192
+ console.log(` Para o colaborador rodar:`);
193
+ console.log(` npx predators-protocol unlock ${plaintext}`);
194
+ console.log("");
195
+ if (warning_canon) console.log(` ${warning_canon}`);
196
+ console.log("");
197
+ console.log(` Colaborador: ${token.collaborator_name} · prefix ${token.prefix}`);
198
+ console.log(` Permissões: ${token.permissions.join(", ")}`);
199
+ if (token.expires_at) {
200
+ console.log(` Expira: ${new Date(token.expires_at).toLocaleDateString("pt-BR")}`);
201
+ }
202
+ if (email_sent) {
203
+ console.log(` Email enviado para: ${token.collaborator_email}`);
204
+ } else if (email_error) {
205
+ console.log(` ATENCAO email falhou: ${email_error}`);
206
+ }
207
+ console.log("");
208
+ }
209
+
210
+ module.exports = { runGenToken, printHelp };
@@ -0,0 +1,147 @@
1
+ // packages/predators-protocol/lib/heartbeat-animation.js
2
+ //
3
+ // Heartbeat Sangue animation canon · Lei do Sangue tema (Tubarão Art. 1 imutável)
4
+ // Pulse: vermelho-sangue → amarelo-dourado → vermelho · 3 batidas · ~2.4s
5
+ //
6
+ // Owner: Borboleta-azul (Designer T3 motion canon · Art. 4 imutável reduced-motion)
7
+ // Cooperação: Tucano-toco a11y · Aranha-tecela visual asset
8
+ // Canon: Lei #13 Pureza · zero clone externo (canon próprio Predators)
9
+ // Authority: Apex T7 BINARY ratificou estilo "Heartbeat Sangue" 2026-05-27
10
+ //
11
+ // Comportamento canon:
12
+ // - 3 batidas (rhythmic systole/diastole)
13
+ // - vermelho-sangue dim → amarelo-dourado BRIGHT → vermelho-sangue dim
14
+ // - inter-beat sleep 400ms · sistole bright 250ms · diástole dim 150ms
15
+ // - resting final em amarelo-dourado (canon APEX_GOLD tagline)
16
+ // - prefers-reduced-motion → render estático bright direto (Tucano-toco Art. 4)
17
+ //
18
+ // ANSI escape codes canon Predators (lib/colors.js compat):
19
+ // \x1b[91m bright red sistole (sangue pulsando)
20
+ // \x1b[2;31m dim red diástole (sangue descansando)
21
+ // \x1b[1;33m bold yellow APEX_GOLD bright
22
+ // \x1b[33m yellow APEX_GOLD normal
23
+ // \x1b[0m reset
24
+
25
+ "use strict";
26
+
27
+ const RESET = "\x1b[0m";
28
+ const BLOOD_BRIGHT = "\x1b[91m"; // sistole · sangue jorrando
29
+ const BLOOD_DIM = "\x1b[2;31m"; // diástole · sangue descansando
30
+ const GOLD_BRIGHT = "\x1b[1;33m"; // APEX_GOLD bright
31
+ const GOLD_NORMAL = "\x1b[33m"; // APEX_GOLD resting
32
+ const CURSOR_HIDE = "\x1b[?25l";
33
+ const CURSOR_SHOW = "\x1b[?25h";
34
+ const LINE_START = "\r";
35
+ const ERASE_LINE = "\x1b[2K";
36
+
37
+ function sleep(ms) {
38
+ return new Promise((resolve) => setTimeout(resolve, ms));
39
+ }
40
+
41
+ /**
42
+ * Detecta prefers-reduced-motion via env var ou TTY check
43
+ * Canon Tucano-toco Art. 4 imutável a11y
44
+ */
45
+ function prefersReducedMotion() {
46
+ // CI · NO_COLOR · explicit reduce
47
+ if (process.env.CI === "true") return true;
48
+ if (process.env.NO_COLOR) return true;
49
+ if (process.env.PREDATORS_REDUCE_MOTION === "true") return true;
50
+ return false;
51
+ }
52
+
53
+ /**
54
+ * Renderiza nome "PREDATORS PROTOCOL" centralizado uma cor + style
55
+ * @param {string} colorStart ANSI escape code (BLOOD_BRIGHT, GOLD_BRIGHT, etc)
56
+ * @param {WritableStream} stream process.stdout default
57
+ */
58
+ function renderName(colorStart, stream = process.stdout) {
59
+ // PREDATORS PROTOCOL · canon vigente · sem clone matrix externo (Lei #13)
60
+ const lines = [
61
+ "█▀█ █▀█ █▀▀ █▀▄ ▄▀█ ▀█▀ █▀█ █▀█ █▀",
62
+ "█▀▀ █▀▄ ██▄ █▄▀ █▀█ █ █▄█ █▀▄ ▄█",
63
+ "█▀█ █▀█ █▀█ ▀█▀ █▀█ █▀▀ █▀█ █ ",
64
+ "█▀▀ █▀▄ █▄█ █ █▄█ █▄▄ █▄█ █▄▄",
65
+ ];
66
+ for (const line of lines) {
67
+ stream.write(`${colorStart}${line}${RESET}\n`);
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Move cursor up N lines (re-render heartbeat in same position)
73
+ * @param {number} n lines up
74
+ */
75
+ function cursorUp(n) {
76
+ return `\x1b[${n}A`;
77
+ }
78
+
79
+ /**
80
+ * Heartbeat Sangue canon animation
81
+ *
82
+ * Sequência:
83
+ * 1. render dim red (resting) 150ms
84
+ * 2. SISTOLE 1: bright gold 250ms (BUM)
85
+ * 3. diástole: dim red 400ms
86
+ * 4. SISTOLE 2: bright gold 250ms (BUM)
87
+ * 5. diástole: dim red 400ms
88
+ * 6. SISTOLE 3: bright gold 250ms (BUM)
89
+ * 7. resting final: gold normal held
90
+ *
91
+ * Total: ~1.7s + final resting
92
+ *
93
+ * @param {WritableStream} stream process.stdout default
94
+ * @returns {Promise<void>}
95
+ */
96
+ async function renderHeartbeat(stream = process.stdout) {
97
+ const reduce = prefersReducedMotion();
98
+
99
+ if (reduce || !stream.isTTY) {
100
+ // reduced-motion canon: render estático bright direto · zero motion
101
+ renderName(GOLD_BRIGHT, stream);
102
+ return;
103
+ }
104
+
105
+ const NAME_HEIGHT = 4; // 4 linhas do banner
106
+
107
+ stream.write(CURSOR_HIDE);
108
+
109
+ try {
110
+ // Frame 1: dim red (resting baseline)
111
+ renderName(BLOOD_DIM, stream);
112
+ await sleep(150);
113
+
114
+ // 3 batidas cardiacas: sistole bright → diástole dim → repeat
115
+ for (let beat = 0; beat < 3; beat++) {
116
+ // SISTOLE: bright gold (BUM)
117
+ stream.write(cursorUp(NAME_HEIGHT));
118
+ renderName(GOLD_BRIGHT, stream);
119
+ await sleep(250);
120
+
121
+ if (beat < 2) {
122
+ // diástole: dim red (entre batidas · não no fim)
123
+ stream.write(cursorUp(NAME_HEIGHT));
124
+ renderName(BLOOD_DIM, stream);
125
+ await sleep(400);
126
+ }
127
+ }
128
+
129
+ // Resting final: gold normal (não bright · não dim)
130
+ stream.write(cursorUp(NAME_HEIGHT));
131
+ renderName(GOLD_NORMAL, stream);
132
+ } finally {
133
+ stream.write(CURSOR_SHOW);
134
+ }
135
+ }
136
+
137
+ module.exports = {
138
+ renderHeartbeat,
139
+ prefersReducedMotion,
140
+ renderName,
141
+ // ANSI exports para reuso
142
+ BLOOD_BRIGHT,
143
+ BLOOD_DIM,
144
+ GOLD_BRIGHT,
145
+ GOLD_NORMAL,
146
+ RESET,
147
+ };
package/lib/splash.js CHANGED
@@ -1,114 +1,117 @@
1
- // lib/splash.js · cinematic splash screen first-connection
2
- // Lei #13 Pureza: canon próprio · zero clone Matrix-style externo
3
- // Sub-etapa E · Polvo integração cumulativa
4
-
5
- "use strict";
6
-
7
- const { colorize, colorByLayer, bold, dim, italic, RESET } = require("./colors");
8
- const { renderEye, renderHeroBanner } = require("./ascii-art");
9
- const { isFirstConnection, markConnected, getTheme, readConfig } = require("./config");
10
-
11
- function sleep(ms) {
12
- return new Promise(resolve => setTimeout(resolve, ms));
13
- }
14
-
15
- async function fadeInLines(lines, msPerLine = 80, stream = process.stdout) {
16
- for (const line of lines) {
17
- stream.write(line + "\n");
18
- if (msPerLine > 0) await sleep(msPerLine);
19
- }
20
- }
21
-
22
- async function renderCinematicSplash(stream = process.stdout) {
23
- const theme = getTheme();
24
-
25
- // Clear screen for cinematic feel (only if TTY)
26
- if (stream.isTTY) {
27
- stream.write("\x1b[2J\x1b[H");
28
- }
29
-
30
- stream.write("\n");
31
- // The Eye logo · reveal slow
32
- const eyeLines = renderEye(theme).split("\n");
33
- await fadeInLines(eyeLines, stream.isTTY ? 30 : 0, stream);
34
-
35
- stream.write("\n");
36
-
37
- // Hero banner Predators Protocol text
38
- stream.write(renderHeroBanner(theme));
39
- stream.write("\n");
40
-
41
- // Tagline
42
- const tagline = italic(colorize(
43
- '"The eye that never closes. 63 predadores ativos. Canon vigente."',
44
- "APEX_GOLD",
45
- theme,
46
- ));
47
- stream.write(` ${tagline}\n\n`);
48
-
49
- await sleep(stream.isTTY ? 500 : 0);
50
-
51
- // Welcome message + quick start
52
- const welcomeBlock = [
53
- bold(colorize(" ▶ Bem-vindo ao Predators Protocol", "BUILDER_CYAN")),
54
- "",
55
- dim(" Framework multi-agente predatório · 63 predadores em 10 camadas"),
56
- dim(" Lei do Sangue inviolável · Synapse · Canon dos 3 Vetos"),
57
- "",
58
- bold(" Quick start:"),
59
- ` ${colorize("npx predators-protocol@beta help", "INTEL_GREEN")} ${dim("· lista comandos canon")}`,
60
- ` ${colorize("npx predators-protocol@beta list-predators", "INTEL_GREEN")} ${dim("· 63 predadores")}`,
61
- ` ${colorize("npx predators-protocol@beta layers-list", "INTEL_GREEN")} ${dim("· 7 context layers L0-L6")}`,
62
- ` ${colorize("npx predators-protocol@beta config", "INTEL_GREEN")} ${dim("· preferences · theme · audio toggle")}`,
63
- "",
64
- dim(" GitHub: https://github.com/SharkLEx/predators-protocol"),
65
- dim(" Licença: Proprietary · Alex Gonzaga (Tubarão-Apex)"),
66
- "",
67
- ];
68
- await fadeInLines(welcomeBlock, stream.isTTY ? 40 : 0, stream);
69
- }
70
-
71
- async function renderMiniSplash(stream = process.stdout) {
72
- const theme = getTheme();
73
- const config = readConfig();
74
- const eyeMini = colorize("◉", "APEX_GOLD", theme);
75
- const name = colorize("Predators Protocol", "APEX_GOLD", theme);
76
- const ver = dim("· canon vigente · 63 predadores ativos");
77
- const lastSeen = config.lastConnectionAt
78
- ? dim(`(última conexão: ${new Date(config.lastConnectionAt).toISOString().slice(0, 10)})`)
79
- : "";
80
- stream.write(`\n ${eyeMini} ${name} ${ver} ${lastSeen}\n\n`);
81
- }
82
-
83
- async function runInitSplash(options = {}) {
84
- const stream = options.stream || process.stdout;
85
- const force = options.force || false;
86
- const minimal = options.minimal || false;
87
-
88
- const config = readConfig();
89
- if (!config.splash.enabled && !force) {
90
- return { rendered: false, reason: "splash_disabled_user_pref" };
91
- }
92
-
93
- const firstTime = isFirstConnection();
94
-
95
- if (firstTime || force) {
96
- await renderCinematicSplash(stream);
97
- markConnected();
98
- return { rendered: true, mode: "cinematic", firstTime };
99
- }
100
- if (minimal || !options.fullEveryTime) {
101
- await renderMiniSplash(stream);
102
- markConnected();
103
- return { rendered: true, mode: "minimal", firstTime: false };
104
- }
105
- await renderCinematicSplash(stream);
106
- markConnected();
107
- return { rendered: true, mode: "cinematic", firstTime: false };
108
- }
109
-
110
- module.exports = {
111
- renderCinematicSplash,
112
- renderMiniSplash,
113
- runInitSplash,
114
- };
1
+ // lib/splash.js · cinematic splash screen first-connection
2
+ // Lei #13 Pureza: canon próprio · zero clone Matrix-style externo
3
+ // Sub-etapa E · Polvo integração cumulativa
4
+
5
+ "use strict";
6
+
7
+ const { colorize, colorByLayer, bold, dim, italic, RESET } = require("./colors");
8
+ const { renderEye, renderHeroBanner } = require("./ascii-art");
9
+ const { isFirstConnection, markConnected, getTheme, readConfig } = require("./config");
10
+ const { renderHeartbeat } = require("./heartbeat-animation");
11
+
12
+ function sleep(ms) {
13
+ return new Promise(resolve => setTimeout(resolve, ms));
14
+ }
15
+
16
+ async function fadeInLines(lines, msPerLine = 80, stream = process.stdout) {
17
+ for (const line of lines) {
18
+ stream.write(line + "\n");
19
+ if (msPerLine > 0) await sleep(msPerLine);
20
+ }
21
+ }
22
+
23
+ async function renderCinematicSplash(stream = process.stdout) {
24
+ const theme = getTheme();
25
+
26
+ // Clear screen for cinematic feel (only if TTY)
27
+ if (stream.isTTY) {
28
+ stream.write("\x1b[2J\x1b[H");
29
+ }
30
+
31
+ stream.write("\n");
32
+ // The Eye logo · reveal slow
33
+ const eyeLines = renderEye(theme).split("\n");
34
+ await fadeInLines(eyeLines, stream.isTTY ? 30 : 0, stream);
35
+
36
+ stream.write("\n");
37
+
38
+ // Hero banner "PREDATORS PROTOCOL" · canon Heartbeat Sangue (Lei #1 tema)
39
+ // 3 batidas vermelho-sangue → amarelo-dourado · ~1.7s + resting (Apex T7 BINARY 2026-05-27)
40
+ // Borboleta-azul Art. 4 imutável reduced-motion preservado via heartbeat-animation.js
41
+ await renderHeartbeat(stream);
42
+ stream.write("\n");
43
+
44
+ // Tagline (64 predadores pós-F4 Baleia-cantora · canon vigente)
45
+ const tagline = italic(colorize(
46
+ '"The eye that never closes. 64 predadores ativos. Canon vigente."',
47
+ "APEX_GOLD",
48
+ theme,
49
+ ));
50
+ stream.write(` ${tagline}\n\n`);
51
+
52
+ await sleep(stream.isTTY ? 500 : 0);
53
+
54
+ // Welcome message + quick start
55
+ const welcomeBlock = [
56
+ bold(colorize(" Bem-vindo ao Predators Protocol", "BUILDER_CYAN")),
57
+ "",
58
+ dim(" Framework multi-agente predatório · 64 predadores em 10 camadas"),
59
+ dim(" Lei do Sangue inviolável · Synapse · Canon dos 3 Vetos"),
60
+ "",
61
+ bold(" Quick start:"),
62
+ ` ${colorize("npx predators-protocol@beta help", "INTEL_GREEN")} ${dim("· lista comandos canon")}`,
63
+ ` ${colorize("npx predators-protocol@beta list-predators", "INTEL_GREEN")} ${dim("· 64 predadores")}`,
64
+ ` ${colorize("npx predators-protocol@beta layers-list", "INTEL_GREEN")} ${dim("· 7 context layers L0-L6")}`,
65
+ ` ${colorize("npx predators-protocol@beta config", "INTEL_GREEN")} ${dim("· preferences · theme · audio toggle")}`,
66
+ "",
67
+ dim(" GitHub: https://github.com/SharkLEx/predators-protocol"),
68
+ dim(" Licença: Proprietary · Alex Gonzaga (Tubarão-Apex)"),
69
+ "",
70
+ ];
71
+ await fadeInLines(welcomeBlock, stream.isTTY ? 40 : 0, stream);
72
+ }
73
+
74
+ async function renderMiniSplash(stream = process.stdout) {
75
+ const theme = getTheme();
76
+ const config = readConfig();
77
+ const eyeMini = colorize("◉", "APEX_GOLD", theme);
78
+ const name = colorize("Predators Protocol", "APEX_GOLD", theme);
79
+ const ver = dim("· canon vigente · 64 predadores ativos");
80
+ const lastSeen = config.lastConnectionAt
81
+ ? dim(`(última conexão: ${new Date(config.lastConnectionAt).toISOString().slice(0, 10)})`)
82
+ : "";
83
+ stream.write(`\n ${eyeMini} ${name} ${ver} ${lastSeen}\n\n`);
84
+ }
85
+
86
+ async function runInitSplash(options = {}) {
87
+ const stream = options.stream || process.stdout;
88
+ const force = options.force || false;
89
+ const minimal = options.minimal || false;
90
+
91
+ const config = readConfig();
92
+ if (!config.splash.enabled && !force) {
93
+ return { rendered: false, reason: "splash_disabled_user_pref" };
94
+ }
95
+
96
+ const firstTime = isFirstConnection();
97
+
98
+ if (firstTime || force) {
99
+ await renderCinematicSplash(stream);
100
+ markConnected();
101
+ return { rendered: true, mode: "cinematic", firstTime };
102
+ }
103
+ if (minimal || !options.fullEveryTime) {
104
+ await renderMiniSplash(stream);
105
+ markConnected();
106
+ return { rendered: true, mode: "minimal", firstTime: false };
107
+ }
108
+ await renderCinematicSplash(stream);
109
+ markConnected();
110
+ return { rendered: true, mode: "cinematic", firstTime: false };
111
+ }
112
+
113
+ module.exports = {
114
+ renderCinematicSplash,
115
+ renderMiniSplash,
116
+ runInitSplash,
117
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "predators-protocol",
3
- "version": "0.4.0-beta.0",
4
- "description": "Predators Protocol · multi-agent predatory framework · 64 predators in 10 layers · canon Lei #14 PERFEITO OU FIX-GERAL · UX layer + sync + tour + telemetry opt-in · proprietary",
3
+ "version": "0.5.2-beta.0",
4
+ "description": "Predators Protocol \u00b7 multi-agent predatory framework \u00b7 64 predators in 10 layers \u00b7 canon Lei #14 PERFEITO OU FIX-GERAL \u00b7 FASE 7 COMPLETA: RuntimeRouter + Synapse Engine + LLM Real Production + v1 \u2192 H\u00edbrida full transition \u00b7 proprietary",
5
5
  "keywords": [
6
6
  "predators-protocol",
7
7
  "multi-agent",
@@ -21,7 +21,7 @@
21
21
  "directory": "packages/predators-protocol"
22
22
  },
23
23
  "license": "SEE LICENSE IN LICENSE",
24
- "author": "Alex Gonzaga (Tubarão-Apex) <alex@predators-protocol.dev>",
24
+ "author": "Alex Gonzaga (Tubar\u00e3o-Apex) <alex@predators-protocol.dev>",
25
25
  "type": "commonjs",
26
26
  "bin": {
27
27
  "predators-protocol": "bin/predators-cli.js"