@oracle-agent/oracle 0.22.9 → 0.22.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oracle-agent/oracle",
3
- "version": "0.22.9",
3
+ "version": "0.22.11",
4
4
  "description": "Oracle: standalone prepare-only multichain agent control plane. Runs its own agent loop, or plugs into any MCP-compatible harness. Policy-bounded intents for a user-signed wallet; the public package never takes your key.",
5
5
  "license": "BUSL-1.1",
6
6
  "type": "module",
@@ -5,7 +5,7 @@
5
5
  const COMMAND = "npx";
6
6
  const ARGS = ["-y", "--package", PACKAGE, "oracle-data-mcp"];
7
7
  const INIT_COMMAND = "npx -y --package @oracle-agent/oracle oracle-init";
8
- const NATIVE_COMMAND = "npm i -g @oracle-agent/oracle && oracle setup model && oracle chat";
8
+ const NATIVE_COMMAND = "curl -fsSL https://oracle.demi.la/install.sh | bash && oracle setup model && oracle chat";
9
9
 
10
10
  const apiUrl = document.querySelector("#api-url");
11
11
  const apiKey = document.querySelector("#api-key");
@@ -0,0 +1,300 @@
1
+ #!/usr/bin/env bash
2
+ # Oracle public installer — prepare-only crypto agent control plane.
3
+ #
4
+ # curl -fsSL https://oracle.demi.la/install.sh | bash
5
+ # curl -fsSL https://oracle.demi.la/install.sh | bash -s -- --version latest
6
+ # curl -fsSL https://oracle.demi.la/install.sh | bash -s -- --prefix "$HOME/.local"
7
+ #
8
+ # What this does:
9
+ # - installs @oracle-agent/oracle into a user prefix (no root, no global npm -g)
10
+ # - puts `oracle` on PATH via ~/.local/bin (or --prefix/bin)
11
+ # - never asks for keys, seeds, or wallet approval
12
+ #
13
+ # What this never does:
14
+ # - sign or broadcast transactions
15
+ # - install a private signer/executor
16
+ # - require Hermes or any other agent harness
17
+ set -euo pipefail
18
+
19
+ ORACLE_INSTALL_VERSION="${ORACLE_INSTALL_VERSION:-latest}"
20
+ ORACLE_INSTALL_PREFIX="${ORACLE_INSTALL_PREFIX:-}"
21
+ ORACLE_INSTALL_FORCE_NODE="${ORACLE_INSTALL_FORCE_NODE:-0}"
22
+ ORACLE_NPM_PACKAGE="${ORACLE_NPM_PACKAGE:-@oracle-agent/oracle}"
23
+ MIN_NODE_MAJOR=20
24
+ MIN_NODE_MINOR=19
25
+ NONINTERACTIVE=1
26
+ DO_SETUP=0
27
+ DO_DOCTOR=1
28
+ PRINT_ONLY=0
29
+
30
+ log() { printf 'oracle-install: %s\n' "$*"; }
31
+ err() { printf 'oracle-install: ERROR: %s\n' "$*" >&2; }
32
+ die() { err "$*"; exit 1; }
33
+ have() { command -v "$1" >/dev/null 2>&1; }
34
+
35
+ usage() {
36
+ cat <<'EOF'
37
+ Oracle install (curl)
38
+
39
+ curl -fsSL https://oracle.demi.la/install.sh | bash
40
+ curl -fsSL https://oracle.demi.la/install.sh | bash -s -- [options]
41
+
42
+ Options:
43
+ --version <ver|latest> Package version (default: latest)
44
+ --prefix <dir> Install root (default: ~/.local)
45
+ --home <dir> Package home (default: ~/.local/share/oracle)
46
+ --no-doctor Skip post-install doctor
47
+ --setup Run `oracle setup model` after install (interactive)
48
+ --print Print plan only
49
+ -h, --help Show help
50
+
51
+ Env:
52
+ ORACLE_INSTALL_VERSION same as --version
53
+ ORACLE_INSTALL_PREFIX same as --prefix
54
+ ORACLE_HOME package data dir override
55
+ npm_config_registry custom npm registry
56
+ EOF
57
+ }
58
+
59
+ while [ $# -gt 0 ]; do
60
+ case "$1" in
61
+ --version) ORACLE_INSTALL_VERSION="${2:-}"; shift 2 ;;
62
+ --prefix) ORACLE_INSTALL_PREFIX="${2:-}"; shift 2 ;;
63
+ --home) ORACLE_HOME_OVERRIDE="${2:-}"; shift 2 ;;
64
+ --no-doctor) DO_DOCTOR=0; shift ;;
65
+ --setup) DO_SETUP=1; shift ;;
66
+ --print) PRINT_ONLY=1; shift ;;
67
+ -h|--help) usage; exit 0 ;;
68
+ *) die "unknown arg: $1 (see --help)" ;;
69
+ esac
70
+ done
71
+
72
+ # --- platform ---------------------------------------------------------------
73
+ OS="$(uname -s 2>/dev/null || echo unknown)"
74
+ ARCH="$(uname -m 2>/dev/null || echo unknown)"
75
+ case "$OS" in
76
+ Linux|Darwin) ;;
77
+ MINGW*|MSYS*|CYGWIN*)
78
+ die "Windows: use PowerShell installer or npm i -g @oracle-agent/oracle. See https://oracle.demi.la/downloads/"
79
+ ;;
80
+ *) die "unsupported OS: $OS" ;;
81
+ esac
82
+
83
+ PREFIX="${ORACLE_INSTALL_PREFIX:-$HOME/.local}"
84
+ BIN_DIR="${PREFIX}/bin"
85
+ SHARE_DIR="${ORACLE_HOME_OVERRIDE:-${ORACLE_HOME:-$HOME/.local/share/oracle}}"
86
+ PKG_DIR="${SHARE_DIR}/package"
87
+
88
+ need_cmds() {
89
+ for c in curl tar mkdir ln chmod; do
90
+ have "$c" || die "missing required command: $c"
91
+ done
92
+ }
93
+
94
+ node_ok() {
95
+ have node || return 1
96
+ # node -p 'process.versions.node'
97
+ local ver major minor
98
+ ver="$(node -p 'process.versions.node' 2>/dev/null || true)"
99
+ [ -n "$ver" ] || return 1
100
+ major="${ver%%.*}"
101
+ minor="${ver#*.}"; minor="${minor%%.*}"
102
+ if [ "$major" -gt "$MIN_NODE_MAJOR" ]; then return 0; fi
103
+ if [ "$major" -eq "$MIN_NODE_MAJOR" ] && [ "${minor:-0}" -ge "$MIN_NODE_MINOR" ]; then return 0; fi
104
+ return 1
105
+ }
106
+
107
+ ensure_node() {
108
+ if node_ok; then
109
+ log "node $(node -p 'process.versions.node') OK"
110
+ return 0
111
+ fi
112
+ if have node; then
113
+ err "node $(node -p 'process.versions.node' 2>/dev/null || echo '?') is too old (need >= ${MIN_NODE_MAJOR}.${MIN_NODE_MINOR})"
114
+ else
115
+ err "node not found (need >= ${MIN_NODE_MAJOR}.${MIN_NODE_MINOR})"
116
+ fi
117
+
118
+ # Best-effort: nvm if already present
119
+ if [ -s "$HOME/.nvm/nvm.sh" ]; then
120
+ # shellcheck disable=SC1091
121
+ . "$HOME/.nvm/nvm.sh"
122
+ log "trying nvm install ${MIN_NODE_MAJOR}"
123
+ nvm install "$MIN_NODE_MAJOR" >/dev/null
124
+ nvm use "$MIN_NODE_MAJOR" >/dev/null
125
+ node_ok && { log "node $(node -p 'process.versions.node') via nvm"; return 0; }
126
+ fi
127
+
128
+ cat >&2 <<EOF
129
+ oracle-install: install Node.js ${MIN_NODE_MAJOR}.${MIN_NODE_MINOR}+ then re-run:
130
+
131
+ # macOS (Homebrew)
132
+ brew install node@${MIN_NODE_MAJOR}
133
+
134
+ # Ubuntu/Debian
135
+ curl -fsSL https://deb.nodesource.com/setup_${MIN_NODE_MAJOR}.x | sudo -E bash -
136
+ sudo apt-get install -y nodejs
137
+
138
+ # or nvm
139
+ curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
140
+ nvm install ${MIN_NODE_MAJOR}
141
+
142
+ Then:
143
+ curl -fsSL https://oracle.demi.la/install.sh | bash
144
+ EOF
145
+ exit 1
146
+ }
147
+
148
+ ensure_npm() {
149
+ have npm || die "npm not found (ships with Node). Reinstall Node ${MIN_NODE_MAJOR}+."
150
+ log "npm $(npm -v 2>/dev/null || echo '?')"
151
+ }
152
+
153
+ resolve_version() {
154
+ local want="$ORACLE_INSTALL_VERSION"
155
+ if [ "$want" = "latest" ] || [ -z "$want" ]; then
156
+ want="$(npm view "$ORACLE_NPM_PACKAGE" version --prefer-online 2>/dev/null || true)"
157
+ [ -n "$want" ] || die "could not resolve latest version of $ORACLE_NPM_PACKAGE (network/npm?)"
158
+ fi
159
+ ORACLE_RESOLVED_VERSION="$want"
160
+ log "target ${ORACLE_NPM_PACKAGE}@${ORACLE_RESOLVED_VERSION}"
161
+ }
162
+
163
+ install_package() {
164
+ mkdir -p "$PKG_DIR" "$BIN_DIR" "$SHARE_DIR"
165
+ # Isolated prefix install — no sudo, no global pollution
166
+ cat >"$PKG_DIR/package.json" <<EOF
167
+ {
168
+ "name": "oracle-user-install",
169
+ "private": true,
170
+ "description": "Oracle curl-install root (do not publish)"
171
+ }
172
+ EOF
173
+ log "installing into $PKG_DIR"
174
+ (
175
+ cd "$PKG_DIR"
176
+ npm install "${ORACLE_NPM_PACKAGE}@${ORACLE_RESOLVED_VERSION}" \
177
+ --no-fund \
178
+ --no-audit \
179
+ --prefer-online \
180
+ --loglevel=error
181
+ )
182
+
183
+ local oracle_bin=""
184
+ if [ -x "$PKG_DIR/node_modules/.bin/oracle" ]; then
185
+ oracle_bin="$PKG_DIR/node_modules/.bin/oracle"
186
+ elif [ -f "$PKG_DIR/node_modules/@oracle-agent/oracle/bin/oracle.mjs" ]; then
187
+ oracle_bin="$PKG_DIR/node_modules/@oracle-agent/oracle/bin/oracle.mjs"
188
+ else
189
+ die "install finished but oracle binary missing under $PKG_DIR"
190
+ fi
191
+
192
+ # Stable launcher in BIN_DIR
193
+ cat >"$BIN_DIR/oracle" <<EOF
194
+ #!/usr/bin/env bash
195
+ # Generated by oracle.demi.la/install.sh — do not edit; re-run installer to upgrade.
196
+ set -euo pipefail
197
+ export ORACLE_INSTALL_ROOT="$PKG_DIR"
198
+ exec "$oracle_bin" "\$@"
199
+ EOF
200
+ chmod 755 "$BIN_DIR/oracle"
201
+
202
+ # Convenience: also expose oracle-data-mcp if present
203
+ if [ -x "$PKG_DIR/node_modules/.bin/oracle-data-mcp" ]; then
204
+ cat >"$BIN_DIR/oracle-data-mcp" <<EOF
205
+ #!/usr/bin/env bash
206
+ set -euo pipefail
207
+ exec "$PKG_DIR/node_modules/.bin/oracle-data-mcp" "\$@"
208
+ EOF
209
+ chmod 755 "$BIN_DIR/oracle-data-mcp"
210
+ fi
211
+
212
+ # Record install metadata
213
+ cat >"$SHARE_DIR/install.json" <<EOF
214
+ {
215
+ "package": "${ORACLE_NPM_PACKAGE}",
216
+ "version": "${ORACLE_RESOLVED_VERSION}",
217
+ "prefix": "${PREFIX}",
218
+ "bin": "${BIN_DIR}/oracle",
219
+ "home": "${PKG_DIR}",
220
+ "installedAt": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
221
+ "method": "curl-install.sh"
222
+ }
223
+ EOF
224
+ }
225
+
226
+ path_hint() {
227
+ case ":$PATH:" in
228
+ *":$BIN_DIR:"*) return 0 ;;
229
+ esac
230
+ cat <<EOF
231
+
232
+ Add Oracle to your PATH (one-time):
233
+
234
+ # bash
235
+ echo 'export PATH="$BIN_DIR:\$PATH"' >> ~/.bashrc && source ~/.bashrc
236
+
237
+ # zsh
238
+ echo 'export PATH="$BIN_DIR:\$PATH"' >> ~/.zshrc && source ~/.zshrc
239
+
240
+ # fish
241
+ fish_add_path $BIN_DIR
242
+ EOF
243
+ }
244
+
245
+ verify() {
246
+ export PATH="$BIN_DIR:$PATH"
247
+ hash -r 2>/dev/null || true
248
+ if ! have oracle; then
249
+ die "oracle not on PATH after install. Expected $BIN_DIR/oracle"
250
+ fi
251
+ local ver
252
+ ver="$(oracle --version 2>/dev/null | head -1 || true)"
253
+ log "installed: ${ver:-oracle (version unknown)}"
254
+ if [ "$DO_DOCTOR" = 1 ]; then
255
+ oracle doctor 2>/dev/null | head -20 || true
256
+ fi
257
+ }
258
+
259
+ print_next() {
260
+ cat <<EOF
261
+
262
+ Oracle ready (prepare-only · your wallet signs).
263
+
264
+ oracle --version
265
+ oracle setup model
266
+ oracle chat
267
+ oracle doctor --agentic
268
+ oracle harness detect
269
+
270
+ Upgrade later:
271
+ curl -fsSL https://oracle.demi.la/install.sh | bash
272
+
273
+ Install root: $PKG_DIR
274
+ Binary: $BIN_DIR/oracle
275
+ EOF
276
+ path_hint
277
+ }
278
+
279
+ main() {
280
+ need_cmds
281
+ log "os=$OS arch=$ARCH"
282
+ log "prefix=$PREFIX home=$SHARE_DIR"
283
+ if [ "$PRINT_ONLY" = 1 ]; then
284
+ resolve_version
285
+ log "would install ${ORACLE_NPM_PACKAGE}@${ORACLE_RESOLVED_VERSION} → $PKG_DIR"
286
+ exit 0
287
+ fi
288
+ ensure_node
289
+ ensure_npm
290
+ resolve_version
291
+ install_package
292
+ verify
293
+ if [ "$DO_SETUP" = 1 ]; then
294
+ export PATH="$BIN_DIR:$PATH"
295
+ oracle setup model || true
296
+ fi
297
+ print_next
298
+ }
299
+
300
+ main
@@ -27,7 +27,7 @@ section{padding-top:72px;scroll-margin-top:90px}.sub{color:var(--muted);line-hei
27
27
  <main class="wrap">
28
28
  <header><p class="eyebrow">Public release</p><h1>Install Oracle.<br><em>Your wallet signs.</em></h1><p class="lede">The CLI, desktop beta, source, research tools, and unsigned transaction preparation are public to everyone. No wallet connection or NFT is required to download or run Oracle.</p></header>
29
29
  <aside class="policy"><h2>Locals Only means 0% Oracle fees</h2><p>A Locals Only NFT waives the <b>Oracle integrator fee</b>. It does not unlock the product, arm execution, waive provider or network costs, or change the keyless prepare-only custody boundary.</p></aside>
30
- <section id="cli"><p class="eyebrow">Oracle CLI</p><h2>Install from npm</h2><p class="sub">Requires Node 20.19 or newer. npm <code>latest</code> contains the full public runtime.</p><div class="install"><div class="cmd"><code id="cmd">npm i -g @oracle-agent/oracle</code><button class="copy" id="copy" type="button">Copy</button></div><div class="meta"><span>public npm package</span><span>keyless</span><span>prepare-only</span></div></div></section>
30
+ <section id="cli"><p class="eyebrow">Oracle CLI</p><h2>Install with curl</h2><p class="sub">One line. Linux and macOS. Requires Node 20.19+ (the script checks and tells you how to get it). Installs into <code>~/.local</code> — no sudo, no global npm.</p><div class="install"><div class="cmd"><code id="cmd">curl -fsSL https://oracle.demi.la/install.sh | bash</code><button class="copy" id="copy" type="button">Copy</button></div><div class="meta"><span>curl install</span><span>keyless</span><span>prepare-only</span><span>user prefix</span></div></div><p class="sub" style="margin-top:18px">npm still works if you prefer: <code>npm i -g @oracle-agent/oracle</code></p></section>
31
31
  <section id="desktop"><p class="eyebrow">Desktop beta · 0.4.0</p><h2>Native installers</h2><p class="sub">Each installer bundles the same public runtime. Download directly, then verify it against the published SHA-256 manifest.</p><div class="artifacts">
32
32
  <div class="artifact" data-artifact="Oracle-0.4.0.AppImage"><div><h3>Linux</h3><small>AppImage · x64</small></div><div class="artifact-meta"><span class="build">Oracle 0.4.0 beta</span></div><code class="hash" data-hash>checksum loading</code><a class="dl-btn" href="/downloads/artifacts/Oracle-0.4.0.AppImage" download>Download</a></div>
33
33
  <div class="artifact" data-artifact="Oracle-0.4.0-arm64.dmg"><div><h3>macOS</h3><small>DMG · Apple silicon</small></div><div class="artifact-meta"><span class="build">Oracle 0.4.0 beta</span></div><code class="hash" data-hash>checksum loading</code><a class="dl-btn" href="/downloads/artifacts/Oracle-0.4.0-arm64.dmg" download>Download</a></div>
@@ -1775,7 +1775,7 @@ footer{margin-top:clamp(72px,12vh,120px);border-top:1px solid var(--line);paddin
1775
1775
  <p class="section-label rv">Oracle CLI</p>
1776
1776
  <h2 class="section-title rv">One surface. <em>Every chain.</em></h2>
1777
1777
  <div class="cli-install rv">
1778
- <div class="cli-install-cmd"><code>oracle</code> <span class="cli-install-hint">npm install -g @oracle-agent/oracle</span></div>
1778
+ <div class="cli-install-cmd"><code>curl -fsSL https://oracle.demi.la/install.sh | bash</code> <span class="cli-install-hint">then oracle setup model && oracle chat</span></div>
1779
1779
  </div>
1780
1780
  <p class="section-lede rv">The real Oracle shell, isolated from desktop chrome. No accounts, no servers. The CLI runs on your machine and reads straight from public RPCs.</p>
1781
1781
  <p class="section-lede rv">Pin the active surface with <code style="color:var(--blue2)">/chain hyperliquid</code>, switch models, ask naturally. Oracle reads, prices, and prepares — you sign.</p>
@@ -0,0 +1,300 @@
1
+ #!/usr/bin/env bash
2
+ # Oracle public installer — prepare-only crypto agent control plane.
3
+ #
4
+ # curl -fsSL https://oracle.demi.la/install.sh | bash
5
+ # curl -fsSL https://oracle.demi.la/install.sh | bash -s -- --version latest
6
+ # curl -fsSL https://oracle.demi.la/install.sh | bash -s -- --prefix "$HOME/.local"
7
+ #
8
+ # What this does:
9
+ # - installs @oracle-agent/oracle into a user prefix (no root, no global npm -g)
10
+ # - puts `oracle` on PATH via ~/.local/bin (or --prefix/bin)
11
+ # - never asks for keys, seeds, or wallet approval
12
+ #
13
+ # What this never does:
14
+ # - sign or broadcast transactions
15
+ # - install a private signer/executor
16
+ # - require Hermes or any other agent harness
17
+ set -euo pipefail
18
+
19
+ ORACLE_INSTALL_VERSION="${ORACLE_INSTALL_VERSION:-latest}"
20
+ ORACLE_INSTALL_PREFIX="${ORACLE_INSTALL_PREFIX:-}"
21
+ ORACLE_INSTALL_FORCE_NODE="${ORACLE_INSTALL_FORCE_NODE:-0}"
22
+ ORACLE_NPM_PACKAGE="${ORACLE_NPM_PACKAGE:-@oracle-agent/oracle}"
23
+ MIN_NODE_MAJOR=20
24
+ MIN_NODE_MINOR=19
25
+ NONINTERACTIVE=1
26
+ DO_SETUP=0
27
+ DO_DOCTOR=1
28
+ PRINT_ONLY=0
29
+
30
+ log() { printf 'oracle-install: %s\n' "$*"; }
31
+ err() { printf 'oracle-install: ERROR: %s\n' "$*" >&2; }
32
+ die() { err "$*"; exit 1; }
33
+ have() { command -v "$1" >/dev/null 2>&1; }
34
+
35
+ usage() {
36
+ cat <<'EOF'
37
+ Oracle install (curl)
38
+
39
+ curl -fsSL https://oracle.demi.la/install.sh | bash
40
+ curl -fsSL https://oracle.demi.la/install.sh | bash -s -- [options]
41
+
42
+ Options:
43
+ --version <ver|latest> Package version (default: latest)
44
+ --prefix <dir> Install root (default: ~/.local)
45
+ --home <dir> Package home (default: ~/.local/share/oracle)
46
+ --no-doctor Skip post-install doctor
47
+ --setup Run `oracle setup model` after install (interactive)
48
+ --print Print plan only
49
+ -h, --help Show help
50
+
51
+ Env:
52
+ ORACLE_INSTALL_VERSION same as --version
53
+ ORACLE_INSTALL_PREFIX same as --prefix
54
+ ORACLE_HOME package data dir override
55
+ npm_config_registry custom npm registry
56
+ EOF
57
+ }
58
+
59
+ while [ $# -gt 0 ]; do
60
+ case "$1" in
61
+ --version) ORACLE_INSTALL_VERSION="${2:-}"; shift 2 ;;
62
+ --prefix) ORACLE_INSTALL_PREFIX="${2:-}"; shift 2 ;;
63
+ --home) ORACLE_HOME_OVERRIDE="${2:-}"; shift 2 ;;
64
+ --no-doctor) DO_DOCTOR=0; shift ;;
65
+ --setup) DO_SETUP=1; shift ;;
66
+ --print) PRINT_ONLY=1; shift ;;
67
+ -h|--help) usage; exit 0 ;;
68
+ *) die "unknown arg: $1 (see --help)" ;;
69
+ esac
70
+ done
71
+
72
+ # --- platform ---------------------------------------------------------------
73
+ OS="$(uname -s 2>/dev/null || echo unknown)"
74
+ ARCH="$(uname -m 2>/dev/null || echo unknown)"
75
+ case "$OS" in
76
+ Linux|Darwin) ;;
77
+ MINGW*|MSYS*|CYGWIN*)
78
+ die "Windows: use PowerShell installer or npm i -g @oracle-agent/oracle. See https://oracle.demi.la/downloads/"
79
+ ;;
80
+ *) die "unsupported OS: $OS" ;;
81
+ esac
82
+
83
+ PREFIX="${ORACLE_INSTALL_PREFIX:-$HOME/.local}"
84
+ BIN_DIR="${PREFIX}/bin"
85
+ SHARE_DIR="${ORACLE_HOME_OVERRIDE:-${ORACLE_HOME:-$HOME/.local/share/oracle}}"
86
+ PKG_DIR="${SHARE_DIR}/package"
87
+
88
+ need_cmds() {
89
+ for c in curl tar mkdir ln chmod; do
90
+ have "$c" || die "missing required command: $c"
91
+ done
92
+ }
93
+
94
+ node_ok() {
95
+ have node || return 1
96
+ # node -p 'process.versions.node'
97
+ local ver major minor
98
+ ver="$(node -p 'process.versions.node' 2>/dev/null || true)"
99
+ [ -n "$ver" ] || return 1
100
+ major="${ver%%.*}"
101
+ minor="${ver#*.}"; minor="${minor%%.*}"
102
+ if [ "$major" -gt "$MIN_NODE_MAJOR" ]; then return 0; fi
103
+ if [ "$major" -eq "$MIN_NODE_MAJOR" ] && [ "${minor:-0}" -ge "$MIN_NODE_MINOR" ]; then return 0; fi
104
+ return 1
105
+ }
106
+
107
+ ensure_node() {
108
+ if node_ok; then
109
+ log "node $(node -p 'process.versions.node') OK"
110
+ return 0
111
+ fi
112
+ if have node; then
113
+ err "node $(node -p 'process.versions.node' 2>/dev/null || echo '?') is too old (need >= ${MIN_NODE_MAJOR}.${MIN_NODE_MINOR})"
114
+ else
115
+ err "node not found (need >= ${MIN_NODE_MAJOR}.${MIN_NODE_MINOR})"
116
+ fi
117
+
118
+ # Best-effort: nvm if already present
119
+ if [ -s "$HOME/.nvm/nvm.sh" ]; then
120
+ # shellcheck disable=SC1091
121
+ . "$HOME/.nvm/nvm.sh"
122
+ log "trying nvm install ${MIN_NODE_MAJOR}"
123
+ nvm install "$MIN_NODE_MAJOR" >/dev/null
124
+ nvm use "$MIN_NODE_MAJOR" >/dev/null
125
+ node_ok && { log "node $(node -p 'process.versions.node') via nvm"; return 0; }
126
+ fi
127
+
128
+ cat >&2 <<EOF
129
+ oracle-install: install Node.js ${MIN_NODE_MAJOR}.${MIN_NODE_MINOR}+ then re-run:
130
+
131
+ # macOS (Homebrew)
132
+ brew install node@${MIN_NODE_MAJOR}
133
+
134
+ # Ubuntu/Debian
135
+ curl -fsSL https://deb.nodesource.com/setup_${MIN_NODE_MAJOR}.x | sudo -E bash -
136
+ sudo apt-get install -y nodejs
137
+
138
+ # or nvm
139
+ curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
140
+ nvm install ${MIN_NODE_MAJOR}
141
+
142
+ Then:
143
+ curl -fsSL https://oracle.demi.la/install.sh | bash
144
+ EOF
145
+ exit 1
146
+ }
147
+
148
+ ensure_npm() {
149
+ have npm || die "npm not found (ships with Node). Reinstall Node ${MIN_NODE_MAJOR}+."
150
+ log "npm $(npm -v 2>/dev/null || echo '?')"
151
+ }
152
+
153
+ resolve_version() {
154
+ local want="$ORACLE_INSTALL_VERSION"
155
+ if [ "$want" = "latest" ] || [ -z "$want" ]; then
156
+ want="$(npm view "$ORACLE_NPM_PACKAGE" version --prefer-online 2>/dev/null || true)"
157
+ [ -n "$want" ] || die "could not resolve latest version of $ORACLE_NPM_PACKAGE (network/npm?)"
158
+ fi
159
+ ORACLE_RESOLVED_VERSION="$want"
160
+ log "target ${ORACLE_NPM_PACKAGE}@${ORACLE_RESOLVED_VERSION}"
161
+ }
162
+
163
+ install_package() {
164
+ mkdir -p "$PKG_DIR" "$BIN_DIR" "$SHARE_DIR"
165
+ # Isolated prefix install — no sudo, no global pollution
166
+ cat >"$PKG_DIR/package.json" <<EOF
167
+ {
168
+ "name": "oracle-user-install",
169
+ "private": true,
170
+ "description": "Oracle curl-install root (do not publish)"
171
+ }
172
+ EOF
173
+ log "installing into $PKG_DIR"
174
+ (
175
+ cd "$PKG_DIR"
176
+ npm install "${ORACLE_NPM_PACKAGE}@${ORACLE_RESOLVED_VERSION}" \
177
+ --no-fund \
178
+ --no-audit \
179
+ --prefer-online \
180
+ --loglevel=error
181
+ )
182
+
183
+ local oracle_bin=""
184
+ if [ -x "$PKG_DIR/node_modules/.bin/oracle" ]; then
185
+ oracle_bin="$PKG_DIR/node_modules/.bin/oracle"
186
+ elif [ -f "$PKG_DIR/node_modules/@oracle-agent/oracle/bin/oracle.mjs" ]; then
187
+ oracle_bin="$PKG_DIR/node_modules/@oracle-agent/oracle/bin/oracle.mjs"
188
+ else
189
+ die "install finished but oracle binary missing under $PKG_DIR"
190
+ fi
191
+
192
+ # Stable launcher in BIN_DIR
193
+ cat >"$BIN_DIR/oracle" <<EOF
194
+ #!/usr/bin/env bash
195
+ # Generated by oracle.demi.la/install.sh — do not edit; re-run installer to upgrade.
196
+ set -euo pipefail
197
+ export ORACLE_INSTALL_ROOT="$PKG_DIR"
198
+ exec "$oracle_bin" "\$@"
199
+ EOF
200
+ chmod 755 "$BIN_DIR/oracle"
201
+
202
+ # Convenience: also expose oracle-data-mcp if present
203
+ if [ -x "$PKG_DIR/node_modules/.bin/oracle-data-mcp" ]; then
204
+ cat >"$BIN_DIR/oracle-data-mcp" <<EOF
205
+ #!/usr/bin/env bash
206
+ set -euo pipefail
207
+ exec "$PKG_DIR/node_modules/.bin/oracle-data-mcp" "\$@"
208
+ EOF
209
+ chmod 755 "$BIN_DIR/oracle-data-mcp"
210
+ fi
211
+
212
+ # Record install metadata
213
+ cat >"$SHARE_DIR/install.json" <<EOF
214
+ {
215
+ "package": "${ORACLE_NPM_PACKAGE}",
216
+ "version": "${ORACLE_RESOLVED_VERSION}",
217
+ "prefix": "${PREFIX}",
218
+ "bin": "${BIN_DIR}/oracle",
219
+ "home": "${PKG_DIR}",
220
+ "installedAt": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
221
+ "method": "curl-install.sh"
222
+ }
223
+ EOF
224
+ }
225
+
226
+ path_hint() {
227
+ case ":$PATH:" in
228
+ *":$BIN_DIR:"*) return 0 ;;
229
+ esac
230
+ cat <<EOF
231
+
232
+ Add Oracle to your PATH (one-time):
233
+
234
+ # bash
235
+ echo 'export PATH="$BIN_DIR:\$PATH"' >> ~/.bashrc && source ~/.bashrc
236
+
237
+ # zsh
238
+ echo 'export PATH="$BIN_DIR:\$PATH"' >> ~/.zshrc && source ~/.zshrc
239
+
240
+ # fish
241
+ fish_add_path $BIN_DIR
242
+ EOF
243
+ }
244
+
245
+ verify() {
246
+ export PATH="$BIN_DIR:$PATH"
247
+ hash -r 2>/dev/null || true
248
+ if ! have oracle; then
249
+ die "oracle not on PATH after install. Expected $BIN_DIR/oracle"
250
+ fi
251
+ local ver
252
+ ver="$(oracle --version 2>/dev/null | head -1 || true)"
253
+ log "installed: ${ver:-oracle (version unknown)}"
254
+ if [ "$DO_DOCTOR" = 1 ]; then
255
+ oracle doctor 2>/dev/null | head -20 || true
256
+ fi
257
+ }
258
+
259
+ print_next() {
260
+ cat <<EOF
261
+
262
+ Oracle ready (prepare-only · your wallet signs).
263
+
264
+ oracle --version
265
+ oracle setup model
266
+ oracle chat
267
+ oracle doctor --agentic
268
+ oracle harness detect
269
+
270
+ Upgrade later:
271
+ curl -fsSL https://oracle.demi.la/install.sh | bash
272
+
273
+ Install root: $PKG_DIR
274
+ Binary: $BIN_DIR/oracle
275
+ EOF
276
+ path_hint
277
+ }
278
+
279
+ main() {
280
+ need_cmds
281
+ log "os=$OS arch=$ARCH"
282
+ log "prefix=$PREFIX home=$SHARE_DIR"
283
+ if [ "$PRINT_ONLY" = 1 ]; then
284
+ resolve_version
285
+ log "would install ${ORACLE_NPM_PACKAGE}@${ORACLE_RESOLVED_VERSION} → $PKG_DIR"
286
+ exit 0
287
+ fi
288
+ ensure_node
289
+ ensure_npm
290
+ resolve_version
291
+ install_package
292
+ verify
293
+ if [ "$DO_SETUP" = 1 ]; then
294
+ export PATH="$BIN_DIR:$PATH"
295
+ oracle setup model || true
296
+ fi
297
+ print_next
298
+ }
299
+
300
+ main