-
Notifications
You must be signed in to change notification settings - Fork 56
feat(doctor): add Pgserve (canonical backbone) check section #1605
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -712,6 +712,97 @@ export function checkLegacyAgentFrontmatter(workspaceRoot?: string): CheckResult | |
| return results; | ||
| } | ||
|
|
||
| /** | ||
| * Check canonical pgserve state — whether the pgserve binary is on PATH, | ||
| * registered under pm2, and listening on the canonical port. Mirrors omni | ||
| * doctor's `pgserve-canonical` check so both halves of the canonical-stack | ||
| * surface the same shared-backbone visibility. | ||
| * | ||
| * Three outcomes: | ||
| * - pgserve missing → WARN with install hint (not FAIL because genie can | ||
| * auto-spawn its own daemon as a fallback for fingerprint-routed CLI). | ||
| * - pgserve installed but not under pm2 → WARN pointing at `pgserve install`. | ||
| * - pgserve registered + reachable → PASS, surface the canonical URL so | ||
| * operators can verify what genie-serve / omni-api are connecting to. | ||
| */ | ||
| async function checkPgserveCanonical(): Promise<CheckResult[]> { | ||
| const results: CheckResult[] = []; | ||
|
|
||
| // Step 1: pgserve binary on PATH? Probe via `pgserve port` (NOT --version | ||
| // — that flag doesn't exist in pgserve@^2.1.0 and false-negatived in | ||
| // historical doctor implementations). | ||
| let canonicalPort: number | null = null; | ||
| try { | ||
| const out = execFileSync('pgserve', ['port'], { | ||
| encoding: 'utf8', | ||
| timeout: 3000, | ||
| stdio: ['ignore', 'pipe', 'ignore'], | ||
| }); | ||
| const parsed = Number.parseInt(out.trim(), 10); | ||
| if (Number.isFinite(parsed) && parsed > 0 && parsed <= 65535) { | ||
| canonicalPort = parsed; | ||
| } | ||
| } catch { | ||
| /* pgserve binary missing or non-zero exit — handled below */ | ||
| } | ||
|
|
||
| if (canonicalPort === null) { | ||
| results.push({ | ||
| name: 'pgserve binary', | ||
| status: 'warn', | ||
| message: 'not on PATH (or `pgserve port` failed)', | ||
| suggestion: | ||
| 'Install canonical pgserve: bun add -g pgserve@^2.1.0 (then run `pgserve install` to register under pm2)', | ||
| }); | ||
| return results; | ||
| } | ||
| results.push({ | ||
| name: 'pgserve binary', | ||
| status: 'pass', | ||
| message: `canonical port ${canonicalPort}`, | ||
| }); | ||
|
|
||
| // Step 2: pm2-supervised? Check via `pgserve status --json`. | ||
| try { | ||
| const status = execFileSync('pgserve', ['status', '--json'], { | ||
| encoding: 'utf8', | ||
| timeout: 3000, | ||
| stdio: ['ignore', 'pipe', 'ignore'], | ||
| }); | ||
|
Comment on lines
+767
to
+771
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar to the binary probe above, consider using Bun's asynchronous shell primitive ($) instead of execFileSync to maintain consistency within this async function and the rest of the file's async check logic. The hardcoded timeout is permitted in this context to prevent the process from hanging. const status = await $("pgserve status --json").timeout(3000).quiet().text();References
|
||
| const parsed = JSON.parse(status) as { installed?: boolean; status?: string }; | ||
| if (parsed.installed === true && parsed.status === 'online') { | ||
| results.push({ | ||
| name: 'pgserve under pm2', | ||
| status: 'pass', | ||
| message: `online — shared backbone for genie-serve + omni-api on :${canonicalPort}`, | ||
| }); | ||
| } else if (parsed.installed === true) { | ||
| results.push({ | ||
| name: 'pgserve under pm2', | ||
| status: 'warn', | ||
| message: `registered but status=${parsed.status ?? 'unknown'}`, | ||
| suggestion: 'Recover with: pm2 restart pgserve (logs: ~/.pgserve/logs/)', | ||
| }); | ||
| } else { | ||
| results.push({ | ||
| name: 'pgserve under pm2', | ||
| status: 'warn', | ||
| message: 'binary present but not registered under pm2', | ||
| suggestion: 'Register canonical pgserve: pgserve install', | ||
| }); | ||
| } | ||
| } catch { | ||
| results.push({ | ||
| name: 'pgserve under pm2', | ||
| status: 'warn', | ||
| message: '`pgserve status` failed (pm2 unreachable?)', | ||
| suggestion: 'Verify pm2: pm2 list | Re-register: pgserve install', | ||
| }); | ||
| } | ||
|
|
||
| return results; | ||
| } | ||
|
|
||
| /** | ||
| * Main doctor command | ||
| */ | ||
|
|
@@ -765,6 +856,7 @@ export async function doctorCommand(options?: { | |
| runCheckSection('Tmux', await checkTmux(), counts); | ||
| runCheckSection('Tmux Configs', checkTmuxConfigs(), counts); | ||
| runCheckSection('Worker Profiles', await checkWorkerProfiles(), counts); | ||
| runCheckSection('Pgserve (canonical backbone)', await checkPgserveCanonical(), counts); | ||
| runCheckSection('Omni Bridge', await checkBridge(), counts); | ||
| runCheckSection('Agent Config', checkLegacyAgentFrontmatter(), counts); | ||
| runCheckSection('Genie Specialist', checkGenieAgentTemplate(), counts); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The checkPgserveCanonical function is marked as async, but it uses the synchronous execFileSync for probing the binary. For consistency with other async checks in this file (like checkTmux) and to avoid blocking the event loop unnecessarily, consider using Bun's asynchronous shell primitive ($). The use of a hardcoded timeout is acceptable here to prevent performance issues during the probe, as per repository guidelines.
References