vibeman 0.0.5 → 0.0.7

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 (239) hide show
  1. package/dist/api.js +43 -0
  2. package/dist/index.js +227 -104
  3. package/dist/ui/assets/index-C_kQPI1m.js +9 -0
  4. package/dist/ui/index.html +12 -0
  5. package/package.json +13 -46
  6. package/README.md +0 -12
  7. package/dist/runtime/api/.tsbuildinfo +0 -1
  8. package/dist/runtime/api/agent/agent-service.d.ts +0 -229
  9. package/dist/runtime/api/agent/agent-service.js +0 -963
  10. package/dist/runtime/api/agent/ai-providers/amp-cli-provider.d.ts +0 -38
  11. package/dist/runtime/api/agent/ai-providers/amp-cli-provider.js +0 -268
  12. package/dist/runtime/api/agent/ai-providers/claude-code-adapter.d.ts +0 -61
  13. package/dist/runtime/api/agent/ai-providers/claude-code-adapter.js +0 -362
  14. package/dist/runtime/api/agent/ai-providers/codex-cli-provider.d.ts +0 -36
  15. package/dist/runtime/api/agent/ai-providers/codex-cli-provider.js +0 -375
  16. package/dist/runtime/api/agent/ai-providers/gemini-cli-provider.d.ts +0 -24
  17. package/dist/runtime/api/agent/ai-providers/gemini-cli-provider.js +0 -291
  18. package/dist/runtime/api/agent/ai-providers/index.d.ts +0 -9
  19. package/dist/runtime/api/agent/ai-providers/index.js +0 -9
  20. package/dist/runtime/api/agent/ai-providers/types.d.ts +0 -185
  21. package/dist/runtime/api/agent/ai-providers/types.js +0 -5
  22. package/dist/runtime/api/agent/amp-cli-provider.test.d.ts +0 -1
  23. package/dist/runtime/api/agent/amp-cli-provider.test.js +0 -99
  24. package/dist/runtime/api/agent/codex-cli-provider.test.d.ts +0 -1
  25. package/dist/runtime/api/agent/codex-cli-provider.test.js +0 -172
  26. package/dist/runtime/api/agent/core-agent-service.d.ts +0 -119
  27. package/dist/runtime/api/agent/core-agent-service.js +0 -267
  28. package/dist/runtime/api/agent/parsers.d.ts +0 -16
  29. package/dist/runtime/api/agent/parsers.js +0 -308
  30. package/dist/runtime/api/agent/prompt-service.d.ts +0 -30
  31. package/dist/runtime/api/agent/prompt-service.js +0 -452
  32. package/dist/runtime/api/agent/prompt-service.test.d.ts +0 -1
  33. package/dist/runtime/api/agent/prompt-service.test.js +0 -265
  34. package/dist/runtime/api/agent/routing-policy.d.ts +0 -171
  35. package/dist/runtime/api/agent/routing-policy.js +0 -196
  36. package/dist/runtime/api/agent/routing-policy.test.d.ts +0 -1
  37. package/dist/runtime/api/agent/routing-policy.test.js +0 -63
  38. package/dist/runtime/api/api/router-helpers.d.ts +0 -32
  39. package/dist/runtime/api/api/router-helpers.js +0 -31
  40. package/dist/runtime/api/api/routers/ai.d.ts +0 -200
  41. package/dist/runtime/api/api/routers/ai.js +0 -396
  42. package/dist/runtime/api/api/routers/executions.d.ts +0 -93
  43. package/dist/runtime/api/api/routers/executions.js +0 -94
  44. package/dist/runtime/api/api/routers/git.d.ts +0 -45
  45. package/dist/runtime/api/api/routers/git.js +0 -35
  46. package/dist/runtime/api/api/routers/provider-config.d.ts +0 -199
  47. package/dist/runtime/api/api/routers/provider-config.js +0 -252
  48. package/dist/runtime/api/api/routers/settings.d.ts +0 -158
  49. package/dist/runtime/api/api/routers/settings.js +0 -129
  50. package/dist/runtime/api/api/routers/tasks.d.ts +0 -141
  51. package/dist/runtime/api/api/routers/tasks.js +0 -238
  52. package/dist/runtime/api/api/routers/workflows.d.ts +0 -275
  53. package/dist/runtime/api/api/routers/workflows.js +0 -311
  54. package/dist/runtime/api/api/routers/worktrees.d.ts +0 -101
  55. package/dist/runtime/api/api/routers/worktrees.js +0 -80
  56. package/dist/runtime/api/api/trpc.d.ts +0 -118
  57. package/dist/runtime/api/api/trpc.js +0 -34
  58. package/dist/runtime/api/index.d.ts +0 -9
  59. package/dist/runtime/api/index.js +0 -117
  60. package/dist/runtime/api/lib/id-generator.d.ts +0 -70
  61. package/dist/runtime/api/lib/id-generator.js +0 -123
  62. package/dist/runtime/api/lib/local-config.d.ts +0 -335
  63. package/dist/runtime/api/lib/local-config.js +0 -304
  64. package/dist/runtime/api/lib/logger.d.ts +0 -11
  65. package/dist/runtime/api/lib/logger.js +0 -188
  66. package/dist/runtime/api/lib/provider-detection.d.ts +0 -61
  67. package/dist/runtime/api/lib/provider-detection.js +0 -326
  68. package/dist/runtime/api/lib/server/agent-service-singleton.d.ts +0 -6
  69. package/dist/runtime/api/lib/server/agent-service-singleton.js +0 -27
  70. package/dist/runtime/api/lib/server/bootstrap.d.ts +0 -38
  71. package/dist/runtime/api/lib/server/bootstrap.js +0 -197
  72. package/dist/runtime/api/lib/server/git-service-singleton.d.ts +0 -6
  73. package/dist/runtime/api/lib/server/git-service-singleton.js +0 -47
  74. package/dist/runtime/api/lib/server/project-root.d.ts +0 -2
  75. package/dist/runtime/api/lib/server/project-root.js +0 -61
  76. package/dist/runtime/api/lib/server/task-service-singleton.d.ts +0 -7
  77. package/dist/runtime/api/lib/server/task-service-singleton.js +0 -58
  78. package/dist/runtime/api/lib/server/vibeman-info.d.ts +0 -5
  79. package/dist/runtime/api/lib/server/vibeman-info.js +0 -85
  80. package/dist/runtime/api/lib/server/vibing-orchestrator-singleton.d.ts +0 -7
  81. package/dist/runtime/api/lib/server/vibing-orchestrator-singleton.js +0 -57
  82. package/dist/runtime/api/lib/trpc/server.d.ts +0 -965
  83. package/dist/runtime/api/lib/trpc/server.js +0 -11
  84. package/dist/runtime/api/lib/trpc/ws-server.d.ts +0 -8
  85. package/dist/runtime/api/lib/trpc/ws-server.js +0 -33
  86. package/dist/runtime/api/persistence/database-service.d.ts +0 -14
  87. package/dist/runtime/api/persistence/database-service.js +0 -74
  88. package/dist/runtime/api/persistence/execution-log-persistence.d.ts +0 -90
  89. package/dist/runtime/api/persistence/execution-log-persistence.js +0 -426
  90. package/dist/runtime/api/persistence/execution-log-persistence.test.d.ts +0 -1
  91. package/dist/runtime/api/persistence/execution-log-persistence.test.js +0 -170
  92. package/dist/runtime/api/router.d.ts +0 -968
  93. package/dist/runtime/api/router.js +0 -34
  94. package/dist/runtime/api/settings-service.d.ts +0 -110
  95. package/dist/runtime/api/settings-service.js +0 -678
  96. package/dist/runtime/api/tasks/file-watcher.d.ts +0 -23
  97. package/dist/runtime/api/tasks/file-watcher.js +0 -88
  98. package/dist/runtime/api/tasks/task-file-parser.d.ts +0 -14
  99. package/dist/runtime/api/tasks/task-file-parser.js +0 -180
  100. package/dist/runtime/api/tasks/task-service.d.ts +0 -36
  101. package/dist/runtime/api/tasks/task-service.js +0 -173
  102. package/dist/runtime/api/tasks/task-updater.d.ts +0 -62
  103. package/dist/runtime/api/tasks/task-updater.js +0 -260
  104. package/dist/runtime/api/tasks/task-updater.test.d.ts +0 -1
  105. package/dist/runtime/api/tasks/task-updater.test.js +0 -303
  106. package/dist/runtime/api/types/index.d.ts +0 -186
  107. package/dist/runtime/api/types/index.js +0 -1
  108. package/dist/runtime/api/types/settings.d.ts +0 -105
  109. package/dist/runtime/api/types/settings.js +0 -2
  110. package/dist/runtime/api/types.d.ts +0 -2
  111. package/dist/runtime/api/types.js +0 -1
  112. package/dist/runtime/api/utils/env.d.ts +0 -6
  113. package/dist/runtime/api/utils/env.js +0 -12
  114. package/dist/runtime/api/utils/stripNextEnv.d.ts +0 -7
  115. package/dist/runtime/api/utils/stripNextEnv.js +0 -22
  116. package/dist/runtime/api/utils/title-slug.d.ts +0 -6
  117. package/dist/runtime/api/utils/title-slug.js +0 -77
  118. package/dist/runtime/api/utils/url.d.ts +0 -2
  119. package/dist/runtime/api/utils/url.js +0 -19
  120. package/dist/runtime/api/vcs/git-history-service.d.ts +0 -57
  121. package/dist/runtime/api/vcs/git-history-service.js +0 -228
  122. package/dist/runtime/api/vcs/git-service.d.ts +0 -136
  123. package/dist/runtime/api/vcs/git-service.js +0 -307
  124. package/dist/runtime/api/vcs/worktree-service.d.ts +0 -93
  125. package/dist/runtime/api/vcs/worktree-service.js +0 -518
  126. package/dist/runtime/api/vcs/worktree-service.test.d.ts +0 -1
  127. package/dist/runtime/api/vcs/worktree-service.test.js +0 -20
  128. package/dist/runtime/api/workflows/quality-pipeline.d.ts +0 -58
  129. package/dist/runtime/api/workflows/quality-pipeline.js +0 -401
  130. package/dist/runtime/api/workflows/vibing-orchestrator.d.ts +0 -406
  131. package/dist/runtime/api/workflows/vibing-orchestrator.js +0 -2462
  132. package/dist/runtime/api/workflows/workflow-effects.d.ts +0 -45
  133. package/dist/runtime/api/workflows/workflow-effects.js +0 -49
  134. package/dist/runtime/api/workflows/workflow-reconciler.d.ts +0 -65
  135. package/dist/runtime/api/workflows/workflow-reconciler.js +0 -226
  136. package/dist/runtime/api/workflows/workflow-reducer.d.ts +0 -26
  137. package/dist/runtime/api/workflows/workflow-reducer.js +0 -288
  138. package/dist/runtime/api/workflows/workflow-reducer.test.d.ts +0 -1
  139. package/dist/runtime/api/workflows/workflow-reducer.test.js +0 -247
  140. package/dist/runtime/api/workflows/workflow-schema.d.ts +0 -546
  141. package/dist/runtime/api/workflows/workflow-schema.js +0 -256
  142. package/dist/runtime/web/.next/BUILD_ID +0 -1
  143. package/dist/runtime/web/.next/app-build-manifest.json +0 -66
  144. package/dist/runtime/web/.next/app-path-routes-manifest.json +0 -8
  145. package/dist/runtime/web/.next/build-manifest.json +0 -33
  146. package/dist/runtime/web/.next/package.json +0 -1
  147. package/dist/runtime/web/.next/prerender-manifest.json +0 -61
  148. package/dist/runtime/web/.next/react-loadable-manifest.json +0 -8
  149. package/dist/runtime/web/.next/required-server-files.json +0 -334
  150. package/dist/runtime/web/.next/routes-manifest.json +0 -70
  151. package/dist/runtime/web/.next/server/app/.vibeman/assets/images/[...path]/route.js +0 -1
  152. package/dist/runtime/web/.next/server/app/.vibeman/assets/images/[...path]/route.js.nft.json +0 -1
  153. package/dist/runtime/web/.next/server/app/.vibeman/assets/images/[...path]/route_client-reference-manifest.js +0 -1
  154. package/dist/runtime/web/.next/server/app/_not-found/page.js +0 -2
  155. package/dist/runtime/web/.next/server/app/_not-found/page.js.nft.json +0 -1
  156. package/dist/runtime/web/.next/server/app/_not-found/page_client-reference-manifest.js +0 -1
  157. package/dist/runtime/web/.next/server/app/_not-found.html +0 -7
  158. package/dist/runtime/web/.next/server/app/_not-found.meta +0 -8
  159. package/dist/runtime/web/.next/server/app/_not-found.rsc +0 -22
  160. package/dist/runtime/web/.next/server/app/api/health/route.js +0 -1
  161. package/dist/runtime/web/.next/server/app/api/health/route.js.nft.json +0 -1
  162. package/dist/runtime/web/.next/server/app/api/health/route_client-reference-manifest.js +0 -1
  163. package/dist/runtime/web/.next/server/app/api/images/[...path]/route.js +0 -1
  164. package/dist/runtime/web/.next/server/app/api/images/[...path]/route.js.nft.json +0 -1
  165. package/dist/runtime/web/.next/server/app/api/images/[...path]/route_client-reference-manifest.js +0 -1
  166. package/dist/runtime/web/.next/server/app/api/upload/route.js +0 -1
  167. package/dist/runtime/web/.next/server/app/api/upload/route.js.nft.json +0 -1
  168. package/dist/runtime/web/.next/server/app/api/upload/route_client-reference-manifest.js +0 -1
  169. package/dist/runtime/web/.next/server/app/index.html +0 -7
  170. package/dist/runtime/web/.next/server/app/index.meta +0 -7
  171. package/dist/runtime/web/.next/server/app/index.rsc +0 -27
  172. package/dist/runtime/web/.next/server/app/page.js +0 -112
  173. package/dist/runtime/web/.next/server/app/page.js.nft.json +0 -1
  174. package/dist/runtime/web/.next/server/app/page_client-reference-manifest.js +0 -1
  175. package/dist/runtime/web/.next/server/app-paths-manifest.json +0 -8
  176. package/dist/runtime/web/.next/server/chunks/210.js +0 -1
  177. package/dist/runtime/web/.next/server/chunks/291.js +0 -18
  178. package/dist/runtime/web/.next/server/chunks/552.js +0 -22
  179. package/dist/runtime/web/.next/server/chunks/780.js +0 -1
  180. package/dist/runtime/web/.next/server/chunks/905.js +0 -6
  181. package/dist/runtime/web/.next/server/chunks/98.js +0 -1
  182. package/dist/runtime/web/.next/server/functions-config-manifest.json +0 -4
  183. package/dist/runtime/web/.next/server/middleware-build-manifest.js +0 -1
  184. package/dist/runtime/web/.next/server/middleware-manifest.json +0 -6
  185. package/dist/runtime/web/.next/server/middleware-react-loadable-manifest.js +0 -1
  186. package/dist/runtime/web/.next/server/next-font-manifest.js +0 -1
  187. package/dist/runtime/web/.next/server/next-font-manifest.json +0 -1
  188. package/dist/runtime/web/.next/server/pages/404.html +0 -7
  189. package/dist/runtime/web/.next/server/pages/500.html +0 -1
  190. package/dist/runtime/web/.next/server/pages/_app.js +0 -1
  191. package/dist/runtime/web/.next/server/pages/_app.js.nft.json +0 -1
  192. package/dist/runtime/web/.next/server/pages/_document.js +0 -1
  193. package/dist/runtime/web/.next/server/pages/_document.js.nft.json +0 -1
  194. package/dist/runtime/web/.next/server/pages/_error.js +0 -19
  195. package/dist/runtime/web/.next/server/pages/_error.js.nft.json +0 -1
  196. package/dist/runtime/web/.next/server/pages-manifest.json +0 -6
  197. package/dist/runtime/web/.next/server/server-reference-manifest.js +0 -1
  198. package/dist/runtime/web/.next/server/server-reference-manifest.json +0 -1
  199. package/dist/runtime/web/.next/server/webpack-runtime.js +0 -1
  200. package/dist/runtime/web/.next/static/LJFZk_8tvKFN_Ee4HqUuM/_buildManifest.js +0 -1
  201. package/dist/runtime/web/.next/static/LJFZk_8tvKFN_Ee4HqUuM/_ssgManifest.js +0 -1
  202. package/dist/runtime/web/.next/static/chunks/05c91ade-7d09b2b280adffd1.js +0 -1
  203. package/dist/runtime/web/.next/static/chunks/201-51bef3fa8c832e2e.js +0 -1
  204. package/dist/runtime/web/.next/static/chunks/524-89747ed9b0294f8a.js +0 -1
  205. package/dist/runtime/web/.next/static/chunks/554-8bec6e9cca6acc67.js +0 -1
  206. package/dist/runtime/web/.next/static/chunks/764.86e9503a69d45a85.js +0 -1
  207. package/dist/runtime/web/.next/static/chunks/7ab4dc20-239138e0ae7af24a.js +0 -1
  208. package/dist/runtime/web/.next/static/chunks/905-342391e3d3a3678f.js +0 -20
  209. package/dist/runtime/web/.next/static/chunks/a8a5ce16-4edea7df2d9b544a.js +0 -79
  210. package/dist/runtime/web/.next/static/chunks/ad74d572-4c1b162e2c15acaa.js +0 -1
  211. package/dist/runtime/web/.next/static/chunks/app/.vibeman/assets/images/[...path]/route-7b752a8641f96c1f.js +0 -1
  212. package/dist/runtime/web/.next/static/chunks/app/_not-found/page-34e66b251c2b5044.js +0 -1
  213. package/dist/runtime/web/.next/static/chunks/app/api/health/route-7b752a8641f96c1f.js +0 -1
  214. package/dist/runtime/web/.next/static/chunks/app/api/images/[...path]/route-7b752a8641f96c1f.js +0 -1
  215. package/dist/runtime/web/.next/static/chunks/app/api/upload/route-7b752a8641f96c1f.js +0 -1
  216. package/dist/runtime/web/.next/static/chunks/app/layout-df9ac93cb02b2385.js +0 -1
  217. package/dist/runtime/web/.next/static/chunks/app/page-6610743f7de5f92a.js +0 -1
  218. package/dist/runtime/web/.next/static/chunks/c25e0690-e9b798b8de667da1.js +0 -1
  219. package/dist/runtime/web/.next/static/chunks/framework-57157ec4d37f64aa.js +0 -1
  220. package/dist/runtime/web/.next/static/chunks/main-app-156cc0c60371bd78.js +0 -1
  221. package/dist/runtime/web/.next/static/chunks/main-df25d367c47b1fec.js +0 -1
  222. package/dist/runtime/web/.next/static/chunks/pages/_app-9f629a5e1131d19f.js +0 -1
  223. package/dist/runtime/web/.next/static/chunks/pages/_error-9238238274c7efcd.js +0 -1
  224. package/dist/runtime/web/.next/static/chunks/polyfills-42372ed130431b0a.js +0 -1
  225. package/dist/runtime/web/.next/static/chunks/webpack-cd50e39b423d1808.js +0 -1
  226. package/dist/runtime/web/.next/static/css/2728291c68f99cb1.css +0 -3
  227. package/dist/runtime/web/.next/static/css/4fbf378a264bd4ea.css +0 -1
  228. package/dist/runtime/web/.next/static/css/521bd69cc298cd1a.css +0 -1
  229. package/dist/runtime/web/.next/static/css/537e22821e101b87.css +0 -1
  230. package/dist/runtime/web/.next/static/media/19cfc7226ec3afaa-s.woff2 +0 -0
  231. package/dist/runtime/web/.next/static/media/21350d82a1f187e9-s.woff2 +0 -0
  232. package/dist/runtime/web/.next/static/media/8e9860b6e62d6359-s.woff2 +0 -0
  233. package/dist/runtime/web/.next/static/media/ba9851c3c22cd980-s.woff2 +0 -0
  234. package/dist/runtime/web/.next/static/media/c5fe6dc8356a8c31-s.woff2 +0 -0
  235. package/dist/runtime/web/.next/static/media/df0a9ae256c0569c-s.woff2 +0 -0
  236. package/dist/runtime/web/.next/static/media/e4af272ccee01ff0-s.p.woff2 +0 -0
  237. package/dist/runtime/web/package.json +0 -65
  238. package/dist/runtime/web/server.js +0 -44
  239. package/dist/tsconfig.tsbuildinfo +0 -1
