indieclaw-agent 2.0.0 → 2.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/index.js +36 -44
- package/install.sh +63 -22
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -143,12 +143,14 @@ try {
|
|
|
143
143
|
}
|
|
144
144
|
|
|
145
145
|
// --- OpenClaw Detection ---
|
|
146
|
-
|
|
146
|
+
const OPENCLAW_PORTS = [18789, 8080, 11434, 1234, 8000];
|
|
147
|
+
|
|
148
|
+
function tryOpenClawPort(port) {
|
|
147
149
|
return new Promise((resolve) => {
|
|
148
150
|
const req = http.request(
|
|
149
151
|
{
|
|
150
152
|
hostname: '127.0.0.1',
|
|
151
|
-
port
|
|
153
|
+
port,
|
|
152
154
|
path: '/v1/models',
|
|
153
155
|
method: 'GET',
|
|
154
156
|
timeout: 2000,
|
|
@@ -160,30 +162,44 @@ function detectOpenClaw() {
|
|
|
160
162
|
try {
|
|
161
163
|
const json = JSON.parse(body);
|
|
162
164
|
const models = (json.data || []).map((m) => m.id);
|
|
163
|
-
|
|
165
|
+
if (models.length > 0) {
|
|
166
|
+
resolve({ available: true, models, port });
|
|
167
|
+
} else {
|
|
168
|
+
resolve({ available: false, models: [], port });
|
|
169
|
+
}
|
|
164
170
|
} catch {
|
|
165
|
-
resolve({ available: false, models: [] });
|
|
171
|
+
resolve({ available: false, models: [], port });
|
|
166
172
|
}
|
|
167
173
|
});
|
|
168
174
|
}
|
|
169
175
|
);
|
|
170
176
|
req.on('timeout', () => {
|
|
171
177
|
req.destroy();
|
|
172
|
-
resolve({ available: false, models: [] });
|
|
178
|
+
resolve({ available: false, models: [], port });
|
|
173
179
|
});
|
|
174
180
|
req.on('error', () => {
|
|
175
|
-
resolve({ available: false, models: [] });
|
|
181
|
+
resolve({ available: false, models: [], port });
|
|
176
182
|
});
|
|
177
183
|
req.end();
|
|
178
184
|
});
|
|
179
185
|
}
|
|
180
186
|
|
|
187
|
+
async function detectOpenClaw() {
|
|
188
|
+
// Try all common ports in parallel
|
|
189
|
+
const results = await Promise.all(OPENCLAW_PORTS.map(tryOpenClawPort));
|
|
190
|
+
const found = results.find((r) => r.available);
|
|
191
|
+
if (found) {
|
|
192
|
+
return { available: true, models: found.models, port: found.port };
|
|
193
|
+
}
|
|
194
|
+
return { available: false, models: [], port: null };
|
|
195
|
+
}
|
|
196
|
+
|
|
181
197
|
// Run detection on startup
|
|
182
198
|
detectOpenClaw().then((oc) => {
|
|
183
199
|
if (oc.available) {
|
|
184
|
-
console.log(` [OpenClaw] Detected! Models: ${oc.models.join(', ')}`);
|
|
200
|
+
console.log(` [OpenClaw] Detected on port ${oc.port}! Models: ${oc.models.join(', ')}`);
|
|
185
201
|
} else {
|
|
186
|
-
console.log(
|
|
202
|
+
console.log(` [OpenClaw] Not detected on ports ${OPENCLAW_PORTS.join(', ')}`);
|
|
187
203
|
}
|
|
188
204
|
});
|
|
189
205
|
|
|
@@ -1190,42 +1206,18 @@ function handleCronHistory(ws, { id }) {
|
|
|
1190
1206
|
}
|
|
1191
1207
|
|
|
1192
1208
|
// --- Agent List (OpenClaw Models) ---
|
|
1193
|
-
function handleAgentList(ws, { id }) {
|
|
1194
|
-
const
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
}
|
|
1202
|
-
(
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
res.on('end', () => {
|
|
1206
|
-
try {
|
|
1207
|
-
const json = JSON.parse(body);
|
|
1208
|
-
const models = (json.data || []).map((m) => ({
|
|
1209
|
-
id: m.id,
|
|
1210
|
-
name: m.id,
|
|
1211
|
-
status: 'running',
|
|
1212
|
-
port: 18789,
|
|
1213
|
-
}));
|
|
1214
|
-
reply(ws, id, models);
|
|
1215
|
-
} catch {
|
|
1216
|
-
reply(ws, id, []);
|
|
1217
|
-
}
|
|
1218
|
-
});
|
|
1219
|
-
}
|
|
1220
|
-
);
|
|
1221
|
-
req.on('timeout', () => {
|
|
1222
|
-
req.destroy();
|
|
1223
|
-
reply(ws, id, []);
|
|
1224
|
-
});
|
|
1225
|
-
req.on('error', () => {
|
|
1226
|
-
reply(ws, id, []);
|
|
1227
|
-
});
|
|
1228
|
-
req.end();
|
|
1209
|
+
async function handleAgentList(ws, { id }) {
|
|
1210
|
+
const oc = await detectOpenClaw();
|
|
1211
|
+
if (oc.available) {
|
|
1212
|
+
const models = oc.models.map((modelId) => ({
|
|
1213
|
+
id: modelId,
|
|
1214
|
+
name: modelId,
|
|
1215
|
+
status: 'running',
|
|
1216
|
+
port: oc.port,
|
|
1217
|
+
}));
|
|
1218
|
+
return reply(ws, id, models);
|
|
1219
|
+
}
|
|
1220
|
+
reply(ws, id, []);
|
|
1229
1221
|
}
|
|
1230
1222
|
|
|
1231
1223
|
// --- Agent Logs ---
|
package/install.sh
CHANGED
|
@@ -23,7 +23,7 @@ else
|
|
|
23
23
|
fi
|
|
24
24
|
|
|
25
25
|
# Step 1: Check/Install Node.js
|
|
26
|
-
echo -e "${YELLOW}[1/
|
|
26
|
+
echo -e "${YELLOW}[1/5]${NC} Checking Node.js..."
|
|
27
27
|
if command -v node &> /dev/null; then
|
|
28
28
|
NODE_VERSION=$(node -v)
|
|
29
29
|
echo -e " ${GREEN}✓${NC} Node.js ${NODE_VERSION} found"
|
|
@@ -46,12 +46,13 @@ else
|
|
|
46
46
|
fi
|
|
47
47
|
|
|
48
48
|
# Step 2: Install indieclaw-agent
|
|
49
|
-
echo -e "${YELLOW}[2/
|
|
50
|
-
$SUDO npm install -g indieclaw-agent 2>/dev/null || npm install -g indieclaw-agent
|
|
51
|
-
|
|
49
|
+
echo -e "${YELLOW}[2/5]${NC} Installing indieclaw-agent..."
|
|
50
|
+
$SUDO npm install -g indieclaw-agent@latest 2>/dev/null || npm install -g indieclaw-agent@latest
|
|
51
|
+
AGENT_VERSION=$(node -e "try{console.log(require(require('child_process').execSync('which indieclaw-agent',{encoding:'utf8'}).trim().replace(/indieclaw-agent$/,'')+'../lib/node_modules/indieclaw-agent/package.json').version)}catch{console.log('2.0.0')}" 2>/dev/null || echo "2.0.0")
|
|
52
|
+
echo -e " ${GREEN}✓${NC} indieclaw-agent v${AGENT_VERSION} installed"
|
|
52
53
|
|
|
53
54
|
# Step 3: Create systemd service
|
|
54
|
-
echo -e "${YELLOW}[3/
|
|
55
|
+
echo -e "${YELLOW}[3/5]${NC} Setting up background service..."
|
|
55
56
|
AGENT_PATH=$(which indieclaw-agent)
|
|
56
57
|
CURRENT_USER=$(whoami)
|
|
57
58
|
|
|
@@ -74,32 +75,72 @@ EOF
|
|
|
74
75
|
|
|
75
76
|
$SUDO systemctl daemon-reload
|
|
76
77
|
$SUDO systemctl enable indieclaw-agent
|
|
77
|
-
$SUDO systemctl
|
|
78
|
+
$SUDO systemctl restart indieclaw-agent
|
|
78
79
|
echo -e " ${GREEN}✓${NC} Service created and started"
|
|
79
80
|
|
|
80
|
-
# Step 4: Wait for token
|
|
81
|
+
# Step 4: Wait for token and detect IP
|
|
82
|
+
echo -e "${YELLOW}[4/5]${NC} Detecting configuration..."
|
|
81
83
|
sleep 2
|
|
82
84
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
echo -e "${CYAN}═══════════════════════════════════════${NC}"
|
|
86
|
-
echo ""
|
|
85
|
+
PORT=3100
|
|
86
|
+
HOSTNAME=$(hostname)
|
|
87
87
|
|
|
88
|
+
# Get token
|
|
88
89
|
if [ -f "$HOME/.indieclaw-token" ]; then
|
|
89
90
|
TOKEN=$(cat "$HOME/.indieclaw-token")
|
|
90
|
-
echo -e " ${GREEN}${BOLD}Setup complete!${NC}"
|
|
91
|
-
echo ""
|
|
92
|
-
echo -e " Your auth token:"
|
|
93
|
-
echo ""
|
|
94
|
-
echo -e " ${BOLD}${CYAN}${TOKEN}${NC}"
|
|
95
|
-
echo ""
|
|
96
|
-
echo -e " Copy this token into the IndieClaw app."
|
|
97
|
-
echo -e " Port: ${BOLD}3100${NC}"
|
|
98
91
|
else
|
|
99
|
-
echo -e " ${
|
|
92
|
+
echo -e " ${YELLOW}⚠${NC} Token file not found yet. Check: cat ~/.indieclaw-token"
|
|
93
|
+
TOKEN=""
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
# Detect IP (same logic as agent: try tailscale first, fallback to network)
|
|
97
|
+
MACHINE_IP=""
|
|
98
|
+
if command -v tailscale &> /dev/null; then
|
|
99
|
+
MACHINE_IP=$(tailscale ip -4 2>/dev/null || true)
|
|
100
|
+
fi
|
|
101
|
+
if [ -z "$MACHINE_IP" ]; then
|
|
102
|
+
MACHINE_IP=$(hostname -I 2>/dev/null | awk '{print $1}' || ip route get 1 2>/dev/null | awk '{print $7; exit}' || echo "")
|
|
103
|
+
fi
|
|
104
|
+
if [ -z "$MACHINE_IP" ]; then
|
|
105
|
+
MACHINE_IP="YOUR_SERVER_IP"
|
|
106
|
+
fi
|
|
107
|
+
|
|
108
|
+
echo -e " ${GREEN}✓${NC} IP: ${MACHINE_IP}"
|
|
109
|
+
|
|
110
|
+
# Step 5: Check OpenClaw
|
|
111
|
+
echo -e "${YELLOW}[5/5]${NC} Checking OpenClaw..."
|
|
112
|
+
OPENCLAW_STATUS="not detected"
|
|
113
|
+
if curl -s --max-time 2 http://127.0.0.1:18789/v1/models > /dev/null 2>&1; then
|
|
114
|
+
OPENCLAW_STATUS="detected on port 18789"
|
|
115
|
+
echo -e " ${GREEN}✓${NC} OpenClaw detected on port 18789"
|
|
116
|
+
else
|
|
117
|
+
echo -e " ${YELLOW}—${NC} OpenClaw not detected on port 18789 (optional, for AI features)"
|
|
118
|
+
fi
|
|
119
|
+
|
|
120
|
+
# Build deep link
|
|
121
|
+
DEEP_LINK="indieclaw://connect?host=${MACHINE_IP}&port=${PORT}&token=${TOKEN}&name=${HOSTNAME}&tls=0"
|
|
122
|
+
|
|
123
|
+
# Show results
|
|
124
|
+
echo ""
|
|
125
|
+
echo -e "${CYAN}╔═══════════════════════════════════════╗${NC}"
|
|
126
|
+
echo -e "${CYAN}║ ${BOLD}IndieClaw Agent v${AGENT_VERSION}${NC}${CYAN} ║${NC}"
|
|
127
|
+
echo -e "${CYAN}╠═══════════════════════════════════════╣${NC}"
|
|
128
|
+
echo -e "${CYAN}║${NC} Port: ${BOLD}${PORT}${NC}"
|
|
129
|
+
echo -e "${CYAN}║${NC} IP: ${BOLD}${MACHINE_IP}${NC}"
|
|
130
|
+
echo -e "${CYAN}║${NC} OpenClaw: ${BOLD}${OPENCLAW_STATUS}${NC}"
|
|
131
|
+
echo -e "${CYAN}╚═══════════════════════════════════════╝${NC}"
|
|
132
|
+
echo ""
|
|
133
|
+
|
|
134
|
+
if [ -n "$TOKEN" ]; then
|
|
135
|
+
echo -e " ${BOLD}Auth Token:${NC}"
|
|
136
|
+
echo -e " ${CYAN}${TOKEN}${NC}"
|
|
137
|
+
echo ""
|
|
138
|
+
echo -e " ${BOLD}Deep Link (paste in phone browser):${NC}"
|
|
139
|
+
echo -e " ${CYAN}${DEEP_LINK}${NC}"
|
|
100
140
|
echo ""
|
|
101
|
-
echo -e "
|
|
102
|
-
echo -e " ${BOLD}
|
|
141
|
+
echo -e " ${BOLD}Or scan QR code:${NC}"
|
|
142
|
+
echo -e " Run: ${BOLD}indieclaw-agent${NC} interactively to see QR code"
|
|
143
|
+
echo -e " Or: ${BOLD}sudo journalctl -u indieclaw-agent --no-pager | head -50${NC}"
|
|
103
144
|
fi
|
|
104
145
|
|
|
105
146
|
echo ""
|