agor-live 0.3.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 (297) hide show
  1. package/LICENSE +94 -0
  2. package/README.md +163 -0
  3. package/bin/agor-daemon.js +20 -0
  4. package/bin/agor.js +14 -0
  5. package/dist/cli/base-command.d.ts +29 -0
  6. package/dist/cli/base-command.js +41 -0
  7. package/dist/cli/commands/board/add-session.d.ts +15 -0
  8. package/dist/cli/commands/board/add-session.js +102 -0
  9. package/dist/cli/commands/board/list.d.ts +14 -0
  10. package/dist/cli/commands/board/list.js +74 -0
  11. package/dist/cli/commands/config/clear.d.ts +13 -0
  12. package/dist/cli/commands/config/clear.js +21 -0
  13. package/dist/cli/commands/config/get.d.ts +13 -0
  14. package/dist/cli/commands/config/get.js +41 -0
  15. package/dist/cli/commands/config/index.d.ts +13 -0
  16. package/dist/cli/commands/config/index.js +118 -0
  17. package/dist/cli/commands/config/set.d.ts +14 -0
  18. package/dist/cli/commands/config/set.js +50 -0
  19. package/dist/cli/commands/config/unset.d.ts +13 -0
  20. package/dist/cli/commands/config/unset.js +35 -0
  21. package/dist/cli/commands/daemon/index.d.ts +13 -0
  22. package/dist/cli/commands/daemon/index.js +65 -0
  23. package/dist/cli/commands/daemon/logs.d.ts +13 -0
  24. package/dist/cli/commands/daemon/logs.js +78 -0
  25. package/dist/cli/commands/daemon/restart.d.ts +13 -0
  26. package/dist/cli/commands/daemon/restart.js +177 -0
  27. package/dist/cli/commands/daemon/start.d.ts +13 -0
  28. package/dist/cli/commands/daemon/start.js +193 -0
  29. package/dist/cli/commands/daemon/status.d.ts +13 -0
  30. package/dist/cli/commands/daemon/status.js +93 -0
  31. package/dist/cli/commands/daemon/stop.d.ts +13 -0
  32. package/dist/cli/commands/daemon/stop.js +108 -0
  33. package/dist/cli/commands/init.d.ts +44 -0
  34. package/dist/cli/commands/init.js +459 -0
  35. package/dist/cli/commands/mcp/add.d.ts +26 -0
  36. package/dist/cli/commands/mcp/add.js +162 -0
  37. package/dist/cli/commands/mcp/list.d.ts +16 -0
  38. package/dist/cli/commands/mcp/list.js +89 -0
  39. package/dist/cli/commands/mcp/remove.d.ts +17 -0
  40. package/dist/cli/commands/mcp/remove.js +86 -0
  41. package/dist/cli/commands/mcp/show.d.ts +14 -0
  42. package/dist/cli/commands/mcp/show.js +131 -0
  43. package/dist/cli/commands/repo/add.d.ts +16 -0
  44. package/dist/cli/commands/repo/add.js +105 -0
  45. package/dist/cli/commands/repo/list.d.ts +17 -0
  46. package/dist/cli/commands/repo/list.js +99 -0
  47. package/dist/cli/commands/repo/rm.d.ts +17 -0
  48. package/dist/cli/commands/repo/rm.js +126 -0
  49. package/dist/cli/commands/repo/worktree/add.d.ts +21 -0
  50. package/dist/cli/commands/repo/worktree/add.js +145 -0
  51. package/dist/cli/commands/repo/worktree/list.d.ts +21 -0
  52. package/dist/cli/commands/repo/worktree/list.js +136 -0
  53. package/dist/cli/commands/session/list.d.ts +30 -0
  54. package/dist/cli/commands/session/list.js +204 -0
  55. package/dist/cli/commands/session/load-claude.d.ts +16 -0
  56. package/dist/cli/commands/session/load-claude.js +211 -0
  57. package/dist/cli/commands/user/create-admin.d.ts +13 -0
  58. package/dist/cli/commands/user/create-admin.js +65 -0
  59. package/dist/cli/commands/user/create.d.ts +16 -0
  60. package/dist/cli/commands/user/create.js +126 -0
  61. package/dist/cli/commands/user/delete.d.ts +16 -0
  62. package/dist/cli/commands/user/delete.js +77 -0
  63. package/dist/cli/commands/user/list.d.ts +13 -0
  64. package/dist/cli/commands/user/list.js +78 -0
  65. package/dist/cli/commands/user/update.d.ts +19 -0
  66. package/dist/cli/commands/user/update.js +149 -0
  67. package/dist/cli/hooks/command-not-found.d.ts +9 -0
  68. package/dist/cli/hooks/command-not-found.js +14 -0
  69. package/dist/cli/lib/banner.d.ts +25 -0
  70. package/dist/cli/lib/banner.js +25 -0
  71. package/dist/cli/lib/context.d.ts +27 -0
  72. package/dist/cli/lib/context.js +32 -0
  73. package/dist/cli/lib/daemon-manager.d.ts +48 -0
  74. package/dist/cli/lib/daemon-manager.js +109 -0
  75. package/dist/cli/lib/help.d.ts +13 -0
  76. package/dist/cli/lib/help.js +46 -0
  77. package/dist/core/agentic-tool-B_gFNpk5.d.ts +33 -0
  78. package/dist/core/agentic-tool-DsyX8diw.d.cts +33 -0
  79. package/dist/core/api/index.cjs +98 -0
  80. package/dist/core/api/index.d.cts +174 -0
  81. package/dist/core/api/index.d.ts +174 -0
  82. package/dist/core/api/index.js +62 -0
  83. package/dist/core/board-comment-BUm0fpmD.d.cts +134 -0
  84. package/dist/core/board-comment-gC_-twPx.d.ts +134 -0
  85. package/dist/core/claude/index.cjs +673 -0
  86. package/dist/core/claude/index.d.cts +124 -0
  87. package/dist/core/claude/index.d.ts +124 -0
  88. package/dist/core/claude/index.js +629 -0
  89. package/dist/core/config/browser.cjs +165 -0
  90. package/dist/core/config/browser.d.cts +289 -0
  91. package/dist/core/config/browser.d.ts +289 -0
  92. package/dist/core/config/browser.js +131 -0
  93. package/dist/core/config/index.cjs +518 -0
  94. package/dist/core/config/index.d.cts +246 -0
  95. package/dist/core/config/index.d.ts +246 -0
  96. package/dist/core/config/index.js +451 -0
  97. package/dist/core/db/index.cjs +3726 -0
  98. package/dist/core/db/index.d.cts +631 -0
  99. package/dist/core/db/index.d.ts +631 -0
  100. package/dist/core/db/index.js +3649 -0
  101. package/dist/core/dist/agentic-tool-B_gFNpk5.d.ts +33 -0
  102. package/dist/core/dist/agentic-tool-DsyX8diw.d.cts +33 -0
  103. package/dist/core/dist/api/index.cjs +98 -0
  104. package/dist/core/dist/api/index.d.cts +174 -0
  105. package/dist/core/dist/api/index.d.ts +174 -0
  106. package/dist/core/dist/api/index.js +62 -0
  107. package/dist/core/dist/board-comment-BUm0fpmD.d.cts +134 -0
  108. package/dist/core/dist/board-comment-gC_-twPx.d.ts +134 -0
  109. package/dist/core/dist/claude/index.cjs +673 -0
  110. package/dist/core/dist/claude/index.d.cts +124 -0
  111. package/dist/core/dist/claude/index.d.ts +124 -0
  112. package/dist/core/dist/claude/index.js +629 -0
  113. package/dist/core/dist/config/browser.cjs +165 -0
  114. package/dist/core/dist/config/browser.d.cts +289 -0
  115. package/dist/core/dist/config/browser.d.ts +289 -0
  116. package/dist/core/dist/config/browser.js +131 -0
  117. package/dist/core/dist/config/index.cjs +518 -0
  118. package/dist/core/dist/config/index.d.cts +246 -0
  119. package/dist/core/dist/config/index.d.ts +246 -0
  120. package/dist/core/dist/config/index.js +451 -0
  121. package/dist/core/dist/db/index.cjs +3726 -0
  122. package/dist/core/dist/db/index.d.cts +631 -0
  123. package/dist/core/dist/db/index.d.ts +631 -0
  124. package/dist/core/dist/db/index.js +3649 -0
  125. package/dist/core/dist/environment/variable-resolver.cjs +92 -0
  126. package/dist/core/dist/environment/variable-resolver.d.cts +52 -0
  127. package/dist/core/dist/environment/variable-resolver.d.ts +52 -0
  128. package/dist/core/dist/environment/variable-resolver.js +53 -0
  129. package/dist/core/dist/feathers/index.cjs +66 -0
  130. package/dist/core/dist/feathers/index.d.cts +7 -0
  131. package/dist/core/dist/feathers/index.d.ts +7 -0
  132. package/dist/core/dist/feathers/index.js +25 -0
  133. package/dist/core/dist/feathers-BzHEPnpl.d.cts +228 -0
  134. package/dist/core/dist/feathers-BzHEPnpl.d.ts +228 -0
  135. package/dist/core/dist/git/index.cjs +302 -0
  136. package/dist/core/dist/git/index.d.cts +137 -0
  137. package/dist/core/dist/git/index.d.ts +137 -0
  138. package/dist/core/dist/git/index.js +260 -0
  139. package/dist/core/dist/id-DMqyogFB.d.cts +131 -0
  140. package/dist/core/dist/id-DMqyogFB.d.ts +131 -0
  141. package/dist/core/dist/index.cjs +4653 -0
  142. package/dist/core/dist/index.d.cts +23 -0
  143. package/dist/core/dist/index.d.ts +23 -0
  144. package/dist/core/dist/index.js +4509 -0
  145. package/dist/core/dist/message-BoxZISHg.d.cts +120 -0
  146. package/dist/core/dist/message-DvBzHu7V.d.ts +120 -0
  147. package/dist/core/dist/permissions/index.cjs +112 -0
  148. package/dist/core/dist/permissions/index.d.cts +81 -0
  149. package/dist/core/dist/permissions/index.d.ts +81 -0
  150. package/dist/core/dist/permissions/index.js +85 -0
  151. package/dist/core/dist/repo-3CUrCRbq.d.cts +405 -0
  152. package/dist/core/dist/repo-CnvJ0B6-.d.ts +405 -0
  153. package/dist/core/dist/session-BPjJlVdZ.d.cts +429 -0
  154. package/dist/core/dist/session-wAzjHatv.d.ts +429 -0
  155. package/dist/core/dist/task-BIEgT1DK.d.cts +163 -0
  156. package/dist/core/dist/task-DuIfiUbW.d.ts +163 -0
  157. package/dist/core/dist/templates/handlebars-helpers.cjs +156 -0
  158. package/dist/core/dist/templates/handlebars-helpers.d.cts +45 -0
  159. package/dist/core/dist/templates/handlebars-helpers.d.ts +45 -0
  160. package/dist/core/dist/templates/handlebars-helpers.js +119 -0
  161. package/dist/core/dist/tools/claude/models.cjs +70 -0
  162. package/dist/core/dist/tools/claude/models.d.cts +27 -0
  163. package/dist/core/dist/tools/claude/models.d.ts +27 -0
  164. package/dist/core/dist/tools/claude/models.js +44 -0
  165. package/dist/core/dist/tools/index.cjs +3367 -0
  166. package/dist/core/dist/tools/index.d.cts +967 -0
  167. package/dist/core/dist/tools/index.d.ts +967 -0
  168. package/dist/core/dist/tools/index.js +3314 -0
  169. package/dist/core/dist/tools/models.cjs +119 -0
  170. package/dist/core/dist/tools/models.d.cts +47 -0
  171. package/dist/core/dist/tools/models.d.ts +47 -0
  172. package/dist/core/dist/tools/models.js +86 -0
  173. package/dist/core/dist/types/index.cjs +152 -0
  174. package/dist/core/dist/types/index.d.cts +214 -0
  175. package/dist/core/dist/types/index.d.ts +214 -0
  176. package/dist/core/dist/types/index.js +112 -0
  177. package/dist/core/dist/user-BmL3kFol.d.ts +50 -0
  178. package/dist/core/dist/user-eUuKj7yM.d.cts +50 -0
  179. package/dist/core/dist/utils/pricing.cjs +102 -0
  180. package/dist/core/dist/utils/pricing.d.cts +43 -0
  181. package/dist/core/dist/utils/pricing.d.ts +43 -0
  182. package/dist/core/dist/utils/pricing.js +75 -0
  183. package/dist/core/dist/worktrees-BzIxB1U6.d.cts +2745 -0
  184. package/dist/core/dist/worktrees-CYem1ya2.d.ts +2745 -0
  185. package/dist/core/environment/variable-resolver.cjs +92 -0
  186. package/dist/core/environment/variable-resolver.d.cts +52 -0
  187. package/dist/core/environment/variable-resolver.d.ts +52 -0
  188. package/dist/core/environment/variable-resolver.js +53 -0
  189. package/dist/core/feathers/index.cjs +66 -0
  190. package/dist/core/feathers/index.d.cts +7 -0
  191. package/dist/core/feathers/index.d.ts +7 -0
  192. package/dist/core/feathers/index.js +25 -0
  193. package/dist/core/feathers-BzHEPnpl.d.cts +228 -0
  194. package/dist/core/feathers-BzHEPnpl.d.ts +228 -0
  195. package/dist/core/git/index.cjs +302 -0
  196. package/dist/core/git/index.d.cts +137 -0
  197. package/dist/core/git/index.d.ts +137 -0
  198. package/dist/core/git/index.js +260 -0
  199. package/dist/core/id-DMqyogFB.d.cts +131 -0
  200. package/dist/core/id-DMqyogFB.d.ts +131 -0
  201. package/dist/core/index.cjs +4653 -0
  202. package/dist/core/index.d.cts +23 -0
  203. package/dist/core/index.d.ts +23 -0
  204. package/dist/core/index.js +4509 -0
  205. package/dist/core/message-BoxZISHg.d.cts +120 -0
  206. package/dist/core/message-DvBzHu7V.d.ts +120 -0
  207. package/dist/core/package.json +133 -0
  208. package/dist/core/permissions/index.cjs +112 -0
  209. package/dist/core/permissions/index.d.cts +81 -0
  210. package/dist/core/permissions/index.d.ts +81 -0
  211. package/dist/core/permissions/index.js +85 -0
  212. package/dist/core/repo-3CUrCRbq.d.cts +405 -0
  213. package/dist/core/repo-CnvJ0B6-.d.ts +405 -0
  214. package/dist/core/session-BPjJlVdZ.d.cts +429 -0
  215. package/dist/core/session-wAzjHatv.d.ts +429 -0
  216. package/dist/core/task-BIEgT1DK.d.cts +163 -0
  217. package/dist/core/task-DuIfiUbW.d.ts +163 -0
  218. package/dist/core/templates/handlebars-helpers.cjs +156 -0
  219. package/dist/core/templates/handlebars-helpers.d.cts +45 -0
  220. package/dist/core/templates/handlebars-helpers.d.ts +45 -0
  221. package/dist/core/templates/handlebars-helpers.js +119 -0
  222. package/dist/core/tools/claude/models.cjs +70 -0
  223. package/dist/core/tools/claude/models.d.cts +27 -0
  224. package/dist/core/tools/claude/models.d.ts +27 -0
  225. package/dist/core/tools/claude/models.js +44 -0
  226. package/dist/core/tools/index.cjs +3367 -0
  227. package/dist/core/tools/index.d.cts +967 -0
  228. package/dist/core/tools/index.d.ts +967 -0
  229. package/dist/core/tools/index.js +3314 -0
  230. package/dist/core/tools/models.cjs +119 -0
  231. package/dist/core/tools/models.d.cts +47 -0
  232. package/dist/core/tools/models.d.ts +47 -0
  233. package/dist/core/tools/models.js +86 -0
  234. package/dist/core/types/index.cjs +152 -0
  235. package/dist/core/types/index.d.cts +214 -0
  236. package/dist/core/types/index.d.ts +214 -0
  237. package/dist/core/types/index.js +112 -0
  238. package/dist/core/user-BmL3kFol.d.ts +50 -0
  239. package/dist/core/user-eUuKj7yM.d.cts +50 -0
  240. package/dist/core/utils/pricing.cjs +102 -0
  241. package/dist/core/utils/pricing.d.cts +43 -0
  242. package/dist/core/utils/pricing.d.ts +43 -0
  243. package/dist/core/utils/pricing.js +75 -0
  244. package/dist/core/worktrees-BzIxB1U6.d.cts +2745 -0
  245. package/dist/core/worktrees-CYem1ya2.d.ts +2745 -0
  246. package/dist/daemon/adapters/drizzle.d.ts +114 -0
  247. package/dist/daemon/adapters/drizzle.js +219 -0
  248. package/dist/daemon/declarations.d.ts +101 -0
  249. package/dist/daemon/declarations.js +0 -0
  250. package/dist/daemon/index.d.ts +2 -0
  251. package/dist/daemon/index.js +4093 -0
  252. package/dist/daemon/mcp/routes.d.ts +15 -0
  253. package/dist/daemon/mcp/routes.js +641 -0
  254. package/dist/daemon/mcp/tokens.d.ts +50 -0
  255. package/dist/daemon/mcp/tokens.js +85 -0
  256. package/dist/daemon/services/board-comments.d.ts +97 -0
  257. package/dist/daemon/services/board-comments.js +326 -0
  258. package/dist/daemon/services/board-objects.d.ts +71 -0
  259. package/dist/daemon/services/board-objects.js +117 -0
  260. package/dist/daemon/services/boards.d.ts +64 -0
  261. package/dist/daemon/services/boards.js +286 -0
  262. package/dist/daemon/services/config.d.ts +35 -0
  263. package/dist/daemon/services/config.js +68 -0
  264. package/dist/daemon/services/context.d.ts +55 -0
  265. package/dist/daemon/services/context.js +113 -0
  266. package/dist/daemon/services/health-monitor.d.ts +58 -0
  267. package/dist/daemon/services/health-monitor.js +158 -0
  268. package/dist/daemon/services/mcp-servers.d.ts +42 -0
  269. package/dist/daemon/services/mcp-servers.js +275 -0
  270. package/dist/daemon/services/messages.d.ts +49 -0
  271. package/dist/daemon/services/messages.js +269 -0
  272. package/dist/daemon/services/repos.d.ts +61 -0
  273. package/dist/daemon/services/repos.js +350 -0
  274. package/dist/daemon/services/session-mcp-servers.d.ts +56 -0
  275. package/dist/daemon/services/session-mcp-servers.js +51 -0
  276. package/dist/daemon/services/sessions.d.ts +64 -0
  277. package/dist/daemon/services/sessions.js +398 -0
  278. package/dist/daemon/services/tasks.d.ts +55 -0
  279. package/dist/daemon/services/tasks.js +318 -0
  280. package/dist/daemon/services/terminals.d.ts +75 -0
  281. package/dist/daemon/services/terminals.js +110 -0
  282. package/dist/daemon/services/users.d.ts +98 -0
  283. package/dist/daemon/services/users.js +177 -0
  284. package/dist/daemon/services/worktrees.d.ts +98 -0
  285. package/dist/daemon/services/worktrees.js +719 -0
  286. package/dist/daemon/strategies/anonymous.d.ts +20 -0
  287. package/dist/daemon/strategies/anonymous.js +32 -0
  288. package/dist/ui/assets/cc-CYmbalCD.png +0 -0
  289. package/dist/ui/assets/codex-4sLD1mVS.png +0 -0
  290. package/dist/ui/assets/cursor-BUy5pFVL.png +0 -0
  291. package/dist/ui/assets/gemini-ajOb7iAl.png +0 -0
  292. package/dist/ui/assets/index-Dc4ELxry.css +32 -0
  293. package/dist/ui/assets/index-KfIu8v4V.js +578 -0
  294. package/dist/ui/favicon.png +0 -0
  295. package/dist/ui/index.html +26 -0
  296. package/dist/ui/vite.svg +1 -0
  297. package/package.json +90 -0
