openclaw-lark-multi-agent 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +301 -0
- package/README.zh-CN.md +301 -0
- package/SECURITY.md +29 -0
- package/config.example.json +26 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +208 -0
- package/dist/config.d.ts +17 -0
- package/dist/config.js +28 -0
- package/dist/feishu-bot.d.ts +123 -0
- package/dist/feishu-bot.js +985 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +52 -0
- package/dist/message-store.d.ts +80 -0
- package/dist/message-store.js +333 -0
- package/dist/openclaw-client.d.ts +111 -0
- package/dist/openclaw-client.js +555 -0
- package/package.json +65 -0
- package/scripts/install-linux-systemd.sh +147 -0
- package/scripts/install-windows-service.bat +47 -0
- package/scripts/openclaw-lark-multi-agent.plist +29 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
APP_NAME="openclaw-lark-multi-agent"
|
|
5
|
+
SERVICE_NAME="${APP_NAME}.service"
|
|
6
|
+
MODE="user"
|
|
7
|
+
DEPLOY_DIR="${LMA_DEPLOY_DIR:-$HOME/.local/lib/$APP_NAME}"
|
|
8
|
+
STATE_DIR="${LMA_STATE_DIR:-$HOME/.openclaw/$APP_NAME}"
|
|
9
|
+
RESTART="1"
|
|
10
|
+
SUDO_CMD="${SUDO_CMD:-sudo}"
|
|
11
|
+
|
|
12
|
+
usage() {
|
|
13
|
+
cat <<USAGE
|
|
14
|
+
Usage: $0 [--user|--system] [--deploy-dir DIR] [--state-dir DIR] [--no-restart]
|
|
15
|
+
|
|
16
|
+
Build and deploy ${APP_NAME} to a runtime directory, then install a systemd service.
|
|
17
|
+
|
|
18
|
+
Defaults:
|
|
19
|
+
mode: --user
|
|
20
|
+
deploy dir: ~/.local/lib/${APP_NAME}
|
|
21
|
+
state dir: ~/.openclaw/${APP_NAME}
|
|
22
|
+
|
|
23
|
+
Examples:
|
|
24
|
+
$0
|
|
25
|
+
$0 --system
|
|
26
|
+
$0 --deploy-dir ~/.local/lib/${APP_NAME}-prod --state-dir ~/.openclaw/${APP_NAME}-prod
|
|
27
|
+
USAGE
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
while [[ $# -gt 0 ]]; do
|
|
31
|
+
case "$1" in
|
|
32
|
+
--user) MODE="user"; shift ;;
|
|
33
|
+
--system) MODE="system"; shift ;;
|
|
34
|
+
--deploy-dir) DEPLOY_DIR="$2"; shift 2 ;;
|
|
35
|
+
--state-dir) STATE_DIR="$2"; shift 2 ;;
|
|
36
|
+
--no-restart) RESTART="0"; shift ;;
|
|
37
|
+
-h|--help) usage; exit 0 ;;
|
|
38
|
+
*) echo "Unknown argument: $1" >&2; usage; exit 1 ;;
|
|
39
|
+
esac
|
|
40
|
+
done
|
|
41
|
+
|
|
42
|
+
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
43
|
+
NODE_BIN="${NODE_BIN:-$(command -v node)}"
|
|
44
|
+
NPM_BIN="${NPM_BIN:-$(command -v npm)}"
|
|
45
|
+
CURRENT_USER="$(id -un)"
|
|
46
|
+
|
|
47
|
+
if [[ -z "${NODE_BIN}" || -z "${NPM_BIN}" ]]; then
|
|
48
|
+
echo "node/npm not found in PATH" >&2
|
|
49
|
+
exit 1
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
cd "$ROOT_DIR"
|
|
53
|
+
echo "==> Building ${APP_NAME} from ${ROOT_DIR}"
|
|
54
|
+
"$NPM_BIN" ci
|
|
55
|
+
"$NPM_BIN" run build
|
|
56
|
+
|
|
57
|
+
mkdir -p "$DEPLOY_DIR/dist" "$STATE_DIR/data"
|
|
58
|
+
|
|
59
|
+
# First install convenience: migrate existing local runtime data if the state dir
|
|
60
|
+
# does not already have a database. Future installs preserve state data in place.
|
|
61
|
+
if [[ ! -f "$STATE_DIR/data/messages.db" && -d "$ROOT_DIR/data" ]]; then
|
|
62
|
+
echo "==> Migrating existing data/ to state dir"
|
|
63
|
+
cp -a "$ROOT_DIR/data/." "$STATE_DIR/data/"
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
echo "==> Deploying runtime files to ${DEPLOY_DIR}"
|
|
67
|
+
# Deploy build output only; source files are intentionally not copied.
|
|
68
|
+
rsync -a --delete "$ROOT_DIR/dist/" "$DEPLOY_DIR/dist/"
|
|
69
|
+
cp "$ROOT_DIR/package.json" "$DEPLOY_DIR/package.json"
|
|
70
|
+
cp "$ROOT_DIR/package-lock.json" "$DEPLOY_DIR/package-lock.json"
|
|
71
|
+
|
|
72
|
+
if [[ -f "$STATE_DIR/config.json" ]]; then
|
|
73
|
+
echo "==> Keeping existing config: ${STATE_DIR}/config.json"
|
|
74
|
+
elif [[ -f "$ROOT_DIR/config.json" ]]; then
|
|
75
|
+
echo "==> Copying config.json to state dir"
|
|
76
|
+
cp "$ROOT_DIR/config.json" "$STATE_DIR/config.json"
|
|
77
|
+
elif [[ -f "$ROOT_DIR/config.example.json" ]]; then
|
|
78
|
+
echo "==> Creating config.json from config.example.json (edit before use)"
|
|
79
|
+
cp "$ROOT_DIR/config.example.json" "$STATE_DIR/config.json"
|
|
80
|
+
else
|
|
81
|
+
echo "WARNING: no config.json or config.example.json found" >&2
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
# Install runtime dependencies only in deploy dir.
|
|
85
|
+
echo "==> Installing production dependencies in deploy dir"
|
|
86
|
+
(cd "$DEPLOY_DIR" && "$NPM_BIN" ci --omit=dev)
|
|
87
|
+
|
|
88
|
+
UNIT_CONTENT="[Unit]
|
|
89
|
+
Description=OpenClaw Lark Multi-Agent - Multi-bot bridge for OpenClaw
|
|
90
|
+
After=network.target
|
|
91
|
+
Wants=network-online.target
|
|
92
|
+
|
|
93
|
+
[Service]
|
|
94
|
+
Type=simple
|
|
95
|
+
WorkingDirectory=${DEPLOY_DIR}
|
|
96
|
+
ExecStart=${NODE_BIN} dist/index.js ${STATE_DIR}/config.json
|
|
97
|
+
Restart=always
|
|
98
|
+
RestartSec=5
|
|
99
|
+
Environment=NODE_ENV=production
|
|
100
|
+
Environment=LMA_DATA_DIR=${STATE_DIR}/data
|
|
101
|
+
|
|
102
|
+
# Logging
|
|
103
|
+
StandardOutput=journal
|
|
104
|
+
StandardError=journal
|
|
105
|
+
SyslogIdentifier=${APP_NAME}
|
|
106
|
+
"
|
|
107
|
+
|
|
108
|
+
if [[ "$MODE" == "system" ]]; then
|
|
109
|
+
UNIT_CONTENT+="User=${CURRENT_USER}
|
|
110
|
+
|
|
111
|
+
[Install]
|
|
112
|
+
WantedBy=multi-user.target
|
|
113
|
+
"
|
|
114
|
+
UNIT_PATH="/etc/systemd/system/${SERVICE_NAME}"
|
|
115
|
+
echo "==> Installing system service: ${UNIT_PATH}"
|
|
116
|
+
tmp_unit="$(mktemp)"
|
|
117
|
+
printf '%s' "$UNIT_CONTENT" > "$tmp_unit"
|
|
118
|
+
${SUDO_CMD} install -m 0644 "$tmp_unit" "$UNIT_PATH"
|
|
119
|
+
rm -f "$tmp_unit"
|
|
120
|
+
${SUDO_CMD} systemctl daemon-reload
|
|
121
|
+
${SUDO_CMD} systemctl enable "$SERVICE_NAME"
|
|
122
|
+
if [[ "$RESTART" == "1" ]]; then
|
|
123
|
+
${SUDO_CMD} systemctl restart "$SERVICE_NAME"
|
|
124
|
+
${SUDO_CMD} systemctl status "$SERVICE_NAME" --no-pager --lines=8 || true
|
|
125
|
+
fi
|
|
126
|
+
else
|
|
127
|
+
UNIT_CONTENT+="
|
|
128
|
+
[Install]
|
|
129
|
+
WantedBy=default.target
|
|
130
|
+
"
|
|
131
|
+
UNIT_DIR="$HOME/.config/systemd/user"
|
|
132
|
+
UNIT_PATH="${UNIT_DIR}/${SERVICE_NAME}"
|
|
133
|
+
mkdir -p "$UNIT_DIR"
|
|
134
|
+
echo "==> Installing user service: ${UNIT_PATH}"
|
|
135
|
+
printf '%s' "$UNIT_CONTENT" > "$UNIT_PATH"
|
|
136
|
+
systemctl --user daemon-reload
|
|
137
|
+
systemctl --user enable "$SERVICE_NAME"
|
|
138
|
+
if [[ "$RESTART" == "1" ]]; then
|
|
139
|
+
systemctl --user restart "$SERVICE_NAME"
|
|
140
|
+
systemctl --user status "$SERVICE_NAME" --no-pager --lines=8 || true
|
|
141
|
+
fi
|
|
142
|
+
fi
|
|
143
|
+
|
|
144
|
+
echo "==> Done"
|
|
145
|
+
echo "Deploy dir: ${DEPLOY_DIR}"
|
|
146
|
+
echo "State dir: ${STATE_DIR}"
|
|
147
|
+
echo "Mode: ${MODE}"
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
@echo off
|
|
2
|
+
REM Install openclaw-lark-multi-agent as a Windows Service using NSSM.
|
|
3
|
+
REM Recommended for npm installs:
|
|
4
|
+
REM npm install -g openclaw-lark-multi-agent
|
|
5
|
+
REM openclaw-lark-multi-agent init
|
|
6
|
+
REM openclaw-lark-multi-agent install-windows-service
|
|
7
|
+
REM
|
|
8
|
+
REM Download NSSM from https://nssm.cc/download and put nssm.exe in PATH.
|
|
9
|
+
|
|
10
|
+
SET SERVICE_NAME=openclaw-lark-multi-agent
|
|
11
|
+
SET STATE_DIR=%USERPROFILE%\.openclaw\openclaw-lark-multi-agent
|
|
12
|
+
SET CONFIG_PATH=%STATE_DIR%\config.json
|
|
13
|
+
SET DATA_DIR=%STATE_DIR%\data
|
|
14
|
+
|
|
15
|
+
IF NOT EXIST "%CONFIG_PATH%" (
|
|
16
|
+
openclaw-lark-multi-agent init
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
where openclaw-lark-multi-agent >nul 2>nul
|
|
20
|
+
IF ERRORLEVEL 1 (
|
|
21
|
+
echo openclaw-lark-multi-agent CLI not found in PATH.
|
|
22
|
+
echo Run: npm install -g openclaw-lark-multi-agent
|
|
23
|
+
pause
|
|
24
|
+
exit /b 1
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
FOR /F "usebackq delims=" %%i IN (`where openclaw-lark-multi-agent`) DO (
|
|
28
|
+
SET CLI_PATH=%%i
|
|
29
|
+
GOTO :found_cli
|
|
30
|
+
)
|
|
31
|
+
:found_cli
|
|
32
|
+
|
|
33
|
+
echo Installing %SERVICE_NAME%...
|
|
34
|
+
nssm install %SERVICE_NAME% "%CLI_PATH%" start "%CONFIG_PATH%"
|
|
35
|
+
nssm set %SERVICE_NAME% AppDirectory "%STATE_DIR%"
|
|
36
|
+
nssm set %SERVICE_NAME% AppStdout "%STATE_DIR%\stdout.log"
|
|
37
|
+
nssm set %SERVICE_NAME% AppStderr "%STATE_DIR%\stderr.log"
|
|
38
|
+
nssm set %SERVICE_NAME% AppRotateFiles 1
|
|
39
|
+
nssm set %SERVICE_NAME% AppRotateBytes 10485760
|
|
40
|
+
nssm set %SERVICE_NAME% AppEnvironmentExtra NODE_ENV=production LMA_DATA_DIR="%DATA_DIR%"
|
|
41
|
+
nssm set %SERVICE_NAME% Start SERVICE_AUTO_START
|
|
42
|
+
|
|
43
|
+
echo Starting %SERVICE_NAME%...
|
|
44
|
+
nssm start %SERVICE_NAME%
|
|
45
|
+
|
|
46
|
+
echo Done. Use "nssm status %SERVICE_NAME%" to check.
|
|
47
|
+
pause
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
+
<plist version="1.0">
|
|
4
|
+
<dict>
|
|
5
|
+
<key>Label</key>
|
|
6
|
+
<string>com.hackerphysics.openclaw-lark-multi-agent</string>
|
|
7
|
+
<key>ProgramArguments</key>
|
|
8
|
+
<array>
|
|
9
|
+
<string>/usr/local/bin/node</string>
|
|
10
|
+
<string>dist/index.js</string>
|
|
11
|
+
<string>config.json</string>
|
|
12
|
+
</array>
|
|
13
|
+
<key>WorkingDirectory</key>
|
|
14
|
+
<string>/Users/YOUR_USERNAME/openclaw-lark-multi-agent</string>
|
|
15
|
+
<key>RunAtLoad</key>
|
|
16
|
+
<true/>
|
|
17
|
+
<key>KeepAlive</key>
|
|
18
|
+
<true/>
|
|
19
|
+
<key>StandardOutPath</key>
|
|
20
|
+
<string>/tmp/openclaw-lark-multi-agent.log</string>
|
|
21
|
+
<key>StandardErrorPath</key>
|
|
22
|
+
<string>/tmp/openclaw-lark-multi-agent.err</string>
|
|
23
|
+
<key>EnvironmentVariables</key>
|
|
24
|
+
<dict>
|
|
25
|
+
<key>NODE_ENV</key>
|
|
26
|
+
<string>production</string>
|
|
27
|
+
</dict>
|
|
28
|
+
</dict>
|
|
29
|
+
</plist>
|