nuxs-capsule 0.1.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 +21 -0
- package/bin/nuxs-capsule-intercept.js +4 -0
- package/bin/nuxs-capsule.js +20 -0
- package/dist/install.d.ts +17 -0
- package/dist/install.d.ts.map +1 -0
- package/dist/install.js +243 -0
- package/dist/install.js.map +1 -0
- package/dist/intercept.d.ts +19 -0
- package/dist/intercept.d.ts.map +1 -0
- package/dist/intercept.js +232 -0
- package/dist/intercept.js.map +1 -0
- package/dist/lib/fileStat.d.ts +20 -0
- package/dist/lib/fileStat.d.ts.map +1 -0
- package/dist/lib/fileStat.js +71 -0
- package/dist/lib/fileStat.js.map +1 -0
- package/dist/lib/fingerprint.d.ts +10 -0
- package/dist/lib/fingerprint.d.ts.map +1 -0
- package/dist/lib/fingerprint.js +41 -0
- package/dist/lib/fingerprint.js.map +1 -0
- package/dist/lib/tokenCount.d.ts +13 -0
- package/dist/lib/tokenCount.d.ts.map +1 -0
- package/dist/lib/tokenCount.js +32 -0
- package/dist/lib/tokenCount.js.map +1 -0
- package/dist/license/check.d.ts +14 -0
- package/dist/license/check.d.ts.map +1 -0
- package/dist/license/check.js +141 -0
- package/dist/license/check.js.map +1 -0
- package/dist/providers/llmClient.d.ts +20 -0
- package/dist/providers/llmClient.d.ts.map +1 -0
- package/dist/providers/llmClient.js +40 -0
- package/dist/providers/llmClient.js.map +1 -0
- package/dist/server.d.ts +10 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +268 -0
- package/dist/server.js.map +1 -0
- package/dist/setup.d.ts +14 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/setup.js +135 -0
- package/dist/setup.js.map +1 -0
- package/dist/telemetry/usage.d.ts +19 -0
- package/dist/telemetry/usage.d.ts.map +1 -0
- package/dist/telemetry/usage.js +114 -0
- package/dist/telemetry/usage.js.map +1 -0
- package/dist/tools/apiCapsule.d.ts +16 -0
- package/dist/tools/apiCapsule.d.ts.map +1 -0
- package/dist/tools/apiCapsule.js +169 -0
- package/dist/tools/apiCapsule.js.map +1 -0
- package/dist/tools/eventsCapsule.d.ts +15 -0
- package/dist/tools/eventsCapsule.d.ts.map +1 -0
- package/dist/tools/eventsCapsule.js +72 -0
- package/dist/tools/eventsCapsule.js.map +1 -0
- package/dist/tools/logCapsule.d.ts +38 -0
- package/dist/tools/logCapsule.d.ts.map +1 -0
- package/dist/tools/logCapsule.js +283 -0
- package/dist/tools/logCapsule.js.map +1 -0
- package/dist/tools/networkCapsule.d.ts +18 -0
- package/dist/tools/networkCapsule.d.ts.map +1 -0
- package/dist/tools/networkCapsule.js +151 -0
- package/dist/tools/networkCapsule.js.map +1 -0
- package/dist/tools/sessionCapsule.d.ts +21 -0
- package/dist/tools/sessionCapsule.d.ts.map +1 -0
- package/dist/tools/sessionCapsule.js +174 -0
- package/dist/tools/sessionCapsule.js.map +1 -0
- package/dist/tools/sqlCapsule.d.ts +17 -0
- package/dist/tools/sqlCapsule.d.ts.map +1 -0
- package/dist/tools/sqlCapsule.js +144 -0
- package/dist/tools/sqlCapsule.js.map +1 -0
- package/dist/tools/stackCapsule.d.ts +9 -0
- package/dist/tools/stackCapsule.d.ts.map +1 -0
- package/dist/tools/stackCapsule.js +132 -0
- package/dist/tools/stackCapsule.js.map +1 -0
- package/dist/tools/threadsCapsule.d.ts +14 -0
- package/dist/tools/threadsCapsule.d.ts.map +1 -0
- package/dist/tools/threadsCapsule.js +77 -0
- package/dist/tools/threadsCapsule.js.map +1 -0
- package/dist/types.d.ts +199 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/dist/wrap.d.ts +14 -0
- package/dist/wrap.d.ts.map +1 -0
- package/dist/wrap.js +100 -0
- package/dist/wrap.js.map +1 -0
- package/package.json +60 -0
package/README.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# @nuxs/capsule
|
|
2
|
+
|
|
3
|
+
> Compressor universal pra agentes IA. Camada invisível via MCP server + Hook PreToolUse.
|
|
4
|
+
> Economiza 50-90% dos tokens em Claude Code, Cursor, OpenClaw, Hermes.
|
|
5
|
+
|
|
6
|
+
**Status:** V1 em desenvolvimento (privado). Site: https://nuxs.ai
|
|
7
|
+
|
|
8
|
+
## Instalação (quando lançar V1)
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install -g @nuxs/capsule
|
|
12
|
+
nuxs-capsule setup
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Plano completo
|
|
16
|
+
|
|
17
|
+
Ver `docs/NUXS-CAPSULE-V2-PLAN.md` no [repo pixeldesk](https://github.com/josueramosleites-collab/pixeldesk/blob/main/docs/NUXS-CAPSULE-V2-PLAN.md).
|
|
18
|
+
|
|
19
|
+
## Licença
|
|
20
|
+
|
|
21
|
+
Source-available — uso comercial requer license key Nuxs.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Entry CLI multi-comando: nuxs-capsule [install|setup|wrap|serve]
|
|
3
|
+
|
|
4
|
+
const cmd = process.argv[2];
|
|
5
|
+
|
|
6
|
+
if (cmd === 'install') {
|
|
7
|
+
await import('../dist/install.js');
|
|
8
|
+
} else if (cmd === 'setup') {
|
|
9
|
+
await import('../dist/setup.js');
|
|
10
|
+
} else if (cmd === 'wrap') {
|
|
11
|
+
process.argv.splice(2, 1); // remove "wrap" do argv pro parser interno
|
|
12
|
+
await import('../dist/wrap.js');
|
|
13
|
+
} else if (cmd === 'serve' || cmd === undefined) {
|
|
14
|
+
// Default: roda como MCP server (stdio)
|
|
15
|
+
await import('../dist/server.js');
|
|
16
|
+
} else {
|
|
17
|
+
console.error(`nuxs-capsule: comando desconhecido "${cmd}"`);
|
|
18
|
+
console.error('Use: install | setup | wrap | serve');
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI: `npx nuxs-capsule install`
|
|
3
|
+
*
|
|
4
|
+
* Instalador GUIADO interativo [Finn 26/Mai/2026]. Diferente do setup
|
|
5
|
+
* que só configura MCP local, este aqui:
|
|
6
|
+
*
|
|
7
|
+
* 1. Detecta tudo no PC [Claude Code, Cursor, OpenClaw CLI, Hermes API]
|
|
8
|
+
* 2. Configura local via setup.ts
|
|
9
|
+
* 3. Lê ~/.ssh/config + ~/.ssh/known_hosts pra achar servidores
|
|
10
|
+
* 4. Lista hosts e pergunta "instalar Capsule lá também?"
|
|
11
|
+
* 5. Se sim, faz SSH e roda install-linux.sh remoto via curl
|
|
12
|
+
* 6. License key entrada UMA vez, usada pra todos
|
|
13
|
+
*
|
|
14
|
+
* Modelo de UX: estilo `vercel` CLI [pergunta o mínimo, faz o resto].
|
|
15
|
+
*/
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=install.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG"}
|
package/dist/install.js
ADDED
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI: `npx nuxs-capsule install`
|
|
3
|
+
*
|
|
4
|
+
* Instalador GUIADO interativo [Finn 26/Mai/2026]. Diferente do setup
|
|
5
|
+
* que só configura MCP local, este aqui:
|
|
6
|
+
*
|
|
7
|
+
* 1. Detecta tudo no PC [Claude Code, Cursor, OpenClaw CLI, Hermes API]
|
|
8
|
+
* 2. Configura local via setup.ts
|
|
9
|
+
* 3. Lê ~/.ssh/config + ~/.ssh/known_hosts pra achar servidores
|
|
10
|
+
* 4. Lista hosts e pergunta "instalar Capsule lá também?"
|
|
11
|
+
* 5. Se sim, faz SSH e roda install-linux.sh remoto via curl
|
|
12
|
+
* 6. License key entrada UMA vez, usada pra todos
|
|
13
|
+
*
|
|
14
|
+
* Modelo de UX: estilo `vercel` CLI [pergunta o mínimo, faz o resto].
|
|
15
|
+
*/
|
|
16
|
+
import { execSync } from 'node:child_process';
|
|
17
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
18
|
+
import { homedir } from 'node:os';
|
|
19
|
+
import { join } from 'node:path';
|
|
20
|
+
import { createInterface } from 'node:readline/promises';
|
|
21
|
+
const SSH_CONFIG = join(homedir(), '.ssh', 'config');
|
|
22
|
+
const SSH_KNOWN_HOSTS = join(homedir(), '.ssh', 'known_hosts');
|
|
23
|
+
const INSTALL_LINUX_URL = 'https://pixeldesk.dev/install-linux.sh';
|
|
24
|
+
// ─── Detect local ──────────────────────────────────────────────────
|
|
25
|
+
function detectLocalAgents() {
|
|
26
|
+
const out = [];
|
|
27
|
+
if (existsSync(join(homedir(), '.claude', 'settings.json'))) {
|
|
28
|
+
out.push({ kind: 'claude_code', source: 'local', detail: '~/.claude/settings.json' });
|
|
29
|
+
}
|
|
30
|
+
if (existsSync(join(homedir(), '.cursor', 'mcp.json'))) {
|
|
31
|
+
out.push({ kind: 'cursor', source: 'local', detail: '~/.cursor/mcp.json' });
|
|
32
|
+
}
|
|
33
|
+
// OpenClaw CLI no PATH
|
|
34
|
+
try {
|
|
35
|
+
const path = execSync('which openclaw', { stdio: ['ignore', 'pipe', 'ignore'] })
|
|
36
|
+
.toString().trim();
|
|
37
|
+
if (path) {
|
|
38
|
+
out.push({ kind: 'openclaw', source: 'local', detail: path });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch { /* not installed */ }
|
|
42
|
+
// Hermes API rodando local
|
|
43
|
+
try {
|
|
44
|
+
const r = execSync('curl -s -m 1 http://127.0.0.1:8642/v1/models 2>/dev/null || echo NO', {
|
|
45
|
+
stdio: ['ignore', 'pipe', 'ignore']
|
|
46
|
+
}).toString().trim();
|
|
47
|
+
if (r && !r.includes('NO')) {
|
|
48
|
+
out.push({ kind: 'hermes', source: 'local', detail: 'http://127.0.0.1:8642' });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch { /* not running */ }
|
|
52
|
+
return out;
|
|
53
|
+
}
|
|
54
|
+
// ─── Detect SSH hosts ──────────────────────────────────────────────
|
|
55
|
+
function parseSshConfig(text) {
|
|
56
|
+
const hosts = [];
|
|
57
|
+
let cur = null;
|
|
58
|
+
for (const raw of text.split('\n')) {
|
|
59
|
+
const line = raw.trim();
|
|
60
|
+
if (!line || line.startsWith('#'))
|
|
61
|
+
continue;
|
|
62
|
+
const m = line.match(/^(\w+)\s+(.+)$/);
|
|
63
|
+
if (!m)
|
|
64
|
+
continue;
|
|
65
|
+
const key = m[1].toLowerCase();
|
|
66
|
+
const val = m[2].trim();
|
|
67
|
+
if (key === 'host') {
|
|
68
|
+
// pode ser "Host alias" ou "Host *" (wildcard, ignora)
|
|
69
|
+
if (val === '*' || val.includes('*')) {
|
|
70
|
+
cur = null;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (cur)
|
|
74
|
+
hosts.push(cur);
|
|
75
|
+
cur = { alias: val, hostname: val };
|
|
76
|
+
}
|
|
77
|
+
else if (cur) {
|
|
78
|
+
if (key === 'hostname')
|
|
79
|
+
cur.hostname = val;
|
|
80
|
+
else if (key === 'user')
|
|
81
|
+
cur.user = val;
|
|
82
|
+
else if (key === 'port')
|
|
83
|
+
cur.port = parseInt(val, 10);
|
|
84
|
+
else if (key === 'identityfile')
|
|
85
|
+
cur.identityFile = val;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (cur)
|
|
89
|
+
hosts.push(cur);
|
|
90
|
+
return hosts;
|
|
91
|
+
}
|
|
92
|
+
function detectSshHosts() {
|
|
93
|
+
if (!existsSync(SSH_CONFIG))
|
|
94
|
+
return [];
|
|
95
|
+
try {
|
|
96
|
+
return parseSshConfig(readFileSync(SSH_CONFIG, 'utf8'));
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return [];
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// ─── Remote install via SSH ────────────────────────────────────────
|
|
103
|
+
async function probeRemoteAgents(host) {
|
|
104
|
+
const ssh = `ssh -o ConnectTimeout=5 -o BatchMode=yes ${host.alias}`;
|
|
105
|
+
const out = [];
|
|
106
|
+
try {
|
|
107
|
+
const oc = execSync(`${ssh} 'which openclaw 2>/dev/null || echo NO'`, {
|
|
108
|
+
stdio: ['ignore', 'pipe', 'ignore'], timeout: 8000
|
|
109
|
+
}).toString().trim();
|
|
110
|
+
if (oc && !oc.includes('NO')) {
|
|
111
|
+
out.push({ kind: 'openclaw', source: 'remote', host: host.alias, detail: oc });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
catch { /* timeout ou auth fail */ }
|
|
115
|
+
try {
|
|
116
|
+
const hr = execSync(`${ssh} 'curl -s -m 1 http://127.0.0.1:8642/v1/models >/dev/null 2>&1 && echo YES || echo NO'`, { stdio: ['ignore', 'pipe', 'ignore'], timeout: 8000 }).toString().trim();
|
|
117
|
+
if (hr === 'YES') {
|
|
118
|
+
out.push({ kind: 'hermes', source: 'remote', host: host.alias, detail: '127.0.0.1:8642' });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
catch { /* idem */ }
|
|
122
|
+
return out;
|
|
123
|
+
}
|
|
124
|
+
function remoteInstall(host, kind, envVars) {
|
|
125
|
+
const envStr = Object.entries(envVars)
|
|
126
|
+
.map(([k, v]) => `${k}=${JSON.stringify(v)}`)
|
|
127
|
+
.join(' ');
|
|
128
|
+
const cmd = `ssh ${host.alias} "curl -fsSL ${INSTALL_LINUX_URL} | ${envStr} AGENT_KIND=${kind} bash"`;
|
|
129
|
+
console.log(` → ssh ${host.alias} curl ${INSTALL_LINUX_URL} | bash`);
|
|
130
|
+
try {
|
|
131
|
+
execSync(cmd, { stdio: 'inherit', timeout: 90_000 });
|
|
132
|
+
return true;
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
console.error(` ✗ Falhou: ${err.message}`);
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// ─── Main flow ─────────────────────────────────────────────────────
|
|
140
|
+
async function ask(rl, q) {
|
|
141
|
+
return (await rl.question(q)).trim();
|
|
142
|
+
}
|
|
143
|
+
async function confirm(rl, q) {
|
|
144
|
+
const ans = (await rl.question(`${q} [y/N] `)).trim().toLowerCase();
|
|
145
|
+
return ans === 'y' || ans === 'yes' || ans === 's' || ans === 'sim';
|
|
146
|
+
}
|
|
147
|
+
async function main() {
|
|
148
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
149
|
+
try {
|
|
150
|
+
console.log('\n🟢 Nuxs Capsule — Instalador guiado\n');
|
|
151
|
+
// 1. License key
|
|
152
|
+
console.log('Pra licenciar todas as instalações [PC + servidores] de uma vez:');
|
|
153
|
+
const licenseKey = await ask(rl, ' License key [nxs_…] ou Enter pra Free anônimo: ');
|
|
154
|
+
// 2. Token do PixelDesk pros bridges
|
|
155
|
+
const pdToken = await ask(rl, ' PixelDesk agent token [pdsk_…]: ');
|
|
156
|
+
const pdSlug = await ask(rl, ' PixelDesk office slug: ');
|
|
157
|
+
// 3. Detect local
|
|
158
|
+
console.log('\n🔍 Detectando agentes no PC…');
|
|
159
|
+
const localAgents = detectLocalAgents();
|
|
160
|
+
if (localAgents.length === 0) {
|
|
161
|
+
console.log(' [nenhum agente detectado]');
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
for (const a of localAgents) {
|
|
165
|
+
console.log(` ✓ ${a.kind} [${a.detail}]`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
// 4. Configura local via setup.ts
|
|
169
|
+
if (localAgents.some((a) => a.kind === 'claude_code' || a.kind === 'cursor')) {
|
|
170
|
+
console.log('\n→ Configurando MCP em Claude Code / Cursor…');
|
|
171
|
+
try {
|
|
172
|
+
// Reaproveita o fluxo do setup.ts
|
|
173
|
+
execSync(`node ${join(__dirname, 'setup.js')}`, {
|
|
174
|
+
stdio: 'inherit',
|
|
175
|
+
env: { ...process.env, NUXS_LICENSE_KEY: licenseKey || '' }
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
console.log(' ⚠ Falha em rodar setup automático. Roda manualmente: npx nuxs-capsule setup');
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// 5. SSH hosts
|
|
183
|
+
console.log('\n🔍 Lendo ~/.ssh/config…');
|
|
184
|
+
const hosts = detectSshHosts();
|
|
185
|
+
if (hosts.length === 0) {
|
|
186
|
+
console.log(' [nenhum servidor configurado no SSH config]');
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
console.log(` ${hosts.length} servidor[es] encontrado[s]:`);
|
|
190
|
+
for (const h of hosts) {
|
|
191
|
+
console.log(` • ${h.alias} [${h.user ? h.user + '@' : ''}${h.hostname}]`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
// 6. Probe cada host
|
|
195
|
+
if (hosts.length > 0) {
|
|
196
|
+
const toInstall = await confirm(rl, '\nVerificar quais servidores tem agentes [pode demorar]?');
|
|
197
|
+
if (toInstall) {
|
|
198
|
+
for (const host of hosts) {
|
|
199
|
+
console.log(`\n • ${host.alias}…`);
|
|
200
|
+
const remote = await probeRemoteAgents(host);
|
|
201
|
+
if (remote.length === 0) {
|
|
202
|
+
console.log(' [sem OpenClaw/Hermes detectado ou SSH falhou]');
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
for (const a of remote) {
|
|
206
|
+
console.log(` ✓ ${a.kind} em ${a.detail}`);
|
|
207
|
+
}
|
|
208
|
+
if (!pdToken || !pdSlug) {
|
|
209
|
+
console.log(' ⚠ Sem token/slug — pulo este server.');
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
const yes = await confirm(rl, ` Instalar Capsule nos ${remote.length} agente[s]?`);
|
|
213
|
+
if (!yes)
|
|
214
|
+
continue;
|
|
215
|
+
for (const a of remote) {
|
|
216
|
+
const env = {
|
|
217
|
+
AGENT_NAME: `${a.kind}-${host.alias}`,
|
|
218
|
+
PIXELDESK_TOKEN: pdToken,
|
|
219
|
+
PIXELDESK_SLUG: pdSlug
|
|
220
|
+
};
|
|
221
|
+
if (a.kind === 'hermes') {
|
|
222
|
+
const apiKey = await ask(rl, ` HERMES_API_KEY pra ${host.alias} [sk_…]: `);
|
|
223
|
+
if (apiKey)
|
|
224
|
+
env.HERMES_API_KEY = apiKey;
|
|
225
|
+
}
|
|
226
|
+
remoteInstall(host, a.kind, env);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
console.log('\n✅ Instalação concluída.');
|
|
232
|
+
console.log(' Acompanha tudo em: https://pixeldesk.dev/mymind → aba Capsule');
|
|
233
|
+
console.log(' Painel admin [Josu]: https://pixeldesk.dev/admin/capsule\n');
|
|
234
|
+
}
|
|
235
|
+
finally {
|
|
236
|
+
rl.close();
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
main().catch((err) => {
|
|
240
|
+
console.error('\n❌ Erro:', err.message);
|
|
241
|
+
process.exit(1);
|
|
242
|
+
});
|
|
243
|
+
//# sourceMappingURL=install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;AACrD,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;AAC/D,MAAM,iBAAiB,GAAG,wCAAwC,CAAC;AAiBnE,sEAAsE;AAEtE,SAAS,iBAAiB;IACxB,MAAM,GAAG,GAAoB,EAAE,CAAC;IAChC,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC;QAC5D,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,yBAAyB,EAAE,CAAC,CAAC;IACxF,CAAC;IACD,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC;QACvD,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,oBAAoB,EAAE,CAAC,CAAC;IAC9E,CAAC;IACD,uBAAuB;IACvB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,QAAQ,CAAC,gBAAgB,EAAE,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC;aAC7E,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;QACrB,IAAI,IAAI,EAAE,CAAC;YACT,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,mBAAmB,CAAC,CAAC;IAC/B,2BAA2B;IAC3B,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,QAAQ,CAAC,qEAAqE,EAAE;YACxF,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;SACpC,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAC,CAAC;QACjF,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;IAC7B,OAAO,GAAG,CAAC;AACb,CAAC;AAED,sEAAsE;AAEtE,SAAS,cAAc,CAAC,IAAY;IAClC,MAAM,KAAK,GAAc,EAAE,CAAC;IAC5B,IAAI,GAAG,GAAmB,IAAI,CAAC;IAC/B,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QACxB,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAC5C,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;QACvC,IAAI,CAAC,CAAC;YAAE,SAAS;QACjB,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,WAAW,EAAE,CAAC;QAChC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,CAAC;QACzB,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;YACnB,uDAAuD;YACvD,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACrC,GAAG,GAAG,IAAI,CAAC;gBACX,SAAS;YACX,CAAC;YACD,IAAI,GAAG;gBAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACzB,GAAG,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;QACtC,CAAC;aAAM,IAAI,GAAG,EAAE,CAAC;YACf,IAAI,GAAG,KAAK,UAAU;gBAAE,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC;iBACtC,IAAI,GAAG,KAAK,MAAM;gBAAE,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC;iBACnC,IAAI,GAAG,KAAK,MAAM;gBAAE,GAAG,CAAC,IAAI,GAAG,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;iBACjD,IAAI,GAAG,KAAK,cAAc;gBAAE,GAAG,CAAC,YAAY,GAAG,GAAG,CAAC;QAC1D,CAAC;IACH,CAAC;IACD,IAAI,GAAG;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,cAAc;IACrB,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,EAAE,CAAC;IACvC,IAAI,CAAC;QACH,OAAO,cAAc,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,sEAAsE;AAEtE,KAAK,UAAU,iBAAiB,CAAC,IAAa;IAC5C,MAAM,GAAG,GAAG,4CAA4C,IAAI,CAAC,KAAK,EAAE,CAAC;IACrE,MAAM,GAAG,GAAoB,EAAE,CAAC;IAChC,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,QAAQ,CAAC,GAAG,GAAG,0CAA0C,EAAE;YACpE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,IAAI;SACnD,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;QACrB,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;QACjF,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,0BAA0B,CAAC,CAAC;IACtC,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,QAAQ,CACjB,GAAG,GAAG,wFAAwF,EAC9F,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CACvD,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;QACpB,IAAI,EAAE,KAAK,KAAK,EAAE,CAAC;YACjB,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAAC;QAC7F,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC;IACtB,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,aAAa,CACpB,IAAa,EACb,IAA2B,EAC3B,OAA+B;IAE/B,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;SACnC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;SAC5C,IAAI,CAAC,GAAG,CAAC,CAAC;IACb,MAAM,GAAG,GACP,OAAO,IAAI,CAAC,KAAK,gBAAgB,iBAAiB,MAAM,MAAM,eAAe,IAAI,QAAQ,CAAC;IAC5F,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,KAAK,SAAS,iBAAiB,SAAS,CAAC,CAAC;IACtE,IAAI,CAAC;QACH,QAAQ,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QACrD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,eAAgB,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QACvD,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,sEAAsE;AAEtE,KAAK,UAAU,GAAG,CAAC,EAAsC,EAAE,CAAS;IAClE,OAAO,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AACvC,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,EAAsC,EAAE,CAAS;IACtE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACpE,OAAO,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,KAAK,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,KAAK,CAAC;AACtE,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7E,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;QAEvD,iBAAiB;QACjB,OAAO,CAAC,GAAG,CAAC,kEAAkE,CAAC,CAAC;QAChF,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,EAAE,EAAE,mDAAmD,CAAC,CAAC;QAEtF,qCAAqC;QACrC,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,EAAE,EAAE,oCAAoC,CAAC,CAAC;QACpE,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,EAAE,EAAE,2BAA2B,CAAC,CAAC;QAE1D,kBAAkB;QAClB,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;QAC9C,MAAM,WAAW,GAAG,iBAAiB,EAAE,CAAC;QACxC,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7B,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;QAC7C,CAAC;aAAM,CAAC;YACN,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;gBAC5B,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC;QAED,kCAAkC;QAClC,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,aAAa,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,EAAE,CAAC;YAC7E,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;YAC7D,IAAI,CAAC;gBACH,kCAAkC;gBAClC,QAAQ,CAAC,QAAQ,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,EAAE,EAAE;oBAC9C,KAAK,EAAE,SAAS;oBAChB,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,gBAAgB,EAAE,UAAU,IAAI,EAAE,EAAE;iBAC5D,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,CAAC,GAAG,CAAC,+EAA+E,CAAC,CAAC;YAC/F,CAAC;QACH,CAAC;QAED,eAAe;QACf,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;QACzC,MAAM,KAAK,GAAG,cAAc,EAAE,CAAC;QAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;QAC/D,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,MAAM,8BAA8B,CAAC,CAAC;YAC7D,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtB,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC;YAC/E,CAAC;QACH,CAAC;QAED,qBAAqB;QACrB,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,EAAE,EAAE,0DAA0D,CAAC,CAAC;YAChG,IAAI,SAAS,EAAE,CAAC;gBACd,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;oBACpC,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC;oBAC7C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;wBACxB,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;wBACjE,SAAS;oBACX,CAAC;oBACD,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;wBACvB,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;oBAChD,CAAC;oBACD,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;wBACxB,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;wBACxD,SAAS;oBACX,CAAC;oBACD,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,EAAE,EAAE,4BAA4B,MAAM,CAAC,MAAM,aAAa,CAAC,CAAC;oBACtF,IAAI,CAAC,GAAG;wBAAE,SAAS;oBACnB,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;wBACvB,MAAM,GAAG,GAA2B;4BAClC,UAAU,EAAE,GAAG,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE;4BACrC,eAAe,EAAE,OAAO;4BACxB,cAAc,EAAE,MAAM;yBACvB,CAAC;wBACF,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;4BACxB,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,EAAE,EAAE,4BAA4B,IAAI,CAAC,KAAK,WAAW,CAAC,CAAC;4BAChF,IAAI,MAAM;gCAAE,GAAG,CAAC,cAAc,GAAG,MAAM,CAAC;wBAC1C,CAAC;wBACD,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC,IAA6B,EAAE,GAAG,CAAC,CAAC;oBAC5D,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;QACzC,OAAO,CAAC,GAAG,CAAC,iEAAiE,CAAC,CAAC;QAC/E,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;IAC9E,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IACxC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Binário do Hook PreToolUse — `nuxs-capsule-intercept`.
|
|
3
|
+
*
|
|
4
|
+
* Recebe via stdin: { tool_name, tool_input } JSON (formato Claude Code hook).
|
|
5
|
+
* Decide em <50ms se intercepta baseado em extension + size.
|
|
6
|
+
*
|
|
7
|
+
* Se intercepta:
|
|
8
|
+
* 1. Gera cápsula → escreve em ~/.nuxs/cache/<sha>.<type>.{json|md}
|
|
9
|
+
* 2. Devolve via stdout: { hookSpecificOutput: { updatedInput: { file_path: <cache_path> } } }
|
|
10
|
+
* 3. Claude Code lê o arquivo cápsula em vez do original (camada invisível)
|
|
11
|
+
*
|
|
12
|
+
* Se NÃO intercepta:
|
|
13
|
+
* exit 0, passa adiante.
|
|
14
|
+
*
|
|
15
|
+
* Doc Anthropic confirma: hooks SUBSTITUEM tool_input via updatedInput,
|
|
16
|
+
* mas NÃO substituem tool_result. updatedInput é o caminho correto.
|
|
17
|
+
*/
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=intercept.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intercept.d.ts","sourceRoot":"","sources":["../src/intercept.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG"}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Binário do Hook PreToolUse — `nuxs-capsule-intercept`.
|
|
3
|
+
*
|
|
4
|
+
* Recebe via stdin: { tool_name, tool_input } JSON (formato Claude Code hook).
|
|
5
|
+
* Decide em <50ms se intercepta baseado em extension + size.
|
|
6
|
+
*
|
|
7
|
+
* Se intercepta:
|
|
8
|
+
* 1. Gera cápsula → escreve em ~/.nuxs/cache/<sha>.<type>.{json|md}
|
|
9
|
+
* 2. Devolve via stdout: { hookSpecificOutput: { updatedInput: { file_path: <cache_path> } } }
|
|
10
|
+
* 3. Claude Code lê o arquivo cápsula em vez do original (camada invisível)
|
|
11
|
+
*
|
|
12
|
+
* Se NÃO intercepta:
|
|
13
|
+
* exit 0, passa adiante.
|
|
14
|
+
*
|
|
15
|
+
* Doc Anthropic confirma: hooks SUBSTITUEM tool_input via updatedInput,
|
|
16
|
+
* mas NÃO substituem tool_result. updatedInput é o caminho correto.
|
|
17
|
+
*/
|
|
18
|
+
import { writeFileSync, existsSync, readFileSync } from 'node:fs';
|
|
19
|
+
import { homedir } from 'node:os';
|
|
20
|
+
import { join } from 'node:path';
|
|
21
|
+
import { ensureDir, fileInfo, readFirstBytes, cacheKey } from './lib/fileStat.js';
|
|
22
|
+
import { estimateTokensFromBytes, estimateCostUsd } from './lib/tokenCount.js';
|
|
23
|
+
import { getMachineFingerprint } from './lib/fingerprint.js';
|
|
24
|
+
import { trackUsage } from './telemetry/usage.js';
|
|
25
|
+
import { networkCapsuleFromFile } from './tools/networkCapsule.js';
|
|
26
|
+
import { apiCapsule } from './tools/apiCapsule.js';
|
|
27
|
+
const NUXS_DIR = join(homedir(), '.nuxs');
|
|
28
|
+
const CACHE_DIR = join(NUXS_DIR, 'cache');
|
|
29
|
+
const CACHE_TTL_MS = 24 * 60 * 60 * 1000;
|
|
30
|
+
// Thresholds objetivos pra interceptação
|
|
31
|
+
const THRESHOLDS = {
|
|
32
|
+
log: 10_000,
|
|
33
|
+
json: 20_000,
|
|
34
|
+
sql: 50_000,
|
|
35
|
+
stack_size_sniff: 5_000,
|
|
36
|
+
api_response: 20_000
|
|
37
|
+
};
|
|
38
|
+
async function main() {
|
|
39
|
+
const stdin = await readStdin();
|
|
40
|
+
if (!stdin) {
|
|
41
|
+
process.exit(0);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
let input;
|
|
45
|
+
try {
|
|
46
|
+
input = JSON.parse(stdin);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
process.exit(0); // input mal formado — passa adiante
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const toolName = input.tool_name ?? '';
|
|
53
|
+
const toolInput = input.tool_input ?? {};
|
|
54
|
+
// Só intercepta Read/Bash/WebFetch
|
|
55
|
+
if (!/^(Read|Bash|WebFetch)$/.test(toolName)) {
|
|
56
|
+
process.exit(0);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const decision = await decide(toolName, toolInput);
|
|
60
|
+
if (!decision.intercept) {
|
|
61
|
+
process.exit(0);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
// Cache hit? Pula geração
|
|
65
|
+
ensureDir(CACHE_DIR);
|
|
66
|
+
let cachePath = decision.cache_path;
|
|
67
|
+
if (!existsSync(cachePath) || cacheStale(cachePath)) {
|
|
68
|
+
try {
|
|
69
|
+
await generateCapsule(decision.capsule_type, toolInput, cachePath);
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
// Geração falhou — passa adiante normal (graceful degradation)
|
|
73
|
+
process.exit(0);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Devolve updatedInput pra Claude Code redirecionar o Read
|
|
78
|
+
const output = {
|
|
79
|
+
hookSpecificOutput: {
|
|
80
|
+
hookEventName: 'PreToolUse',
|
|
81
|
+
updatedInput: {
|
|
82
|
+
...toolInput,
|
|
83
|
+
file_path: cachePath
|
|
84
|
+
},
|
|
85
|
+
additionalContext: `[Nuxs Capsule] ${decision.capsule_type} comprimido. ${decision.reason ?? ''}`
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
process.stdout.write(JSON.stringify(output));
|
|
89
|
+
process.exit(0);
|
|
90
|
+
}
|
|
91
|
+
async function decide(toolName, toolInput) {
|
|
92
|
+
// Extrai file_path do input
|
|
93
|
+
const filePath = extractFilePath(toolName, toolInput);
|
|
94
|
+
if (!filePath)
|
|
95
|
+
return { intercept: false };
|
|
96
|
+
const info = fileInfo(filePath);
|
|
97
|
+
if (!info.exists)
|
|
98
|
+
return { intercept: false };
|
|
99
|
+
// Decisão objetiva por extension + size
|
|
100
|
+
let type = null;
|
|
101
|
+
let reason = '';
|
|
102
|
+
if (info.ext === '.har') {
|
|
103
|
+
type = 'network';
|
|
104
|
+
reason = `HAR file ${humanSize(info.size)}`;
|
|
105
|
+
}
|
|
106
|
+
else if (info.ext === '.log' && info.size > THRESHOLDS.log) {
|
|
107
|
+
type = 'log'; // V2 — por enquanto não cobre, deixa passar
|
|
108
|
+
return { intercept: false };
|
|
109
|
+
}
|
|
110
|
+
else if (info.ext === '.json' && info.size > THRESHOLDS.json) {
|
|
111
|
+
type = 'api';
|
|
112
|
+
reason = `JSON ${humanSize(info.size)}`;
|
|
113
|
+
}
|
|
114
|
+
else if (info.ext === '.sql' && info.size > THRESHOLDS.sql) {
|
|
115
|
+
type = 'sql';
|
|
116
|
+
return { intercept: false }; // V1 não auto-intercepta SQL — só tool MCP explícita
|
|
117
|
+
}
|
|
118
|
+
else if (info.size > THRESHOLDS.stack_size_sniff) {
|
|
119
|
+
// Sniff content pra detectar stack trace
|
|
120
|
+
const head = readFirstBytes(filePath, 500);
|
|
121
|
+
if (/at\s+\w.*?\(.*?\d+:\d+\)/.test(head) || /^\s*Traceback/m.test(head)) {
|
|
122
|
+
type = 'stack';
|
|
123
|
+
return { intercept: false }; // stack precisa LLM, V1 ativa só algoritmo puro
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (!type)
|
|
127
|
+
return { intercept: false };
|
|
128
|
+
// Algoritmo puro: network + api → ativa sempre (zero custo)
|
|
129
|
+
const key = cacheKey(filePath, info.mtimeMs);
|
|
130
|
+
const cachePath = join(CACHE_DIR, `${key}.${type}.json`);
|
|
131
|
+
return {
|
|
132
|
+
intercept: true,
|
|
133
|
+
capsule_type: type,
|
|
134
|
+
cache_path: cachePath,
|
|
135
|
+
reason
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
function extractFilePath(toolName, input) {
|
|
139
|
+
if (toolName === 'Read') {
|
|
140
|
+
return input.file_path ?? null;
|
|
141
|
+
}
|
|
142
|
+
if (toolName === 'Bash') {
|
|
143
|
+
// Heurística: extrai path de comandos comuns
|
|
144
|
+
const cmd = input.command ?? '';
|
|
145
|
+
const m = cmd.match(/(?:cat|tail|head|less|more|jq[^|]*)\s+(['"]?)(\S+\.\w{2,5})\1/);
|
|
146
|
+
return m?.[2] ?? null;
|
|
147
|
+
}
|
|
148
|
+
// WebFetch: não tem file_path, capsula só executa em response
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
async function generateCapsule(type, toolInput, cachePath) {
|
|
152
|
+
const filePath = extractFilePath(type === 'network' ? 'Read' : 'Read', toolInput);
|
|
153
|
+
if (!filePath)
|
|
154
|
+
throw new Error('no file_path');
|
|
155
|
+
const info = fileInfo(filePath);
|
|
156
|
+
const startedAt = Date.now();
|
|
157
|
+
let output;
|
|
158
|
+
let provider = 'algorithm';
|
|
159
|
+
let outputBytes = 0;
|
|
160
|
+
if (type === 'network') {
|
|
161
|
+
const capsule = networkCapsuleFromFile(filePath);
|
|
162
|
+
output = JSON.stringify(capsule, null, 2);
|
|
163
|
+
outputBytes = Buffer.byteLength(output, 'utf8');
|
|
164
|
+
}
|
|
165
|
+
else if (type === 'api') {
|
|
166
|
+
const raw = readFileSync(filePath, 'utf8');
|
|
167
|
+
const capsule = apiCapsule(raw);
|
|
168
|
+
output = JSON.stringify(capsule, null, 2);
|
|
169
|
+
outputBytes = Buffer.byteLength(output, 'utf8');
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
throw new Error(`hook intercept não cobre ${type} no V1`);
|
|
173
|
+
}
|
|
174
|
+
writeFileSync(cachePath, output);
|
|
175
|
+
// Telemetria fire-and-forget
|
|
176
|
+
const record = {
|
|
177
|
+
timestamp: new Date().toISOString(),
|
|
178
|
+
capsule_type: type,
|
|
179
|
+
input_size_bytes: info.size,
|
|
180
|
+
output_size_bytes: outputBytes,
|
|
181
|
+
input_tokens_estimated: estimateTokensFromBytes(info.size),
|
|
182
|
+
output_tokens_estimated: estimateTokensFromBytes(outputBytes),
|
|
183
|
+
tokens_saved: estimateTokensFromBytes(info.size) - estimateTokensFromBytes(outputBytes),
|
|
184
|
+
provider_used: provider,
|
|
185
|
+
cost_saved_usd: estimateCostUsd(estimateTokensFromBytes(info.size) - estimateTokensFromBytes(outputBytes), 0, 'haiku-4-5' // estimativa baseada em modelo médio que user pagaria
|
|
186
|
+
),
|
|
187
|
+
agent_detected: detectAgentFromEnv(),
|
|
188
|
+
latency_ms: Date.now() - startedAt,
|
|
189
|
+
machine_fingerprint: getMachineFingerprint()
|
|
190
|
+
};
|
|
191
|
+
// Fire and forget, não bloqueia
|
|
192
|
+
trackUsage(record).catch(() => { });
|
|
193
|
+
}
|
|
194
|
+
function detectAgentFromEnv() {
|
|
195
|
+
if (process.env.CLAUDE_CODE_SESSION_ID)
|
|
196
|
+
return 'claude_code';
|
|
197
|
+
if (process.env.CURSOR_AGENT)
|
|
198
|
+
return 'cursor';
|
|
199
|
+
if (process.env.OPENCLAW_SESSION)
|
|
200
|
+
return 'openclaw';
|
|
201
|
+
if (process.env.HERMES_AGENT)
|
|
202
|
+
return 'hermes';
|
|
203
|
+
return 'unknown';
|
|
204
|
+
}
|
|
205
|
+
function cacheStale(path) {
|
|
206
|
+
try {
|
|
207
|
+
const info = fileInfo(path);
|
|
208
|
+
return Date.now() - info.mtimeMs > CACHE_TTL_MS;
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
return true;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
function humanSize(bytes) {
|
|
215
|
+
if (bytes > 1_000_000)
|
|
216
|
+
return `${(bytes / 1_000_000).toFixed(1)}MB`;
|
|
217
|
+
if (bytes > 1_000)
|
|
218
|
+
return `${(bytes / 1_000).toFixed(0)}KB`;
|
|
219
|
+
return `${bytes}B`;
|
|
220
|
+
}
|
|
221
|
+
async function readStdin() {
|
|
222
|
+
const chunks = [];
|
|
223
|
+
for await (const chunk of process.stdin) {
|
|
224
|
+
chunks.push(chunk);
|
|
225
|
+
}
|
|
226
|
+
return Buffer.concat(chunks).toString('utf8');
|
|
227
|
+
}
|
|
228
|
+
main().catch((err) => {
|
|
229
|
+
console.error('[nuxs-capsule-intercept] error:', err);
|
|
230
|
+
process.exit(0); // erro fatal — passa adiante normal
|
|
231
|
+
});
|
|
232
|
+
//# sourceMappingURL=intercept.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intercept.js","sourceRoot":"","sources":["../src/intercept.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAW,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClF,OAAO,EAAE,uBAAuB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC/E,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGnD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;AAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AAC1C,MAAM,YAAY,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEzC,yCAAyC;AACzC,MAAM,UAAU,GAAG;IACjB,GAAG,EAAE,MAAM;IACX,IAAI,EAAE,MAAM;IACZ,GAAG,EAAE,MAAM;IACX,gBAAgB,EAAE,KAAK;IACvB,YAAY,EAAE,MAAM;CACrB,CAAC;AAEF,KAAK,UAAU,IAAI;IACjB,MAAM,KAAK,GAAG,MAAM,SAAS,EAAE,CAAC;IAChC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChB,OAAO;IACT,CAAC;IAED,IAAI,KAAmE,CAAC;IACxE,IAAI,CAAC;QACH,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,oCAAoC;QACrD,OAAO;IACT,CAAC;IAED,MAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC;IACvC,MAAM,SAAS,GAAG,KAAK,CAAC,UAAU,IAAI,EAAE,CAAC;IAEzC,mCAAmC;IACnC,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChB,OAAO;IACT,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACnD,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;QACxB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChB,OAAO;IACT,CAAC;IAED,0BAA0B;IAC1B,SAAS,CAAC,SAAS,CAAC,CAAC;IACrB,IAAI,SAAS,GAAG,QAAQ,CAAC,UAAW,CAAC;IACrC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QACpD,IAAI,CAAC;YACH,MAAM,eAAe,CAAC,QAAQ,CAAC,YAAa,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QACtE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,+DAA+D;YAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAChB,OAAO;QACT,CAAC;IACH,CAAC;IAED,2DAA2D;IAC3D,MAAM,MAAM,GAAe;QACzB,kBAAkB,EAAE;YAClB,aAAa,EAAE,YAAY;YAC3B,YAAY,EAAE;gBACZ,GAAG,SAAS;gBACZ,SAAS,EAAE,SAAS;aACrB;YACD,iBAAiB,EAAE,kBAAkB,QAAQ,CAAC,YAAY,gBAAgB,QAAQ,CAAC,MAAM,IAAI,EAAE,EAAE;SAClG;KACF,CAAC;IACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,KAAK,UAAU,MAAM,CACnB,QAAgB,EAChB,SAAkC;IAElC,4BAA4B;IAC5B,MAAM,QAAQ,GAAG,eAAe,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACtD,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAE3C,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAChC,IAAI,CAAC,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAE9C,wCAAwC;IACxC,IAAI,IAAI,GAAuB,IAAI,CAAC;IACpC,IAAI,MAAM,GAAG,EAAE,CAAC;IAEhB,IAAI,IAAI,CAAC,GAAG,KAAK,MAAM,EAAE,CAAC;QACxB,IAAI,GAAG,SAAS,CAAC;QACjB,MAAM,GAAG,YAAY,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IAC9C,CAAC;SAAM,IAAI,IAAI,CAAC,GAAG,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC;QAC7D,IAAI,GAAG,KAAK,CAAC,CAAC,4CAA4C;QAC1D,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAC9B,CAAC;SAAM,IAAI,IAAI,CAAC,GAAG,KAAK,OAAO,IAAI,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC;QAC/D,IAAI,GAAG,KAAK,CAAC;QACb,MAAM,GAAG,QAAQ,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IAC1C,CAAC;SAAM,IAAI,IAAI,CAAC,GAAG,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC;QAC7D,IAAI,GAAG,KAAK,CAAC;QACb,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,qDAAqD;IACpF,CAAC;SAAM,IAAI,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC,gBAAgB,EAAE,CAAC;QACnD,yCAAyC;QACzC,MAAM,IAAI,GAAG,cAAc,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QAC3C,IAAI,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACzE,IAAI,GAAG,OAAO,CAAC;YACf,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,gDAAgD;QAC/E,CAAC;IACH,CAAC;IAED,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAEvC,4DAA4D;IAC5D,MAAM,GAAG,GAAG,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,GAAG,GAAG,IAAI,IAAI,OAAO,CAAC,CAAC;IACzD,OAAO;QACL,SAAS,EAAE,IAAI;QACf,YAAY,EAAE,IAAI;QAClB,UAAU,EAAE,SAAS;QACrB,MAAM;KACP,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,QAAgB,EAAE,KAA8B;IACvE,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;QACxB,OAAQ,KAAK,CAAC,SAAoB,IAAI,IAAI,CAAC;IAC7C,CAAC;IACD,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;QACxB,6CAA6C;QAC7C,MAAM,GAAG,GAAI,KAAK,CAAC,OAAkB,IAAI,EAAE,CAAC;QAC5C,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,+DAA+D,CAAC,CAAC;QACrF,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;IACxB,CAAC;IACD,8DAA8D;IAC9D,OAAO,IAAI,CAAC;AACd,CAAC;AAED,KAAK,UAAU,eAAe,CAC5B,IAAiB,EACjB,SAAkC,EAClC,SAAiB;IAEjB,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAClF,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAEhC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,IAAI,MAAc,CAAC;IACnB,IAAI,QAAQ,GAAG,WAAW,CAAC;IAC3B,IAAI,WAAW,GAAG,CAAC,CAAC;IAEpB,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,MAAM,OAAO,GAAG,sBAAsB,CAAC,QAAQ,CAAC,CAAC;QACjD,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAC1C,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClD,CAAC;SAAM,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QAChC,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAC1C,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClD,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,KAAK,CAAC,4BAA4B,IAAI,QAAQ,CAAC,CAAC;IAC5D,CAAC;IAED,aAAa,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAEjC,6BAA6B;IAC7B,MAAM,MAAM,GAAgB;QAC1B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,YAAY,EAAE,IAAI;QAClB,gBAAgB,EAAE,IAAI,CAAC,IAAI;QAC3B,iBAAiB,EAAE,WAAW;QAC9B,sBAAsB,EAAE,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC;QAC1D,uBAAuB,EAAE,uBAAuB,CAAC,WAAW,CAAC;QAC7D,YAAY,EAAE,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,uBAAuB,CAAC,WAAW,CAAC;QACvF,aAAa,EAAE,QAAQ;QACvB,cAAc,EAAE,eAAe,CAC7B,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,uBAAuB,CAAC,WAAW,CAAC,EACzE,CAAC,EACD,WAAW,CAAC,sDAAsD;SACnE;QACD,cAAc,EAAE,kBAAkB,EAAE;QACpC,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;QAClC,mBAAmB,EAAE,qBAAqB,EAAE;KAC7C,CAAC;IACF,gCAAgC;IAChC,UAAU,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,kBAAkB;IACzB,IAAI,OAAO,CAAC,GAAG,CAAC,sBAAsB;QAAE,OAAO,aAAa,CAAC;IAC7D,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY;QAAE,OAAO,QAAQ,CAAC;IAC9C,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB;QAAE,OAAO,UAAU,CAAC;IACpD,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY;QAAE,OAAO,QAAQ,CAAC;IAC9C,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC5B,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,GAAG,YAAY,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,KAAa;IAC9B,IAAI,KAAK,GAAG,SAAS;QAAE,OAAO,GAAG,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IACpE,IAAI,KAAK,GAAG,KAAK;QAAE,OAAO,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5D,OAAO,GAAG,KAAK,GAAG,CAAC;AACrB,CAAC;AAED,KAAK,UAAU,SAAS;IACtB,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QACxC,MAAM,CAAC,IAAI,CAAC,KAAe,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAChD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,GAAG,CAAC,CAAC;IACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,oCAAoC;AACvD,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helpers de I/O — stat, read, hash. Tudo síncrono onde rapidez importa
|
|
3
|
+
* (hook tem que decidir em <50ms).
|
|
4
|
+
*/
|
|
5
|
+
export interface FileInfo {
|
|
6
|
+
exists: boolean;
|
|
7
|
+
size: number;
|
|
8
|
+
mtimeMs: number;
|
|
9
|
+
ext: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function fileInfo(path: string): FileInfo;
|
|
12
|
+
/** Lê apenas os primeiros N bytes — pra sniff de content. */
|
|
13
|
+
export declare function readFirstBytes(path: string, n: number): string;
|
|
14
|
+
/** Hash estável pra cache key (file_path + mtime). */
|
|
15
|
+
export declare function cacheKey(path: string, mtimeMs: number): string;
|
|
16
|
+
export declare function ensureDir(path: string): void;
|
|
17
|
+
export declare function ensureParentDir(filePath: string): void;
|
|
18
|
+
/** Tenta detectar agente que invocou (via env vars). */
|
|
19
|
+
export declare function detectAgent(): string;
|
|
20
|
+
//# sourceMappingURL=fileStat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileStat.d.ts","sourceRoot":"","sources":["../../src/lib/fileStat.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAS/C;AAED,6DAA6D;AAC7D,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAU9D;AAED,sDAAsD;AACtD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAI5C;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAEtD;AAED,wDAAwD;AACxD,wBAAgB,WAAW,IAAI,MAAM,CAgBpC"}
|