agentlife 1.1.6 → 1.1.7
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/dist/index.js +49 -48
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4726,16 +4726,24 @@ function ensureDirs() {
|
|
|
4726
4726
|
if (!fs6.existsSync(BIN_DIR))
|
|
4727
4727
|
fs6.mkdirSync(BIN_DIR, { recursive: true, mode: 448 });
|
|
4728
4728
|
}
|
|
4729
|
-
function
|
|
4730
|
-
if (fs6.existsSync(DEVICE_FILE))
|
|
4731
|
-
|
|
4732
|
-
|
|
4733
|
-
|
|
4734
|
-
|
|
4735
|
-
|
|
4736
|
-
}
|
|
4737
|
-
}
|
|
4729
|
+
function loadDeviceIdentity() {
|
|
4730
|
+
if (!fs6.existsSync(DEVICE_FILE))
|
|
4731
|
+
return null;
|
|
4732
|
+
try {
|
|
4733
|
+
const raw = fs6.readFileSync(DEVICE_FILE, "utf-8");
|
|
4734
|
+
const parsed = JSON.parse(raw);
|
|
4735
|
+
if (typeof parsed.deviceId === "string" && typeof parsed.deviceSecret === "string") {
|
|
4736
|
+
return { deviceId: parsed.deviceId, deviceSecret: parsed.deviceSecret };
|
|
4737
|
+
}
|
|
4738
|
+
return null;
|
|
4739
|
+
} catch {
|
|
4740
|
+
return null;
|
|
4738
4741
|
}
|
|
4742
|
+
}
|
|
4743
|
+
function loadOrCreateDeviceIdentity() {
|
|
4744
|
+
const existing = loadDeviceIdentity();
|
|
4745
|
+
if (existing)
|
|
4746
|
+
return existing;
|
|
4739
4747
|
const identity = {
|
|
4740
4748
|
deviceId: crypto2.randomUUID(),
|
|
4741
4749
|
deviceSecret: crypto2.randomBytes(32).toString("base64url")
|
|
@@ -4747,6 +4755,7 @@ function loadOrCreateDeviceIdentity() {
|
|
|
4747
4755
|
console.log(`[cloudflared-supervisor] generated new device identity (deviceId=${identity.deviceId})`);
|
|
4748
4756
|
return identity;
|
|
4749
4757
|
}
|
|
4758
|
+
var AGENTLIFE_API_BASE = API_BASE;
|
|
4750
4759
|
function loadCachedTunnel() {
|
|
4751
4760
|
if (!fs6.existsSync(TUNNEL_FILE))
|
|
4752
4761
|
return null;
|
|
@@ -5124,57 +5133,22 @@ function registerWebApp(api) {
|
|
|
5124
5133
|
|
|
5125
5134
|
// services/pairing.ts
|
|
5126
5135
|
var TUNNEL_READY_TIMEOUT_MS = 90000;
|
|
5127
|
-
async function detectTunnelUrl(port) {
|
|
5128
|
-
try {
|
|
5129
|
-
const cfgPath = path10.join(os6.homedir(), ".cloudflared", "config.yml");
|
|
5130
|
-
if (!fsSync3.existsSync(cfgPath))
|
|
5131
|
-
return null;
|
|
5132
|
-
const cfg = fsSync3.readFileSync(cfgPath, "utf-8");
|
|
5133
|
-
const lines = cfg.split(`
|
|
5134
|
-
`);
|
|
5135
|
-
for (let i = 0;i < lines.length; i++) {
|
|
5136
|
-
const hostMatch = lines[i].match(/hostname:\s*(.+)/);
|
|
5137
|
-
if (hostMatch) {
|
|
5138
|
-
const nextLine = lines[i + 1] || "";
|
|
5139
|
-
const svcMatch = nextLine.match(/service:\s*http:\/\/localhost:(\d+)/);
|
|
5140
|
-
if (svcMatch && parseInt(svcMatch[1]) === port) {
|
|
5141
|
-
return `wss://${hostMatch[1].trim()}`;
|
|
5142
|
-
}
|
|
5143
|
-
}
|
|
5144
|
-
}
|
|
5145
|
-
return null;
|
|
5146
|
-
} catch {
|
|
5147
|
-
return null;
|
|
5148
|
-
}
|
|
5149
|
-
}
|
|
5150
5136
|
function registerPairingServices(api) {
|
|
5151
5137
|
api.registerService({
|
|
5152
5138
|
id: "agentlife-pairing-qr",
|
|
5153
5139
|
start: async (_ctx) => {
|
|
5154
5140
|
try {
|
|
5155
5141
|
const cfg = api.runtime.config.loadConfig();
|
|
5156
|
-
const bind = cfg.gateway?.bind ?? "loopback";
|
|
5157
5142
|
const port = cfg.gateway?.port ?? 18789;
|
|
5158
5143
|
const token = cfg.gateway?.auth?.token;
|
|
5159
5144
|
if (!token)
|
|
5160
5145
|
return;
|
|
5161
5146
|
const supervisorTunnel = await awaitTunnelReady(TUNNEL_READY_TIMEOUT_MS) ?? getTunnelInfo();
|
|
5162
|
-
|
|
5163
|
-
|
|
5164
|
-
|
|
5165
|
-
} else {
|
|
5166
|
-
console.warn("[agentlife] Tunnel not ready after " + TUNNEL_READY_TIMEOUT_MS / 1000 + "s — falling back to LAN URL. Phone pairing will only work on the same Wi-Fi.");
|
|
5167
|
-
const userTunnel = await detectTunnelUrl(port);
|
|
5168
|
-
if (userTunnel) {
|
|
5169
|
-
url = userTunnel;
|
|
5170
|
-
} else if (bind === "lan" || bind === "auto" || bind === "custom") {
|
|
5171
|
-
const nets = os6.networkInterfaces();
|
|
5172
|
-
const lanIp = Object.values(nets).flat().find((n) => n && !n.internal && n.family === "IPv4")?.address;
|
|
5173
|
-
url = `ws://${lanIp ?? "127.0.0.1"}:${port}`;
|
|
5174
|
-
} else {
|
|
5175
|
-
url = `ws://127.0.0.1:${port}`;
|
|
5176
|
-
}
|
|
5147
|
+
if (!supervisorTunnel?.tunnelUrl) {
|
|
5148
|
+
console.warn(`[agentlife] Cloudflared tunnel did not come up within ${TUNNEL_READY_TIMEOUT_MS / 1000}s — ` + `pairing QR will not be emitted. Check cloudflared-supervisor logs in the gateway output.`);
|
|
5149
|
+
return;
|
|
5177
5150
|
}
|
|
5151
|
+
const url = supervisorTunnel.tunnelUrl;
|
|
5178
5152
|
const bootstrapToken = mintBootstrapToken();
|
|
5179
5153
|
const payload = JSON.stringify({ url, bootstrapToken });
|
|
5180
5154
|
const setupCode = Buffer.from(payload).toString("base64url");
|
|
@@ -6709,6 +6683,33 @@ function registerAdminGateway(api, state2) {
|
|
|
6709
6683
|
try {
|
|
6710
6684
|
const cleaned = [];
|
|
6711
6685
|
const baseDir = state2.agentlifeStateDir ?? path12.join(os7.homedir(), ".openclaw", "agentlife");
|
|
6686
|
+
const identity = loadDeviceIdentity();
|
|
6687
|
+
if (!identity) {
|
|
6688
|
+
cleaned.push("server deprovision skipped (no device identity)");
|
|
6689
|
+
} else {
|
|
6690
|
+
try {
|
|
6691
|
+
const res = await fetch(`${AGENTLIFE_API_BASE}/api/v1/devices/deprovision`, {
|
|
6692
|
+
method: "POST",
|
|
6693
|
+
headers: { "Content-Type": "application/json" },
|
|
6694
|
+
body: JSON.stringify({
|
|
6695
|
+
deviceId: identity.deviceId,
|
|
6696
|
+
deviceSecret: identity.deviceSecret
|
|
6697
|
+
}),
|
|
6698
|
+
signal: AbortSignal.timeout(1e4)
|
|
6699
|
+
});
|
|
6700
|
+
if (res.ok) {
|
|
6701
|
+
cleaned.push("deprovisioned tunnel on server");
|
|
6702
|
+
} else if (res.status === 404) {
|
|
6703
|
+
cleaned.push("server had no record of this device (already gone)");
|
|
6704
|
+
} else {
|
|
6705
|
+
cleaned.push(`server deprovision returned HTTP ${res.status} (continuing)`);
|
|
6706
|
+
console.warn(`[agentlife] uninstall: deprovision HTTP ${res.status}, continuing with local cleanup`);
|
|
6707
|
+
}
|
|
6708
|
+
} catch (err) {
|
|
6709
|
+
cleaned.push(`server deprovision failed (continuing): ${err?.message ?? "unknown error"}`);
|
|
6710
|
+
console.warn(`[agentlife] uninstall: deprovision failed (${err?.message ?? err}), continuing with local cleanup`);
|
|
6711
|
+
}
|
|
6712
|
+
}
|
|
6712
6713
|
if (state2.runCommand) {
|
|
6713
6714
|
try {
|
|
6714
6715
|
const result = await state2.runCommand(["openclaw", "cron", "list", "--json"], { timeoutMs: 1e4 });
|