@agentuity/cli 0.0.109 → 0.0.111

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 (253) hide show
  1. package/dist/build-report.d.ts +201 -0
  2. package/dist/build-report.d.ts.map +1 -0
  3. package/dist/build-report.js +335 -0
  4. package/dist/build-report.js.map +1 -0
  5. package/dist/cli.d.ts.map +1 -1
  6. package/dist/cli.js +19 -4
  7. package/dist/cli.js.map +1 -1
  8. package/dist/cmd/build/entry-generator.d.ts.map +1 -1
  9. package/dist/cmd/build/entry-generator.js +3 -1
  10. package/dist/cmd/build/entry-generator.js.map +1 -1
  11. package/dist/cmd/build/index.d.ts.map +1 -1
  12. package/dist/cmd/build/index.js +44 -1
  13. package/dist/cmd/build/index.js.map +1 -1
  14. package/dist/cmd/build/typecheck.d.ts +7 -1
  15. package/dist/cmd/build/typecheck.d.ts.map +1 -1
  16. package/dist/cmd/build/typecheck.js +11 -1
  17. package/dist/cmd/build/typecheck.js.map +1 -1
  18. package/dist/cmd/build/vite/agent-discovery.d.ts +1 -1
  19. package/dist/cmd/build/vite/agent-discovery.d.ts.map +1 -1
  20. package/dist/cmd/build/vite/agent-discovery.js +3 -3
  21. package/dist/cmd/build/vite/agent-discovery.js.map +1 -1
  22. package/dist/cmd/build/vite/index.d.ts +2 -1
  23. package/dist/cmd/build/vite/index.d.ts.map +1 -1
  24. package/dist/cmd/build/vite/index.js +3 -2
  25. package/dist/cmd/build/vite/index.js.map +1 -1
  26. package/dist/cmd/build/vite/metadata-generator.d.ts.map +1 -1
  27. package/dist/cmd/build/vite/metadata-generator.js +3 -5
  28. package/dist/cmd/build/vite/metadata-generator.js.map +1 -1
  29. package/dist/cmd/build/vite/registry-generator.d.ts +1 -1
  30. package/dist/cmd/build/vite/registry-generator.d.ts.map +1 -1
  31. package/dist/cmd/build/vite/registry-generator.js +126 -41
  32. package/dist/cmd/build/vite/registry-generator.js.map +1 -1
  33. package/dist/cmd/build/vite/route-discovery.d.ts +6 -0
  34. package/dist/cmd/build/vite/route-discovery.d.ts.map +1 -1
  35. package/dist/cmd/build/vite/route-discovery.js +19 -0
  36. package/dist/cmd/build/vite/route-discovery.js.map +1 -1
  37. package/dist/cmd/build/vite/vite-builder.d.ts +3 -0
  38. package/dist/cmd/build/vite/vite-builder.d.ts.map +1 -1
  39. package/dist/cmd/build/vite/vite-builder.js +10 -2
  40. package/dist/cmd/build/vite/vite-builder.js.map +1 -1
  41. package/dist/cmd/build/vite-bundler.d.ts +3 -0
  42. package/dist/cmd/build/vite-bundler.d.ts.map +1 -1
  43. package/dist/cmd/build/vite-bundler.js +14 -5
  44. package/dist/cmd/build/vite-bundler.js.map +1 -1
  45. package/dist/cmd/cloud/deploy.d.ts.map +1 -1
  46. package/dist/cmd/cloud/deploy.js +149 -10
  47. package/dist/cmd/cloud/deploy.js.map +1 -1
  48. package/dist/cmd/cloud/deployment/show.d.ts.map +1 -1
  49. package/dist/cmd/cloud/deployment/show.js +0 -1
  50. package/dist/cmd/cloud/deployment/show.js.map +1 -1
  51. package/dist/cmd/cloud/sandbox/create.d.ts.map +1 -1
  52. package/dist/cmd/cloud/sandbox/create.js +18 -0
  53. package/dist/cmd/cloud/sandbox/create.js.map +1 -1
  54. package/dist/cmd/cloud/sandbox/delete.d.ts.map +1 -1
  55. package/dist/cmd/cloud/sandbox/delete.js +2 -6
  56. package/dist/cmd/cloud/sandbox/delete.js.map +1 -1
  57. package/dist/cmd/cloud/sandbox/download.d.ts +3 -0
  58. package/dist/cmd/cloud/sandbox/download.d.ts.map +1 -0
  59. package/dist/cmd/cloud/sandbox/download.js +89 -0
  60. package/dist/cmd/cloud/sandbox/download.js.map +1 -0
  61. package/dist/cmd/cloud/sandbox/env.d.ts +3 -0
  62. package/dist/cmd/cloud/sandbox/env.d.ts.map +1 -0
  63. package/dist/cmd/cloud/sandbox/env.js +90 -0
  64. package/dist/cmd/cloud/sandbox/env.js.map +1 -0
  65. package/dist/cmd/cloud/sandbox/get.d.ts.map +1 -1
  66. package/dist/cmd/cloud/sandbox/get.js +5 -0
  67. package/dist/cmd/cloud/sandbox/get.js.map +1 -1
  68. package/dist/cmd/cloud/sandbox/index.d.ts.map +1 -1
  69. package/dist/cmd/cloud/sandbox/index.js +14 -0
  70. package/dist/cmd/cloud/sandbox/index.js.map +1 -1
  71. package/dist/cmd/cloud/sandbox/ls.d.ts +3 -0
  72. package/dist/cmd/cloud/sandbox/ls.d.ts.map +1 -0
  73. package/dist/cmd/cloud/sandbox/ls.js +119 -0
  74. package/dist/cmd/cloud/sandbox/ls.js.map +1 -0
  75. package/dist/cmd/cloud/sandbox/mkdir.d.ts +3 -0
  76. package/dist/cmd/cloud/sandbox/mkdir.d.ts.map +1 -0
  77. package/dist/cmd/cloud/sandbox/mkdir.js +59 -0
  78. package/dist/cmd/cloud/sandbox/mkdir.js.map +1 -0
  79. package/dist/cmd/cloud/sandbox/rm.d.ts +3 -0
  80. package/dist/cmd/cloud/sandbox/rm.d.ts.map +1 -0
  81. package/dist/cmd/cloud/sandbox/rm.js +45 -0
  82. package/dist/cmd/cloud/sandbox/rm.js.map +1 -0
  83. package/dist/cmd/cloud/sandbox/rmdir.d.ts +3 -0
  84. package/dist/cmd/cloud/sandbox/rmdir.d.ts.map +1 -0
  85. package/dist/cmd/cloud/sandbox/rmdir.js +59 -0
  86. package/dist/cmd/cloud/sandbox/rmdir.js.map +1 -0
  87. package/dist/cmd/cloud/sandbox/snapshot/create.d.ts.map +1 -1
  88. package/dist/cmd/cloud/sandbox/snapshot/create.js +0 -2
  89. package/dist/cmd/cloud/sandbox/snapshot/create.js.map +1 -1
  90. package/dist/cmd/cloud/sandbox/snapshot/get.d.ts.map +1 -1
  91. package/dist/cmd/cloud/sandbox/snapshot/get.js +0 -2
  92. package/dist/cmd/cloud/sandbox/snapshot/get.js.map +1 -1
  93. package/dist/cmd/cloud/sandbox/snapshot/list.d.ts.map +1 -1
  94. package/dist/cmd/cloud/sandbox/snapshot/list.js +0 -3
  95. package/dist/cmd/cloud/sandbox/snapshot/list.js.map +1 -1
  96. package/dist/cmd/cloud/sandbox/upload.d.ts +3 -0
  97. package/dist/cmd/cloud/sandbox/upload.d.ts.map +1 -0
  98. package/dist/cmd/cloud/sandbox/upload.js +77 -0
  99. package/dist/cmd/cloud/sandbox/upload.js.map +1 -0
  100. package/dist/cmd/dev/index.d.ts.map +1 -1
  101. package/dist/cmd/dev/index.js +126 -23
  102. package/dist/cmd/dev/index.js.map +1 -1
  103. package/dist/cmd/dev/sync.d.ts.map +1 -1
  104. package/dist/cmd/dev/sync.js +8 -14
  105. package/dist/cmd/dev/sync.js.map +1 -1
  106. package/dist/cmd/git/account/add.d.ts +17 -0
  107. package/dist/cmd/git/account/add.d.ts.map +1 -0
  108. package/dist/cmd/git/account/add.js +244 -0
  109. package/dist/cmd/git/account/add.js.map +1 -0
  110. package/dist/cmd/git/account/index.d.ts +3 -0
  111. package/dist/cmd/git/account/index.d.ts.map +1 -0
  112. package/dist/cmd/git/account/index.js +11 -0
  113. package/dist/cmd/git/account/index.js.map +1 -0
  114. package/dist/cmd/git/account/list.d.ts +2 -0
  115. package/dist/cmd/git/account/list.d.ts.map +1 -0
  116. package/dist/cmd/git/account/list.js +111 -0
  117. package/dist/cmd/git/account/list.js.map +1 -0
  118. package/dist/cmd/git/account/remove.d.ts +2 -0
  119. package/dist/cmd/git/account/remove.d.ts.map +1 -0
  120. package/dist/cmd/git/account/remove.js +171 -0
  121. package/dist/cmd/git/account/remove.js.map +1 -0
  122. package/dist/cmd/git/index.d.ts +3 -0
  123. package/dist/cmd/git/index.d.ts.map +1 -0
  124. package/dist/cmd/git/index.js +19 -0
  125. package/dist/cmd/git/index.js.map +1 -0
  126. package/dist/cmd/git/link.d.ts +32 -0
  127. package/dist/cmd/git/link.d.ts.map +1 -0
  128. package/dist/cmd/git/link.js +357 -0
  129. package/dist/cmd/git/link.js.map +1 -0
  130. package/dist/cmd/git/list.d.ts +2 -0
  131. package/dist/cmd/git/list.d.ts.map +1 -0
  132. package/dist/cmd/git/list.js +137 -0
  133. package/dist/cmd/git/list.js.map +1 -0
  134. package/dist/cmd/git/status.d.ts +2 -0
  135. package/dist/cmd/git/status.d.ts.map +1 -0
  136. package/dist/cmd/git/status.js +119 -0
  137. package/dist/cmd/git/status.js.map +1 -0
  138. package/dist/cmd/git/unlink.d.ts +2 -0
  139. package/dist/cmd/git/unlink.d.ts.map +1 -0
  140. package/dist/cmd/git/unlink.js +98 -0
  141. package/dist/cmd/git/unlink.js.map +1 -0
  142. package/dist/cmd/index.d.ts.map +1 -1
  143. package/dist/cmd/index.js +2 -0
  144. package/dist/cmd/index.js.map +1 -1
  145. package/dist/cmd/integration/api.d.ts +61 -0
  146. package/dist/cmd/integration/api.d.ts.map +1 -0
  147. package/dist/cmd/integration/api.js +176 -0
  148. package/dist/cmd/integration/api.js.map +1 -0
  149. package/dist/cmd/integration/github/connect.d.ts +2 -0
  150. package/dist/cmd/integration/github/connect.d.ts.map +1 -0
  151. package/dist/cmd/integration/github/connect.js +197 -0
  152. package/dist/cmd/integration/github/connect.js.map +1 -0
  153. package/dist/cmd/integration/github/disconnect.d.ts +2 -0
  154. package/dist/cmd/integration/github/disconnect.d.ts.map +1 -0
  155. package/dist/cmd/integration/github/disconnect.js +121 -0
  156. package/dist/cmd/integration/github/disconnect.js.map +1 -0
  157. package/dist/cmd/integration/github/index.d.ts +2 -0
  158. package/dist/cmd/integration/github/index.d.ts.map +1 -0
  159. package/dist/cmd/integration/github/index.js +21 -0
  160. package/dist/cmd/integration/github/index.js.map +1 -0
  161. package/dist/cmd/integration/index.d.ts +2 -0
  162. package/dist/cmd/integration/index.d.ts.map +1 -0
  163. package/dist/cmd/integration/index.js +16 -0
  164. package/dist/cmd/integration/index.js.map +1 -0
  165. package/dist/cmd/project/auth/generate.d.ts +5 -0
  166. package/dist/cmd/project/auth/generate.d.ts.map +1 -0
  167. package/dist/cmd/project/auth/generate.js +102 -0
  168. package/dist/cmd/project/auth/generate.js.map +1 -0
  169. package/dist/cmd/project/auth/index.d.ts +2 -0
  170. package/dist/cmd/project/auth/index.d.ts.map +1 -0
  171. package/dist/cmd/project/auth/index.js +21 -0
  172. package/dist/cmd/project/auth/index.js.map +1 -0
  173. package/dist/cmd/project/auth/init.d.ts +2 -0
  174. package/dist/cmd/project/auth/init.d.ts.map +1 -0
  175. package/dist/cmd/project/auth/init.js +220 -0
  176. package/dist/cmd/project/auth/init.js.map +1 -0
  177. package/dist/cmd/project/auth/shared.d.ts +88 -0
  178. package/dist/cmd/project/auth/shared.d.ts.map +1 -0
  179. package/dist/cmd/project/auth/shared.js +435 -0
  180. package/dist/cmd/project/auth/shared.js.map +1 -0
  181. package/dist/cmd/project/index.d.ts.map +1 -1
  182. package/dist/cmd/project/index.js +9 -1
  183. package/dist/cmd/project/index.js.map +1 -1
  184. package/dist/cmd/project/template-flow.d.ts.map +1 -1
  185. package/dist/cmd/project/template-flow.js +106 -0
  186. package/dist/cmd/project/template-flow.js.map +1 -1
  187. package/dist/config.d.ts +2 -0
  188. package/dist/config.d.ts.map +1 -1
  189. package/dist/config.js +24 -0
  190. package/dist/config.js.map +1 -1
  191. package/dist/errors.d.ts +2 -1
  192. package/dist/errors.d.ts.map +1 -1
  193. package/dist/errors.js +5 -0
  194. package/dist/errors.js.map +1 -1
  195. package/dist/types.d.ts +3 -4
  196. package/dist/types.d.ts.map +1 -1
  197. package/dist/types.js +5 -2
  198. package/dist/types.js.map +1 -1
  199. package/package.json +6 -5
  200. package/src/build-report.ts +457 -0
  201. package/src/cli.ts +20 -4
  202. package/src/cmd/build/entry-generator.ts +3 -1
  203. package/src/cmd/build/index.ts +51 -1
  204. package/src/cmd/build/typecheck.ts +19 -1
  205. package/src/cmd/build/vite/agent-discovery.ts +4 -4
  206. package/src/cmd/build/vite/index.ts +5 -2
  207. package/src/cmd/build/vite/metadata-generator.ts +5 -7
  208. package/src/cmd/build/vite/registry-generator.ts +136 -43
  209. package/src/cmd/build/vite/route-discovery.ts +20 -0
  210. package/src/cmd/build/vite/vite-builder.ts +13 -2
  211. package/src/cmd/build/vite-bundler.ts +17 -4
  212. package/src/cmd/cloud/deploy.ts +183 -12
  213. package/src/cmd/cloud/deployment/show.ts +0 -1
  214. package/src/cmd/cloud/sandbox/create.ts +22 -0
  215. package/src/cmd/cloud/sandbox/delete.ts +2 -6
  216. package/src/cmd/cloud/sandbox/download.ts +96 -0
  217. package/src/cmd/cloud/sandbox/env.ts +104 -0
  218. package/src/cmd/cloud/sandbox/get.ts +5 -0
  219. package/src/cmd/cloud/sandbox/index.ts +14 -0
  220. package/src/cmd/cloud/sandbox/ls.ts +126 -0
  221. package/src/cmd/cloud/sandbox/mkdir.ts +65 -0
  222. package/src/cmd/cloud/sandbox/rm.ts +51 -0
  223. package/src/cmd/cloud/sandbox/rmdir.ts +65 -0
  224. package/src/cmd/cloud/sandbox/snapshot/create.ts +0 -2
  225. package/src/cmd/cloud/sandbox/snapshot/get.ts +0 -2
  226. package/src/cmd/cloud/sandbox/snapshot/list.ts +0 -3
  227. package/src/cmd/cloud/sandbox/upload.ts +83 -0
  228. package/src/cmd/dev/index.ts +147 -33
  229. package/src/cmd/dev/sync.ts +26 -30
  230. package/src/cmd/git/account/add.ts +317 -0
  231. package/src/cmd/git/account/index.ts +12 -0
  232. package/src/cmd/git/account/list.ts +139 -0
  233. package/src/cmd/git/account/remove.ts +212 -0
  234. package/src/cmd/git/index.ts +20 -0
  235. package/src/cmd/git/link.ts +468 -0
  236. package/src/cmd/git/list.ts +161 -0
  237. package/src/cmd/git/status.ts +144 -0
  238. package/src/cmd/git/unlink.ts +117 -0
  239. package/src/cmd/index.ts +2 -0
  240. package/src/cmd/integration/api.ts +379 -0
  241. package/src/cmd/integration/github/connect.ts +242 -0
  242. package/src/cmd/integration/github/disconnect.ts +149 -0
  243. package/src/cmd/integration/github/index.ts +21 -0
  244. package/src/cmd/integration/index.ts +16 -0
  245. package/src/cmd/project/auth/generate.ts +116 -0
  246. package/src/cmd/project/auth/index.ts +21 -0
  247. package/src/cmd/project/auth/init.ts +263 -0
  248. package/src/cmd/project/auth/shared.ts +534 -0
  249. package/src/cmd/project/index.ts +9 -1
  250. package/src/cmd/project/template-flow.ts +125 -0
  251. package/src/config.ts +34 -0
  252. package/src/errors.ts +7 -0
  253. package/src/types.ts +5 -2
