pi-link 0.4.0 → 0.5.0

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/bin/pi-link.mjs CHANGED
@@ -340,8 +340,8 @@ function describeMode(mode) {
340
340
  // ── Parser ─────────────────────────────────────────────────────────────────
341
341
  //
342
342
  // Single sequential pass populates `state`; dispatcher reads it. Phases:
343
- // 1. Global flags (--global, --help, --version, --)
344
- // 2. Mode-selecting flags (--list, --resolve, --resolve=<name>)
343
+ // 1. Global flags (--global, --help, --version, --json, --)
344
+ // 2. Mode-selecting flags (--list, --status, --resolve, --resolve=<name>)
345
345
  // 3. Mode-specific extra-token rejection
346
346
  // 4. Launcher mode entry (mode null + bare positional)
347
347
  // 5. Launcher passthrough (mode launcher) with orphan-positional rejection
@@ -619,25 +619,26 @@ function failNoHub(port) {
619
619
  process.exit(2);
620
620
  }
621
621
 
622
- // The frozen contract, checked before any field is read. Anything else on the
623
- // port — a different service, a newer hub, a truncated proxy — must produce the
624
- // unsupported message, never a stack trace. Unknown extra fields stay allowed.
622
+ // The fields the table reads, checked before any of them is read. A body that
623
+ // lacks them or mistypes them — a different service, a truncated proxy, a newer
624
+ // hub gone incompatible — must produce the unsupported message, never a stack
625
+ // trace. Passing says the rows can be printed, nothing more: what the CLI never
626
+ // prints it never checks, so the hub's payload invariants, and whether a hub sent
627
+ // this at all, are not established here.
625
628
  function isContextField(c) {
626
629
  if (c === null) return true;
627
630
  if (!c || typeof c !== "object") return false;
628
631
  return (c.tokens === null || typeof c.tokens === "number") && typeof c.window === "number";
629
632
  }
630
633
 
631
- function isTerminalEntry(entry, index) {
634
+ function isTerminalEntry(entry) {
632
635
  if (!entry || typeof entry !== "object" || Array.isArray(entry)) return false;
633
636
  if (typeof entry.name !== "string") return false;
634
- // Hub first, then clients — the ordering the renderer relies on.
635
- if (entry.role !== (index === 0 ? "hub" : "client")) return false;
636
637
  // `status` and `sinceSeconds` are one optional pair: both or neither.
637
638
  //
638
639
  // The value is checked for shape, not vocabulary. `idle`/`thinking`/
639
640
  // `compacting`/`tool:<name>` are today's kinds, but that set has already grown
640
- // once (`compacting` arrived after 0.3.0) and the CLI never branches on it — it
641
+ // once (`compacting`, in 0.3.0) and the CLI never branches on it — it
641
642
  // only prints it. Freezing the list here would make a newer hub's fifth kind
642
643
  // reject the whole payload, and only while some terminal happened to be in that
643
644
  // state: an intermittent failure telling the user to update. An empty string is
@@ -653,11 +654,7 @@ function isTerminalEntry(entry, index) {
653
654
 
654
655
  function isStatusPayload(payload) {
655
656
  if (!payload || typeof payload !== "object" || Array.isArray(payload)) return false;
656
- if (typeof payload.hub !== "string" || typeof payload.port !== "number") return false;
657
- // A hub always reports itself, so an empty list is not this contract.
658
- if (!Array.isArray(payload.terminals) || payload.terminals.length === 0) return false;
659
- if (!payload.terminals.every(isTerminalEntry)) return false;
660
- return payload.terminals[0].name === payload.hub;
657
+ return Array.isArray(payload.terminals) && payload.terminals.every((e) => isTerminalEntry(e));
661
658
  }
662
659
 
663
660
  async function runStatus(state) {
@@ -700,7 +697,6 @@ async function runStatus(state) {
700
697
  return;
701
698
  }
702
699
 
703
- // Payload order is meaningful: the hub is first, then clients sorted by name.
704
700
  console.log(
705
701
  renderTable(payload.terminals, [
706
702
  { header: "NAME", get: (e) => e.name },