@sigmashake/ssg 0.5.1 → 0.6.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/ssg.cjs +25 -10
- package/package.json +9 -3
- package/scripts/postinstall.cjs +0 -150
package/bin/ssg.cjs
CHANGED
|
@@ -1,21 +1,35 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// bin/ssg.
|
|
3
|
-
//
|
|
4
|
-
//
|
|
2
|
+
// bin/ssg.cjs — launcher for @sigmashake/ssg
|
|
3
|
+
// Resolves the native binary from the platform-specific optional dependency,
|
|
4
|
+
// falls back to a local dist/ build (dev environment), then to Bun + source.
|
|
5
5
|
'use strict';
|
|
6
6
|
|
|
7
7
|
const {execFileSync, spawnSync} = require('child_process');
|
|
8
8
|
const path = require('path');
|
|
9
9
|
const fs = require('fs');
|
|
10
10
|
|
|
11
|
-
// Binary naming convention: ssg-{platform}-{arch}[.exe]
|
|
12
|
-
// Matches the build:* scripts in package.json.
|
|
13
11
|
const ext = process.platform === 'win32' ? '.exe' : '';
|
|
14
|
-
const
|
|
15
|
-
|
|
12
|
+
const platformPkg = `@sigmashake/ssg-${process.platform}-${process.arch}`;
|
|
13
|
+
let binaryPath;
|
|
16
14
|
|
|
17
|
-
//
|
|
18
|
-
|
|
15
|
+
// 1. Try platform-specific optional dependency (npm install path)
|
|
16
|
+
try {
|
|
17
|
+
const pkgRoot = path.dirname(require.resolve(`${platformPkg}/package.json`));
|
|
18
|
+
const candidate = path.join(pkgRoot, 'bin', `ssg${ext}`);
|
|
19
|
+
if (fs.existsSync(candidate)) binaryPath = candidate;
|
|
20
|
+
} catch {}
|
|
21
|
+
|
|
22
|
+
// 2. Fall back to local dist/ (dev build / bun build --compile)
|
|
23
|
+
if (!binaryPath) {
|
|
24
|
+
const devBin = path.resolve(
|
|
25
|
+
__dirname, '..', 'dist',
|
|
26
|
+
`ssg-${process.platform}-${process.arch}${ext}`,
|
|
27
|
+
);
|
|
28
|
+
if (fs.existsSync(devBin)) binaryPath = devBin;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// 3. Run binary if found
|
|
32
|
+
if (binaryPath) {
|
|
19
33
|
const result = spawnSync(binaryPath, process.argv.slice(2), {
|
|
20
34
|
stdio: 'inherit',
|
|
21
35
|
env: process.env,
|
|
@@ -23,7 +37,7 @@ if (fs.existsSync(binaryPath)) {
|
|
|
23
37
|
process.exit(result.status ?? 1);
|
|
24
38
|
}
|
|
25
39
|
|
|
26
|
-
//
|
|
40
|
+
// 4. Last resort: run TypeScript source via Bun (unsupported platform / dev)
|
|
27
41
|
const src = path.resolve(__dirname, '..', 'src', 'cli.ts');
|
|
28
42
|
|
|
29
43
|
let bunPath;
|
|
@@ -43,6 +57,7 @@ try {
|
|
|
43
57
|
if (!bunPath) {
|
|
44
58
|
process.stderr.write(
|
|
45
59
|
`ssg: no pre-compiled binary for ${process.platform}-${process.arch}.\n` +
|
|
60
|
+
`Expected platform package: ${platformPkg}\n` +
|
|
46
61
|
'Install Bun to run from source (https://bun.sh):\n\n' +
|
|
47
62
|
' curl -fsSL https://bun.sh/install | bash\n\n',
|
|
48
63
|
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sigmashake/ssg",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "AI Agent Governance CLI — evaluate tool calls against rules, block dangerous operations, and surface blocked commands",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -8,10 +8,16 @@
|
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
10
|
"bin/",
|
|
11
|
-
"scripts/postinstall.cjs",
|
|
12
11
|
"LICENSE",
|
|
13
12
|
"README.md"
|
|
14
13
|
],
|
|
14
|
+
"optionalDependencies": {
|
|
15
|
+
"@sigmashake/ssg-linux-x64": "~0.6.0",
|
|
16
|
+
"@sigmashake/ssg-linux-arm64": "~0.6.0",
|
|
17
|
+
"@sigmashake/ssg-darwin-arm64": "~0.6.0",
|
|
18
|
+
"@sigmashake/ssg-darwin-x64": "~0.6.0",
|
|
19
|
+
"@sigmashake/ssg-win32-x64": "~0.6.0"
|
|
20
|
+
},
|
|
15
21
|
"scripts": {
|
|
16
22
|
"dev": "bun run src/cli.ts",
|
|
17
23
|
"build": "bun build --compile src/cli.ts --outfile ssg",
|
|
@@ -22,7 +28,7 @@
|
|
|
22
28
|
"build:linux-arm64": "bun build --compile --target=bun-linux-arm64 src/cli.ts --outfile dist/ssg-linux-arm64",
|
|
23
29
|
"build:all": "bun run build:linux && bun run build:linux-arm64 && bun run build:macos-arm64 && bun run build:macos-x64 && bun run build:windows",
|
|
24
30
|
"build:protected:all": "bash ../sigmashake-dist/scripts/build-protected.sh",
|
|
25
|
-
"
|
|
31
|
+
"pub:platforms": "bash ../sigmashake-dist/scripts/publish-platforms.sh",
|
|
26
32
|
"prepublishOnly": "bun run build:protected:all",
|
|
27
33
|
"test": "bun test",
|
|
28
34
|
"lint": "bun run src/cli.ts lint",
|
package/scripts/postinstall.cjs
DELETED
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// scripts/postinstall.js — downloads the platform binary from GitHub Releases.
|
|
3
|
-
// Runs automatically after `npm install @sigmashake/ssg`.
|
|
4
|
-
'use strict';
|
|
5
|
-
|
|
6
|
-
const https = require('https');
|
|
7
|
-
const fs = require('fs');
|
|
8
|
-
const path = require('path');
|
|
9
|
-
const zlib = require('zlib');
|
|
10
|
-
|
|
11
|
-
const VERSION = require('../package.json').version;
|
|
12
|
-
const BASE_URL = `https://github.com/sigmashakeinc/ssg/releases/download/v${VERSION}`;
|
|
13
|
-
|
|
14
|
-
const PLATFORM_MAP = {
|
|
15
|
-
'linux-x64': {archive: 'ssg-linux-x64.tar.gz', binary: 'ssg', ext: ''},
|
|
16
|
-
'linux-arm64': {archive: 'ssg-linux-arm64.tar.gz', binary: 'ssg', ext: ''},
|
|
17
|
-
'darwin-arm64': {archive: 'ssg-darwin-arm64.tar.gz', binary: 'ssg', ext: ''},
|
|
18
|
-
'darwin-x64': {archive: 'ssg-darwin-x64.tar.gz', binary: 'ssg', ext: ''},
|
|
19
|
-
'win32-x64': {archive: 'ssg-win32-x64.zip', binary: 'ssg.exe', ext: '.exe'},
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
const platform = process.platform;
|
|
23
|
-
const arch = process.arch;
|
|
24
|
-
const key = `${platform}-${arch}`;
|
|
25
|
-
const info = PLATFORM_MAP[key];
|
|
26
|
-
|
|
27
|
-
if (!info) {
|
|
28
|
-
console.warn(`[ssg] No pre-compiled binary for ${key}. Install Bun to run from source.`);
|
|
29
|
-
process.exit(0);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const distDir = path.resolve(__dirname, '..', 'dist');
|
|
33
|
-
const binaryPath = path.join(distDir, `ssg-${platform}-${arch}${info.ext}`);
|
|
34
|
-
|
|
35
|
-
if (fs.existsSync(binaryPath)) {
|
|
36
|
-
process.exit(0); // Already downloaded
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
fs.mkdirSync(distDir, {recursive: true});
|
|
40
|
-
|
|
41
|
-
const url = `${BASE_URL}/${info.archive}`;
|
|
42
|
-
console.log(`[ssg] Downloading binary for ${key}...`);
|
|
43
|
-
|
|
44
|
-
function followRedirects(url, maxRedirects, cb) {
|
|
45
|
-
if (maxRedirects === 0) return cb(new Error('Too many redirects'));
|
|
46
|
-
const mod = url.startsWith('https:') ? https : require('http');
|
|
47
|
-
mod.get(url, res => {
|
|
48
|
-
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
49
|
-
return followRedirects(res.headers.location, maxRedirects - 1, cb);
|
|
50
|
-
}
|
|
51
|
-
cb(null, res);
|
|
52
|
-
}).on('error', cb);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
followRedirects(url, 10, (err, res) => {
|
|
56
|
-
if (err) {
|
|
57
|
-
console.warn(`[ssg] Download failed: ${err.message}. Install Bun to run from source.`);
|
|
58
|
-
process.exit(0);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (res.statusCode !== 200) {
|
|
62
|
-
console.warn(`[ssg] HTTP ${res.statusCode} downloading binary. Install Bun to run from source.`);
|
|
63
|
-
process.exit(0);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (info.archive.endsWith('.tar.gz')) {
|
|
67
|
-
// tar.gz: decompress with zlib, extract binary with manual tar parsing
|
|
68
|
-
const gunzip = zlib.createGunzip();
|
|
69
|
-
let buffer = Buffer.alloc(0);
|
|
70
|
-
|
|
71
|
-
res.pipe(gunzip);
|
|
72
|
-
gunzip.on('data', chunk => { buffer = Buffer.concat([buffer, chunk]); });
|
|
73
|
-
gunzip.on('end', () => {
|
|
74
|
-
// Minimal tar parser: scan for the binary file entry
|
|
75
|
-
let offset = 0;
|
|
76
|
-
let found = false;
|
|
77
|
-
while (offset + 512 <= buffer.length) {
|
|
78
|
-
const header = buffer.slice(offset, offset + 512);
|
|
79
|
-
const name = header.slice(0, 100).toString('utf8').replace(/\0/g, '');
|
|
80
|
-
const sizeStr = header.slice(124, 136).toString('utf8').replace(/\0/g, '').trim();
|
|
81
|
-
const size = sizeStr ? parseInt(sizeStr, 8) : 0;
|
|
82
|
-
offset += 512;
|
|
83
|
-
if (!name || size === 0) { offset += Math.ceil(size / 512) * 512; continue; }
|
|
84
|
-
const baseName = path.basename(name);
|
|
85
|
-
if (baseName === 'ssg' || baseName === info.binary) {
|
|
86
|
-
const data = buffer.slice(offset, offset + size);
|
|
87
|
-
fs.writeFileSync(binaryPath, data, {mode: 0o755});
|
|
88
|
-
console.log(`[ssg] Installed to ${binaryPath}`);
|
|
89
|
-
found = true;
|
|
90
|
-
break;
|
|
91
|
-
}
|
|
92
|
-
offset += Math.ceil(size / 512) * 512;
|
|
93
|
-
}
|
|
94
|
-
if (!found) {
|
|
95
|
-
console.warn('[ssg] Binary not found in archive. Install Bun to run from source.');
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
gunzip.on('error', e => {
|
|
99
|
-
console.warn(`[ssg] Extract failed: ${e.message}`);
|
|
100
|
-
});
|
|
101
|
-
} else {
|
|
102
|
-
// .zip: use built-in adm-zip fallback or just warn
|
|
103
|
-
const chunks = [];
|
|
104
|
-
res.on('data', c => chunks.push(c));
|
|
105
|
-
res.on('end', () => {
|
|
106
|
-
// Minimal ZIP parser for the binary entry
|
|
107
|
-
const data = Buffer.concat(chunks);
|
|
108
|
-
// Find central directory end record (PK\x05\x06)
|
|
109
|
-
let eocd = -1;
|
|
110
|
-
for (let i = data.length - 22; i >= 0; i--) {
|
|
111
|
-
if (data[i] === 0x50 && data[i+1] === 0x4b && data[i+2] === 0x05 && data[i+3] === 0x06) {
|
|
112
|
-
eocd = i; break;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
if (eocd < 0) { console.warn('[ssg] Invalid ZIP'); process.exit(0); }
|
|
116
|
-
const cdOffset = data.readUInt32LE(eocd + 16);
|
|
117
|
-
const cdCount = data.readUInt16LE(eocd + 10);
|
|
118
|
-
let pos = cdOffset;
|
|
119
|
-
for (let i = 0; i < cdCount; i++) {
|
|
120
|
-
const sig = data.readUInt32LE(pos);
|
|
121
|
-
if (sig !== 0x02014b50) break;
|
|
122
|
-
const compMethod = data.readUInt16LE(pos + 10);
|
|
123
|
-
const compSize = data.readUInt32LE(pos + 20);
|
|
124
|
-
const nameLen = data.readUInt16LE(pos + 28);
|
|
125
|
-
const extraLen = data.readUInt16LE(pos + 30);
|
|
126
|
-
const commentLen = data.readUInt16LE(pos + 32);
|
|
127
|
-
const localOffset = data.readUInt32LE(pos + 42);
|
|
128
|
-
const entryName = data.slice(pos + 46, pos + 46 + nameLen).toString('utf8');
|
|
129
|
-
pos += 46 + nameLen + extraLen + commentLen;
|
|
130
|
-
if (path.basename(entryName) !== info.binary) continue;
|
|
131
|
-
// Read local file header
|
|
132
|
-
const lhNameLen = data.readUInt16LE(localOffset + 26);
|
|
133
|
-
const lhExtraLen = data.readUInt16LE(localOffset + 28);
|
|
134
|
-
const dataStart = localOffset + 30 + lhNameLen + lhExtraLen;
|
|
135
|
-
let fileData;
|
|
136
|
-
if (compMethod === 0) {
|
|
137
|
-
fileData = data.slice(dataStart, dataStart + compSize);
|
|
138
|
-
} else if (compMethod === 8) {
|
|
139
|
-
fileData = zlib.inflateRawSync(data.slice(dataStart, dataStart + compSize));
|
|
140
|
-
} else {
|
|
141
|
-
console.warn(`[ssg] Unsupported ZIP compression ${compMethod}`);
|
|
142
|
-
process.exit(0);
|
|
143
|
-
}
|
|
144
|
-
fs.writeFileSync(binaryPath, fileData, {mode: 0o755});
|
|
145
|
-
console.log(`[ssg] Installed to ${binaryPath}`);
|
|
146
|
-
break;
|
|
147
|
-
}
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
});
|