@djinnos/djinn 0.1.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/README.md +27 -0
- package/bin/djinn +22 -0
- package/package.json +36 -0
- package/scripts/install.js +158 -0
package/README.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# @djinnos/djinn
|
|
2
|
+
|
|
3
|
+
Agentic coding framework that goes from idea to code using orchestrator personas.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @djinnos/djinn
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or use directly with npx:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx @djinnos/djinn
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
Navigate to your project and run:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
djinn
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## More Information
|
|
26
|
+
|
|
27
|
+
See the [GitHub repository](https://github.com/djinnos/djinn) for full documentation.
|
package/bin/djinn
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { spawn } = require('child_process');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
|
|
7
|
+
const ext = process.platform === 'win32' ? '.exe' : '';
|
|
8
|
+
const binary = path.join(__dirname, `djinn${ext}`);
|
|
9
|
+
|
|
10
|
+
if (!fs.existsSync(binary)) {
|
|
11
|
+
console.error('Error: djinn binary not found. Try reinstalling: npm install -g djinn-cli');
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const child = spawn(binary, process.argv.slice(2), {
|
|
16
|
+
stdio: 'inherit',
|
|
17
|
+
env: process.env
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
child.on('close', (code) => {
|
|
21
|
+
process.exit(code);
|
|
22
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@djinnos/djinn",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Agentic coding framework - from idea to code using orchestrator personas",
|
|
5
|
+
"bin": {
|
|
6
|
+
"djinn": "bin/djinn"
|
|
7
|
+
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"postinstall": "node scripts/install.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"bin",
|
|
13
|
+
"scripts"
|
|
14
|
+
],
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/djinnos/djinn.git"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"ai",
|
|
21
|
+
"coding",
|
|
22
|
+
"assistant",
|
|
23
|
+
"cli",
|
|
24
|
+
"agentic",
|
|
25
|
+
"llm"
|
|
26
|
+
],
|
|
27
|
+
"author": "Djinn",
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"bugs": {
|
|
30
|
+
"url": "https://github.com/djinnos/djinn/issues"
|
|
31
|
+
},
|
|
32
|
+
"homepage": "https://github.com/djinnos/djinn#readme",
|
|
33
|
+
"engines": {
|
|
34
|
+
"node": ">=16.0.0"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const https = require('https');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const { execSync } = require('child_process');
|
|
7
|
+
const zlib = require('zlib');
|
|
8
|
+
const tar = require('tar');
|
|
9
|
+
|
|
10
|
+
const REPO = 'djinnos/djinn';
|
|
11
|
+
const BINARY_NAME = 'djinn';
|
|
12
|
+
|
|
13
|
+
function getPlatform() {
|
|
14
|
+
const platform = process.platform;
|
|
15
|
+
switch (platform) {
|
|
16
|
+
case 'darwin': return 'darwin';
|
|
17
|
+
case 'linux': return 'linux';
|
|
18
|
+
case 'win32': return 'windows';
|
|
19
|
+
default: throw new Error(`Unsupported platform: ${platform}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function getArch() {
|
|
24
|
+
const arch = process.arch;
|
|
25
|
+
switch (arch) {
|
|
26
|
+
case 'x64': return 'amd64';
|
|
27
|
+
case 'arm64': return 'arm64';
|
|
28
|
+
default: throw new Error(`Unsupported architecture: ${arch}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function getLatestVersion() {
|
|
33
|
+
return new Promise((resolve, reject) => {
|
|
34
|
+
const options = {
|
|
35
|
+
hostname: 'api.github.com',
|
|
36
|
+
path: `/repos/${REPO}/releases/latest`,
|
|
37
|
+
headers: { 'User-Agent': 'djinn-npm-installer' }
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
https.get(options, (res) => {
|
|
41
|
+
let data = '';
|
|
42
|
+
res.on('data', chunk => data += chunk);
|
|
43
|
+
res.on('end', () => {
|
|
44
|
+
try {
|
|
45
|
+
const release = JSON.parse(data);
|
|
46
|
+
const version = release.tag_name.replace(/^v/, '');
|
|
47
|
+
resolve(version);
|
|
48
|
+
} catch (e) {
|
|
49
|
+
reject(new Error('Failed to parse release info'));
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}).on('error', reject);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async function downloadFile(url, dest) {
|
|
57
|
+
return new Promise((resolve, reject) => {
|
|
58
|
+
const file = fs.createWriteStream(dest);
|
|
59
|
+
|
|
60
|
+
const request = (url) => {
|
|
61
|
+
https.get(url, { headers: { 'User-Agent': 'djinn-npm-installer' } }, (res) => {
|
|
62
|
+
if (res.statusCode === 302 || res.statusCode === 301) {
|
|
63
|
+
request(res.headers.location);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (res.statusCode !== 200) {
|
|
68
|
+
reject(new Error(`Download failed with status ${res.statusCode}`));
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
res.pipe(file);
|
|
73
|
+
file.on('finish', () => {
|
|
74
|
+
file.close();
|
|
75
|
+
resolve();
|
|
76
|
+
});
|
|
77
|
+
}).on('error', (err) => {
|
|
78
|
+
fs.unlink(dest, () => {});
|
|
79
|
+
reject(err);
|
|
80
|
+
});
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
request(url);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async function extractTarGz(archivePath, destDir) {
|
|
88
|
+
return new Promise((resolve, reject) => {
|
|
89
|
+
fs.createReadStream(archivePath)
|
|
90
|
+
.pipe(zlib.createGunzip())
|
|
91
|
+
.pipe(tar.extract({ cwd: destDir }))
|
|
92
|
+
.on('finish', resolve)
|
|
93
|
+
.on('error', reject);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async function extractZip(archivePath, destDir) {
|
|
98
|
+
// For Windows, use PowerShell to extract
|
|
99
|
+
try {
|
|
100
|
+
execSync(`powershell -command "Expand-Archive -Path '${archivePath}' -DestinationPath '${destDir}' -Force"`, {
|
|
101
|
+
stdio: 'pipe'
|
|
102
|
+
});
|
|
103
|
+
} catch (e) {
|
|
104
|
+
throw new Error('Failed to extract zip archive');
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async function main() {
|
|
109
|
+
try {
|
|
110
|
+
const platform = getPlatform();
|
|
111
|
+
const arch = getArch();
|
|
112
|
+
|
|
113
|
+
console.log(`Detected platform: ${platform}/${arch}`);
|
|
114
|
+
|
|
115
|
+
const version = await getLatestVersion();
|
|
116
|
+
console.log(`Installing djinn v${version}...`);
|
|
117
|
+
|
|
118
|
+
const ext = platform === 'windows' ? 'zip' : 'tar.gz';
|
|
119
|
+
const archiveName = `${BINARY_NAME}_${version}_${platform}_${arch}.${ext}`;
|
|
120
|
+
const downloadUrl = `https://github.com/${REPO}/releases/download/v${version}/${archiveName}`;
|
|
121
|
+
|
|
122
|
+
const binDir = path.join(__dirname, '..', 'bin');
|
|
123
|
+
const tmpDir = path.join(__dirname, '..', '.tmp');
|
|
124
|
+
const archivePath = path.join(tmpDir, archiveName);
|
|
125
|
+
|
|
126
|
+
// Create directories
|
|
127
|
+
fs.mkdirSync(binDir, { recursive: true });
|
|
128
|
+
fs.mkdirSync(tmpDir, { recursive: true });
|
|
129
|
+
|
|
130
|
+
console.log(`Downloading from ${downloadUrl}...`);
|
|
131
|
+
await downloadFile(downloadUrl, archivePath);
|
|
132
|
+
|
|
133
|
+
console.log('Extracting...');
|
|
134
|
+
if (ext === 'zip') {
|
|
135
|
+
await extractZip(archivePath, tmpDir);
|
|
136
|
+
} else {
|
|
137
|
+
await extractTarGz(archivePath, tmpDir);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Move binary to bin directory
|
|
141
|
+
const binaryExt = platform === 'windows' ? '.exe' : '';
|
|
142
|
+
const srcBinary = path.join(tmpDir, `${BINARY_NAME}${binaryExt}`);
|
|
143
|
+
const destBinary = path.join(binDir, `${BINARY_NAME}${binaryExt}`);
|
|
144
|
+
|
|
145
|
+
fs.copyFileSync(srcBinary, destBinary);
|
|
146
|
+
fs.chmodSync(destBinary, 0o755);
|
|
147
|
+
|
|
148
|
+
// Cleanup
|
|
149
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
150
|
+
|
|
151
|
+
console.log(`Successfully installed djinn v${version}`);
|
|
152
|
+
} catch (error) {
|
|
153
|
+
console.error('Installation failed:', error.message);
|
|
154
|
+
process.exit(1);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
main();
|