aegiscode 4.0.10 → 4.0.11
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/package.json +3 -1
- package/scripts/download-binary.mjs +155 -0
- package/scripts/empty-stub.mjs +1 -0
- package/scripts/ensure-node-version.mjs +27 -0
- package/scripts/install.sh +121 -0
- package/scripts/make-bin.mjs +17 -0
- package/scripts/sharp-stub/index.js +9 -0
- package/scripts/sharp-stub/package.json +5 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aegiscode",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.11",
|
|
4
4
|
"description": "AEGIS CLI — AI-powered coding assistant",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"aegiscode": "bin/cli.js"
|
|
11
11
|
},
|
|
12
12
|
"scripts": {
|
|
13
|
+
"preinstall": "node scripts/ensure-node-version.mjs",
|
|
13
14
|
"build": "node esbuild.mjs",
|
|
14
15
|
"build:publish": "npm run build && node scripts/make-bin.mjs",
|
|
15
16
|
"dev": "NODE_NO_WARNINGS=1 tsx src/main.tsx",
|
|
@@ -47,6 +48,7 @@
|
|
|
47
48
|
},
|
|
48
49
|
"files": [
|
|
49
50
|
"bin/",
|
|
51
|
+
"scripts/",
|
|
50
52
|
"README.md",
|
|
51
53
|
"LICENSE"
|
|
52
54
|
],
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* postinstall script — downloads the prebuilt aegis-cli binary for the current platform.
|
|
4
|
+
* The binary is saved to <package>/bin/ and then spawned by bin/cli.js.
|
|
5
|
+
*
|
|
6
|
+
* Requires zero external dependencies (uses only Node.js built-ins).
|
|
7
|
+
*
|
|
8
|
+
* Binary source: GitHub releases
|
|
9
|
+
* https://github.com/aegisinfo/aegiscode/releases/latest/download/aegis-cli-{platform}-{arch}
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { createWriteStream, existsSync, chmodSync, mkdirSync } from 'fs';
|
|
13
|
+
import { get } from 'https';
|
|
14
|
+
import { join, dirname } from 'path';
|
|
15
|
+
import { fileURLToPath } from 'url';
|
|
16
|
+
|
|
17
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
18
|
+
const PACKAGE_ROOT = join(__dirname, '..');
|
|
19
|
+
const BIN_DIR = join(PACKAGE_ROOT, 'bin');
|
|
20
|
+
|
|
21
|
+
const BASE_URL =
|
|
22
|
+
'https://github.com/aegisinfo/aegiscode/releases/latest/download';
|
|
23
|
+
|
|
24
|
+
// Maps Node.js process.platform + process.arch → GitHub release asset name
|
|
25
|
+
const PLATFORM_MAP = {
|
|
26
|
+
'linux-x64': 'aegis-cli-linux-x64',
|
|
27
|
+
'linux-arm64': 'aegis-cli-linux-arm64',
|
|
28
|
+
'darwin-x64': 'aegis-cli-darwin-x64',
|
|
29
|
+
'darwin-arm64': 'aegis-cli-darwin-arm64',
|
|
30
|
+
'win32-x64': 'aegis-cli-win-x64.exe',
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// Fallback URLs for platforms that don't have a dedicated binary yet
|
|
34
|
+
const FALLBACK_MAP = {
|
|
35
|
+
'linux-arm': 'aegis-cli-linux-arm64',
|
|
36
|
+
'darwin': 'aegis-cli-darwin-x64',
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
// Helpers
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
|
|
43
|
+
function detectBinaryName() {
|
|
44
|
+
const os = process.platform;
|
|
45
|
+
const arch = process.arch;
|
|
46
|
+
const key = `${os}-${arch}`;
|
|
47
|
+
|
|
48
|
+
if (PLATFORM_MAP[key]) return PLATFORM_MAP[key];
|
|
49
|
+
|
|
50
|
+
// Try fallback (e.g. linux-arm → linux-arm64 binary if close enough)
|
|
51
|
+
for (const [pattern, fallback] of Object.entries(FALLBACK_MAP)) {
|
|
52
|
+
if (key.startsWith(pattern)) return fallback;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
throw new Error(
|
|
56
|
+
`Unsupported platform: ${key}\n` +
|
|
57
|
+
` Supported: ${Object.keys(PLATFORM_MAP).join(', ')}\n` +
|
|
58
|
+
` You can build from source: git clone https://github.com/aegisinfo/aegiscode && cd aegiscode && npm install && npm run build`
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function downloadFile(url, dest) {
|
|
63
|
+
return new Promise((resolve, reject) => {
|
|
64
|
+
const file = createWriteStream(dest);
|
|
65
|
+
const req = get(url, (res) => {
|
|
66
|
+
// Follow redirect (GitHub releases redirect to S3)
|
|
67
|
+
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
68
|
+
file.close();
|
|
69
|
+
// Avoid file-exists check on redirect target — let the stream overwrite
|
|
70
|
+
downloadFile(res.headers.location, dest).then(resolve).catch(reject);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (res.statusCode !== 200) {
|
|
75
|
+
file.close();
|
|
76
|
+
// Try to collect error body
|
|
77
|
+
let body = '';
|
|
78
|
+
res.on('data', (chunk) => (body += chunk.toString()));
|
|
79
|
+
res.on('end', () => {
|
|
80
|
+
const detail = body.trim().slice(0, 200);
|
|
81
|
+
reject(
|
|
82
|
+
new Error(`HTTP ${res.statusCode} — ${detail || 'no body'}`)
|
|
83
|
+
);
|
|
84
|
+
});
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
res.pipe(file);
|
|
89
|
+
file.on('finish', () => {
|
|
90
|
+
file.close();
|
|
91
|
+
resolve();
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
req.on('error', (err) => {
|
|
96
|
+
file.close();
|
|
97
|
+
// Attempt cleanup
|
|
98
|
+
try { file.close(); } catch { /* ignore */ }
|
|
99
|
+
reject(err);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
req.setTimeout(60_000, () => {
|
|
103
|
+
req.destroy();
|
|
104
|
+
reject(new Error('Download timed out after 60s'));
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// ---------------------------------------------------------------------------
|
|
110
|
+
// Main
|
|
111
|
+
// ---------------------------------------------------------------------------
|
|
112
|
+
|
|
113
|
+
async function main() {
|
|
114
|
+
const binaryName = detectBinaryName();
|
|
115
|
+
const url = `${BASE_URL}/${binaryName}`;
|
|
116
|
+
const dest = join(BIN_DIR, binaryName);
|
|
117
|
+
|
|
118
|
+
// Check if binary already exists (reinstall / postinstall after prepublish)
|
|
119
|
+
if (existsSync(dest)) {
|
|
120
|
+
console.log(`✓ aegis-cli already installed at ${dest}`);
|
|
121
|
+
chmodSync(dest, 0o755);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
console.log(`⬡ Downloading aegis-cli for ${process.platform}-${process.arch}...`);
|
|
126
|
+
|
|
127
|
+
mkdirSync(BIN_DIR, { recursive: true });
|
|
128
|
+
|
|
129
|
+
try {
|
|
130
|
+
await downloadFile(url, dest);
|
|
131
|
+
chmodSync(dest, 0o755);
|
|
132
|
+
console.log(`✓ aegis-cli installed to ${dest}`);
|
|
133
|
+
} catch (err) {
|
|
134
|
+
console.error('');
|
|
135
|
+
console.error(`⚠ Failed to download aegis-cli binary: ${err.message}`);
|
|
136
|
+
console.error('');
|
|
137
|
+
console.error(' Possible causes:');
|
|
138
|
+
console.error(' • No binary release for your platform yet');
|
|
139
|
+
console.error(' • No internet connectivity');
|
|
140
|
+
console.error(' • GitHub releases are unavailable');
|
|
141
|
+
console.error('');
|
|
142
|
+
console.error(' Options:');
|
|
143
|
+
console.error(' 1. Download manually from: https://github.com/aegisinfo/aegiscode/releases');
|
|
144
|
+
console.error(' and place the binary in: ' + BIN_DIR);
|
|
145
|
+
console.error(' 2. Build from source:');
|
|
146
|
+
console.error(' git clone https://github.com/aegisinfo/aegiscode');
|
|
147
|
+
console.error(' cd aegiscode && npm install && npm run build');
|
|
148
|
+
console.error(' 3. Install via installer script:');
|
|
149
|
+
console.error(' curl -fsSL https://dl.aegiscloud.org/install.sh | bash');
|
|
150
|
+
console.error('');
|
|
151
|
+
process.exit(1);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
main();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Preinstall hook — checks Node >= 22 and guides toward automatic upgrade.
|
|
4
|
+
* Full auto-install: curl -fsSL https://raw.githubusercontent.com/aegisinfo/aegiscode/main/scripts/install.sh | sh
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const MIN_MAJOR = 22;
|
|
8
|
+
const currentMajor = parseInt(process.version.slice(1), 10);
|
|
9
|
+
|
|
10
|
+
if (currentMajor >= MIN_MAJOR) {
|
|
11
|
+
process.exit(0);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
console.error(`
|
|
15
|
+
╔══════════════════════════════════════════════════════════╗
|
|
16
|
+
║ ⚠️ Node.js ${process.version} detected — AEGIS CLI needs Node >= ${MIN_MAJOR} ║
|
|
17
|
+
╠══════════════════════════════════════════════════════════╣
|
|
18
|
+
║ Auto-install (recommended): ║
|
|
19
|
+
║ curl -fsSL https://aegiscode.dev/install.sh | sh ║
|
|
20
|
+
║ ║
|
|
21
|
+
║ Manual upgrade (Linux): ║
|
|
22
|
+
║ curl -fsSL https://deb.nodesource.com/setup_22.x | ║
|
|
23
|
+
║ sudo -E bash - ║
|
|
24
|
+
║ sudo apt-get install -y nodejs ║
|
|
25
|
+
╚══════════════════════════════════════════════════════════╝
|
|
26
|
+
`);
|
|
27
|
+
process.exit(1);
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
REPO="aegisinfo/aegiscode"
|
|
5
|
+
PACKAGE="aegiscode"
|
|
6
|
+
MIN_NODE_MAJOR=22
|
|
7
|
+
|
|
8
|
+
# ── Colors ──────────────────────────────────────────────
|
|
9
|
+
RED='\033[0;31m'; GREEN='\033[0;32m'; CYAN='\033[0;36m'
|
|
10
|
+
YELLOW='\033[1;33m'; NC='\033[0m'
|
|
11
|
+
|
|
12
|
+
log() { echo -e "${CYAN}→${NC} $1"; }
|
|
13
|
+
ok() { echo -e "${GREEN}✓${NC} $1"; }
|
|
14
|
+
warn() { echo -e "${YELLOW}⚠${NC} $1"; }
|
|
15
|
+
err() { echo -e "${RED}✗${NC} $1"; exit 1; }
|
|
16
|
+
|
|
17
|
+
# ── Detect Node.js ──────────────────────────────────────
|
|
18
|
+
detect_node() {
|
|
19
|
+
if command -v node &>/dev/null; then
|
|
20
|
+
NODE_VERSION=$(node -v | sed 's/^v//')
|
|
21
|
+
NODE_MAJOR=$(echo "$NODE_VERSION" | cut -d. -f1)
|
|
22
|
+
log "Node.js ${NODE_VERSION} detected"
|
|
23
|
+
return 0
|
|
24
|
+
fi
|
|
25
|
+
return 1
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
# ── Install Node.js 22 ──────────────────────────────────
|
|
29
|
+
install_node() {
|
|
30
|
+
warn "Node.js >= ${MIN_NODE_MAJOR} required (found ${NODE_VERSION:-none})"
|
|
31
|
+
log "Installing Node.js ${MIN_NODE_MAJOR}..."
|
|
32
|
+
|
|
33
|
+
# Strategy: nvm
|
|
34
|
+
if [ -n "${NVM_DIR:-}" ] || [ -f "$HOME/.nvm/nvm.sh" ]; then
|
|
35
|
+
NVM_DIR="${NVM_DIR:-$HOME/.nvm}"
|
|
36
|
+
log "Using nvm..."
|
|
37
|
+
\. "$NVM_DIR/nvm.sh"
|
|
38
|
+
nvm install "$MIN_NODE_MAJOR"
|
|
39
|
+
nvm alias default "$MIN_NODE_MAJOR"
|
|
40
|
+
ok "Node.js $(node -v) installed via nvm"
|
|
41
|
+
return 0
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
# Strategy: fnm
|
|
45
|
+
if command -v fnm &>/dev/null; then
|
|
46
|
+
log "Using fnm..."
|
|
47
|
+
fnm install "$MIN_NODE_MAJOR"
|
|
48
|
+
fnm default "$MIN_NODE_MAJOR"
|
|
49
|
+
eval "$(fnm env)"
|
|
50
|
+
ok "Node.js $(node -v) installed via fnm"
|
|
51
|
+
return 0
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
# Strategy: nodesource (Linux)
|
|
55
|
+
if [ "$(uname -s)" = "Linux" ]; then
|
|
56
|
+
log "Using nodesource..."
|
|
57
|
+
curl -fsSL "https://deb.nodesource.com/setup_${MIN_NODE_MAJOR}.x" | sudo -E bash -
|
|
58
|
+
sudo apt-get install -y nodejs
|
|
59
|
+
ok "Node.js $(node -v) installed via nodesource"
|
|
60
|
+
return 0
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
# Strategy: brew (macOS)
|
|
64
|
+
if command -v brew &>/dev/null; then
|
|
65
|
+
log "Using Homebrew..."
|
|
66
|
+
brew install node@${MIN_NODE_MAJOR}
|
|
67
|
+
brew link --overwrite node@${MIN_NODE_MAJOR}
|
|
68
|
+
ok "Node.js $(node -v) installed via Homebrew"
|
|
69
|
+
return 0
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
err "Could not auto-install Node.js. Install manually:\n curl -fsSL https://deb.nodesource.com/setup_${MIN_NODE_MAJOR}.x | sudo -E bash -\n sudo apt-get install -y nodejs"
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
# ── Fix npm prefix (avoid EACCES) ───────────────────────
|
|
76
|
+
fix_npm_prefix() {
|
|
77
|
+
if [ "$(npm config get prefix)" = "/usr/local" ]; then
|
|
78
|
+
if [ ! -w "/usr/local/lib/node_modules" ]; then
|
|
79
|
+
warn "No write permission for /usr/local/lib/node_modules"
|
|
80
|
+
log "Configuring npm to use ~/.npm-global..."
|
|
81
|
+
mkdir -p "$HOME/.npm-global"
|
|
82
|
+
npm config set prefix "$HOME/.npm-global"
|
|
83
|
+
# Add to PATH if not already there
|
|
84
|
+
case ":$PATH:" in
|
|
85
|
+
*:"$HOME/.npm-global/bin":*) ;;
|
|
86
|
+
*)
|
|
87
|
+
echo 'export PATH="$HOME/.npm-global/bin:$PATH"' >> "$HOME/.bashrc"
|
|
88
|
+
echo 'export PATH="$HOME/.npm-global/bin:$PATH"' >> "$HOME/.profile"
|
|
89
|
+
export PATH="$HOME/.npm-global/bin:$PATH"
|
|
90
|
+
;;
|
|
91
|
+
esac
|
|
92
|
+
ok "npm prefix set to ~/.npm-global"
|
|
93
|
+
fi
|
|
94
|
+
fi
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
# ── Main ────────────────────────────────────────────────
|
|
98
|
+
echo
|
|
99
|
+
echo " ${CYAN}━━━ AEGIS CLI Installer ━━━${NC}"
|
|
100
|
+
echo
|
|
101
|
+
|
|
102
|
+
detect_node || NODE_MAJOR=0
|
|
103
|
+
|
|
104
|
+
if [ "$NODE_MAJOR" -lt "$MIN_NODE_MAJOR" ]; then
|
|
105
|
+
install_node
|
|
106
|
+
# Re-source PATH in case nvm/fnm added node
|
|
107
|
+
export PATH="$HOME/.npm-global/bin:$PATH"
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
fix_npm_prefix
|
|
111
|
+
|
|
112
|
+
log "Installing ${PACKAGE}..."
|
|
113
|
+
npm install -g "${PACKAGE}@latest" 2>/dev/null || npm install -g "${PACKAGE}@latest" --no-optional
|
|
114
|
+
|
|
115
|
+
echo
|
|
116
|
+
if command -v aegis &>/dev/null; then
|
|
117
|
+
ok "AEGIS CLI installed! Run: aegis --help"
|
|
118
|
+
else
|
|
119
|
+
warn "Add ~/.npm-global/bin to your PATH, then run: aegis --help"
|
|
120
|
+
fi
|
|
121
|
+
echo
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* make-bin.mjs — copies the built dist/main.js to bin/cli.js as-is (no obfuscation).
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { readFileSync, writeFileSync, mkdirSync, chmodSync } from 'node:fs';
|
|
6
|
+
import { dirname, join } from 'node:path';
|
|
7
|
+
import { fileURLToPath } from 'node:url';
|
|
8
|
+
|
|
9
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
const src = join(__dirname, '..', 'dist', 'main.js');
|
|
11
|
+
const dest = join(__dirname, '..', 'bin', 'cli.js');
|
|
12
|
+
|
|
13
|
+
mkdirSync(join(__dirname, '..', 'bin'), { recursive: true });
|
|
14
|
+
writeFileSync(dest, readFileSync(src, 'utf-8'), 'utf-8');
|
|
15
|
+
chmodSync(dest, 0o755);
|
|
16
|
+
|
|
17
|
+
console.log(`✓ bin/cli.js written (unobfuscated)`);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// aegiscode only uses @xenova/transformers for text embeddings (all-MiniLM-L6-v2),
|
|
2
|
+
// never image inputs — so the real `sharp` native binary (and its install-time
|
|
3
|
+
// prebuild-install download, a recurring source of `npm install` failures on
|
|
4
|
+
// flaky networks/unsupported platforms) is unneeded dead weight. This stub
|
|
5
|
+
// satisfies `import sharp from 'sharp'` without pulling in native bindings.
|
|
6
|
+
function sharp() {
|
|
7
|
+
throw new Error('sharp is stubbed out in aegiscode — image processing is not supported');
|
|
8
|
+
}
|
|
9
|
+
module.exports = sharp;
|