package/dist/api.js ADDED
@@ -0,0 +1,43 @@
1
+ // ../api/src/index.ts
2
+ import { readdir } from "node:fs/promises";
3
+ import { createServer } from "node:http";
4
+ import { resolve, normalize } from "node:path";
5
+ var port = Number(process.env.API_PORT ?? 6970);
6
+ var startedAt = Date.now();
7
+ var root = process.cwd();
8
+ var server = createServer(async (req, res) => {
9
+ const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
10
+ if (url.pathname === "/api/health") {
11
+ return sendJson(res, { ok: true, uptimeMs: Date.now() - startedAt, root });
12
+ }
13
+ if (url.pathname === "/api/files") {
14
+ const rawPath = url.searchParams.get("path") ?? ".";
15
+ try {
16
+ const entries = await listFiles(rawPath);
17
+ return sendJson(res, { path: rawPath, entries });
18
+ } catch (error) {
19
+ const message = error instanceof Error ? error.message : "Unable to read directory";
20
+ return sendJson(res, { error: message }, 400);
21
+ }
22
+ }
23
+ res.statusCode = 404;
24
+ res.setHeader("content-type", "text/plain; charset=utf-8");
25
+ res.end("Not found");
26
+ });
27
+ server.listen(port, () => {
28
+ console.log(`API ready on http://localhost:${port}`);
29
+ });
30
+ async function listFiles(pathInput) {
31
+ const target = normalize(resolve(root, pathInput));
32
+ const entries = await readdir(target, { withFileTypes: true });
33
+ return entries.map((entry) => ({
34
+ name: entry.name,
35
+ kind: entry.isDirectory() ? "dir" : entry.isFile() ? "file" : "other"
36
+ }));
37
+ }
38
+ function sendJson(res, payload, status = 200) {
39
+ res.statusCode = status;
40
+ res.setHeader("content-type", "application/json");
41
+ res.setHeader("cache-control", "no-store");
42
+ res.end(JSON.stringify(payload));
43
+ }
package/dist/index.js CHANGED
@@ -1,114 +1,237 @@
1
1
  #!/usr/bin/env node
