hablas 2.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/CHANGELOG.md +108 -0
- package/CREDITS.md +33 -0
- package/LICENSE +21 -0
- package/README.md +317 -0
- package/bin/hablas-shim.js +47 -0
- package/dist/index.js +1132 -0
- package/package.json +83 -0
- package/postinstall.js +137 -0
package/package.json
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "hablas",
|
|
3
|
+
"version": "2.0.5",
|
|
4
|
+
"description": "Premium multi-agent AI coding agent for your terminal ā local-first via Ollama, NVIDIA NIM, or any OpenAI-compatible API. Watch the team work in front of you.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"hablas": "./bin/hablas-shim.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin",
|
|
11
|
+
"dist/index.js",
|
|
12
|
+
"dist/binaries/checksums.json",
|
|
13
|
+
"postinstall.js",
|
|
14
|
+
"README.md",
|
|
15
|
+
"LICENSE",
|
|
16
|
+
"CREDITS.md",
|
|
17
|
+
"CHANGELOG.md"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "npx esbuild src/index.ts --bundle --platform=node --target=node20 --format=cjs --minify --outfile=dist/index.js",
|
|
21
|
+
"build:binaries": "node scripts/build-binaries.js",
|
|
22
|
+
"prepublishOnly": "npm run build",
|
|
23
|
+
"postinstall": "node postinstall.js",
|
|
24
|
+
"dev": "ts-node src/index.ts",
|
|
25
|
+
"start": "node dist/index.js",
|
|
26
|
+
"lint": "tsc --noEmit",
|
|
27
|
+
"test": "npm run test:channel && npm run test:orchestrator && npm run test:planner && npm run test:parity",
|
|
28
|
+
"test:channel": "ts-node --transpile-only src/agents/__tests__/agent-channel.test.ts",
|
|
29
|
+
"test:orchestrator": "ts-node --transpile-only src/agents/__tests__/orchestrator.test.ts",
|
|
30
|
+
"test:planner": "ts-node --transpile-only src/agents/__tests__/planner.test.ts",
|
|
31
|
+
"test:parity": "ts-node --transpile-only src/agents/__tests__/parity.test.ts"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"cli",
|
|
35
|
+
"agent",
|
|
36
|
+
"ollama",
|
|
37
|
+
"ai",
|
|
38
|
+
"local",
|
|
39
|
+
"streaming",
|
|
40
|
+
"typescript",
|
|
41
|
+
"hablas",
|
|
42
|
+
"coding-assistant",
|
|
43
|
+
"openai",
|
|
44
|
+
"terminal",
|
|
45
|
+
"developer-tools",
|
|
46
|
+
"code-generation",
|
|
47
|
+
"llm"
|
|
48
|
+
],
|
|
49
|
+
"author": {
|
|
50
|
+
"name": "Abdulmoin Hablas",
|
|
51
|
+
"url": "https://portfolio-monopoly63s-projects.vercel.app/"
|
|
52
|
+
},
|
|
53
|
+
"homepage": "https://portfolio-monopoly63s-projects.vercel.app/",
|
|
54
|
+
"repository": {
|
|
55
|
+
"type": "git",
|
|
56
|
+
"url": "git+https://github.com/Monopoly63/mobile-bot.git"
|
|
57
|
+
},
|
|
58
|
+
"bugs": {
|
|
59
|
+
"url": "https://github.com/Monopoly63/mobile-bot/issues"
|
|
60
|
+
},
|
|
61
|
+
"license": "MIT",
|
|
62
|
+
"engines": {
|
|
63
|
+
"node": ">=20.0.0"
|
|
64
|
+
},
|
|
65
|
+
"dependencies": {
|
|
66
|
+
"chalk": "^5.3.0",
|
|
67
|
+
"chokidar": "^3.6.0",
|
|
68
|
+
"commander": "^12.1.0",
|
|
69
|
+
"diff": "^5.2.0",
|
|
70
|
+
"ora": "^8.0.1"
|
|
71
|
+
},
|
|
72
|
+
"devDependencies": {
|
|
73
|
+
"@types/diff": "^5.2.3",
|
|
74
|
+
"@types/node": "^20.19.41",
|
|
75
|
+
"@types/pino": "^7.0.4",
|
|
76
|
+
"esbuild": "^0.25.0",
|
|
77
|
+
"pino": "^10.3.1",
|
|
78
|
+
"pino-pretty": "^13.1.3",
|
|
79
|
+
"postject": "^1.0.0-alpha.6",
|
|
80
|
+
"ts-node": "^10.9.2",
|
|
81
|
+
"typescript": "5.5"
|
|
82
|
+
}
|
|
83
|
+
}
|
package/postinstall.js
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const https = require('https');
|
|
4
|
+
const crypto = require('crypto');
|
|
5
|
+
const { execSync } = require('child_process');
|
|
6
|
+
|
|
7
|
+
const pkg = require('./package.json');
|
|
8
|
+
const VERSION = pkg.version;
|
|
9
|
+
const REPO = 'Monopoly63/mobile-bot';
|
|
10
|
+
|
|
11
|
+
const BIN_DIR = path.resolve(__dirname, 'bin');
|
|
12
|
+
const CHECKSUM_FILE = path.resolve(__dirname, 'dist', 'binaries', 'checksums.json');
|
|
13
|
+
|
|
14
|
+
// Map Node.js platform/arch to expected release binary filenames
|
|
15
|
+
const PLATFORM_MAP = {
|
|
16
|
+
win32: {
|
|
17
|
+
x64: { filename: 'hablas-win-x64.exe', target: 'win-x64' }
|
|
18
|
+
},
|
|
19
|
+
linux: {
|
|
20
|
+
x64: { filename: 'hablas-linux-x64', target: 'linux-x64' }
|
|
21
|
+
},
|
|
22
|
+
darwin: {
|
|
23
|
+
x64: { filename: 'hablas-macos-x64', target: 'macos-x64' }
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
function getBinaryConfig() {
|
|
28
|
+
const osConfig = PLATFORM_MAP[process.platform];
|
|
29
|
+
if (!osConfig) return null;
|
|
30
|
+
return osConfig[process.arch] || null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function computeFileSha256(filePath) {
|
|
34
|
+
const fileBuffer = fs.readFileSync(filePath);
|
|
35
|
+
const hashSum = crypto.createHash('sha256');
|
|
36
|
+
hashSum.update(fileBuffer);
|
|
37
|
+
return hashSum.digest('hex');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function ensureDir(dir) {
|
|
41
|
+
if (!fs.existsSync(dir)) {
|
|
42
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function downloadFile(url, dest) {
|
|
47
|
+
return new Promise((resolve, reject) => {
|
|
48
|
+
const file = fs.createWriteStream(dest);
|
|
49
|
+
https.get(url, (response) => {
|
|
50
|
+
// Handle redirects
|
|
51
|
+
if (response.statusCode === 302 || response.statusCode === 301) {
|
|
52
|
+
downloadFile(response.headers.location, dest).then(resolve).catch(reject);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (response.statusCode !== 200) {
|
|
56
|
+
reject(new Error(`HTTP status code ${response.statusCode}`));
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
response.pipe(file);
|
|
60
|
+
file.on('finish', () => {
|
|
61
|
+
file.close(resolve);
|
|
62
|
+
});
|
|
63
|
+
}).on('error', (err) => {
|
|
64
|
+
fs.unlink(dest, () => {});
|
|
65
|
+
reject(err);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async function main() {
|
|
71
|
+
console.log(`\nš¦ Installing Hablas CLI Standalone Binary v${VERSION}...`);
|
|
72
|
+
|
|
73
|
+
const config = getBinaryConfig();
|
|
74
|
+
if (!config) {
|
|
75
|
+
console.log(`ā ļø Unsupported platform/architecture: ${process.platform}-${process.arch}`);
|
|
76
|
+
console.log(`š Hablas CLI will run in Graceful Fallback Mode using the bundled Node.js runtime wrapper.`);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
ensureDir(BIN_DIR);
|
|
81
|
+
const destPath = path.resolve(BIN_DIR, config.filename);
|
|
82
|
+
const downloadUrl = `https://github.com/${REPO}/releases/download/v${VERSION}/${config.filename}`;
|
|
83
|
+
|
|
84
|
+
console.log(`š Downloading native binary for ${process.platform}-${process.arch}...`);
|
|
85
|
+
console.log(` URL: ${downloadUrl}`);
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
await downloadFile(downloadUrl, destPath);
|
|
89
|
+
console.log(`ā Download complete. Verifying checksum...`);
|
|
90
|
+
|
|
91
|
+
// Verify Checksum
|
|
92
|
+
if (!fs.existsSync(CHECKSUM_FILE)) {
|
|
93
|
+
throw new Error('Local checksum database (checksums.json) not found in the package distribution.');
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const checksums = JSON.parse(fs.readFileSync(CHECKSUM_FILE, 'utf-8'));
|
|
97
|
+
const expectedSha = checksums[config.filename];
|
|
98
|
+
if (!expectedSha) {
|
|
99
|
+
throw new Error(`No checksum found for binary: ${config.filename}`);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const actualSha = computeFileSha256(destPath);
|
|
103
|
+
if (actualSha !== expectedSha) {
|
|
104
|
+
throw new Error(`Checksum verification failed!\nExpected: ${expectedSha}\nActual: ${actualSha}`);
|
|
105
|
+
}
|
|
106
|
+
console.log(`ā Checksum verified successfully.`);
|
|
107
|
+
|
|
108
|
+
// Set execution permissions
|
|
109
|
+
fs.chmodSync(destPath, 0o755);
|
|
110
|
+
|
|
111
|
+
// Verify executable version
|
|
112
|
+
console.log(`š Validating binary execution and version compatibility...`);
|
|
113
|
+
let output;
|
|
114
|
+
try {
|
|
115
|
+
output = execSync(`"${destPath}" --version`, { encoding: 'utf-8', timeout: 5000 }).trim();
|
|
116
|
+
} catch (err) {
|
|
117
|
+
throw new Error(`Failed to execute downloaded binary: ${err.message}`);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (!output.includes(VERSION)) {
|
|
121
|
+
throw new Error(`Binary version mismatch! Expected v${VERSION} but got response: "${output}"`);
|
|
122
|
+
}
|
|
123
|
+
console.log(`ā Version validation passed: ${output}`);
|
|
124
|
+
console.log(`š Hablas CLI production binary successfully installed globally!`);
|
|
125
|
+
|
|
126
|
+
} catch (err) {
|
|
127
|
+
console.error(`\nā Error during postinstall binary setup: ${err.message}`);
|
|
128
|
+
console.log(`ā ļø Falling back to pure Node.js bundled runtime wrapper.`);
|
|
129
|
+
|
|
130
|
+
// Clean up corrupted file if any
|
|
131
|
+
if (fs.existsSync(destPath)) {
|
|
132
|
+
fs.unlinkSync(destPath);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
main();
|