pi-sdk-web 0.2.0 → 0.2.1
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/server.js +5 -0
- package/dist/static/app.js +33 -1
- package/dist/static/index.html +1 -0
- package/dist/static/style.css +6 -0
- package/dist/ui-context.js +12 -0
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -215,6 +215,11 @@ export class PiWebServer {
|
|
|
215
215
|
// Initial state (state + history), mirroring the Python bridge
|
|
216
216
|
this.sendJson(ws, { type: "state", data: this.buildState() });
|
|
217
217
|
this.sendJson(ws, { type: "history", data: this.buildHistory() });
|
|
218
|
+
// Current extension statuses (setStatus may have fired before this client connected)
|
|
219
|
+
const extStatus = this.uiContext.getStatusSnapshot();
|
|
220
|
+
if (Object.keys(extStatus).length > 0) {
|
|
221
|
+
this.sendJson(ws, { type: "ext_status", data: extStatus });
|
|
222
|
+
}
|
|
218
223
|
}
|
|
219
224
|
sendJson(ws, obj) {
|
|
220
225
|
if (ws.readyState === WebSocket.OPEN) {
|
package/dist/static/app.js
CHANGED
|
@@ -36,6 +36,7 @@ class PiWebClient {
|
|
|
36
36
|
this.modalMode = null; // 'model' | 'thinking'
|
|
37
37
|
this.hasConnectedBefore = false;
|
|
38
38
|
this.commandMenuIndex = -1;
|
|
39
|
+
this.extStatus = {};
|
|
39
40
|
|
|
40
41
|
this.initThemeSwitch();
|
|
41
42
|
|
|
@@ -169,6 +170,9 @@ class PiWebClient {
|
|
|
169
170
|
case 'pi_error':
|
|
170
171
|
this.appendError(data.error);
|
|
171
172
|
break;
|
|
173
|
+
case 'ext_status':
|
|
174
|
+
this.applyExtStatusSnapshot(data.data);
|
|
175
|
+
break;
|
|
172
176
|
case 'extension_ui_request':
|
|
173
177
|
this.handleExtensionUIRequest(data);
|
|
174
178
|
break;
|
|
@@ -1350,8 +1354,36 @@ class PiWebClient {
|
|
|
1350
1354
|
} else if (method === 'setWidget') {
|
|
1351
1355
|
// Persistent widget panel (TUI: above/below editor). Not a popup.
|
|
1352
1356
|
this.renderWidget(req);
|
|
1357
|
+
} else if (method === 'setStatus') {
|
|
1358
|
+
// Extension status text (e.g. magic-context "mc: 29.3K (4%) · idle")
|
|
1359
|
+
this.renderStatusItem(req);
|
|
1360
|
+
}
|
|
1361
|
+
// setTitle / set_editor_text are handled elsewhere or ignored
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1364
|
+
renderStatusItem(req) {
|
|
1365
|
+
const el = document.getElementById('ext-status');
|
|
1366
|
+
if (!el) return;
|
|
1367
|
+
if (req.statusText === undefined || req.statusText === null) {
|
|
1368
|
+
delete this.extStatus[req.statusKey];
|
|
1369
|
+
} else {
|
|
1370
|
+
this.extStatus[req.statusKey] = req.statusText;
|
|
1353
1371
|
}
|
|
1354
|
-
|
|
1372
|
+
this.updateExtStatusDisplay();
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1375
|
+
applyExtStatusSnapshot(snapshot) {
|
|
1376
|
+
if (!snapshot) return;
|
|
1377
|
+
this.extStatus = Object.assign({}, snapshot);
|
|
1378
|
+
this.updateExtStatusDisplay();
|
|
1379
|
+
}
|
|
1380
|
+
|
|
1381
|
+
updateExtStatusDisplay() {
|
|
1382
|
+
const el = document.getElementById('ext-status');
|
|
1383
|
+
if (!el) return;
|
|
1384
|
+
const entries = Object.entries(this.extStatus);
|
|
1385
|
+
el.textContent = entries.map(([k, v]) => `${k}: ${v}`).join(' · ');
|
|
1386
|
+
el.style.display = entries.length ? 'block' : 'none';
|
|
1355
1387
|
}
|
|
1356
1388
|
|
|
1357
1389
|
openExtensionSelect(req) {
|
package/dist/static/index.html
CHANGED
package/dist/static/style.css
CHANGED
package/dist/ui-context.js
CHANGED
|
@@ -21,9 +21,15 @@ export class WebUIContext {
|
|
|
21
21
|
pending = new Map();
|
|
22
22
|
sink;
|
|
23
23
|
identityTheme = createIdentityTheme();
|
|
24
|
+
/** Latest setStatus values per key, so late-connecting browsers get current state */
|
|
25
|
+
statusMap = new Map();
|
|
24
26
|
constructor(sink) {
|
|
25
27
|
this.sink = sink;
|
|
26
28
|
}
|
|
29
|
+
/** Current extension status snapshot (key -> text) for new connections. */
|
|
30
|
+
getStatusSnapshot() {
|
|
31
|
+
return Object.fromEntries(this.statusMap);
|
|
32
|
+
}
|
|
27
33
|
/** Handle a browser `extension_ui_response` message. */
|
|
28
34
|
respond(id, response) {
|
|
29
35
|
const pending = this.pending.get(id);
|
|
@@ -82,6 +88,12 @@ export class WebUIContext {
|
|
|
82
88
|
this.sink({ type: "extension_ui_request", id: crypto.randomUUID(), method: "notify", message, notifyType: type });
|
|
83
89
|
}
|
|
84
90
|
setStatus(key, text) {
|
|
91
|
+
if (text === undefined || text === null) {
|
|
92
|
+
this.statusMap.delete(key);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
this.statusMap.set(key, text);
|
|
96
|
+
}
|
|
85
97
|
this.sink({ type: "extension_ui_request", id: crypto.randomUUID(), method: "setStatus", statusKey: key, statusText: text });
|
|
86
98
|
}
|
|
87
99
|
setTitle(title) {
|