mirror of
https://github.com/clawdbot/clawdbot.git
synced 2026-01-31 11:27:45 +01:00
revert: Switch back to tsc for compiling.
This commit is contained in:
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -94,7 +94,7 @@ jobs:
|
||||
command: pnpm canvas:a2ui:bundle && bunx vitest run
|
||||
- runtime: bun
|
||||
task: build
|
||||
command: bunx tsdown
|
||||
command: bunx tsc -p tsconfig.json --noEmit false
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
@@ -36,4 +36,4 @@ ENV NODE_ENV=production
|
||||
# This reduces the attack surface by preventing container escape via root privileges
|
||||
USER node
|
||||
|
||||
CMD ["node", "dist/index.mjs"]
|
||||
CMD ["node", "dist/index.js"]
|
||||
|
||||
@@ -5,7 +5,7 @@ enum CommandResolver {
|
||||
private static let helperName = "openclaw"
|
||||
|
||||
static func gatewayEntrypoint(in root: URL) -> String? {
|
||||
let distEntry = root.appendingPathComponent("dist/index.mjs").path
|
||||
let distEntry = root.appendingPathComponent("dist/index.js").path
|
||||
if FileManager().isReadableFile(atPath: distEntry) { return distEntry }
|
||||
let openclawEntry = root.appendingPathComponent("openclaw.mjs").path
|
||||
if FileManager().isReadableFile(atPath: openclawEntry) { return openclawEntry }
|
||||
@@ -271,7 +271,7 @@ enum CommandResolver {
|
||||
}
|
||||
|
||||
let missingEntry = """
|
||||
openclaw entrypoint missing (looked for dist/index.mjs or openclaw.mjs); run pnpm build.
|
||||
openclaw entrypoint missing (looked for dist/index.js or openclaw.mjs); run pnpm build.
|
||||
"""
|
||||
return self.errorCommand(with: missingEntry)
|
||||
|
||||
@@ -360,10 +360,10 @@ enum CommandResolver {
|
||||
if command -v openclaw >/dev/null 2>&1; then
|
||||
CLI="$(command -v openclaw)"
|
||||
openclaw \(quotedArgs);
|
||||
elif [ -n "${PRJ:-}" ] && [ -f "$PRJ/dist/index.mjs" ]; then
|
||||
elif [ -n "${PRJ:-}" ] && [ -f "$PRJ/dist/index.js" ]; then
|
||||
if command -v node >/dev/null 2>&1; then
|
||||
CLI="node $PRJ/dist/index.mjs"
|
||||
node "$PRJ/dist/index.mjs" \(quotedArgs);
|
||||
CLI="node $PRJ/dist/index.js"
|
||||
node "$PRJ/dist/index.js" \(quotedArgs);
|
||||
else
|
||||
echo "Node >=22 required on remote host"; exit 127;
|
||||
fi
|
||||
|
||||
@@ -45,7 +45,7 @@ import Testing
|
||||
@Test func gatewayEntrypointPrefersDistOverBin() throws {
|
||||
let tmp = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
|
||||
.appendingPathComponent(UUID().uuidString, isDirectory: true)
|
||||
let dist = tmp.appendingPathComponent("dist/index.mjs")
|
||||
let dist = tmp.appendingPathComponent("dist/index.js")
|
||||
let bin = tmp.appendingPathComponent("bin/openclaw.js")
|
||||
try FileManager().createDirectory(at: dist.deletingLastPathComponent(), withIntermediateDirectories: true)
|
||||
try FileManager().createDirectory(at: bin.deletingLastPathComponent(), withIntermediateDirectories: true)
|
||||
|
||||
@@ -12,19 +12,19 @@ services:
|
||||
- ${OPENCLAW_CONFIG_DIR}:/home/node/.openclaw
|
||||
- ${OPENCLAW_WORKSPACE_DIR}:/home/node/.openclaw/workspace
|
||||
ports:
|
||||
- "${OPENCLAW_GATEWAY_PORT:-18789}:18789"
|
||||
- "${OPENCLAW_BRIDGE_PORT:-18790}:18790"
|
||||
- '${OPENCLAW_GATEWAY_PORT:-18789}:18789'
|
||||
- '${OPENCLAW_BRIDGE_PORT:-18790}:18790'
|
||||
init: true
|
||||
restart: unless-stopped
|
||||
command:
|
||||
[
|
||||
"node",
|
||||
"dist/index.mjs",
|
||||
"gateway",
|
||||
"--bind",
|
||||
"${OPENCLAW_GATEWAY_BIND:-lan}",
|
||||
"--port",
|
||||
"${OPENCLAW_GATEWAY_PORT:-18789}"
|
||||
'node',
|
||||
'dist/index.js',
|
||||
'gateway',
|
||||
'--bind',
|
||||
'${OPENCLAW_GATEWAY_BIND:-lan}',
|
||||
'--port',
|
||||
'${OPENCLAW_GATEWAY_PORT:-18789}',
|
||||
]
|
||||
|
||||
openclaw-cli:
|
||||
@@ -42,4 +42,4 @@ services:
|
||||
stdin_open: true
|
||||
tty: true
|
||||
init: true
|
||||
entrypoint: ["node", "dist/index.mjs"]
|
||||
entrypoint: ['node', 'dist/index.js']
|
||||
|
||||
@@ -211,4 +211,4 @@ echo "Token: $OPENCLAW_GATEWAY_TOKEN"
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
echo " ${COMPOSE_HINT} logs -f openclaw-gateway"
|
||||
echo " ${COMPOSE_HINT} exec openclaw-gateway node dist/index.mjs health --token \"$OPENCLAW_GATEWAY_TOKEN\""
|
||||
echo " ${COMPOSE_HINT} exec openclaw-gateway node dist/index.js health --token \"$OPENCLAW_GATEWAY_TOKEN\""
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
summary: "Optional Docker-based setup and onboarding for OpenClaw"
|
||||
summary: 'Optional Docker-based setup and onboarding for OpenClaw'
|
||||
read_when:
|
||||
- You want a containerized gateway instead of local installs
|
||||
- You are validating the Docker flow
|
||||
@@ -16,6 +16,7 @@ Docker is **optional**. Use it only if you want a containerized gateway or to va
|
||||
- **Sandboxing note**: agent sandboxing uses Docker too, but it does **not** require the full gateway to run in Docker. See [Sandboxing](/gateway/sandboxing).
|
||||
|
||||
This guide covers:
|
||||
|
||||
- Containerized Gateway (full OpenClaw in Docker)
|
||||
- Per-session Agent Sandbox (host gateway + Docker-isolated agent tools)
|
||||
|
||||
@@ -37,6 +38,7 @@ From repo root:
|
||||
```
|
||||
|
||||
This script:
|
||||
|
||||
- builds the gateway image
|
||||
- runs the onboarding wizard
|
||||
- prints optional provider setup hints
|
||||
@@ -44,15 +46,18 @@ This script:
|
||||
- generates a gateway token and writes it to `.env`
|
||||
|
||||
Optional env vars:
|
||||
|
||||
- `OPENCLAW_DOCKER_APT_PACKAGES` — install extra apt packages during build
|
||||
- `OPENCLAW_EXTRA_MOUNTS` — add extra host bind mounts
|
||||
- `OPENCLAW_HOME_VOLUME` — persist `/home/node` in a named volume
|
||||
|
||||
After it finishes:
|
||||
|
||||
- Open `http://127.0.0.1:18789/` in your browser.
|
||||
- Paste the token into the Control UI (Settings → token).
|
||||
|
||||
It writes config/workspace on the host:
|
||||
|
||||
- `~/.openclaw/`
|
||||
- `~/.openclaw/workspace`
|
||||
|
||||
@@ -81,6 +86,7 @@ export OPENCLAW_EXTRA_MOUNTS="$HOME/.codex:/home/node/.codex:ro,$HOME/github:/ho
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- Paths must be shared with Docker Desktop on macOS/Windows.
|
||||
- If you edit `OPENCLAW_EXTRA_MOUNTS`, rerun `docker-setup.sh` to regenerate the
|
||||
extra compose file.
|
||||
@@ -110,6 +116,7 @@ export OPENCLAW_EXTRA_MOUNTS="$HOME/.codex:/home/node/.codex:ro,$HOME/github:/ho
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- If you change `OPENCLAW_HOME_VOLUME`, rerun `docker-setup.sh` to regenerate the
|
||||
extra compose file.
|
||||
- The named volume persists until removed with `docker volume rm <name>`.
|
||||
@@ -129,6 +136,7 @@ export OPENCLAW_DOCKER_APT_PACKAGES="ffmpeg build-essential"
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- This accepts a space-separated list of apt package names.
|
||||
- If you change `OPENCLAW_DOCKER_APT_PACKAGES`, rerun `docker-setup.sh` to rebuild
|
||||
the image.
|
||||
@@ -163,7 +171,7 @@ RUN pnpm ui:build
|
||||
|
||||
ENV NODE_ENV=production
|
||||
|
||||
CMD ["node","dist/index.mjs"]
|
||||
CMD ["node","dist/index.js"]
|
||||
```
|
||||
|
||||
### Channel setup (optional)
|
||||
@@ -171,16 +179,19 @@ CMD ["node","dist/index.mjs"]
|
||||
Use the CLI container to configure channels, then restart the gateway if needed.
|
||||
|
||||
WhatsApp (QR):
|
||||
|
||||
```bash
|
||||
docker compose run --rm openclaw-cli channels login
|
||||
```
|
||||
|
||||
Telegram (bot token):
|
||||
|
||||
```bash
|
||||
docker compose run --rm openclaw-cli channels add --channel telegram --token "<token>"
|
||||
```
|
||||
|
||||
Discord (bot token):
|
||||
|
||||
```bash
|
||||
docker compose run --rm openclaw-cli channels add --channel discord --token "<token>"
|
||||
```
|
||||
@@ -190,7 +201,7 @@ Docs: [WhatsApp](/channels/whatsapp), [Telegram](/channels/telegram), [Discord](
|
||||
### Health check
|
||||
|
||||
```bash
|
||||
docker compose exec openclaw-gateway node dist/index.mjs health --token "$OPENCLAW_GATEWAY_TOKEN"
|
||||
docker compose exec openclaw-gateway node dist/index.js health --token "$OPENCLAW_GATEWAY_TOKEN"
|
||||
```
|
||||
|
||||
### E2E smoke test (Docker)
|
||||
@@ -218,6 +229,7 @@ Deep dive: [Sandboxing](/gateway/sandboxing)
|
||||
|
||||
When `agents.defaults.sandbox` is enabled, **non-main sessions** run tools inside a Docker
|
||||
container. The gateway stays on your host, but the tool execution is isolated:
|
||||
|
||||
- scope: `"agent"` by default (one container + workspace per agent)
|
||||
- scope: `"session"` for per-session isolation
|
||||
- per-scope workspace folder mounted at `/workspace`
|
||||
@@ -233,6 +245,7 @@ one container and one workspace.
|
||||
If you use multi-agent routing, each agent can override sandbox + tool settings:
|
||||
`agents.list[].sandbox` and `agents.list[].tools` (plus `agents.list[].tools.sandbox.tools`). This lets you run
|
||||
mixed access levels in one gateway:
|
||||
|
||||
- Full access (personal agent)
|
||||
- Read-only tools + read-only workspace (family/work agent)
|
||||
- No filesystem/shell tools (public agent)
|
||||
@@ -255,60 +268,72 @@ precedence, and troubleshooting.
|
||||
### Enable sandboxing
|
||||
|
||||
If you plan to install packages in `setupCommand`, note:
|
||||
|
||||
- Default `docker.network` is `"none"` (no egress).
|
||||
- `readOnlyRoot: true` blocks package installs.
|
||||
- `user` must be root for `apt-get` (omit `user` or set `user: "0:0"`).
|
||||
OpenClaw auto-recreates containers when `setupCommand` (or docker config) changes
|
||||
unless the container was **recently used** (within ~5 minutes). Hot containers
|
||||
log a warning with the exact `openclaw sandbox recreate ...` command.
|
||||
OpenClaw auto-recreates containers when `setupCommand` (or docker config) changes
|
||||
unless the container was **recently used** (within ~5 minutes). Hot containers
|
||||
log a warning with the exact `openclaw sandbox recreate ...` command.
|
||||
|
||||
```json5
|
||||
{
|
||||
agents: {
|
||||
defaults: {
|
||||
sandbox: {
|
||||
mode: "non-main", // off | non-main | all
|
||||
scope: "agent", // session | agent | shared (agent is default)
|
||||
workspaceAccess: "none", // none | ro | rw
|
||||
workspaceRoot: "~/.openclaw/sandboxes",
|
||||
mode: 'non-main', // off | non-main | all
|
||||
scope: 'agent', // session | agent | shared (agent is default)
|
||||
workspaceAccess: 'none', // none | ro | rw
|
||||
workspaceRoot: '~/.openclaw/sandboxes',
|
||||
docker: {
|
||||
image: "openclaw-sandbox:bookworm-slim",
|
||||
workdir: "/workspace",
|
||||
image: 'openclaw-sandbox:bookworm-slim',
|
||||
workdir: '/workspace',
|
||||
readOnlyRoot: true,
|
||||
tmpfs: ["/tmp", "/var/tmp", "/run"],
|
||||
network: "none",
|
||||
user: "1000:1000",
|
||||
capDrop: ["ALL"],
|
||||
env: { LANG: "C.UTF-8" },
|
||||
setupCommand: "apt-get update && apt-get install -y git curl jq",
|
||||
tmpfs: ['/tmp', '/var/tmp', '/run'],
|
||||
network: 'none',
|
||||
user: '1000:1000',
|
||||
capDrop: ['ALL'],
|
||||
env: { LANG: 'C.UTF-8' },
|
||||
setupCommand: 'apt-get update && apt-get install -y git curl jq',
|
||||
pidsLimit: 256,
|
||||
memory: "1g",
|
||||
memorySwap: "2g",
|
||||
memory: '1g',
|
||||
memorySwap: '2g',
|
||||
cpus: 1,
|
||||
ulimits: {
|
||||
nofile: { soft: 1024, hard: 2048 },
|
||||
nproc: 256
|
||||
nproc: 256,
|
||||
},
|
||||
seccompProfile: "/path/to/seccomp.json",
|
||||
apparmorProfile: "openclaw-sandbox",
|
||||
dns: ["1.1.1.1", "8.8.8.8"],
|
||||
extraHosts: ["internal.service:10.0.0.5"]
|
||||
seccompProfile: '/path/to/seccomp.json',
|
||||
apparmorProfile: 'openclaw-sandbox',
|
||||
dns: ['1.1.1.1', '8.8.8.8'],
|
||||
extraHosts: ['internal.service:10.0.0.5'],
|
||||
},
|
||||
prune: {
|
||||
idleHours: 24, // 0 disables idle pruning
|
||||
maxAgeDays: 7 // 0 disables max-age pruning
|
||||
}
|
||||
}
|
||||
}
|
||||
maxAgeDays: 7, // 0 disables max-age pruning
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
tools: {
|
||||
sandbox: {
|
||||
tools: {
|
||||
allow: ["exec", "process", "read", "write", "edit", "sessions_list", "sessions_history", "sessions_send", "sessions_spawn", "session_status"],
|
||||
deny: ["browser", "canvas", "nodes", "cron", "discord", "gateway"]
|
||||
}
|
||||
}
|
||||
}
|
||||
allow: [
|
||||
'exec',
|
||||
'process',
|
||||
'read',
|
||||
'write',
|
||||
'edit',
|
||||
'sessions_list',
|
||||
'sessions_history',
|
||||
'sessions_send',
|
||||
'sessions_spawn',
|
||||
'session_status',
|
||||
],
|
||||
deny: ['browser', 'canvas', 'nodes', 'cron', 'discord', 'gateway'],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
@@ -328,6 +353,7 @@ scripts/sandbox-setup.sh
|
||||
This builds `openclaw-sandbox:bookworm-slim` using `Dockerfile.sandbox`.
|
||||
|
||||
### Sandbox common image (optional)
|
||||
|
||||
If you want a sandbox image with common build tooling (Node, Go, Rust, etc.), build the common image:
|
||||
|
||||
```bash
|
||||
@@ -338,7 +364,11 @@ This builds `openclaw-sandbox-common:bookworm-slim`. To use it:
|
||||
|
||||
```json5
|
||||
{
|
||||
agents: { defaults: { sandbox: { docker: { image: "openclaw-sandbox-common:bookworm-slim" } } } }
|
||||
agents: {
|
||||
defaults: {
|
||||
sandbox: { docker: { image: 'openclaw-sandbox-common:bookworm-slim' } },
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
@@ -355,6 +385,7 @@ This builds `openclaw-sandbox-browser:bookworm-slim` using
|
||||
an optional noVNC observer (headful via Xvfb).
|
||||
|
||||
Notes:
|
||||
|
||||
- Headful (Xvfb) reduces bot blocking vs headless.
|
||||
- Headless can still be used by setting `agents.defaults.sandbox.browser.headless=true`.
|
||||
- No full desktop environment (GNOME) is needed; Xvfb provides the display.
|
||||
@@ -366,10 +397,10 @@ Use config:
|
||||
agents: {
|
||||
defaults: {
|
||||
sandbox: {
|
||||
browser: { enabled: true }
|
||||
}
|
||||
}
|
||||
}
|
||||
browser: { enabled: true },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
@@ -379,13 +410,14 @@ Custom browser image:
|
||||
{
|
||||
agents: {
|
||||
defaults: {
|
||||
sandbox: { browser: { image: "my-openclaw-browser" } }
|
||||
}
|
||||
}
|
||||
sandbox: { browser: { image: 'my-openclaw-browser' } },
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
When enabled, the agent receives:
|
||||
|
||||
- a sandbox browser control URL (for the `browser` tool)
|
||||
- a noVNC URL (if enabled and headless=false)
|
||||
|
||||
@@ -405,9 +437,9 @@ docker build -t my-openclaw-sbx -f Dockerfile.sandbox .
|
||||
{
|
||||
agents: {
|
||||
defaults: {
|
||||
sandbox: { docker: { image: "my-openclaw-sbx" } }
|
||||
}
|
||||
}
|
||||
sandbox: { docker: { image: 'my-openclaw-sbx' } },
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
@@ -420,10 +452,12 @@ docker build -t my-openclaw-sbx -f Dockerfile.sandbox .
|
||||
### Pruning strategy
|
||||
|
||||
Two knobs:
|
||||
|
||||
- `prune.idleHours`: remove containers not used in X hours (0 = disable)
|
||||
- `prune.maxAgeDays`: remove containers older than X days (0 = disable)
|
||||
|
||||
Example:
|
||||
|
||||
- Keep busy sessions but cap lifetime:
|
||||
`idleHours: 24`, `maxAgeDays: 7`
|
||||
- Never prune:
|
||||
@@ -431,8 +465,8 @@ Example:
|
||||
|
||||
### Security notes
|
||||
|
||||
- Hard wall only applies to **tools** (exec/read/write/edit/apply_patch).
|
||||
- Host-only tools like browser/camera/canvas are blocked by default.
|
||||
- Hard wall only applies to **tools** (exec/read/write/edit/apply_patch).
|
||||
- Host-only tools like browser/camera/canvas are blocked by default.
|
||||
- Allowing `browser` in sandbox **breaks isolation** (browser runs on host).
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
@@ -57,7 +57,7 @@ primary_region = "iad"
|
||||
NODE_OPTIONS = "--max-old-space-size=1536"
|
||||
|
||||
[processes]
|
||||
app = "node dist/index.mjs gateway --allow-unconfigured --port 3000 --bind lan"
|
||||
app = "node dist/index.js gateway --allow-unconfigured --port 3000 --bind lan"
|
||||
|
||||
[http_service]
|
||||
internal_port = 3000
|
||||
@@ -78,13 +78,13 @@ primary_region = "iad"
|
||||
|
||||
**Key settings:**
|
||||
|
||||
| Setting | Why |
|
||||
|---------|-----|
|
||||
| `--bind lan` | Binds to `0.0.0.0` so Fly's proxy can reach the gateway |
|
||||
| `--allow-unconfigured` | Starts without a config file (you'll create one after) |
|
||||
| `internal_port = 3000` | Must match `--port 3000` (or `OPENCLAW_GATEWAY_PORT`) for Fly health checks |
|
||||
| `memory = "2048mb"` | 512MB is too small; 2GB recommended |
|
||||
| `OPENCLAW_STATE_DIR = "/data"` | Persists state on the volume |
|
||||
| Setting | Why |
|
||||
| ------------------------------ | --------------------------------------------------------------------------- |
|
||||
| `--bind lan` | Binds to `0.0.0.0` so Fly's proxy can reach the gateway |
|
||||
| `--allow-unconfigured` | Starts without a config file (you'll create one after) |
|
||||
| `internal_port = 3000` | Must match `--port 3000` (or `OPENCLAW_GATEWAY_PORT`) for Fly health checks |
|
||||
| `memory = "2048mb"` | 512MB is too small; 2GB recommended |
|
||||
| `OPENCLAW_STATE_DIR = "/data"` | Persists state on the volume |
|
||||
|
||||
## 3) Set secrets
|
||||
|
||||
@@ -104,6 +104,7 @@ fly secrets set DISCORD_BOT_TOKEN=MTQ...
|
||||
```
|
||||
|
||||
**Notes:**
|
||||
|
||||
- Non-loopback binds (`--bind lan`) require `OPENCLAW_GATEWAY_TOKEN` for security.
|
||||
- Treat these tokens like passwords.
|
||||
- **Prefer env vars over config file** for all API keys and tokens. This keeps secrets out of `openclaw.json` where they could be accidentally exposed or logged.
|
||||
@@ -117,12 +118,14 @@ fly deploy
|
||||
First deploy builds the Docker image (~2-3 minutes). Subsequent deploys are faster.
|
||||
|
||||
After deployment, verify:
|
||||
|
||||
```bash
|
||||
fly status
|
||||
fly logs
|
||||
```
|
||||
|
||||
You should see:
|
||||
|
||||
```
|
||||
[gateway] listening on ws://0.0.0.0:3000 (PID xxx)
|
||||
[discord] logged in to discord as xxx
|
||||
@@ -137,6 +140,7 @@ fly ssh console
|
||||
```
|
||||
|
||||
Create the config directory and file:
|
||||
|
||||
```bash
|
||||
mkdir -p /data
|
||||
cat > /data/openclaw.json << 'EOF'
|
||||
@@ -194,12 +198,14 @@ EOF
|
||||
**Note:** With `OPENCLAW_STATE_DIR=/data`, the config path is `/data/openclaw.json`.
|
||||
|
||||
**Note:** The Discord token can come from either:
|
||||
|
||||
- Environment variable: `DISCORD_BOT_TOKEN` (recommended for secrets)
|
||||
- Config file: `channels.discord.token`
|
||||
|
||||
If using env var, no need to add token to config. The gateway reads `DISCORD_BOT_TOKEN` automatically.
|
||||
|
||||
Restart to apply:
|
||||
|
||||
```bash
|
||||
exit
|
||||
fly machine restart <machine-id>
|
||||
@@ -210,6 +216,7 @@ fly machine restart <machine-id>
|
||||
### Control UI
|
||||
|
||||
Open in browser:
|
||||
|
||||
```bash
|
||||
fly open
|
||||
```
|
||||
@@ -250,12 +257,14 @@ Fly can't reach the gateway on the configured port.
|
||||
Container keeps restarting or getting killed. Signs: `SIGABRT`, `v8::internal::Runtime_AllocateInYoungGeneration`, or silent restarts.
|
||||
|
||||
**Fix:** Increase memory in `fly.toml`:
|
||||
|
||||
```toml
|
||||
[[vm]]
|
||||
memory = "2048mb"
|
||||
```
|
||||
|
||||
Or update an existing machine:
|
||||
|
||||
```bash
|
||||
fly machine update <machine-id> --vm-memory 2048 -y
|
||||
```
|
||||
@@ -269,6 +278,7 @@ Gateway refuses to start with "already running" errors.
|
||||
This happens when the container restarts but the PID lock file persists on the volume.
|
||||
|
||||
**Fix:** Delete the lock file:
|
||||
|
||||
```bash
|
||||
fly ssh console --command "rm -f /data/gateway.*.lock"
|
||||
fly machine restart <machine-id>
|
||||
@@ -281,6 +291,7 @@ The lock file is at `/data/gateway.*.lock` (not in a subdirectory).
|
||||
If using `--allow-unconfigured`, the gateway creates a minimal config. Your custom config at `/data/openclaw.json` should be read on restart.
|
||||
|
||||
Verify the config exists:
|
||||
|
||||
```bash
|
||||
fly ssh console --command "cat /data/openclaw.json"
|
||||
```
|
||||
@@ -299,6 +310,7 @@ fly sftp shell
|
||||
```
|
||||
|
||||
**Note:** `fly sftp` may fail if the file already exists. Delete first:
|
||||
|
||||
```bash
|
||||
fly ssh console --command "rm /data/openclaw.json"
|
||||
```
|
||||
@@ -332,10 +344,10 @@ If you need to change the startup command without a full redeploy:
|
||||
fly machines list
|
||||
|
||||
# Update command
|
||||
fly machine update <machine-id> --command "node dist/index.mjs gateway --port 3000 --bind lan" -y
|
||||
fly machine update <machine-id> --command "node dist/index.js gateway --port 3000 --bind lan" -y
|
||||
|
||||
# Or with memory increase
|
||||
fly machine update <machine-id> --vm-memory 2048 --command "node dist/index.mjs gateway --port 3000 --bind lan" -y
|
||||
fly machine update <machine-id> --vm-memory 2048 --command "node dist/index.js gateway --port 3000 --bind lan" -y
|
||||
```
|
||||
|
||||
**Note:** After `fly deploy`, the machine command may reset to what's in `fly.toml`. If you made manual changes, re-apply them after deploy.
|
||||
@@ -381,6 +393,7 @@ fly ips allocate-v6 --private -a my-openclaw
|
||||
```
|
||||
|
||||
After this, `fly ips list` should show only a `private` type IP:
|
||||
|
||||
```
|
||||
VERSION IP TYPE REGION
|
||||
v6 fdaa:x:x:x:x::x private global
|
||||
@@ -391,6 +404,7 @@ v6 fdaa:x:x:x:x::x private global
|
||||
Since there's no public URL, use one of these methods:
|
||||
|
||||
**Option 1: Local proxy (simplest)**
|
||||
|
||||
```bash
|
||||
# Forward local port 3000 to the app
|
||||
fly proxy 3000:3000 -a my-openclaw
|
||||
@@ -399,6 +413,7 @@ fly proxy 3000:3000 -a my-openclaw
|
||||
```
|
||||
|
||||
**Option 2: WireGuard VPN**
|
||||
|
||||
```bash
|
||||
# Create WireGuard config (one-time)
|
||||
fly wireguard create
|
||||
@@ -408,6 +423,7 @@ fly wireguard create
|
||||
```
|
||||
|
||||
**Option 3: SSH only**
|
||||
|
||||
```bash
|
||||
fly ssh console -a my-openclaw
|
||||
```
|
||||
@@ -421,6 +437,7 @@ If you need webhook callbacks (Twilio, Telnyx, etc.) without public exposure:
|
||||
3. **Outbound-only** - Some providers (Twilio) work fine for outbound calls without webhooks
|
||||
|
||||
Example voice-call config with ngrok:
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": {
|
||||
@@ -441,12 +458,12 @@ The ngrok tunnel runs inside the container and provides a public webhook URL wit
|
||||
|
||||
### Security benefits
|
||||
|
||||
| Aspect | Public | Private |
|
||||
|--------|--------|---------|
|
||||
| Internet scanners | Discoverable | Hidden |
|
||||
| Direct attacks | Possible | Blocked |
|
||||
| Control UI access | Browser | Proxy/VPN |
|
||||
| Webhook delivery | Direct | Via tunnel |
|
||||
| Aspect | Public | Private |
|
||||
| ----------------- | ------------ | ---------- |
|
||||
| Internet scanners | Discoverable | Hidden |
|
||||
| Direct attacks | Possible | Blocked |
|
||||
| Control UI access | Browser | Proxy/VPN |
|
||||
| Webhook delivery | Direct | Via tunnel |
|
||||
|
||||
## Notes
|
||||
|
||||
@@ -459,6 +476,7 @@ The ngrok tunnel runs inside the container and provides a public webhook URL wit
|
||||
## Cost
|
||||
|
||||
With the recommended config (`shared-cpu-2x`, 2GB RAM):
|
||||
|
||||
- ~$10-15/month depending on usage
|
||||
- Free tier includes some allowance
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
summary: "Run OpenClaw Gateway 24/7 on a GCP Compute Engine VM (Docker) with durable state"
|
||||
summary: 'Run OpenClaw Gateway 24/7 on a GCP Compute Engine VM (Docker) with durable state'
|
||||
read_when:
|
||||
- You want OpenClaw running 24/7 on GCP
|
||||
- You want a production-grade, always-on Gateway on your own VM
|
||||
@@ -25,6 +25,7 @@ Pricing varies by machine type and region; pick the smallest VM that fits your w
|
||||
- Access the Control UI from your laptop via an SSH tunnel
|
||||
|
||||
The Gateway can be accessed via:
|
||||
|
||||
- SSH port forwarding from your laptop
|
||||
- Direct port exposure if you manage firewalling and tokens yourself
|
||||
|
||||
@@ -36,14 +37,14 @@ For the generic Docker flow, see [Docker](/install/docker).
|
||||
|
||||
## Quick path (experienced operators)
|
||||
|
||||
1) Create GCP project + enable Compute Engine API
|
||||
2) Create Compute Engine VM (e2-small, Debian 12, 20GB)
|
||||
3) SSH into the VM
|
||||
4) Install Docker
|
||||
5) Clone OpenClaw repository
|
||||
6) Create persistent host directories
|
||||
7) Configure `.env` and `docker-compose.yml`
|
||||
8) Bake required binaries, build, and launch
|
||||
1. Create GCP project + enable Compute Engine API
|
||||
2. Create Compute Engine VM (e2-small, Debian 12, 20GB)
|
||||
3. SSH into the VM
|
||||
4. Install Docker
|
||||
5. Clone OpenClaw repository
|
||||
6. Create persistent host directories
|
||||
7. Configure `.env` and `docker-compose.yml`
|
||||
8. Bake required binaries, build, and launch
|
||||
|
||||
---
|
||||
|
||||
@@ -112,9 +113,9 @@ gcloud services enable compute.googleapis.com
|
||||
|
||||
**Machine types:**
|
||||
|
||||
| Type | Specs | Cost | Notes |
|
||||
|------|-------|------|-------|
|
||||
| e2-small | 2 vCPU, 2GB RAM | ~$12/mo | Recommended |
|
||||
| Type | Specs | Cost | Notes |
|
||||
| -------- | ------------------------ | ------------------ | ------------------ |
|
||||
| e2-small | 2 vCPU, 2GB RAM | ~$12/mo | Recommended |
|
||||
| e2-micro | 2 vCPU (shared), 1GB RAM | Free tier eligible | May OOM under load |
|
||||
|
||||
**CLI:**
|
||||
@@ -263,20 +264,20 @@ services:
|
||||
ports:
|
||||
# Recommended: keep the Gateway loopback-only on the VM; access via SSH tunnel.
|
||||
# To expose it publicly, remove the `127.0.0.1:` prefix and firewall accordingly.
|
||||
- "127.0.0.1:${OPENCLAW_GATEWAY_PORT}:18789"
|
||||
- '127.0.0.1:${OPENCLAW_GATEWAY_PORT}:18789'
|
||||
|
||||
# Optional: only if you run iOS/Android nodes against this VM and need Canvas host.
|
||||
# If you expose this publicly, read /gateway/security and firewall accordingly.
|
||||
# - "18793:18793"
|
||||
command:
|
||||
[
|
||||
"node",
|
||||
"dist/index.mjs",
|
||||
"gateway",
|
||||
"--bind",
|
||||
"${OPENCLAW_GATEWAY_BIND}",
|
||||
"--port",
|
||||
"${OPENCLAW_GATEWAY_PORT}"
|
||||
'node',
|
||||
'dist/index.js',
|
||||
'gateway',
|
||||
'--bind',
|
||||
'${OPENCLAW_GATEWAY_BIND}',
|
||||
'--port',
|
||||
'${OPENCLAW_GATEWAY_PORT}',
|
||||
]
|
||||
```
|
||||
|
||||
@@ -290,6 +291,7 @@ Anything installed at runtime will be lost on restart.
|
||||
All external binaries required by skills must be installed at image build time.
|
||||
|
||||
The examples below show three common binaries only:
|
||||
|
||||
- `gog` for Gmail access
|
||||
- `goplaces` for Google Places
|
||||
- `wacli` for WhatsApp
|
||||
@@ -298,6 +300,7 @@ These are examples, not a complete list.
|
||||
You may install as many binaries as needed using the same pattern.
|
||||
|
||||
If you add new skills later that depend on additional binaries, you must:
|
||||
|
||||
1. Update the Dockerfile
|
||||
2. Rebuild the image
|
||||
3. Restart the containers
|
||||
@@ -338,7 +341,7 @@ RUN pnpm ui:build
|
||||
|
||||
ENV NODE_ENV=production
|
||||
|
||||
CMD ["node","dist/index.mjs"]
|
||||
CMD ["node","dist/index.js"]
|
||||
```
|
||||
|
||||
---
|
||||
@@ -403,18 +406,18 @@ Paste your gateway token.
|
||||
OpenClaw runs in Docker, but Docker is not the source of truth.
|
||||
All long-lived state must survive restarts, rebuilds, and reboots.
|
||||
|
||||
| Component | Location | Persistence mechanism | Notes |
|
||||
|---|---|---|---|
|
||||
| Gateway config | `/home/node/.openclaw/` | Host volume mount | Includes `openclaw.json`, tokens |
|
||||
| Model auth profiles | `/home/node/.openclaw/` | Host volume mount | OAuth tokens, API keys |
|
||||
| Skill configs | `/home/node/.openclaw/skills/` | Host volume mount | Skill-level state |
|
||||
| Agent workspace | `/home/node/.openclaw/workspace/` | Host volume mount | Code and agent artifacts |
|
||||
| WhatsApp session | `/home/node/.openclaw/` | Host volume mount | Preserves QR login |
|
||||
| Gmail keyring | `/home/node/.openclaw/` | Host volume + password | Requires `GOG_KEYRING_PASSWORD` |
|
||||
| External binaries | `/usr/local/bin/` | Docker image | Must be baked at build time |
|
||||
| Node runtime | Container filesystem | Docker image | Rebuilt every image build |
|
||||
| OS packages | Container filesystem | Docker image | Do not install at runtime |
|
||||
| Docker container | Ephemeral | Restartable | Safe to destroy |
|
||||
| Component | Location | Persistence mechanism | Notes |
|
||||
| ------------------- | --------------------------------- | ---------------------- | -------------------------------- |
|
||||
| Gateway config | `/home/node/.openclaw/` | Host volume mount | Includes `openclaw.json`, tokens |
|
||||
| Model auth profiles | `/home/node/.openclaw/` | Host volume mount | OAuth tokens, API keys |
|
||||
| Skill configs | `/home/node/.openclaw/skills/` | Host volume mount | Skill-level state |
|
||||
| Agent workspace | `/home/node/.openclaw/workspace/` | Host volume mount | Code and agent artifacts |
|
||||
| WhatsApp session | `/home/node/.openclaw/` | Host volume mount | Preserves QR login |
|
||||
| Gmail keyring | `/home/node/.openclaw/` | Host volume + password | Requires `GOG_KEYRING_PASSWORD` |
|
||||
| External binaries | `/usr/local/bin/` | Docker image | Must be baked at build time |
|
||||
| Node runtime | Container filesystem | Docker image | Rebuilt every image build |
|
||||
| OS packages | Container filesystem | Docker image | Do not install at runtime |
|
||||
| Docker container | Ephemeral | Restartable | Safe to destroy |
|
||||
|
||||
---
|
||||
|
||||
@@ -473,6 +476,7 @@ For personal use, your default user account works fine.
|
||||
For automation or CI/CD pipelines, create a dedicated service account with minimal permissions:
|
||||
|
||||
1. Create a service account:
|
||||
|
||||
```bash
|
||||
gcloud iam service-accounts create openclaw-deploy \
|
||||
--display-name="OpenClaw Deployment"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
summary: "Run OpenClaw Gateway 24/7 on a cheap Hetzner VPS (Docker) with durable state and baked-in binaries"
|
||||
summary: 'Run OpenClaw Gateway 24/7 on a cheap Hetzner VPS (Docker) with durable state and baked-in binaries'
|
||||
read_when:
|
||||
- You want OpenClaw running 24/7 on a cloud VPS (not your laptop)
|
||||
- You want a production-grade, always-on Gateway on your own VPS
|
||||
@@ -10,6 +10,7 @@ read_when:
|
||||
# OpenClaw on Hetzner (Docker, Production VPS Guide)
|
||||
|
||||
## Goal
|
||||
|
||||
Run a persistent OpenClaw Gateway on a Hetzner VPS using Docker, with durable state, baked-in binaries, and safe restart behavior.
|
||||
|
||||
If you want “OpenClaw 24/7 for ~$5”, this is the simplest reliable setup.
|
||||
@@ -24,6 +25,7 @@ Hetzner pricing changes; pick the smallest Debian/Ubuntu VPS and scale up if you
|
||||
- Access the Control UI from your laptop via an SSH tunnel
|
||||
|
||||
The Gateway can be accessed via:
|
||||
|
||||
- SSH port forwarding from your laptop
|
||||
- Direct port exposure if you manage firewalling and tokens yourself
|
||||
|
||||
@@ -35,29 +37,29 @@ For the generic Docker flow, see [Docker](/install/docker).
|
||||
|
||||
## Quick path (experienced operators)
|
||||
|
||||
1) Provision Hetzner VPS
|
||||
2) Install Docker
|
||||
3) Clone OpenClaw repository
|
||||
4) Create persistent host directories
|
||||
5) Configure `.env` and `docker-compose.yml`
|
||||
6) Bake required binaries into the image
|
||||
7) `docker compose up -d`
|
||||
8) Verify persistence and Gateway access
|
||||
1. Provision Hetzner VPS
|
||||
2. Install Docker
|
||||
3. Clone OpenClaw repository
|
||||
4. Create persistent host directories
|
||||
5. Configure `.env` and `docker-compose.yml`
|
||||
6. Bake required binaries into the image
|
||||
7. `docker compose up -d`
|
||||
8. Verify persistence and Gateway access
|
||||
|
||||
---
|
||||
|
||||
## What you need
|
||||
|
||||
- Hetzner VPS with root access
|
||||
- SSH access from your laptop
|
||||
- Basic comfort with SSH + copy/paste
|
||||
- ~20 minutes
|
||||
- Docker and Docker Compose
|
||||
- Model auth credentials
|
||||
- Optional provider credentials
|
||||
- WhatsApp QR
|
||||
- Telegram bot token
|
||||
- Gmail OAuth
|
||||
- Hetzner VPS with root access
|
||||
- SSH access from your laptop
|
||||
- Basic comfort with SSH + copy/paste
|
||||
- ~20 minutes
|
||||
- Docker and Docker Compose
|
||||
- Model auth credentials
|
||||
- Optional provider credentials
|
||||
- WhatsApp QR
|
||||
- Telegram bot token
|
||||
- Gmail OAuth
|
||||
|
||||
---
|
||||
|
||||
@@ -175,20 +177,20 @@ services:
|
||||
ports:
|
||||
# Recommended: keep the Gateway loopback-only on the VPS; access via SSH tunnel.
|
||||
# To expose it publicly, remove the `127.0.0.1:` prefix and firewall accordingly.
|
||||
- "127.0.0.1:${OPENCLAW_GATEWAY_PORT}:18789"
|
||||
- '127.0.0.1:${OPENCLAW_GATEWAY_PORT}:18789'
|
||||
|
||||
# Optional: only if you run iOS/Android nodes against this VPS and need Canvas host.
|
||||
# If you expose this publicly, read /gateway/security and firewall accordingly.
|
||||
# - "18793:18793"
|
||||
command:
|
||||
[
|
||||
"node",
|
||||
"dist/index.mjs",
|
||||
"gateway",
|
||||
"--bind",
|
||||
"${OPENCLAW_GATEWAY_BIND}",
|
||||
"--port",
|
||||
"${OPENCLAW_GATEWAY_PORT}"
|
||||
'node',
|
||||
'dist/index.js',
|
||||
'gateway',
|
||||
'--bind',
|
||||
'${OPENCLAW_GATEWAY_BIND}',
|
||||
'--port',
|
||||
'${OPENCLAW_GATEWAY_PORT}',
|
||||
]
|
||||
```
|
||||
|
||||
@@ -202,6 +204,7 @@ Anything installed at runtime will be lost on restart.
|
||||
All external binaries required by skills must be installed at image build time.
|
||||
|
||||
The examples below show three common binaries only:
|
||||
|
||||
- `gog` for Gmail access
|
||||
- `goplaces` for Google Places
|
||||
- `wacli` for WhatsApp
|
||||
@@ -210,6 +213,7 @@ These are examples, not a complete list.
|
||||
You may install as many binaries as needed using the same pattern.
|
||||
|
||||
If you add new skills later that depend on additional binaries, you must:
|
||||
|
||||
1. Update the Dockerfile
|
||||
2. Rebuild the image
|
||||
3. Restart the containers
|
||||
@@ -250,7 +254,7 @@ RUN pnpm ui:build
|
||||
|
||||
ENV NODE_ENV=production
|
||||
|
||||
CMD ["node","dist/index.mjs"]
|
||||
CMD ["node","dist/index.js"]
|
||||
```
|
||||
|
||||
---
|
||||
@@ -311,15 +315,15 @@ Paste your gateway token.
|
||||
OpenClaw runs in Docker, but Docker is not the source of truth.
|
||||
All long-lived state must survive restarts, rebuilds, and reboots.
|
||||
|
||||
| Component | Location | Persistence mechanism | Notes |
|
||||
|---|---|---|---|
|
||||
| Gateway config | `/home/node/.openclaw/` | Host volume mount | Includes `openclaw.json`, tokens |
|
||||
| Model auth profiles | `/home/node/.openclaw/` | Host volume mount | OAuth tokens, API keys |
|
||||
| Skill configs | `/home/node/.openclaw/skills/` | Host volume mount | Skill-level state |
|
||||
| Agent workspace | `/home/node/.openclaw/workspace/` | Host volume mount | Code and agent artifacts |
|
||||
| WhatsApp session | `/home/node/.openclaw/` | Host volume mount | Preserves QR login |
|
||||
| Gmail keyring | `/home/node/.openclaw/` | Host volume + password | Requires `GOG_KEYRING_PASSWORD` |
|
||||
| External binaries | `/usr/local/bin/` | Docker image | Must be baked at build time |
|
||||
| Node runtime | Container filesystem | Docker image | Rebuilt every image build |
|
||||
| OS packages | Container filesystem | Docker image | Do not install at runtime |
|
||||
| Docker container | Ephemeral | Restartable | Safe to destroy |
|
||||
| Component | Location | Persistence mechanism | Notes |
|
||||
| ------------------- | --------------------------------- | ---------------------- | -------------------------------- |
|
||||
| Gateway config | `/home/node/.openclaw/` | Host volume mount | Includes `openclaw.json`, tokens |
|
||||
| Model auth profiles | `/home/node/.openclaw/` | Host volume mount | OAuth tokens, API keys |
|
||||
| Skill configs | `/home/node/.openclaw/skills/` | Host volume mount | Skill-level state |
|
||||
| Agent workspace | `/home/node/.openclaw/workspace/` | Host volume mount | Code and agent artifacts |
|
||||
| WhatsApp session | `/home/node/.openclaw/` | Host volume mount | Preserves QR login |
|
||||
| Gmail keyring | `/home/node/.openclaw/` | Host volume + password | Requires `GOG_KEYRING_PASSWORD` |
|
||||
| External binaries | `/usr/local/bin/` | Docker image | Must be baked at build time |
|
||||
| Node runtime | Container filesystem | Docker image | Rebuilt every image build |
|
||||
| OS packages | Container filesystem | Docker image | Do not install at runtime |
|
||||
| Docker container | Ephemeral | Restartable | Safe to destroy |
|
||||
|
||||
177
docs/plugin.md
177
docs/plugin.md
@@ -1,9 +1,10 @@
|
||||
---
|
||||
summary: "OpenClaw plugins/extensions: discovery, config, and safety"
|
||||
summary: 'OpenClaw plugins/extensions: discovery, config, and safety'
|
||||
read_when:
|
||||
- Adding or modifying plugins/extensions
|
||||
- Documenting plugin install or load rules
|
||||
---
|
||||
|
||||
# Plugins (Extensions)
|
||||
|
||||
## Quick start (new to plugins?)
|
||||
@@ -17,19 +18,19 @@ install).
|
||||
|
||||
Fast path:
|
||||
|
||||
1) See what’s already loaded:
|
||||
1. See what’s already loaded:
|
||||
|
||||
```bash
|
||||
openclaw plugins list
|
||||
```
|
||||
|
||||
2) Install an official plugin (example: Voice Call):
|
||||
2. Install an official plugin (example: Voice Call):
|
||||
|
||||
```bash
|
||||
openclaw plugins install @openclaw/voice-call
|
||||
```
|
||||
|
||||
3) Restart the Gateway, then configure under `plugins.entries.<id>.config`.
|
||||
3. Restart the Gateway, then configure under `plugins.entries.<id>.config`.
|
||||
|
||||
See [Voice Call](/plugins/voice-call) for a concrete example plugin.
|
||||
|
||||
@@ -73,12 +74,13 @@ Plugins can access selected core helpers via `api.runtime`. For telephony TTS:
|
||||
|
||||
```ts
|
||||
const result = await api.runtime.tts.textToSpeechTelephony({
|
||||
text: "Hello from OpenClaw",
|
||||
text: 'Hello from OpenClaw',
|
||||
cfg: api.config,
|
||||
});
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- Uses core `messages.tts` configuration (OpenAI or ElevenLabs).
|
||||
- Returns PCM audio buffer + sample rate. Plugins must resample/encode for providers.
|
||||
- Edge TTS is not supported for telephony.
|
||||
@@ -87,18 +89,22 @@ Notes:
|
||||
|
||||
OpenClaw scans, in order:
|
||||
|
||||
1) Config paths
|
||||
1. Config paths
|
||||
|
||||
- `plugins.load.paths` (file or directory)
|
||||
|
||||
2) Workspace extensions
|
||||
2. Workspace extensions
|
||||
|
||||
- `<workspace>/.openclaw/extensions/*.ts`
|
||||
- `<workspace>/.openclaw/extensions/*/index.ts`
|
||||
|
||||
3) Global extensions
|
||||
3. Global extensions
|
||||
|
||||
- `~/.openclaw/extensions/*.ts`
|
||||
- `~/.openclaw/extensions/*/index.ts`
|
||||
|
||||
4) Bundled extensions (shipped with OpenClaw, **disabled by default**)
|
||||
4. Bundled extensions (shipped with OpenClaw, **disabled by default**)
|
||||
|
||||
- `<openclaw>/extensions/*`
|
||||
|
||||
Bundled plugins must be enabled explicitly via `plugins.entries.<id>.enabled`
|
||||
@@ -164,6 +170,7 @@ Example:
|
||||
|
||||
OpenClaw can also merge **external channel catalogs** (for example, an MPM
|
||||
registry export). Drop a JSON file at one of:
|
||||
|
||||
- `~/.openclaw/mpm/plugins.json`
|
||||
- `~/.openclaw/mpm/catalog.json`
|
||||
- `~/.openclaw/plugins/catalog.json`
|
||||
@@ -188,17 +195,18 @@ configured id.
|
||||
{
|
||||
plugins: {
|
||||
enabled: true,
|
||||
allow: ["voice-call"],
|
||||
deny: ["untrusted-plugin"],
|
||||
load: { paths: ["~/Projects/oss/voice-call-extension"] },
|
||||
allow: ['voice-call'],
|
||||
deny: ['untrusted-plugin'],
|
||||
load: { paths: ['~/Projects/oss/voice-call-extension'] },
|
||||
entries: {
|
||||
"voice-call": { enabled: true, config: { provider: "twilio" } }
|
||||
}
|
||||
}
|
||||
'voice-call': { enabled: true, config: { provider: 'twilio' } },
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Fields:
|
||||
|
||||
- `enabled`: master toggle (default: true)
|
||||
- `allow`: allowlist (optional)
|
||||
- `deny`: denylist (optional; deny wins)
|
||||
@@ -208,6 +216,7 @@ Fields:
|
||||
Config changes **require a gateway restart**.
|
||||
|
||||
Validation rules (strict):
|
||||
|
||||
- Unknown plugin ids in `entries`, `allow`, `deny`, or `slots` are **errors**.
|
||||
- Unknown `channels.<id>` keys are **errors** unless a plugin manifest declares
|
||||
the channel id.
|
||||
@@ -224,9 +233,9 @@ Some plugin categories are **exclusive** (only one active at a time). Use
|
||||
{
|
||||
plugins: {
|
||||
slots: {
|
||||
memory: "memory-core" // or "none" to disable memory plugins
|
||||
}
|
||||
}
|
||||
memory: 'memory-core', // or "none" to disable memory plugins
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
@@ -311,6 +320,7 @@ export default function register(api) {
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- Hook directories follow the normal hook structure (`HOOK.md` + `handler.ts`).
|
||||
- Hook eligibility rules still apply (OS/bins/env/config requirements).
|
||||
- Plugin-managed hooks show up in `openclaw hooks list` with `plugin:<id>`.
|
||||
@@ -330,29 +340,29 @@ Example:
|
||||
|
||||
```ts
|
||||
api.registerProvider({
|
||||
id: "acme",
|
||||
label: "AcmeAI",
|
||||
id: 'acme',
|
||||
label: 'AcmeAI',
|
||||
auth: [
|
||||
{
|
||||
id: "oauth",
|
||||
label: "OAuth",
|
||||
kind: "oauth",
|
||||
id: 'oauth',
|
||||
label: 'OAuth',
|
||||
kind: 'oauth',
|
||||
run: async (ctx) => {
|
||||
// Run OAuth flow and return auth profiles.
|
||||
return {
|
||||
profiles: [
|
||||
{
|
||||
profileId: "acme:default",
|
||||
profileId: 'acme:default',
|
||||
credential: {
|
||||
type: "oauth",
|
||||
provider: "acme",
|
||||
access: "...",
|
||||
refresh: "...",
|
||||
type: 'oauth',
|
||||
provider: 'acme',
|
||||
access: '...',
|
||||
refresh: '...',
|
||||
expires: Date.now() + 3600 * 1000,
|
||||
},
|
||||
},
|
||||
],
|
||||
defaultModel: "acme/opus-1",
|
||||
defaultModel: 'acme/opus-1',
|
||||
};
|
||||
},
|
||||
},
|
||||
@@ -361,6 +371,7 @@ api.registerProvider({
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- `run` receives a `ProviderAuthContext` with `prompter`, `runtime`,
|
||||
`openUrl`, and `oauth.createVpsAwareHandlers` helpers.
|
||||
- Return `configPatch` when you need to add default models or provider config.
|
||||
@@ -374,23 +385,26 @@ validated by your channel plugin code.
|
||||
|
||||
```ts
|
||||
const myChannel = {
|
||||
id: "acmechat",
|
||||
id: 'acmechat',
|
||||
meta: {
|
||||
id: "acmechat",
|
||||
label: "AcmeChat",
|
||||
selectionLabel: "AcmeChat (API)",
|
||||
docsPath: "/channels/acmechat",
|
||||
blurb: "demo channel plugin.",
|
||||
aliases: ["acme"],
|
||||
id: 'acmechat',
|
||||
label: 'AcmeChat',
|
||||
selectionLabel: 'AcmeChat (API)',
|
||||
docsPath: '/channels/acmechat',
|
||||
blurb: 'demo channel plugin.',
|
||||
aliases: ['acme'],
|
||||
},
|
||||
capabilities: { chatTypes: ["direct"] },
|
||||
capabilities: { chatTypes: ['direct'] },
|
||||
config: {
|
||||
listAccountIds: (cfg) => Object.keys(cfg.channels?.acmechat?.accounts ?? {}),
|
||||
listAccountIds: (cfg) =>
|
||||
Object.keys(cfg.channels?.acmechat?.accounts ?? {}),
|
||||
resolveAccount: (cfg, accountId) =>
|
||||
(cfg.channels?.acmechat?.accounts?.[accountId ?? "default"] ?? { accountId }),
|
||||
cfg.channels?.acmechat?.accounts?.[accountId ?? 'default'] ?? {
|
||||
accountId,
|
||||
},
|
||||
},
|
||||
outbound: {
|
||||
deliveryMode: "direct",
|
||||
deliveryMode: 'direct',
|
||||
sendText: async () => ({ ok: true }),
|
||||
},
|
||||
};
|
||||
@@ -401,6 +415,7 @@ export default function (api) {
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- Put config under `channels.<id>` (not `plugins.entries`).
|
||||
- `meta.label` is used for labels in CLI/UI lists.
|
||||
- `meta.aliases` adds alternate ids for normalization and CLI inputs.
|
||||
@@ -412,27 +427,32 @@ Notes:
|
||||
Use this when you want a **new chat surface** (a “messaging channel”), not a model provider.
|
||||
Model provider docs live under `/providers/*`.
|
||||
|
||||
1) Pick an id + config shape
|
||||
1. Pick an id + config shape
|
||||
|
||||
- All channel config lives under `channels.<id>`.
|
||||
- Prefer `channels.<id>.accounts.<accountId>` for multi‑account setups.
|
||||
|
||||
2) Define the channel metadata
|
||||
2. Define the channel metadata
|
||||
|
||||
- `meta.label`, `meta.selectionLabel`, `meta.docsPath`, `meta.blurb` control CLI/UI lists.
|
||||
- `meta.docsPath` should point at a docs page like `/channels/<id>`.
|
||||
- `meta.preferOver` lets a plugin replace another channel (auto-enable prefers it).
|
||||
- `meta.detailLabel` and `meta.systemImage` are used by UIs for detail text/icons.
|
||||
|
||||
3) Implement the required adapters
|
||||
3. Implement the required adapters
|
||||
|
||||
- `config.listAccountIds` + `config.resolveAccount`
|
||||
- `capabilities` (chat types, media, threads, etc.)
|
||||
- `outbound.deliveryMode` + `outbound.sendText` (for basic send)
|
||||
|
||||
4) Add optional adapters as needed
|
||||
4. Add optional adapters as needed
|
||||
|
||||
- `setup` (wizard), `security` (DM policy), `status` (health/diagnostics)
|
||||
- `gateway` (start/stop/login), `mentions`, `threading`, `streaming`
|
||||
- `actions` (message actions), `commands` (native command behavior)
|
||||
|
||||
5) Register the channel in your plugin
|
||||
5. Register the channel in your plugin
|
||||
|
||||
- `api.registerChannel({ plugin })`
|
||||
|
||||
Minimal config example:
|
||||
@@ -442,10 +462,10 @@ Minimal config example:
|
||||
channels: {
|
||||
acmechat: {
|
||||
accounts: {
|
||||
default: { token: "ACME_TOKEN", enabled: true }
|
||||
}
|
||||
}
|
||||
}
|
||||
default: { token: 'ACME_TOKEN', enabled: true },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
@@ -453,23 +473,26 @@ Minimal channel plugin (outbound‑only):
|
||||
|
||||
```ts
|
||||
const plugin = {
|
||||
id: "acmechat",
|
||||
id: 'acmechat',
|
||||
meta: {
|
||||
id: "acmechat",
|
||||
label: "AcmeChat",
|
||||
selectionLabel: "AcmeChat (API)",
|
||||
docsPath: "/channels/acmechat",
|
||||
blurb: "AcmeChat messaging channel.",
|
||||
aliases: ["acme"],
|
||||
id: 'acmechat',
|
||||
label: 'AcmeChat',
|
||||
selectionLabel: 'AcmeChat (API)',
|
||||
docsPath: '/channels/acmechat',
|
||||
blurb: 'AcmeChat messaging channel.',
|
||||
aliases: ['acme'],
|
||||
},
|
||||
capabilities: { chatTypes: ["direct"] },
|
||||
capabilities: { chatTypes: ['direct'] },
|
||||
config: {
|
||||
listAccountIds: (cfg) => Object.keys(cfg.channels?.acmechat?.accounts ?? {}),
|
||||
listAccountIds: (cfg) =>
|
||||
Object.keys(cfg.channels?.acmechat?.accounts ?? {}),
|
||||
resolveAccount: (cfg, accountId) =>
|
||||
(cfg.channels?.acmechat?.accounts?.[accountId ?? "default"] ?? { accountId }),
|
||||
cfg.channels?.acmechat?.accounts?.[accountId ?? 'default'] ?? {
|
||||
accountId,
|
||||
},
|
||||
},
|
||||
outbound: {
|
||||
deliveryMode: "direct",
|
||||
deliveryMode: 'direct',
|
||||
sendText: async ({ text }) => {
|
||||
// deliver `text` to your channel here
|
||||
return { ok: true };
|
||||
@@ -493,7 +516,7 @@ See the dedicated guide: [Plugin agent tools](/plugins/agent-tools).
|
||||
|
||||
```ts
|
||||
export default function (api) {
|
||||
api.registerGatewayMethod("myplugin.status", ({ respond }) => {
|
||||
api.registerGatewayMethod('myplugin.status', ({ respond }) => {
|
||||
respond(true, { ok: true });
|
||||
});
|
||||
}
|
||||
@@ -503,11 +526,14 @@ export default function (api) {
|
||||
|
||||
```ts
|
||||
export default function (api) {
|
||||
api.registerCli(({ program }) => {
|
||||
program.command("mycmd").action(() => {
|
||||
console.log("Hello");
|
||||
});
|
||||
}, { commands: ["mycmd"] });
|
||||
api.registerCli(
|
||||
({ program }) => {
|
||||
program.command('mycmd').action(() => {
|
||||
console.log('Hello');
|
||||
});
|
||||
},
|
||||
{ commands: ['mycmd'] },
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
@@ -520,8 +546,8 @@ that don't need LLM processing.
|
||||
```ts
|
||||
export default function (api) {
|
||||
api.registerCommand({
|
||||
name: "mystatus",
|
||||
description: "Show plugin status",
|
||||
name: 'mystatus',
|
||||
description: 'Show plugin status',
|
||||
handler: (ctx) => ({
|
||||
text: `Plugin is running! Channel: ${ctx.channel}`,
|
||||
}),
|
||||
@@ -550,12 +576,12 @@ Example with authorization and arguments:
|
||||
|
||||
```ts
|
||||
api.registerCommand({
|
||||
name: "setmode",
|
||||
description: "Set plugin mode",
|
||||
name: 'setmode',
|
||||
description: 'Set plugin mode',
|
||||
acceptsArgs: true,
|
||||
requireAuth: true,
|
||||
handler: async (ctx) => {
|
||||
const mode = ctx.args?.trim() || "default";
|
||||
const mode = ctx.args?.trim() || 'default';
|
||||
await saveMode(mode);
|
||||
return { text: `Mode set to: ${mode}` };
|
||||
},
|
||||
@@ -563,6 +589,7 @@ api.registerCommand({
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- Plugin commands are processed **before** built-in commands and the AI agent
|
||||
- Commands are registered globally and work across all channels
|
||||
- Command names are case-insensitive (`/MyStatus` matches `/mystatus`)
|
||||
@@ -575,9 +602,9 @@ Notes:
|
||||
```ts
|
||||
export default function (api) {
|
||||
api.registerService({
|
||||
id: "my-service",
|
||||
start: () => api.logger.info("ready"),
|
||||
stop: () => api.logger.info("bye"),
|
||||
id: 'my-service',
|
||||
start: () => api.logger.info('ready'),
|
||||
stop: () => api.logger.info('bye'),
|
||||
});
|
||||
}
|
||||
```
|
||||
@@ -635,4 +662,4 @@ Plugins run in-process with the Gateway. Treat them as trusted code:
|
||||
Plugins can (and should) ship tests:
|
||||
|
||||
- In-repo plugins can keep Vitest tests under `src/**` (example: `src/plugins/voice-call.plugin.test.ts`).
|
||||
- Separately published plugins should run their own CI (lint/build/test) and validate `openclaw.extensions` points at the built entrypoint (`dist/index.mjs`).
|
||||
- Separately published plugins should run their own CI (lint/build/test) and validate `openclaw.extensions` points at the built entrypoint (`dist/index.js`).
|
||||
|
||||
@@ -9,20 +9,20 @@
|
||||
#
|
||||
# See https://fly.io/docs/reference/configuration/
|
||||
|
||||
app = "my-openclaw" # change to your app name
|
||||
primary_region = "iad" # change to your closest region
|
||||
app = "my-openclaw" # change to your app name
|
||||
primary_region = "iad" # change to your closest region
|
||||
|
||||
[build]
|
||||
dockerfile = "Dockerfile"
|
||||
dockerfile = "Dockerfile"
|
||||
|
||||
[env]
|
||||
NODE_ENV = "production"
|
||||
OPENCLAW_PREFER_PNPM = "1"
|
||||
OPENCLAW_STATE_DIR = "/data"
|
||||
NODE_OPTIONS = "--max-old-space-size=1536"
|
||||
NODE_ENV = "production"
|
||||
OPENCLAW_PREFER_PNPM = "1"
|
||||
OPENCLAW_STATE_DIR = "/data"
|
||||
NODE_OPTIONS = "--max-old-space-size=1536"
|
||||
|
||||
[processes]
|
||||
app = "node dist/index.mjs gateway --allow-unconfigured --port 3000 --bind lan"
|
||||
app = "node dist/index.js gateway --allow-unconfigured --port 3000 --bind lan"
|
||||
|
||||
# NOTE: No [http_service] block = no public ingress allocated.
|
||||
# The gateway will only be accessible via:
|
||||
@@ -31,9 +31,9 @@ primary_region = "iad" # change to your closest region
|
||||
# - fly ssh console
|
||||
|
||||
[[vm]]
|
||||
size = "shared-cpu-2x"
|
||||
memory = "2048mb"
|
||||
size = "shared-cpu-2x"
|
||||
memory = "2048mb"
|
||||
|
||||
[mounts]
|
||||
source = "openclaw_data"
|
||||
destination = "/data"
|
||||
source = "openclaw_data"
|
||||
destination = "/data"
|
||||
|
||||
36
fly.toml
36
fly.toml
@@ -2,33 +2,33 @@
|
||||
# See https://fly.io/docs/reference/configuration/
|
||||
|
||||
app = "openclaw"
|
||||
primary_region = "iad" # change to your closest region
|
||||
primary_region = "iad" # change to your closest region
|
||||
|
||||
[build]
|
||||
dockerfile = "Dockerfile"
|
||||
dockerfile = "Dockerfile"
|
||||
|
||||
[env]
|
||||
NODE_ENV = "production"
|
||||
# Fly uses x86, but keep this for consistency
|
||||
OPENCLAW_PREFER_PNPM = "1"
|
||||
OPENCLAW_STATE_DIR = "/data"
|
||||
NODE_OPTIONS = "--max-old-space-size=1536"
|
||||
NODE_ENV = "production"
|
||||
# Fly uses x86, but keep this for consistency
|
||||
OPENCLAW_PREFER_PNPM = "1"
|
||||
OPENCLAW_STATE_DIR = "/data"
|
||||
NODE_OPTIONS = "--max-old-space-size=1536"
|
||||
|
||||
[processes]
|
||||
app = "node dist/index.mjs gateway --allow-unconfigured --port 3000 --bind lan"
|
||||
app = "node dist/index.js gateway --allow-unconfigured --port 3000 --bind lan"
|
||||
|
||||
[http_service]
|
||||
internal_port = 3000
|
||||
force_https = true
|
||||
auto_stop_machines = false # Keep running for persistent connections
|
||||
auto_start_machines = true
|
||||
min_machines_running = 1
|
||||
processes = ["app"]
|
||||
internal_port = 3000
|
||||
force_https = true
|
||||
auto_stop_machines = false # Keep running for persistent connections
|
||||
auto_start_machines = true
|
||||
min_machines_running = 1
|
||||
processes = ["app"]
|
||||
|
||||
[[vm]]
|
||||
size = "shared-cpu-2x"
|
||||
memory = "2048mb"
|
||||
size = "shared-cpu-2x"
|
||||
memory = "2048mb"
|
||||
|
||||
[mounts]
|
||||
source = "openclaw_data"
|
||||
destination = "/data"
|
||||
source = "openclaw_data"
|
||||
destination = "/data"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import module from "node:module";
|
||||
import module from 'node:module';
|
||||
|
||||
// https://nodejs.org/api/module.html#module-compile-cache
|
||||
if (module.enableCompileCache && !process.env.NODE_DISABLE_COMPILE_CACHE) {
|
||||
@@ -11,4 +11,4 @@ if (module.enableCompileCache && !process.env.NODE_DISABLE_COMPILE_CACHE) {
|
||||
}
|
||||
}
|
||||
|
||||
await import("./dist/entry.mjs");
|
||||
await import('./dist/entry.js');
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
"version": "2026.1.29",
|
||||
"description": "WhatsApp gateway CLI (Baileys web) with Pi RPC agent",
|
||||
"type": "module",
|
||||
"main": "dist/index.mjs",
|
||||
"main": "dist/index.js",
|
||||
"exports": {
|
||||
".": "./dist/index.mjs",
|
||||
".": "./dist/index.js",
|
||||
"./plugin-sdk": "./dist/plugin-sdk/index.js",
|
||||
"./plugin-sdk/*": "./dist/plugin-sdk/*",
|
||||
"./cli-entry": "./openclaw.mjs"
|
||||
@@ -85,7 +85,7 @@
|
||||
"docs:bin": "node scripts/build-docs-list.mjs",
|
||||
"docs:dev": "cd docs && mint dev",
|
||||
"docs:build": "cd docs && pnpm dlx --reporter append-only mint broken-links",
|
||||
"build": "pnpm canvas:a2ui:bundle && tsdown && node --import tsx scripts/canvas-a2ui-copy.ts && node --import tsx scripts/copy-hook-metadata.ts && node --import tsx scripts/write-build-info.ts",
|
||||
"build": "pnpm canvas:a2ui:bundle && tsc -p tsconfig.json --noEmit false && node --import tsx scripts/canvas-a2ui-copy.ts && node --import tsx scripts/copy-hook-metadata.ts && node --import tsx scripts/write-build-info.ts",
|
||||
"plugins:sync": "node --import tsx scripts/sync-plugin-versions.ts",
|
||||
"release:check": "node --import tsx scripts/release-check.ts",
|
||||
"ui:install": "node scripts/ui.js install",
|
||||
@@ -227,7 +227,6 @@
|
||||
"oxlint": "^1.42.0",
|
||||
"oxlint-tsgolint": "^0.11.4",
|
||||
"rolldown": "1.0.0-rc.2",
|
||||
"tsdown": "^0.20.1",
|
||||
"tsx": "^4.21.0",
|
||||
"typescript": "^5.9.3",
|
||||
"vitest": "^4.0.18"
|
||||
|
||||
424
pnpm-lock.yaml
generated
424
pnpm-lock.yaml
generated
@@ -220,9 +220,6 @@ importers:
|
||||
rolldown:
|
||||
specifier: 1.0.0-rc.2
|
||||
version: 1.0.0-rc.2
|
||||
tsdown:
|
||||
specifier: ^0.20.1
|
||||
version: 0.20.1(@typescript/native-preview@7.0.0-dev.20260130.1)(typescript@5.9.3)
|
||||
tsx:
|
||||
specifier: ^4.21.0
|
||||
version: 4.21.0
|
||||
@@ -663,36 +660,19 @@ packages:
|
||||
resolution: {integrity: sha512-XTmhdItcBckcVVTy65Xp+42xG4LX5GK+9AqAsXPXk4IqUNv+LyQo5TMwNjuFYBfAB2GTG9iSQGk+QLc03vhf3w==}
|
||||
engines: {node: '>=16'}
|
||||
|
||||
'@babel/generator@8.0.0-beta.4':
|
||||
resolution: {integrity: sha512-5xRfRZk6wx1BRu2XnTE8cTh2mx1ixrZ3/vpn7p/RCJpgctL6pexVVHE3eqtwlYvHhPAuOYCAlnsAyXpBdmfh5Q==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
|
||||
'@babel/helper-string-parser@7.27.1':
|
||||
resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-string-parser@8.0.0-beta.4':
|
||||
resolution: {integrity: sha512-FGwbdQ/I2nJXXfyxa7dT0Fr/zPWwgX7m+hNVj0HrIHYJtyLxSQeQY1Kd8QkAYviQJV3OWFlRLuGd5epF03bdQg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
|
||||
'@babel/helper-validator-identifier@7.28.5':
|
||||
resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-validator-identifier@8.0.0-beta.4':
|
||||
resolution: {integrity: sha512-6t0IaUEzlinbLmsGIvBZIHEJGjuchx+cMj+FbS78zL17tucYervgbwO07V5/CgBenVraontpmyMCTVyqCfxhFQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
|
||||
'@babel/parser@7.28.6':
|
||||
resolution: {integrity: sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
hasBin: true
|
||||
|
||||
'@babel/parser@8.0.0-beta.4':
|
||||
resolution: {integrity: sha512-fBcUqUN3eenLyg25QFkOwY1lmV6L0RdG92g6gxyS2CVCY8kHdibkQz1+zV3bLzxcvNnfHoi3i9n5Dci+g93acg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
hasBin: true
|
||||
|
||||
'@babel/runtime@7.28.6':
|
||||
resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
@@ -701,10 +681,6 @@ packages:
|
||||
resolution: {integrity: sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/types@8.0.0-beta.4':
|
||||
resolution: {integrity: sha512-xjk2xqYp25ePzAs0I08hN2lrbUDDQFfCjwq6MIEa8HwHa0WK8NfNtdvtXod8Ku2CbE1iui7qwWojGvjQiyrQeA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
|
||||
'@bcoe/v8-coverage@1.0.2':
|
||||
resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==}
|
||||
engines: {node: '>=18'}
|
||||
@@ -1145,9 +1121,6 @@ packages:
|
||||
resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
|
||||
'@jridgewell/gen-mapping@0.3.13':
|
||||
resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
|
||||
|
||||
'@jridgewell/resolve-uri@3.1.2':
|
||||
resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
@@ -1822,9 +1795,6 @@ packages:
|
||||
resolution: {integrity: sha512-R5R9tb2AXs2IRLNKLBJDynhkfmx7mX0vi8NkhZb3gUkPWHn6HXk5J8iQ/dql0U3ApfWym4kXXmBDRGO+oeOfjg==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
'@oxc-project/types@0.110.0':
|
||||
resolution: {integrity: sha512-6Ct21OIlrEnFEJk5LT4e63pk3btsI6/TusD/GStLi7wYlGJNOl1GI9qvXAnRAxQU9zqA2Oz+UwhfTOU2rPZVow==}
|
||||
|
||||
'@oxc-project/types@0.111.0':
|
||||
resolution: {integrity: sha512-bh54LJMafgRGl2cPQ/QM+tI5rWaShm/wK9KywEj/w36MhiPKXYM67H2y3q+9pr4YO7ufwg2AKdBAZkhHBD8ClA==}
|
||||
|
||||
@@ -1978,9 +1948,6 @@ packages:
|
||||
'@protobufjs/utf8@1.1.0':
|
||||
resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==}
|
||||
|
||||
'@quansync/fs@1.0.0':
|
||||
resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==}
|
||||
|
||||
'@reflink/reflink-darwin-arm64@0.1.19':
|
||||
resolution: {integrity: sha512-ruy44Lpepdk1FqDz38vExBY/PVUsjxZA+chd9wozjUH9JjuDT/HEaQYA6wYN9mf041l0yLVar6BCZuWABJvHSA==}
|
||||
engines: {node: '>= 10'}
|
||||
@@ -2033,163 +2000,83 @@ packages:
|
||||
resolution: {integrity: sha512-DmCG8GzysnCZ15bres3N5AHCmwBwYgp0As6xjhQ47rAUTUXxJiK+lLUxaGsX3hd/30qUpVElh05PbGuxRPgJwA==}
|
||||
engines: {node: '>= 10'}
|
||||
|
||||
'@rolldown/binding-android-arm64@1.0.0-rc.1':
|
||||
resolution: {integrity: sha512-He6ZoCfv5D7dlRbrhNBkuMVIHd0GDnjJwbICE1OWpG7G3S2gmJ+eXkcNLJjzjNDpeI2aRy56ou39AJM9AD8YFA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
'@rolldown/binding-android-arm64@1.0.0-rc.2':
|
||||
resolution: {integrity: sha512-AGV80viZ4Hil4C16GFH+PSwq10jclV9oyRFhD+5HdowPOCJ+G+99N5AClQvMkUMIahTY8cX0SQpKEEWcCg6fSA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
'@rolldown/binding-darwin-arm64@1.0.0-rc.1':
|
||||
resolution: {integrity: sha512-YzJdn08kSOXnj85ghHauH2iHpOJ6eSmstdRTLyaziDcUxe9SyQJgGyx/5jDIhDvtOcNvMm2Ju7m19+S/Rm1jFg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@rolldown/binding-darwin-arm64@1.0.0-rc.2':
|
||||
resolution: {integrity: sha512-PYR+PQu1mMmQiiKHN2JiOctvH32Xc/Mf+Su2RSmWtC9BbIqlqsVWjbulnShk0imjRim0IsbkMMCN5vYQwiuqaA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@rolldown/binding-darwin-x64@1.0.0-rc.1':
|
||||
resolution: {integrity: sha512-cIvAbqM+ZVV6lBSKSBtlNqH5iCiW933t1q8j0H66B3sjbe8AxIRetVqfGgcHcJtMzBIkIALlL9fcDrElWLJQcQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@rolldown/binding-darwin-x64@1.0.0-rc.2':
|
||||
resolution: {integrity: sha512-X2G36Z6oh5ynoYpE2JAyG+uQ4kO/3N7XydM/I98FNk8VVgDKjajFF+v7TXJ2FMq6xa7Xm0UIUKHW2MRQroqoUA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@rolldown/binding-freebsd-x64@1.0.0-rc.1':
|
||||
resolution: {integrity: sha512-rVt+B1B/qmKwCl1XD02wKfgh3vQPXRXdB/TicV2w6g7RVAM1+cZcpigwhLarqiVCxDObFZ7UgXCxPC7tpDoRog==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
|
||||
'@rolldown/binding-freebsd-x64@1.0.0-rc.2':
|
||||
resolution: {integrity: sha512-XpiFTsl9qjiDfrmJF6CE3dgj1nmSbxUIT+p2HIbXV6WOj/32btO8FKkWSsOphUwVinEt3R8HVkVrcLtFNruMMQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
|
||||
'@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.1':
|
||||
resolution: {integrity: sha512-69YKwJJBOFprQa1GktPgbuBOfnn+EGxu8sBJ1TjPER+zhSpYeaU4N07uqmyBiksOLGXsMegymuecLobfz03h8Q==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.2':
|
||||
resolution: {integrity: sha512-zjYZ99e47Wlygs4hW+sQ+kshlO8ake9OoY2ecnJ9cwpDGiiIB9rQ3LgP3kt8j6IeVyMSksu//VEhc8Mrd1lRIw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@rolldown/binding-linux-arm64-gnu@1.0.0-rc.1':
|
||||
resolution: {integrity: sha512-9JDhHUf3WcLfnViFWm+TyorqUtnSAHaCzlSNmMOq824prVuuzDOK91K0Hl8DUcEb9M5x2O+d2/jmBMsetRIn3g==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@rolldown/binding-linux-arm64-gnu@1.0.0-rc.2':
|
||||
resolution: {integrity: sha512-Piso04EZ9IHV1aZSsLQVMOPTiCq4Ps2UPL3pchjNXHGJGFiB9U42s22LubPaEBFS+i6tCawS5EarIwex1zC4BA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@rolldown/binding-linux-arm64-musl@1.0.0-rc.1':
|
||||
resolution: {integrity: sha512-UvApLEGholmxw/HIwmUnLq3CwdydbhaHHllvWiCTNbyGom7wTwOtz5OAQbAKZYyiEOeIXZNPkM7nA4Dtng7CLw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@rolldown/binding-linux-arm64-musl@1.0.0-rc.2':
|
||||
resolution: {integrity: sha512-OwJCeMZlmjKsN9pfJfTmqYpe3JC+L6RO87+hu9ajRLr1Lh6cM2FRQ8e48DLRyRDww8Ti695XQvqEANEMmsuzLw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@rolldown/binding-linux-x64-gnu@1.0.0-rc.1':
|
||||
resolution: {integrity: sha512-uVctNgZHiGnJx5Fij7wHLhgw4uyZBVi6mykeWKOqE7bVy9Hcxn0fM/IuqdMwk6hXlaf9fFShDTFz2+YejP+x0A==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@rolldown/binding-linux-x64-gnu@1.0.0-rc.2':
|
||||
resolution: {integrity: sha512-uQqBmA8dTWbKvfqbeSsXNUssRGfdgQCc0hkGfhQN7Pf85wG2h0Fd/z2d+ykyT4YbcsjQdgEGxBNsg3v4ekOuEA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@rolldown/binding-linux-x64-musl@1.0.0-rc.1':
|
||||
resolution: {integrity: sha512-T6Eg0xWwcxd/MzBcuv4Z37YVbUbJxy5cMNnbIt/Yr99wFwli30O4BPlY8hKeGyn6lWNtU0QioBS46lVzDN38bg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@rolldown/binding-linux-x64-musl@1.0.0-rc.2':
|
||||
resolution: {integrity: sha512-ItZabVsICCYWHbP+jcAgNzjPAYg5GIVQp/NpqT6iOgWctaMYtobClc5m0kNtxwqfNrLXoyt998xUey4AvcxnGQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@rolldown/binding-openharmony-arm64@1.0.0-rc.1':
|
||||
resolution: {integrity: sha512-PuGZVS2xNJyLADeh2F04b+Cz4NwvpglbtWACgrDOa5YDTEHKwmiTDjoD5eZ9/ptXtcpeFrMqD2H4Zn33KAh1Eg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [openharmony]
|
||||
|
||||
'@rolldown/binding-openharmony-arm64@1.0.0-rc.2':
|
||||
resolution: {integrity: sha512-U4UYANwafcMXSUC0VqdrqTAgCo2v8T7SiuTYwVFXgia0KOl8jiv3okwCFqeZNuw/G6EWDiqhT8kK1DLgyLsxow==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [openharmony]
|
||||
|
||||
'@rolldown/binding-wasm32-wasi@1.0.0-rc.1':
|
||||
resolution: {integrity: sha512-2mOxY562ihHlz9lEXuaGEIDCZ1vI+zyFdtsoa3M62xsEunDXQE+DVPO4S4x5MPK9tKulG/aFcA/IH5eVN257Cw==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
cpu: [wasm32]
|
||||
|
||||
'@rolldown/binding-wasm32-wasi@1.0.0-rc.2':
|
||||
resolution: {integrity: sha512-ZIWCjQsMon4tqRoao0Vzowjwx0cmFT3kublh2nNlgeasIJMWlIGHtr0d4fPypm57Rqx4o1h4L8SweoK2q6sMGA==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
cpu: [wasm32]
|
||||
|
||||
'@rolldown/binding-win32-arm64-msvc@1.0.0-rc.1':
|
||||
resolution: {integrity: sha512-oQVOP5cfAWZwRD0Q3nGn/cA9FW3KhMMuQ0NIndALAe6obqjLhqYVYDiGGRGrxvnjJsVbpLwR14gIUYnpIcHR1g==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@rolldown/binding-win32-arm64-msvc@1.0.0-rc.2':
|
||||
resolution: {integrity: sha512-NIo7vwRUPEzZ4MuZGr5YbDdjJ84xdiG+YYf8ZBfTgvIsk9wM0sZamJPEXvaLkzVIHpOw5uqEHXS85Gqqb7aaqQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@rolldown/binding-win32-x64-msvc@1.0.0-rc.1':
|
||||
resolution: {integrity: sha512-Ydsxxx++FNOuov3wCBPaYjZrEvKOOGq3k+BF4BPridhg2pENfitSRD2TEuQ8i33bp5VptuNdC9IzxRKU031z5A==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@rolldown/binding-win32-x64-msvc@1.0.0-rc.2':
|
||||
resolution: {integrity: sha512-bLKzyLFbvngeNPZocuLo3LILrKwCrkyMxmRXs6fZYDrvh7cyZRw9v56maDL9ipPas0OOmQK1kAKYwvTs30G21Q==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@rolldown/pluginutils@1.0.0-rc.1':
|
||||
resolution: {integrity: sha512-UTBjtTxVOhodhzFVp/ayITaTETRHPUPYZPXQe0WU0wOgxghMojXxYjOiPOauKIYNWJAWS2fd7gJgGQK8GU8vDA==}
|
||||
|
||||
'@rolldown/pluginutils@1.0.0-rc.2':
|
||||
resolution: {integrity: sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw==}
|
||||
|
||||
@@ -2649,9 +2536,6 @@ packages:
|
||||
'@types/http-errors@2.0.5':
|
||||
resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==}
|
||||
|
||||
'@types/jsesc@2.5.1':
|
||||
resolution: {integrity: sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw==}
|
||||
|
||||
'@types/jsonwebtoken@9.0.10':
|
||||
resolution: {integrity: sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA==}
|
||||
|
||||
@@ -2928,10 +2812,6 @@ packages:
|
||||
resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
ansis@4.2.0:
|
||||
resolution: {integrity: sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
any-promise@1.3.0:
|
||||
resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
|
||||
|
||||
@@ -2972,10 +2852,6 @@ packages:
|
||||
resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
ast-kit@3.0.0-beta.1:
|
||||
resolution: {integrity: sha512-trmleAnZ2PxN/loHWVhhx1qeOHSRXq4TDsBBxq3GqeJitfk3+jTQ+v/C1km/KYq9M7wKqCewMh+/NAvVH7m+bw==}
|
||||
engines: {node: '>=20.19.0'}
|
||||
|
||||
ast-types@0.13.4:
|
||||
resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==}
|
||||
engines: {node: '>=4'}
|
||||
@@ -3041,9 +2917,6 @@ packages:
|
||||
bignumber.js@9.3.1:
|
||||
resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==}
|
||||
|
||||
birpc@4.0.0:
|
||||
resolution: {integrity: sha512-LShSxJP0KTmd101b6DRyGBj57LZxSDYWKitQNW/mi8GRMvZb078Uf9+pveax1DrVL89vm7mWe+TovdI/UDOuPw==}
|
||||
|
||||
bluebird@3.7.2:
|
||||
resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==}
|
||||
|
||||
@@ -3083,10 +2956,6 @@ packages:
|
||||
resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
cac@6.7.14:
|
||||
resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
cacheable@2.3.2:
|
||||
resolution: {integrity: sha512-w+ZuRNmex9c1TR9RcsxbfTKCjSL0rh1WA5SABbrWprIHeNBdmyQLSYonlDy9gpD+63XT8DgZ/wNh1Smvc9WnJA==}
|
||||
|
||||
@@ -3287,9 +3156,6 @@ packages:
|
||||
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
defu@6.1.4:
|
||||
resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==}
|
||||
|
||||
degenerator@5.0.1:
|
||||
resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==}
|
||||
engines: {node: '>= 14'}
|
||||
@@ -3343,15 +3209,6 @@ packages:
|
||||
resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
dts-resolver@2.1.3:
|
||||
resolution: {integrity: sha512-bihc7jPC90VrosXNzK0LTE2cuLP6jr0Ro8jk+kMugHReJVLIpHz/xadeq3MhuwyO4TD4OA3L1Q8pBBFRc08Tsw==}
|
||||
engines: {node: '>=20.19.0'}
|
||||
peerDependencies:
|
||||
oxc-resolver: '>=11.0.0'
|
||||
peerDependenciesMeta:
|
||||
oxc-resolver:
|
||||
optional: true
|
||||
|
||||
dunder-proto@1.0.1:
|
||||
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -3377,10 +3234,6 @@ packages:
|
||||
emoji-regex@9.2.2:
|
||||
resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
|
||||
|
||||
empathic@2.0.0:
|
||||
resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
encodeurl@2.0.0:
|
||||
resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==}
|
||||
engines: {node: '>= 0.8'}
|
||||
@@ -3719,9 +3572,6 @@ packages:
|
||||
resolution: {integrity: sha512-U7tt8JsyrxSRKspfhtLET79pU8K+tInj5QZXs1jSugO1Vq5dFj3kmZsRldo29mTBfcjDRVRXrEZ6LS63Cog9ZA==}
|
||||
engines: {node: '>=16.9.0'}
|
||||
|
||||
hookable@6.0.1:
|
||||
resolution: {integrity: sha512-uKGyY8BuzN/a5gvzvA+3FVWo0+wUjgtfSdnmjtrOVwQCZPHpHDH2WRO3VZSOeluYrHoDCiXFffZXs8Dj1ULWtw==}
|
||||
|
||||
hookified@1.15.0:
|
||||
resolution: {integrity: sha512-51w+ZZGt7Zw5q7rM3nC4t3aLn/xvKDETsXqMczndvwyVQhAHfUmUuFBRFcos8Iyebtk7OAE9dL26wFNzZVVOkw==}
|
||||
|
||||
@@ -3781,10 +3631,6 @@ packages:
|
||||
import-in-the-middle@2.0.6:
|
||||
resolution: {integrity: sha512-3vZV3jX0XRFW3EJDTwzWoZa+RH1b8eTTx6YOCjglrLyPuepwoBti1k3L2dKwdCUrnVEfc5CuRuGstaC/uQJJaw==}
|
||||
|
||||
import-without-cache@0.2.5:
|
||||
resolution: {integrity: sha512-B6Lc2s6yApwnD2/pMzFh/d5AVjdsDXjgkeJ766FmFuJELIGHNycKRj+l3A39yZPM4CchqNCB4RITEAYB1KUM6A==}
|
||||
engines: {node: '>=20.19.0'}
|
||||
|
||||
inherits@2.0.4:
|
||||
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
|
||||
|
||||
@@ -3892,11 +3738,6 @@ packages:
|
||||
jsbn@0.1.1:
|
||||
resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==}
|
||||
|
||||
jsesc@3.1.0:
|
||||
resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==}
|
||||
engines: {node: '>=6'}
|
||||
hasBin: true
|
||||
|
||||
json-bigint@1.0.0:
|
||||
resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==}
|
||||
|
||||
@@ -4698,9 +4539,6 @@ packages:
|
||||
resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==}
|
||||
engines: {node: '>=0.6'}
|
||||
|
||||
quansync@1.0.0:
|
||||
resolution: {integrity: sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==}
|
||||
|
||||
quick-format-unescaped@4.0.4:
|
||||
resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==}
|
||||
|
||||
@@ -4787,30 +4625,6 @@ packages:
|
||||
resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==}
|
||||
hasBin: true
|
||||
|
||||
rolldown-plugin-dts@0.21.8:
|
||||
resolution: {integrity: sha512-czOQoe6eZpRKCv9P+ijO/v4A2TwQjASAV7qezUxRZSua06Yb2REPIZv/mbfXiZDP1ZfI7Ez7re7qfK9F9u0Epw==}
|
||||
engines: {node: '>=20.19.0'}
|
||||
peerDependencies:
|
||||
'@ts-macro/tsc': ^0.3.6
|
||||
'@typescript/native-preview': '>=7.0.0-dev.20250601.1'
|
||||
rolldown: ^1.0.0-beta.57
|
||||
typescript: ^5.0.0
|
||||
vue-tsc: ~3.2.0
|
||||
peerDependenciesMeta:
|
||||
'@ts-macro/tsc':
|
||||
optional: true
|
||||
'@typescript/native-preview':
|
||||
optional: true
|
||||
typescript:
|
||||
optional: true
|
||||
vue-tsc:
|
||||
optional: true
|
||||
|
||||
rolldown@1.0.0-rc.1:
|
||||
resolution: {integrity: sha512-M3AeZjYE6UclblEf531Hch0WfVC/NOL43Cc+WdF3J50kk5/fvouHhDumSGTh0oRjbZ8C4faaVr5r6Nx1xMqDGg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
hasBin: true
|
||||
|
||||
rolldown@1.0.0-rc.2:
|
||||
resolution: {integrity: sha512-1g/8Us9J8sgJGn3hZfBecX1z4U3y5KO7V/aV2U1M/9UUzLNqHA8RfFQ/NPT7HLxOIldyIgrcjaYTRvA81KhJIg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
@@ -5134,38 +4948,9 @@ packages:
|
||||
tr46@0.0.3:
|
||||
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
|
||||
|
||||
tree-kill@1.2.2:
|
||||
resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==}
|
||||
hasBin: true
|
||||
|
||||
ts-algebra@2.0.0:
|
||||
resolution: {integrity: sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==}
|
||||
|
||||
tsdown@0.20.1:
|
||||
resolution: {integrity: sha512-Wo1BzqNQVZ6SFQV8rjQBwMmNubO+yV3F+vp2WNTjEaS4S5CT1C1dHtUbeFMrCEasZpGy5w6TshpehNnfTe8QBQ==}
|
||||
engines: {node: '>=20.19.0'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
'@arethetypeswrong/core': ^0.18.1
|
||||
'@vitejs/devtools': '*'
|
||||
publint: ^0.3.0
|
||||
typescript: ^5.0.0
|
||||
unplugin-lightningcss: ^0.4.0
|
||||
unplugin-unused: ^0.5.0
|
||||
peerDependenciesMeta:
|
||||
'@arethetypeswrong/core':
|
||||
optional: true
|
||||
'@vitejs/devtools':
|
||||
optional: true
|
||||
publint:
|
||||
optional: true
|
||||
typescript:
|
||||
optional: true
|
||||
unplugin-lightningcss:
|
||||
optional: true
|
||||
unplugin-unused:
|
||||
optional: true
|
||||
|
||||
tslib@2.8.1:
|
||||
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
|
||||
|
||||
@@ -5219,9 +5004,6 @@ packages:
|
||||
resolution: {integrity: sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
unconfig-core@7.4.2:
|
||||
resolution: {integrity: sha512-VgPCvLWugINbXvMQDf8Jh0mlbvNjNC6eSUziHsBCMpxR05OPrNrvDnyatdMjRgcHaaNsCqz+wjNXxNw1kRLHUg==}
|
||||
|
||||
undici-types@6.21.0:
|
||||
resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
|
||||
|
||||
@@ -5246,16 +5028,6 @@ packages:
|
||||
resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
unrun@0.2.26:
|
||||
resolution: {integrity: sha512-A3DQLBcDyTui4Hlaoojkldg+8x+CIR+tcSHY0wzW+CgB4X/DNyH58jJpXp1B/EkE+yG6tU8iH1mWsLtwFU3IQg==}
|
||||
engines: {node: '>=20.19.0'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
synckit: ^0.11.11
|
||||
peerDependenciesMeta:
|
||||
synckit:
|
||||
optional: true
|
||||
|
||||
uri-js@4.4.1:
|
||||
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
|
||||
|
||||
@@ -5979,31 +5751,14 @@ snapshots:
|
||||
jsonwebtoken: 9.0.3
|
||||
uuid: 8.3.2
|
||||
|
||||
'@babel/generator@8.0.0-beta.4':
|
||||
dependencies:
|
||||
'@babel/parser': 8.0.0-beta.4
|
||||
'@babel/types': 8.0.0-beta.4
|
||||
'@jridgewell/gen-mapping': 0.3.13
|
||||
'@jridgewell/trace-mapping': 0.3.31
|
||||
'@types/jsesc': 2.5.1
|
||||
jsesc: 3.1.0
|
||||
|
||||
'@babel/helper-string-parser@7.27.1': {}
|
||||
|
||||
'@babel/helper-string-parser@8.0.0-beta.4': {}
|
||||
|
||||
'@babel/helper-validator-identifier@7.28.5': {}
|
||||
|
||||
'@babel/helper-validator-identifier@8.0.0-beta.4': {}
|
||||
|
||||
'@babel/parser@7.28.6':
|
||||
dependencies:
|
||||
'@babel/types': 7.28.6
|
||||
|
||||
'@babel/parser@8.0.0-beta.4':
|
||||
dependencies:
|
||||
'@babel/types': 8.0.0-beta.4
|
||||
|
||||
'@babel/runtime@7.28.6': {}
|
||||
|
||||
'@babel/types@7.28.6':
|
||||
@@ -6011,11 +5766,6 @@ snapshots:
|
||||
'@babel/helper-string-parser': 7.27.1
|
||||
'@babel/helper-validator-identifier': 7.28.5
|
||||
|
||||
'@babel/types@8.0.0-beta.4':
|
||||
dependencies:
|
||||
'@babel/helper-string-parser': 8.0.0-beta.4
|
||||
'@babel/helper-validator-identifier': 8.0.0-beta.4
|
||||
|
||||
'@bcoe/v8-coverage@1.0.2': {}
|
||||
|
||||
'@borewit/text-codec@0.2.1': {}
|
||||
@@ -6403,11 +6153,6 @@ snapshots:
|
||||
dependencies:
|
||||
minipass: 7.1.2
|
||||
|
||||
'@jridgewell/gen-mapping@0.3.13':
|
||||
dependencies:
|
||||
'@jridgewell/sourcemap-codec': 1.5.5
|
||||
'@jridgewell/trace-mapping': 0.3.31
|
||||
|
||||
'@jridgewell/resolve-uri@3.1.2': {}
|
||||
|
||||
'@jridgewell/sourcemap-codec@1.5.5': {}
|
||||
@@ -6473,7 +6218,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@types/node': 24.10.9
|
||||
optionalDependencies:
|
||||
axios: 1.13.4
|
||||
axios: 1.13.4(debug@4.4.3)
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
|
||||
@@ -6670,7 +6415,7 @@ snapshots:
|
||||
'@azure/core-auth': 1.10.1
|
||||
'@azure/msal-node': 3.8.6
|
||||
'@microsoft/agents-activity': 1.2.3
|
||||
axios: 1.13.4
|
||||
axios: 1.13.4(debug@4.4.3)
|
||||
jsonwebtoken: 9.0.3
|
||||
jwks-rsa: 3.2.2
|
||||
object-path: 0.11.8
|
||||
@@ -7171,8 +6916,6 @@ snapshots:
|
||||
|
||||
'@opentelemetry/semantic-conventions@1.39.0': {}
|
||||
|
||||
'@oxc-project/types@0.110.0': {}
|
||||
|
||||
'@oxc-project/types@0.111.0': {}
|
||||
|
||||
'@oxfmt/darwin-arm64@0.27.0':
|
||||
@@ -7271,10 +7014,6 @@ snapshots:
|
||||
|
||||
'@protobufjs/utf8@1.1.0': {}
|
||||
|
||||
'@quansync/fs@1.0.0':
|
||||
dependencies:
|
||||
quansync: 1.0.0
|
||||
|
||||
'@reflink/reflink-darwin-arm64@0.1.19':
|
||||
optional: true
|
||||
|
||||
@@ -7311,90 +7050,47 @@ snapshots:
|
||||
'@reflink/reflink-win32-x64-msvc': 0.1.19
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-android-arm64@1.0.0-rc.1':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-android-arm64@1.0.0-rc.2':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-darwin-arm64@1.0.0-rc.1':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-darwin-arm64@1.0.0-rc.2':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-darwin-x64@1.0.0-rc.1':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-darwin-x64@1.0.0-rc.2':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-freebsd-x64@1.0.0-rc.1':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-freebsd-x64@1.0.0-rc.2':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.1':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.2':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-arm64-gnu@1.0.0-rc.1':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-arm64-gnu@1.0.0-rc.2':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-arm64-musl@1.0.0-rc.1':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-arm64-musl@1.0.0-rc.2':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-x64-gnu@1.0.0-rc.1':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-x64-gnu@1.0.0-rc.2':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-x64-musl@1.0.0-rc.1':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-x64-musl@1.0.0-rc.2':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-openharmony-arm64@1.0.0-rc.1':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-openharmony-arm64@1.0.0-rc.2':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-wasm32-wasi@1.0.0-rc.1':
|
||||
dependencies:
|
||||
'@napi-rs/wasm-runtime': 1.1.1
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-wasm32-wasi@1.0.0-rc.2':
|
||||
dependencies:
|
||||
'@napi-rs/wasm-runtime': 1.1.1
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-win32-arm64-msvc@1.0.0-rc.1':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-win32-arm64-msvc@1.0.0-rc.2':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-win32-x64-msvc@1.0.0-rc.1':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-win32-x64-msvc@1.0.0-rc.2':
|
||||
optional: true
|
||||
|
||||
'@rolldown/pluginutils@1.0.0-rc.1': {}
|
||||
|
||||
'@rolldown/pluginutils@1.0.0-rc.2': {}
|
||||
|
||||
'@rollup/rollup-android-arm-eabi@4.57.1':
|
||||
@@ -7502,7 +7198,7 @@ snapshots:
|
||||
'@slack/types': 2.19.0
|
||||
'@slack/web-api': 7.13.0
|
||||
'@types/express': 5.0.6
|
||||
axios: 1.13.4
|
||||
axios: 1.13.4(debug@4.4.3)
|
||||
express: 5.2.1
|
||||
path-to-regexp: 8.3.0
|
||||
raw-body: 3.0.2
|
||||
@@ -7548,7 +7244,7 @@ snapshots:
|
||||
'@slack/types': 2.19.0
|
||||
'@types/node': 25.1.0
|
||||
'@types/retry': 0.12.0
|
||||
axios: 1.13.4
|
||||
axios: 1.13.4(debug@4.4.3)
|
||||
eventemitter3: 5.0.4
|
||||
form-data: 4.0.5
|
||||
is-electron: 2.2.2
|
||||
@@ -8006,8 +7702,6 @@ snapshots:
|
||||
|
||||
'@types/http-errors@2.0.5': {}
|
||||
|
||||
'@types/jsesc@2.5.1': {}
|
||||
|
||||
'@types/jsonwebtoken@9.0.10':
|
||||
dependencies:
|
||||
'@types/ms': 2.1.0
|
||||
@@ -8351,8 +8045,6 @@ snapshots:
|
||||
|
||||
ansi-styles@6.2.3: {}
|
||||
|
||||
ansis@4.2.0: {}
|
||||
|
||||
any-promise@1.3.0: {}
|
||||
|
||||
apache-arrow@18.1.0:
|
||||
@@ -8390,12 +8082,6 @@ snapshots:
|
||||
|
||||
assertion-error@2.0.1: {}
|
||||
|
||||
ast-kit@3.0.0-beta.1:
|
||||
dependencies:
|
||||
'@babel/parser': 8.0.0-beta.4
|
||||
estree-walker: 3.0.3
|
||||
pathe: 2.0.3
|
||||
|
||||
ast-types@0.13.4:
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
@@ -8442,14 +8128,6 @@ snapshots:
|
||||
|
||||
aws4@1.13.2: {}
|
||||
|
||||
axios@1.13.4:
|
||||
dependencies:
|
||||
follow-redirects: 1.15.11
|
||||
form-data: 4.0.5
|
||||
proxy-from-env: 1.1.0
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
|
||||
axios@1.13.4(debug@4.4.3):
|
||||
dependencies:
|
||||
follow-redirects: 1.15.11(debug@4.4.3)
|
||||
@@ -8476,8 +8154,6 @@ snapshots:
|
||||
|
||||
bignumber.js@9.3.1: {}
|
||||
|
||||
birpc@4.0.0: {}
|
||||
|
||||
bluebird@3.7.2: {}
|
||||
|
||||
body-parser@1.20.4:
|
||||
@@ -8534,8 +8210,6 @@ snapshots:
|
||||
|
||||
bytes@3.1.2: {}
|
||||
|
||||
cac@6.7.14: {}
|
||||
|
||||
cacheable@2.3.2:
|
||||
dependencies:
|
||||
'@cacheable/memory': 2.0.7
|
||||
@@ -8722,8 +8396,6 @@ snapshots:
|
||||
|
||||
deepmerge@4.3.1: {}
|
||||
|
||||
defu@6.1.4: {}
|
||||
|
||||
degenerator@5.0.1:
|
||||
dependencies:
|
||||
ast-types: 0.13.4
|
||||
@@ -8770,8 +8442,6 @@ snapshots:
|
||||
|
||||
dotenv@17.2.3: {}
|
||||
|
||||
dts-resolver@2.1.3: {}
|
||||
|
||||
dunder-proto@1.0.1:
|
||||
dependencies:
|
||||
call-bind-apply-helpers: 1.0.2
|
||||
@@ -8797,8 +8467,6 @@ snapshots:
|
||||
|
||||
emoji-regex@9.2.2: {}
|
||||
|
||||
empathic@2.0.0: {}
|
||||
|
||||
encodeurl@2.0.0: {}
|
||||
|
||||
entities@4.5.0: {}
|
||||
@@ -9025,8 +8693,6 @@ snapshots:
|
||||
|
||||
flatbuffers@24.12.23: {}
|
||||
|
||||
follow-redirects@1.15.11: {}
|
||||
|
||||
follow-redirects@1.15.11(debug@4.4.3):
|
||||
optionalDependencies:
|
||||
debug: 4.4.3
|
||||
@@ -9241,8 +8907,6 @@ snapshots:
|
||||
hono@4.11.4:
|
||||
optional: true
|
||||
|
||||
hookable@6.0.1: {}
|
||||
|
||||
hookified@1.15.0: {}
|
||||
|
||||
html-escaper@2.0.2: {}
|
||||
@@ -9322,8 +8986,6 @@ snapshots:
|
||||
cjs-module-lexer: 2.2.0
|
||||
module-details-from-path: 1.0.4
|
||||
|
||||
import-without-cache@0.2.5: {}
|
||||
|
||||
inherits@2.0.4: {}
|
||||
|
||||
ini@1.3.8: {}
|
||||
@@ -9432,8 +9094,6 @@ snapshots:
|
||||
|
||||
jsbn@0.1.1: {}
|
||||
|
||||
jsesc@3.1.0: {}
|
||||
|
||||
json-bigint@1.0.0:
|
||||
dependencies:
|
||||
bignumber.js: 9.3.1
|
||||
@@ -10283,8 +9943,6 @@ snapshots:
|
||||
|
||||
qs@6.5.3: {}
|
||||
|
||||
quansync@1.0.0: {}
|
||||
|
||||
quick-format-unescaped@4.0.4: {}
|
||||
|
||||
range-parser@1.2.1: {}
|
||||
@@ -10394,42 +10052,6 @@ snapshots:
|
||||
dependencies:
|
||||
glob: 10.5.0
|
||||
|
||||
rolldown-plugin-dts@0.21.8(@typescript/native-preview@7.0.0-dev.20260130.1)(rolldown@1.0.0-rc.1)(typescript@5.9.3):
|
||||
dependencies:
|
||||
'@babel/generator': 8.0.0-beta.4
|
||||
'@babel/parser': 8.0.0-beta.4
|
||||
'@babel/types': 8.0.0-beta.4
|
||||
ast-kit: 3.0.0-beta.1
|
||||
birpc: 4.0.0
|
||||
dts-resolver: 2.1.3
|
||||
get-tsconfig: 4.13.1
|
||||
obug: 2.1.1
|
||||
rolldown: 1.0.0-rc.1
|
||||
optionalDependencies:
|
||||
'@typescript/native-preview': 7.0.0-dev.20260130.1
|
||||
typescript: 5.9.3
|
||||
transitivePeerDependencies:
|
||||
- oxc-resolver
|
||||
|
||||
rolldown@1.0.0-rc.1:
|
||||
dependencies:
|
||||
'@oxc-project/types': 0.110.0
|
||||
'@rolldown/pluginutils': 1.0.0-rc.1
|
||||
optionalDependencies:
|
||||
'@rolldown/binding-android-arm64': 1.0.0-rc.1
|
||||
'@rolldown/binding-darwin-arm64': 1.0.0-rc.1
|
||||
'@rolldown/binding-darwin-x64': 1.0.0-rc.1
|
||||
'@rolldown/binding-freebsd-x64': 1.0.0-rc.1
|
||||
'@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.1
|
||||
'@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.1
|
||||
'@rolldown/binding-linux-arm64-musl': 1.0.0-rc.1
|
||||
'@rolldown/binding-linux-x64-gnu': 1.0.0-rc.1
|
||||
'@rolldown/binding-linux-x64-musl': 1.0.0-rc.1
|
||||
'@rolldown/binding-openharmony-arm64': 1.0.0-rc.1
|
||||
'@rolldown/binding-wasm32-wasi': 1.0.0-rc.1
|
||||
'@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.1
|
||||
'@rolldown/binding-win32-x64-msvc': 1.0.0-rc.1
|
||||
|
||||
rolldown@1.0.0-rc.2:
|
||||
dependencies:
|
||||
'@oxc-project/types': 0.111.0
|
||||
@@ -10865,37 +10487,8 @@ snapshots:
|
||||
|
||||
tr46@0.0.3: {}
|
||||
|
||||
tree-kill@1.2.2: {}
|
||||
|
||||
ts-algebra@2.0.0: {}
|
||||
|
||||
tsdown@0.20.1(@typescript/native-preview@7.0.0-dev.20260130.1)(typescript@5.9.3):
|
||||
dependencies:
|
||||
ansis: 4.2.0
|
||||
cac: 6.7.14
|
||||
defu: 6.1.4
|
||||
empathic: 2.0.0
|
||||
hookable: 6.0.1
|
||||
import-without-cache: 0.2.5
|
||||
obug: 2.1.1
|
||||
picomatch: 4.0.3
|
||||
rolldown: 1.0.0-rc.1
|
||||
rolldown-plugin-dts: 0.21.8(@typescript/native-preview@7.0.0-dev.20260130.1)(rolldown@1.0.0-rc.1)(typescript@5.9.3)
|
||||
semver: 7.7.3
|
||||
tinyexec: 1.0.2
|
||||
tinyglobby: 0.2.15
|
||||
tree-kill: 1.2.2
|
||||
unconfig-core: 7.4.2
|
||||
unrun: 0.2.26
|
||||
optionalDependencies:
|
||||
typescript: 5.9.3
|
||||
transitivePeerDependencies:
|
||||
- '@ts-macro/tsc'
|
||||
- '@typescript/native-preview'
|
||||
- oxc-resolver
|
||||
- synckit
|
||||
- vue-tsc
|
||||
|
||||
tslib@2.8.1: {}
|
||||
|
||||
tslog@4.10.2: {}
|
||||
@@ -10938,11 +10531,6 @@ snapshots:
|
||||
|
||||
uint8array-extras@1.5.0: {}
|
||||
|
||||
unconfig-core@7.4.2:
|
||||
dependencies:
|
||||
'@quansync/fs': 1.0.0
|
||||
quansync: 1.0.0
|
||||
|
||||
undici-types@6.21.0: {}
|
||||
|
||||
undici-types@7.16.0: {}
|
||||
@@ -10957,10 +10545,6 @@ snapshots:
|
||||
|
||||
unpipe@1.0.0: {}
|
||||
|
||||
unrun@0.2.26:
|
||||
dependencies:
|
||||
rolldown: 1.0.0-rc.1
|
||||
|
||||
uri-js@4.4.1:
|
||||
dependencies:
|
||||
punycode: 2.3.1
|
||||
|
||||
@@ -31,7 +31,7 @@ echo "Starting gateway container..."
|
||||
-e "OPENCLAW_SKIP_CRON=1" \
|
||||
-e "OPENCLAW_SKIP_CANVAS_HOST=1" \
|
||||
"$IMAGE_NAME" \
|
||||
bash -lc "node dist/index.mjs gateway --port $PORT --bind lan --allow-unconfigured > /tmp/gateway-net-e2e.log 2>&1"
|
||||
bash -lc "node dist/index.js gateway --port $PORT --bind lan --allow-unconfigured > /tmp/gateway-net-e2e.log 2>&1"
|
||||
|
||||
echo "Waiting for gateway to come up..."
|
||||
for _ in $(seq 1 20); do
|
||||
|
||||
@@ -83,7 +83,7 @@ TRASH
|
||||
}
|
||||
|
||||
start_gateway() {
|
||||
node dist/index.mjs gateway --port 18789 --bind loopback --allow-unconfigured > /tmp/gateway-e2e.log 2>&1 &
|
||||
node dist/index.js gateway --port 18789 --bind loopback --allow-unconfigured > /tmp/gateway-e2e.log 2>&1 &
|
||||
GATEWAY_PID="$!"
|
||||
}
|
||||
|
||||
@@ -185,7 +185,7 @@ TRASH
|
||||
local validate_fn="${4:-}"
|
||||
|
||||
# Default onboarding command wrapper.
|
||||
run_wizard_cmd "$case_name" "$home_dir" "node dist/index.mjs onboard $ONBOARD_FLAGS" "$send_fn" true "$validate_fn"
|
||||
run_wizard_cmd "$case_name" "$home_dir" "node dist/index.js onboard $ONBOARD_FLAGS" "$send_fn" true "$validate_fn"
|
||||
}
|
||||
|
||||
make_home() {
|
||||
@@ -268,7 +268,7 @@ TRASH
|
||||
home_dir="$(make_home local-basic)"
|
||||
export HOME="$home_dir"
|
||||
mkdir -p "$HOME"
|
||||
node dist/index.mjs onboard \
|
||||
node dist/index.js onboard \
|
||||
--non-interactive \
|
||||
--accept-risk \
|
||||
--flow quickstart \
|
||||
@@ -345,7 +345,7 @@ NODE
|
||||
export HOME="$home_dir"
|
||||
mkdir -p "$HOME"
|
||||
# Smoke test non-interactive remote config write.
|
||||
node dist/index.mjs onboard --non-interactive --accept-risk \
|
||||
node dist/index.js onboard --non-interactive --accept-risk \
|
||||
--mode remote \
|
||||
--remote-url ws://gateway.local:18789 \
|
||||
--remote-token remote-token \
|
||||
@@ -398,7 +398,7 @@ NODE
|
||||
}
|
||||
JSON
|
||||
|
||||
node dist/index.mjs onboard \
|
||||
node dist/index.js onboard \
|
||||
--non-interactive \
|
||||
--accept-risk \
|
||||
--flow quickstart \
|
||||
@@ -441,7 +441,7 @@ NODE
|
||||
local home_dir
|
||||
home_dir="$(make_home channels)"
|
||||
# Channels-only configure flow.
|
||||
run_wizard_cmd channels "$home_dir" "node dist/index.mjs configure --section channels" send_channels_flow
|
||||
run_wizard_cmd channels "$home_dir" "node dist/index.js configure --section channels" send_channels_flow
|
||||
|
||||
config_path="$HOME/.openclaw/openclaw.json"
|
||||
assert_file "$config_path"
|
||||
@@ -492,7 +492,7 @@ NODE
|
||||
}
|
||||
JSON
|
||||
|
||||
run_wizard_cmd skills "$home_dir" "node dist/index.mjs configure --section skills" send_skills_flow
|
||||
run_wizard_cmd skills "$home_dir" "node dist/index.js configure --section skills" send_skills_flow
|
||||
|
||||
config_path="$HOME/.openclaw/openclaw.json"
|
||||
assert_file "$config_path"
|
||||
|
||||
@@ -29,7 +29,7 @@ module.exports = {
|
||||
};
|
||||
JS
|
||||
|
||||
node dist/index.mjs plugins list --json > /tmp/plugins.json
|
||||
node dist/index.js plugins list --json > /tmp/plugins.json
|
||||
|
||||
node - <<'"'"'NODE'"'"'
|
||||
const fs = require("node:fs");
|
||||
@@ -81,8 +81,8 @@ module.exports = {
|
||||
JS
|
||||
tar -czf /tmp/demo-plugin-tgz.tgz -C "$pack_dir" package
|
||||
|
||||
node dist/index.mjs plugins install /tmp/demo-plugin-tgz.tgz
|
||||
node dist/index.mjs plugins list --json > /tmp/plugins2.json
|
||||
node dist/index.js plugins install /tmp/demo-plugin-tgz.tgz
|
||||
node dist/index.js plugins list --json > /tmp/plugins2.json
|
||||
|
||||
node - <<'"'"'NODE'"'"'
|
||||
const fs = require("node:fs");
|
||||
@@ -118,8 +118,8 @@ module.exports = {
|
||||
};
|
||||
JS
|
||||
|
||||
node dist/index.mjs plugins install "$dir_plugin"
|
||||
node dist/index.mjs plugins list --json > /tmp/plugins3.json
|
||||
node dist/index.js plugins install "$dir_plugin"
|
||||
node dist/index.js plugins list --json > /tmp/plugins3.json
|
||||
|
||||
node - <<'"'"'NODE'"'"'
|
||||
const fs = require("node:fs");
|
||||
@@ -156,8 +156,8 @@ module.exports = {
|
||||
};
|
||||
JS
|
||||
|
||||
node dist/index.mjs plugins install "file:$file_pack_dir/package"
|
||||
node dist/index.mjs plugins list --json > /tmp/plugins4.json
|
||||
node dist/index.js plugins install "file:$file_pack_dir/package"
|
||||
node dist/index.js plugins list --json > /tmp/plugins4.json
|
||||
|
||||
node - <<'"'"'NODE'"'"'
|
||||
const fs = require("node:fs");
|
||||
|
||||
@@ -110,8 +110,8 @@ merge_framework_machos() {
|
||||
echo "📦 Ensuring deps (pnpm install)"
|
||||
(cd "$ROOT_DIR" && pnpm install --no-frozen-lockfile --config.node-linker=hoisted)
|
||||
if [[ "${SKIP_TSC:-0}" != "1" ]]; then
|
||||
echo "📦 Building JS (pnpm tsdown)"
|
||||
(cd "$ROOT_DIR" && pnpm tsdown)
|
||||
echo "📦 Building JS (pnpm tsc)"
|
||||
(cd "$ROOT_DIR" && pnpm tsc -p tsconfig.json --noEmit false)
|
||||
else
|
||||
echo "📦 Skipping TS build (SKIP_TSC=1)"
|
||||
fi
|
||||
|
||||
@@ -1,34 +1,36 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { setupGitHooks } from "./setup-git-hooks.js";
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { spawnSync } from 'node:child_process';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { setupGitHooks } from './setup-git-hooks.js';
|
||||
|
||||
function detectPackageManager(ua = process.env.npm_config_user_agent ?? "") {
|
||||
function detectPackageManager(ua = process.env.npm_config_user_agent ?? '') {
|
||||
// Examples:
|
||||
// - "pnpm/10.23.0 npm/? node/v22.21.1 darwin arm64"
|
||||
// - "npm/10.9.4 node/v22.12.0 linux x64"
|
||||
// - "bun/1.2.2"
|
||||
const normalized = String(ua).trim();
|
||||
if (normalized.startsWith("pnpm/")) return "pnpm";
|
||||
if (normalized.startsWith("bun/")) return "bun";
|
||||
if (normalized.startsWith("npm/")) return "npm";
|
||||
if (normalized.startsWith("yarn/")) return "yarn";
|
||||
return "unknown";
|
||||
if (normalized.startsWith('pnpm/')) return 'pnpm';
|
||||
if (normalized.startsWith('bun/')) return 'bun';
|
||||
if (normalized.startsWith('npm/')) return 'npm';
|
||||
if (normalized.startsWith('yarn/')) return 'yarn';
|
||||
return 'unknown';
|
||||
}
|
||||
|
||||
function shouldApplyPnpmPatchedDependenciesFallback(pm = detectPackageManager()) {
|
||||
function shouldApplyPnpmPatchedDependenciesFallback(
|
||||
pm = detectPackageManager(),
|
||||
) {
|
||||
// pnpm already applies pnpm.patchedDependencies itself; re-applying would fail.
|
||||
return pm !== "pnpm";
|
||||
return pm !== 'pnpm';
|
||||
}
|
||||
|
||||
function getRepoRoot() {
|
||||
const here = path.dirname(fileURLToPath(import.meta.url));
|
||||
return path.resolve(here, "..");
|
||||
return path.resolve(here, '..');
|
||||
}
|
||||
|
||||
function ensureExecutable(targetPath) {
|
||||
if (process.platform === "win32") return;
|
||||
if (process.platform === 'win32') return;
|
||||
if (!fs.existsSync(targetPath)) return;
|
||||
try {
|
||||
const mode = fs.statSync(targetPath).mode & 0o777;
|
||||
@@ -40,29 +42,32 @@ function ensureExecutable(targetPath) {
|
||||
}
|
||||
|
||||
function hasGit(repoRoot) {
|
||||
const result = spawnSync("git", ["--version"], { cwd: repoRoot, stdio: "ignore" });
|
||||
const result = spawnSync('git', ['--version'], {
|
||||
cwd: repoRoot,
|
||||
stdio: 'ignore',
|
||||
});
|
||||
return result.status === 0;
|
||||
}
|
||||
|
||||
function extractPackageName(key) {
|
||||
if (key.startsWith("@")) {
|
||||
const idx = key.indexOf("@", 1);
|
||||
if (key.startsWith('@')) {
|
||||
const idx = key.indexOf('@', 1);
|
||||
if (idx === -1) return key;
|
||||
return key.slice(0, idx);
|
||||
}
|
||||
const idx = key.lastIndexOf("@");
|
||||
const idx = key.lastIndexOf('@');
|
||||
if (idx <= 0) return key;
|
||||
return key.slice(0, idx);
|
||||
}
|
||||
|
||||
function stripPrefix(p) {
|
||||
if (p.startsWith("a/") || p.startsWith("b/")) return p.slice(2);
|
||||
if (p.startsWith('a/') || p.startsWith('b/')) return p.slice(2);
|
||||
return p;
|
||||
}
|
||||
|
||||
function parseRange(segment) {
|
||||
// segment: "-12,5" or "+7"
|
||||
const [startRaw, countRaw] = segment.slice(1).split(",");
|
||||
const [startRaw, countRaw] = segment.slice(1).split(',');
|
||||
const start = Number.parseInt(startRaw, 10);
|
||||
const count = countRaw ? Number.parseInt(countRaw, 10) : 1;
|
||||
if (Number.isNaN(start) || Number.isNaN(count)) {
|
||||
@@ -72,12 +77,12 @@ function parseRange(segment) {
|
||||
}
|
||||
|
||||
function parsePatch(patchText) {
|
||||
const lines = patchText.split("\n");
|
||||
const lines = patchText.split('\n');
|
||||
const files = [];
|
||||
let i = 0;
|
||||
|
||||
while (i < lines.length) {
|
||||
if (!lines[i].startsWith("diff --git ")) {
|
||||
if (!lines[i].startsWith('diff --git ')) {
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
@@ -86,20 +91,22 @@ function parsePatch(patchText) {
|
||||
i += 1;
|
||||
|
||||
// Skip index line(s)
|
||||
while (i < lines.length && lines[i].startsWith("index ")) i += 1;
|
||||
while (i < lines.length && lines[i].startsWith('index ')) i += 1;
|
||||
|
||||
if (i < lines.length && lines[i].startsWith("--- ")) {
|
||||
if (i < lines.length && lines[i].startsWith('--- ')) {
|
||||
file.oldPath = stripPrefix(lines[i].slice(4).trim());
|
||||
i += 1;
|
||||
}
|
||||
if (i < lines.length && lines[i].startsWith("+++ ")) {
|
||||
if (i < lines.length && lines[i].startsWith('+++ ')) {
|
||||
file.newPath = stripPrefix(lines[i].slice(4).trim());
|
||||
i += 1;
|
||||
}
|
||||
|
||||
while (i < lines.length && lines[i].startsWith("@@")) {
|
||||
while (i < lines.length && lines[i].startsWith('@@')) {
|
||||
const header = lines[i];
|
||||
const match = /^@@\s+(-\d+(?:,\d+)?)\s+(\+\d+(?:,\d+)?)\s+@@/.exec(header);
|
||||
const match = /^@@\s+(-\d+(?:,\d+)?)\s+(\+\d+(?:,\d+)?)\s+@@/.exec(
|
||||
header,
|
||||
);
|
||||
if (!match) throw new Error(`invalid hunk header: ${header}`);
|
||||
const oldRange = parseRange(match[1]);
|
||||
const newRange = parseRange(match[2]);
|
||||
@@ -108,12 +115,12 @@ function parsePatch(patchText) {
|
||||
const hunkLines = [];
|
||||
while (i < lines.length) {
|
||||
const line = lines[i];
|
||||
if (line.startsWith("@@") || line.startsWith("diff --git ")) break;
|
||||
if (line === "") {
|
||||
if (line.startsWith('@@') || line.startsWith('diff --git ')) break;
|
||||
if (line === '') {
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
if (line.startsWith("\\ No newline at end of file")) {
|
||||
if (line.startsWith('\\ No newline at end of file')) {
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
@@ -142,16 +149,16 @@ function readFileLines(targetPath) {
|
||||
if (!fs.existsSync(targetPath)) {
|
||||
throw new Error(`target file missing: ${targetPath}`);
|
||||
}
|
||||
const raw = fs.readFileSync(targetPath, "utf-8");
|
||||
const hasTrailingNewline = raw.endsWith("\n");
|
||||
const parts = raw.split("\n");
|
||||
const raw = fs.readFileSync(targetPath, 'utf-8');
|
||||
const hasTrailingNewline = raw.endsWith('\n');
|
||||
const parts = raw.split('\n');
|
||||
if (hasTrailingNewline) parts.pop();
|
||||
return { lines: parts, hasTrailingNewline };
|
||||
}
|
||||
|
||||
function writeFileLines(targetPath, lines, hadTrailingNewline) {
|
||||
const content = lines.join("\n") + (hadTrailingNewline ? "\n" : "");
|
||||
fs.writeFileSync(targetPath, content, "utf-8");
|
||||
const content = lines.join('\n') + (hadTrailingNewline ? '\n' : '');
|
||||
fs.writeFileSync(targetPath, content, 'utf-8');
|
||||
}
|
||||
|
||||
function applyHunk(lines, hunk, offset) {
|
||||
@@ -159,7 +166,7 @@ function applyHunk(lines, hunk, offset) {
|
||||
const expected = [];
|
||||
for (const raw of hunk.lines) {
|
||||
const marker = raw[0];
|
||||
if (marker === " " || marker === "+") {
|
||||
if (marker === ' ' || marker === '+') {
|
||||
expected.push(raw.slice(1));
|
||||
}
|
||||
}
|
||||
@@ -180,21 +187,21 @@ function applyHunk(lines, hunk, offset) {
|
||||
for (const raw of hunk.lines) {
|
||||
const marker = raw[0];
|
||||
const text = raw.slice(1);
|
||||
if (marker === " ") {
|
||||
if (marker === ' ') {
|
||||
if (lines[cursor] !== text) {
|
||||
throw new Error(
|
||||
`context mismatch at line ${cursor + 1}: expected "${text}", found "${lines[cursor] ?? "<eof>"}"`,
|
||||
`context mismatch at line ${cursor + 1}: expected "${text}", found "${lines[cursor] ?? '<eof>'}"`,
|
||||
);
|
||||
}
|
||||
cursor += 1;
|
||||
} else if (marker === "-") {
|
||||
} else if (marker === '-') {
|
||||
if (lines[cursor] !== text) {
|
||||
throw new Error(
|
||||
`delete mismatch at line ${cursor + 1}: expected "${text}", found "${lines[cursor] ?? "<eof>"}"`,
|
||||
`delete mismatch at line ${cursor + 1}: expected "${text}", found "${lines[cursor] ?? '<eof>'}"`,
|
||||
);
|
||||
}
|
||||
lines.splice(cursor, 1);
|
||||
} else if (marker === "+") {
|
||||
} else if (marker === '+') {
|
||||
lines.splice(cursor, 0, text);
|
||||
cursor += 1;
|
||||
} else {
|
||||
@@ -207,11 +214,11 @@ function applyHunk(lines, hunk, offset) {
|
||||
}
|
||||
|
||||
function applyPatchToFile(targetDir, filePatch) {
|
||||
if (filePatch.newPath === "/dev/null") {
|
||||
if (filePatch.newPath === '/dev/null') {
|
||||
// deletion not needed for our patches
|
||||
return;
|
||||
}
|
||||
const relPath = stripPrefix(filePatch.newPath ?? filePatch.oldPath ?? "");
|
||||
const relPath = stripPrefix(filePatch.newPath ?? filePatch.oldPath ?? '');
|
||||
const targetPath = path.join(targetDir, relPath);
|
||||
const { lines, hasTrailingNewline } = readFileLines(targetPath);
|
||||
|
||||
@@ -225,7 +232,10 @@ function applyPatchToFile(targetDir, filePatch) {
|
||||
|
||||
function applyPatchSet({ patchText, targetDir }) {
|
||||
let resolvedTarget = path.resolve(targetDir);
|
||||
if (!fs.existsSync(resolvedTarget) || !fs.statSync(resolvedTarget).isDirectory()) {
|
||||
if (
|
||||
!fs.existsSync(resolvedTarget) ||
|
||||
!fs.statSync(resolvedTarget).isDirectory()
|
||||
) {
|
||||
console.warn(`[postinstall] skip missing target: ${resolvedTarget}`);
|
||||
return;
|
||||
}
|
||||
@@ -244,28 +254,28 @@ function applyPatchFile({ patchPath, targetDir }) {
|
||||
if (!fs.existsSync(absPatchPath)) {
|
||||
throw new Error(`missing patch: ${absPatchPath}`);
|
||||
}
|
||||
const patchText = fs.readFileSync(absPatchPath, "utf-8");
|
||||
const patchText = fs.readFileSync(absPatchPath, 'utf-8');
|
||||
applyPatchSet({ patchText, targetDir });
|
||||
}
|
||||
|
||||
function trySetupCompletion(repoRoot) {
|
||||
// Skip in CI or if explicitly disabled
|
||||
if (process.env.CI || process.env.OPENCLAW_SKIP_COMPLETION_SETUP) return;
|
||||
|
||||
const binPath = path.join(repoRoot, "openclaw.mjs");
|
||||
|
||||
const binPath = path.join(repoRoot, 'openclaw.mjs');
|
||||
if (!fs.existsSync(binPath)) return;
|
||||
|
||||
|
||||
// In development, dist might not exist yet during postinstall
|
||||
const distEntry = path.join(repoRoot, "dist", "index.js");
|
||||
const distEntry = path.join(repoRoot, 'dist', 'index.js');
|
||||
if (!fs.existsSync(distEntry)) return;
|
||||
|
||||
try {
|
||||
// Run with OPENCLAW_SKIP_POSTINSTALL to avoid any weird recursion,
|
||||
// though distinct from this script.
|
||||
spawnSync(process.execPath, [binPath, "completion", "--install", "--yes"], {
|
||||
spawnSync(process.execPath, [binPath, 'completion', '--install', '--yes'], {
|
||||
cwd: repoRoot,
|
||||
stdio: "inherit",
|
||||
env: { ...process.env, OPENCLAW_SKIP_POSTINSTALL: "1" },
|
||||
stdio: 'inherit',
|
||||
env: { ...process.env, OPENCLAW_SKIP_POSTINSTALL: '1' },
|
||||
});
|
||||
} catch (err) {
|
||||
// Ignore errors to not break install
|
||||
@@ -276,7 +286,7 @@ function main() {
|
||||
const repoRoot = getRepoRoot();
|
||||
process.chdir(repoRoot);
|
||||
|
||||
ensureExecutable(path.join(repoRoot, "dist", "entry.mjs"));
|
||||
ensureExecutable(path.join(repoRoot, 'dist', '/entry.js'));
|
||||
setupGitHooks({ repoRoot });
|
||||
trySetupCompletion(repoRoot);
|
||||
|
||||
@@ -284,18 +294,18 @@ function main() {
|
||||
return;
|
||||
}
|
||||
|
||||
const pkgPath = path.join(repoRoot, "package.json");
|
||||
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
||||
const pkgPath = path.join(repoRoot, 'package.json');
|
||||
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
||||
const patched = pkg?.pnpm?.patchedDependencies ?? {};
|
||||
|
||||
// Bun does not support pnpm.patchedDependencies. Apply these patch files to
|
||||
// node_modules packages as a best-effort compatibility layer.
|
||||
for (const [key, relPatchPath] of Object.entries(patched)) {
|
||||
if (typeof relPatchPath !== "string" || !relPatchPath.trim()) continue;
|
||||
if (typeof relPatchPath !== 'string' || !relPatchPath.trim()) continue;
|
||||
const pkgName = extractPackageName(String(key));
|
||||
if (!pkgName) continue;
|
||||
applyPatchFile({
|
||||
targetDir: path.join("node_modules", ...pkgName.split("/")),
|
||||
targetDir: path.join('node_modules', ...pkgName.split('/')),
|
||||
patchPath: relPatchPath,
|
||||
});
|
||||
}
|
||||
@@ -303,10 +313,10 @@ function main() {
|
||||
|
||||
try {
|
||||
const skip =
|
||||
process.env.OPENCLAW_SKIP_POSTINSTALL === "1" ||
|
||||
process.env.CLAWDBOT_SKIP_POSTINSTALL === "1" ||
|
||||
process.env.VITEST === "true" ||
|
||||
process.env.NODE_ENV === "test";
|
||||
process.env.OPENCLAW_SKIP_POSTINSTALL === '1' ||
|
||||
process.env.CLAWDBOT_SKIP_POSTINSTALL === '1' ||
|
||||
process.env.VITEST === 'true' ||
|
||||
process.env.NODE_ENV === 'test';
|
||||
|
||||
if (!skip) {
|
||||
main();
|
||||
|
||||
@@ -1,21 +1,24 @@
|
||||
#!/usr/bin/env node
|
||||
import { spawn } from "node:child_process";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import process from "node:process";
|
||||
import { spawn } from 'node:child_process';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import process from 'node:process';
|
||||
|
||||
const args = process.argv.slice(2);
|
||||
const env = { ...process.env };
|
||||
const cwd = process.cwd();
|
||||
const compilerOverride = env.OPENCLAW_TS_COMPILER ?? env.CLAWDBOT_TS_COMPILER;
|
||||
const compiler = compilerOverride === "tsc" ? "tsc" : "tsgo";
|
||||
const projectArgs = ["--project", "tsconfig.json"];
|
||||
const compiler = compilerOverride === 'tsc' ? 'tsc' : 'tsgo';
|
||||
const projectArgs = ['--project', 'tsconfig.json'];
|
||||
|
||||
const distRoot = path.join(cwd, "dist");
|
||||
const distEntry = path.join(distRoot, "entry.mjs");
|
||||
const buildStampPath = path.join(distRoot, ".buildstamp");
|
||||
const srcRoot = path.join(cwd, "src");
|
||||
const configFiles = [path.join(cwd, "tsconfig.json"), path.join(cwd, "package.json")];
|
||||
const distRoot = path.join(cwd, 'dist');
|
||||
const distEntry = path.join(distRoot, '/entry.js');
|
||||
const buildStampPath = path.join(distRoot, '.buildstamp');
|
||||
const srcRoot = path.join(cwd, 'src');
|
||||
const configFiles = [
|
||||
path.join(cwd, 'tsconfig.json'),
|
||||
path.join(cwd, 'package.json'),
|
||||
];
|
||||
|
||||
const statMtime = (filePath) => {
|
||||
try {
|
||||
@@ -27,10 +30,10 @@ const statMtime = (filePath) => {
|
||||
|
||||
const isExcludedSource = (filePath) => {
|
||||
const relativePath = path.relative(srcRoot, filePath);
|
||||
if (relativePath.startsWith("..")) return false;
|
||||
if (relativePath.startsWith('..')) return false;
|
||||
return (
|
||||
relativePath.endsWith(".test.ts") ||
|
||||
relativePath.endsWith(".test.tsx") ||
|
||||
relativePath.endsWith('.test.ts') ||
|
||||
relativePath.endsWith('.test.tsx') ||
|
||||
relativePath.endsWith(`test-helpers.ts`)
|
||||
);
|
||||
};
|
||||
@@ -66,7 +69,7 @@ const findLatestMtime = (dirPath, shouldSkip) => {
|
||||
};
|
||||
|
||||
const shouldBuild = () => {
|
||||
if (env.OPENCLAW_FORCE_BUILD === "1") return true;
|
||||
if (env.OPENCLAW_FORCE_BUILD === '1') return true;
|
||||
const stampMtime = statMtime(buildStampPath);
|
||||
if (stampMtime == null) return true;
|
||||
if (statMtime(distEntry) == null) return true;
|
||||
@@ -82,18 +85,18 @@ const shouldBuild = () => {
|
||||
};
|
||||
|
||||
const logRunner = (message) => {
|
||||
if (env.OPENCLAW_RUNNER_LOG === "0") return;
|
||||
if (env.OPENCLAW_RUNNER_LOG === '0') return;
|
||||
process.stderr.write(`[openclaw] ${message}\n`);
|
||||
};
|
||||
|
||||
const runNode = () => {
|
||||
const nodeProcess = spawn(process.execPath, ["openclaw.mjs", ...args], {
|
||||
const nodeProcess = spawn(process.execPath, ['openclaw.mjs', ...args], {
|
||||
cwd,
|
||||
env,
|
||||
stdio: "inherit",
|
||||
stdio: 'inherit',
|
||||
});
|
||||
|
||||
nodeProcess.on("exit", (exitCode, exitSignal) => {
|
||||
nodeProcess.on('exit', (exitCode, exitSignal) => {
|
||||
if (exitSignal) {
|
||||
process.exit(1);
|
||||
}
|
||||
@@ -107,25 +110,29 @@ const writeBuildStamp = () => {
|
||||
fs.writeFileSync(buildStampPath, `${Date.now()}\n`);
|
||||
} catch (error) {
|
||||
// Best-effort stamp; still allow the runner to start.
|
||||
logRunner(`Failed to write build stamp: ${error?.message ?? "unknown error"}`);
|
||||
logRunner(
|
||||
`Failed to write build stamp: ${error?.message ?? 'unknown error'}`,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
if (!shouldBuild()) {
|
||||
runNode();
|
||||
} else {
|
||||
logRunner("Building TypeScript (dist is stale).");
|
||||
const pnpmArgs = ["exec", compiler, ...projectArgs];
|
||||
const buildCmd = process.platform === "win32" ? "cmd.exe" : "pnpm";
|
||||
logRunner('Building TypeScript (dist is stale).');
|
||||
const pnpmArgs = ['exec', compiler, ...projectArgs];
|
||||
const buildCmd = process.platform === 'win32' ? 'cmd.exe' : 'pnpm';
|
||||
const buildArgs =
|
||||
process.platform === "win32" ? ["/d", "/s", "/c", "pnpm", ...pnpmArgs] : pnpmArgs;
|
||||
process.platform === 'win32'
|
||||
? ['/d', '/s', '/c', 'pnpm', ...pnpmArgs]
|
||||
: pnpmArgs;
|
||||
const build = spawn(buildCmd, buildArgs, {
|
||||
cwd,
|
||||
env,
|
||||
stdio: "inherit",
|
||||
stdio: 'inherit',
|
||||
});
|
||||
|
||||
build.on("exit", (code, signal) => {
|
||||
build.on('exit', (code, signal) => {
|
||||
if (signal) {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ if (initialBuild.status !== 0) {
|
||||
process.exit(initialBuild.status ?? 1);
|
||||
}
|
||||
|
||||
const compilerProcess = spawn("pnpm", ["tsdown", '--watch', 'src/'], {
|
||||
const compilerProcess = spawn("pnpm", ["tsc", '-p', 'tsconfig.json', '--noEmit', 'false', '--watch'], {
|
||||
cwd,
|
||||
env,
|
||||
stdio: "inherit",
|
||||
|
||||
@@ -24,7 +24,7 @@ describe("ensureSkillsWatcher", () => {
|
||||
expect(ignored.some((re) => re.test("/tmp/workspace/skills/node_modules/pkg/index.js"))).toBe(
|
||||
true,
|
||||
);
|
||||
expect(ignored.some((re) => re.test("/tmp/workspace/skills/dist/index.mjs"))).toBe(true);
|
||||
expect(ignored.some((re) => re.test("/tmp/workspace/skills/dist/index.js"))).toBe(true);
|
||||
expect(ignored.some((re) => re.test("/tmp/workspace/skills/.git/config"))).toBe(true);
|
||||
expect(ignored.some((re) => re.test("/tmp/.hidden/skills/index.md"))).toBe(false);
|
||||
});
|
||||
|
||||
@@ -43,7 +43,7 @@ describe("browser CLI --browser-profile flag", () => {
|
||||
});
|
||||
|
||||
it("does not conflict with global --profile flag", () => {
|
||||
// The global --profile flag is handled by entry.mjs before Commander
|
||||
// The global --profile flag is handled by /entry.js before Commander
|
||||
// This test verifies --browser-profile is a separate option
|
||||
const program = new Command();
|
||||
program.name("test");
|
||||
|
||||
@@ -4,22 +4,22 @@ import { rewriteUpdateFlagArgv } from "./run-main.js";
|
||||
|
||||
describe("rewriteUpdateFlagArgv", () => {
|
||||
it("leaves argv unchanged when --update is absent", () => {
|
||||
const argv = ["node", "entry.mjs", "status"];
|
||||
const argv = ["node", "entry.js", "status"];
|
||||
expect(rewriteUpdateFlagArgv(argv)).toBe(argv);
|
||||
});
|
||||
|
||||
it("rewrites --update into the update command", () => {
|
||||
expect(rewriteUpdateFlagArgv(["node", "entry.mjs", "--update"])).toEqual([
|
||||
expect(rewriteUpdateFlagArgv(["node", "entry.js", "--update"])).toEqual([
|
||||
"node",
|
||||
"entry.mjs",
|
||||
"entry.js",
|
||||
"update",
|
||||
]);
|
||||
});
|
||||
|
||||
it("preserves global flags that appear before --update", () => {
|
||||
expect(rewriteUpdateFlagArgv(["node", "entry.mjs", "--profile", "p", "--update"])).toEqual([
|
||||
expect(rewriteUpdateFlagArgv(["node", "entry.js", "--profile", "p", "--update"])).toEqual([
|
||||
"node",
|
||||
"entry.mjs",
|
||||
"entry.js",
|
||||
"--profile",
|
||||
"p",
|
||||
"update",
|
||||
@@ -27,9 +27,9 @@ describe("rewriteUpdateFlagArgv", () => {
|
||||
});
|
||||
|
||||
it("keeps update options after the rewritten command", () => {
|
||||
expect(rewriteUpdateFlagArgv(["node", "entry.mjs", "--update", "--json"])).toEqual([
|
||||
expect(rewriteUpdateFlagArgv(["node", "entry.js", "--update", "--json"])).toEqual([
|
||||
"node",
|
||||
"entry.mjs",
|
||||
"entry.js",
|
||||
"update",
|
||||
"--json",
|
||||
]);
|
||||
|
||||
@@ -747,7 +747,7 @@ export async function updateCommand(opts: UpdateCommandOptions): Promise<void> {
|
||||
let afterVersion = beforeVersion;
|
||||
if (pkgRoot) {
|
||||
afterVersion = await readPackageVersion(pkgRoot);
|
||||
const entryPath = path.join(pkgRoot, "dist", "entry.mjs");
|
||||
const entryPath = path.join(pkgRoot, "dist", "entry.js");
|
||||
if (await pathExists(entryPath)) {
|
||||
const doctorStep = await runUpdateStep({
|
||||
name: `${CLI_NAME} doctor`,
|
||||
@@ -969,7 +969,9 @@ export async function updateCommand(opts: UpdateCommandOptions): Promise<void> {
|
||||
try {
|
||||
const { doctorCommand } = await import("../commands/doctor.js");
|
||||
const interactiveDoctor = Boolean(process.stdin.isTTY) && !opts.json && opts.yes !== true;
|
||||
await doctorCommand(defaultRuntime, { nonInteractive: !interactiveDoctor });
|
||||
await doctorCommand(defaultRuntime, {
|
||||
nonInteractive: !interactiveDoctor,
|
||||
});
|
||||
} catch (err) {
|
||||
defaultRuntime.log(theme.warn(`Doctor failed: ${String(err)}`));
|
||||
} finally {
|
||||
@@ -1220,7 +1222,9 @@ ${theme.muted("Docs:")} ${formatDocsLink("/cli/update", "docs.openclaw.ai/cli/up
|
||||
)
|
||||
.action(async (opts) => {
|
||||
try {
|
||||
await updateWizardCommand({ timeout: opts.timeout as string | undefined });
|
||||
await updateWizardCommand({
|
||||
timeout: opts.timeout as string | undefined,
|
||||
});
|
||||
} catch (err) {
|
||||
defaultRuntime.error(String(err));
|
||||
defaultRuntime.exit(1);
|
||||
|
||||
@@ -103,7 +103,12 @@ vi.mock("../memory/manager.js", () => ({
|
||||
sourceCounts: [{ source: "memory", files: 2, chunks: 3 }],
|
||||
cache: { enabled: true, entries: 10, maxEntries: 500 },
|
||||
fts: { enabled: true, available: true },
|
||||
vector: { enabled: true, available: true, extensionPath: "/opt/vec0.dylib", dims: 1024 },
|
||||
vector: {
|
||||
enabled: true,
|
||||
available: true,
|
||||
extensionPath: "/opt/vec0.dylib",
|
||||
dims: 1024,
|
||||
},
|
||||
}),
|
||||
close: vi.fn(async () => {}),
|
||||
__agentId: agentId,
|
||||
@@ -254,7 +259,7 @@ vi.mock("../daemon/service.js", () => ({
|
||||
isLoaded: async () => true,
|
||||
readRuntime: async () => ({ status: "running", pid: 1234 }),
|
||||
readCommand: async () => ({
|
||||
programArguments: ["node", "dist/entry.mjs", "gateway"],
|
||||
programArguments: ["node", "dist/entry.js", "gateway"],
|
||||
sourcePath: "/tmp/Library/LaunchAgents/bot.molt.gateway.plist",
|
||||
}),
|
||||
}),
|
||||
@@ -267,7 +272,7 @@ vi.mock("../daemon/node-service.js", () => ({
|
||||
isLoaded: async () => true,
|
||||
readRuntime: async () => ({ status: "running", pid: 4321 }),
|
||||
readCommand: async () => ({
|
||||
programArguments: ["node", "dist/entry.mjs", "node-host"],
|
||||
programArguments: ["node", "dist/entry.js", "node-host"],
|
||||
sourcePath: "/tmp/Library/LaunchAgents/bot.molt.node.plist",
|
||||
}),
|
||||
}),
|
||||
|
||||
@@ -24,7 +24,7 @@ afterEach(() => {
|
||||
describe("resolveGatewayProgramArguments", () => {
|
||||
it("uses realpath-resolved dist entry when running via npx shim", async () => {
|
||||
const argv1 = path.resolve("/tmp/.npm/_npx/63c3/node_modules/.bin/openclaw");
|
||||
const entryPath = path.resolve("/tmp/.npm/_npx/63c3/node_modules/openclaw/dist/entry.mjs");
|
||||
const entryPath = path.resolve("/tmp/.npm/_npx/63c3/node_modules/openclaw/dist/entry.js");
|
||||
process.argv = ["node", argv1];
|
||||
fsMocks.realpath.mockResolvedValue(entryPath);
|
||||
fsMocks.access.mockImplementation(async (target: string) => {
|
||||
@@ -49,10 +49,10 @@ describe("resolveGatewayProgramArguments", () => {
|
||||
// Simulates pnpm global install where node_modules/openclaw is a symlink
|
||||
// to .pnpm/openclaw@X.Y.Z/node_modules/openclaw
|
||||
const symlinkPath = path.resolve(
|
||||
"/Users/test/Library/pnpm/global/5/node_modules/openclaw/dist/entry.mjs",
|
||||
"/Users/test/Library/pnpm/global/5/node_modules/openclaw/dist/entry.js",
|
||||
);
|
||||
const realpathResolved = path.resolve(
|
||||
"/Users/test/Library/pnpm/global/5/node_modules/.pnpm/openclaw@2026.1.21-2/node_modules/openclaw/dist/entry.mjs",
|
||||
"/Users/test/Library/pnpm/global/5/node_modules/.pnpm/openclaw@2026.1.21-2/node_modules/openclaw/dist/entry.js",
|
||||
);
|
||||
process.argv = ["node", symlinkPath];
|
||||
fsMocks.realpath.mockResolvedValue(realpathResolved);
|
||||
@@ -67,7 +67,7 @@ describe("resolveGatewayProgramArguments", () => {
|
||||
|
||||
it("falls back to node_modules package dist when .bin path is not resolved", async () => {
|
||||
const argv1 = path.resolve("/tmp/.npm/_npx/63c3/node_modules/.bin/openclaw");
|
||||
const indexPath = path.resolve("/tmp/.npm/_npx/63c3/node_modules/openclaw/dist/index.mjs");
|
||||
const indexPath = path.resolve("/tmp/.npm/_npx/63c3/node_modules/openclaw/dist/index.js");
|
||||
process.argv = ["node", argv1];
|
||||
fsMocks.realpath.mockRejectedValue(new Error("no realpath"));
|
||||
fsMocks.access.mockImplementation(async (target: string) => {
|
||||
|
||||
@@ -47,7 +47,7 @@ export async function resolveControlUiDistIndexPath(
|
||||
}
|
||||
const normalized = path.resolve(argv1);
|
||||
|
||||
// Case 1: entrypoint is directly inside dist/ (e.g., dist/entry.mjs)
|
||||
// Case 1: entrypoint is directly inside dist/ (e.g., dist/entry.js)
|
||||
const distDir = path.dirname(normalized);
|
||||
if (path.basename(distDir) === "dist") {
|
||||
return path.join(distDir, "control-ui", "index.html");
|
||||
|
||||
@@ -73,8 +73,8 @@ function isGatewayArgv(args: string[]): boolean {
|
||||
}
|
||||
|
||||
const entryCandidates = [
|
||||
"dist/index.mjs",
|
||||
"dist/entry.mjs",
|
||||
"dist/index.js",
|
||||
"dist/entry.js",
|
||||
"openclaw.mjs",
|
||||
"scripts/run-node.mjs",
|
||||
"src/index.ts",
|
||||
|
||||
@@ -6,8 +6,8 @@ describe("isMainModule", () => {
|
||||
it("returns true when argv[1] matches current file", () => {
|
||||
expect(
|
||||
isMainModule({
|
||||
currentFile: "/repo/dist/index.mjs",
|
||||
argv: ["node", "/repo/dist/index.mjs"],
|
||||
currentFile: "/repo/dist/index.js",
|
||||
argv: ["node", "/repo/dist/index.js"],
|
||||
cwd: "/repo",
|
||||
env: {},
|
||||
}),
|
||||
@@ -17,10 +17,10 @@ describe("isMainModule", () => {
|
||||
it("returns true under PM2 when pm_exec_path matches current file", () => {
|
||||
expect(
|
||||
isMainModule({
|
||||
currentFile: "/repo/dist/index.mjs",
|
||||
currentFile: "/repo/dist/index.js",
|
||||
argv: ["node", "/pm2/lib/ProcessContainerFork.js"],
|
||||
cwd: "/repo",
|
||||
env: { pm_exec_path: "/repo/dist/index.mjs", pm_id: "0" },
|
||||
env: { pm_exec_path: "/repo/dist/index.js", pm_id: "0" },
|
||||
}),
|
||||
).toBe(true);
|
||||
});
|
||||
@@ -28,7 +28,7 @@ describe("isMainModule", () => {
|
||||
it("returns false when running under PM2 but this module is imported", () => {
|
||||
expect(
|
||||
isMainModule({
|
||||
currentFile: "/repo/node_modules/openclaw/dist/index.mjs",
|
||||
currentFile: "/repo/node_modules/openclaw/dist/index.js",
|
||||
argv: ["node", "/repo/app.js"],
|
||||
cwd: "/repo",
|
||||
env: { pm_exec_path: "/repo/app.js", pm_id: "0" },
|
||||
|
||||
@@ -37,7 +37,7 @@ describe("ports helpers", () => {
|
||||
expect(
|
||||
classifyPortListener(
|
||||
{
|
||||
commandLine: "node /Users/me/Projects/openclaw/dist/entry.mjs gateway",
|
||||
commandLine: "node /Users/me/Projects/openclaw/dist/entry.js gateway",
|
||||
},
|
||||
18789,
|
||||
),
|
||||
|
||||
@@ -102,11 +102,11 @@ describe("installPluginFromArchive", () => {
|
||||
JSON.stringify({
|
||||
name: "@openclaw/voice-call",
|
||||
version: "0.0.1",
|
||||
openclaw: { extensions: ["./dist/index.mjs"] },
|
||||
openclaw: { extensions: ["./dist/index.js"] },
|
||||
}),
|
||||
"utf-8",
|
||||
);
|
||||
fs.writeFileSync(path.join(pkgDir, "dist", "index.mjs"), "export {};", "utf-8");
|
||||
fs.writeFileSync(path.join(pkgDir, "dist", "index.js"), "export {};", "utf-8");
|
||||
|
||||
const archivePath = packToArchive({
|
||||
pkgDir,
|
||||
@@ -127,7 +127,7 @@ describe("installPluginFromArchive", () => {
|
||||
expect(result.pluginId).toBe("voice-call");
|
||||
expect(result.targetDir).toBe(path.join(stateDir, "extensions", "voice-call"));
|
||||
expect(fs.existsSync(path.join(result.targetDir, "package.json"))).toBe(true);
|
||||
expect(fs.existsSync(path.join(result.targetDir, "dist", "index.mjs"))).toBe(true);
|
||||
expect(fs.existsSync(path.join(result.targetDir, "dist", "index.js"))).toBe(true);
|
||||
});
|
||||
|
||||
it("rejects installing when plugin already exists", async () => {
|
||||
@@ -140,7 +140,7 @@ describe("installPluginFromArchive", () => {
|
||||
JSON.stringify({
|
||||
name: "@openclaw/voice-call",
|
||||
version: "0.0.1",
|
||||
openclaw: { extensions: ["./dist/index.mjs"] },
|
||||
openclaw: { extensions: ["./dist/index.js"] },
|
||||
}),
|
||||
"utf-8",
|
||||
);
|
||||
@@ -182,10 +182,10 @@ describe("installPluginFromArchive", () => {
|
||||
JSON.stringify({
|
||||
name: "@openclaw/zipper",
|
||||
version: "0.0.1",
|
||||
openclaw: { extensions: ["./dist/index.mjs"] },
|
||||
openclaw: { extensions: ["./dist/index.js"] },
|
||||
}),
|
||||
);
|
||||
zip.file("package/dist/index.mjs", "export {};");
|
||||
zip.file("package/dist/index.js", "export {};");
|
||||
const buffer = await zip.generateAsync({ type: "nodebuffer" });
|
||||
fs.writeFileSync(archivePath, buffer);
|
||||
|
||||
@@ -203,7 +203,7 @@ describe("installPluginFromArchive", () => {
|
||||
expect(result.pluginId).toBe("zipper");
|
||||
expect(result.targetDir).toBe(path.join(stateDir, "extensions", "zipper"));
|
||||
expect(fs.existsSync(path.join(result.targetDir, "package.json"))).toBe(true);
|
||||
expect(fs.existsSync(path.join(result.targetDir, "dist", "index.mjs"))).toBe(true);
|
||||
expect(fs.existsSync(path.join(result.targetDir, "dist", "index.js"))).toBe(true);
|
||||
});
|
||||
|
||||
it("allows updates when mode is update", async () => {
|
||||
@@ -216,7 +216,7 @@ describe("installPluginFromArchive", () => {
|
||||
JSON.stringify({
|
||||
name: "@openclaw/voice-call",
|
||||
version: "0.0.1",
|
||||
openclaw: { extensions: ["./dist/index.mjs"] },
|
||||
openclaw: { extensions: ["./dist/index.js"] },
|
||||
}),
|
||||
"utf-8",
|
||||
);
|
||||
@@ -234,7 +234,7 @@ describe("installPluginFromArchive", () => {
|
||||
JSON.stringify({
|
||||
name: "@openclaw/voice-call",
|
||||
version: "0.0.2",
|
||||
openclaw: { extensions: ["./dist/index.mjs"] },
|
||||
openclaw: { extensions: ["./dist/index.js"] },
|
||||
}),
|
||||
"utf-8",
|
||||
);
|
||||
|
||||
@@ -114,7 +114,7 @@ const spawnGatewayInstance = async (name: string): Promise<GatewayInstance> => {
|
||||
child = spawn(
|
||||
"node",
|
||||
[
|
||||
"dist/index.mjs",
|
||||
"dist/index.js",
|
||||
"gateway",
|
||||
"--port",
|
||||
String(port),
|
||||
@@ -201,7 +201,7 @@ const stopGatewayInstance = async (inst: GatewayInstance) => {
|
||||
const runCliJson = async (args: string[], env: NodeJS.ProcessEnv): Promise<unknown> => {
|
||||
const stdout: string[] = [];
|
||||
const stderr: string[] = [];
|
||||
const child = spawn("node", ["dist/index.mjs", ...args], {
|
||||
const child = spawn("node", ["dist/index.js", ...args], {
|
||||
cwd: process.cwd(),
|
||||
env: { ...process.env, ...env },
|
||||
stdio: ["ignore", "pipe", "pipe"],
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
import { defineConfig } from 'tsdown'
|
||||
|
||||
export default defineConfig([
|
||||
{
|
||||
entry: 'src/index.ts',
|
||||
platform: 'node',
|
||||
},
|
||||
{
|
||||
entry: 'src/entry.ts',
|
||||
platform: 'node',
|
||||
},
|
||||
])
|
||||
Reference in New Issue
Block a user