@ornexus/synapse-cli 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +18 -0
- package/LICENSE +127 -0
- package/README.md +662 -0
- package/install.js +323 -0
- package/package.json +111 -0
- package/sync-version.js +186 -0
package/install.js
ADDED
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Synapse CLI - Binary Installer
|
|
5
|
+
*
|
|
6
|
+
* Downloads and installs the pre-compiled native binary from GitHub Releases.
|
|
7
|
+
* The binary is self-contained with all assets encrypted inside.
|
|
8
|
+
*
|
|
9
|
+
* Usage: npx @ornexus/synapse-cli
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const https = require('https');
|
|
13
|
+
const http = require('http');
|
|
14
|
+
const fs = require('fs');
|
|
15
|
+
const path = require('path');
|
|
16
|
+
const os = require('os');
|
|
17
|
+
const { execSync } = require('child_process');
|
|
18
|
+
const crypto = require('crypto');
|
|
19
|
+
|
|
20
|
+
const args = process.argv.slice(2);
|
|
21
|
+
|
|
22
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, 'package.json'), 'utf8'));
|
|
23
|
+
const VERSION = pkg.version;
|
|
24
|
+
const REPO = 'OrNexus-AI/synapse-cli';
|
|
25
|
+
const RELEASE_URL = `https://api.github.com/repos/${REPO}/releases/tags/v${VERSION}`;
|
|
26
|
+
const LATEST_RELEASE_URL = `https://api.github.com/repos/${REPO}/releases/latest`;
|
|
27
|
+
|
|
28
|
+
// Auth token for private repos (GITHUB_TOKEN, GH_TOKEN, or gh CLI token)
|
|
29
|
+
function getGitHubToken() {
|
|
30
|
+
if (process.env.GITHUB_TOKEN) return process.env.GITHUB_TOKEN;
|
|
31
|
+
if (process.env.GH_TOKEN) return process.env.GH_TOKEN;
|
|
32
|
+
// Try to get token from gh CLI
|
|
33
|
+
try {
|
|
34
|
+
return execSync('gh auth token', { stdio: 'pipe', timeout: 5000 }).toString().trim();
|
|
35
|
+
} catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const GITHUB_TOKEN = getGitHubToken();
|
|
41
|
+
|
|
42
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
43
|
+
// PLATFORM DETECTION
|
|
44
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
45
|
+
|
|
46
|
+
function getPlatformInfo() {
|
|
47
|
+
const platform = os.platform();
|
|
48
|
+
const arch = os.arch();
|
|
49
|
+
|
|
50
|
+
const map = {
|
|
51
|
+
'darwin-arm64': { binary: 'synapse-cli-darwin-arm64', installDir: path.join(os.homedir(), '.local', 'bin') },
|
|
52
|
+
'darwin-x64': { binary: 'synapse-cli-darwin-x64', installDir: path.join(os.homedir(), '.local', 'bin') },
|
|
53
|
+
'linux-x64': { binary: 'synapse-cli-linux-x64', installDir: path.join(os.homedir(), '.local', 'bin') },
|
|
54
|
+
'win32-x64': { binary: 'synapse-cli-windows-x64.exe', installDir: path.join(process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local'), 'synapse-cli') },
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const key = `${platform}-${arch}`;
|
|
58
|
+
const info = map[key];
|
|
59
|
+
|
|
60
|
+
if (!info) {
|
|
61
|
+
console.error(`\n Plataforma nao suportada: ${platform}-${arch}`);
|
|
62
|
+
console.error(` Plataformas suportadas: ${Object.keys(map).join(', ')}`);
|
|
63
|
+
console.error(`\n Build from source: bun install && bun run compile\n`);
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return info;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
71
|
+
// HTTP HELPERS
|
|
72
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
73
|
+
|
|
74
|
+
function fetch(url, options = {}) {
|
|
75
|
+
return new Promise((resolve, reject) => {
|
|
76
|
+
const protocol = url.startsWith('https') ? https : http;
|
|
77
|
+
const headers = {
|
|
78
|
+
'User-Agent': `synapse-cli/${VERSION}`,
|
|
79
|
+
'Accept': options.accept || 'application/json',
|
|
80
|
+
...options.headers,
|
|
81
|
+
};
|
|
82
|
+
// Add auth token for GitHub API requests (required for private repos)
|
|
83
|
+
if (GITHUB_TOKEN && url.includes('github.com')) {
|
|
84
|
+
headers['Authorization'] = `Bearer ${GITHUB_TOKEN}`;
|
|
85
|
+
}
|
|
86
|
+
const req = protocol.get(url, { headers }, (res) => {
|
|
87
|
+
// Follow redirects
|
|
88
|
+
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
89
|
+
return fetch(res.headers.location, options).then(resolve).catch(reject);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (res.statusCode !== 200) {
|
|
93
|
+
reject(new Error(`HTTP ${res.statusCode}: ${url}`));
|
|
94
|
+
res.resume();
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (options.stream) {
|
|
99
|
+
resolve(res);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const chunks = [];
|
|
104
|
+
res.on('data', (chunk) => chunks.push(chunk));
|
|
105
|
+
res.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')));
|
|
106
|
+
res.on('error', reject);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
req.on('error', reject);
|
|
110
|
+
req.setTimeout(30000, () => {
|
|
111
|
+
req.destroy();
|
|
112
|
+
reject(new Error(`Timeout: ${url}`));
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
118
|
+
// DOWNLOAD & INSTALL
|
|
119
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
120
|
+
|
|
121
|
+
async function downloadBinary(url, destPath) {
|
|
122
|
+
const res = await fetch(url, { accept: 'application/octet-stream', stream: true });
|
|
123
|
+
const totalSize = parseInt(res.headers['content-length'] || '0', 10);
|
|
124
|
+
|
|
125
|
+
return new Promise((resolve, reject) => {
|
|
126
|
+
const file = fs.createWriteStream(destPath);
|
|
127
|
+
let downloaded = 0;
|
|
128
|
+
let lastPercent = -1;
|
|
129
|
+
|
|
130
|
+
res.on('data', (chunk) => {
|
|
131
|
+
downloaded += chunk.length;
|
|
132
|
+
if (totalSize > 0) {
|
|
133
|
+
const percent = Math.floor((downloaded / totalSize) * 100);
|
|
134
|
+
if (percent !== lastPercent && percent % 10 === 0) {
|
|
135
|
+
process.stdout.write(`\r Downloading... ${percent}%`);
|
|
136
|
+
lastPercent = percent;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
res.pipe(file);
|
|
142
|
+
file.on('finish', () => {
|
|
143
|
+
process.stdout.write('\r Downloading... 100%\n');
|
|
144
|
+
file.close(resolve);
|
|
145
|
+
});
|
|
146
|
+
file.on('error', reject);
|
|
147
|
+
res.on('error', reject);
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async function getChecksums(release) {
|
|
152
|
+
const checksumAsset = release.assets.find(a => a.name === 'SHA256SUMS.txt');
|
|
153
|
+
if (!checksumAsset) return {};
|
|
154
|
+
|
|
155
|
+
const checksumUrl = GITHUB_TOKEN ? checksumAsset.url : checksumAsset.browser_download_url;
|
|
156
|
+
const content = await fetch(checksumUrl, { accept: 'application/octet-stream' });
|
|
157
|
+
const checksums = {};
|
|
158
|
+
for (const line of content.split('\n')) {
|
|
159
|
+
const parts = line.trim().split(/\s+/);
|
|
160
|
+
if (parts.length === 2) {
|
|
161
|
+
checksums[parts[1]] = parts[0];
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return checksums;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function verifySha256(filePath, expectedHash) {
|
|
168
|
+
const fileBuffer = fs.readFileSync(filePath);
|
|
169
|
+
const hash = crypto.createHash('sha256').update(fileBuffer).digest('hex');
|
|
170
|
+
return hash === expectedHash;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function isInPath(dir) {
|
|
174
|
+
const pathDirs = (process.env.PATH || '').split(path.delimiter);
|
|
175
|
+
return pathDirs.some(d => {
|
|
176
|
+
try {
|
|
177
|
+
return fs.realpathSync(d) === fs.realpathSync(dir);
|
|
178
|
+
} catch {
|
|
179
|
+
return d === dir;
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
async function install() {
|
|
185
|
+
const { binary, installDir } = getPlatformInfo();
|
|
186
|
+
|
|
187
|
+
console.log(`\n Synapse CLI v${VERSION}`);
|
|
188
|
+
console.log(` Binary: ${binary}`);
|
|
189
|
+
console.log(` Install: ${installDir}`);
|
|
190
|
+
console.log(` Auth: ${GITHUB_TOKEN ? 'token detected' : 'none (public repos only)'}\n`);
|
|
191
|
+
|
|
192
|
+
// Fetch release info
|
|
193
|
+
process.stdout.write(' Fetching release info...');
|
|
194
|
+
let release;
|
|
195
|
+
try {
|
|
196
|
+
const data = await fetch(RELEASE_URL);
|
|
197
|
+
release = JSON.parse(data);
|
|
198
|
+
} catch {
|
|
199
|
+
// Fallback to latest release
|
|
200
|
+
try {
|
|
201
|
+
const data = await fetch(LATEST_RELEASE_URL);
|
|
202
|
+
release = JSON.parse(data);
|
|
203
|
+
} catch (err) {
|
|
204
|
+
console.error(`\n\n Falha ao buscar release: ${err.message}`);
|
|
205
|
+
if (!GITHUB_TOKEN) {
|
|
206
|
+
console.error('\n O repositorio requer autenticacao. Configure um token:');
|
|
207
|
+
console.error(' export GITHUB_TOKEN=<seu-token>');
|
|
208
|
+
console.error(' # ou autentique com: gh auth login');
|
|
209
|
+
}
|
|
210
|
+
console.error(`\n Baixe manualmente: https://github.com/${REPO}/releases\n`);
|
|
211
|
+
process.exit(1);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
console.log(' OK');
|
|
215
|
+
|
|
216
|
+
// Find binary asset
|
|
217
|
+
const asset = release.assets.find(a => a.name === binary);
|
|
218
|
+
if (!asset) {
|
|
219
|
+
console.error(`\n Binario nao encontrado na release: ${binary}`);
|
|
220
|
+
console.error(` Assets disponiveis: ${release.assets.map(a => a.name).join(', ')}`);
|
|
221
|
+
console.error(`\n Baixe manualmente: https://github.com/${REPO}/releases\n`);
|
|
222
|
+
process.exit(1);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Create install directory
|
|
226
|
+
fs.mkdirSync(installDir, { recursive: true });
|
|
227
|
+
const destPath = path.join(installDir, os.platform() === 'win32' ? 'synapse-cli.exe' : 'synapse-cli');
|
|
228
|
+
const tmpPath = destPath + '.tmp';
|
|
229
|
+
|
|
230
|
+
// Download — use API URL for private repos (browser_download_url requires browser auth)
|
|
231
|
+
const downloadUrl = GITHUB_TOKEN
|
|
232
|
+
? asset.url // API URL: api.github.com/repos/.../releases/assets/{id}
|
|
233
|
+
: asset.browser_download_url;
|
|
234
|
+
await downloadBinary(downloadUrl, tmpPath);
|
|
235
|
+
|
|
236
|
+
// Verify checksum
|
|
237
|
+
process.stdout.write(' Verifying SHA256 checksum...');
|
|
238
|
+
const checksums = await getChecksums(release);
|
|
239
|
+
const expectedHash = checksums[binary];
|
|
240
|
+
if (expectedHash) {
|
|
241
|
+
if (verifySha256(tmpPath, expectedHash)) {
|
|
242
|
+
console.log(' OK');
|
|
243
|
+
} else {
|
|
244
|
+
console.log(' FAILED');
|
|
245
|
+
fs.unlinkSync(tmpPath);
|
|
246
|
+
console.error('\n ERRO: Checksum invalido! O download pode estar corrompido.');
|
|
247
|
+
console.error(` Baixe manualmente: https://github.com/${REPO}/releases\n`);
|
|
248
|
+
process.exit(1);
|
|
249
|
+
}
|
|
250
|
+
} else {
|
|
251
|
+
console.log(' (no checksum available, skipped)');
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Atomic move
|
|
255
|
+
if (fs.existsSync(destPath)) {
|
|
256
|
+
fs.unlinkSync(destPath);
|
|
257
|
+
}
|
|
258
|
+
fs.renameSync(tmpPath, destPath);
|
|
259
|
+
|
|
260
|
+
// Set executable permission on Unix
|
|
261
|
+
if (os.platform() !== 'win32') {
|
|
262
|
+
fs.chmodSync(destPath, 0o755);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
console.log(`\n Instalado: ${destPath}`);
|
|
266
|
+
|
|
267
|
+
// Check if install dir is in PATH
|
|
268
|
+
if (!isInPath(installDir)) {
|
|
269
|
+
console.log(`\n Adicione ao PATH:`);
|
|
270
|
+
if (os.platform() === 'win32') {
|
|
271
|
+
console.log(` setx PATH "%PATH%;${installDir}"`);
|
|
272
|
+
} else {
|
|
273
|
+
const shell = process.env.SHELL || '/bin/bash';
|
|
274
|
+
const rcFile = shell.includes('zsh') ? '~/.zshrc' : '~/.bashrc';
|
|
275
|
+
console.log(` echo 'export PATH="${installDir}:$PATH"' >> ${rcFile}`);
|
|
276
|
+
console.log(` source ${rcFile}`);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
console.log(`\n Execute: synapse-cli --help\n`);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
284
|
+
// HELP & VERSION
|
|
285
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
286
|
+
|
|
287
|
+
function showVersion() {
|
|
288
|
+
console.log(`@ornexus/synapse-cli v${VERSION}`);
|
|
289
|
+
process.exit(0);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
function showHelp() {
|
|
293
|
+
console.log('');
|
|
294
|
+
console.log(` Synapse CLI Installer v${VERSION}`);
|
|
295
|
+
console.log(' Downloads and installs the native binary from GitHub Releases.');
|
|
296
|
+
console.log('');
|
|
297
|
+
console.log(' Usage: npx @ornexus/synapse-cli [options]');
|
|
298
|
+
console.log('');
|
|
299
|
+
console.log(' Options:');
|
|
300
|
+
console.log(' -v, --version Show version');
|
|
301
|
+
console.log(' -h, --help Show this help');
|
|
302
|
+
console.log('');
|
|
303
|
+
console.log(' Auth (for private repos):');
|
|
304
|
+
console.log(' export GITHUB_TOKEN=<token> # or GH_TOKEN');
|
|
305
|
+
console.log(' gh auth login # or use gh CLI');
|
|
306
|
+
console.log('');
|
|
307
|
+
console.log(' The binary is self-contained with encrypted assets.');
|
|
308
|
+
console.log(` Manual download: https://github.com/${REPO}/releases`);
|
|
309
|
+
console.log('');
|
|
310
|
+
process.exit(0);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
314
|
+
// MAIN
|
|
315
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
316
|
+
|
|
317
|
+
if (args.includes('-v') || args.includes('--version')) showVersion();
|
|
318
|
+
if (args.includes('-h') || args.includes('--help')) showHelp();
|
|
319
|
+
|
|
320
|
+
install().catch(err => {
|
|
321
|
+
console.error(`\n Erro: ${err.message}\n`);
|
|
322
|
+
process.exit(1);
|
|
323
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ornexus/synapse-cli",
|
|
3
|
+
"version": "4.2.0",
|
|
4
|
+
"description": "Synapse CLI - AI Agent Orchestrator for multi-platform development (Claude Code, Cursor, VS Code, Gemini, Codex)",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"claude",
|
|
7
|
+
"claude-code",
|
|
8
|
+
"agent",
|
|
9
|
+
"orchestrator",
|
|
10
|
+
"development-workflow",
|
|
11
|
+
"epic",
|
|
12
|
+
"story",
|
|
13
|
+
"automation",
|
|
14
|
+
"ai-agent",
|
|
15
|
+
"llm",
|
|
16
|
+
"devops",
|
|
17
|
+
"ci-cd",
|
|
18
|
+
"git-workflow",
|
|
19
|
+
"pull-request",
|
|
20
|
+
"code-review"
|
|
21
|
+
],
|
|
22
|
+
"author": {
|
|
23
|
+
"name": "OrNexus Team",
|
|
24
|
+
"url": "https://github.com/ornexus-ai"
|
|
25
|
+
},
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"workspaces": [
|
|
28
|
+
"packages/shared",
|
|
29
|
+
"packages/core",
|
|
30
|
+
"packages/cli"
|
|
31
|
+
],
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "https://github.com/OrNexus-AI/synapse-cli.git"
|
|
35
|
+
},
|
|
36
|
+
"homepage": "https://github.com/OrNexus-AI/synapse-cli#readme",
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://github.com/OrNexus-AI/synapse-cli/issues"
|
|
39
|
+
},
|
|
40
|
+
"bin": {
|
|
41
|
+
"synapse-cli": "install.js"
|
|
42
|
+
},
|
|
43
|
+
"files": [
|
|
44
|
+
"README.md",
|
|
45
|
+
"install.js",
|
|
46
|
+
"sync-version.js",
|
|
47
|
+
".env.example"
|
|
48
|
+
],
|
|
49
|
+
"scripts": {
|
|
50
|
+
"postinstall": "node -e \"console.log('\\nSynapse CLI v'+require('./package.json').version+' instalado!\\n\\nSetup: npx @ornexus/synapse-cli\\nBinarios: https://github.com/OrNexus-AI/synapse-cli/releases\\n')\"",
|
|
51
|
+
"sync": "node sync-version.js",
|
|
52
|
+
"prepublishOnly": "node sync-version.js && node -e \"console.log('Publishing Synapse CLI v'+require('./package.json').version)\"",
|
|
53
|
+
"version": "npm run sync && echo '🔖 Nova versão:' && cat package.json | grep version",
|
|
54
|
+
"test": "vitest run",
|
|
55
|
+
"typecheck": "tsc --noEmit",
|
|
56
|
+
"lint": "bunx biome check packages/",
|
|
57
|
+
"lint:fix": "bunx biome check --fix packages/",
|
|
58
|
+
"bundle:assets": "bun run scripts/bundle-assets.ts",
|
|
59
|
+
"build": "bun run --filter '@synapse-cli/shared' build && bun run --filter '@synapse-cli/core' build && bun run --filter '@synapse-cli/cli' build",
|
|
60
|
+
"compile": "bun run bundle:assets && bun run build && bun run compile:all",
|
|
61
|
+
"compile:all": "bun run compile:linux-x64 && bun run compile:darwin-arm64 && bun run compile:darwin-x64 && bun run compile:windows-x64",
|
|
62
|
+
"compile:linux-x64": "bun build packages/cli/src/index.ts --compile --target=bun-linux-x64 --outfile dist/bin/synapse-cli-linux-x64",
|
|
63
|
+
"compile:darwin-arm64": "bun build packages/cli/src/index.ts --compile --target=bun-darwin-arm64 --outfile dist/bin/synapse-cli-darwin-arm64",
|
|
64
|
+
"compile:darwin-x64": "bun build packages/cli/src/index.ts --compile --target=bun-darwin-x64 --outfile dist/bin/synapse-cli-darwin-x64",
|
|
65
|
+
"compile:windows-x64": "bun build packages/cli/src/index.ts --compile --target=bun-windows-x64 --outfile dist/bin/synapse-cli-windows-x64.exe",
|
|
66
|
+
"build:publish": "bun run scripts/build-publish.ts",
|
|
67
|
+
"check": "bun run lint && bun run typecheck && bun run test"
|
|
68
|
+
},
|
|
69
|
+
"engines": {
|
|
70
|
+
"node": ">=18.0.0"
|
|
71
|
+
},
|
|
72
|
+
"os": [
|
|
73
|
+
"darwin",
|
|
74
|
+
"linux",
|
|
75
|
+
"win32"
|
|
76
|
+
],
|
|
77
|
+
"publishConfig": {
|
|
78
|
+
"access": "public",
|
|
79
|
+
"registry": "https://registry.npmjs.org"
|
|
80
|
+
},
|
|
81
|
+
"funding": {
|
|
82
|
+
"type": "github",
|
|
83
|
+
"url": "https://github.com/sponsors/ornexus"
|
|
84
|
+
},
|
|
85
|
+
"overrides": {
|
|
86
|
+
"signal-exit": "3.0.7",
|
|
87
|
+
"ai": "4.3.19",
|
|
88
|
+
"hono": ">=4.12.2",
|
|
89
|
+
"jsondiffpatch": ">=0.7.2"
|
|
90
|
+
},
|
|
91
|
+
"resolutions": {
|
|
92
|
+
"ai": "4.3.19",
|
|
93
|
+
"hono": ">=4.12.2",
|
|
94
|
+
"jsondiffpatch": ">=0.7.2"
|
|
95
|
+
},
|
|
96
|
+
"dependencies": {
|
|
97
|
+
"@clack/prompts": "^1.0.1",
|
|
98
|
+
"@modelcontextprotocol/sdk": "1.27.1",
|
|
99
|
+
"ai": "4.3.19",
|
|
100
|
+
"execa": "^9.6.1",
|
|
101
|
+
"node-cache": "^5.1.2",
|
|
102
|
+
"picocolors": "^1.1.1",
|
|
103
|
+
"signal-exit": "3.0.7",
|
|
104
|
+
"zod": "^4.3.6"
|
|
105
|
+
},
|
|
106
|
+
"devDependencies": {
|
|
107
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
108
|
+
"react-devtools-core": "7.0.1",
|
|
109
|
+
"vitest": "^3.2.4"
|
|
110
|
+
}
|
|
111
|
+
}
|
package/sync-version.js
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Synapse - Version Sync Script
|
|
4
|
+
*
|
|
5
|
+
* Sincroniza a versão do package.json em todos os arquivos do projeto.
|
|
6
|
+
* Executado automaticamente no prepublishOnly.
|
|
7
|
+
*
|
|
8
|
+
* Uso: node sync-version.js
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const fs = require('fs');
|
|
12
|
+
const path = require('path');
|
|
13
|
+
|
|
14
|
+
// Ler versão do package.json (fonte única de verdade)
|
|
15
|
+
const pkg = require('./package.json');
|
|
16
|
+
const VERSION = pkg.version;
|
|
17
|
+
const VERSION_MAJOR_MINOR = VERSION.split('.').slice(0, 2).join('.');
|
|
18
|
+
|
|
19
|
+
console.log(`\n🔄 Sincronizando versão ${VERSION} em todos os arquivos...\n`);
|
|
20
|
+
|
|
21
|
+
// Definição dos arquivos e padrões a substituir
|
|
22
|
+
const replacements = [
|
|
23
|
+
// Sub-package versions (shared, core, cli)
|
|
24
|
+
{
|
|
25
|
+
file: 'packages/shared/package.json',
|
|
26
|
+
patterns: [
|
|
27
|
+
[/"version": "[\d.]+"/g, `"version": "${VERSION}"`],
|
|
28
|
+
]
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
file: 'packages/core/package.json',
|
|
32
|
+
patterns: [
|
|
33
|
+
[/"version": "[\d.]+"/g, `"version": "${VERSION}"`],
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
file: 'packages/cli/package.json',
|
|
38
|
+
patterns: [
|
|
39
|
+
[/"version": "[\d.]+"/g, `"version": "${VERSION}"`],
|
|
40
|
+
]
|
|
41
|
+
},
|
|
42
|
+
// synapse-cli.md
|
|
43
|
+
{
|
|
44
|
+
file: 'targets/claude-code/synapse-cli.md',
|
|
45
|
+
patterns: [
|
|
46
|
+
[/# Synapse v[\d.]+ -/g, `# Synapse v${VERSION} -`],
|
|
47
|
+
[/SYNAPSE-CLI v[\d.]+ \(state\.json\)/g, `SYNAPSE-CLI v${VERSION} (state.json)`],
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
// synapse-cli.agent.yaml
|
|
51
|
+
{
|
|
52
|
+
file: 'targets/claude-code/synapse-cli.agent.yaml',
|
|
53
|
+
patterns: [
|
|
54
|
+
[/version: '[\d.]+'/g, `version: '${VERSION}'`],
|
|
55
|
+
[/SYNAPSE-CLI v[\d.]+ \(External Claude CLI\)/g, `SYNAPSE-CLI v${VERSION} (External Claude CLI)`],
|
|
56
|
+
]
|
|
57
|
+
},
|
|
58
|
+
// install.sh
|
|
59
|
+
{
|
|
60
|
+
file: 'install.sh',
|
|
61
|
+
patterns: [
|
|
62
|
+
[/VERSION="[\d.]+"/g, `VERSION="${VERSION}"`],
|
|
63
|
+
]
|
|
64
|
+
},
|
|
65
|
+
// install.ps1
|
|
66
|
+
{
|
|
67
|
+
file: 'install.ps1',
|
|
68
|
+
patterns: [
|
|
69
|
+
[/\$VERSION = "[\d.]+"/g, `$VERSION = "${VERSION}"`],
|
|
70
|
+
]
|
|
71
|
+
},
|
|
72
|
+
// core/data/state-template.json
|
|
73
|
+
{
|
|
74
|
+
file: 'core/data/state-template.json',
|
|
75
|
+
patterns: [
|
|
76
|
+
[/"version": "[\d.]+"/g, `"version": "${VERSION}"`],
|
|
77
|
+
[/"synapse_cli_version": "[\d.]+"/g, `"synapse_cli_version": "${VERSION}"`],
|
|
78
|
+
]
|
|
79
|
+
},
|
|
80
|
+
// core/data/step-registry.json
|
|
81
|
+
{
|
|
82
|
+
file: 'core/data/step-registry.json',
|
|
83
|
+
patterns: [
|
|
84
|
+
[/"version": "[\d.]+"/g, `"version": "${VERSION}"`],
|
|
85
|
+
]
|
|
86
|
+
},
|
|
87
|
+
// core/data/state-utils.md
|
|
88
|
+
{
|
|
89
|
+
file: 'core/data/state-utils.md',
|
|
90
|
+
patterns: [
|
|
91
|
+
[/# State Utilities - Synapse v[\d.]+/g, `# State Utilities - Synapse v${VERSION}`],
|
|
92
|
+
]
|
|
93
|
+
},
|
|
94
|
+
// core/data/worktree-sync.md
|
|
95
|
+
{
|
|
96
|
+
file: 'core/data/worktree-sync.md',
|
|
97
|
+
patterns: [
|
|
98
|
+
[/# Worktree Synchronization Utilities - Synapse v[\d.]+/g, `# Worktree Synchronization Utilities - Synapse v${VERSION}`],
|
|
99
|
+
]
|
|
100
|
+
},
|
|
101
|
+
// core/data/worktree-sync-functions.sh
|
|
102
|
+
{
|
|
103
|
+
file: 'core/data/worktree-sync-functions.sh',
|
|
104
|
+
patterns: [
|
|
105
|
+
[/# Synapse - Worktree Sync Functions v[\d.]+/g, `# Synapse - Worktree Sync Functions v${VERSION}`],
|
|
106
|
+
]
|
|
107
|
+
},
|
|
108
|
+
// targets/claude-code/workflow.md
|
|
109
|
+
{
|
|
110
|
+
file: 'targets/claude-code/workflow.md',
|
|
111
|
+
patterns: [
|
|
112
|
+
[/Synapse v[\d.]+/g, `Synapse v${VERSION}`],
|
|
113
|
+
]
|
|
114
|
+
},
|
|
115
|
+
// Platform agent files
|
|
116
|
+
{
|
|
117
|
+
file: 'targets/cursor/agent.md',
|
|
118
|
+
patterns: [
|
|
119
|
+
[/# Synapse v[\d.]+ -/g, `# Synapse v${VERSION} -`],
|
|
120
|
+
]
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
file: 'targets/vscode/agent.md',
|
|
124
|
+
patterns: [
|
|
125
|
+
[/# Synapse v[\d.]+ -/g, `# Synapse v${VERSION} -`],
|
|
126
|
+
]
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
file: 'targets/gemini-cli/agent.md',
|
|
130
|
+
patterns: [
|
|
131
|
+
[/# Synapse v[\d.]+ -/g, `# Synapse v${VERSION} -`],
|
|
132
|
+
]
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
file: 'targets/codex/agents.md',
|
|
136
|
+
patterns: [
|
|
137
|
+
[/# Synapse v[\d.]+ -/g, `# Synapse v${VERSION} -`],
|
|
138
|
+
]
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
file: 'targets/antigravity/gemini.md',
|
|
142
|
+
patterns: [
|
|
143
|
+
[/Synapse v[\d.]+/g, `Synapse v${VERSION}`],
|
|
144
|
+
]
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
file: 'targets/antigravity/skill/SKILL.md',
|
|
148
|
+
patterns: [
|
|
149
|
+
[/Synapse v[\d.]+/g, `Synapse v${VERSION}`],
|
|
150
|
+
]
|
|
151
|
+
},
|
|
152
|
+
];
|
|
153
|
+
|
|
154
|
+
let filesUpdated = 0;
|
|
155
|
+
let totalReplacements = 0;
|
|
156
|
+
|
|
157
|
+
for (const { file, patterns } of replacements) {
|
|
158
|
+
const filePath = path.join(__dirname, file);
|
|
159
|
+
|
|
160
|
+
if (!fs.existsSync(filePath)) {
|
|
161
|
+
console.log(` ⚠️ ${file} não encontrado, pulando...`);
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
let content = fs.readFileSync(filePath, 'utf8');
|
|
166
|
+
let fileReplacements = 0;
|
|
167
|
+
|
|
168
|
+
for (const [pattern, replacement] of patterns) {
|
|
169
|
+
const matches = content.match(pattern);
|
|
170
|
+
if (matches) {
|
|
171
|
+
content = content.replace(pattern, replacement);
|
|
172
|
+
fileReplacements += matches.length;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (fileReplacements > 0) {
|
|
177
|
+
fs.writeFileSync(filePath, content);
|
|
178
|
+
console.log(` ✅ ${file} (${fileReplacements} substituição(ões))`);
|
|
179
|
+
filesUpdated++;
|
|
180
|
+
totalReplacements += fileReplacements;
|
|
181
|
+
} else {
|
|
182
|
+
console.log(` ⏭️ ${file} (já atualizado)`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
console.log(`\n✨ Sincronização completa: ${filesUpdated} arquivo(s), ${totalReplacements} substituição(ões)\n`);
|