@kandiforge/spectacle 0.2.1

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/bin/kandi-gpt ADDED
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { spawn } = require('child_process');
4
+ const path = require('path');
5
+
6
+ // Determine binary name based on platform
7
+ const binaryName = process.platform === 'win32' ? 'kandi-gpt-bin.exe' : 'kandi-gpt-bin';
8
+ const binaryPath = path.join(__dirname, binaryName);
9
+
10
+ // Spawn the binary with all arguments
11
+ const child = spawn(binaryPath, process.argv.slice(2), {
12
+ stdio: 'inherit',
13
+ env: process.env
14
+ });
15
+
16
+ // Forward exit code
17
+ child.on('exit', (code) => {
18
+ process.exit(code || 0);
19
+ });
20
+
21
+ // Handle errors
22
+ child.on('error', (err) => {
23
+ console.error('Failed to start kandi-gpt binary:', err.message);
24
+ process.exit(1);
25
+ });
package/bin/kandi-plan ADDED
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { spawn } = require('child_process');
4
+ const path = require('path');
5
+
6
+ // Determine binary name based on platform
7
+ const binaryName = process.platform === 'win32' ? 'kandi-plan-bin.exe' : 'kandi-plan-bin';
8
+ const binaryPath = path.join(__dirname, binaryName);
9
+
10
+ // Spawn the binary with all arguments
11
+ const child = spawn(binaryPath, process.argv.slice(2), {
12
+ stdio: 'inherit',
13
+ env: process.env
14
+ });
15
+
16
+ // Forward exit code
17
+ child.on('exit', (code) => {
18
+ process.exit(code || 0);
19
+ });
20
+
21
+ // Handle errors
22
+ child.on('error', (err) => {
23
+ console.error('Failed to start kandi-plan binary:', err.message);
24
+ process.exit(1);
25
+ });
package/bin/spectacle ADDED
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { spawn } = require('child_process');
4
+ const path = require('path');
5
+
6
+ // Determine binary name based on platform
7
+ const binaryName = process.platform === 'win32' ? 'spectacle-bin.exe' : 'spectacle-bin';
8
+ const binaryPath = path.join(__dirname, binaryName);
9
+
10
+ // Spawn the binary with all arguments
11
+ const child = spawn(binaryPath, process.argv.slice(2), {
12
+ stdio: 'inherit',
13
+ env: process.env
14
+ });
15
+
16
+ // Forward exit code
17
+ child.on('exit', (code) => {
18
+ process.exit(code || 0);
19
+ });
20
+
21
+ // Handle errors
22
+ child.on('error', (err) => {
23
+ console.error('Failed to start spectacle binary:', err.message);
24
+ process.exit(1);
25
+ });
Binary file
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@kandiforge/spectacle",
3
+ "version": "0.2.1",
4
+ "description": "Spectacle server and CLI tools for KandiForge ecosystem",
5
+ "author": "Abstract Class Consulting Inc.",
6
+ "license": "PROPRIETARY",
7
+ "homepage": "https://github.com/KandiForge/apps",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/KandiForge/apps.git",
11
+ "directory": "spectacle"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/KandiForge/apps/issues"
15
+ },
16
+ "keywords": [
17
+ "spectacle",
18
+ "server",
19
+ "cli",
20
+ "kandiforge",
21
+ "development"
22
+ ],
23
+ "bin": {
24
+ "spectacle": "./bin/spectacle",
25
+ "kandi-plan": "./bin/kandi-plan",
26
+ "kandi-gpt": "./bin/kandi-gpt"
27
+ },
28
+ "scripts": {
29
+ "postinstall": "node scripts/install.js",
30
+ "test": "echo \"No tests configured\""
31
+ },
32
+ "files": [
33
+ "bin/",
34
+ "scripts/",
35
+ "README.md",
36
+ "LICENSE"
37
+ ],
38
+ "engines": {
39
+ "node": ">=14.0.0"
40
+ }
41
+ }
@@ -0,0 +1,147 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const https = require('https');
6
+ const { execSync } = require('child_process');
7
+
8
+ // This version MUST match package.json
9
+ const RELEASE_VERSION = '0.2.1';
10
+ const GITHUB_REPO = 'KandiForge/distribution';
11
+
12
+ function downloadFile(url, destPath) {
13
+ return new Promise((resolve, reject) => {
14
+ console.log(`Downloading from: ${url}`);
15
+
16
+ https.get(url, (response) => {
17
+ if (response.statusCode === 302 || response.statusCode === 301) {
18
+ // Follow redirect
19
+ return downloadFile(response.headers.location, destPath)
20
+ .then(resolve)
21
+ .catch(reject);
22
+ }
23
+
24
+ if (response.statusCode !== 200) {
25
+ reject(new Error(`Failed to download: ${response.statusCode} ${response.statusMessage}`));
26
+ return;
27
+ }
28
+
29
+ const file = fs.createWriteStream(destPath);
30
+ response.pipe(file);
31
+
32
+ file.on('finish', () => {
33
+ file.close();
34
+ resolve();
35
+ });
36
+
37
+ file.on('error', (err) => {
38
+ fs.unlink(destPath, () => {});
39
+ reject(err);
40
+ });
41
+ }).on('error', reject);
42
+ });
43
+ }
44
+
45
+ async function install() {
46
+ try {
47
+ const platform = process.platform;
48
+ const arch = process.arch;
49
+
50
+ // Determine file name based on platform
51
+ let fileName, extractCmd;
52
+ const binaries = platform === 'win32'
53
+ ? ['spectacle.exe', 'kandi-plan.exe', 'kandi-gpt.exe']
54
+ : ['spectacle', 'kandi-plan', 'kandi-gpt'];
55
+
56
+ if (platform === 'darwin') {
57
+ fileName = `spectacle-v${RELEASE_VERSION}-macos-universal.tar.gz`;
58
+ extractCmd = `tar -xzf`;
59
+ } else if (platform === 'linux') {
60
+ fileName = `spectacle-v${RELEASE_VERSION}-linux-x64.tar.gz`;
61
+ extractCmd = `tar -xzf`;
62
+ } else if (platform === 'win32') {
63
+ fileName = `spectacle-v${RELEASE_VERSION}-windows-x64.zip`;
64
+ extractCmd = `unzip -o`;
65
+ } else {
66
+ throw new Error(`Platform ${platform} is not supported. Supported: macOS, Linux, Windows`);
67
+ }
68
+
69
+ // Download URL from GitHub release assets (public even for private repos)
70
+ const downloadUrl = `https://github.com/${GITHUB_REPO}/releases/download/spectacle-v${RELEASE_VERSION}/${fileName}`;
71
+
72
+ const binDir = path.join(__dirname, '..', 'bin');
73
+ const tempFile = path.join(binDir, fileName);
74
+
75
+ // Create bin directory if it doesn't exist
76
+ if (!fs.existsSync(binDir)) {
77
+ fs.mkdirSync(binDir, { recursive: true });
78
+ }
79
+
80
+ // Download the release archive
81
+ console.log(`Installing Spectacle v${RELEASE_VERSION} for ${platform} ${arch}...`);
82
+ await downloadFile(downloadUrl, tempFile);
83
+
84
+ // Extract the binary
85
+ console.log('Extracting binary...');
86
+ // Use appropriate flag based on archive type: -C for tar, -d for unzip
87
+ const destFlag = platform === 'win32' ? '-d' : '-C';
88
+ execSync(`${extractCmd} "${tempFile}" ${destFlag} "${binDir}"`, { stdio: 'inherit' });
89
+
90
+ // Clean up archive
91
+ fs.unlinkSync(tempFile);
92
+
93
+ // The archive extracts to spectacle-v{version}/[spectacle, kandi-plan, kandi-gpt][.exe]
94
+ const extractedDir = path.join(binDir, `spectacle-v${RELEASE_VERSION}`);
95
+
96
+ // Move all binaries to the correct location
97
+ const installedBinaries = [];
98
+ for (const binaryName of binaries) {
99
+ const extractedPath = path.join(extractedDir, binaryName);
100
+
101
+ // Determine destination name: spectacle -> spectacle-bin, kandi-plan -> kandi-plan-bin, kandi-gpt -> kandi-gpt-bin
102
+ const baseName = binaryName.replace('.exe', '');
103
+ const destName = `${baseName}-bin${platform === 'win32' ? '.exe' : ''}`;
104
+ const binaryPath = path.join(binDir, destName);
105
+
106
+ if (fs.existsSync(extractedPath)) {
107
+ fs.renameSync(extractedPath, binaryPath);
108
+
109
+ // Make binary executable (Unix only)
110
+ if (platform !== 'win32') {
111
+ fs.chmodSync(binaryPath, 0o755);
112
+ }
113
+
114
+ installedBinaries.push({ name: baseName, path: binaryPath });
115
+ } else {
116
+ console.warn(`⚠️ Warning: ${binaryName} not found in archive at ${extractedPath}`);
117
+ }
118
+ }
119
+
120
+ // Clean up the extracted directory
121
+ if (fs.existsSync(extractedDir)) {
122
+ fs.rmdirSync(extractedDir, { recursive: true });
123
+ }
124
+
125
+ if (installedBinaries.length === 0) {
126
+ throw new Error('No binaries were found in the archive');
127
+ }
128
+
129
+ console.log('✅ Spectacle installed successfully!');
130
+ console.log('\nInstalled binaries:');
131
+ for (const binary of installedBinaries) {
132
+ console.log(` - ${binary.name}: ${binary.path}`);
133
+ }
134
+ console.log('\nTo get started, run:');
135
+ console.log(' spectacle --help');
136
+ console.log(' kandi-plan --help');
137
+ console.log(' kandi-gpt --help');
138
+
139
+ } catch (error) {
140
+ console.error('❌ Installation failed:', error.message);
141
+ console.error('\nPlease report this issue at: https://github.com/KandiForge/apps/issues');
142
+ process.exit(1);
143
+ }
144
+ }
145
+
146
+ // Run installation
147
+ install();