pi-sdk-web 0.3.3 → 0.3.5
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 +18 -0
- package/dist/static/app.js +78 -44
- package/dist/static/style.css +11 -0
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -278,6 +278,7 @@ export class PiWebServer {
|
|
|
278
278
|
cwd: this.formatCwd(this.session.sessionManager.getCwd()),
|
|
279
279
|
gitBranch: this.getGitBranch(this.session.sessionManager.getCwd()),
|
|
280
280
|
commands: this.getCommands(),
|
|
281
|
+
tools: this.getActiveTools(),
|
|
281
282
|
};
|
|
282
283
|
try {
|
|
283
284
|
state.sessionStats = this.session.getSessionStats();
|
|
@@ -352,6 +353,19 @@ export class PiWebServer {
|
|
|
352
353
|
return [];
|
|
353
354
|
}
|
|
354
355
|
}
|
|
356
|
+
/** Tools currently exposed to the LLM (name + description). */
|
|
357
|
+
getActiveTools() {
|
|
358
|
+
try {
|
|
359
|
+
const active = new Set(this.session.getActiveToolNames());
|
|
360
|
+
return this.session
|
|
361
|
+
.getAllTools()
|
|
362
|
+
.filter((t) => active.has(t.name))
|
|
363
|
+
.map((t) => ({ name: t.name, description: t.description }));
|
|
364
|
+
}
|
|
365
|
+
catch {
|
|
366
|
+
return [];
|
|
367
|
+
}
|
|
368
|
+
}
|
|
355
369
|
handleClientMessage(ws, raw) {
|
|
356
370
|
let data;
|
|
357
371
|
try {
|
|
@@ -385,6 +399,10 @@ export class PiWebServer {
|
|
|
385
399
|
case "get_stats":
|
|
386
400
|
this.broadcastStats();
|
|
387
401
|
break;
|
|
402
|
+
case "get_state":
|
|
403
|
+
// Used by the sidebar Tools refresh button
|
|
404
|
+
this.broadcastState();
|
|
405
|
+
break;
|
|
388
406
|
case "bash": {
|
|
389
407
|
const command = typeof data.command === "string" ? data.command : "";
|
|
390
408
|
if (!command)
|
package/dist/static/app.js
CHANGED
|
@@ -208,7 +208,7 @@ class PiWebClient {
|
|
|
208
208
|
}
|
|
209
209
|
|
|
210
210
|
// Loaded resources
|
|
211
|
-
this.renderLoadedResources(state.commands);
|
|
211
|
+
this.renderLoadedResources(state.commands, state.tools);
|
|
212
212
|
|
|
213
213
|
// First footer line: pwd (branch) • session name
|
|
214
214
|
const pwd = state.cwd || '';
|
|
@@ -220,56 +220,90 @@ class PiWebClient {
|
|
|
220
220
|
this.renderStats(state.sessionStats, state);
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
-
renderLoadedResources(commands) {
|
|
223
|
+
renderLoadedResources(commands, tools) {
|
|
224
224
|
if (!this.loadedResourcesEl) return;
|
|
225
|
-
|
|
226
|
-
this.loadedResourcesEl.innerHTML = '';
|
|
227
|
-
return;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
const groups = { skill: [], prompt: [], extension: [] };
|
|
231
|
-
for (const cmd of commands) {
|
|
232
|
-
const source = cmd.source;
|
|
233
|
-
if (source === 'skill') groups.skill.push(cmd);
|
|
234
|
-
else if (source === 'prompt') groups.prompt.push(cmd);
|
|
235
|
-
else groups.extension.push(cmd);
|
|
236
|
-
}
|
|
225
|
+
this.loadedResourcesEl.innerHTML = '';
|
|
237
226
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
227
|
+
// Loaded Resources block (Skills/Prompts/Extensions)
|
|
228
|
+
if (commands && commands.length > 0) {
|
|
229
|
+
const groups = { skill: [], prompt: [], extension: [] };
|
|
230
|
+
for (const cmd of commands) {
|
|
231
|
+
const source = cmd.source;
|
|
232
|
+
if (source === 'skill') groups.skill.push(cmd);
|
|
233
|
+
else if (source === 'prompt') groups.prompt.push(cmd);
|
|
234
|
+
else groups.extension.push(cmd);
|
|
235
|
+
}
|
|
241
236
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
237
|
+
const div = document.createElement('div');
|
|
238
|
+
div.className = 'resources-block';
|
|
239
|
+
div.dataset.expanded = 'false';
|
|
245
240
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
241
|
+
const header = document.createElement('div');
|
|
242
|
+
header.className = 'resources-header';
|
|
243
|
+
header.textContent = 'Loaded Resources (click to expand)';
|
|
249
244
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
}
|
|
254
|
-
if (groups.prompt.length > 0) {
|
|
255
|
-
sections.push(this.resourceSection('Prompts', groups.prompt.map((c) => c.name)));
|
|
256
|
-
}
|
|
257
|
-
if (groups.extension.length > 0) {
|
|
258
|
-
sections.push(this.resourceSection('Extensions', groups.extension.map((c) => c.name)));
|
|
259
|
-
}
|
|
260
|
-
body.innerHTML = sections.join('');
|
|
245
|
+
const body = document.createElement('div');
|
|
246
|
+
body.className = 'resources-body';
|
|
247
|
+
body.style.display = 'none';
|
|
261
248
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
249
|
+
const sections = [];
|
|
250
|
+
if (groups.skill.length > 0) {
|
|
251
|
+
sections.push(this.resourceSection('Skills', groups.skill.map((c) => c.name)));
|
|
252
|
+
}
|
|
253
|
+
if (groups.prompt.length > 0) {
|
|
254
|
+
sections.push(this.resourceSection('Prompts', groups.prompt.map((c) => c.name)));
|
|
255
|
+
}
|
|
256
|
+
if (groups.extension.length > 0) {
|
|
257
|
+
sections.push(this.resourceSection('Extensions', groups.extension.map((c) => c.name)));
|
|
258
|
+
}
|
|
259
|
+
body.innerHTML = sections.join('');
|
|
260
|
+
|
|
261
|
+
div.appendChild(header);
|
|
262
|
+
div.appendChild(body);
|
|
263
|
+
div.addEventListener('click', () => {
|
|
264
|
+
const expanded = div.dataset.expanded === 'true';
|
|
265
|
+
div.dataset.expanded = expanded ? 'false' : 'true';
|
|
266
|
+
body.style.display = expanded ? 'none' : 'block';
|
|
267
|
+
header.textContent = expanded ? 'Loaded Resources (click to expand)' : 'Loaded Resources (click to collapse)';
|
|
268
|
+
});
|
|
269
|
+
this.loadedResourcesEl.appendChild(div);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Separate Tools block below Loaded Resources (web enhancement)
|
|
273
|
+
if (tools && tools.length > 0) {
|
|
274
|
+
const div = document.createElement('div');
|
|
275
|
+
div.className = 'resources-block';
|
|
276
|
+
div.dataset.expanded = 'false';
|
|
277
|
+
div.style.marginTop = '6px';
|
|
278
|
+
|
|
279
|
+
const header = document.createElement('div');
|
|
280
|
+
header.className = 'resources-header';
|
|
281
|
+
header.textContent = 'Tools (click to expand)';
|
|
282
|
+
const refreshBtn = document.createElement('span');
|
|
283
|
+
refreshBtn.className = 'tools-refresh';
|
|
284
|
+
refreshBtn.title = 'Refresh tools list';
|
|
285
|
+
refreshBtn.textContent = '⟳';
|
|
286
|
+
refreshBtn.addEventListener('click', (e) => {
|
|
287
|
+
e.stopPropagation();
|
|
288
|
+
this.send({ type: 'get_state' });
|
|
289
|
+
});
|
|
290
|
+
header.appendChild(refreshBtn);
|
|
270
291
|
|
|
271
|
-
|
|
272
|
-
|
|
292
|
+
const body = document.createElement('div');
|
|
293
|
+
body.className = 'resources-body';
|
|
294
|
+
body.style.display = 'none';
|
|
295
|
+
body.innerHTML = this.resourceSection('', tools.map((t) => t.name));
|
|
296
|
+
|
|
297
|
+
div.appendChild(header);
|
|
298
|
+
div.appendChild(body);
|
|
299
|
+
div.addEventListener('click', () => {
|
|
300
|
+
const expanded = div.dataset.expanded === 'true';
|
|
301
|
+
div.dataset.expanded = expanded ? 'false' : 'true';
|
|
302
|
+
body.style.display = expanded ? 'none' : 'block';
|
|
303
|
+
header.firstChild.textContent = expanded ? 'Tools (click to expand)' : 'Tools (click to collapse)';
|
|
304
|
+
});
|
|
305
|
+
this.loadedResourcesEl.appendChild(div);
|
|
306
|
+
}
|
|
273
307
|
}
|
|
274
308
|
|
|
275
309
|
resourceSection(name, items) {
|
package/dist/static/style.css
CHANGED
|
@@ -171,6 +171,17 @@ body {
|
|
|
171
171
|
color: var(--dim);
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
+
.tools-refresh {
|
|
175
|
+
float: right;
|
|
176
|
+
cursor: pointer;
|
|
177
|
+
color: var(--accent);
|
|
178
|
+
padding: 0 4px;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.tools-refresh:hover {
|
|
182
|
+
text-decoration: underline;
|
|
183
|
+
}
|
|
184
|
+
|
|
174
185
|
.resources-body {
|
|
175
186
|
margin-top: 6px;
|
|
176
187
|
color: var(--muted);
|