pi-mega-compact 0.4.9 → 0.4.10
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/extensions/mega-compact.js +51 -37
- package/extensions/mega-compact.ts +45 -27
- package/package.json +1 -1
|
@@ -651,33 +651,40 @@ export default function (pi) {
|
|
|
651
651
|
// ---- Dashboard server commands ----------------------------------------
|
|
652
652
|
const portFile = join(currentStateDir, "port.pid");
|
|
653
653
|
const runnerFile = join(currentStateDir, "_dashboard-runner.mjs");
|
|
654
|
+
const launchLog = join(currentStateDir, "_dashboard-launch.log");
|
|
654
655
|
// Whether the runner must be spawned with --experimental-strip-types (true only
|
|
655
656
|
// when we fall back to the .ts source outside node_modules; false when using
|
|
656
657
|
// the shipped compiled dist/extensions/dashboard-server.js).
|
|
657
658
|
let dashboardNeedsStrip = false;
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
const info = JSON.parse(readFileSync(portFile, "utf-8"));
|
|
664
|
-
if (!info?.port)
|
|
665
|
-
return null;
|
|
666
|
-
const url = `http://localhost:${info.port}`; // guardrails-allow PREVENT-PI-004: localhost URL of the dashboard server this extension spawned
|
|
667
|
-
// Quick liveness probe
|
|
668
|
-
const res = await fetch(`${url}/api/snapshot`, { signal: AbortSignal.timeout(1500) }); // guardrails-allow PREVENT-PI-004: localhost probe to the dashboard server this extension spawned
|
|
669
|
-
if (res.ok)
|
|
670
|
-
return { port: info.port, url };
|
|
671
|
-
}
|
|
672
|
-
catch {
|
|
673
|
-
// stale or unreachable — clean up
|
|
659
|
+
// The dashboard server binds 9320–9329 (TARGET_PORT..TARGET_PORT+PORT_RANGE-1
|
|
660
|
+
// in dashboard-server.js). Probe each for a live /api/snapshot so we can detect
|
|
661
|
+
// readiness even when port.pid landed in a different state dir than we poll.
|
|
662
|
+
async function findLivePort() {
|
|
663
|
+
for (let port = 9320; port <= 9329; port++) {
|
|
674
664
|
try {
|
|
675
|
-
|
|
665
|
+
const res = await fetch(`http://localhost:${port}/api/snapshot`, { signal: AbortSignal.timeout(800) }); // guardrails-allow PREVENT-PI-004: localhost liveness probe of the dashboard server this extension spawned
|
|
666
|
+
if (res.ok)
|
|
667
|
+
return port;
|
|
676
668
|
}
|
|
677
|
-
catch { /*
|
|
669
|
+
catch { /* not on this port — try next */ }
|
|
678
670
|
}
|
|
679
671
|
return null;
|
|
680
672
|
}
|
|
673
|
+
/** Try to reach a running dashboard server. Returns { port, url } or null. */
|
|
674
|
+
async function isServerRunning() {
|
|
675
|
+
const port = await findLivePort();
|
|
676
|
+
if (!port) {
|
|
677
|
+
// Stale marker with no live server behind it — clean up.
|
|
678
|
+
if (existsSync(portFile)) {
|
|
679
|
+
try {
|
|
680
|
+
unlinkSync(portFile);
|
|
681
|
+
}
|
|
682
|
+
catch { /* ignore */ }
|
|
683
|
+
}
|
|
684
|
+
return null;
|
|
685
|
+
}
|
|
686
|
+
return { port, url: `http://localhost:${port}` }; // guardrails-allow PREVENT-PI-004: localhost URL of the dashboard server this extension spawned
|
|
687
|
+
}
|
|
681
688
|
/**
|
|
682
689
|
* Resolve the launchable dashboard-server module.
|
|
683
690
|
*
|
|
@@ -718,11 +725,16 @@ export default function (pi) {
|
|
|
718
725
|
return false;
|
|
719
726
|
dashboardNeedsStrip = resolved.needsStripTypes;
|
|
720
727
|
const script = [
|
|
721
|
-
`import {
|
|
722
|
-
`
|
|
723
|
-
`
|
|
728
|
+
`import { appendFileSync } from "node:fs";`,
|
|
729
|
+
`const __log = ${JSON.stringify(launchLog)};`,
|
|
730
|
+
`function __fail(err) {`,
|
|
731
|
+
` const msg = "[mega-compact] dashboard failed: " + (err && err.stack ? err.stack : String(err));`,
|
|
732
|
+
` try { appendFileSync(__log, msg + "\\n"); } catch { /* ignore */ }`,
|
|
733
|
+
` console.error(msg);`,
|
|
724
734
|
` process.exit(1);`,
|
|
725
|
-
`}
|
|
735
|
+
`}`,
|
|
736
|
+
`import { launchDashboardServer } from ${JSON.stringify(resolved.entry)};`,
|
|
737
|
+
`launchDashboardServer(${JSON.stringify(currentStateDir)}).catch(__fail);`,
|
|
726
738
|
].join("\n");
|
|
727
739
|
writeFileSync(runnerFile, script);
|
|
728
740
|
return true;
|
|
@@ -763,24 +775,26 @@ export default function (pi) {
|
|
|
763
775
|
stdio: "ignore",
|
|
764
776
|
});
|
|
765
777
|
child.unref();
|
|
766
|
-
// Poll for
|
|
767
|
-
|
|
768
|
-
|
|
778
|
+
// Poll for a live server (port 9320–9329) instead of relying solely on the
|
|
779
|
+
// port.pid marker, which can land in a different state dir than the one we
|
|
780
|
+
// poll when a prior compact left currentStateDir pointing elsewhere.
|
|
781
|
+
const deadline = Date.now() + 6_000;
|
|
782
|
+
let port = null;
|
|
769
783
|
while (Date.now() < deadline) {
|
|
770
|
-
await new Promise((
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
if (raw?.port) {
|
|
775
|
-
port = raw.port;
|
|
776
|
-
break;
|
|
777
|
-
}
|
|
778
|
-
}
|
|
779
|
-
catch { /* keep polling */ }
|
|
780
|
-
}
|
|
784
|
+
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
785
|
+
port = await findLivePort();
|
|
786
|
+
if (port)
|
|
787
|
+
break;
|
|
781
788
|
}
|
|
782
789
|
if (!port) {
|
|
783
|
-
|
|
790
|
+
let detail = "";
|
|
791
|
+
try {
|
|
792
|
+
const log = readFileSync(launchLog, "utf-8").trim();
|
|
793
|
+
if (log)
|
|
794
|
+
detail = ` — ${log.split("\n").slice(-3).join("; ")}`;
|
|
795
|
+
}
|
|
796
|
+
catch { /* no log yet */ }
|
|
797
|
+
ctx.ui.notify(`[mega-compact] dashboard server failed to start${detail}. See ${launchLog}`);
|
|
784
798
|
return;
|
|
785
799
|
}
|
|
786
800
|
const url = `http://localhost:${port}`; // guardrails-allow PREVENT-PI-004: localhost URL of the dashboard server this extension spawned
|
|
@@ -790,26 +790,36 @@ export default function (pi: ExtensionAPI) {
|
|
|
790
790
|
|
|
791
791
|
const portFile = join(currentStateDir, "port.pid");
|
|
792
792
|
const runnerFile = join(currentStateDir, "_dashboard-runner.mjs");
|
|
793
|
+
const launchLog = join(currentStateDir, "_dashboard-launch.log");
|
|
793
794
|
// Whether the runner must be spawned with --experimental-strip-types (true only
|
|
794
795
|
// when we fall back to the .ts source outside node_modules; false when using
|
|
795
796
|
// the shipped compiled dist/extensions/dashboard-server.js).
|
|
796
797
|
let dashboardNeedsStrip = false;
|
|
797
798
|
|
|
799
|
+
// The dashboard server binds 9320–9329 (TARGET_PORT..TARGET_PORT+PORT_RANGE-1
|
|
800
|
+
// in dashboard-server.js). Probe each for a live /api/snapshot so we can detect
|
|
801
|
+
// readiness even when port.pid landed in a different state dir than we poll.
|
|
802
|
+
async function findLivePort(): Promise<number | null> {
|
|
803
|
+
for (let port = 9320; port <= 9329; port++) {
|
|
804
|
+
try {
|
|
805
|
+
const res = await fetch(`http://localhost:${port}/api/snapshot`, { signal: AbortSignal.timeout(800) }); // guardrails-allow PREVENT-PI-004: localhost liveness probe of the dashboard server this extension spawned
|
|
806
|
+
if (res.ok) return port;
|
|
807
|
+
} catch { /* not on this port — try next */ }
|
|
808
|
+
}
|
|
809
|
+
return null;
|
|
810
|
+
}
|
|
811
|
+
|
|
798
812
|
/** Try to reach a running dashboard server. Returns { port, url } or null. */
|
|
799
813
|
async function isServerRunning(): Promise<{ port: number; url: string } | null> {
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
if (
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
if (res.ok) return { port: info.port, url };
|
|
808
|
-
} catch {
|
|
809
|
-
// stale or unreachable — clean up
|
|
810
|
-
try { unlinkSync(portFile); } catch { /* ignore */ }
|
|
814
|
+
const port = await findLivePort();
|
|
815
|
+
if (!port) {
|
|
816
|
+
// Stale marker with no live server behind it — clean up.
|
|
817
|
+
if (existsSync(portFile)) {
|
|
818
|
+
try { unlinkSync(portFile); } catch { /* ignore */ }
|
|
819
|
+
}
|
|
820
|
+
return null;
|
|
811
821
|
}
|
|
812
|
-
return
|
|
822
|
+
return { port, url: `http://localhost:${port}` }; // guardrails-allow PREVENT-PI-004: localhost URL of the dashboard server this extension spawned
|
|
813
823
|
}
|
|
814
824
|
|
|
815
825
|
/**
|
|
@@ -850,11 +860,16 @@ export default function (pi: ExtensionAPI) {
|
|
|
850
860
|
if (!resolved) return false;
|
|
851
861
|
dashboardNeedsStrip = resolved.needsStripTypes;
|
|
852
862
|
const script = [
|
|
853
|
-
`import {
|
|
854
|
-
`
|
|
855
|
-
`
|
|
863
|
+
`import { appendFileSync } from "node:fs";`,
|
|
864
|
+
`const __log = ${JSON.stringify(launchLog)};`,
|
|
865
|
+
`function __fail(err) {`,
|
|
866
|
+
` const msg = "[mega-compact] dashboard failed: " + (err && err.stack ? err.stack : String(err));`,
|
|
867
|
+
` try { appendFileSync(__log, msg + "\\n"); } catch { /* ignore */ }`,
|
|
868
|
+
` console.error(msg);`,
|
|
856
869
|
` process.exit(1);`,
|
|
857
|
-
`}
|
|
870
|
+
`}`,
|
|
871
|
+
`import { launchDashboardServer } from ${JSON.stringify(resolved.entry)};`,
|
|
872
|
+
`launchDashboardServer(${JSON.stringify(currentStateDir)}).catch(__fail);`,
|
|
858
873
|
].join("\n");
|
|
859
874
|
writeFileSync(runnerFile, script);
|
|
860
875
|
return true;
|
|
@@ -900,21 +915,24 @@ export default function (pi: ExtensionAPI) {
|
|
|
900
915
|
});
|
|
901
916
|
child.unref();
|
|
902
917
|
|
|
903
|
-
// Poll for
|
|
904
|
-
|
|
905
|
-
|
|
918
|
+
// Poll for a live server (port 9320–9329) instead of relying solely on the
|
|
919
|
+
// port.pid marker, which can land in a different state dir than the one we
|
|
920
|
+
// poll when a prior compact left currentStateDir pointing elsewhere.
|
|
921
|
+
const deadline = Date.now() + 6_000;
|
|
922
|
+
let port: number | null = null;
|
|
906
923
|
while (Date.now() < deadline) {
|
|
907
|
-
await new Promise((
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
const raw = JSON.parse(readFileSync(portFile, "utf-8"));
|
|
911
|
-
if (raw?.port) { port = raw.port; break; }
|
|
912
|
-
} catch { /* keep polling */ }
|
|
913
|
-
}
|
|
924
|
+
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
925
|
+
port = await findLivePort();
|
|
926
|
+
if (port) break;
|
|
914
927
|
}
|
|
915
928
|
|
|
916
929
|
if (!port) {
|
|
917
|
-
|
|
930
|
+
let detail = "";
|
|
931
|
+
try {
|
|
932
|
+
const log = readFileSync(launchLog, "utf-8").trim();
|
|
933
|
+
if (log) detail = ` — ${log.split("\n").slice(-3).join("; ")}`;
|
|
934
|
+
} catch { /* no log yet */ }
|
|
935
|
+
ctx.ui.notify(`[mega-compact] dashboard server failed to start${detail}. See ${launchLog}`);
|
|
918
936
|
return;
|
|
919
937
|
}
|
|
920
938
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-mega-compact",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.10",
|
|
4
4
|
"description": "Layered, local, vector-backed context compressor for pi — supersede/collapse/cluster compaction with deduped inline recall.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "BSD-2-Clause",
|