@clawlabz/clawskin 1.0.1 → 1.0.2
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/package.json +1 -1
- package/public/app.html +10 -5
- package/public/js/app/ClawSkinApp.js +49 -41
- package/serve.cjs +5 -0
package/package.json
CHANGED
package/public/app.html
CHANGED
|
@@ -319,11 +319,16 @@
|
|
|
319
319
|
let app, editingSlot = null;
|
|
320
320
|
|
|
321
321
|
// ── Fullscreen canvas sizing ──
|
|
322
|
+
// Fixed logical resolution — CSS scales it up with pixelated rendering.
|
|
323
|
+
// This keeps pixel characters proportional on any screen size.
|
|
324
|
+
const LOGICAL_W = 960;
|
|
325
|
+
const LOGICAL_H = 600;
|
|
326
|
+
|
|
322
327
|
function resizeCanvas() {
|
|
323
328
|
const c = document.getElementById('app-canvas');
|
|
324
|
-
c.width =
|
|
325
|
-
c.height =
|
|
326
|
-
if (app) { app.width =
|
|
329
|
+
c.width = LOGICAL_W;
|
|
330
|
+
c.height = LOGICAL_H;
|
|
331
|
+
if (app) { app.width = LOGICAL_W; app.height = LOGICAL_H; }
|
|
327
332
|
}
|
|
328
333
|
window.addEventListener('resize', resizeCanvas);
|
|
329
334
|
resizeCanvas();
|
|
@@ -533,8 +538,8 @@
|
|
|
533
538
|
document.addEventListener('DOMContentLoaded', () => {
|
|
534
539
|
try {
|
|
535
540
|
app = new ClawSkinApp('app-canvas', {
|
|
536
|
-
width:
|
|
537
|
-
height:
|
|
541
|
+
width: LOGICAL_W,
|
|
542
|
+
height: LOGICAL_H,
|
|
538
543
|
});
|
|
539
544
|
app.init();
|
|
540
545
|
window._app = app;
|
|
@@ -170,15 +170,16 @@ class ClawSkinApp {
|
|
|
170
170
|
const config = await res.json();
|
|
171
171
|
if (config?.gatewayUrl) {
|
|
172
172
|
const saved = this.settings.load();
|
|
173
|
+
const token = config.token || saved.token || '';
|
|
174
|
+
this._configAgents = config.agents || [];
|
|
173
175
|
this.settings.update({
|
|
174
176
|
gatewayUrl: config.gatewayUrl,
|
|
177
|
+
token: token,
|
|
175
178
|
autoConnect: true,
|
|
176
179
|
});
|
|
177
180
|
if (window._connPanel) {
|
|
178
181
|
window._connPanel.render(this.settings.load());
|
|
179
182
|
}
|
|
180
|
-
// Use token from local config, fall back to previously saved token
|
|
181
|
-
const token = config.token || saved.token || '';
|
|
182
183
|
this.gateway.connect(config.gatewayUrl, token);
|
|
183
184
|
return;
|
|
184
185
|
}
|
|
@@ -266,55 +267,62 @@ class ClawSkinApp {
|
|
|
266
267
|
// ──── Multi-Agent Management ────
|
|
267
268
|
|
|
268
269
|
async _discoverAgents() {
|
|
270
|
+
// Start with agents from config file (all agents, regardless of activity)
|
|
271
|
+
const configAgents = this._configAgents || [];
|
|
272
|
+
const knownAgentIds = new Set();
|
|
273
|
+
|
|
274
|
+
// Phase 1: Create slots for all agents from config file
|
|
275
|
+
for (const agent of configAgents) {
|
|
276
|
+
if (!agent.id) continue;
|
|
277
|
+
knownAgentIds.add(agent.id);
|
|
278
|
+
this._addAgent({
|
|
279
|
+
agentId: agent.id,
|
|
280
|
+
name: agent.name || agent.id,
|
|
281
|
+
label: agent.name || agent.id,
|
|
282
|
+
sessionKeys: [],
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Phase 2: Discover active sessions from Gateway and attach to slots
|
|
269
287
|
try {
|
|
270
288
|
const result = await this.gateway.getSessionsList({ activeMinutes: 1440 });
|
|
271
289
|
const sessions = result?.sessions || result || [];
|
|
272
290
|
|
|
273
|
-
if (
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
// Group sessions by agentId
|
|
279
|
-
// Session keys look like: "agent:main:main", "agent:ifig:discord:channel:123", "agent:xhs:main"
|
|
280
|
-
// The agentId is either session.agentId or extracted from the key pattern "agent:<agentId>:..."
|
|
281
|
-
const agentMap = new Map();
|
|
282
|
-
|
|
283
|
-
for (const session of sessions) {
|
|
284
|
-
const key = session.key || session.sessionKey;
|
|
285
|
-
if (!key) continue;
|
|
291
|
+
if (Array.isArray(sessions)) {
|
|
292
|
+
for (const session of sessions) {
|
|
293
|
+
const key = session.key || session.sessionKey;
|
|
294
|
+
if (!key) continue;
|
|
286
295
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
}
|
|
296
|
+
let agentId = session.agentId || null;
|
|
297
|
+
if (!agentId) {
|
|
298
|
+
const match = key.match(/^agent:([^:]+):/);
|
|
299
|
+
agentId = match ? match[1] : 'main';
|
|
300
|
+
}
|
|
293
301
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
agentId
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
302
|
+
// If this agent wasn't in config, create a slot for it
|
|
303
|
+
if (!knownAgentIds.has(agentId)) {
|
|
304
|
+
knownAgentIds.add(agentId);
|
|
305
|
+
this._addAgent({
|
|
306
|
+
agentId,
|
|
307
|
+
label: session.label || agentId,
|
|
308
|
+
sessionKeys: [key],
|
|
309
|
+
});
|
|
310
|
+
} else {
|
|
311
|
+
// Attach session key to existing slot
|
|
312
|
+
const slot = this.agents.find(a => a.agentId === agentId);
|
|
313
|
+
if (slot && !slot.sessionKeys.includes(key)) {
|
|
314
|
+
slot.sessionKeys.push(key);
|
|
315
|
+
slot.stateMapper.addSessionKey(key);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
300
318
|
}
|
|
301
|
-
agentMap.get(agentId).sessionKeys.push(key);
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
// Create one AgentSlot per unique agentId
|
|
305
|
-
for (const [agentId, info] of agentMap) {
|
|
306
|
-
this._addAgent({
|
|
307
|
-
agentId,
|
|
308
|
-
label: info.label,
|
|
309
|
-
sessionKeys: info.sessionKeys,
|
|
310
|
-
});
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
if (this.agents.length === 0) {
|
|
314
|
-
this._addAgent({ agentId: 'main', label: 'Main Agent', sessionKeys: ['main'] });
|
|
315
319
|
}
|
|
316
320
|
} catch (e) {
|
|
317
321
|
console.warn('[ClawSkinApp] session discovery failed:', e);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Phase 3: Fallback — ensure at least one agent exists
|
|
325
|
+
if (this.agents.length === 0) {
|
|
318
326
|
this._addAgent({ agentId: 'main', label: 'Main Agent', sessionKeys: ['main'] });
|
|
319
327
|
}
|
|
320
328
|
|
package/serve.cjs
CHANGED
|
@@ -44,11 +44,16 @@ function getLocalGatewayConfig() {
|
|
|
44
44
|
const config = JSON.parse(raw);
|
|
45
45
|
const gw = config.gateway || {};
|
|
46
46
|
const port = gw.port || 18789;
|
|
47
|
+
const agentsList = (config.agents?.list || []).map(a => ({
|
|
48
|
+
id: a.id,
|
|
49
|
+
name: a.identity?.name || a.name || a.id,
|
|
50
|
+
}));
|
|
47
51
|
return {
|
|
48
52
|
gatewayUrl: `ws://localhost:${port}`,
|
|
49
53
|
// Safe to expose token on localhost — serve.cjs binds to 127.0.0.1 by default.
|
|
50
54
|
// The token never leaves the local machine.
|
|
51
55
|
token: (gw.auth && gw.auth.token) || '',
|
|
56
|
+
agents: agentsList,
|
|
52
57
|
};
|
|
53
58
|
} catch { continue; }
|
|
54
59
|
}
|