@@ -371,6 +371,7 @@ export const command = createCommand({
371
371
  // Vite stays running and handles frontend changes via HMR
372
372
  let shouldRestart = false;
373
373
  let gravityProcess: ProcessLike | null = null;
374
+ let gravityHeartbeatInterval: ReturnType<typeof setInterval> | null = null;
374
375
  let stdinListenerRegistered = false; // Track if stdin listener is already registered
375
376
 
376
377
  const restartServer = () => {
@@ -395,6 +396,8 @@ export const command = createCommand({
395
396
  let cleaningUp = false;
396
397
  // Track if shutdown was requested (SIGINT/SIGTERM) to break the main loop
397
398
  let shutdownRequested = false;
399
+ // Store stdin data handler reference for cleanup
400
+ let stdinDataHandler: ((data: Buffer | string) => void) | null = null;
398
401
 
399
402
  /**
400
403
  * Centralized cleanup function for all resources.
@@ -425,6 +428,12 @@ export const command = createCommand({
425
428
  logger.debug('Error stopping Bun server during cleanup: %s', err);
426
429
  }
427
430
 
431
+ // Stop gravity heartbeat interval
432
+ if (gravityHeartbeatInterval) {
433
+ clearInterval(gravityHeartbeatInterval);
434
+ gravityHeartbeatInterval = null;
435
+ }
436
+
428
437
  // Kill gravity client with SIGTERM first, then SIGKILL as fallback
429
438
  if (gravityProcess) {
430
439
  logger.debug('Killing gravity process...');
@@ -479,6 +488,21 @@ export const command = createCommand({
479
488
  if (!exitAfter) {
480
489
  cleaningUp = false;
481
490
  } else {
491
+ // Clean up stdin keyboard handler right before exiting
492
+ // This must happen AFTER all async cleanup to keep event loop alive
493
+ if (stdinListenerRegistered && process.stdin.isTTY) {
494
+ try {
495
+ if (stdinDataHandler) {
496
+ process.stdin.removeListener('data', stdinDataHandler);
497
+ stdinDataHandler = null;
498
+ }
499
+ process.stdin.setRawMode(false);
500
+ process.stdin.pause();
501
+ process.stdin.unref();
502
+ } catch {
503
+ // Ignore errors during final cleanup
504
+ }
505
+ }
482
506
  logger.debug('Exiting with code %d', exitCode);
483
507
  originalExit(exitCode);
484
508
  }
@@ -497,6 +521,12 @@ export const command = createCommand({
497
521
  logger.debug('Error stopping Bun server for restart: %s', err);
498
522
  }
499
523
 
524
+ // Stop gravity heartbeat interval
525
+ if (gravityHeartbeatInterval) {
526
+ clearInterval(gravityHeartbeatInterval);
527
+ gravityHeartbeatInterval = null;
528
+ }
529
+
500
530
  // Kill gravity client
501
531
  if (gravityProcess) {
502
532
  try {
@@ -515,23 +545,37 @@ export const command = createCommand({
515
545
 
516
546
  // SIGINT/SIGTERM: coordinate shutdown between bundle and dev resources
517
547
  let signalHandlersRegistered = false;
548
+ let exitingFromSignal = false;
518
549
  if (!signalHandlersRegistered) {
519
550
  signalHandlersRegistered = true;
520
551
 
521
- const safeExit = async (code: number, reason?: string) => {
552
+ const safeExit = (code: number, reason?: string) => {
553
+ // Prevent multiple signal handlers from racing
554
+ if (exitingFromSignal) return;
555
+ exitingFromSignal = true;
556
+
522
557
  if (reason) {
523
558
  logger.debug('DevMode terminating (%d) due to: %s', code, reason);
524
559
  }
525
560
  shutdownRequested = true;
526
- await cleanup(true, code);
561
+ // Run cleanup and ensure we wait for it to complete before exiting
562
+ cleanup(true, code).catch((err) => {
563
+ logger.debug('Cleanup error: %s', err);
564
+ originalExit(1);
565
+ });
527
566
  };
528
567
 
529
568
  process.on('SIGINT', () => {
530
- void safeExit(0, 'SIGINT');
569
+ safeExit(0, 'SIGINT');
531
570
  });
532
571
 
533
572
  process.on('SIGTERM', () => {
534
- void safeExit(0, 'SIGTERM');
573
+ safeExit(0, 'SIGTERM');
574
+ });
575
+
576
+ // Handle SIGHUP (terminal closed) - same as SIGINT
577
+ process.on('SIGHUP', () => {
578
+ safeExit(0, 'SIGHUP');
535
579
  });
536
580
 
537
581
  // Handle uncaught exceptions - clean up and exit rather than limping on
@@ -553,6 +597,20 @@ export const command = createCommand({
553
597
 
554
598
  // Ensure resources are always cleaned up on exit (synchronous fallback)
555
599
  process.on('exit', () => {
600
+ // Clean up stdin keyboard handler
601
+ if (stdinListenerRegistered && process.stdin.isTTY) {
602
+ try {
603
+ if (stdinDataHandler) {
604
+ process.stdin.removeListener('data', stdinDataHandler);
605
+ }
606
+ process.stdin.setRawMode(false);
607
+ process.stdin.pause();
608
+ process.stdin.unref();
609
+ } catch {
610
+ // Ignore errors during exit cleanup
611
+ }
612
+ }
613
+
556
614
  // Kill gravity client with SIGKILL for immediate termination
557
615
  if (gravityProcess && gravityProcess.exitCode === null) {
558
616
  try {
@@ -622,7 +680,34 @@ export const command = createCommand({
622
680
  );
623
681
  }
624
682
 
625
- // Step 2: Generate entry file with workbench config
683
+ // Step 2: Discover agents and routes for registry generation
684
+ const srcDir = join(rootDir, 'src');
685
+ const { discoverAgents } = await import('../build/vite/agent-discovery');
686
+ const { discoverRoutes } = await import('../build/vite/route-discovery');
687
+ const { generateAgentRegistry, generateRouteRegistry } = await import(
688
+ '../build/vite/registry-generator'
689
+ );
690
+
691
+ const agentMetadata = await discoverAgents(
692
+ srcDir,
693
+ project?.projectId ?? '',
694
+ deploymentId,
695
+ logger
696
+ );
697
+ const { routes, routeInfoList } = await discoverRoutes(
698
+ srcDir,
699
+ project?.projectId ?? '',
700
+ deploymentId,
701
+ logger
702
+ );
703
+
704
+ // Generate agent and route registries for type augmentation
705
+ // (TypeScript needs these files to exist for proper type inference)
706
+ generateAgentRegistry(srcDir, agentMetadata);
707
+ generateRouteRegistry(srcDir, routeInfoList);
708
+ logger.debug('Agent and route registries generated for dev mode');
709
+
710
+ // Step 3: Generate entry file with workbench config
626
711
  // Note: vitePort is NOT passed here - the app reads process.env.VITE_PORT at runtime
627
712
  const { generateEntryFile } = await import('../build/entry-generator');
628
713
  await generateEntryFile({
@@ -634,7 +719,7 @@ export const command = createCommand({
634
719
  workbench: workbenchConfigData.enabled ? workbenchConfigData : undefined,
635
720
  });
636
721
 
637
- // Step 3: Bundle the app with LLM patches (dev mode = no minification)
722
+ // Step 4: Bundle the app with LLM patches (dev mode = no minification)
638
723
  // This produces .agentuity/app.js with AI Gateway routing patches applied
639
724
  const { installExternalsAndBuild } = await import(
640
725
  '../build/vite/server-bundler'
@@ -646,14 +731,11 @@ export const command = createCommand({
646
731
  });
647
732
 
648
733
  // Generate metadata file (needed for eval ID lookup at runtime)
649
- const { discoverAgents } = await import('../build/vite/agent-discovery');
650
- const { discoverRoutes } = await import('../build/vite/route-discovery');
734
+ // Reuse agentMetadata and routes from Step 2
651
735
  const { generateMetadata, writeMetadataFile } = await import(
652
736
  '../build/vite/metadata-generator'
653
737
  );
654
738
 
655
- const srcDir = join(rootDir, 'src');
656
-
657
739
  const promises: Promise<void>[] = [];
658
740
 
659
741
  // Generate/update prompt files (non-blocking)
@@ -664,25 +746,13 @@ export const command = createCommand({
664
746
  logger.warn('Failed to generate prompt files: %s', err.message)
665
747
  )
666
748
  );
667
- const agents = await discoverAgents(
668
- srcDir,
669
- project?.projectId ?? '',
670
- deploymentId,
671
- logger
672
- );
673
- const { routes } = await discoverRoutes(
674
- srcDir,
675
- project?.projectId ?? '',
676
- deploymentId,
677
- logger
678
- );
679
749
 
680
750
  const metadata = await generateMetadata({
681
751
  rootDir,
682
752
  projectId: project?.projectId ?? '',
683
753
  orgId: project?.orgId ?? '',
684
754
  deploymentId,
685
- agents,
755
+ agents: agentMetadata,
686
756
  routes,
687
757
  dev: true,
688
758
  logger,
@@ -786,6 +856,7 @@ export const command = createCommand({
786
856
  process.env.AGENTUITY_STREAM_URL = serviceUrls.stream;
787
857
  process.env.AGENTUITY_CLOUD_ORG_ID = project.orgId;
788
858
  process.env.AGENTUITY_CLOUD_PROJECT_ID = project.projectId;
859
+ process.env.AGENTUITY_CLOUD_DEPLOYMENT_ID = deploymentId;
789
860
  }
790
861
 
791
862
  // Set Vite port for asset proxying in bundled app
@@ -862,6 +933,7 @@ export const command = createCommand({
862
933
  project.projectId,
863
934
  '--token',
864
935
  process.env.AGENTUITY_SDK_KEY!, // set above
936
+ '--health-check',
865
937
  ],
866
938
  {
867
939
  cwd: rootDir,
@@ -881,13 +953,46 @@ export const command = createCommand({
881
953
  });
882
954
  }
883
955
 
884
- // Log gravity output
956
+ // Log gravity output and detect heartbeat port
885
957
  (async () => {
886
958
  try {
887
959
  if (gravityProcess?.stdout) {
888
960
  for await (const chunk of gravityProcess.stdout) {
889
961
  const text = new TextDecoder().decode(chunk);
890
- logger.debug('[gravity] %s', text.trim());
962
+ const trimmed = text.trim();
963
+
964
+ // Check for heartbeat port announcement
965
+ const match = trimmed.match(/^HEARTBEAT_PORT=(\d+)$/m);
966
+ if (match) {
967
+ const heartbeatPort = parseInt(match[1], 10);
968
+ logger.debug('Gravity heartbeat port detected: %d', heartbeatPort);
969
+
970
+ // Start sending heartbeats every 5 seconds
971
+ if (!gravityHeartbeatInterval) {
972
+ const sendHeartbeat = async () => {
973
+ try {
974
+ await fetch(
975
+ `http://127.0.0.1:${heartbeatPort}/heartbeat`,
976
+ {
977
+ method: 'POST',
978
+ signal: AbortSignal.timeout(2000),
979
+ }
980
+ );
981
+ logger.trace('Gravity heartbeat sent');
982
+ } catch (err) {
983
+ logger.trace('Gravity heartbeat failed: %s', err);
984
+ }
985
+ };
986
+
987
+ // Send initial heartbeat immediately
988
+ sendHeartbeat();
989
+
990
+ // Then send every 5 seconds
991
+ gravityHeartbeatInterval = setInterval(sendHeartbeat, 5000);
992
+ }
993
+ } else if (trimmed) {
994
+ logger.debug('[gravity] %s', trimmed);
995
+ }
891
996
  }
892
997
  }
893
998
  } catch (err) {
@@ -930,12 +1035,23 @@ export const command = createCommand({
930
1035
  console.log(tui.muted(' q') + ' - quit\n');
931
1036
  };
932
1037
 
933
- process.stdin.on('data', (data) => {
1038
+ // Store handler reference for cleanup
1039
+ stdinDataHandler = (data) => {
934
1040
  const key = data.toString();
935
1041
 
936
- // Handle Ctrl+C - send SIGINT to trigger graceful shutdown
937
- if (key === '\u0003') {
938
- process.kill(process.pid, 'SIGINT');
1042
+ // Handle Ctrl+C or q - trigger graceful shutdown
1043
+ if (key === '\u0003' || key === 'q') {
1044
+ // Remove stdin listener immediately to prevent re-entrancy
1045
+ if (stdinDataHandler) {
1046
+ process.stdin.removeListener('data', stdinDataHandler);
1047
+ stdinDataHandler = null;
1048
+ }
1049
+ // Set shutdown flag and trigger cleanup directly
1050
+ shutdownRequested = true;
1051
+ cleanup(true, 0).catch((err) => {
1052
+ logger.debug('Cleanup error: %s', err);
1053
+ originalExit(1);
1054
+ });
939
1055
  return;
940
1056
  }
941
1057
 
@@ -952,14 +1068,12 @@ export const command = createCommand({
952
1068
  centerTitle: false,
953
1069
  });
954
1070
  break;
955
- case 'q':
956
- void cleanup(true, 0);
957
- break;
958
1071
  default:
959
1072
  process.stdout.write(data);
960
1073
  break;
961
1074
  }
962
- });
1075
+ };
1076
+ process.stdin.on('data', stdinDataHandler);
963
1077
  }
964
1078
 
965
1079
  showWelcome();
@@ -15,7 +15,7 @@ interface AgentSyncPayload {
15
15
  interface EvalSyncPayload {
16
16
  id: string;
17
17
  name: string;
18
- evalId: string;
18
+ identifier: string;
19
19
  description?: string;
20
20
  version: string;
21
21
  filename: string;
@@ -100,7 +100,7 @@ function getEvalsToSync(
100
100
 
101
101
  evalsToCreate.push({
102
102
  ...evalItem,
103
- evalId: evalItem.evalId,
103
+ identifier: evalItem.identifier,
104
104
  projectId,
105
105
  agentIdentifier: agent.agentId,
106
106
  });
@@ -133,18 +133,28 @@ class DevmodeSyncService implements IDevmodeSyncService {
133
133
  projectId: string,
134
134
  deploymentId: string
135
135
  ): Promise<void> {
136
+ this.logger.debug(
137
+ '[CLI SYNC] sync() called with projectId=%s, deploymentId=%s',
138
+ projectId,
139
+ deploymentId
140
+ );
141
+ this.logger.debug(
142
+ '[CLI SYNC] currentMetadata has %d agents',
143
+ currentMetadata.agents?.length ?? 0
144
+ );
145
+
136
146
  // Build previous agent IDs set
137
147
  const previousAgentIds = new Set<string>();
138
148
  if (previousMetadata) {
139
149
  this.logger.debug(
140
- 'Previous metadata found with %d agent(s)',
150
+ '[CLI SYNC] Previous metadata found with %d agent(s)',
141
151
  previousMetadata.agents?.length ?? 0
142
152
  );
143
153
  for (const agent of previousMetadata.agents || []) {
144
154
  previousAgentIds.add(agent.id);
145
155
  }
146
156
  } else {
147
- this.logger.debug('No previous metadata, all agents will be treated as new');
157
+ this.logger.debug('[CLI SYNC] No previous metadata, all agents will be treated as new');
148
158
  }
149
159
 
150
160
  // Build previous eval IDs set
@@ -178,9 +188,10 @@ class DevmodeSyncService implements IDevmodeSyncService {
178
188
  );
179
189
  for (const evalItem of agent.evals) {
180
190
  this.logger.debug(
181
- '[CLI EVAL SYNC] - %s (evalId: %s)',
191
+ '[CLI EVAL SYNC] - %s (id: %s, identifier: %s)',
182
192
  evalItem.name,
183
- evalItem.evalId
193
+ evalItem.id,
194
+ evalItem.identifier
184
195
  );
185
196
  }
186
197
  }
@@ -208,13 +219,11 @@ class DevmodeSyncService implements IDevmodeSyncService {
208
219
  agentsToDelete.length
209
220
  );
210
221
  }
211
- if (evalsToCreate.length > 0 || evalsToDelete.length > 0) {
212
- this.logger.debug(
213
- 'Bulk syncing %d eval(s) to create, %d eval(s) to delete',
214
- evalsToCreate.length,
215
- evalsToDelete.length
216
- );
217
- }
222
+ this.logger.debug(
223
+ '[CLI EVAL SYNC] Evals to sync: %d to create, %d to delete',
224
+ evalsToCreate.length,
225
+ evalsToDelete.length
226
+ );
218
227
 
219
228
  // Sync both in parallel
220
229
  try {
@@ -273,14 +282,7 @@ class DevmodeSyncService implements IDevmodeSyncService {
273
282
  evalsToDelete: string[],
274
283
  deploymentId: string
275
284
  ): Promise<void> {
276
- this.logger.debug(
277
- '[CLI EVAL SYNC] syncEvals called: %d to create, %d to delete',
278
- evals.length,
279
- evalsToDelete.length
280
- );
281
-
282
285
  if (evals.length === 0 && evalsToDelete.length === 0) {
283
- this.logger.debug('[CLI EVAL SYNC] No evals to sync, skipping');
284
286
  return;
285
287
  }
286
288
 
@@ -290,15 +292,10 @@ class DevmodeSyncService implements IDevmodeSyncService {
290
292
  delete: evalsToDelete,
291
293
  };
292
294
 
293
- this.logger.debug('[CLI EVAL SYNC] Sending payload to POST /cli/devmode/eval:');
294
- for (const evalItem of evals) {
295
- this.logger.debug(
296
- '[CLI EVAL SYNC] - %s (id: %s, evalId: %s)',
297
- evalItem.name,
298
- evalItem.id,
299
- evalItem.evalId
300
- );
301
- }
295
+ this.logger.debug(
296
+ '[CLI EVAL SYNC] Sending payload to POST /cli/devmode/eval: %s',
297
+ JSON.stringify(payload, null, 2)
298
+ );
302
299
 
303
300
  try {
304
301
  await this.apiClient.post(
@@ -306,7 +303,6 @@ class DevmodeSyncService implements IDevmodeSyncService {
306
303
  payload,
307
304
  z.object({ success: z.boolean() })
308
305
  );
309
- this.logger.debug('[CLI EVAL SYNC] Sync successful');
310
306
  } catch (error) {
311
307
  this.logger.error('[CLI EVAL SYNC] Sync failed: %s', error);
312
308
  throw error;