@swarmclawai/swarmclaw 1.7.2 → 1.7.3

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/README.md CHANGED
@@ -399,6 +399,14 @@ Operational docs: https://swarmclaw.ai/docs/observability
399
399
 
400
400
  ## Releases
401
401
 
402
+ ### v1.7.3 Highlights
403
+
404
+ Desktop packaging fix for Linux AppImage and deb builds.
405
+
406
+ - **Linux desktop native modules match Electron.** Packaged Linux builds now copy Electron-rebuilt native addons into the embedded Next standalone server, fixing the `better-sqlite3` Node ABI mismatch reported in [#65](https://github.com/swarmclawai/swarmclaw/issues/65).
407
+ - **Desktop packaging regression coverage.** The Electron `afterPack` hook now has a Linux standalone native-module sync test wired into `npm run test:cli`.
408
+ - **macOS desktop note.** macOS builds remain ad-hoc signed and not notarized in this release, so the existing Gatekeeper/quarantine workaround still applies until Developer ID signing is available.
409
+
402
410
  ### v1.7.2 Highlights
403
411
 
404
412
  CLI provider usability follow-up for v1.7.0/v1.7.1. The expanded coding-agent roster is now easier to find, configure, and validate from onboarding and setup diagnostics.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swarmclawai/swarmclaw",
3
- "version": "1.7.2",
3
+ "version": "1.7.3",
4
4
  "description": "Build and run autonomous AI agents with OpenClaw, Hermes, multiple model providers, orchestration, delegation, memory, skills, schedules, and chat connectors.",
5
5
  "main": "electron-dist/main.js",
6
6
  "license": "MIT",
@@ -84,7 +84,7 @@
84
84
  "lint:baseline": "node ./scripts/lint-baseline.mjs check",
85
85
  "lint:baseline:update": "node ./scripts/lint-baseline.mjs update",
86
86
  "cli": "node ./bin/swarmclaw.js",
87
- "test:cli": "node --test src/cli/*.test.js bin/*.test.js scripts/postinstall.test.mjs scripts/run-next-build.test.mjs scripts/run-next-typegen.test.mjs",
87
+ "test:cli": "node --test src/cli/*.test.js bin/*.test.js scripts/electron-after-pack.test.mjs scripts/postinstall.test.mjs scripts/run-next-build.test.mjs scripts/run-next-typegen.test.mjs",
88
88
  "test:setup": "tsx --test src/app/api/setup/check-provider/route.test.ts src/lib/server/provider-model-discovery.test.ts src/components/auth/setup-wizard/utils.test.ts src/components/auth/setup-wizard/types.test.ts src/hooks/setup-done-detection.test.ts src/lib/setup-defaults.test.ts src/lib/server/storage-auth.test.ts src/lib/server/storage-auth-docker.test.ts",
89
89
  "test:openclaw": "tsx --test src/lib/openclaw/openclaw-agent-id.test.ts src/lib/openclaw/openclaw-endpoint.test.ts src/lib/server/agents/agent-runtime-config.test.ts src/lib/server/build-llm.test.ts src/lib/server/connectors/connector-routing.test.ts src/lib/server/connectors/openclaw.test.ts src/lib/server/connectors/swarmdock.test.ts src/lib/server/gateway/protocol.test.ts src/lib/server/llm-response-cache.test.ts src/lib/server/mcp-conformance.test.ts src/lib/server/openclaw/agent-resolver.test.ts src/lib/server/openclaw/deploy.test.ts src/lib/server/openclaw/skills-normalize.test.ts src/lib/server/session-tools/openclaw-nodes.test.ts src/lib/server/session-tools/swarmdock.test.ts src/lib/server/tasks/task-quality-gate.test.ts src/lib/server/tasks/task-validation.test.ts src/lib/server/tool-capability-policy.test.ts src/lib/providers/openai.test.ts src/lib/providers/openclaw-exports.test.ts src/app/api/openclaw/dashboard-url/route.test.ts",
90
90
  "test:runtime": "tsx --test src/lib/a2a/agent-card.test.ts src/lib/strip-internal-metadata.test.ts src/lib/provider-sets.test.ts src/lib/providers/opencode-cli.test.ts src/lib/providers/cli-provider-metadata.test.ts src/lib/providers/cli-utils.test.ts src/lib/providers/generic-cli.test.ts src/lib/server/cli-provider-readiness.test.ts src/lib/server/provider-health.test.ts src/lib/server/mcp-gateway-runtime.test.ts src/lib/server/mcp-connection-pool.test.ts src/lib/server/knowledge-sources.test.ts src/lib/server/chat-execution/chat-execution-grounding.test.ts src/lib/server/chat-execution/chat-turn-preparation.test.ts src/lib/server/chat-execution/iteration-timers.test.ts src/lib/server/chat-execution/post-stream-finalization.test.ts src/lib/server/chats/clear-undo-snapshots.test.ts src/lib/server/connectors/email.test.ts src/lib/server/protocols/protocol-service.test.ts src/lib/server/runtime/run-ledger.test.ts src/lib/server/observability/otel-config.test.ts src/lib/server/safe-parse-body.test.ts src/lib/server/missions/mission-templates.test.ts src/lib/app/view-constants.test.ts src/lib/quality/quality-summary.test.ts src/app/api/approvals/route.test.ts src/app/api/agents/agents-route.test.ts src/app/api/tasks/tasks-route.test.ts src/app/api/chats/chat-route.test.ts src/app/api/chats/clear-route.test.ts src/app/api/chats/compact-route.test.ts src/app/api/chats/context-status-route.test.ts src/app/api/connectors/connector-doctor-route.test.ts src/app/api/healthz/route.test.ts src/app/api/logs/route.test.ts src/app/api/providers/[id]/route.test.ts src/app/api/tts/route.test.ts",
@@ -1,218 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- const electron_1 = require("electron");
40
- const node_fs_1 = __importDefault(require("node:fs"));
41
- const node_path_1 = __importDefault(require("node:path"));
42
- const paths_1 = require("./paths");
43
- const server_lifecycle_1 = require("./server-lifecycle");
44
- const menu_1 = require("./menu");
45
- const DEV_URL_DEFAULT = 'http://127.0.0.1:3456';
46
- const LOG_TAIL_BYTES = 1500;
47
- let mainWindow = null;
48
- let serverHandle = null;
49
- let serverLogFile = null;
50
- let isQuitting = false;
51
- const gotLock = electron_1.app.requestSingleInstanceLock();
52
- if (!gotLock) {
53
- electron_1.app.quit();
54
- }
55
- else {
56
- electron_1.app.on('second-instance', () => {
57
- if (mainWindow) {
58
- if (mainWindow.isMinimized())
59
- mainWindow.restore();
60
- mainWindow.focus();
61
- }
62
- });
63
- electron_1.app.on('ready', () => void onReady());
64
- electron_1.app.on('window-all-closed', () => {
65
- if (process.platform !== 'darwin')
66
- electron_1.app.quit();
67
- });
68
- electron_1.app.on('activate', () => {
69
- if (mainWindow !== null)
70
- return;
71
- if (serverHandle) {
72
- createMainWindow(serverHandle.url);
73
- }
74
- else if (!electron_1.app.isPackaged) {
75
- createMainWindow(process.env.SWARMCLAW_DEV_URL || DEV_URL_DEFAULT);
76
- }
77
- });
78
- electron_1.app.on('before-quit', () => {
79
- isQuitting = true;
80
- });
81
- electron_1.app.on('will-quit', async (event) => {
82
- if (!serverHandle)
83
- return;
84
- event.preventDefault();
85
- try {
86
- await serverHandle.stop();
87
- }
88
- finally {
89
- serverHandle = null;
90
- electron_1.app.exit(0);
91
- }
92
- });
93
- }
94
- async function onReady() {
95
- const paths = (0, paths_1.resolveRuntimePaths)();
96
- (0, menu_1.buildAppMenu)(paths, () => mainWindow);
97
- const iconPath = resolveIconPath();
98
- if (process.platform === 'darwin' && iconPath && electron_1.app.dock) {
99
- const img = electron_1.nativeImage.createFromPath(iconPath);
100
- if (!img.isEmpty())
101
- electron_1.app.dock.setIcon(img);
102
- }
103
- if (!electron_1.app.isPackaged) {
104
- const devUrl = process.env.SWARMCLAW_DEV_URL || DEV_URL_DEFAULT;
105
- console.log(`[swarmclaw] dev mode, loading ${devUrl}`);
106
- createMainWindow(devUrl);
107
- return;
108
- }
109
- serverLogFile = node_path_1.default.join(electron_1.app.getPath('userData'), 'logs', 'server.log');
110
- node_fs_1.default.mkdirSync(node_path_1.default.dirname(serverLogFile), { recursive: true });
111
- try {
112
- serverHandle = await (0, server_lifecycle_1.startEmbeddedServer)({
113
- paths,
114
- logFile: serverLogFile,
115
- onStdout: (c) => process.stdout.write(`[swarmclaw] ${c}`),
116
- onStderr: (c) => process.stderr.write(`[swarmclaw] ${c}`),
117
- onExit: (code, signal) => {
118
- if (!isQuitting) {
119
- console.error(`[swarmclaw] server exited unexpectedly (code=${code}, signal=${signal ?? 'none'})`);
120
- void showServerCrashDialog(code, signal);
121
- }
122
- },
123
- });
124
- }
125
- catch (err) {
126
- await showStartupFailureDialog(err, paths);
127
- electron_1.app.exit(1);
128
- return;
129
- }
130
- createMainWindow(serverHandle.url);
131
- void Promise.resolve().then(() => __importStar(require('./updater'))).then((m) => m.initAutoUpdater());
132
- }
133
- function resolveIconPath() {
134
- const candidate = electron_1.app.isPackaged
135
- ? node_path_1.default.join(process.resourcesPath, 'icon.png')
136
- : node_path_1.default.join(__dirname, '..', 'resources', 'icon.png');
137
- return node_fs_1.default.existsSync(candidate) ? candidate : undefined;
138
- }
139
- function createMainWindow(startUrl) {
140
- const iconPath = resolveIconPath();
141
- mainWindow = new electron_1.BrowserWindow({
142
- width: 1440,
143
- height: 900,
144
- minWidth: 1024,
145
- minHeight: 640,
146
- backgroundColor: '#0b0b0f',
147
- show: true,
148
- ...(iconPath ? { icon: iconPath } : {}),
149
- webPreferences: {
150
- contextIsolation: true,
151
- nodeIntegration: false,
152
- sandbox: false,
153
- },
154
- });
155
- const wc = mainWindow.webContents;
156
- if (!electron_1.app.isPackaged)
157
- wc.openDevTools({ mode: 'detach' });
158
- wc.on('did-start-loading', () => console.log('[swarmclaw] did-start-loading'));
159
- wc.on('did-finish-load', () => console.log('[swarmclaw] did-finish-load'));
160
- wc.on('did-fail-load', (_e, code, desc, url) => console.error(`[swarmclaw] did-fail-load code=${code} desc=${desc} url=${url}`));
161
- wc.on('render-process-gone', (_e, details) => console.error(`[swarmclaw] render-process-gone reason=${details.reason}`));
162
- wc.on('unresponsive', () => console.error('[swarmclaw] webContents unresponsive'));
163
- mainWindow.on('closed', () => {
164
- mainWindow = null;
165
- });
166
- mainWindow.webContents.setWindowOpenHandler(({ url }) => {
167
- if (url.startsWith(startUrl))
168
- return { action: 'allow' };
169
- void electron_1.shell.openExternal(url);
170
- return { action: 'deny' };
171
- });
172
- void mainWindow.loadURL(startUrl).catch((err) => {
173
- console.error('[swarmclaw] loadURL rejected:', err);
174
- });
175
- }
176
- async function showServerCrashDialog(code, signal) {
177
- const buttons = serverLogFile ? ['Open Logs Folder', 'Quit'] : ['Quit'];
178
- const quitButtonId = buttons.length - 1;
179
- const detail = buildLogDetail(`code=${code ?? 'null'} signal=${signal ?? 'none'}`);
180
- const res = await electron_1.dialog.showMessageBox({
181
- type: 'error',
182
- buttons,
183
- defaultId: quitButtonId,
184
- cancelId: quitButtonId,
185
- title: 'SwarmClaw stopped',
186
- message: 'The SwarmClaw server exited unexpectedly.',
187
- detail,
188
- });
189
- if (serverLogFile && res.response === 0)
190
- electron_1.shell.showItemInFolder(serverLogFile);
191
- electron_1.app.exit(1);
192
- }
193
- async function showStartupFailureDialog(err, paths) {
194
- const message = err instanceof Error ? err.message : String(err);
195
- const base = `${message}\n\nStandalone entry: ${paths.standaloneEntry}\nData dir: ${paths.dataDir}`;
196
- const detail = buildLogDetail(base);
197
- const buttons = serverLogFile ? ['Open Logs Folder', 'Quit'] : ['Quit'];
198
- const quitButtonId = buttons.length - 1;
199
- const res = await electron_1.dialog.showMessageBox({
200
- type: 'error',
201
- buttons,
202
- defaultId: quitButtonId,
203
- cancelId: quitButtonId,
204
- title: 'SwarmClaw failed to start',
205
- message: 'The embedded server did not start.',
206
- detail,
207
- });
208
- if (serverLogFile && res.response === 0)
209
- electron_1.shell.showItemInFolder(serverLogFile);
210
- }
211
- function buildLogDetail(base) {
212
- if (!serverLogFile)
213
- return base;
214
- const tail = (0, server_lifecycle_1.tailLogFile)(serverLogFile, LOG_TAIL_BYTES).trim();
215
- if (!tail)
216
- return `${base}\n\nLog file: ${serverLogFile}\n(no output captured yet)`;
217
- return `${base}\n\nLog tail (${serverLogFile}):\n${tail}`;
218
- }