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.
- package/README.md +14 -1
- package/bin/predators-cli.js +726 -637
- package/bundle/QUICKSTART-SOCIO.md +14 -1
- package/bundle/docs/CANON/SUB-FASE-7-3-INTEGRATION-ANTHROPIC-API-REAL-LLM-PRODUCTION.md +147 -0
- package/bundle/docs/CANON/SUB-FASE-7-4-FINAL-V1-PARA-HIBRIDA-FULL-TRANSITION.md +145 -0
- package/lib/access-token-client.js +273 -0
- package/lib/config.js +50 -5
- package/lib/gen-token-client.js +210 -0
- package/lib/heartbeat-animation.js +147 -0
- package/lib/splash.js +117 -114
- package/package.json +3 -3
|
@@ -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
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
"",
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
` ${colorize("npx predators-protocol@beta
|
|
63
|
-
"",
|
|
64
|
-
|
|
65
|
-
dim("
|
|
66
|
-
"",
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const
|
|
76
|
-
const
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
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
|
-
"description": "Predators Protocol
|
|
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 (
|
|
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"
|