@pushpalsdev/cli 1.0.8 → 1.0.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.
Files changed (28) hide show
  1. package/dist/pushpals-cli.js +176 -19
  2. package/monitor-ui/+not-found.html +440 -0
  3. package/monitor-ui/_expo/.routes.json +3 -0
  4. package/monitor-ui/_expo/static/js/web/entry-7e55666b7443eef13f7696e8d422e8cf.js +1218 -0
  5. package/monitor-ui/_expo/static/js/web/index-04194fb85c12ac46718492c2ff687e6c.js +6 -0
  6. package/monitor-ui/_sitemap.html +440 -0
  7. package/monitor-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/back-icon-mask.0a328cd9c1afd0afe8e3b1ec5165b1b4.png +0 -0
  8. package/monitor-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/back-icon.35ba0eaec5a4f5ed12ca16fabeae451d.png +0 -0
  9. package/monitor-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55.png +0 -0
  10. package/monitor-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55@2x.png +0 -0
  11. package/monitor-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55@3x.png +0 -0
  12. package/monitor-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55@4x.png +0 -0
  13. package/monitor-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7.png +0 -0
  14. package/monitor-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7@2x.png +0 -0
  15. package/monitor-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7@3x.png +0 -0
  16. package/monitor-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7@4x.png +0 -0
  17. package/monitor-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/search-icon.286d67d3f74808a60a78d3ebf1a5fb57.png +0 -0
  18. package/monitor-ui/assets/__node_modules/expo-router/assets/arrow_down.017bc6ba3fc25503e5eb5e53826d48a8.png +0 -0
  19. package/monitor-ui/assets/__node_modules/expo-router/assets/error.d1ea1496f9057eb392d5bbf3732a61b7.png +0 -0
  20. package/monitor-ui/assets/__node_modules/expo-router/assets/file.19eeb73b9593a38f8e9f418337fc7d10.png +0 -0
  21. package/monitor-ui/assets/__node_modules/expo-router/assets/forward.d8b800c443b8972542883e0b9de2bdc6.png +0 -0
  22. package/monitor-ui/assets/__node_modules/expo-router/assets/pkg.ab19f4cbc543357183a20571f68380a3.png +0 -0
  23. package/monitor-ui/assets/__node_modules/expo-router/assets/sitemap.412dd9275b6b48ad28f5e3d81bb1f626.png +0 -0
  24. package/monitor-ui/assets/__node_modules/expo-router/assets/unmatched.20e71bdf79e3a97bf55fd9e164041578.png +0 -0
  25. package/monitor-ui/favicon.ico +0 -0
  26. package/monitor-ui/index.html +440 -0
  27. package/monitor-ui/modal.html +440 -0
  28. package/package.json +3 -2
@@ -2,8 +2,16 @@
2
2
  // @bun
3
3
 
4
4
  // ../../scripts/pushpals-cli.ts
5
- import { appendFileSync, chmodSync, cpSync, existsSync as existsSync3, mkdirSync, readFileSync as readFileSync3, writeFileSync } from "fs";
6
- import { dirname, join as join2, resolve as resolve3 } from "path";
5
+ import {
6
+ appendFileSync,
7
+ chmodSync,
8
+ cpSync,
9
+ existsSync as existsSync3,
10
+ mkdirSync,
11
+ readFileSync as readFileSync3,
12
+ writeFileSync
13
+ } from "fs";
14
+ import { dirname, extname, join as join2, resolve as resolve3 } from "path";
7
15
  import { createInterface } from "readline";
8
16
 
9
17
  // ../shared/src/client_preflight.ts
@@ -1228,6 +1236,56 @@ function resolveBundledRuntimeAssetSource() {
1228
1236
  }
1229
1237
  return null;
1230
1238
  }
