@pathbit/agentdevkit 0.0.0-stage → 0.0.5
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/.pbai4devs/COMPATIBILIDADE.md +109 -0
- package/.pbai4devs/INSTRUCTIONS.md +87 -0
- package/.pbai4devs/README.md +50 -0
- package/.pbai4devs/agents/README.md +18 -0
- package/.pbai4devs/agents/revisor/AGENT.md +16 -0
- package/.pbai4devs/agents/revisor/antigravity.yaml +8 -0
- package/.pbai4devs/agents/revisor/claude.yaml +5 -0
- package/.pbai4devs/agents/revisor/cursor.yaml +5 -0
- package/.pbai4devs/agents/revisor/gemini.yaml +6 -0
- package/.pbai4devs/agents/revisor/github.yaml +5 -0
- package/.pbai4devs/agents/revisor/kimi-code.yaml +5 -0
- package/.pbai4devs/agents/revisor/mimocode.yaml +10 -0
- package/.pbai4devs/agents/revisor/opencode.yaml +7 -0
- package/.pbai4devs/agents/revisor/zcode.yaml +5 -0
- package/.pbai4devs/commands/README.md +30 -0
- package/.pbai4devs/commands/atualizar-ferramentas/COMMAND.md +17 -0
- package/.pbai4devs/commands/diagnosticar/COMMAND.md +18 -0
- package/.pbai4devs/commands/instalar-ferramentas/COMMAND.md +21 -0
- package/.pbai4devs/commands/preparar-dev/COMMAND.md +14 -0
- package/.pbai4devs/commands/proximos-passos/COMMAND.md +9 -0
- package/.pbai4devs/commands/revisar-entrega/COMMAND.md +29 -0
- package/.pbai4devs/commands/sincronizar/COMMAND.md +20 -0
- package/.pbai4devs/commands/status-roadmap/COMMAND.md +12 -0
- package/.pbai4devs/commands/testar-navegador/COMMAND.md +16 -0
- package/.pbai4devs/commands/verificar-agentes/COMMAND.md +19 -0
- package/.pbai4devs/estado/README.md +12 -0
- package/.pbai4devs/external-skills/CATALOG.json +121 -0
- package/.pbai4devs/external-skills/README.md +48 -0
- package/.pbai4devs/rules/README.md +18 -0
- package/.pbai4devs/rules/ambiente-local/RULE.md +33 -0
- package/.pbai4devs/rules/ambiente-local/cursor.yaml +4 -0
- package/.pbai4devs/rules/documentacao/RULE.md +11 -0
- package/.pbai4devs/rules/documentacao/cursor.yaml +4 -0
- package/.pbai4devs/rules/estrutura/RULE.md +33 -0
- package/.pbai4devs/rules/estrutura/cursor.yaml +4 -0
- package/.pbai4devs/rules/git/RULE.md +18 -0
- package/.pbai4devs/rules/git/cursor.yaml +4 -0
- package/.pbai4devs/rules/proximos-passos/RULE.md +14 -0
- package/.pbai4devs/rules/qualidade/RULE.md +32 -0
- package/.pbai4devs/rules/qualidade/cursor.yaml +4 -0
- package/.pbai4devs/scripts/README.md +69 -0
- package/.pbai4devs/scripts/diagnosticar-ambiente/SCRIPT.mjs +41 -0
- package/.pbai4devs/scripts/diagnosticar-ambiente/tests/TEST.mjs +30 -0
- package/.pbai4devs/scripts/executar-script/README.md +28 -0
- package/.pbai4devs/scripts/executar-script/SCRIPT.mjs +78 -0
- package/.pbai4devs/scripts/executar-script/tests/TEST.mjs +122 -0
- package/.pbai4devs/scripts/gerenciar-skills-externas/README.md +31 -0
- package/.pbai4devs/scripts/gerenciar-skills-externas/SCRIPT.mjs +182 -0
- package/.pbai4devs/scripts/gerenciar-skills-externas/tests/TEST.mjs +134 -0
- package/.pbai4devs/scripts/inspecionar-projeto/SCRIPT.mjs +190 -0
- package/.pbai4devs/scripts/inspecionar-projeto/tests/TEST.mjs +161 -0
- package/.pbai4devs/scripts/lib/README.md +9 -0
- package/.pbai4devs/scripts/lib/adapters.mjs +135 -0
- package/.pbai4devs/scripts/lib/catalog.mjs +170 -0
- package/.pbai4devs/scripts/lib/gitignore.mjs +348 -0
- package/.pbai4devs/scripts/lib/npm.mjs +17 -0
- package/.pbai4devs/scripts/lib/resource-path.mjs +20 -0
- package/.pbai4devs/scripts/lib/runtime.mjs +28 -0
- package/.pbai4devs/scripts/lib/script-config.mjs +8 -0
- package/.pbai4devs/scripts/preparar-ferramentas/BOOTSTRAP.md +34 -0
- package/.pbai4devs/scripts/preparar-ferramentas/BOOTSTRAP.mjs +189 -0
- package/.pbai4devs/scripts/preparar-ferramentas/README.md +71 -0
- package/.pbai4devs/scripts/preparar-ferramentas/SCRIPT.mjs +455 -0
- package/.pbai4devs/scripts/preparar-ferramentas/tests/FIXTURE.html +20 -0
- package/.pbai4devs/scripts/preparar-ferramentas/tests/SMOKE_BROWSER.mjs +55 -0
- package/.pbai4devs/scripts/preparar-ferramentas/tests/SMOKE_DESKTOP.mjs +61 -0
- package/.pbai4devs/scripts/preparar-ferramentas/tests/SMOKE_VERCEL.mjs +192 -0
- package/.pbai4devs/scripts/preparar-ferramentas/tests/TEST.mjs +552 -0
- package/.pbai4devs/scripts/preparar-ferramentas/tests/bootstrap.test.mjs +94 -0
- package/.pbai4devs/scripts/preparar-ferramentas/tests/fixtures-vercel/just-bash/input.txt +2 -0
- package/.pbai4devs/scripts/preparar-ferramentas/tests/fixtures-vercel/just-bash-overlay/input.txt +1 -0
- package/.pbai4devs/scripts/preparar-ferramentas/tests/fixtures-vercel/skills/agentdevkit-smoke/SKILL.md +8 -0
- package/.pbai4devs/scripts/preparar-ferramentas/tests/fixtures-vercel/webreel/index.html +6 -0
- package/.pbai4devs/scripts/preparar-ferramentas/tests/fixtures-vercel/webreel/webreel.config.json +10 -0
- package/.pbai4devs/scripts/revisar-entrega/README.md +36 -0
- package/.pbai4devs/scripts/revisar-entrega/SCRIPT.mjs +249 -0
- package/.pbai4devs/scripts/revisar-entrega/tests/TEST.mjs +249 -0
- package/.pbai4devs/scripts/sincronizar-agentes/README.md +41 -0
- package/.pbai4devs/scripts/sincronizar-agentes/SCRIPT.mjs +473 -0
- package/.pbai4devs/scripts/sincronizar-agentes/tests/LOCAL_IGNORE.mjs +290 -0
- package/.pbai4devs/scripts/sincronizar-agentes/tests/TEST.mjs +869 -0
- package/.pbai4devs/scripts/testar-infraestrutura/SCRIPT.mjs +39 -0
- package/.pbai4devs/scripts/testar-infraestrutura/tests/TEST.mjs +29 -0
- package/.pbai4devs/scripts/testar-maturidade/README.md +54 -0
- package/.pbai4devs/scripts/testar-maturidade/SCRIPT.mjs +477 -0
- package/.pbai4devs/scripts/testar-maturidade/assets/calculator.mjs +1 -0
- package/.pbai4devs/scripts/testar-maturidade/assets/calculator.test.mjs.template +8 -0
- package/.pbai4devs/scripts/testar-maturidade/assets/http-api.test.mjs.template +28 -0
- package/.pbai4devs/scripts/testar-maturidade/assets/server.mjs +34 -0
- package/.pbai4devs/scripts/testar-maturidade/tests/TEST.mjs +305 -0
- package/.pbai4devs/scripts/testar-navegador/REFERENCE.md +49 -0
- package/.pbai4devs/scripts/testar-navegador/SCRIPT.conf +1 -0
- package/.pbai4devs/scripts/testar-navegador/SCRIPT.js +64 -0
- package/.pbai4devs/scripts/testar-navegador/tests/FAIL.js +8 -0
- package/.pbai4devs/scripts/testar-navegador/tests/SUCCESS.js +13 -0
- package/.pbai4devs/scripts/verificar-recursos/README.md +25 -0
- package/.pbai4devs/scripts/verificar-recursos/SCRIPT.mjs +209 -0
- package/.pbai4devs/scripts/verificar-recursos/tests/TEST.mjs +310 -0
- package/.pbai4devs/scripts/verificar-recursos/tests/ambiente-local.mjs +80 -0
- package/.pbai4devs/skills/README.md +24 -0
- package/.pbai4devs/skills/git/git-branch/SKILL.md +11 -0
- package/.pbai4devs/skills/git/git-commit/SKILL.md +16 -0
- package/.pbai4devs/skills/git/git-diff/SKILL.md +9 -0
- package/.pbai4devs/skills/git/git-fetch/SKILL.md +10 -0
- package/.pbai4devs/skills/git/git-log/SKILL.md +9 -0
- package/.pbai4devs/skills/git/git-merge/SKILL.md +13 -0
- package/.pbai4devs/skills/git/git-pull/SKILL.md +12 -0
- package/.pbai4devs/skills/git/git-push/SKILL.md +12 -0
- package/.pbai4devs/skills/git/git-status/SKILL.md +9 -0
- package/.pbai4devs/skills/git/git-worktree/SKILL.md +10 -0
- package/.pbai4devs/skills/produto/criar-design-doc/SKILL.md +37 -0
- package/.pbai4devs/skills/produto/criar-prd/SKILL.md +35 -0
- package/.pbai4devs/skills/produto/criar-ux-ui/SKILL.md +34 -0
- package/.pbai4devs/skills/projeto/atualizar-documentacao/SKILL.md +26 -0
- package/.pbai4devs/skills/projeto/configurar-projeto/SKILL.md +62 -0
- package/.pbai4devs/skills/projeto/criar-agente/SKILL.md +20 -0
- package/.pbai4devs/skills/projeto/criar-comando/SKILL.md +25 -0
- package/.pbai4devs/skills/projeto/criar-recurso/SKILL.md +41 -0
- package/.pbai4devs/skills/projeto/criar-regra/SKILL.md +19 -0
- package/.pbai4devs/skills/projeto/criar-skill/SKILL.md +22 -0
- package/.pbai4devs/skills/projeto/executar-script/SKILL.md +29 -0
- package/.pbai4devs/skills/projeto/preparar-dev/SKILL.md +45 -0
- package/.pbai4devs/skills/projeto/preparar-ferramentas/SKILL.md +56 -0
- package/.pbai4devs/skills/projeto/proximos-passos/SKILL.md +23 -0
- package/.pbai4devs/skills/projeto/sincronizar-agentes/SKILL.md +42 -0
- package/.pbai4devs/skills/projeto/usar-skills-externas/SKILL.md +28 -0
- package/.pbai4devs/skills/projeto/verificar-trabalho/SKILL.md +45 -0
- package/.pbai4devs/skills/specs/criar-spec/SKILL.md +33 -0
- package/.pbai4devs/skills/specs/gerenciar-roadmap/SKILL.md +26 -0
- package/.pbai4devs/skills/specs/implementar-spec/SKILL.md +48 -0
- package/.pbai4devs/templates/README.md +65 -0
- package/.pbai4devs/templates/adr/TEMPLATE.md +21 -0
- package/.pbai4devs/templates/ambiente-local/Makefile.template +48 -0
- package/.pbai4devs/templates/ambiente-local/TEMPLATE.md +48 -0
- package/.pbai4devs/templates/ambiente-local/compose.local.yml.template +16 -0
- package/.pbai4devs/templates/ambiente-local/dockerignore.template +28 -0
- package/.pbai4devs/templates/changelog/TEMPLATE.md +17 -0
- package/.pbai4devs/templates/claude/TEMPLATE.md +8 -0
- package/.pbai4devs/templates/clients/ADAPTERS.json +306 -0
- package/.pbai4devs/templates/clients/TEMPLATE.md +12 -0
- package/.pbai4devs/templates/comando/TEMPLATE.md +15 -0
- package/.pbai4devs/templates/configuracao/TEMPLATE.md +46 -0
- package/.pbai4devs/templates/configuracao-raiz/TEMPLATE.md +22 -0
- package/.pbai4devs/templates/configuracao-raiz/editorconfig.template +21 -0
- package/.pbai4devs/templates/configuracao-raiz/env.example.template +3 -0
- package/.pbai4devs/templates/configuracao-raiz/gitattributes.template +6 -0
- package/.pbai4devs/templates/contribuicao/TEMPLATE.md +23 -0
- package/.pbai4devs/templates/design/TEMPLATE.md +30 -0
- package/.pbai4devs/templates/entrypoints/AGENTS.md +19 -0
- package/.pbai4devs/templates/entrypoints/CLAUDE.md +7 -0
- package/.pbai4devs/templates/entrypoints/GEMINI.md +7 -0
- package/.pbai4devs/templates/entrypoints/TEMPLATE.md +12 -0
- package/.pbai4devs/templates/gitignore/TEMPLATE.md +42 -0
- package/.pbai4devs/templates/gitignore/agents.ignore +45 -0
- package/.pbai4devs/templates/gitignore/clients.json +20 -0
- package/.pbai4devs/templates/gitignore/local.ignore +10 -0
- package/.pbai4devs/templates/gitignore/shared.ignore +60 -0
- package/.pbai4devs/templates/instrucoes-agentes/TEMPLATE.md +25 -0
- package/.pbai4devs/templates/plano-implementacao/TEMPLATE.md +27 -0
- package/.pbai4devs/templates/prd/TEMPLATE.md +30 -0
- package/.pbai4devs/templates/readme-pasta/TEMPLATE.md +16 -0
- package/.pbai4devs/templates/readme-projeto/TEMPLATE.md +34 -0
- package/.pbai4devs/templates/release/TEMPLATE.md +23 -0
- package/.pbai4devs/templates/revisao-entrega/TEMPLATE.md +41 -0
- package/.pbai4devs/templates/roadmap/TEMPLATE.md +18 -0
- package/.pbai4devs/templates/seguranca/TEMPLATE.md +22 -0
- package/.pbai4devs/templates/spec/TEMPLATE.md +61 -0
- package/.pbai4devs/templates/tasks/TEMPLATE.md +20 -0
- package/.pbai4devs/templates/ux-ui/TEMPLATE.md +26 -0
- package/.pbai4devs/tools/README.md +87 -0
- package/.pbai4devs/tools/agent-browser/README.md +26 -0
- package/.pbai4devs/tools/agent-browser/SCRIPT.mjs +5 -0
- package/.pbai4devs/tools/agent-browser/TOOL.json +33 -0
- package/.pbai4devs/tools/agent-desktop/README.md +26 -0
- package/.pbai4devs/tools/agent-desktop/SCRIPT.mjs +5 -0
- package/.pbai4devs/tools/agent-desktop/TOOL.json +30 -0
- package/.pbai4devs/tools/just-bash/README.md +23 -0
- package/.pbai4devs/tools/just-bash/SCRIPT.mjs +5 -0
- package/.pbai4devs/tools/just-bash/TOOL.json +27 -0
- package/.pbai4devs/tools/markdownlint-cli2/README.md +18 -0
- package/.pbai4devs/tools/markdownlint-cli2/SCRIPT.mjs +5 -0
- package/.pbai4devs/tools/markdownlint-cli2/TOOL.json +28 -0
- package/.pbai4devs/tools/opensrc/README.md +25 -0
- package/.pbai4devs/tools/opensrc/SCRIPT.mjs +5 -0
- package/.pbai4devs/tools/opensrc/TOOL.json +29 -0
- package/.pbai4devs/tools/portless/README.md +21 -0
- package/.pbai4devs/tools/portless/SCRIPT.mjs +5 -0
- package/.pbai4devs/tools/portless/TOOL.json +30 -0
- package/.pbai4devs/tools/skills/README.md +24 -0
- package/.pbai4devs/tools/skills/SCRIPT.mjs +5 -0
- package/.pbai4devs/tools/skills/TOOL.json +33 -0
- package/.pbai4devs/tools/webreel/README.md +23 -0
- package/.pbai4devs/tools/webreel/SCRIPT.mjs +5 -0
- package/.pbai4devs/tools/webreel/TOOL.json +25 -0
- package/CHANGELOG.md +58 -0
- package/CONTRIBUTING.md +73 -0
- package/LICENSE +21 -0
- package/README.en.md +78 -0
- package/README.es.md +80 -0
- package/README.md +88 -2
- package/bin/README.md +8 -0
- package/bin/agentdevkit.mjs +35 -0
- package/docs/README.md +81 -0
- package/docs/guides/README.md +14 -0
- package/docs/guides/cli.md +81 -0
- package/docs/guides/installation.md +78 -0
- package/docs/guides/resources.md +121 -0
- package/docs/guides/tools-and-testing.md +85 -0
- package/docs/guides/troubleshooting.md +151 -0
- package/docs/guides/workflow.md +130 -0
- package/docs/maintainers/README.md +12 -0
- package/docs/maintainers/community.md +49 -0
- package/docs/maintainers/development.md +54 -0
- package/docs/maintainers/maintenance.md +104 -0
- package/docs/maintainers/packages.md +76 -0
- package/docs/product/README.md +12 -0
- package/docs/product/design.md +94 -0
- package/docs/product/prd.md +64 -0
- package/docs/product/roadmap.md +36 -0
- package/docs/product/ux-ui.md +42 -0
- package/docs/specs/README.md +20 -0
- package/docs/specs/github-packages/SPEC.md +45 -0
- package/docs/specs/v0.0.1/README.md +10 -0
- package/docs/specs/v0.0.1/SPEC.md +57 -0
- package/docs/specs/v0.0.2/README.md +10 -0
- package/docs/specs/v0.0.2/SPEC.md +67 -0
- package/docs/specs/v0.0.3/README.md +10 -0
- package/docs/specs/v0.0.3/SPEC.md +64 -0
- package/docs/specs/v0.0.4/README.md +10 -0
- package/docs/specs/v0.0.4/SPEC.md +53 -0
- package/docs/specs/v0.0.5/README.md +9 -0
- package/docs/specs/v0.0.5/SPEC.md +42 -0
- package/package.json +52 -4
- package/src/README.md +16 -0
- package/src/adapters/index.mjs +1 -0
- package/src/cli.mjs +162 -0
- package/src/config.mjs +14 -0
- package/src/i18n.mjs +42 -0
- package/src/install.mjs +367 -0
- package/src/next.mjs +79 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
import { get } from 'node:https';
|
|
4
|
+
import { createReadStream, createWriteStream, existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, readlinkSync, realpathSync, renameSync, rmSync } from 'node:fs';
|
|
5
|
+
import { delimiter, dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';
|
|
6
|
+
import { spawnSync } from 'node:child_process';
|
|
7
|
+
import { pipeline } from 'node:stream/promises';
|
|
8
|
+
import { fileURLToPath } from 'node:url';
|
|
9
|
+
import { findExecutable, projectRoot } from '../lib/runtime.mjs';
|
|
10
|
+
import { npmCandidates } from '../lib/npm.mjs';
|
|
11
|
+
|
|
12
|
+
const versionPattern = /^\d+\.\d+\.\d+$/;
|
|
13
|
+
const stat = path => { try { return lstatSync(path); } catch (error) { if (error.code === 'ENOENT') return null; throw error; } };
|
|
14
|
+
const failure = message => { throw new Error(message); };
|
|
15
|
+
|
|
16
|
+
function safePath(root, parts) {
|
|
17
|
+
let path = root;
|
|
18
|
+
for (const part of parts) {
|
|
19
|
+
if (!part || part === '..' || part.includes('/') || part.includes('\\')) failure('Caminho de runtime invalido.');
|
|
20
|
+
path = join(path, part);
|
|
21
|
+
if (stat(path)?.isSymbolicLink()) failure(`Cache nao pode ser link simbolico: ${path}`);
|
|
22
|
+
}
|
|
23
|
+
return path;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function environmentWithNode(environment, node) {
|
|
27
|
+
const result = { ...environment };
|
|
28
|
+
const key = Object.keys(result).find(key => key.toLowerCase() === 'path') || 'PATH';
|
|
29
|
+
result[key] = `${dirname(node)}${delimiter}${result[key] || ''}`;
|
|
30
|
+
return result;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export async function downloadOfficial(url, destination) {
|
|
34
|
+
const parsed = new URL(url);
|
|
35
|
+
if (parsed.protocol !== 'https:' || parsed.hostname !== 'nodejs.org' || parsed.username || parsed.password) failure('Origem de runtime nao autorizada.');
|
|
36
|
+
const response = await new Promise((accept, reject) => {
|
|
37
|
+
const request = get(parsed, accept);
|
|
38
|
+
request.on('error', reject);
|
|
39
|
+
request.setTimeout(300000, () => request.destroy(new Error('Tempo limite no download do Node.')));
|
|
40
|
+
});
|
|
41
|
+
if (response.statusCode !== 200) { response.resume(); failure(`Download do Node falhou: HTTP ${response.statusCode}`); }
|
|
42
|
+
let size = 0;
|
|
43
|
+
response.on('data', chunk => { size += chunk.length; if (size > 150 * 1024 * 1024) response.destroy(new Error('Download do Node excedeu o limite.')); });
|
|
44
|
+
await pipeline(response, createWriteStream(destination, { flags: 'wx' }));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function probe(node, minimum, run, environment) {
|
|
48
|
+
const result = run(node, ['-p', 'JSON.stringify({version:process.versions.node,node:process.execPath,bun:Boolean(process.versions.bun)})'], { encoding: 'utf8', timeout: 20000, env: environment });
|
|
49
|
+
if (result.error || result.status !== 0) return null;
|
|
50
|
+
try {
|
|
51
|
+
const info = JSON.parse(result.stdout);
|
|
52
|
+
return !info.bun && versionPattern.test(info.version) && Number(info.version.split('.')[0]) >= minimum ? info : null;
|
|
53
|
+
} catch { return null; }
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function npmFor(node, run, environment, platform, localOnly = false) {
|
|
57
|
+
const candidates = localOnly ? [join(dirname(node), 'node_modules/npm/bin/npm-cli.js'), join(dirname(node), '../lib/node_modules/npm/bin/npm-cli.js')] : npmCandidates({ node, environment });
|
|
58
|
+
for (const candidate of candidates) {
|
|
59
|
+
if (!candidate || !candidate.endsWith('npm-cli.js') || !stat(candidate)?.isFile()) continue;
|
|
60
|
+
if (localOnly) {
|
|
61
|
+
const base = platform === 'win32' ? dirname(node) : resolve(dirname(node), '..');
|
|
62
|
+
const path = relative(base, candidate);
|
|
63
|
+
if (path.startsWith('..') || path.includes(`..${sep}`)) continue;
|
|
64
|
+
safePath(base, path.split(sep));
|
|
65
|
+
}
|
|
66
|
+
const file = realpathSync(candidate);
|
|
67
|
+
const result = run(node, [file, '--version'], { encoding: 'utf8', timeout: 20000, env: environmentWithNode(environment, node) });
|
|
68
|
+
if (!result.error && result.status === 0 && /^\d+\.\d+\.\d+(?:-[\w.-]+)?$/.test(result.stdout?.trim() || '')) return file;
|
|
69
|
+
}
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function platformName(platform, arch, run, environment, libc) {
|
|
74
|
+
if (!['darwin', 'linux', 'win32'].includes(platform) || !['x64', 'arm64'].includes(arch)) failure('Node local suporta Windows, macOS e Linux x64/arm64.');
|
|
75
|
+
if (platform === 'win32') return `win-${arch}`;
|
|
76
|
+
if (platform === 'darwin') return `darwin-${arch}`;
|
|
77
|
+
if (!libc) {
|
|
78
|
+
if (process.report?.getReport().header.glibcVersionRuntime) libc = 'glibc';
|
|
79
|
+
else {
|
|
80
|
+
const result = run('ldd', ['--version'], { encoding: 'utf8', timeout: 10000, env: environment });
|
|
81
|
+
const text = `${result.stdout || ''}\n${result.stderr || ''}`;
|
|
82
|
+
libc = /musl/i.test(text) ? 'musl' : /glibc|gnu/i.test(text) ? 'glibc' : null;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (!['glibc', 'musl'].includes(libc)) failure('Nao foi possivel identificar glibc/musl.');
|
|
86
|
+
return `linux-${arch}${libc === 'musl' ? '-musl' : ''}`;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function validateArchive(members, top) {
|
|
90
|
+
if (!members.trim()) failure('Arquivo vazio.');
|
|
91
|
+
for (const name of members.trimEnd().split(/\r?\n/)) {
|
|
92
|
+
if (/[\\:\x00-\x1f\x7f]/.test(name) || name.startsWith('/') || name.split('/').includes('..') || (name !== top && name !== top + '/' && !name.startsWith(top + '/'))) failure('Arquivo contem caminho fora da distribuicao.');
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function validateExtracted(root) {
|
|
97
|
+
const base = realpathSync(root);
|
|
98
|
+
function inside(path) { const value = relative(base, path); return value !== '..' && !value.startsWith('..' + sep) && !isAbsolute(value); }
|
|
99
|
+
function visit(directory) {
|
|
100
|
+
for (const name of readdirSync(directory)) {
|
|
101
|
+
const file = join(directory, name), info = lstatSync(file);
|
|
102
|
+
if (info.isSymbolicLink()) {
|
|
103
|
+
const target = readlinkSync(file);
|
|
104
|
+
if (isAbsolute(target) || !inside(resolve(directory, target)) || !inside(realpathSync(file))) failure('Arquivo contem link fora da distribuicao.');
|
|
105
|
+
} else if (info.isDirectory()) visit(file);
|
|
106
|
+
else if (!info.isFile() || info.nlink > 1) failure('Arquivo contem tipo ou hardlink inseguro.');
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
visit(base);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export async function ensureRuntime({ root = projectRoot, minimum = 24, node = process.execPath, platform = process.platform, arch = process.arch, libc, run = spawnSync, download = downloadOfficial, environment = process.env } = {}) {
|
|
113
|
+
if (Number(process.versions.node.split('.')[0]) < 18) failure('O inicializador requer Node.js 18+; instale Node.js 24+ pelo gerenciador do SO.');
|
|
114
|
+
root = realpathSync(root);
|
|
115
|
+
const current = probe(node, minimum, run, environment);
|
|
116
|
+
if (current) {
|
|
117
|
+
const npm = npmFor(current.node, run, environment, platform);
|
|
118
|
+
if (npm) return { node: current.node, npm, version: current.version, source: 'current' };
|
|
119
|
+
}
|
|
120
|
+
const targetPlatform = platformName(platform, arch, run, environment, libc);
|
|
121
|
+
const cache = safePath(root, ['.pbai4devs', 'tools', '.cache', 'runtime', 'node', targetPlatform]);
|
|
122
|
+
if (stat(cache) && !stat(cache).isDirectory()) failure('Cache de runtime nao e diretorio.');
|
|
123
|
+
if (existsSync(cache)) for (const version of readdirSync(cache).filter(name => /^v24\.\d+\.\d+$/.test(name)).sort((left, right) => right.localeCompare(left, undefined, { numeric: true }))) {
|
|
124
|
+
const base = safePath(cache, [version]);
|
|
125
|
+
const executable = safePath(base, platform === 'win32' ? ['node.exe'] : ['bin', 'node']);
|
|
126
|
+
const found = probe(executable, minimum, run, environment);
|
|
127
|
+
if (found) { const npm = npmFor(executable, run, environment, platform, true); if (npm) return { node: executable, npm, version: found.version, source: 'cache' }; }
|
|
128
|
+
}
|
|
129
|
+
const tar = findExecutable('tar', environment, platform);
|
|
130
|
+
if (!tar) failure('Instale tar pelo gerenciador do SO para extrair o Node local.');
|
|
131
|
+
mkdirSync(cache, { recursive: true });
|
|
132
|
+
const stage = mkdtempSync(join(cache, '.stage.')); let backup, target;
|
|
133
|
+
const cleanup = () => {
|
|
134
|
+
if (backup && existsSync(backup) && !existsSync(target)) renameSync(backup, target);
|
|
135
|
+
rmSync(stage, { recursive: true, force: true });
|
|
136
|
+
};
|
|
137
|
+
const onInt = () => { cleanup(); process.exit(130); }, onTerm = () => { cleanup(); process.exit(143); };
|
|
138
|
+
process.once('SIGINT', onInt); process.once('SIGTERM', onTerm);
|
|
139
|
+
try {
|
|
140
|
+
const manifest = join(stage, 'SHASUMS256.txt');
|
|
141
|
+
await download('https://nodejs.org/dist/latest-v24.x/SHASUMS256.txt', manifest);
|
|
142
|
+
const extension = platform === 'win32' ? 'zip' : 'tar.gz';
|
|
143
|
+
const candidates = readFileSync(manifest, 'utf8').split(/\r?\n/).map(line => line.match(/^([a-f0-9]{64})\s+(node-v24\.\d+\.\d+-[^\s]+)$/i)).filter(match => match && match[2].endsWith(`-${targetPlatform}.${extension}`));
|
|
144
|
+
if (candidates.length !== 1) failure(`Distribuicao oficial Node 24 indisponivel para ${targetPlatform}.`);
|
|
145
|
+
const [, expected, filename] = candidates[0], archive = join(stage, filename);
|
|
146
|
+
await download(`https://nodejs.org/dist/${filename.match(/^node-(v24\.\d+\.\d+)-/)[1]}/${filename}`, archive);
|
|
147
|
+
const hash = createHash('sha256'); for await (const chunk of createReadStream(archive)) hash.update(chunk);
|
|
148
|
+
if (hash.digest('hex') !== expected.toLowerCase()) failure('SHA-256 divergente; arquivo recusado.');
|
|
149
|
+
const list = args => {
|
|
150
|
+
const result = run(tar, args, { encoding: 'utf8', timeout: 120000, maxBuffer: 16 * 1024 * 1024, env: environment });
|
|
151
|
+
if (result.error || result.status !== 0) failure(`tar falhou: ${result.error?.message || result.stderr || result.status}`);
|
|
152
|
+
return result.stdout;
|
|
153
|
+
};
|
|
154
|
+
const top = filename.slice(0, -extension.length - 1);
|
|
155
|
+
validateArchive(list(['-tf', archive]), top);
|
|
156
|
+
const unpack = join(stage, 'unpack'); mkdirSync(unpack);
|
|
157
|
+
list(['-xf', archive, '-C', unpack]);
|
|
158
|
+
validateExtracted(unpack);
|
|
159
|
+
const installation = safePath(unpack, [top]);
|
|
160
|
+
const executable = safePath(installation, platform === 'win32' ? ['node.exe'] : ['bin', 'node']);
|
|
161
|
+
const found = probe(executable, minimum, run, environment);
|
|
162
|
+
const npm = found && npmFor(executable, run, environment, platform, true);
|
|
163
|
+
if (!found || !npm) failure('Node/npm extraidos falharam na verificacao.');
|
|
164
|
+
const version = filename.match(/^node-(v24\.\d+\.\d+)-/)[1]; target = safePath(cache, [version]);
|
|
165
|
+
if (existsSync(target)) { backup = join(stage, 'previous'); renameSync(target, backup); }
|
|
166
|
+
renameSync(installation, target);
|
|
167
|
+
return { node: join(target, relative(installation, executable)), npm: join(target, relative(installation, npm)), version: found.version, source: 'download' };
|
|
168
|
+
} finally { process.removeListener('SIGINT', onInt); process.removeListener('SIGTERM', onTerm); cleanup(); }
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export async function main(args = process.argv.slice(2), options = {}) {
|
|
172
|
+
const runtimeOnly = args[0] === '--runtime-only';
|
|
173
|
+
if (runtimeOnly && args.length !== 1) failure('--runtime-only nao aceita selecao ou outros argumentos.');
|
|
174
|
+
if (!runtimeOnly && args.some(arg => arg.startsWith('-'))) failure('Use --runtime-only ou uma selecao de ferramentas.');
|
|
175
|
+
const runtime = await ensureRuntime(options);
|
|
176
|
+
process.stdout.write(`node=${runtime.node}\n`);
|
|
177
|
+
if (runtimeOnly) return 0;
|
|
178
|
+
const result = (options.run || spawnSync)(runtime.node, [join(options.root || projectRoot, '.pbai4devs/scripts/preparar-ferramentas/SCRIPT.mjs'), 'setup', ...args], { stdio: 'inherit', env: environmentWithNode(options.environment || process.env, runtime.node) });
|
|
179
|
+
if (result.error) throw result.error;
|
|
180
|
+
return result.status ?? 1;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function isEntrypoint() {
|
|
184
|
+
try { return Boolean(process.argv[1]) && realpathSync(resolve(process.argv[1])) === fileURLToPath(import.meta.url); }
|
|
185
|
+
catch { return false; }
|
|
186
|
+
}
|
|
187
|
+
if (isEntrypoint()) {
|
|
188
|
+
try { process.exitCode = await main(); } catch (error) { console.error(`bootstrap: ${error.message}`); process.exitCode = 1; }
|
|
189
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Instalação, atualização e execução das ferramentas locais.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Preparar ferramentas
|
|
6
|
+
|
|
7
|
+
O [catálogo](../../tools/README.md) é descoberto pelos arquivos `TOOL.json`.
|
|
8
|
+
|
|
9
|
+
## Primeiro uso
|
|
10
|
+
|
|
11
|
+
Peça ao agente `instalar-ferramentas`. Ele segue o
|
|
12
|
+
[preparo automático](BOOTSTRAP.md): verifica Node/npm, instala o runtime local
|
|
13
|
+
quando necessário e continua sozinho até a validação das ferramentas.
|
|
14
|
+
O inicializador JavaScript aceita Node 18+ e prepara Node 24+ localmente.
|
|
15
|
+
Sem Node/npm, o agente usa o gerenciador do SO antes de executar o kit.
|
|
16
|
+
Não há mudança permanente no PATH nem scripts Bash ou PowerShell.
|
|
17
|
+
|
|
18
|
+
Se Node 24+ com npm já estiver disponível, também pode executar diretamente:
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
node .pbai4devs/scripts/preparar-ferramentas/SCRIPT.mjs setup
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
`setup` reutiliza instalações saudáveis e executa `check` para cada ferramenta.
|
|
25
|
+
Aceita `base`, grupo ou nome; sem seleção, usa `all`. Incompatibilidades na
|
|
26
|
+
seleção geral são informadas como não aplicáveis; pedir uma delas pelo nome
|
|
27
|
+
falha. Falhas de instalação/verificação são relatadas e retornam código 1.
|
|
28
|
+
Sem npm funcional, o preparo para antes de alterar as ferramentas.
|
|
29
|
+
Ao mover o hub, preserve suas pastas `.local` e `.cache`; `setup` reutiliza os
|
|
30
|
+
pacotes e regenera os atalhos locais, que usam imports relativos.
|
|
31
|
+
|
|
32
|
+
## Operações individuais
|
|
33
|
+
|
|
34
|
+
Com runtime disponível, execute a ação diretamente. Se ele faltar, use
|
|
35
|
+
`node .pbai4devs/scripts/preparar-ferramentas/BOOTSTRAP.mjs --runtime-only`
|
|
36
|
+
e reutilize o caminho retornado; esse modo não instala ferramentas.
|
|
37
|
+
|
|
38
|
+
Na raiz do repositório:
|
|
39
|
+
|
|
40
|
+
```sh
|
|
41
|
+
node .pbai4devs/scripts/preparar-ferramentas/SCRIPT.mjs list
|
|
42
|
+
node .pbai4devs/scripts/preparar-ferramentas/SCRIPT.mjs install skills
|
|
43
|
+
node .pbai4devs/scripts/preparar-ferramentas/SCRIPT.mjs update base
|
|
44
|
+
node .pbai4devs/scripts/preparar-ferramentas/SCRIPT.mjs check all
|
|
45
|
+
node .pbai4devs/scripts/preparar-ferramentas/SCRIPT.mjs unlock skills
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
`info <nome>` mostra configuração e estado; `run <nome> [argumentos]` executa
|
|
49
|
+
sem instalar. Sem ação, há ajuda. Cada ferramenta tem uma única entrada
|
|
50
|
+
`SCRIPT.mjs`, executada com Node em qualquer sistema.
|
|
51
|
+
|
|
52
|
+
`unlock <nome>` recupera somente um lock local com PID comprovadamente morto.
|
|
53
|
+
Locks ativos, de outro host ou sem metadados verificáveis são preservados.
|
|
54
|
+
Não aceita grupos. Um lock ausente não cria arquivos.
|
|
55
|
+
|
|
56
|
+
O requisito comum é Node.js 24+ com npm. O gerenciador usa o Node atual.
|
|
57
|
+
Downloads usam npm oficial com scripts de instalação desativados e integridade
|
|
58
|
+
conferida.
|
|
59
|
+
Permissões de binários POSIX são aplicadas somente aos caminhos declarados
|
|
60
|
+
em `executables` no `TOOL.json`, antes do probe.
|
|
61
|
+
Atualizações usam staging e preservam a versão anterior em caso de falha.
|
|
62
|
+
Atalhos locais recusam diretórios e arquivos simbólicos antes de escrever.
|
|
63
|
+
O preparo valida os CLIs. Navegador, permissões desktop e FFmpeg dependem da
|
|
64
|
+
tarefa; ele não inicia aplicações nem concede permissões automaticamente.
|
|
65
|
+
|
|
66
|
+
Testes: `node --test .pbai4devs/scripts/preparar-ferramentas/tests/TEST.mjs`.
|
|
67
|
+
Após instalar `skills`, `just-bash`, `opensrc`, `webreel` e `portless`, execute
|
|
68
|
+
`node .pbai4devs/scripts/preparar-ferramentas/tests/SMOKE_VERCEL.mjs`.
|
|
69
|
+
Ele prova descoberta local, shell virtual e validação de roteiro; Portless
|
|
70
|
+
recebe probes. Vídeo, proxy, TLS e downloads de fontes não são exercitados.
|
|
71
|
+
Relatórios ficam em `.agent-tests/vercel-labs/`.
|