batman
This commit is contained in:
@@ -0,0 +1 @@
|
||||
node_modules/
|
||||
@@ -0,0 +1,153 @@
|
||||
# vitruvio-cli
|
||||
|
||||
Ferramentas de linha de comando para criação e manutenção de repositórios Vitruvio.
|
||||
|
||||
---
|
||||
|
||||
## Pré-requisitos
|
||||
|
||||
- **Node.js** 18 ou superior
|
||||
- **Git** instalado e acessível no terminal
|
||||
- **Chave SSH** configurada no servidor Gitea da davinTI (necessária para clonar via SSH — há fallback automático para HTTPS)
|
||||
|
||||
---
|
||||
|
||||
## Instalação
|
||||
|
||||
### Linux
|
||||
|
||||
```bash
|
||||
# 1. Clone o repositório
|
||||
git clone ssh://git@git.davinti.com.br:2222/davinTI/vitruvio-cli.git
|
||||
cd vitruvio-cli
|
||||
|
||||
# 2. Instale as dependências
|
||||
npm install
|
||||
|
||||
# 3. Registre o comando globalmente
|
||||
npm link
|
||||
```
|
||||
|
||||
Se você usa **mise** para gerenciar versões do Node, rode também:
|
||||
|
||||
```bash
|
||||
mise reshim
|
||||
```
|
||||
|
||||
Verifique a instalação:
|
||||
|
||||
```bash
|
||||
vitruvio --help
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Windows
|
||||
|
||||
Abra o **PowerShell** ou **Prompt de Comando** como administrador.
|
||||
|
||||
```powershell
|
||||
# 1. Clone o repositório
|
||||
git clone ssh://git@git.davinti.com.br:2222/davinTI/vitruvio-cli.git
|
||||
cd vitruvio-cli
|
||||
|
||||
# 2. Instale as dependências
|
||||
npm install
|
||||
|
||||
# 3. Registre o comando globalmente
|
||||
npm link
|
||||
```
|
||||
|
||||
Verifique a instalação:
|
||||
|
||||
```powershell
|
||||
vitruvio --help
|
||||
```
|
||||
|
||||
> **Nota:** Caso o terminal não reconheça o comando `vitruvio` após o `npm link`, verifique se o diretório de binários globais do npm está no PATH do sistema. Para descobrir o caminho:
|
||||
> ```powershell
|
||||
> npm config get prefix
|
||||
> ```
|
||||
> Adicione o caminho retornado (ex: `C:\Users\SeuUsuario\AppData\Roaming\npm`) nas variáveis de ambiente do sistema em **Painel de Controle → Sistema → Variáveis de Ambiente → Path**.
|
||||
|
||||
---
|
||||
|
||||
## Comandos
|
||||
|
||||
### `vitruvio init <nome>`
|
||||
|
||||
Cria um novo repositório Vitruvio a partir do template base.
|
||||
|
||||
```bash
|
||||
vitruvio init meu-modulo
|
||||
```
|
||||
|
||||
- Clona o template `projeto-base` para um diretório com o nome informado
|
||||
- Remove o histórico git do template e inicializa um repositório limpo sem remotes
|
||||
- Pronto para você adicionar seu próprio remote e fazer o primeiro commit
|
||||
|
||||
**Após o init:**
|
||||
|
||||
```bash
|
||||
cd meu-modulo
|
||||
|
||||
# Edite o vitruvio.json com a chave e nome do seu módulo
|
||||
# Depois:
|
||||
git remote add origin <url-do-seu-repositório>
|
||||
git add .
|
||||
git commit -m "feat: scaffold inicial"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `vitruvio update-repo`
|
||||
|
||||
Atualiza os arquivos `CLAUDE.md` gerenciados no repositório atual com a versão mais recente do template.
|
||||
|
||||
```bash
|
||||
# Execute dentro de um repositório Vitruvio (onde há vitruvio.json)
|
||||
cd meu-modulo
|
||||
vitruvio update-repo
|
||||
```
|
||||
|
||||
Arquivos atualizados por este comando:
|
||||
|
||||
```
|
||||
CLAUDE.md
|
||||
endpoints/CLAUDE.md
|
||||
panels/CLAUDE.md
|
||||
patches/CLAUDE.md
|
||||
processes/CLAUDE.md
|
||||
queries/CLAUDE.md
|
||||
reports/CLAUDE.md
|
||||
scripts/CLAUDE.md
|
||||
```
|
||||
|
||||
Nenhum outro arquivo do repositório é tocado.
|
||||
|
||||
---
|
||||
|
||||
### `vitruvio update-base`
|
||||
|
||||
Sincroniza os diretórios gerenciados do diretório de plataforma local com o repositório `base-claude`.
|
||||
|
||||
```bash
|
||||
vitruvio update-base
|
||||
```
|
||||
|
||||
Diretório de plataforma atualizado:
|
||||
|
||||
| Sistema | Caminho |
|
||||
|---------|---------|
|
||||
| Linux | `~/.local/share/vitruvio-platform/` |
|
||||
| Windows | `%LOCALAPPDATA%\vitruvio-platform\` |
|
||||
|
||||
Diretórios gerenciados (substituídos completamente):
|
||||
|
||||
```
|
||||
libs/
|
||||
docs/
|
||||
examples/
|
||||
```
|
||||
|
||||
Qualquer outro diretório ou arquivo fora dessa lista não é alterado.
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env node
|
||||
'use strict';
|
||||
|
||||
var { Command } = require('commander');
|
||||
var pkg = require('../package.json');
|
||||
|
||||
var initCmd = require('../src/commands/init');
|
||||
var updateRepoCmd = require('../src/commands/update-repo');
|
||||
var updateBaseCmd = require('../src/commands/update-base');
|
||||
|
||||
var program = new Command();
|
||||
|
||||
program
|
||||
.name('vitruvio')
|
||||
.description('Ferramentas de linha de comando para repositórios Vitruvio')
|
||||
.version(pkg.version);
|
||||
|
||||
initCmd.register(program);
|
||||
updateRepoCmd.register(program);
|
||||
updateBaseCmd.register(program);
|
||||
|
||||
program.parse(process.argv);
|
||||
Generated
+69
@@ -0,0 +1,69 @@
|
||||
{
|
||||
"name": "vitruvio-cli",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "vitruvio-cli",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"commander": "^12.0.0",
|
||||
"fs-extra": "^11.2.0"
|
||||
},
|
||||
"bin": {
|
||||
"vitruvio": "bin/vitruvio.js"
|
||||
}
|
||||
},
|
||||
"node_modules/commander": {
|
||||
"version": "12.1.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz",
|
||||
"integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/fs-extra": {
|
||||
"version": "11.3.4",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz",
|
||||
"integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.14"
|
||||
}
|
||||
},
|
||||
"node_modules/graceful-fs": {
|
||||
"version": "4.2.11",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
|
||||
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/jsonfile": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz",
|
||||
"integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"node_modules/universalify": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
|
||||
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "vitruvio-cli",
|
||||
"version": "1.0.0",
|
||||
"description": "CLI tooling for Vitruvio content repositories",
|
||||
"bin": {
|
||||
"vitruvio": "bin/vitruvio.js"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "node bin/vitruvio.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": "^12.0.0",
|
||||
"fs-extra": "^11.2.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
'use strict';
|
||||
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var { execSync } = require('child_process');
|
||||
var fse = require('fs-extra');
|
||||
var { cloneWithFallback, cleanupTemp } = require('../utils/git');
|
||||
|
||||
var SSH_URL = 'ssh://git@git.davinti.com.br:2222/davinTI/projeto-base.git';
|
||||
var HTTPS_URL = 'https://git.davinti.com.br/davinTI/projeto-base.git';
|
||||
|
||||
function register(program) {
|
||||
program
|
||||
.command('init <nome>')
|
||||
.description('Cria um novo repositório Vitruvio a partir do template base')
|
||||
.action(function (name) {
|
||||
var targetDir = path.resolve(process.cwd(), name);
|
||||
|
||||
if (fs.existsSync(targetDir)) {
|
||||
console.error('Erro: o diretório já existe: ' + targetDir);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log('Clonando template para ' + targetDir + '...');
|
||||
|
||||
var tmpDir = null;
|
||||
try {
|
||||
tmpDir = cloneWithFallback(SSH_URL, HTTPS_URL);
|
||||
} catch (e) {
|
||||
console.error('Erro: não foi possível clonar o repositório template.');
|
||||
console.error(e.message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
fse.copySync(tmpDir, targetDir, {
|
||||
filter: function (src) {
|
||||
var rel = path.relative(tmpDir, src);
|
||||
return rel !== '.git' && !rel.startsWith('.git' + path.sep);
|
||||
}
|
||||
});
|
||||
} finally {
|
||||
cleanupTemp(tmpDir);
|
||||
}
|
||||
|
||||
execSync('git init', { cwd: targetDir, stdio: 'pipe' });
|
||||
|
||||
console.log('');
|
||||
console.log('Pronto! Seu novo repositório Vitruvio está em:');
|
||||
console.log(' ' + targetDir);
|
||||
console.log('');
|
||||
console.log('Próximos passos:');
|
||||
console.log(' 1. Edite o vitruvio.json — atualize metadata.key e metadata.name do seu módulo');
|
||||
console.log(' 2. Adicione o seu remote:');
|
||||
console.log(' cd ' + name);
|
||||
console.log(' git remote add origin <url-do-seu-repositório>');
|
||||
console.log(' 3. Faça o commit inicial:');
|
||||
console.log(' git add .');
|
||||
console.log(' git commit -m "feat: scaffold inicial"');
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { register: register };
|
||||
@@ -0,0 +1,76 @@
|
||||
'use strict';
|
||||
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var fse = require('fs-extra');
|
||||
var { cloneWithFallback, cleanupTemp } = require('../utils/git');
|
||||
var { getPlatformDir } = require('../utils/platform');
|
||||
|
||||
var SSH_URL = 'ssh://git@git.davinti.com.br:2222/davinTI/base-claude.git';
|
||||
var HTTPS_URL = 'https://git.davinti.com.br/davinTI/base-claude.git';
|
||||
|
||||
// Directories inside the platform dir that are fully managed by this command.
|
||||
// Each of these is replaced in its entirety — files removed from the source
|
||||
// are also removed locally. Directories not in this list are never touched.
|
||||
var MANAGED_DIRS = ['libs', 'docs', 'examples'];
|
||||
|
||||
function register(program) {
|
||||
program
|
||||
.command('update-base')
|
||||
.description('Sincroniza os diretórios gerenciados do diretório de plataforma Vitruvio com o repositório base-claude')
|
||||
.action(function () {
|
||||
var platformDir;
|
||||
try {
|
||||
platformDir = getPlatformDir();
|
||||
} catch (e) {
|
||||
console.error('Erro: ' + e.message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log('Diretório de plataforma: ' + platformDir);
|
||||
console.log('Buscando repositório base-claude...');
|
||||
|
||||
var tmpDir = null;
|
||||
try {
|
||||
tmpDir = cloneWithFallback(SSH_URL, HTTPS_URL);
|
||||
} catch (e) {
|
||||
console.error('Erro: não foi possível clonar o repositório base-claude.');
|
||||
console.error(e.message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
fse.ensureDirSync(platformDir);
|
||||
|
||||
var results = [];
|
||||
|
||||
MANAGED_DIRS.forEach(function (dirName) {
|
||||
var src = path.join(tmpDir, dirName);
|
||||
var dest = path.join(platformDir, dirName);
|
||||
|
||||
if (!fs.existsSync(src)) {
|
||||
results.push({ dir: dirName, status: 'não encontrado no repositório' });
|
||||
return;
|
||||
}
|
||||
|
||||
// Full replacement: remove existing dir, copy fresh from source
|
||||
if (fs.existsSync(dest)) {
|
||||
fse.removeSync(dest);
|
||||
}
|
||||
fse.copySync(src, dest);
|
||||
results.push({ dir: dirName, status: 'atualizado' });
|
||||
});
|
||||
|
||||
console.log('');
|
||||
results.forEach(function (r) {
|
||||
console.log(' ' + r.dir + '/ — ' + r.status);
|
||||
});
|
||||
console.log('');
|
||||
console.log('Atualização concluída.');
|
||||
} finally {
|
||||
cleanupTemp(tmpDir);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { register: register };
|
||||
@@ -0,0 +1,82 @@
|
||||
'use strict';
|
||||
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var fse = require('fs-extra');
|
||||
var { cloneWithFallback, cleanupTemp } = require('../utils/git');
|
||||
|
||||
var SSH_URL = 'ssh://git@git.davinti.com.br:2222/davinTI/projeto-base.git';
|
||||
var HTTPS_URL = 'https://git.davinti.com.br/davinTI/projeto-base.git';
|
||||
|
||||
// CLAUDE.md files managed by the template — relative paths from repo root
|
||||
var MANAGED_FILES = [
|
||||
'CLAUDE.md',
|
||||
'endpoints/CLAUDE.md',
|
||||
'panels/CLAUDE.md',
|
||||
'patches/CLAUDE.md',
|
||||
'processes/CLAUDE.md',
|
||||
'queries/CLAUDE.md',
|
||||
'reports/CLAUDE.md',
|
||||
'scripts/CLAUDE.md'
|
||||
];
|
||||
|
||||
function register(program) {
|
||||
program
|
||||
.command('update-repo')
|
||||
.description('Atualiza os arquivos CLAUDE.md gerenciados neste repositório com a versão mais recente do template')
|
||||
.action(function () {
|
||||
var repoDir = process.cwd();
|
||||
|
||||
if (!fs.existsSync(path.join(repoDir, 'vitruvio.json'))) {
|
||||
console.error('Erro: nenhum vitruvio.json encontrado no diretório atual.');
|
||||
console.error('Execute este comando dentro de um repositório Vitruvio.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log('Buscando template mais recente...');
|
||||
|
||||
var tmpDir = null;
|
||||
try {
|
||||
tmpDir = cloneWithFallback(SSH_URL, HTTPS_URL);
|
||||
} catch (e) {
|
||||
console.error('Erro: não foi possível clonar o repositório template.');
|
||||
console.error(e.message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
var updated = [];
|
||||
var skipped = [];
|
||||
|
||||
MANAGED_FILES.forEach(function (relPath) {
|
||||
var src = path.join(tmpDir, relPath);
|
||||
var dest = path.join(repoDir, relPath);
|
||||
|
||||
if (!fs.existsSync(src)) {
|
||||
skipped.push(relPath);
|
||||
return;
|
||||
}
|
||||
|
||||
fse.ensureDirSync(path.dirname(dest));
|
||||
fse.copySync(src, dest, { overwrite: true });
|
||||
updated.push(relPath);
|
||||
});
|
||||
|
||||
console.log('');
|
||||
if (updated.length > 0) {
|
||||
console.log('Arquivos atualizados (' + updated.length + '):');
|
||||
updated.forEach(function (f) { console.log(' ' + f); });
|
||||
}
|
||||
if (skipped.length > 0) {
|
||||
console.log('Não encontrados no template (' + skipped.length + '):');
|
||||
skipped.forEach(function (f) { console.log(' ' + f); });
|
||||
}
|
||||
console.log('');
|
||||
console.log('Atualização concluída.');
|
||||
} finally {
|
||||
cleanupTemp(tmpDir);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { register: register };
|
||||
@@ -0,0 +1,48 @@
|
||||
'use strict';
|
||||
|
||||
var path = require('path');
|
||||
var os = require('os');
|
||||
var fs = require('fs');
|
||||
var { execSync } = require('child_process');
|
||||
|
||||
/**
|
||||
* Shallow-clones a git URL into a unique temp directory.
|
||||
* Returns the path to the cloned directory.
|
||||
* Throws on failure.
|
||||
*/
|
||||
function cloneToTemp(url) {
|
||||
var tmpBase = os.tmpdir();
|
||||
var tmpDir = path.join(tmpBase, 'vitruvio-' + Date.now() + '-' + Math.random().toString(36).slice(2));
|
||||
fs.mkdirSync(tmpDir, { recursive: true });
|
||||
execSync('git clone --depth 1 ' + url + ' ' + tmpDir, { stdio: 'pipe' });
|
||||
return tmpDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries SSH clone first; if it fails, tries HTTPS clone.
|
||||
* Returns the path to the cloned directory.
|
||||
*/
|
||||
function cloneWithFallback(sshUrl, httpsUrl) {
|
||||
try {
|
||||
return cloneToTemp(sshUrl);
|
||||
} catch (e) {
|
||||
console.log('Clone SSH falhou, tentando HTTPS...');
|
||||
return cloneToTemp(httpsUrl);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a temporary directory created by cloneToTemp.
|
||||
*/
|
||||
function cleanupTemp(tmpDir) {
|
||||
if (!tmpDir || !tmpDir.includes('vitruvio-')) {
|
||||
throw new Error('Refusing to delete unexpected path: ' + tmpDir);
|
||||
}
|
||||
fs.rmSync(tmpDir, { recursive: true, force: true });
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
cloneToTemp: cloneToTemp,
|
||||
cloneWithFallback: cloneWithFallback,
|
||||
cleanupTemp: cleanupTemp
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
'use strict';
|
||||
|
||||
var path = require('path');
|
||||
var os = require('os');
|
||||
|
||||
/**
|
||||
* Returns the path to the Vitruvio platform directory for the current OS.
|
||||
* Linux/macOS: ~/.local/share/vitruvio-platform/
|
||||
* Windows: %LOCALAPPDATA%\vitruvio-platform\
|
||||
*/
|
||||
function getPlatformDir() {
|
||||
if (process.platform === 'win32') {
|
||||
var localAppData = process.env.LOCALAPPDATA;
|
||||
if (!localAppData) {
|
||||
throw new Error('LOCALAPPDATA environment variable is not set.');
|
||||
}
|
||||
return path.join(localAppData, 'vitruvio-platform');
|
||||
}
|
||||
return path.join(os.homedir(), '.local', 'share', 'vitruvio-platform');
|
||||
}
|
||||
|
||||
module.exports = { getPlatformDir: getPlatformDir };
|
||||
Reference in New Issue
Block a user