@@ -0,0 +1,459 @@
1
+ // src/commands/init.ts
2
+ import { access, constants, mkdir, readdir, rm } from "fs/promises";
3
+ import { homedir } from "os";
4
+ import { join } from "path";
5
+ import { setConfigValue } from "@agor/core/config";
6
+ import { createDatabase, createUser, initializeDatabase, seedInitialData } from "@agor/core/db";
7
+ import { Command, Flags } from "@oclif/core";
8
+ import chalk from "chalk";
9
+ import inquirer from "inquirer";
10
+ var Init = class _Init extends Command {
11
+ static description = "Initialize Agor environment (creates ~/.agor/ and database)";
12
+ static examples = [
13
+ "<%= config.bin %> <%= command.id %>",
14
+ "<%= config.bin %> <%= command.id %> --local"
15
+ ];
16
+ static flags = {
17
+ local: Flags.boolean({
18
+ char: "l",
19
+ description: "Initialize local .agor/ directory in current working directory",
20
+ default: false
21
+ }),
22
+ force: Flags.boolean({
23
+ char: "f",
24
+ description: "Force re-initialization without prompts (deletes database, repos, and worktrees)",
25
+ default: false
26
+ })
27
+ };
28
+ async pathExists(path) {
29
+ try {
30
+ await access(path, constants.F_OK);
31
+ return true;
32
+ } catch {
33
+ return false;
34
+ }
35
+ }
36
+ expandHome(path) {
37
+ if (path.startsWith("~/")) {
38
+ return join(homedir(), path.slice(2));
39
+ }
40
+ return path;
41
+ }
42
+ /**
43
+ * Count rows in database tables for display
44
+ */
45
+ async getDbStats(dbPath) {
46
+ try {
47
+ const { createDatabase: createDatabase2, sessions, tasks, messages, repos } = await import("@agor/core/db");
48
+ const db = createDatabase2({ url: `file:${dbPath}` });
49
+ const sessionRows = await db.select({ id: sessions.session_id }).from(sessions).all();
50
+ const taskRows = await db.select({ id: tasks.task_id }).from(tasks).all();
51
+ const messageRows = await db.select({ id: messages.message_id }).from(messages).all();
52
+ const repoRows = await db.select({ id: repos.repo_id }).from(repos).all();
53
+ return {
54
+ sessions: sessionRows.length,
55
+ tasks: taskRows.length,
56
+ messages: messageRows.length,
57
+ repos: repoRows.length
58
+ };
59
+ } catch {
60
+ return null;
61
+ }
62
+ }
63
+ /**
64
+ * List directories in a path (repos, worktrees)
65
+ */
66
+ async listDirs(path) {
67
+ try {
68
+ const entries = await readdir(path, { withFileTypes: true });
69
+ return entries.filter((e) => e.isDirectory()).map((e) => e.name);
70
+ } catch {
71
+ return [];
72
+ }
73
+ }
74
+ /**
75
+ * Detect if running in GitHub Codespaces
76
+ */
77
+ isCodespaces() {
78
+ return process.env.CODESPACES === "true" || process.env.CODESPACE_NAME !== void 0;
79
+ }
80
+ async run() {
81
+ const { flags } = await this.parse(_Init);
82
+ this.log("\u2728 Initializing Agor...\n");
83
+ if (this.isCodespaces() && !flags.force) {
84
+ this.log(chalk.cyan.bold("\u{1F680} GitHub Codespaces detected!\n"));
85
+ this.log(chalk.yellow("\u26A0\uFE0F Sandbox Mode:"));
86
+ this.log(" - Data persists only while Codespace is active");
87
+ this.log(" - Stopped Codespaces retain data for 30 days");
88
+ this.log(" - Rebuilt Codespaces lose all data\n");
89
+ this.log(chalk.dim("For production use, install Agor locally:"));
90
+ this.log(chalk.dim(" https://github.com/mistercrunch/agor#installation\n"));
91
+ }
92
+ try {
93
+ const baseDir = flags.local ? join(process.cwd(), ".agor") : join(homedir(), ".agor");
94
+ const dbPath = join(baseDir, "agor.db");
95
+ const reposDir = join(baseDir, "repos");
96
+ const worktreesDir = join(baseDir, "worktrees");
97
+ const alreadyExists = await this.pathExists(baseDir);
98
+ const dbExists = await this.pathExists(dbPath);
99
+ const reposExist = await this.pathExists(reposDir);
100
+ const worktreesExist = await this.pathExists(worktreesDir);
101
+ if (!alreadyExists) {
102
+ await this.performInit(baseDir, dbPath, flags.force);
103
+ return;
104
+ }
105
+ this.log(chalk.yellow("\u26A0 Agor is already initialized at: ") + chalk.cyan(baseDir));
106
+ this.log("");
107
+ const dbStats = dbExists ? await this.getDbStats(dbPath) : null;
108
+ const repos = reposExist ? await this.listDirs(reposDir) : [];
109
+ const worktrees = worktreesExist ? await this.listDirs(worktreesDir) : [];
110
+ this.log(chalk.bold.red("\u26A0 Re-initialization will delete:"));
111
+ this.log("");
112
+ if (dbExists && dbStats) {
113
+ this.log(`${chalk.cyan(" Database:")} ${dbPath}`);
114
+ this.log(
115
+ chalk.dim(
116
+ ` ${dbStats.sessions} sessions, ${dbStats.tasks} tasks, ${dbStats.messages} messages, ${dbStats.repos} repos`
117
+ )
118
+ );
119
+ } else if (dbExists) {
120
+ this.log(`${chalk.cyan(" Database:")} ${dbPath}`);
121
+ }
122
+ if (repos.length > 0) {
123
+ this.log(`${chalk.cyan(" Repos:")} ${reposDir}`);
124
+ for (const repo of repos.slice(0, 5)) {
125
+ this.log(chalk.dim(` - ${repo}`));
126
+ }
127
+ if (repos.length > 5) {
128
+ this.log(chalk.dim(` ... and ${repos.length - 5} more`));
129
+ }
130
+ }
131
+ if (worktrees.length > 0) {
132
+ this.log(`${chalk.cyan(" Worktrees:")} ${worktreesDir}`);
133
+ for (const wt of worktrees.slice(0, 5)) {
134
+ this.log(chalk.dim(` - ${wt}`));
135
+ }
136
+ if (worktrees.length > 5) {
137
+ this.log(chalk.dim(` ... and ${worktrees.length - 5} more`));
138
+ }
139
+ }
140
+ this.log("");
141
+ if (flags.force) {
142
+ this.log(chalk.yellow("\u{1F5D1}\uFE0F --force flag set: deleting everything without prompts..."));
143
+ await this.cleanupExisting(baseDir, dbPath, reposDir, worktreesDir);
144
+ await this.performInit(baseDir, dbPath, true);
145
+ return;
146
+ }
147
+ const { confirmed } = await inquirer.prompt([
148
+ {
149
+ type: "confirm",
150
+ name: "confirmed",
151
+ message: "Delete all existing data and re-initialize?",
152
+ default: false
153
+ }
154
+ ]);
155
+ if (!confirmed) {
156
+ this.log(chalk.dim("Cancelled. Use --force to skip this prompt."));
157
+ process.exit(0);
158
+ return;
159
+ }
160
+ await this.cleanupExisting(baseDir, dbPath, reposDir, worktreesDir);
161
+ await this.performInit(baseDir, dbPath, false);
162
+ } catch (error) {
163
+ this.error(
164
+ `Failed to initialize Agor: ${error instanceof Error ? error.message : String(error)}`
165
+ );
166
+ }
167
+ }
168
+ /**
169
+ * Clean up existing installation
170
+ */
171
+ async cleanupExisting(_baseDir, dbPath, reposDir, worktreesDir) {
172
+ this.log("");
173
+ this.log("\u{1F5D1}\uFE0F Cleaning up existing installation...");
174
+ if (await this.pathExists(dbPath)) {
175
+ await rm(dbPath, { force: true });
176
+ this.log(`${chalk.green(" \u2713")} Deleted database`);
177
+ }
178
+ if (await this.pathExists(reposDir)) {
179
+ await rm(reposDir, { recursive: true, force: true });
180
+ this.log(`${chalk.green(" \u2713")} Deleted repos`);
181
+ }
182
+ if (await this.pathExists(worktreesDir)) {
183
+ await rm(worktreesDir, { recursive: true, force: true });
184
+ this.log(`${chalk.green(" \u2713")} Deleted worktrees`);
185
+ }
186
+ }
187
+ /**
188
+ * Perform fresh initialization
189
+ */
190
+ async performInit(baseDir, dbPath, skipPrompts = false) {
191
+ this.log("");
192
+ this.log("\u{1F4C1} Creating directory structure...");
193
+ const dirs = [
194
+ baseDir,
195
+ join(baseDir, "repos"),
196
+ join(baseDir, "worktrees"),
197
+ join(baseDir, "concepts"),
198
+ join(baseDir, "logs")
199
+ ];
200
+ for (const dir of dirs) {
201
+ await mkdir(dir, { recursive: true });
202
+ this.log(`${chalk.green(" \u2713")} ${dir}`);
203
+ }
204
+ this.log("");
205
+ this.log("\u{1F4BE} Setting up database...");
206
+ const db = createDatabase({ url: `file:${dbPath}` });
207
+ await initializeDatabase(db);
208
+ this.log(`${chalk.green(" \u2713")} Created ${dbPath}`);
209
+ this.log("");
210
+ this.log("\u{1F331} Seeding initial data...");
211
+ await seedInitialData(db);
212
+ this.log(`${chalk.green(" \u2713")} Created Main Board`);
213
+ if (!skipPrompts) {
214
+ await this.promptAuthSetup(dbPath);
215
+ await this.promptApiKeys();
216
+ }
217
+ this.log("");
218
+ this.log(chalk.green.bold("\u2705 Agor initialized successfully!"));
219
+ this.log("");
220
+ this.log(` Database: ${chalk.cyan(dbPath)}`);
221
+ this.log(` Repos: ${chalk.cyan(join(baseDir, "repos"))}`);
222
+ this.log(` Worktrees: ${chalk.cyan(join(baseDir, "worktrees"))}`);
223
+ this.log(` Concepts: ${chalk.cyan(join(baseDir, "concepts"))}`);
224
+ this.log(` Logs: ${chalk.cyan(join(baseDir, "logs"))}`);
225
+ this.log("");
226
+ if (this.isCodespaces()) {
227
+ this.log(chalk.bold("\u{1F4DD} API Key Setup (Optional):"));
228
+ this.log("");
229
+ this.log("To use AI agents (Claude, Gemini, etc.), set API keys:");
230
+ this.log("");
231
+ this.log(chalk.cyan("1. Environment variables (recommended for Codespaces):"));
232
+ this.log(' export ANTHROPIC_API_KEY="sk-ant-..."');
233
+ this.log(' export OPENAI_API_KEY="sk-..."');
234
+ this.log(' export GOOGLE_AI_API_KEY="..."');
235
+ this.log("");
236
+ this.log(chalk.cyan("2. Codespaces Secrets (persistent across rebuilds):"));
237
+ this.log(" GitHub \u2192 Settings \u2192 Codespaces \u2192 Secrets");
238
+ this.log(" Add keys there and rebuild Codespace");
239
+ this.log("");
240
+ this.log(chalk.yellow("\u{1F4A1} Tip: To preserve your work:"));
241
+ this.log(" - Keep Codespace active (auto-stops after 30 min idle)");
242
+ this.log(" - Export important sessions before stopping");
243
+ this.log(" - Use git to commit session transcripts");
244
+ this.log("");
245
+ }
246
+ this.log(chalk.bold("Next steps:"));
247
+ this.log(" - Run 'agor daemon' to start the daemon");
248
+ this.log(" - Run 'agor session list' to view all sessions");
249
+ this.log("");
250
+ }
251
+ /**
252
+ * Prompt user for auth/multiplayer setup
253
+ */
254
+ async promptAuthSetup(dbPath) {
255
+ this.log("");
256
+ const { enableAuth } = await inquirer.prompt([
257
+ {
258
+ type: "confirm",
259
+ name: "enableAuth",
260
+ message: "Enable authentication and multiplayer features?",
261
+ default: false
262
+ }
263
+ ]);
264
+ if (!enableAuth) {
265
+ this.log(chalk.gray("Authentication disabled. Running in single-user mode."));
266
+ this.log("");
267
+ this.log(chalk.gray("You can enable auth later with:"));
268
+ this.log(chalk.gray(" agor config set daemon.requireAuth true"));
269
+ this.log(chalk.gray(" agor user create-admin"));
270
+ return;
271
+ }
272
+ await setConfigValue("daemon.requireAuth", true);
273
+ await setConfigValue("daemon.allowAnonymous", false);
274
+ this.log(`${chalk.green(" \u2713")} Enabled authentication`);
275
+ this.log("");
276
+ const { createAdmin } = await inquirer.prompt([
277
+ {
278
+ type: "confirm",
279
+ name: "createAdmin",
280
+ message: "Create an admin user?",
281
+ default: true
282
+ }
283
+ ]);
284
+ if (!createAdmin) {
285
+ this.log("");
286
+ this.log(chalk.yellow("\u26A0 You must create an admin user before starting the daemon:"));
287
+ this.log(chalk.gray(" agor user create-admin"));
288
+ return;
289
+ }
290
+ const { email, username, password } = await inquirer.prompt([
291
+ {
292
+ type: "input",
293
+ name: "email",
294
+ message: "Email:",
295
+ validate: (input) => {
296
+ if (!input || !input.includes("@")) {
297
+ return "Please enter a valid email address";
298
+ }
299
+ return true;
300
+ }
301
+ },
302
+ {
303
+ type: "input",
304
+ name: "username",
305
+ message: "Username:",
306
+ validate: (input) => {
307
+ if (!input || input.length < 2) {
308
+ return "Username must be at least 2 characters";
309
+ }
310
+ return true;
311
+ }
312
+ },
313
+ {
314
+ type: "password",
315
+ name: "password",
316
+ message: "Password:",
317
+ mask: "*",
318
+ validate: (input) => {
319
+ if (!input || input.length < 4) {
320
+ return "Password must be at least 4 characters";
321
+ }
322
+ return true;
323
+ }
324
+ }
325
+ ]);
326
+ try {
327
+ const db = createDatabase({ url: `file:${dbPath}` });
328
+ const user = await createUser(db, {
329
+ email,
330
+ password,
331
+ name: username,
332
+ role: "admin"
333
+ });
334
+ this.log(
335
+ chalk.green(" \u2713") + ` Admin user created successfully (ID: ${chalk.gray(user.user_id.substring(0, 8))})`
336
+ );
337
+ } catch (error) {
338
+ this.log("");
339
+ this.log(chalk.red("\u2717 Failed to create admin user"));
340
+ if (error instanceof Error) {
341
+ this.log(chalk.red(` ${error.message}`));
342
+ }
343
+ this.log("");
344
+ this.log(chalk.gray("You can create an admin user later with:"));
345
+ this.log(chalk.gray(" agor user create-admin"));
346
+ }
347
+ }
348
+ /**
349
+ * Prompt user for API key setup
350
+ */
351
+ async promptApiKeys() {
352
+ this.log("");
353
+ this.log(chalk.bold("\u{1F511} API Key Setup"));
354
+ this.log("");
355
+ this.log(chalk.gray("Configure API keys for AI agents (optional, can be set later)"));
356
+ this.log("");
357
+ const { setupKeys } = await inquirer.prompt([
358
+ {
359
+ type: "confirm",
360
+ name: "setupKeys",
361
+ message: "Set up API keys now?",
362
+ default: false
363
+ }
364
+ ]);
365
+ if (!setupKeys) {
366
+ this.log("");
367
+ this.log(chalk.gray("Skipped. You can set API keys later with:"));
368
+ this.log(chalk.gray(' agor config set credentials.ANTHROPIC_API_KEY "sk-ant-..."'));
369
+ this.log(chalk.gray(' agor config set credentials.OPENAI_API_KEY "sk-..."'));
370
+ this.log(chalk.gray(' agor config set credentials.GEMINI_API_KEY "..."'));
371
+ return;
372
+ }
373
+ const { setupAnthropic } = await inquirer.prompt([
374
+ {
375
+ type: "confirm",
376
+ name: "setupAnthropic",
377
+ message: "Set up Anthropic API key (for Claude Code)?",
378
+ default: true
379
+ }
380
+ ]);
381
+ if (setupAnthropic) {
382
+ const { anthropicKey } = await inquirer.prompt([
383
+ {
384
+ type: "password",
385
+ name: "anthropicKey",
386
+ message: "Anthropic API key (sk-ant-...):",
387
+ mask: "*",
388
+ validate: (input) => {
389
+ if (!input || input.length < 10) {
390
+ return "Please enter a valid API key";
391
+ }
392
+ return true;
393
+ }
394
+ }
395
+ ]);
396
+ await setConfigValue("credentials.ANTHROPIC_API_KEY", anthropicKey);
397
+ this.log(chalk.green(" \u2713") + " Anthropic API key saved");
398
+ }
399
+ const { setupOpenAI } = await inquirer.prompt([
400
+ {
401
+ type: "confirm",
402
+ name: "setupOpenAI",
403
+ message: "Set up OpenAI API key (for Codex)?",
404
+ default: false
405
+ }
406
+ ]);
407
+ if (setupOpenAI) {
408
+ const { openaiKey } = await inquirer.prompt([
409
+ {
410
+ type: "password",
411
+ name: "openaiKey",
412
+ message: "OpenAI API key (sk-...):",
413
+ mask: "*",
414
+ validate: (input) => {
415
+ if (!input || input.length < 10) {
416
+ return "Please enter a valid API key";
417
+ }
418
+ return true;
419
+ }
420
+ }
421
+ ]);
422
+ await setConfigValue("credentials.OPENAI_API_KEY", openaiKey);
423
+ this.log(chalk.green(" \u2713") + " OpenAI API key saved");
424
+ }
425
+ const { setupGemini } = await inquirer.prompt([
426
+ {
427
+ type: "confirm",
428
+ name: "setupGemini",
429
+ message: "Set up Google Gemini API key?",
430
+ default: false
431
+ }
432
+ ]);
433
+ if (setupGemini) {
434
+ const { geminiKey } = await inquirer.prompt([
435
+ {
436
+ type: "password",
437
+ name: "geminiKey",
438
+ message: "Google Gemini API key:",
439
+ mask: "*",
440
+ validate: (input) => {
441
+ if (!input || input.length < 10) {
442
+ return "Please enter a valid API key";
443
+ }
444
+ return true;
445
+ }
446
+ }
447
+ ]);
448
+ await setConfigValue("credentials.GEMINI_API_KEY", geminiKey);
449
+ this.log(chalk.green(" \u2713") + " Gemini API key saved");
450
+ }
451
+ this.log("");
452
+ this.log(
453
+ chalk.gray("Note: API keys are stored in ~/.agor/config.yaml (keep this file secure!)")
454
+ );
455
+ }
456
+ };
457
+ export {
458
+ Init as default
459
+ };
@@ -0,0 +1,26 @@
1
+ import * as _oclif_core_interfaces from '@oclif/core/interfaces';
2
+ import { Command } from '@oclif/core';
3
+
4
+ declare class McpAdd extends Command {
5
+ static description: string;
6
+ static examples: string[];
7
+ static args: {
8
+ name: _oclif_core_interfaces.Arg<string, Record<string, unknown>>;
9
+ };
10
+ static flags: {
11
+ transport: _oclif_core_interfaces.OptionFlag<string, _oclif_core_interfaces.CustomOptions>;
12
+ command: _oclif_core_interfaces.OptionFlag<string | undefined, _oclif_core_interfaces.CustomOptions>;
13
+ args: _oclif_core_interfaces.OptionFlag<string | undefined, _oclif_core_interfaces.CustomOptions>;
14
+ url: _oclif_core_interfaces.OptionFlag<string | undefined, _oclif_core_interfaces.CustomOptions>;
15
+ scope: _oclif_core_interfaces.OptionFlag<string, _oclif_core_interfaces.CustomOptions>;
16
+ 'session-id': _oclif_core_interfaces.OptionFlag<string | undefined, _oclif_core_interfaces.CustomOptions>;
17
+ 'repo-id': _oclif_core_interfaces.OptionFlag<string | undefined, _oclif_core_interfaces.CustomOptions>;
18
+ 'display-name': _oclif_core_interfaces.OptionFlag<string | undefined, _oclif_core_interfaces.CustomOptions>;
19
+ description: _oclif_core_interfaces.OptionFlag<string | undefined, _oclif_core_interfaces.CustomOptions>;
20
+ enabled: _oclif_core_interfaces.BooleanFlag<boolean>;
21
+ env: _oclif_core_interfaces.OptionFlag<string | undefined, _oclif_core_interfaces.CustomOptions>;
22
+ };
23
+ run(): Promise<void>;
24
+ }
25
+
26
+ export { McpAdd as default };
@@ -0,0 +1,162 @@
1
+ // src/commands/mcp/add.ts
2
+ import { createClient, isDaemonRunning } from "@agor/core/api";
3
+ import { getDaemonUrl } from "@agor/core/config";
4
+ import { Args, Command, Flags } from "@oclif/core";
5
+ import chalk from "chalk";
6
+ var McpAdd = class _McpAdd extends Command {
7
+ static description = "Add a new MCP server";
8
+ static examples = [
9
+ '<%= config.bin %> <%= command.id %> filesystem --command npx --args "@modelcontextprotocol/server-filesystem,/path/to/allowed"',
10
+ "<%= config.bin %> <%= command.id %> sentry --transport http --url https://mcp.sentry.dev/mcp",
11
+ '<%= config.bin %> <%= command.id %> custom-tool --command node --args "dist/server.js" --scope session --session-id 0199b856'
12
+ ];
13
+ static args = {
14
+ name: Args.string({
15
+ description: "MCP server name (e.g., filesystem, sentry, custom-tool)",
16
+ required: true
17
+ })
18
+ };
19
+ static flags = {
20
+ transport: Flags.string({
21
+ char: "t",
22
+ description: "Transport type",
23
+ options: ["stdio", "http", "sse"],
24
+ default: "stdio"
25
+ }),
26
+ command: Flags.string({
27
+ char: "c",
28
+ description: "Command to run (for stdio transport)"
29
+ }),
30
+ args: Flags.string({
31
+ char: "a",
32
+ description: "Command arguments (comma-separated)"
33
+ }),
34
+ url: Flags.string({
35
+ char: "u",
36
+ description: "Server URL (for http/sse transport)"
37
+ }),
38
+ scope: Flags.string({
39
+ char: "s",
40
+ description: "Server scope",
41
+ options: ["global", "team", "repo", "session"],
42
+ default: "global"
43
+ }),
44
+ "session-id": Flags.string({
45
+ description: "Session ID (required if scope=session)"
46
+ }),
47
+ "repo-id": Flags.string({
48
+ description: "Repo ID (required if scope=repo)"
49
+ }),
50
+ "display-name": Flags.string({
51
+ char: "d",
52
+ description: "Display name for the server"
53
+ }),
54
+ description: Flags.string({
55
+ description: "Server description"
56
+ }),
57
+ enabled: Flags.boolean({
58
+ description: "Enable server immediately",
59
+ default: true
60
+ }),
61
+ env: Flags.string({
62
+ char: "e",
63
+ description: "Environment variables (key=value pairs, comma-separated)"
64
+ })
65
+ };
66
+ async run() {
67
+ const { args, flags } = await this.parse(_McpAdd);
68
+ const daemonUrl = await getDaemonUrl();
69
+ const running = await isDaemonRunning(daemonUrl);
70
+ if (!running) {
71
+ this.error(
72
+ `Daemon not running. Start it with: ${chalk.cyan("cd apps/agor-daemon && pnpm dev")}`
73
+ );
74
+ }
75
+ if (flags.transport === "stdio" && !flags.command) {
76
+ this.error("--command is required for stdio transport");
77
+ }
78
+ if ((flags.transport === "http" || flags.transport === "sse") && !flags.url) {
79
+ this.error("--url is required for http/sse transport");
80
+ }
81
+ if (flags.scope === "session" && !flags["session-id"]) {
82
+ this.error("--session-id is required when scope=session");
83
+ }
84
+ if (flags.scope === "repo" && !flags["repo-id"]) {
85
+ this.error("--repo-id is required when scope=repo");
86
+ }
87
+ try {
88
+ this.log("");
89
+ this.log(chalk.bold(`Adding MCP server ${chalk.cyan(args.name)}...`));
90
+ const data = {
91
+ name: args.name,
92
+ display_name: flags["display-name"],
93
+ description: flags.description,
94
+ transport: flags.transport,
95
+ scope: flags.scope,
96
+ enabled: flags.enabled,
97
+ source: "user"
98
+ };
99
+ if (flags.command) data.command = flags.command;
100
+ if (flags.args) data.args = flags.args.split(",").map((arg) => arg.trim());
101
+ if (flags.url) data.url = flags.url;
102
+ if (flags.env) {
103
+ const envPairs = flags.env.split(",").map((pair) => pair.trim());
104
+ const envObject = {};
105
+ for (const pair of envPairs) {
106
+ const [key, value] = pair.split("=");
107
+ if (key && value) {
108
+ envObject[key.trim()] = value.trim();
109
+ }
110
+ }
111
+ if (Object.keys(envObject).length > 0) {
112
+ data.env = envObject;
113
+ }
114
+ }
115
+ if (flags["session-id"]) data.session_id = flags["session-id"];
116
+ if (flags["repo-id"]) data.repo_id = flags["repo-id"];
117
+ const client = createClient(daemonUrl);
118
+ const server = await client.service("mcp-servers").create(data);
119
+ this.log(`${chalk.green("\u2713")} MCP server added`);
120
+ this.log("");
121
+ this.log(chalk.bold("Server Details:"));
122
+ this.log(` ${chalk.cyan("ID")}: ${String(server.mcp_server_id).substring(0, 8)}`);
123
+ this.log(` ${chalk.cyan("Name")}: ${server.name}`);
124
+ this.log(` ${chalk.cyan("Transport")}: ${server.transport}`);
125
+ this.log(` ${chalk.cyan("Scope")}: ${server.scope}`);
126
+ this.log(
127
+ ` ${chalk.cyan("Enabled")}: ${server.enabled ? chalk.green("\u2713") : chalk.gray("\u2717")}`
128
+ );
129
+ if (server.command) {
130
+ this.log(` ${chalk.cyan("Command")}: ${server.command}`);
131
+ }
132
+ if (server.args) {
133
+ this.log(` ${chalk.cyan("Args")}: ${server.args.join(", ")}`);
134
+ }
135
+ if (server.url) {
136
+ this.log(` ${chalk.cyan("URL")}: ${server.url}`);
137
+ }
138
+ if (server.env) {
139
+ const envKeys = Object.keys(server.env);
140
+ this.log(` ${chalk.cyan("Environment")}: ${envKeys.join(", ")}`);
141
+ }
142
+ this.log("");
143
+ await new Promise((resolve) => {
144
+ client.io.once("disconnect", () => resolve());
145
+ client.io.close();
146
+ setTimeout(() => resolve(), 1e3);
147
+ });
148
+ process.exit(0);
149
+ } catch (error) {
150
+ const message = error instanceof Error ? error.message : String(error);
151
+ this.log("");
152
+ this.log(chalk.red("\u2717 Failed to add MCP server"));
153
+ this.log("");
154
+ this.log(chalk.dim(message));
155
+ this.log("");
156
+ process.exit(1);
157
+ }
158
+ }
159
+ };
160
+ export {
161
+ McpAdd as default
162
+ };
@@ -0,0 +1,16 @@
1
+ import * as _oclif_core_interfaces from '@oclif/core/interfaces';
2
+ import { Command } from '@oclif/core';
3
+
4
+ declare class McpList extends Command {
5
+ static description: string;
6
+ static examples: string[];
7
+ static flags: {
8
+ scope: _oclif_core_interfaces.OptionFlag<string | undefined, _oclif_core_interfaces.CustomOptions>;
9
+ transport: _oclif_core_interfaces.OptionFlag<string | undefined, _oclif_core_interfaces.CustomOptions>;
10
+ enabled: _oclif_core_interfaces.BooleanFlag<boolean>;
11
+ };
12
+ run(): Promise<void>;
13
+ private cleanup;
14
+ }
15
+
16
+ export { McpList as default };