@intutic/proxy 1.5.0 → 1.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/README.md +3 -2
- package/bin/proxy.js +135 -12
- package/package.json +6 -7
- package/bin/intutic-proxy +0 -0
package/README.md
CHANGED
|
@@ -10,8 +10,9 @@ intutic-proxy is a high-performance AI agent proxy written in Rust (edition 2021
|
|
|
10
10
|
|
|
11
11
|
### WASM Plugin Sandbox
|
|
12
12
|
|
|
13
|
-
- **Runtime**: wasmtime
|
|
14
|
-
- **Memory limit**:
|
|
13
|
+
- **Runtime**: wasmtime v29 with pre-compiled module caching
|
|
14
|
+
- **Memory limit**: 16 MB per plugin invocation
|
|
15
|
+
- **Fuel limit**: 1,000,000 units per plugin invocation
|
|
15
16
|
- **Execution timeout**: 5 ms hard wall-clock cutoff
|
|
16
17
|
- **Isolation**: Each plugin runs in a dedicated WASM store
|
|
17
18
|
|
package/bin/proxy.js
CHANGED
|
@@ -1,24 +1,147 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Launcher for the native intutic-proxy binary.
|
|
4
|
+
*
|
|
5
|
+
* The npm package deliberately ships NO compiled binary. Publishing one would
|
|
6
|
+
* mean shipping whichever platform the release runner happened to build on
|
|
7
|
+
* (ubuntu-latest → linux-x64) to every consumer, so macOS and Windows installs
|
|
8
|
+
* received an ELF binary that cannot exec. Instead the correct per-platform
|
|
9
|
+
* asset is fetched on first run from the GitHub Release for this package's
|
|
10
|
+
* version, which .github/workflows/publish.yml uploads for all five targets.
|
|
11
|
+
*
|
|
12
|
+
* The download mirrors tools/cli/src/commands/connect.ts: same asset names
|
|
13
|
+
* (which MUST match the `artifact_name` values in the publish workflow's
|
|
14
|
+
* build-rust-proxy matrix), same URL scheme, and the same ~/.intutic/bin cache
|
|
15
|
+
* — so `intutic connect` and `npx @intutic/proxy` never download twice.
|
|
16
|
+
*/
|
|
2
17
|
import { spawn } from 'child_process';
|
|
3
18
|
import path from 'path';
|
|
4
19
|
import fs from 'fs';
|
|
20
|
+
import os from 'os';
|
|
21
|
+
import { createRequire } from 'module';
|
|
5
22
|
import { fileURLToPath } from 'url';
|
|
6
23
|
|
|
7
24
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
8
|
-
const
|
|
9
|
-
const
|
|
25
|
+
const require = createRequire(import.meta.url);
|
|
26
|
+
const { version } = require('../package.json');
|
|
10
27
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
28
|
+
const isWindows = process.platform === 'win32';
|
|
29
|
+
const binaryName = isWindows ? 'intutic-proxy.exe' : 'intutic-proxy';
|
|
30
|
+
|
|
31
|
+
/** Asset names MUST match publish.yml's build-rust-proxy matrix artifact_name. */
|
|
32
|
+
function resolveAssetName() {
|
|
33
|
+
const { platform, arch } = process;
|
|
34
|
+
if (platform === 'darwin') {
|
|
35
|
+
if (arch === 'arm64') return 'intutic-proxy-darwin-arm64';
|
|
36
|
+
if (arch === 'x64') return 'intutic-proxy-darwin-x64';
|
|
37
|
+
} else if (platform === 'linux') {
|
|
38
|
+
if (arch === 'x64') return 'intutic-proxy-linux-x64';
|
|
39
|
+
if (arch === 'arm64') return 'intutic-proxy-linux-arm64';
|
|
40
|
+
} else if (platform === 'win32') {
|
|
41
|
+
if (arch === 'x64') return 'intutic-proxy-win32-x64.exe';
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Absolute path to the shared `~/.intutic/bin` cache.
|
|
48
|
+
*
|
|
49
|
+
* `os.homedir()` can return an empty string when HOME is unset or blank (some
|
|
50
|
+
* CI images, `env -i`, certain daemon contexts). `path.join('', …)` yields a
|
|
51
|
+
* RELATIVE path, which would silently write a ~39MB binary into whatever
|
|
52
|
+
* directory the process happened to start in. Refuse that outright.
|
|
53
|
+
*/
|
|
54
|
+
function cacheDir() {
|
|
55
|
+
const home = os.homedir();
|
|
56
|
+
if (!home || !path.isAbsolute(home)) return null;
|
|
57
|
+
return path.join(home, '.intutic', 'bin');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Search order matches `intutic connect`: a locally built binary wins (so repo
|
|
62
|
+
* development never hits the network), then the shared global cache.
|
|
63
|
+
*/
|
|
64
|
+
function findExistingBinary() {
|
|
65
|
+
const cache = cacheDir();
|
|
66
|
+
const candidates = [
|
|
67
|
+
path.join(__dirname, binaryName),
|
|
68
|
+
path.resolve(__dirname, '..', 'target', 'release', binaryName),
|
|
69
|
+
path.resolve(__dirname, '..', '..', '..', 'target', 'release', binaryName),
|
|
70
|
+
...(cache ? [path.join(cache, binaryName)] : []),
|
|
71
|
+
];
|
|
72
|
+
return candidates.find((p) => fs.existsSync(p)) ?? null;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async function downloadBinary(destPath) {
|
|
76
|
+
const assetName = resolveAssetName();
|
|
77
|
+
if (!assetName) {
|
|
78
|
+
throw new Error(
|
|
79
|
+
`Unsupported platform/architecture: ${process.platform}-${process.arch}.\n` +
|
|
80
|
+
`Build from source instead: cargo build --release --package intutic-proxy`
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const url = `https://github.com/intutic/intutic/releases/download/v${version}/${assetName}`;
|
|
85
|
+
process.stderr.write(`intutic-proxy: downloading ${assetName} (v${version})…\n`);
|
|
86
|
+
|
|
87
|
+
const response = await fetch(url);
|
|
88
|
+
if (!response.ok) {
|
|
89
|
+
throw new Error(
|
|
90
|
+
`Failed to download ${assetName} (HTTP ${response.status} ${response.statusText}).\n` +
|
|
91
|
+
` URL: ${url}\n` +
|
|
92
|
+
`Build from source instead: cargo build --release --package intutic-proxy`
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const buffer = Buffer.from(await response.arrayBuffer());
|
|
97
|
+
fs.mkdirSync(path.dirname(destPath), { recursive: true });
|
|
98
|
+
|
|
99
|
+
// Write to a temp path and rename, so a partial download from an interrupted
|
|
100
|
+
// run is never left behind looking like a usable binary.
|
|
101
|
+
const tmpPath = `${destPath}.download`;
|
|
102
|
+
fs.writeFileSync(tmpPath, buffer);
|
|
103
|
+
if (!isWindows) fs.chmodSync(tmpPath, 0o755);
|
|
104
|
+
fs.renameSync(tmpPath, destPath);
|
|
105
|
+
|
|
106
|
+
process.stderr.write(`intutic-proxy: installed to ${destPath}\n`);
|
|
107
|
+
return destPath;
|
|
14
108
|
}
|
|
15
109
|
|
|
16
|
-
|
|
110
|
+
async function main() {
|
|
111
|
+
let binaryPath = findExistingBinary();
|
|
17
112
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
113
|
+
if (!binaryPath) {
|
|
114
|
+
const cache = cacheDir();
|
|
115
|
+
if (!cache) {
|
|
116
|
+
process.stderr.write(
|
|
117
|
+
'Error: cannot resolve a home directory to cache the intutic-proxy binary ' +
|
|
118
|
+
'(HOME is unset or not absolute).\n' +
|
|
119
|
+
'Set HOME, or build from source: cargo build --release --package intutic-proxy\n'
|
|
120
|
+
);
|
|
121
|
+
process.exit(1);
|
|
122
|
+
}
|
|
123
|
+
try {
|
|
124
|
+
binaryPath = await downloadBinary(path.join(cache, binaryName));
|
|
125
|
+
} catch (err) {
|
|
126
|
+
process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
127
|
+
process.exit(1);
|
|
128
|
+
}
|
|
23
129
|
}
|
|
24
|
-
|
|
130
|
+
|
|
131
|
+
const child = spawn(binaryPath, process.argv.slice(2), { stdio: 'inherit' });
|
|
132
|
+
|
|
133
|
+
child.on('error', (err) => {
|
|
134
|
+
process.stderr.write(`Error: failed to start ${binaryPath}: ${err.message}\n`);
|
|
135
|
+
process.exit(1);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
child.on('exit', (code, signal) => {
|
|
139
|
+
if (code !== null) {
|
|
140
|
+
process.exit(code);
|
|
141
|
+
} else if (signal) {
|
|
142
|
+
process.kill(process.pid, signal);
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
main();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intutic/proxy",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.1",
|
|
4
4
|
"description": "Native high-performance AI agent governance proxy binary",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "bin/proxy.js",
|
|
@@ -10,12 +10,8 @@
|
|
|
10
10
|
"publishConfig": {
|
|
11
11
|
"access": "public"
|
|
12
12
|
},
|
|
13
|
-
"scripts": {
|
|
14
|
-
"build": "cargo build --release && mkdir -p bin && (cp target/release/intutic-proxy bin/ 2>/dev/null || cp ../../target/release/intutic-proxy bin/)",
|
|
15
|
-
"prepublishOnly": "cargo build --release && mkdir -p bin && (cp target/release/intutic-proxy bin/ 2>/dev/null || cp ../../target/release/intutic-proxy bin/)"
|
|
16
|
-
},
|
|
17
13
|
"files": [
|
|
18
|
-
"bin/",
|
|
14
|
+
"bin/proxy.js",
|
|
19
15
|
"README.md",
|
|
20
16
|
"LICENSE"
|
|
21
17
|
],
|
|
@@ -36,5 +32,8 @@
|
|
|
36
32
|
],
|
|
37
33
|
"engines": {
|
|
38
34
|
"node": ">=18"
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "cargo build --release"
|
|
39
38
|
}
|
|
40
|
-
}
|
|
39
|
+
}
|
package/bin/intutic-proxy
DELETED
|
Binary file
|