()
| 560 | // ═══════════════════════════════════════════════════════════════════════════ |
| 561 | |
| 562 | async function main() { |
| 563 | const args = parseArgs(); |
| 564 | const config = await buildConfig(args); |
| 565 | |
| 566 | console.log(""); |
| 567 | console.log( |
| 568 | `${c.cyan}${c.bold}Agent Canvas Static-frontend Development Stack${c.reset}`, |
| 569 | ); |
| 570 | console.log(""); |
| 571 | |
| 572 | // Setup phase (1/3) |
| 573 | checkPrerequisites(); |
| 574 | |
| 575 | // Ensure isolated state dirs (same as dev-with-automation). |
| 576 | const { mkdirSync } = await import("node:fs"); |
| 577 | for (const dir of [ |
| 578 | config.stateDir, |
| 579 | join(config.stateDir, "dev_conversations"), |
| 580 | join(config.stateDir, "workspaces"), |
| 581 | join(config.stateDir, "bash_events"), |
| 582 | join(config.stateDir, "storage"), |
| 583 | ]) { |
| 584 | mkdirSync(dir, { recursive: true }); |
| 585 | } |
| 586 | |
| 587 | // Build phase (2/3): block until the SPA is ready to serve. |
| 588 | buildFrontend(config, args); |
| 589 | |
| 590 | // Service phase (3/3) |
| 591 | logStep("3/3", "Starting services..."); |
| 592 | |
| 593 | // The agent-server skip-loads any conversation whose `owner_lease.json` |
| 594 | // is held by a different `owner_instance_id` and not yet expired (45 s |
| 595 | // TTL). If a previous agent-server (e.g. from `npm run dev`) was killed |
| 596 | // ungracefully — or we restart faster than the lease TTL — every |
| 597 | // conversation gets hidden until those stale leases age out, which |
| 598 | // looks like "the new agent-server doesn't inherit my conversations". |
| 599 | // Bail out if a live agent-server is already bound to our port (we'd |
| 600 | // collide anyway), otherwise unlink the stale leases so the new server |
| 601 | // can claim ownership immediately. |
| 602 | if (await isPortBusy(config.agentServerPort)) { |
| 603 | logError( |
| 604 | `Port ${config.agentServerPort} is already in use — another ` + |
| 605 | `agent-server is running. Stop it (e.g. quit \`npm run dev\`) ` + |
| 606 | `before running dev:static.`, |
| 607 | ); |
| 608 | process.exit(1); |
| 609 | } |
| 610 | const conversationsPath = join(config.stateDir, "dev_conversations"); |
| 611 | const cleared = releaseStaleConversationLeases(conversationsPath); |
| 612 | if (cleared > 0) { |
| 613 | logService( |
| 614 | "agent-server", |
| 615 | `Released ${cleared} stale conversation lease(s) so the new ` + |
| 616 | `agent-server can resume ownership.`, |
| 617 | c.dim, |
| 618 | ); |
| 619 | } |
no test coverage detected