pi-sdk-web 0.4.8 → 0.4.9
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 +37 -0
- package/dist/static/app.js +33 -2
- package/dist/static/style.css +19 -0
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -290,6 +290,7 @@ export class PiWebServer {
|
|
|
290
290
|
gitBranch: this.getGitBranch(this.session.sessionManager.getCwd()),
|
|
291
291
|
commands: this.getCommands(),
|
|
292
292
|
tools: this.getActiveTools(),
|
|
293
|
+
extensions: this.getLoadedExtensions(),
|
|
293
294
|
};
|
|
294
295
|
try {
|
|
295
296
|
state.sessionStats = this.session.getSessionStats();
|
|
@@ -377,6 +378,42 @@ export class PiWebServer {
|
|
|
377
378
|
return [];
|
|
378
379
|
}
|
|
379
380
|
}
|
|
381
|
+
/** Loaded extensions with their package names and versions (sidebar list). */
|
|
382
|
+
getLoadedExtensions() {
|
|
383
|
+
try {
|
|
384
|
+
const result = this.session.resourceLoader.getExtensions();
|
|
385
|
+
const list = [];
|
|
386
|
+
const seen = new Set();
|
|
387
|
+
for (const ext of result.extensions) {
|
|
388
|
+
// ext.path points at the extension entry (e.g. .../lib/node_modules/
|
|
389
|
+
// pi-magic-context/dist/index.js); walk up to the nearest package.json
|
|
390
|
+
// for the name/version.
|
|
391
|
+
let dir = dirname(ext.path);
|
|
392
|
+
while (dir !== dirname(dir)) {
|
|
393
|
+
const pkgFile = join(dir, "package.json");
|
|
394
|
+
if (existsSync(pkgFile)) {
|
|
395
|
+
try {
|
|
396
|
+
const pkg = JSON.parse(readFileSync(pkgFile, "utf8"));
|
|
397
|
+
const key = pkg.name ?? ext.path;
|
|
398
|
+
if (!seen.has(key)) {
|
|
399
|
+
seen.add(key);
|
|
400
|
+
list.push({ name: pkg.name ?? key, version: pkg.version ?? "?" });
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
catch {
|
|
404
|
+
// unreadable package.json - skip
|
|
405
|
+
}
|
|
406
|
+
break;
|
|
407
|
+
}
|
|
408
|
+
dir = dirname(dir);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
return list;
|
|
412
|
+
}
|
|
413
|
+
catch {
|
|
414
|
+
return [];
|
|
415
|
+
}
|
|
416
|
+
}
|
|
380
417
|
handleClientMessage(ws, raw) {
|
|
381
418
|
let data;
|
|
382
419
|
try {
|
package/dist/static/app.js
CHANGED
|
@@ -397,7 +397,7 @@ class PiWebClient {
|
|
|
397
397
|
}
|
|
398
398
|
|
|
399
399
|
// Loaded resources
|
|
400
|
-
this.renderLoadedResources(state.commands, state.tools);
|
|
400
|
+
this.renderLoadedResources(state.commands, state.tools, state.extensions);
|
|
401
401
|
|
|
402
402
|
// First footer line: pwd (branch) • session name
|
|
403
403
|
const pwd = state.cwd || '';
|
|
@@ -409,7 +409,7 @@ class PiWebClient {
|
|
|
409
409
|
this.renderStats(state.sessionStats, state);
|
|
410
410
|
}
|
|
411
411
|
|
|
412
|
-
renderLoadedResources(commands, tools) {
|
|
412
|
+
renderLoadedResources(commands, tools, extensions) {
|
|
413
413
|
if (!this.loadedResourcesEl) return;
|
|
414
414
|
this.loadedResourcesEl.innerHTML = '';
|
|
415
415
|
|
|
@@ -493,6 +493,37 @@ class PiWebClient {
|
|
|
493
493
|
});
|
|
494
494
|
this.loadedResourcesEl.appendChild(div);
|
|
495
495
|
}
|
|
496
|
+
|
|
497
|
+
// Separate Extensions block below Tools: loaded extension name + version
|
|
498
|
+
if (extensions && extensions.length > 0) {
|
|
499
|
+
const div = document.createElement('div');
|
|
500
|
+
div.className = 'resources-block';
|
|
501
|
+
div.dataset.expanded = 'false';
|
|
502
|
+
div.style.marginTop = '6px';
|
|
503
|
+
|
|
504
|
+
const header = document.createElement('div');
|
|
505
|
+
header.className = 'resources-header';
|
|
506
|
+
header.textContent = `Extensions (${extensions.length})`;
|
|
507
|
+
|
|
508
|
+
const body = document.createElement('div');
|
|
509
|
+
body.className = 'resources-body';
|
|
510
|
+
body.style.display = 'none';
|
|
511
|
+
body.innerHTML = extensions
|
|
512
|
+
.map((e) => `<div class="resources-item ext-item"><span>${this.escapeHtml(e.name)}</span><span class="ext-version">${this.escapeHtml(e.version)}</span></div>`)
|
|
513
|
+
.join('');
|
|
514
|
+
|
|
515
|
+
div.appendChild(header);
|
|
516
|
+
div.appendChild(body);
|
|
517
|
+
div.addEventListener('click', () => {
|
|
518
|
+
const expanded = div.dataset.expanded === 'true';
|
|
519
|
+
div.dataset.expanded = expanded ? 'false' : 'true';
|
|
520
|
+
body.style.display = expanded ? 'none' : 'block';
|
|
521
|
+
header.textContent = expanded
|
|
522
|
+
? `Extensions (${extensions.length}) · click to expand`
|
|
523
|
+
: `Extensions (${extensions.length}) · click to collapse`;
|
|
524
|
+
});
|
|
525
|
+
this.loadedResourcesEl.appendChild(div);
|
|
526
|
+
}
|
|
496
527
|
}
|
|
497
528
|
|
|
498
529
|
resourceSection(name, items) {
|
package/dist/static/style.css
CHANGED
|
@@ -213,6 +213,25 @@ body {
|
|
|
213
213
|
text-overflow: ellipsis;
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
+
.ext-item {
|
|
217
|
+
display: flex;
|
|
218
|
+
flex-wrap: wrap;
|
|
219
|
+
justify-content: space-between;
|
|
220
|
+
gap: 0 6px;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.ext-item > span:first-child {
|
|
224
|
+
min-width: 0;
|
|
225
|
+
overflow-wrap: anywhere;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.ext-version {
|
|
229
|
+
color: var(--dim);
|
|
230
|
+
font-size: 10px;
|
|
231
|
+
flex-shrink: 0;
|
|
232
|
+
margin-left: auto;
|
|
233
|
+
}
|
|
234
|
+
|
|
216
235
|
#conn-status.connected {
|
|
217
236
|
color: var(--accent);
|
|
218
237
|
background: var(--accent-hover);
|