1239
+ function looksLikeMonitoringHubBuild(root) {
1240
+ return existsSync3(join2(root, "index.html")) && existsSync3(join2(root, "_expo"));
1241
+ }
1242
+ function resolveBundledMonitoringHubRoot() {
1243
+ const candidates = [
1244
+ resolve3(import.meta.dir, "..", "monitor-ui"),
1245
+ resolve3(import.meta.dir, "..", "packages", "cli", "monitor-ui")
1246
+ ];
1247
+ for (const candidate of candidates) {
1248
+ if (looksLikeMonitoringHubBuild(candidate))
1249
+ return candidate;
1250
+ }
1251
+ return null;
1252
+ }
1253
+ function resolveCliSourceCheckoutRoot() {
1254
+ const candidates = [
1255
+ resolve3(import.meta.dir, ".."),
1256
+ resolve3(import.meta.dir, "..", ".."),
1257
+ resolve3(import.meta.dir, "..", "..", "..")
1258
+ ];
1259
+ for (const candidate of candidates) {
1260
+ if (existsSync3(join2(candidate, "package.json")) && existsSync3(join2(candidate, "apps", "client", "app.json")) && existsSync3(join2(candidate, "scripts", "sync-cli-monitor-ui.ts"))) {
1261
+ return candidate;
1262
+ }
1263
+ }
1264
+ return null;
1265
+ }
1266
+ function exportBundledMonitoringHubFromSourceCheckout(sourceRoot) {
1267
+ const exportScriptPath = join2(sourceRoot, "scripts", "sync-cli-monitor-ui.ts");
1268
+ console.log("[pushpals] Packaged monitor UI missing; exporting the shared client monitor...");
1269
+ const proc = Bun.spawnSync([process.execPath, exportScriptPath], {
1270
+ cwd: sourceRoot,
1271
+ stdout: "inherit",
1272
+ stderr: "inherit",
1273
+ env: process.env
1274
+ });
1275
+ if (proc.exitCode !== 0) {
1276
+ throw new Error(`Failed to export packaged monitor UI from source checkout (exit ${proc.exitCode || 1})`);
1277
+ }
1278
+ }
1279
+ async function ensureBundledMonitoringHubRoot() {
1280
+ const existingRoot = resolveBundledMonitoringHubRoot();
1281
+ if (existingRoot)
1282
+ return existingRoot;
1283
+ const sourceRoot = resolveCliSourceCheckoutRoot();
1284
+ if (!sourceRoot)
1285
+ return null;
1286
+ exportBundledMonitoringHubFromSourceCheckout(sourceRoot);
1287
+ return resolveBundledMonitoringHubRoot();
1288
+ }
1231
1289
  function repoLooksLikePushPalsSourceCheckout(repoRoot) {
1232
1290
  return existsSync3(join2(repoRoot, "configs", "default.toml")) || existsSync3(join2(repoRoot, "config", "default.toml"));
1233
1291
  }
@@ -1479,10 +1537,7 @@ async function resolveCommandPath(command, cwd, env) {
1479
1537
  stdout: "pipe",
1480
1538
  stderr: "ignore"
1481
1539
  });
1482
- const [stdout, exitCode] = await Promise.all([
1483
- new Response(proc.stdout).text(),
1484
- proc.exited
1485
- ]);
1540
+ const [stdout, exitCode] = await Promise.all([new Response(proc.stdout).text(), proc.exited]);
1486
1541
  if (exitCode !== 0)
1487
1542
  continue;
1488
1543
  const resolved = stdout.split(/\r?\n/).map((line) => line.trim()).find((line) => line.length > 0);
@@ -1882,6 +1937,91 @@ async function looksLikeMonitoringHub(url) {
1882
1937
  return false;
1883
1938
  }
1884
1939
  }
