@shepai/cli 1.4.0 → 1.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.
Files changed (211) hide show
  1. package/dist/src/infrastructure/services/port.service.d.ts +20 -0
  2. package/dist/src/infrastructure/services/port.service.d.ts.map +1 -0
  3. package/dist/src/infrastructure/services/port.service.js +47 -0
  4. package/dist/src/infrastructure/services/web-server.service.d.ts +43 -0
  5. package/dist/src/infrastructure/services/web-server.service.d.ts.map +1 -0
  6. package/dist/src/infrastructure/services/web-server.service.js +95 -0
  7. package/dist/src/presentation/cli/commands/ui.command.d.ts +22 -0
  8. package/dist/src/presentation/cli/commands/ui.command.d.ts.map +1 -0
  9. package/dist/src/presentation/cli/commands/ui.command.js +74 -0
  10. package/dist/src/presentation/cli/index.d.ts +1 -0
  11. package/dist/src/presentation/cli/index.d.ts.map +1 -1
  12. package/dist/src/presentation/cli/index.js +3 -0
  13. package/dist/tsconfig.build.tsbuildinfo +1 -1
  14. package/package.json +4 -2
  15. package/web/.next/BUILD_ID +1 -0
  16. package/web/.next/app-path-routes-manifest.json +6 -0
  17. package/web/.next/build/chunks/[root-of-the-server]__0f2e5b60._.js +207 -0
  18. package/web/.next/build/chunks/[root-of-the-server]__0f2e5b60._.js.map +8 -0
  19. package/web/.next/build/chunks/[root-of-the-server]__52e8dcc7._.js +500 -0
  20. package/web/.next/build/chunks/[root-of-the-server]__52e8dcc7._.js.map +11 -0
  21. package/web/.next/build/chunks/[turbopack-node]_transforms_postcss_ts_4ffac355._.js +13 -0
  22. package/web/.next/build/chunks/[turbopack-node]_transforms_postcss_ts_4ffac355._.js.map +5 -0
  23. package/web/.next/build/chunks/[turbopack]_runtime.js +795 -0
  24. package/web/.next/build/chunks/[turbopack]_runtime.js.map +10 -0
  25. package/web/.next/build/chunks/node_modules__pnpm_806d01c0._.js +6758 -0
  26. package/web/.next/build/chunks/node_modules__pnpm_806d01c0._.js.map +47 -0
  27. package/web/.next/build/package.json +1 -0
  28. package/web/.next/build/postcss.js +6 -0
  29. package/web/.next/build/postcss.js.map +5 -0
  30. package/web/.next/build-manifest.json +20 -0
  31. package/web/.next/cache/.previewinfo +1 -0
  32. package/web/.next/cache/.rscinfo +1 -0
  33. package/web/.next/cache/.tsbuildinfo +1 -0
  34. package/web/.next/cache/config.json +7 -0
  35. package/web/.next/diagnostics/build-diagnostics.json +6 -0
  36. package/web/.next/diagnostics/framework.json +1 -0
  37. package/web/.next/export-marker.json +6 -0
  38. package/web/.next/fallback-build-manifest.json +12 -0
  39. package/web/.next/images-manifest.json +67 -0
  40. package/web/.next/next-minimal-server.js.nft.json +1 -0
  41. package/web/.next/next-server.js.nft.json +1 -0
  42. package/web/.next/package.json +1 -0
  43. package/web/.next/prerender-manifest.json +109 -0
  44. package/web/.next/required-server-files.js +320 -0
  45. package/web/.next/required-server-files.json +320 -0
  46. package/web/.next/routes-manifest.json +68 -0
  47. package/web/.next/server/app/_global-error/page/app-paths-manifest.json +3 -0
  48. package/web/.next/server/app/_global-error/page/build-manifest.json +17 -0
  49. package/web/.next/server/app/_global-error/page/next-font-manifest.json +6 -0
  50. package/web/.next/server/app/_global-error/page/react-loadable-manifest.json +1 -0
  51. package/web/.next/server/app/_global-error/page/server-reference-manifest.json +4 -0
  52. package/web/.next/server/app/_global-error/page.js +10 -0
  53. package/web/.next/server/app/_global-error/page.js.map +5 -0
  54. package/web/.next/server/app/_global-error/page.js.nft.json +1 -0
  55. package/web/.next/server/app/_global-error/page_client-reference-manifest.js +2 -0
  56. package/web/.next/server/app/_global-error.html +2 -0
  57. package/web/.next/server/app/_global-error.meta +15 -0
  58. package/web/.next/server/app/_global-error.rsc +12 -0
  59. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +5 -0
  60. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +12 -0
  61. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +5 -0
  62. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +4 -0
  63. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -0
  64. package/web/.next/server/app/_not-found/page/app-paths-manifest.json +3 -0
  65. package/web/.next/server/app/_not-found/page/build-manifest.json +17 -0
  66. package/web/.next/server/app/_not-found/page/next-font-manifest.json +6 -0
  67. package/web/.next/server/app/_not-found/page/react-loadable-manifest.json +1 -0
  68. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +4 -0
  69. package/web/.next/server/app/_not-found/page.js +13 -0
  70. package/web/.next/server/app/_not-found/page.js.map +5 -0
  71. package/web/.next/server/app/_not-found/page.js.nft.json +1 -0
  72. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +2 -0
  73. package/web/.next/server/app/_not-found.html +11 -0
  74. package/web/.next/server/app/_not-found.meta +16 -0
  75. package/web/.next/server/app/_not-found.rsc +13 -0
  76. package/web/.next/server/app/_not-found.segments/_full.segment.rsc +13 -0
  77. package/web/.next/server/app/_not-found.segments/_head.segment.rsc +5 -0
  78. package/web/.next/server/app/_not-found.segments/_index.segment.rsc +5 -0
  79. package/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +5 -0
  80. package/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +4 -0
  81. package/web/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -0
  82. package/web/.next/server/app/index.html +11 -0
  83. package/web/.next/server/app/index.meta +14 -0
  84. package/web/.next/server/app/index.rsc +14 -0
  85. package/web/.next/server/app/index.segments/__PAGE__.segment.rsc +6 -0
  86. package/web/.next/server/app/index.segments/_full.segment.rsc +14 -0
  87. package/web/.next/server/app/index.segments/_head.segment.rsc +5 -0
  88. package/web/.next/server/app/index.segments/_index.segment.rsc +5 -0
  89. package/web/.next/server/app/index.segments/_tree.segment.rsc +2 -0
  90. package/web/.next/server/app/page/app-paths-manifest.json +3 -0
  91. package/web/.next/server/app/page/build-manifest.json +17 -0
  92. package/web/.next/server/app/page/next-font-manifest.json +6 -0
  93. package/web/.next/server/app/page/react-loadable-manifest.json +1 -0
  94. package/web/.next/server/app/page/server-reference-manifest.json +4 -0
  95. package/web/.next/server/app/page.js +16 -0
  96. package/web/.next/server/app/page.js.map +5 -0
  97. package/web/.next/server/app/page.js.nft.json +1 -0
  98. package/web/.next/server/app/page_client-reference-manifest.js +2 -0
  99. package/web/.next/server/app/version/page/app-paths-manifest.json +3 -0
  100. package/web/.next/server/app/version/page/build-manifest.json +17 -0
  101. package/web/.next/server/app/version/page/next-font-manifest.json +6 -0
  102. package/web/.next/server/app/version/page/react-loadable-manifest.json +1 -0
  103. package/web/.next/server/app/version/page/server-reference-manifest.json +4 -0
  104. package/web/.next/server/app/version/page.js +15 -0
  105. package/web/.next/server/app/version/page.js.map +5 -0
  106. package/web/.next/server/app/version/page.js.nft.json +1 -0
  107. package/web/.next/server/app/version/page_client-reference-manifest.js +2 -0
  108. package/web/.next/server/app/version.html +11 -0
  109. package/web/.next/server/app/version.meta +15 -0
  110. package/web/.next/server/app/version.rsc +17 -0
  111. package/web/.next/server/app/version.segments/_full.segment.rsc +17 -0
  112. package/web/.next/server/app/version.segments/_head.segment.rsc +5 -0
  113. package/web/.next/server/app/version.segments/_index.segment.rsc +5 -0
  114. package/web/.next/server/app/version.segments/_tree.segment.rsc +2 -0
  115. package/web/.next/server/app/version.segments/version/__PAGE__.segment.rsc +9 -0
  116. package/web/.next/server/app/version.segments/version.segment.rsc +4 -0
  117. package/web/.next/server/app-paths-manifest.json +6 -0
  118. package/web/.next/server/chunks/ssr/403f9_next_dist_2ff794b1._.js +6 -0
  119. package/web/.next/server/chunks/ssr/403f9_next_dist_2ff794b1._.js.map +1 -0
  120. package/web/.next/server/chunks/ssr/403f9_next_dist_6c821c12._.js +4 -0
  121. package/web/.next/server/chunks/ssr/403f9_next_dist_6c821c12._.js.map +1 -0
  122. package/web/.next/server/chunks/ssr/403f9_next_dist_client_components_44deecdf._.js +3 -0
  123. package/web/.next/server/chunks/ssr/403f9_next_dist_client_components_44deecdf._.js.map +1 -0
  124. package/web/.next/server/chunks/ssr/403f9_next_dist_client_components_builtin_global-error_5fefc4d7.js +3 -0
  125. package/web/.next/server/chunks/ssr/403f9_next_dist_client_components_builtin_global-error_5fefc4d7.js.map +1 -0
  126. package/web/.next/server/chunks/ssr/403f9_next_dist_client_components_builtin_unauthorized_a2906ebd.js +3 -0
  127. package/web/.next/server/chunks/ssr/403f9_next_dist_client_components_builtin_unauthorized_a2906ebd.js.map +1 -0
  128. package/web/.next/server/chunks/ssr/403f9_next_dist_esm_build_templates_app-page_dbf21e04.js +4 -0
  129. package/web/.next/server/chunks/ssr/403f9_next_dist_esm_build_templates_app-page_dbf21e04.js.map +1 -0
  130. package/web/.next/server/chunks/ssr/[root-of-the-server]__01b8cb62._.js +3 -0
  131. package/web/.next/server/chunks/ssr/[root-of-the-server]__01b8cb62._.js.map +1 -0
  132. package/web/.next/server/chunks/ssr/[root-of-the-server]__205a2636._.js +3 -0
  133. package/web/.next/server/chunks/ssr/[root-of-the-server]__205a2636._.js.map +1 -0
  134. package/web/.next/server/chunks/ssr/[root-of-the-server]__5aff3b12._.js +3 -0
  135. package/web/.next/server/chunks/ssr/[root-of-the-server]__5aff3b12._.js.map +1 -0
  136. package/web/.next/server/chunks/ssr/[root-of-the-server]__7b98fb96._.js +3 -0
  137. package/web/.next/server/chunks/ssr/[root-of-the-server]__7b98fb96._.js.map +1 -0
  138. package/web/.next/server/chunks/ssr/[root-of-the-server]__8297ff30._.js +3 -0
  139. package/web/.next/server/chunks/ssr/[root-of-the-server]__8297ff30._.js.map +1 -0
  140. package/web/.next/server/chunks/ssr/[root-of-the-server]__c3694f82._.js +10 -0
  141. package/web/.next/server/chunks/ssr/[root-of-the-server]__c3694f82._.js.map +1 -0
  142. package/web/.next/server/chunks/ssr/[root-of-the-server]__d6257aad._.js +3 -0
  143. package/web/.next/server/chunks/ssr/[root-of-the-server]__d6257aad._.js.map +1 -0
  144. package/web/.next/server/chunks/ssr/[root-of-the-server]__d81095d0._.js +3 -0
  145. package/web/.next/server/chunks/ssr/[root-of-the-server]__d81095d0._.js.map +1 -0
  146. package/web/.next/server/chunks/ssr/[turbopack]_runtime.js +795 -0
  147. package/web/.next/server/chunks/ssr/[turbopack]_runtime.js.map +10 -0
  148. package/web/.next/server/chunks/ssr/_0f02ab66._.js +3 -0
  149. package/web/.next/server/chunks/ssr/_0f02ab66._.js.map +1 -0
  150. package/web/.next/server/chunks/ssr/_884ddade._.js +4 -0
  151. package/web/.next/server/chunks/ssr/_884ddade._.js.map +1 -0
  152. package/web/.next/server/chunks/ssr/_90bc0c33._.js +3 -0
  153. package/web/.next/server/chunks/ssr/_90bc0c33._.js.map +1 -0
  154. package/web/.next/server/chunks/ssr/_c536147b._.js +3 -0
  155. package/web/.next/server/chunks/ssr/_c536147b._.js.map +1 -0
  156. package/web/.next/server/chunks/ssr/_c5d377cc._.js +4 -0
  157. package/web/.next/server/chunks/ssr/_c5d377cc._.js.map +1 -0
  158. package/web/.next/server/chunks/ssr/_e519e92f._.js +3 -0
  159. package/web/.next/server/chunks/ssr/_e519e92f._.js.map +1 -0
  160. package/web/.next/server/chunks/ssr/b1a17_presentation_web__next-internal_server_app__global-error_page_actions_4fe4770f.js +3 -0
  161. package/web/.next/server/chunks/ssr/b1a17_presentation_web__next-internal_server_app__global-error_page_actions_4fe4770f.js.map +1 -0
  162. package/web/.next/server/chunks/ssr/node_modules__pnpm_03635e2b._.js +4 -0
  163. package/web/.next/server/chunks/ssr/node_modules__pnpm_03635e2b._.js.map +1 -0
  164. package/web/.next/server/chunks/ssr/node_modules__pnpm_522e4103._.js +3 -0
  165. package/web/.next/server/chunks/ssr/node_modules__pnpm_522e4103._.js.map +1 -0
  166. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app__not-found_page_actions_a836bb2a.js +3 -0
  167. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app__not-found_page_actions_a836bb2a.js.map +1 -0
  168. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_page_actions_a4e3cb6f.js +3 -0
  169. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_page_actions_a4e3cb6f.js.map +1 -0
  170. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_version_page_actions_ea925032.js +3 -0
  171. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_version_page_actions_ea925032.js.map +1 -0
  172. package/web/.next/server/chunks/ssr/src_presentation_web_app_layout_tsx_aa3a06bd._.js +13 -0
  173. package/web/.next/server/chunks/ssr/src_presentation_web_app_layout_tsx_aa3a06bd._.js.map +1 -0
  174. package/web/.next/server/chunks/ssr/src_presentation_web_app_not-found_tsx_64b86c46._.js +3 -0
  175. package/web/.next/server/chunks/ssr/src_presentation_web_app_not-found_tsx_64b86c46._.js.map +1 -0
  176. package/web/.next/server/chunks/ssr/src_presentation_web_app_version_page_tsx_1bab7370._.js +3 -0
  177. package/web/.next/server/chunks/ssr/src_presentation_web_app_version_page_tsx_1bab7370._.js.map +1 -0
  178. package/web/.next/server/functions-config-manifest.json +4 -0
  179. package/web/.next/server/interception-route-rewrite-manifest.js +1 -0
  180. package/web/.next/server/middleware-build-manifest.js +21 -0
  181. package/web/.next/server/middleware-manifest.json +6 -0
  182. package/web/.next/server/next-font-manifest.js +1 -0
  183. package/web/.next/server/next-font-manifest.json +6 -0
  184. package/web/.next/server/pages/404.html +11 -0
  185. package/web/.next/server/pages/500.html +2 -0
  186. package/web/.next/server/pages-manifest.json +4 -0
  187. package/web/.next/server/server-reference-manifest.js +1 -0
  188. package/web/.next/server/server-reference-manifest.json +5 -0
  189. package/web/.next/static/Z9XCmAv7-DjAFCpNEPaUt/_buildManifest.js +11 -0
  190. package/web/.next/static/Z9XCmAv7-DjAFCpNEPaUt/_clientMiddlewareManifest.json +1 -0
  191. package/web/.next/static/Z9XCmAv7-DjAFCpNEPaUt/_ssgManifest.js +1 -0
  192. package/web/.next/static/chunks/4d6504b9f2ca7e4d.js +1 -0
  193. package/web/.next/static/chunks/51816495a9eb288c.css +1 -0
  194. package/web/.next/static/chunks/52a5aeb86329ee2e.js +1 -0
  195. package/web/.next/static/chunks/70993ebedee7eab0.js +2 -0
  196. package/web/.next/static/chunks/71462f20e38a4262.js +4 -0
  197. package/web/.next/static/chunks/86484b9b4aa9f859.js +1 -0
  198. package/web/.next/static/chunks/a6dad97d9634a72d.js +1 -0
  199. package/web/.next/static/chunks/a6dad97d9634a72d.js.map +1 -0
  200. package/web/.next/static/chunks/ab02eec995295bef.js +1 -0
  201. package/web/.next/static/chunks/b3cc49b27e09fa39.js +1 -0
  202. package/web/.next/static/chunks/f3b4460b1496ef52.js +1 -0
  203. package/web/.next/static/chunks/turbopack-76ba02c6b131eee4.js +4 -0
  204. package/web/.next/trace +1 -0
  205. package/web/.next/trace-build +1 -0
  206. package/web/.next/turbopack +0 -0
  207. package/web/.next/types/link.d.ts +163 -0
  208. package/web/.next/types/routes.d.ts +58 -0
  209. package/web/.next/types/validator.ts +70 -0
  210. package/web/next.config.ts +14 -0
  211. package/web/package.json +38 -0
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Port Service
3
+ *
4
+ * Port availability checking and auto-increment logic for the web server.
5
+ * Uses node:net try-bind pattern (same approach as Vite).
6
+ */
7
+ /** Default port for the Shep web UI */
8
+ export declare const DEFAULT_PORT = 4050;
9
+ /** Maximum number of ports to try before giving up */
10
+ export declare const MAX_PORT_ATTEMPTS = 20;
11
+ /**
12
+ * Check if a port is available by attempting to bind to it.
13
+ */
14
+ export declare function isPortAvailable(port: number): Promise<boolean>;
15
+ /**
16
+ * Find an available port starting from `startPort`, incrementing up to `maxAttempts`.
17
+ * Throws if no available port is found or if the port is out of valid range.
18
+ */
19
+ export declare function findAvailablePort(startPort: number, maxAttempts?: number): Promise<number>;
20
+ //# sourceMappingURL=port.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"port.service.d.ts","sourceRoot":"","sources":["../../../../src/infrastructure/services/port.service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,uCAAuC;AACvC,eAAO,MAAM,YAAY,OAAO,CAAC;AAEjC,sDAAsD;AACtD,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAKpC;;GAEG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAgBpE;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,WAAW,GAAE,MAA0B,GACtC,OAAO,CAAC,MAAM,CAAC,CAejB"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Port Service
3
+ *
4
+ * Port availability checking and auto-increment logic for the web server.
5
+ * Uses node:net try-bind pattern (same approach as Vite).
6
+ */
7
+ import net from 'node:net';
8
+ /** Default port for the Shep web UI */
9
+ export const DEFAULT_PORT = 4050;
10
+ /** Maximum number of ports to try before giving up */
11
+ export const MAX_PORT_ATTEMPTS = 20;
12
+ const MIN_PORT = 1024;
13
+ const MAX_PORT = 65535;
14
+ /**
15
+ * Check if a port is available by attempting to bind to it.
16
+ */
17
+ export async function isPortAvailable(port) {
18
+ return new Promise((resolve) => {
19
+ const server = net.createServer();
20
+ server.once('error', () => {
21
+ resolve(false);
22
+ });
23
+ server.once('listening', () => {
24
+ server.close(() => {
25
+ resolve(true);
26
+ });
27
+ });
28
+ server.listen(port, '127.0.0.1');
29
+ });
30
+ }
31
+ /**
32
+ * Find an available port starting from `startPort`, incrementing up to `maxAttempts`.
33
+ * Throws if no available port is found or if the port is out of valid range.
34
+ */
35
+ export async function findAvailablePort(startPort, maxAttempts = MAX_PORT_ATTEMPTS) {
36
+ if (startPort < MIN_PORT || startPort > MAX_PORT) {
37
+ throw new Error(`Port ${startPort} is out of valid range (${MIN_PORT}-${MAX_PORT})`);
38
+ }
39
+ for (let port = startPort; port < startPort + maxAttempts; port++) {
40
+ if (port > MAX_PORT)
41
+ break;
42
+ if (await isPortAvailable(port)) {
43
+ return port;
44
+ }
45
+ }
46
+ throw new Error(`No available port found between ${startPort}-${Math.min(startPort + maxAttempts - 1, MAX_PORT)}`);
47
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Web Server Service
3
+ *
4
+ * Manages the Next.js programmatic server lifecycle.
5
+ * Starts the web UI in the same Node.js process as the CLI,
6
+ * sharing the DI container and application layer.
7
+ *
8
+ * Supports both development (dev: true) and production (dev: false) modes.
9
+ * In production mode, Next.js serves the pre-built .next output.
10
+ */
11
+ import next from 'next';
12
+ import http from 'node:http';
13
+ export interface WebServerDeps {
14
+ createNextApp: typeof next;
15
+ createHttpServer: typeof http.createServer;
16
+ }
17
+ /**
18
+ * Resolve the web UI directory path.
19
+ * Works in both development (src/) and production (dist/) contexts.
20
+ */
21
+ export declare function resolveWebDir(): {
22
+ dir: string;
23
+ dev: boolean;
24
+ };
25
+ export declare class WebServerService {
26
+ private app;
27
+ private server;
28
+ private isShuttingDown;
29
+ private readonly deps;
30
+ constructor(deps?: Partial<WebServerDeps>);
31
+ /**
32
+ * Start the Next.js web server.
33
+ * @param port - Port to listen on
34
+ * @param dir - Path to the Next.js web package directory
35
+ * @param dev - Whether to run in development mode (default: auto-detect)
36
+ */
37
+ start(port: number, dir: string, dev?: boolean): Promise<void>;
38
+ /**
39
+ * Gracefully stop the server.
40
+ */
41
+ stop(): Promise<void>;
42
+ }
43
+ //# sourceMappingURL=web-server.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-server.service.d.ts","sourceRoot":"","sources":["../../../../src/infrastructure/services/web-server.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,IAAI,MAAM,WAAW,CAAC;AAM7B,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,OAAO,IAAI,CAAC;IAC3B,gBAAgB,EAAE,OAAO,IAAI,CAAC,YAAY,CAAC;CAC5C;AAOD;;;GAGG;AACH,wBAAgB,aAAa,IAAI;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,OAAO,CAAA;CAAE,CAiB7D;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,GAAG,CAAwB;IACnC,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgB;gBAEzB,IAAI,GAAE,OAAO,CAAC,aAAa,CAAM;IAI7C;;;;;OAKG;IACG,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,UAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BjE;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAoB5B"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Web Server Service
3
+ *
4
+ * Manages the Next.js programmatic server lifecycle.
5
+ * Starts the web UI in the same Node.js process as the CLI,
6
+ * sharing the DI container and application layer.
7
+ *
8
+ * Supports both development (dev: true) and production (dev: false) modes.
9
+ * In production mode, Next.js serves the pre-built .next output.
10
+ */
11
+ import next from 'next';
12
+ import http from 'node:http';
13
+ import path from 'node:path';
14
+ import fs from 'node:fs';
15
+ const defaultDeps = {
16
+ createNextApp: next,
17
+ createHttpServer: http.createServer,
18
+ };
19
+ /**
20
+ * Resolve the web UI directory path.
21
+ * Works in both development (src/) and production (dist/) contexts.
22
+ */
23
+ export function resolveWebDir() {
24
+ // Check for development source directory first
25
+ const devDir = path.resolve(import.meta.dirname, '../../presentation/web');
26
+ if (fs.existsSync(path.join(devDir, 'next.config.ts'))) {
27
+ return { dir: devDir, dev: true };
28
+ }
29
+ // Production: web UI is shipped alongside dist/ in the package
30
+ const prodDir = path.resolve(import.meta.dirname, '../../../web');
31
+ if (fs.existsSync(path.join(prodDir, 'next.config.ts')) ||
32
+ fs.existsSync(path.join(prodDir, '.next'))) {
33
+ return { dir: prodDir, dev: false };
34
+ }
35
+ throw new Error('Web UI directory not found. Ensure the web UI is built (pnpm build:web).');
36
+ }
37
+ export class WebServerService {
38
+ app = null;
39
+ server = null;
40
+ isShuttingDown = false;
41
+ deps;
42
+ constructor(deps = {}) {
43
+ this.deps = { ...defaultDeps, ...deps };
44
+ }
45
+ /**
46
+ * Start the Next.js web server.
47
+ * @param port - Port to listen on
48
+ * @param dir - Path to the Next.js web package directory
49
+ * @param dev - Whether to run in development mode (default: auto-detect)
50
+ */
51
+ async start(port, dir, dev = true) {
52
+ const app = this.deps.createNextApp({
53
+ dev,
54
+ dir,
55
+ port,
56
+ hostname: 'localhost',
57
+ });
58
+ const handle = app.getRequestHandler();
59
+ await app.prepare();
60
+ this.app = app;
61
+ await new Promise((resolve, reject) => {
62
+ const server = this.deps.createHttpServer((req, res) => {
63
+ handle(req, res);
64
+ });
65
+ server.on('error', reject);
66
+ server.listen(port, 'localhost', () => {
67
+ this.server = server;
68
+ resolve();
69
+ });
70
+ });
71
+ }
72
+ /**
73
+ * Gracefully stop the server.
74
+ */
75
+ async stop() {
76
+ if (this.isShuttingDown)
77
+ return;
78
+ this.isShuttingDown = true;
79
+ try {
80
+ if (this.server) {
81
+ await new Promise((resolve) => {
82
+ this.server.close(() => resolve());
83
+ });
84
+ this.server = null;
85
+ }
86
+ if (this.app) {
87
+ await this.app.close();
88
+ this.app = null;
89
+ }
90
+ }
91
+ finally {
92
+ this.isShuttingDown = false;
93
+ }
94
+ }
95
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * UI Command
3
+ *
4
+ * Starts the Shep web UI server.
5
+ * Runs Next.js in the same process as the CLI, sharing the DI container.
6
+ *
7
+ * Usage: shep ui [--port <number>]
8
+ *
9
+ * @example
10
+ * $ shep ui
11
+ * Shep Web UI
12
+ * Starting web server...
13
+ *
14
+ * ✓ Server ready at http://localhost:4050
15
+ * ℹ Press Ctrl+C to stop
16
+ */
17
+ import { Command } from 'commander';
18
+ /**
19
+ * Create the ui command
20
+ */
21
+ export declare function createUiCommand(): Command;
22
+ //# sourceMappingURL=ui.command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.command.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/cli/commands/ui.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,OAAO,EAAwB,MAAM,WAAW,CAAC;AAgB1D;;GAEG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAiDzC"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * UI Command
3
+ *
4
+ * Starts the Shep web UI server.
5
+ * Runs Next.js in the same process as the CLI, sharing the DI container.
6
+ *
7
+ * Usage: shep ui [--port <number>]
8
+ *
9
+ * @example
10
+ * $ shep ui
11
+ * Shep Web UI
12
+ * Starting web server...
13
+ *
14
+ * ✓ Server ready at http://localhost:4050
15
+ * ℹ Press Ctrl+C to stop
16
+ */
17
+ import { Command, InvalidArgumentError } from 'commander';
18
+ import { findAvailablePort, DEFAULT_PORT } from '../../../infrastructure/services/port.service.js';
19
+ import { WebServerService, resolveWebDir, } from '../../../infrastructure/services/web-server.service.js';
20
+ import { colors, fmt, messages } from '../ui/index.js';
21
+ function parsePort(value) {
22
+ const port = parseInt(value, 10);
23
+ if (isNaN(port) || port < 1024 || port > 65535) {
24
+ throw new InvalidArgumentError('Port must be an integer between 1024 and 65535');
25
+ }
26
+ return port;
27
+ }
28
+ /**
29
+ * Create the ui command
30
+ */
31
+ export function createUiCommand() {
32
+ return new Command('ui')
33
+ .description('Start the Shep web UI')
34
+ .option('-p, --port <number>', 'Port number (1024-65535)', parsePort)
35
+ .addHelpText('after', `
36
+ Examples:
37
+ $ shep ui Start on default port (4050)
38
+ $ shep ui --port 8080 Start on custom port`)
39
+ .action(async (options) => {
40
+ try {
41
+ const startPort = options.port ?? DEFAULT_PORT;
42
+ const port = await findAvailablePort(startPort);
43
+ const { dir, dev } = resolveWebDir();
44
+ messages.newline();
45
+ console.log(fmt.heading('Shep Web UI'));
46
+ console.log(colors.muted(`Starting web server${dev ? ' (dev mode)' : ''}...`));
47
+ messages.newline();
48
+ const service = new WebServerService();
49
+ await service.start(port, dir, dev);
50
+ messages.success(`Server ready at ${fmt.code(`http://localhost:${port}`)}`);
51
+ messages.info('Press Ctrl+C to stop');
52
+ messages.newline();
53
+ // Handle graceful shutdown via SIGINT/SIGTERM
54
+ // The HTTP server keeps the event loop alive — no explicit wait needed
55
+ let isShuttingDown = false;
56
+ const shutdown = async () => {
57
+ if (isShuttingDown)
58
+ return;
59
+ isShuttingDown = true;
60
+ messages.newline();
61
+ messages.info('Shutting down...');
62
+ await service.stop();
63
+ process.exit(0);
64
+ };
65
+ process.on('SIGINT', shutdown);
66
+ process.on('SIGTERM', shutdown);
67
+ }
68
+ catch (error) {
69
+ const err = error instanceof Error ? error : new Error(String(error));
70
+ messages.error('Failed to start web UI', err);
71
+ process.exitCode = 1;
72
+ }
73
+ });
74
+ }
@@ -10,6 +10,7 @@
10
10
  * Commands:
11
11
  * shep Show help
12
12
  * shep version Display version information
13
+ * shep ui Start the web UI
13
14
  * shep --version Display version number only
14
15
  *
15
16
  * Global Options:
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/presentation/cli/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/presentation/cli/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,kBAAkB,CAAC"}
@@ -10,6 +10,7 @@
10
10
  * Commands:
11
11
  * shep Show help
12
12
  * shep version Display version information
13
+ * shep ui Start the web UI
13
14
  * shep --version Display version number only
14
15
  *
15
16
  * Global Options:
@@ -22,6 +23,7 @@ import { Command } from 'commander';
22
23
  import { VersionService } from '../../infrastructure/services/version.service.js';
23
24
  import { createVersionCommand } from './commands/version.command.js';
24
25
  import { createSettingsCommand } from './commands/settings/index.js';
26
+ import { createUiCommand } from './commands/ui.command.js';
25
27
  import { messages } from './ui/index.js';
26
28
  // DI container and settings
27
29
  import { initializeContainer, container } from '../../infrastructure/di/container.js';
@@ -66,6 +68,7 @@ async function bootstrap() {
66
68
  // Register commands
67
69
  program.addCommand(createVersionCommand());
68
70
  program.addCommand(createSettingsCommand());
71
+ program.addCommand(createUiCommand());
69
72
  // Parse arguments (parseAsync needed for async command actions like init)
70
73
  await program.parseAsync();
71
74
  }