@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 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 v21 with pre-compiled module caching
14
- - **Memory limit**: 1 MB per plugin invocation
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 binaryName = process.platform === 'win32' ? 'intutic-proxy.exe' : 'intutic-proxy';
9
- const binaryPath = path.join(__dirname, binaryName);
25
+ const require = createRequire(import.meta.url);
26
+ const { version } = require('../package.json');
10
27
 
11
- if (!fs.existsSync(binaryPath)) {
12
- console.error(`Error: Native intutic-proxy binary not found at ${binaryPath}`);
13
- process.exit(1);
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
- const child = spawn(binaryPath, process.argv.slice(2), { stdio: 'inherit' });
110
+ async function main() {
111
+ let binaryPath = findExistingBinary();
17
112
 
18
- child.on('exit', (code, signal) => {
19
- if (code !== null) {
20
- process.exit(code);
21
- } else if (signal) {
22
- process.kill(process.pid, signal);
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.5.0",
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