1940
+ function buildMonitoringHubRuntimeBootstrap(opts) {
1941
+ return {
1942
+ serverUrl: opts.serverUrl,
1943
+ localAgentUrl: opts.localAgentUrl,
1944
+ sessionId: opts.sessionId,
1945
+ authToken: opts.authToken
1946
+ };
1947
+ }
1948
+ function injectMonitoringHubBootstrap(html, bootstrap) {
1949
+ const payload = jsonHtmlBootstrap(bootstrap);
1950
+ const script = `<script>globalThis.__PUSHPALS_WEB_BOOTSTRAP__=${payload};</script>`;
1951
+ if (html.includes("</head>")) {
1952
+ return html.replace("</head>", `${script}</head>`);
1953
+ }
1954
+ return `${script}${html}`;
1955
+ }
1956
+ function monitoringHubContentType(pathValue) {
1957
+ switch (extname(pathValue).toLowerCase()) {
1958
+ case ".html":
1959
+ return "text/html; charset=utf-8";
1960
+ case ".js":
1961
+ return "application/javascript; charset=utf-8";
1962
+ case ".css":
1963
+ return "text/css; charset=utf-8";
1964
+ case ".json":
1965
+ return "application/json; charset=utf-8";
1966
+ case ".svg":
1967
+ return "image/svg+xml";
1968
+ case ".png":
1969
+ return "image/png";
1970
+ case ".jpg":
1971
+ case ".jpeg":
1972
+ return "image/jpeg";
1973
+ case ".ico":
1974
+ return "image/x-icon";
1975
+ case ".woff2":
1976
+ return "font/woff2";
1977
+ case ".ttf":
1978
+ return "font/ttf";
1979
+ case ".map":
1980
+ return "application/json; charset=utf-8";
1981
+ default:
1982
+ return "application/octet-stream";
1983
+ }
1984
+ }
1985
+ function resolveMonitoringHubAssetPath(assetRoot, pathname) {
1986
+ const root = resolve3(assetRoot);
1987
+ const rootPrefix = `${root}${root.endsWith("\\") || root.endsWith("/") ? "" : process.platform === "win32" ? "\\" : "/"}`;
1988
+ const decodedPath = decodeURIComponent(pathname);
1989
+ const trimmedPath = decodedPath === "/" ? "/index.html" : decodedPath;
1990
+ const relativePath = trimmedPath.replace(/^\/+/, "");
1991
+ const candidatePath = resolve3(root, relativePath);
1992
+ if (candidatePath !== root && !candidatePath.startsWith(rootPrefix))
1993
+ return null;
1994
+ if (existsSync3(candidatePath))
1995
+ return candidatePath;
1996
+ if (!extname(relativePath)) {
1997
+ const nestedIndexPath = resolve3(root, relativePath, "index.html");
1998
+ if ((nestedIndexPath === root || nestedIndexPath.startsWith(rootPrefix)) && existsSync3(nestedIndexPath)) {
1999
+ return nestedIndexPath;
2000
+ }
2001
+ return join2(root, "index.html");
2002
+ }
2003
+ return null;
2004
+ }
2005
+ async function serveBundledMonitoringHub(assetRoot, pathname, bootstrap) {
2006
+ const assetPath = resolveMonitoringHubAssetPath(assetRoot, pathname);
2007
+ if (!assetPath || !existsSync3(assetPath))
2008
+ return null;
2009
+ if (assetPath.endsWith("index.html")) {
2010
+ const html = injectMonitoringHubBootstrap(readFileSync3(assetPath, "utf8"), bootstrap);
2011
+ return new Response(html, {
2012
+ headers: {
2013
+ "content-type": "text/html; charset=utf-8",
2014
+ "cache-control": "no-store"
2015
+ }
2016
+ });
2017
+ }
2018
+ return new Response(Bun.file(assetPath), {
2019
+ headers: {
2020
+ "content-type": monitoringHubContentType(assetPath),
2021
+ "cache-control": "no-store"
2022
+ }
2023
+ });
2024
+ }
1885
2025
  function buildEmbeddedMonitoringHubHtml(opts) {
1886
2026
  const bootstrap = jsonHtmlBootstrap(opts);
1887
2027
  return `<!doctype html>
@@ -2029,10 +2169,16 @@ async function proxyMonitoringHubRequest(serverUrl, authToken, pathValue) {
2029
2169
  });
2030
2170
  }
2031
2171
  async function startEmbeddedMonitoringHub(opts) {
2032
- const html = buildEmbeddedMonitoringHubHtml({
2172
+ const monitoringHubAssetRoot = opts.assetRoot === undefined ? await ensureBundledMonitoringHubRoot() : opts.assetRoot;
2173
+ if (!monitoringHubAssetRoot || !looksLikeMonitoringHubBuild(monitoringHubAssetRoot)) {
2174
+ console.error("[pushpals] Unified monitoring hub assets are unavailable; build or export the packaged client monitor first.");
2175
+ return null;
2176
+ }
2177
+ const bootstrap = buildMonitoringHubRuntimeBootstrap({
2033
2178
  serverUrl: opts.serverUrl,
2034
2179
  localAgentUrl: opts.localAgentUrl,
2035
- sessionId: opts.sessionId
2180
+ sessionId: opts.sessionId,
2181
+ authToken: opts.authToken
2036
2182
  });
2037
2183
  const candidatePorts = Array.from({ length: MONITOR_SCAN_PORTS }, (_, index) => opts.preferredPort + index).concat(0);
2038
2184
  for (const port of candidatePorts) {
@@ -2042,16 +2188,13 @@ async function startEmbeddedMonitoringHub(opts) {
2042
2188
  idleTimeout: 30,
2043
2189
  fetch: async (req) => {
2044
2190
  const url = new URL(req.url);
2045
- if (url.pathname === "/") {
2046
- return new Response(html, {
2047
- headers: {
2048
- "content-type": "text/html; charset=utf-8",
2049
- "cache-control": "no-store"
2050
- }
2051
- });
2052
- }
2053
2191
  if (url.pathname === "/healthz") {
2054
- return Response.json({ ok: true, port, serverUrl: opts.serverUrl, sessionId: opts.sessionId });
2192
+ return Response.json({
2193
+ ok: true,
2194
+ port,
2195
+ serverUrl: opts.serverUrl,
2196
+ sessionId: opts.sessionId
2197
+ });
2055
2198
  }
2056
2199
  if (url.pathname === "/api/status") {
2057
2200
  return await proxyMonitoringHubRequest(opts.serverUrl, opts.authToken, "/system/status");
@@ -2065,6 +2208,9 @@ async function startEmbeddedMonitoringHub(opts) {
2065
2208
  if (url.pathname === "/api/completions") {
2066
2209
  return await proxyMonitoringHubRequest(opts.serverUrl, opts.authToken, "/completions?status=all&limit=20");
2067
2210
  }
2211
+ const bundledResponse = await serveBundledMonitoringHub(monitoringHubAssetRoot, url.pathname, bootstrap);
2212
+ if (bundledResponse)
2213
+ return bundledResponse;
2068
2214
  return new Response("Not found", { status: 404 });
2069
2215
  }
2070
2216
  });
@@ -2286,6 +2432,10 @@ async function openMonitoringHub(url) {
2286
2432
  const code = await proc.exited;
2287
2433
  return code === 0;
2288
2434
  }
2435
+ function isCliExitCommand(text) {
2436
+ const normalized = String(text ?? "").trim().toLowerCase();
2437
+ return normalized === "/exit" || normalized === "/quit" || normalized === "exit" || normalized === "quit";
2438
+ }
2289
2439
  async function main() {
2290
2440
  const argv = process.argv.slice(2);
2291
2441
  logCliInvocation(argv);
@@ -2410,7 +2560,7 @@ async function main() {
2410
2560
  console.log(`sessionId=${localBuddySessionId}`);
2411
2561
  console.log(`repoRoot=${repoRoot}`);
2412
2562
  console.log(`cliStateFile=${statePath}`);
2413
- console.log("[pushpals] Type a message and press Enter. Use /exit to quit.");
2563
+ console.log("[pushpals] Type a message and press Enter. Use /exit or exit to quit.");
2414
2564
  const streamAbort = new AbortController;
2415
2565
  let rl = null;
2416
2566
  const printIncoming = (line) => {
@@ -2431,12 +2581,16 @@ ${line}
2431
2581
  if (shuttingDown)
2432
2582
  return;
2433
2583
  shuttingDown = true;
2584
+ console.log("[pushpals] Shutting down CLI session...");
2434
2585
  streamAbort.abort();
2435
2586
  if (rl)
2436
2587
  rl.close();
2437
2588
  try {
2438
2589
  monitoringHub?.stop();
2439
2590
  } catch {}
2591
+ if (autoStartedServices.length > 0) {
2592
+ console.log("[pushpals] Stopping embedded runtime services...");
2593
+ }
2440
2594
  stopAutoStartedServices();
2441
2595
  };
2442
2596
  process.once("SIGINT", requestStop);
@@ -2455,7 +2609,7 @@ ${line}
2455
2609
  rl.prompt();
2456
2610
  continue;
2457
2611
  }
2458
- if (text === "/exit" || text === "/quit") {
2612
+ if (isCliExitCommand(text)) {
2459
2613
  requestStop();
2460
2614
  break;
2461
2615
  }
@@ -2503,8 +2657,11 @@ export {
2503
2657
  startEmbeddedMonitoringHub,
2504
2658
  resolveCommandPath,
2505
2659
  resolveBundledRuntimeAssetSource,
2660
+ resolveBundledMonitoringHubRoot,
2506
2661
  prepareCliRuntime,
2507
2662
  normalizeChildProcessEnv,
2663
+ isCliExitCommand,
2664
+ injectMonitoringHubBootstrap,
2508
2665
  buildServiceStopCommand,
2509
2666
  buildOpenMonitoringHubCommand,
2510
2667
  buildEmbeddedRuntimeEnv,