2
- import { Command } from 'commander';
3
- import path from 'node:path';
4
- import { fileURLToPath } from 'node:url';
5
- import { spawn } from 'node:child_process';
6
- import fs from 'node:fs';
7
- import { createServer } from 'node:net';
8
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
- const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf-8'));
10
- // resolve into apps/cli/dist/runtime/**
11
- const runtime = (...p) => path.join(__dirname, 'runtime', ...p);
12
- // very small logger
13
- const log = {
14
- info: (msg) => console.log(`ℹ️ ${msg}`),
15
- error: (msg, err) => console.error(`❌ ${msg}`, err),
16
- };
17
- // cross-platform npm command
18
- const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
19
- /** test if a TCP port is open on host (localhost by default) */
20
- async function isPortInUse(port, host = 'localhost') {
21
- const hosts = host === 'localhost' ? ['localhost', '127.0.0.1', '0.0.0.0'] : [host];
22
- for (const h of hosts) {
23
- const inUse = await new Promise((resolve) => {
24
- const srv = createServer()
25
- .once('error', () => resolve(true))
26
- .once('listening', () => srv.close(() => resolve(false)))
27
- .listen(port, h);
28
- });
29
- if (inUse)
30
- return true;
31
- }
32
- return false;
2
+
3
+ // src/index.ts
4
+ import { spawn } from "node:child_process";
5
+ import { createReadStream, existsSync } from "node:fs";
6
+ import { stat } from "node:fs/promises";
7
+ import { createServer, request } from "node:http";
8
+ import { request as requestSecure } from "node:https";
9
+ import { basename, dirname, extname, normalize, resolve } from "node:path";
10
+ import { fileURLToPath } from "node:url";
11
+ var args = process.argv.slice(2);
12
+ var command = args[0];
13
+ if (!command || command === "--help" || command === "-h" || command === "help") {
14
+ printHelp();
15
+ process.exit(0);
33
16
  }
34
- /** load ~/.vibeman/.local/settings.json with defaults */
35
- async function loadSettings() {
36
- const defaults = { server: { port: 6969, host: 'localhost', autoOpenBrowser: true } };
37
- try {
38
- const p = path.resolve('.vibeman/.local/settings.json');
39
- if (fs.existsSync(p))
40
- return { ...defaults, ...JSON.parse(fs.readFileSync(p, 'utf8')) };
17
+ if (command !== "start") {
18
+ console.error(`Unknown command: ${command}`);
19
+ printHelp();
20
+ process.exit(1);
21
+ }
22
+ var options = parseStartArgs(args.slice(1));
23
+ await startApps(options);
24
+ function parseStartArgs(argv) {
25
+ const output = {
26
+ path: ".",
27
+ apiPort: 6970,
28
+ uiPort: 6969,
29
+ open: true
30
+ };
31
+ for (let i = 0;i < argv.length; i += 1) {
32
+ const arg = argv[i];
33
+ if (!arg)
34
+ continue;
35
+ if (arg === "--port") {
36
+ const mainPort = Number(argv[i + 1]);
37
+ output.uiPort = mainPort;
38
+ output.apiPort = mainPort + 1;
39
+ i += 1;
40
+ continue;
41
+ }
42
+ if (arg === "--no-open") {
43
+ output.open = false;
44
+ continue;
41
45
  }
42
- catch {
43
- /* ignore */
46
+ if (!arg.startsWith("-") && output.path === ".") {
47
+ output.path = arg;
44
48
  }
45
- return defaults;
49
+ }
50
+ return output;
51
+ }
52
+ async function startApps(options2) {
53
+ const moduleDir = dirname(fileURLToPath(import.meta.url));
54
+ const distRoot = resolveDistRoot(moduleDir);
55
+ const distApi = distRoot ? resolve(distRoot, "api.js") : "";
56
+ const distUiRoot = distRoot ? resolve(distRoot, "ui") : "";
57
+ const nodePath = resolveNodePath();
58
+ if (!distRoot || !existsSync(distApi) || !existsSync(resolve(distUiRoot, "index.html"))) {
59
+ console.error("Missing dist runtime files. Run the build first.");
60
+ process.exit(1);
61
+ }
62
+ const apiProcess = spawn(nodePath, [distApi], {
63
+ cwd: process.cwd(),
64
+ env: {
65
+ ...process.env,
66
+ API_PORT: String(options2.apiPort)
67
+ },
68
+ stdio: "inherit"
69
+ });
70
+ const uiServer = createUiServer({
71
+ apiBase: `http://localhost:${options2.apiPort}`,
72
+ uiRoot: distUiRoot
73
+ });
74
+ uiServer.listen(options2.uiPort, () => {
75
+ console.log(`UI ready on http://localhost:${options2.uiPort}`);
76
+ });
77
+ const url = new URL(`http://localhost:${options2.uiPort}/`);
78
+ url.searchParams.set("path", options2.path);
79
+ if (options2.open) {
80
+ await openBrowser(url.toString());
81
+ }
82
+ console.log(`
83
+ Vibeman running:`);
84
+ console.log(` API: http://localhost:${options2.apiPort}`);
85
+ console.log(` UI: ${url.toString()}`);
86
+ console.log("Press Ctrl+C to stop.");
87
+ const stop = () => {
88
+ apiProcess.kill();
89
+ uiServer.close();
90
+ };
91
+ process.on("SIGINT", () => {
92
+ stop();
93
+ process.exit(0);
94
+ });
95
+ process.on("SIGTERM", () => {
96
+ stop();
97
+ process.exit(0);
98
+ });
99
+ const exitCode = await waitForExit(apiProcess);
100
+ stop();
101
+ process.exit(exitCode ?? 1);
102
+ }
103
+ async function openBrowser(target) {
104
+ const platform = process.platform;
105
+ if (platform === "darwin") {
106
+ spawn("open", [target], { stdio: "ignore", detached: true }).unref();
107
+ return;
108
+ }
109
+ if (platform === "win32") {
110
+ spawn("cmd", ["/c", "start", target], { stdio: "ignore", detached: true }).unref();
111
+ return;
112
+ }
113
+ spawn("xdg-open", [target], { stdio: "ignore", detached: true }).unref();
114
+ }
115
+ function printHelp() {
116
+ console.log(`vibeman CLI
117
+
118
+ Usage:
119
+ vibeman start [path] [--port <port>] [--no-open]
120
+
121
+ Examples:
122
+ vibeman start .
123
+ vibeman start ./notes --port 7010
124
+ `);
125
+ }
126
+ function waitForExit(child) {
127
+ return new Promise((resolvePromise) => {
128
+ child.once("exit", (code) => resolvePromise(code));
129
+ });
46
130
  }
47
- async function startVibeman(targetDir = '.', opts = {}) {
48
- /* ----- resolve project settings & CLI flags ----- */
49
- process.chdir(path.resolve(targetDir));
50
- const cfg = await loadSettings();
51
- const webPort = opts.port ? +opts.port : cfg.server.port;
52
- const host = opts.host || cfg.server.host;
53
- const openBrowser = 'open' in opts ? !!opts.open : cfg.server.autoOpenBrowser;
54
- const apiBasePort = webPort;
55
- const apiListenPort = apiBasePort + 1;
56
- if (await isPortInUse(webPort, host)) {
57
- log.error(`Port ${webPort} is already in use.`);
58
- process.exit(1);
131
+ function resolveDistRoot(selfDir) {
132
+ const execDir = dirname(process.execPath);
133
+ const candidates = [
134
+ selfDir,
135
+ resolve(execDir, ".."),
136
+ resolve(execDir, "../.."),
137
+ resolve(selfDir, ".."),
138
+ resolve(selfDir, "../..")
139
+ ];
140
+ for (const candidate of candidates) {
141
+ if (existsSync(resolve(candidate, "api.js")) && existsSync(resolve(candidate, "ui", "index.html"))) {
142
+ return candidate;
59
143
  }
60
- if (await isPortInUse(apiListenPort, host)) {
61
- log.error(`API port ${apiListenPort} is already in use.`);
62
- process.exit(1);
144
+ }
145
+ return "";
146
+ }
147
+ function resolveNodePath() {
148
+ const execBase = basename(process.execPath);
149
+ return execBase === "node" || execBase === "node.exe" ? process.execPath : "node";
150
+ }
151
+ function createUiServer({ apiBase, uiRoot }) {
152
+ return createServer(async (req, res) => {
153
+ const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
154
+ if (url.pathname.startsWith("/api")) {
155
+ proxyApi(req, res, url, apiBase);
156
+ return;
63
157
  }
64
- /* ----- API server (runtime/api/index.js) ----- */
65
- const apiEntry = runtime('api', 'index.js');
66
- if (!fs.existsSync(apiEntry)) {
67
- log.error('API artefacts missing – did you run `pnpm run build`?');
68
- process.exit(1);
158
+ try {
159
+ const filePath = resolveStaticPath(uiRoot, url.pathname);
160
+ const fileStat = await stat(filePath);
161
+ if (fileStat.isDirectory()) {
162
+ return serveFile(resolve(filePath, "index.html"), res);
163
+ }
164
+ return serveFile(filePath, res);
165
+ } catch {
166
+ return serveFile(resolve(uiRoot, "index.html"), res);
69
167
  }
70
- spawn(process.execPath, [apiEntry], {
71
- stdio: 'inherit',
72
- env: { ...process.env, HOST: host, PORT: String(apiBasePort) },
73
- }).on('error', (e) => {
74
- log.error('Failed to start API server', e);
75
- process.exit(1);
76
- });
77
- /* ----- Web server (runtime/web/standalone/server.js) or dev fallback --- */
78
- const webEntry = runtime('web', 'server.js');
79
- const webProc = spawn(process.execPath, [webEntry], {
80
- stdio: 'inherit',
81
- env: { ...process.env, PORT: String(webPort), HOSTNAME: host },
82
- });
83
- webProc.on('error', (e) => {
84
- log.error('Failed to start web server', e);
85
- process.exit(1);
86
- });
87
- /* ----- optionally open browser --------------------------------------- */
88
- if (openBrowser) {
89
- setTimeout(async () => {
90
- try {
91
- const open = await import('open');
92
- await open.default(`http://${host}:${webPort}`);
93
- }
94
- catch {
95
- log.info(`🌐 Open http://${host}:${webPort} in your browser`);
96
- }
97
- }, 3000);
168
+ });
169
+ }
170
+ function resolveStaticPath(uiRoot, pathname) {
171
+ const normalized = normalize(pathname).replace(/^(\.\.(\/|\\|$))+/, "");
172
+ const target = resolve(uiRoot, normalized.slice(1));
173
+ if (!target.startsWith(uiRoot)) {
174
+ throw new Error("Invalid path");
175
+ }
176
+ return target;
177
+ }
178
+ function serveFile(filePath, res) {
179
+ if (!existsSync(filePath)) {
180
+ res.statusCode = 404;
181
+ res.setHeader("content-type", "text/plain; charset=utf-8");
182
+ res.end("Not found");
183
+ return;
184
+ }
185
+ res.statusCode = 200;
186
+ res.setHeader("content-type", contentType(filePath));
187
+ createReadStream(filePath).pipe(res);
188
+ }
189
+ function contentType(filePath) {
190
+ switch (extname(filePath)) {
191
+ case ".html":
192
+ return "text/html; charset=utf-8";
193
+ case ".js":
194
+ return "text/javascript; charset=utf-8";
195
+ case ".css":
196
+ return "text/css; charset=utf-8";
197
+ case ".json":
198
+ return "application/json; charset=utf-8";
199
+ case ".svg":
200
+ return "image/svg+xml";
201
+ case ".png":
202
+ return "image/png";
203
+ case ".jpg":
204
+ case ".jpeg":
205
+ return "image/jpeg";
206
+ case ".ico":
207
+ return "image/x-icon";
208
+ default:
209
+ return "application/octet-stream";
210
+ }
211
+ }
212
+ function proxyApi(req, res, url, apiBase) {
213
+ const target = new URL(apiBase);
214
+ target.pathname = url.pathname;
215
+ target.search = url.search;
216
+ const isSecure = target.protocol === "https:";
217
+ const proxyRequest = (isSecure ? requestSecure : request)({
218
+ protocol: target.protocol,
219
+ hostname: target.hostname,
220
+ port: target.port,
221
+ method: req.method,
222
+ path: target.pathname + target.search,
223
+ headers: {
224
+ ...req.headers,
225
+ host: target.host
98
226
  }
227
+ }, (proxyRes) => {
228
+ res.writeHead(proxyRes.statusCode ?? 502, proxyRes.headers);
229
+ proxyRes.pipe(res);
230
+ });
231
+ proxyRequest.on("error", (error) => {
232
+ res.statusCode = 502;
233
+ res.setHeader("content-type", "text/plain; charset=utf-8");
234
+ res.end(`Proxy error: ${error instanceof Error ? error.message : "unknown"}`);
235
+ });
236
+ req.pipe(proxyRequest);
99
237
  }
100
- const program = new Command();
101
- program
102
- .name('vibeman')
103
- .description('A Git-native, Markdown-first product-and-task dashboard')
104
- .version(pkg.version);
105
- program
106
- .command('start')
107
- .argument('[dir]', 'Target project directory', '.')
108
- .option('-p, --port <port>', 'Port number')
109
- .option('-H, --host <host>', 'Bind address')
110
- .option('--no-open', 'Do not open browser')
111
- .action((dir, options) => startVibeman(dir, options));
112
- /* default action → same as `start .` */
113
- program.action(() => startVibeman('.', {}));
114
- program.parse();