pi-sdk-web 0.5.9 → 0.5.11

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 CHANGED
@@ -12,7 +12,7 @@ import { execFileSync } from "node:child_process";
12
12
  import { existsSync, readFileSync } from "node:fs";
13
13
  import { readFile, unlink } from "node:fs/promises";
14
14
  import { createServer } from "node:http";
15
- import { dirname, join, resolve, sep } from "node:path";
15
+ import { dirname, join, relative, resolve, sep } from "node:path";
16
16
  import { fileURLToPath } from "node:url";
17
17
  import { ModelRegistry, VERSION, } from "@earendil-works/pi-coding-agent";
18
18
  import { WebSocket, WebSocketServer } from "ws";
@@ -22,6 +22,18 @@ const DEFAULT_PORT = 4080;
22
22
  // Static frontend: prefer the in-package copy (built by `npm run build` for
23
23
  // global installs), fall back to the repo-root static/ during development.
24
24
  const PACKAGE_DIR = resolve(dirname(fileURLToPath(import.meta.url)), "..");
25
+ /** Format a local file extension path for the sidebar: relative to baseDir,
26
+ * with the ".pi/extensions/" prefix and the entry suffix (".ts"/".js"/"/index")
27
+ * stripped, e.g. ".../.pi/extensions/import-repro.ts" -> "import-repro",
28
+ * ".../extensions/refresh-deepinfra/index.ts" -> "refresh-deepinfra". */
29
+ function describeLocalExtension(entryPath, baseDir) {
30
+ const rel = baseDir
31
+ ? relative(baseDir, entryPath).replace(/\\/g, "/")
32
+ : entryPath.replace(/\\/g, "/");
33
+ let name = rel.replace(/^extensions\//, "");
34
+ name = name.replace(/\/index\.[jt]s$/, "").replace(/\.[jt]s$/, "");
35
+ return name || rel;
36
+ }
25
37
  // Static frontend source:
26
38
  // - dev (tsx runs src/server.ts): always the repo-root static/ (live files)
27
39
  // - published (dist/server.js): the built copy at dist/static (packaged)
@@ -435,9 +447,29 @@ export class PiWebServer {
435
447
  const list = [];
436
448
  const seen = new Set();
437
449
  for (const ext of result.extensions) {
438
- // ext.path points at the extension entry (e.g. .../lib/node_modules/
439
- // pi-magic-context/dist/index.js); walk up to the nearest package.json
440
- // for the name/version.
450
+ // Inline extensions (Pi built-ins like <inline:llama.cpp>, hidden:
451
+ // true) are virtual - no package.json, no disk entry. Skip them so
452
+ // the sidebar lists only real, on-disk extensions.
453
+ if (ext.path.startsWith("<") && ext.path.endsWith(">")) {
454
+ continue;
455
+ }
456
+ const sourceInfo = ext
457
+ .sourceInfo;
458
+ // Local file extensions (~/.pi/agent/extensions/*.ts or project
459
+ // .pi/extensions/*.ts): the nearest package.json is the HOST repo's
460
+ // (e.g. Pi's own monorepo root) and would show a misleading name.
461
+ // Show the extension file name + scope instead.
462
+ if (sourceInfo?.origin === "top-level") {
463
+ const name = describeLocalExtension(ext.path, sourceInfo.baseDir);
464
+ const key = `local:${ext.path}`;
465
+ if (!seen.has(key)) {
466
+ seen.add(key);
467
+ list.push({ name, version: sourceInfo.scope ?? "local" });
468
+ }
469
+ continue;
470
+ }
471
+ // Package extensions: walk up to the nearest package.json (e.g.
472
+ // .../node_modules/pi-magic-context/dist/index.js -> pi-magic-context)
441
473
  let dir = dirname(ext.path);
442
474
  while (dir !== dirname(dir)) {
443
475
  const pkgFile = join(dir, "package.json");
@@ -447,7 +479,14 @@ export class PiWebServer {
447
479
  const key = pkg.name ?? ext.path;
448
480
  if (!seen.has(key)) {
449
481
  seen.add(key);
450
- list.push({ name: pkg.name ?? key, version: pkg.version ?? "?" });
482
+ // Append the install scope (user/project, from sourceInfo) so
483
+ // package extensions show the same dimension as local ones.
484
+ const scope = sourceInfo?.scope;
485
+ const version = pkg.version ?? "?";
486
+ list.push({
487
+ name: pkg.name ?? key,
488
+ version: scope ? `${version} · ${scope}` : version,
489
+ });
451
490
  }
452
491
  }
453
492
  catch {
@@ -4,6 +4,7 @@
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>pi-web</title>
7
+ <link rel="icon" type="image/svg+xml" href="pi-logo.svg">
7
8
  <link rel="stylesheet" href="style.css">
8
9
  </head>
9
10
  <body>
@@ -0,0 +1,28 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 800">
3
+ <style>
4
+ .logo-mark { fill: #000; }
5
+ @media (prefers-color-scheme: dark) {
6
+ .logo-mark { fill: #fff; }
7
+ }
8
+ </style>
9
+ <!-- P shape: outer boundary clockwise, inner hole counter-clockwise -->
10
+ <path class="logo-mark" fill-rule="evenodd" d="
11
+ M165.29 165.29
12
+ H517.36
13
+ V400
14
+ H400
15
+ V517.36
16
+ H282.65
17
+ V634.72
18
+ H165.29
19
+ Z
20
+ M282.65 282.65
21
+ V400
22
+ H400
23
+ V282.65
24
+ Z
25
+ "/>
26
+ <!-- i dot -->
27
+ <path class="logo-mark" d="M517.36 400 H634.72 V634.72 H517.36 Z"/>
28
+ </svg>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-sdk-web",
3
- "version": "0.5.9",
3
+ "version": "0.5.11",
4
4
  "description": "Browser Web access for Pi (AI coding agent) via the Pi SDK - standalone module, zero modification to Pi itself",
5
5
  "type": "module",
6
6
  "bin": {